Skip to main content

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}