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::{
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<tt::TokenTree> {
None
fn macro_call_to_tt(call: &ast::MacroCall) -> Option<tt::Subtree> {
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),
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<TokenTree>,
pub(crate) delimiter: Delimiter,
pub(crate) token_trees: Vec<TokenTree>,
}
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,
}