start tt convertions boilerplate

This commit is contained in:
Aleksey Kladov 2019-01-30 23:58:52 +03:00
parent a4342a7fee
commit c09c6fc97c
2 changed files with 43 additions and 7 deletions

View file

@ -16,6 +16,7 @@ use std::sync::Arc;
use ra_syntax::{ use ra_syntax::{
TextRange, TextUnit, SourceFile, AstNode, SyntaxNode, TreeArc, SyntaxNodePtr, TextRange, TextUnit, SourceFile, AstNode, SyntaxNode, TreeArc, SyntaxNodePtr,
SyntaxKind::*,
ast::{self, NameOwner}, ast::{self, NameOwner},
}; };
@ -201,6 +202,39 @@ pub(crate) fn expand_macro_invocation(
def.expand(input).map(Arc::new) def.expand(input).map(Arc::new)
} }
fn macro_call_to_tt(call: &ast::MacroCall) -> Option<tt::TokenTree> { fn macro_call_to_tt(call: &ast::MacroCall) -> Option<tt::Subtree> {
None let tt = call.token_tree()?;
convert_tt(tt.syntax())
}
fn convert_tt(tt: &SyntaxNode) -> Option<tt::Subtree> {
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)
} }

View file

@ -4,16 +4,18 @@ pub(crate) enum TokenTree {
Leaf(Leaf), Leaf(Leaf),
Subtree(Subtree), Subtree(Subtree),
} }
impl_froms!(TokenTree: Leaf, Subtree);
pub(crate) enum Leaf { pub(crate) enum Leaf {
Literal(Literal), Literal(Literal),
Punct(Punct), Punct(Punct),
Ident(Ident), Ident(Ident),
} }
impl_froms!(Leaf: Literal, Punct, Ident);
pub(crate) struct Subtree { pub(crate) struct Subtree {
delimiter: Delimiter, pub(crate) delimiter: Delimiter,
token_trees: Vec<TokenTree>, pub(crate) token_trees: Vec<TokenTree>,
} }
pub(crate) enum Delimiter { pub(crate) enum Delimiter {
@ -24,13 +26,13 @@ pub(crate) enum Delimiter {
} }
pub(crate) struct Literal { pub(crate) struct Literal {
text: SmolStr, pub(crate) text: SmolStr,
} }
pub(crate) struct Punct { pub(crate) struct Punct {
char: char, pub(crate) char: char,
} }
pub(crate) struct Ident { pub(crate) struct Ident {
text: SmolStr, pub(crate) text: SmolStr,
} }