From 2fc22901730f35405d2bdfe33f88d7b3c6b14304 Mon Sep 17 00:00:00 2001 From: Ekaterina Babshukova Date: Sat, 5 Oct 2019 17:03:03 +0300 Subject: replace AST visitors with macro --- crates/ra_syntax/src/lib.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'crates/ra_syntax/src/lib.rs') diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index edb6076bb..09230ccb2 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs @@ -295,6 +295,7 @@ fn api_walkthrough() { // 1. explicitly call getter methods on AST nodes. // 2. use descendants and `AstNode::cast`. // 3. use descendants and the visitor. + // 4. use descendants and `match_ast!`. // // Here's how the first one looks like: let exprs_cast: Vec = file @@ -319,3 +320,14 @@ fn api_walkthrough() { } assert_eq!(exprs_cast, exprs_visit); } + +#[macro_export] +macro_rules! match_ast { + (match $node:ident { + $( ast::$ast:ident($it:ident) => $res:block, )* + _ => $catch_all:expr, + }) => {{ + $( if let Some($it) = ast::$ast::cast($node.clone()) $res else )* + { $catch_all } + }}; +} -- cgit v1.2.3 From 311dbb854536dd526cdbcadc6d270f9a37e4b816 Mon Sep 17 00:00:00 2001 From: Ekaterina Babshukova Date: Sat, 5 Oct 2019 17:48:31 +0300 Subject: remove `visitor` module --- crates/ra_syntax/src/lib.rs | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) (limited to 'crates/ra_syntax/src/lib.rs') diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index 09230ccb2..c315ba552 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs @@ -160,6 +160,17 @@ impl SourceFile { } } +#[macro_export] +macro_rules! match_ast { + (match $node:ident { + $( ast::$ast:ident($it:ident) => $res:block, )* + _ => $catch_all:expr, + }) => {{ + $( if let Some($it) = ast::$ast::cast($node.clone()) $res else )* + { $catch_all } + }}; +} + /// This test does not assert anything and instead just shows off the crate's /// API. #[test] @@ -294,8 +305,7 @@ fn api_walkthrough() { // To recursively process the tree, there are three approaches: // 1. explicitly call getter methods on AST nodes. // 2. use descendants and `AstNode::cast`. - // 3. use descendants and the visitor. - // 4. use descendants and `match_ast!`. + // 3. use descendants and `match_ast!`. // // Here's how the first one looks like: let exprs_cast: Vec = file @@ -305,29 +315,18 @@ fn api_walkthrough() { .map(|expr| expr.syntax().text().to_string()) .collect(); - // An alternative is to use a visitor. The visitor does not do traversal - // automatically (so it's more akin to a generic lambda) and is constructed - // from closures. This seems more flexible than a single generated visitor - // trait. - use algo::visit::{visitor, Visitor}; + // An alternative is to use a macro. let mut exprs_visit = Vec::new(); for node in file.syntax().descendants() { - if let Some(result) = - visitor().visit::(|expr| expr.syntax().text().to_string()).accept(&node) - { - exprs_visit.push(result); + match_ast! { + match node { + ast::Expr(it) => { + let res = it.syntax().text().to_string(); + exprs_visit.push(res); + }, + _ => (), + } } } assert_eq!(exprs_cast, exprs_visit); } - -#[macro_export] -macro_rules! match_ast { - (match $node:ident { - $( ast::$ast:ident($it:ident) => $res:block, )* - _ => $catch_all:expr, - }) => {{ - $( if let Some($it) = ast::$ast::cast($node.clone()) $res else )* - { $catch_all } - }}; -} -- cgit v1.2.3