From c09c6fc97c1d553dd348383eb98fc7a4788030cb Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 30 Jan 2019 23:58:52 +0300 Subject: start tt convertions boilerplate --- crates/ra_hir/src/macros.rs | 38 ++++++++++++++++++++++++++++++++++++-- crates/ra_hir/src/macros/tt.rs | 12 +++++++----- 2 files changed, 43 insertions(+), 7 deletions(-) (limited to 'crates/ra_hir/src') diff --git a/crates/ra_hir/src/macros.rs b/crates/ra_hir/src/macros.rs index 647df4260..9ba381685 100644 --- a/crates/ra_hir/src/macros.rs +++ b/crates/ra_hir/src/macros.rs @@ -16,6 +16,7 @@ use std::sync::Arc; use ra_syntax::{ TextRange, TextUnit, SourceFile, AstNode, SyntaxNode, TreeArc, SyntaxNodePtr, + SyntaxKind::*, ast::{self, NameOwner}, }; @@ -201,6 +202,39 @@ pub(crate) fn expand_macro_invocation( def.expand(input).map(Arc::new) } -fn macro_call_to_tt(call: &ast::MacroCall) -> Option { - None +fn macro_call_to_tt(call: &ast::MacroCall) -> Option { + let tt = call.token_tree()?; + convert_tt(tt.syntax()) +} + +fn convert_tt(tt: &SyntaxNode) -> Option { + let first_child = tt.first_child()?; + let last_child = tt.last_child()?; + let delimiter = match (first_child.kind(), last_child.kind()) { + (L_PAREN, R_PAREN) => tt::Delimiter::Parenthesis, + (L_CURLY, R_CURLY) => tt::Delimiter::Brace, + (L_BRACK, R_BRACK) => tt::Delimiter::Bracket, + _ => return None, + }; + let mut token_trees = Vec::new(); + for child in tt.children().skip(1) { + if child == first_child || child == last_child || child.kind().is_trivia() { + continue; + } + let child = if child.kind() == TOKEN_TREE { + convert_tt(child)?.into() + } else if child.kind().is_keyword() { + let text = child.leaf_text().unwrap().clone(); + tt::Leaf::from(tt::Ident { text }).into() + } else { + return None; + }; + token_trees.push(child) + } + + let res = tt::Subtree { + delimiter, + token_trees, + }; + Some(res) } diff --git a/crates/ra_hir/src/macros/tt.rs b/crates/ra_hir/src/macros/tt.rs index 817cb262e..11b1089d3 100644 --- a/crates/ra_hir/src/macros/tt.rs +++ b/crates/ra_hir/src/macros/tt.rs @@ -4,16 +4,18 @@ pub(crate) enum TokenTree { Leaf(Leaf), Subtree(Subtree), } +impl_froms!(TokenTree: Leaf, Subtree); pub(crate) enum Leaf { Literal(Literal), Punct(Punct), Ident(Ident), } +impl_froms!(Leaf: Literal, Punct, Ident); pub(crate) struct Subtree { - delimiter: Delimiter, - token_trees: Vec, + pub(crate) delimiter: Delimiter, + pub(crate) token_trees: Vec, } pub(crate) enum Delimiter { @@ -24,13 +26,13 @@ pub(crate) enum Delimiter { } pub(crate) struct Literal { - text: SmolStr, + pub(crate) text: SmolStr, } pub(crate) struct Punct { - char: char, + pub(crate) char: char, } pub(crate) struct Ident { - text: SmolStr, + pub(crate) text: SmolStr, } -- cgit v1.2.3