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 ++++++++++++ crates/ra_syntax/src/validation.rs | 18 ++++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) (limited to 'crates/ra_syntax') 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 } + }}; +} diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs index 4f8935b2c..ab4f15908 100644 --- a/crates/ra_syntax/src/validation.rs +++ b/crates/ra_syntax/src/validation.rs @@ -5,8 +5,7 @@ mod block; use rustc_lexer::unescape; use crate::{ - algo::visit::{visitor_ctx, VisitorCtx}, - ast, AstNode, SyntaxError, SyntaxErrorKind, + ast, match_ast, AstNode, SyntaxError, SyntaxErrorKind, SyntaxKind::{BYTE, BYTE_STRING, CHAR, INT_NUMBER, STRING}, SyntaxNode, SyntaxToken, TextUnit, T, }; @@ -97,12 +96,15 @@ impl From for SyntaxErrorKind { pub(crate) fn validate(root: &SyntaxNode) -> Vec { let mut errors = Vec::new(); for node in root.descendants() { - let _ = visitor_ctx(&mut errors) - .visit::(validate_literal) - .visit::(block::validate_block_expr) - .visit::(|it, errors| validate_numeric_name(it.name_ref(), errors)) - .visit::(|it, errors| validate_numeric_name(it.name_ref(), errors)) - .accept(&node); + match_ast! { + match node { + ast::Literal(it) => { validate_literal(it, &mut errors) }, + ast::BlockExpr(it) => { block::validate_block_expr(it, &mut errors) }, + ast::FieldExpr(it) => { validate_numeric_name(it.name_ref(), &mut errors) }, + ast::RecordField(it) => { validate_numeric_name(it.name_ref(), &mut errors) }, + _ => (), + } + } } errors } -- cgit v1.2.3