From c89abd42621daff2d652566be4e9e4789599268c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 2 Sep 2019 18:51:03 +0300 Subject: simplify --- crates/ra_mbe/src/mbe_expander.rs | 122 +++++++++++++----------------------- crates/ra_mbe/src/subtree_parser.rs | 40 ++---------- crates/ra_mbe/src/syntax_bridge.rs | 32 ++++++++-- crates/ra_mbe/src/tt_cursor.rs | 46 ++------------ 4 files changed, 82 insertions(+), 158 deletions(-) (limited to 'crates/ra_mbe') diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs index f185aecb7..adee0cb42 100644 --- a/crates/ra_mbe/src/mbe_expander.rs +++ b/crates/ra_mbe/src/mbe_expander.rs @@ -1,7 +1,9 @@ +//! This module takes a (parsed) definition of `macro_rules` invocation, a +//! `tt::TokenTree` representing an argument of macro invocation, and produces a +//! `tt::TokenTree` for the result of the expansion. + +use ra_parser::FragmentKind::*; use ra_syntax::SmolStr; -/// This module takes a (parsed) definition of `macro_rules` invocation, a -/// `tt::TokenTree` representing an argument of macro invocation, and produces a -/// `tt::TokenTree` for the result of the expansion. use rustc_hash::FxHashMap; use tt::TokenId; @@ -192,81 +194,11 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result match leaf { crate::Leaf::Var(crate::Var { text, kind }) => { let kind = kind.clone().ok_or(ExpandError::UnexpectedToken)?; - match kind.as_str() { - "ident" => { - let ident = - input.eat_ident().ok_or(ExpandError::UnexpectedToken)?.clone(); - res.inner.insert( - text.clone(), - Binding::Simple(tt::Leaf::from(ident).into()), - ); - } - "path" => { - let path = - input.eat_path().ok_or(ExpandError::UnexpectedToken)?.clone(); - res.inner.insert(text.clone(), Binding::Simple(path)); - } - "expr" => { - let expr = - input.eat_expr().ok_or(ExpandError::UnexpectedToken)?.clone(); - res.inner.insert(text.clone(), Binding::Simple(expr)); - } - "ty" => { - let ty = input.eat_ty().ok_or(ExpandError::UnexpectedToken)?.clone(); - res.inner.insert(text.clone(), Binding::Simple(ty)); - } - "pat" => { - let pat = input.eat_pat().ok_or(ExpandError::UnexpectedToken)?.clone(); - res.inner.insert(text.clone(), Binding::Simple(pat)); - } - "stmt" => { - let pat = input.eat_stmt().ok_or(ExpandError::UnexpectedToken)?.clone(); - res.inner.insert(text.clone(), Binding::Simple(pat)); - } - "block" => { - let block = - input.eat_block().ok_or(ExpandError::UnexpectedToken)?.clone(); - res.inner.insert(text.clone(), Binding::Simple(block)); - } - "meta" => { - let meta = - input.eat_meta().ok_or(ExpandError::UnexpectedToken)?.clone(); - res.inner.insert(text.clone(), Binding::Simple(meta)); - } - "tt" => { - let token = input.eat().ok_or(ExpandError::UnexpectedToken)?.clone(); - res.inner.insert(text.clone(), Binding::Simple(token)); - } - "item" => { - let item = - input.eat_item().ok_or(ExpandError::UnexpectedToken)?.clone(); - res.inner.insert(text.clone(), Binding::Simple(item)); - } - "lifetime" => { - let lifetime = - input.eat_lifetime().ok_or(ExpandError::UnexpectedToken)?.clone(); - res.inner.insert(text.clone(), Binding::Simple(lifetime)); + match match_meta_var(kind.as_str(), input)? { + Some(tt) => { + res.inner.insert(text.clone(), Binding::Simple(tt)); } - "literal" => { - let literal = - input.eat_literal().ok_or(ExpandError::UnexpectedToken)?.clone(); - - res.inner.insert( - text.clone(), - Binding::Simple(tt::Leaf::from(literal).into()), - ); - } - "vis" => { - // `vis` is optional - if let Some(vis) = input.try_eat_vis() { - let vis = vis.clone(); - res.inner.insert(text.clone(), Binding::Simple(vis)); - } else { - res.push_optional(&text); - } - } - - _ => return Err(ExpandError::UnexpectedToken), + None => res.push_optional(text), } } crate::Leaf::Punct(punct) => { @@ -360,6 +292,42 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result Result, ExpandError> { + let fragment = match kind { + "path" => Path, + "expr" => Expr, + "ty" => Type, + "pat" => Pattern, + "stmt" => Statement, + "block" => Block, + "meta" => MetaItem, + "item" => Item, + _ => { + let binding = match kind { + "ident" => { + let ident = input.eat_ident().ok_or(ExpandError::UnexpectedToken)?.clone(); + tt::Leaf::from(ident).into() + } + "tt" => input.eat().ok_or(ExpandError::UnexpectedToken)?.clone(), + "lifetime" => input.eat_lifetime().ok_or(ExpandError::UnexpectedToken)?.clone(), + "literal" => { + let literal = input.eat_literal().ok_or(ExpandError::UnexpectedToken)?.clone(); + tt::Leaf::from(literal).into() + } + // `vis` is optional + "vis" => match input.try_eat_vis() { + Some(vis) => vis, + None => return Ok(None), + }, + _ => return Err(ExpandError::UnexpectedToken), + }; + return Ok(Some(binding)); + } + }; + let binding = input.eat_fragment(fragment).ok_or(ExpandError::UnexpectedToken)?; + Ok(Some(binding)) +} + #[derive(Debug)] struct ExpandCtx<'a> { bindings: &'a Bindings, diff --git a/crates/ra_mbe/src/subtree_parser.rs b/crates/ra_mbe/src/subtree_parser.rs index 5688e7f7f..4440c69ff 100644 --- a/crates/ra_mbe/src/subtree_parser.rs +++ b/crates/ra_mbe/src/subtree_parser.rs @@ -1,6 +1,6 @@ use crate::subtree_source::SubtreeTokenSource; -use ra_parser::{TokenSource, TreeSink}; +use ra_parser::{FragmentKind, TokenSource, TreeSink}; use ra_syntax::SyntaxKind; use tt::buffer::{Cursor, TokenBuffer}; @@ -52,40 +52,10 @@ impl<'a> Parser<'a> { Parser { cur_pos, subtree } } - pub fn parse_path(self) -> Option { - self.parse(ra_parser::parse_path) - } - - pub fn parse_expr(self) -> Option { - self.parse(ra_parser::parse_expr) - } - - pub fn parse_ty(self) -> Option { - self.parse(ra_parser::parse_ty) - } - - pub fn parse_pat(self) -> Option { - self.parse(ra_parser::parse_pat) - } - - pub fn parse_stmt(self) -> Option { - self.parse(|src, sink| ra_parser::parse_stmt(src, sink, false)) - } - - pub fn parse_block(self) -> Option { - self.parse(ra_parser::parse_block) - } - - pub fn parse_meta(self) -> Option { - self.parse(ra_parser::parse_meta) - } - - pub fn parse_item(self) -> Option { - self.parse(ra_parser::parse_item) - } - - pub fn parse_vis(self) -> Option { - self.parse(ra_parser::parse_vis) + pub fn parse_fragment(self, fragment_kind: FragmentKind) -> Option { + self.parse(|token_source, tree_skink| { + ra_parser::parse_fragment(token_source, tree_skink, fragment_kind) + }) } fn parse(self, f: F) -> Option diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs index 8225759e7..a380b1cfd 100644 --- a/crates/ra_mbe/src/syntax_bridge.rs +++ b/crates/ra_mbe/src/syntax_bridge.rs @@ -1,4 +1,7 @@ -use ra_parser::{ParseError, TreeSink}; +use ra_parser::{ + FragmentKind::{self, *}, + ParseError, TreeSink, +}; use ra_syntax::{ ast, AstNode, AstToken, NodeOrToken, Parse, SmolStr, SyntaxKind, SyntaxKind::*, SyntaxNode, SyntaxTreeBuilder, TextRange, TextUnit, T, @@ -63,33 +66,50 @@ where Ok(parse) } +fn fragment_to_syntax_node( + tt: &tt::Subtree, + fragment_kind: FragmentKind, +) -> Result, ExpandError> { + let tokens = [tt.clone().into()]; + let buffer = TokenBuffer::new(&tokens); + let mut token_source = SubtreeTokenSource::new(&buffer); + let mut tree_sink = TtTreeSink::new(buffer.begin()); + ra_parser::parse_fragment(&mut token_source, &mut tree_sink, fragment_kind); + if tree_sink.roots.len() != 1 { + return Err(ExpandError::ConversionError); + } + //FIXME: would be cool to report errors + let parse = tree_sink.inner.finish(); + Ok(parse) +} + /// Parses the token tree (result of macro expansion) to an expression pub fn token_tree_to_expr(tt: &tt::Subtree) -> Result, ExpandError> { - let parse = token_tree_to_syntax_node(tt, ra_parser::parse_expr)?; + let parse = fragment_to_syntax_node(tt, Expr)?; parse.cast().ok_or_else(|| crate::ExpandError::ConversionError) } /// Parses the token tree (result of macro expansion) to a Pattern pub fn token_tree_to_pat(tt: &tt::Subtree) -> Result, ExpandError> { - let parse = token_tree_to_syntax_node(tt, ra_parser::parse_pat)?; + let parse = fragment_to_syntax_node(tt, Pattern)?; parse.cast().ok_or_else(|| crate::ExpandError::ConversionError) } /// Parses the token tree (result of macro expansion) to a Type pub fn token_tree_to_ty(tt: &tt::Subtree) -> Result, ExpandError> { - let parse = token_tree_to_syntax_node(tt, ra_parser::parse_ty)?; + let parse = fragment_to_syntax_node(tt, Type)?; parse.cast().ok_or_else(|| crate::ExpandError::ConversionError) } /// Parses the token tree (result of macro expansion) as a sequence of stmts pub fn token_tree_to_macro_stmts(tt: &tt::Subtree) -> Result, ExpandError> { - let parse = token_tree_to_syntax_node(tt, ra_parser::parse_macro_stmts)?; + let parse = fragment_to_syntax_node(tt, Statements)?; parse.cast().ok_or_else(|| crate::ExpandError::ConversionError) } /// Parses the token tree (result of macro expansion) as a sequence of items pub fn token_tree_to_macro_items(tt: &tt::Subtree) -> Result, ExpandError> { - let parse = token_tree_to_syntax_node(tt, ra_parser::parse_macro_items)?; + let parse = fragment_to_syntax_node(tt, Items)?; parse.cast().ok_or_else(|| crate::ExpandError::ConversionError) } diff --git a/crates/ra_mbe/src/tt_cursor.rs b/crates/ra_mbe/src/tt_cursor.rs index 468276397..a69c006c7 100644 --- a/crates/ra_mbe/src/tt_cursor.rs +++ b/crates/ra_mbe/src/tt_cursor.rs @@ -1,5 +1,6 @@ -use crate::subtree_parser::Parser; -use crate::ParseError; +use crate::{subtree_parser::Parser, ParseError}; + +use ra_parser::FragmentKind; use smallvec::{smallvec, SmallVec}; #[derive(Debug, Clone)] @@ -98,44 +99,9 @@ impl<'a> TtCursor<'a> { }) } - pub(crate) fn eat_path(&mut self) -> Option { - let parser = Parser::new(&mut self.pos, self.subtree); - parser.parse_path() - } - - pub(crate) fn eat_expr(&mut self) -> Option { - let parser = Parser::new(&mut self.pos, self.subtree); - parser.parse_expr() - } - - pub(crate) fn eat_ty(&mut self) -> Option { - let parser = Parser::new(&mut self.pos, self.subtree); - parser.parse_ty() - } - - pub(crate) fn eat_pat(&mut self) -> Option { - let parser = Parser::new(&mut self.pos, self.subtree); - parser.parse_pat() - } - - pub(crate) fn eat_stmt(&mut self) -> Option { - let parser = Parser::new(&mut self.pos, self.subtree); - parser.parse_stmt() - } - - pub(crate) fn eat_block(&mut self) -> Option { - let parser = Parser::new(&mut self.pos, self.subtree); - parser.parse_block() - } - - pub(crate) fn eat_meta(&mut self) -> Option { - let parser = Parser::new(&mut self.pos, self.subtree); - parser.parse_meta() - } - - pub(crate) fn eat_item(&mut self) -> Option { + pub(crate) fn eat_fragment(&mut self, fragment_kind: FragmentKind) -> Option { let parser = Parser::new(&mut self.pos, self.subtree); - parser.parse_item() + parser.parse_fragment(fragment_kind) } pub(crate) fn eat_lifetime(&mut self) -> Option { @@ -154,7 +120,7 @@ impl<'a> TtCursor<'a> { let old_pos = self.pos; let parser = Parser::new(&mut self.pos, self.subtree); - let res = parser.parse_vis(); + let res = parser.parse_fragment(FragmentKind::Visibility); if res.is_none() { self.pos = old_pos; } -- cgit v1.2.3