lsp_max_ast/core/utils.rs
1/// Calls a method on the first node that matches any of the provided types.
2/// Returns the result of the method call.
3///
4/// # Example
5///
6/// ```rust, ignore
7/// use ast::generated::{FunctionDefinition, ClassDefinition};
8/// use lsp_max_ast::dispatch_once;
9///
10/// /* ... */
11/// let result = dispatch_once!(node.lower(), [
12/// FunctionDefinition => return_something(db, param),
13/// ClassDefinition => return_something(db, param)
14/// ]);
15/// ```
16#[macro_export]
17macro_rules! dispatch_once {
18 ($node:expr, [$($ty:ty => $method:ident($($param:expr),*)),*]) => {
19 {
20 let _node = &$node;
21 if false {
22 unreachable!()
23 }
24 $(
25 else if let Some(n) = _node.downcast_ref::<$ty>() {
26 Some(n.$method($($param),*))
27 }
28 )*
29 else {
30 None
31 }
32 }
33 };
34}
35
36/// Calls a method on any node that matches any of the provided types.
37/// Unlike dispatch_once, it will not return.
38///
39/// # Example
40///
41/// ```rust, ignore
42/// use ast::generated::{FunctionDefinition, ClassDefinition};
43/// use lsp_max_ast::dispatch;
44///
45/// /* ... */
46/// dispatch!(node.lower(), [
47/// FunctionDefinition => get_something(db, param),
48/// ClassDefinition => get_something(db, param)
49/// ]);
50/// ```
51#[macro_export]
52macro_rules! dispatch {
53 ($node:expr, [$($ty:ty => $method:ident($($param:expr),*)),*]) => {
54 {
55 let _node = &$node;
56 $(
57 if let Some(n) = _node.downcast_ref::<$ty>() {
58 n.$method($($param),*)?;
59 };
60 )*
61 }
62 };
63}