Refactor tt::Delimiter

This commit is contained in:
Edwin Cheng 2019-12-13 21:53:34 +08:00
parent 16cf6bcf4b
commit 98f98cbb54
8 changed files with 42 additions and 44 deletions

View File

@ -16,7 +16,7 @@ macro_rules! __quote {
{
let children = $crate::__quote!($($tt)*);
let subtree = tt::Subtree {
delimiter: tt::Delimiter::$delim,
delimiter: Some(tt::Delimiter::$delim),
token_trees: $crate::quote::IntoTt::to_tokens(children),
};
subtree
@ -124,7 +124,7 @@ pub(crate) trait IntoTt {
impl IntoTt for Vec<tt::TokenTree> {
fn to_subtree(self) -> tt::Subtree {
tt::Subtree { delimiter: tt::Delimiter::None, token_trees: self }
tt::Subtree { delimiter: None, token_trees: self }
}
fn to_tokens(self) -> Vec<tt::TokenTree> {
@ -254,7 +254,8 @@ mod tests {
let fields =
fields.iter().map(|it| quote!(#it: self.#it.clone(), ).token_trees.clone()).flatten();
let list = tt::Subtree { delimiter: tt::Delimiter::Brace, token_trees: fields.collect() };
let list =
tt::Subtree { delimiter: Some(tt::Delimiter::Brace), token_trees: fields.collect() };
let quoted = quote! {
impl Clone for #struct_name {

View File

@ -159,14 +159,14 @@ impl Rule {
.expect_subtree()
.map_err(|()| ParseError::Expected("expected subtree".to_string()))?
.clone();
lhs.delimiter = tt::Delimiter::None;
lhs.delimiter = None;
src.expect_char('=').map_err(|()| ParseError::Expected("expected `=`".to_string()))?;
src.expect_char('>').map_err(|()| ParseError::Expected("expected `>`".to_string()))?;
let mut rhs = src
.expect_subtree()
.map_err(|()| ParseError::Expected("expected subtree".to_string()))?
.clone();
rhs.delimiter = tt::Delimiter::None;
rhs.delimiter = None;
Ok(crate::Rule { lhs, rhs })
}
}

View File

@ -16,7 +16,7 @@ impl Bindings {
fn push_optional(&mut self, name: &SmolStr) {
// FIXME: Do we have a better way to represent an empty token ?
// Insert an empty subtree for empty token
let tt = tt::Subtree { delimiter: tt::Delimiter::None, token_trees: vec![] }.into();
let tt = tt::Subtree::default().into();
self.inner.insert(name.clone(), Binding::Fragment(Fragment::Tokens(tt)));
}
@ -65,7 +65,7 @@ macro_rules! bail {
}
pub(super) fn match_(pattern: &tt::Subtree, src: &tt::Subtree) -> Result<Bindings, ExpandError> {
assert!(pattern.delimiter == tt::Delimiter::None);
assert!(pattern.delimiter == None);
let mut res = Bindings::default();
let mut src = TtIter::new(src);
@ -210,7 +210,7 @@ impl<'a> TtIter<'a> {
0 => Err(()),
1 => Ok(res[0].clone()),
_ => Ok(tt::TokenTree::Subtree(tt::Subtree {
delimiter: tt::Delimiter::None,
delimiter: None,
token_trees: res.into_iter().cloned().collect(),
})),
}

View File

@ -50,7 +50,7 @@ pub(super) fn transcribe(
template: &tt::Subtree,
bindings: &Bindings,
) -> Result<tt::Subtree, ExpandError> {
assert!(template.delimiter == tt::Delimiter::None);
assert!(template.delimiter == None);
let mut ctx = ExpandCtx { bindings: &bindings, nesting: Vec::new(), var_expanded: false };
expand_subtree(&mut ctx, template)
}
@ -106,7 +106,7 @@ fn expand_var(ctx: &mut ExpandCtx, v: &SmolStr) -> Result<Fragment, ExpandError>
// ```
// We just treat it a normal tokens
let tt = tt::Subtree {
delimiter: tt::Delimiter::None,
delimiter: None,
token_trees: vec![
tt::Leaf::from(tt::Punct { char: '$', spacing: tt::Spacing::Alone }).into(),
tt::Leaf::from(tt::Ident { text: v.clone(), id: tt::TokenId::unspecified() })
@ -147,7 +147,7 @@ fn expand_repeat(
ctx.var_expanded = false;
while let Ok(mut t) = expand_subtree(ctx, template) {
t.delimiter = tt::Delimiter::None;
t.delimiter = None;
// if no var expanded in the child, we count it as a fail
if !ctx.var_expanded {
break;
@ -212,7 +212,7 @@ fn expand_repeat(
// Check if it is a single token subtree without any delimiter
// e.g {Delimiter:None> ['>'] /Delimiter:None>}
let tt = tt::Subtree { delimiter: tt::Delimiter::None, token_trees: buf }.into();
let tt = tt::Subtree { delimiter: None, token_trees: buf }.into();
Ok(Fragment::Tokens(tt))
}
@ -225,7 +225,7 @@ fn push_fragment(buf: &mut Vec<tt::TokenTree>, fragment: Fragment) {
fn push_subtree(buf: &mut Vec<tt::TokenTree>, tt: tt::Subtree) {
match tt.delimiter {
tt::Delimiter::None => buf.extend(tt.token_trees),
None => buf.extend(tt.token_trees),
_ => buf.push(tt.into()),
}
}

View File

@ -114,12 +114,12 @@ impl<'a> TokenSource for SubtreeTokenSource<'a> {
}
}
fn convert_delim(d: tt::Delimiter, closing: bool) -> TtToken {
fn convert_delim(d: Option<tt::Delimiter>, closing: bool) -> TtToken {
let (kinds, texts) = match d {
tt::Delimiter::Parenthesis => ([T!['('], T![')']], "()"),
tt::Delimiter::Brace => ([T!['{'], T!['}']], "{}"),
tt::Delimiter::Bracket => ([T!['['], T![']']], "[]"),
tt::Delimiter::None => ([L_DOLLAR, R_DOLLAR], ""),
Some(tt::Delimiter::Parenthesis) => ([T!['('], T![')']], "()"),
Some(tt::Delimiter::Brace) => ([T!['{'], T!['}']], "{}"),
Some(tt::Delimiter::Bracket) => ([T!['['], T![']']], "[]"),
None => ([L_DOLLAR, R_DOLLAR], ""),
};
let idx = closing as usize;

View File

@ -51,7 +51,7 @@ pub fn token_tree_to_syntax_node(
) -> Result<(Parse<SyntaxNode>, TokenMap), ExpandError> {
let tmp;
let tokens = match tt {
tt::Subtree { delimiter: tt::Delimiter::None, token_trees } => token_trees.as_slice(),
tt::Subtree { delimiter: None, token_trees } => token_trees.as_slice(),
_ => {
tmp = [tt.clone().into()];
&tmp[..]
@ -121,7 +121,7 @@ fn convert_doc_comment(token: &ra_syntax::SyntaxToken) -> Option<Vec<tt::TokenTr
token_trees.push(mk_punct('!'));
}
token_trees.push(tt::TokenTree::from(tt::Subtree {
delimiter: tt::Delimiter::Bracket,
delimiter: Some(tt::Delimiter::Bracket),
token_trees: meta_tkns,
}));
@ -156,7 +156,7 @@ impl Convertor {
fn go(&mut self, tt: &SyntaxNode) -> Option<tt::Subtree> {
// This tree is empty
if tt.first_child_or_token().is_none() {
return Some(tt::Subtree { token_trees: vec![], delimiter: tt::Delimiter::None });
return Some(tt::Subtree { token_trees: vec![], delimiter: None });
}
let first_child = tt.first_child_or_token()?;
@ -173,7 +173,7 @@ impl Convertor {
.last()
.unwrap();
if first_child.kind().is_trivia() {
return Some(tt::Subtree { token_trees: vec![], delimiter: tt::Delimiter::None });
return Some(tt::Subtree { token_trees: vec![], delimiter: None });
}
let last_child = successors(Some(last_child), |it| {
@ -187,10 +187,10 @@ impl Convertor {
.unwrap();
let (delimiter, skip_first) = match (first_child.kind(), last_child.kind()) {
(T!['('], T![')']) => (tt::Delimiter::Parenthesis, true),
(T!['{'], T!['}']) => (tt::Delimiter::Brace, true),
(T!['['], T![']']) => (tt::Delimiter::Bracket, true),
_ => (tt::Delimiter::None, false),
(T!['('], T![')']) => (Some(tt::Delimiter::Parenthesis), true),
(T!['{'], T!['}']) => (Some(tt::Delimiter::Brace), true),
(T!['['], T![']']) => (Some(tt::Delimiter::Bracket), true),
_ => (None, false),
};
let mut token_trees = Vec::new();
@ -246,9 +246,7 @@ impl Convertor {
}
NodeOrToken::Node(node) => {
let child_subtree = self.go(&node)?;
if child_subtree.delimiter == tt::Delimiter::None
&& node.kind() != SyntaxKind::TOKEN_TREE
{
if child_subtree.delimiter.is_none() && node.kind() != SyntaxKind::TOKEN_TREE {
token_trees.extend(child_subtree.token_trees);
} else {
token_trees.push(child_subtree.into());
@ -299,16 +297,16 @@ impl<'a> TtTreeSink<'a> {
}
}
fn delim_to_str(d: tt::Delimiter, closing: bool) -> SmolStr {
fn delim_to_str(d: Option<tt::Delimiter>, closing: bool) -> SmolStr {
let texts = match d {
tt::Delimiter::Parenthesis => "()",
tt::Delimiter::Brace => "{}",
tt::Delimiter::Bracket => "[]",
tt::Delimiter::None => "",
Some(tt::Delimiter::Parenthesis) => "()",
Some(tt::Delimiter::Brace) => "{}",
Some(tt::Delimiter::Bracket) => "[]",
None => return "".into(),
};
let idx = closing as usize;
let text = if !texts.is_empty() { &texts[idx..texts.len() - (1 - idx)] } else { "" };
let text = &texts[idx..texts.len() - (1 - idx)];
text.into()
}
@ -497,7 +495,7 @@ mod tests {
let token_tree = ast::TokenTree::cast(token_tree).unwrap();
let tt = ast_to_token_tree(&token_tree).unwrap().0;
assert_eq!(tt.delimiter, tt::Delimiter::Brace);
assert_eq!(tt.delimiter, Some(tt::Delimiter::Brace));
}
#[test]

View File

@ -1463,7 +1463,7 @@ pub(crate) fn assert_expansion(
let wrapped = ast::SourceFile::parse(&wrapped);
let wrapped = wrapped.tree().syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
let mut wrapped = ast_to_token_tree(&wrapped).unwrap().0;
wrapped.delimiter = tt::Delimiter::None;
wrapped.delimiter = None;
wrapped
};
let (expanded_tree, expected_tree) = match kind {

View File

@ -48,9 +48,9 @@ pub enum Leaf {
}
impl_froms!(Leaf: Literal, Punct, Ident);
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
pub struct Subtree {
pub delimiter: Delimiter,
pub delimiter: Option<Delimiter>,
pub token_trees: Vec<TokenTree>,
}
@ -59,7 +59,6 @@ pub enum Delimiter {
Parenthesis,
Brace,
Bracket,
None,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@ -97,10 +96,10 @@ impl fmt::Display for TokenTree {
impl fmt::Display for Subtree {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let (l, r) = match self.delimiter {
Delimiter::Parenthesis => ("(", ")"),
Delimiter::Brace => ("{", "}"),
Delimiter::Bracket => ("[", "]"),
Delimiter::None => ("", ""),
Some(Delimiter::Parenthesis) => ("(", ")"),
Some(Delimiter::Brace) => ("{", "}"),
Some(Delimiter::Bracket) => ("[", "]"),
None => ("", ""),
};
f.write_str(l)?;
let mut needs_space = false;