Refactoring

This commit is contained in:
Edwin Cheng 2019-12-18 11:47:26 +08:00
parent 2ea1cfd780
commit 41544a4088
4 changed files with 55 additions and 53 deletions

View file

@ -106,7 +106,7 @@ fn match_subtree(
} }
Op::TokenTree(tt::TokenTree::Subtree(lhs)) => { Op::TokenTree(tt::TokenTree::Subtree(lhs)) => {
let rhs = src.expect_subtree().map_err(|()| err!("expected subtree"))?; let rhs = src.expect_subtree().map_err(|()| err!("expected subtree"))?;
if lhs.delimiter.map(|it| it.kind) != rhs.delimiter.map(|it| it.kind) { if lhs.delimiter_kind() != rhs.delimiter_kind() {
bail!("mismatched delimiter") bail!("mismatched delimiter")
} }
let mut src = TtIter::new(rhs); let mut src = TtIter::new(rhs);

View file

@ -70,11 +70,11 @@ impl<'a> SubtreeTokenSource<'a> {
} }
Some(tt::TokenTree::Subtree(subtree)) => { Some(tt::TokenTree::Subtree(subtree)) => {
self.cached_cursor.set(cursor.subtree().unwrap()); self.cached_cursor.set(cursor.subtree().unwrap());
cached.push(Some(convert_delim(subtree.delimiter, false))); cached.push(Some(convert_delim(subtree.delimiter_kind(), false)));
} }
None => { None => {
if let Some(subtree) = cursor.end() { if let Some(subtree) = cursor.end() {
cached.push(Some(convert_delim(subtree.delimiter, true))); cached.push(Some(convert_delim(subtree.delimiter_kind(), true)));
self.cached_cursor.set(cursor.bump()); self.cached_cursor.set(cursor.bump());
} }
} }
@ -114,8 +114,8 @@ impl<'a> TokenSource for SubtreeTokenSource<'a> {
} }
} }
fn convert_delim(d: Option<tt::Delimiter>, closing: bool) -> TtToken { fn convert_delim(d: Option<tt::DelimiterKind>, closing: bool) -> TtToken {
let (kinds, texts) = match d.map(|it| it.kind) { let (kinds, texts) = match d {
Some(tt::DelimiterKind::Parenthesis) => ([T!['('], T![')']], "()"), Some(tt::DelimiterKind::Parenthesis) => ([T!['('], T![')']], "()"),
Some(tt::DelimiterKind::Brace) => ([T!['{'], T!['}']], "{}"), Some(tt::DelimiterKind::Brace) => ([T!['{'], T!['}']], "{}"),
Some(tt::DelimiterKind::Bracket) => ([T!['['], T![']']], "[]"), Some(tt::DelimiterKind::Bracket) => ([T!['['], T![']']], "[]"),

View file

@ -269,35 +269,33 @@ impl Convertor {
.take(token.text().len() - 1) .take(token.text().len() - 1)
.chain(std::iter::once(last_spacing)); .chain(std::iter::once(last_spacing));
for (char, spacing) in token.text().chars().zip(spacing_iter) { for (char, spacing) in token.text().chars().zip(spacing_iter) {
let id = self.alloc(token.text_range()); token_trees.push(
token_trees tt::Leaf::from(tt::Punct {
.push(tt::Leaf::from(tt::Punct { char, spacing, id }).into()); char,
spacing,
id: self.alloc(token.text_range()),
})
.into(),
);
} }
} else { } else {
macro_rules! make_leaf {
($i:ident) => {
tt::$i {
id: self.alloc(token.text_range()),
text: token.text().clone(),
}
.into()
};
}
let child: tt::Leaf = match token.kind() { let child: tt::Leaf = match token.kind() {
T![true] | T![false] => { T![true] | T![false] => make_leaf!(Literal),
let id = self.alloc(token.text_range()); IDENT | LIFETIME => make_leaf!(Ident),
let text = token.text().clone(); k if k.is_keyword() => make_leaf!(Ident),
tt::Literal { text, id }.into() k if k.is_literal() => make_leaf!(Literal),
}
IDENT | LIFETIME => {
let id = self.alloc(token.text_range());
let text = token.text().clone();
tt::Ident { text, id }.into()
}
k if k.is_keyword() => {
let id = self.alloc(token.text_range());
let text = token.text().clone();
tt::Ident { text, id }.into()
}
k if k.is_literal() => {
let id = self.alloc(token.text_range());
let text = token.text().clone();
tt::Literal { text, id }.into()
}
_ => return None, _ => return None,
}; };
token_trees.push(child.into()); token_trees.push(child.into());
} }
} }
@ -370,8 +368,8 @@ impl<'a> TtTreeSink<'a> {
} }
} }
fn delim_to_str(d: Option<tt::Delimiter>, closing: bool) -> SmolStr { fn delim_to_str(d: Option<tt::DelimiterKind>, closing: bool) -> SmolStr {
let texts = match d.map(|it| it.kind) { let texts = match d {
Some(tt::DelimiterKind::Parenthesis) => "()", Some(tt::DelimiterKind::Parenthesis) => "()",
Some(tt::DelimiterKind::Brace) => "{}", Some(tt::DelimiterKind::Brace) => "{}",
Some(tt::DelimiterKind::Bracket) => "[]", Some(tt::DelimiterKind::Bracket) => "[]",
@ -395,7 +393,7 @@ impl<'a> TreeSink for TtTreeSink<'a> {
break; break;
} }
let text: Option<SmolStr> = match self.cursor.token_tree() { let text: SmolStr = match self.cursor.token_tree() {
Some(tt::TokenTree::Leaf(leaf)) => { Some(tt::TokenTree::Leaf(leaf)) => {
// Mark the range if needed // Mark the range if needed
let id = match leaf { let id = match leaf {
@ -407,16 +405,17 @@ impl<'a> TreeSink for TtTreeSink<'a> {
let range = TextRange::offset_len(self.text_pos, TextUnit::of_str(&text)); let range = TextRange::offset_len(self.text_pos, TextUnit::of_str(&text));
self.token_map.insert(id, range); self.token_map.insert(id, range);
self.cursor = self.cursor.bump(); self.cursor = self.cursor.bump();
Some(text) text
} }
Some(tt::TokenTree::Subtree(subtree)) => { Some(tt::TokenTree::Subtree(subtree)) => {
self.cursor = self.cursor.subtree().unwrap(); self.cursor = self.cursor.subtree().unwrap();
if let Some(id) = subtree.delimiter.map(|it| it.id) { if let Some(id) = subtree.delimiter.map(|it| it.id) {
self.open_delims.insert(id, self.text_pos); self.open_delims.insert(id, self.text_pos);
} }
Some(delim_to_str(subtree.delimiter, false)) delim_to_str(subtree.delimiter_kind(), false)
} }
None => self.cursor.end().and_then(|parent| { None => {
if let Some(parent) = self.cursor.end() {
self.cursor = self.cursor.bump(); self.cursor = self.cursor.bump();
if let Some(id) = parent.delimiter.map(|it| it.id) { if let Some(id) = parent.delimiter.map(|it| it.id) {
if let Some(open_delim) = self.open_delims.get(&id) { if let Some(open_delim) = self.open_delims.get(&id) {
@ -427,16 +426,15 @@ impl<'a> TreeSink for TtTreeSink<'a> {
self.token_map.insert_delim(id, open_range, close_range); self.token_map.insert_delim(id, open_range, close_range);
} }
} }
delim_to_str(parent.delimiter_kind(), true)
Some(delim_to_str(parent.delimiter, true)) } else {
}), continue;
}
}
}; };
if let Some(text) = text {
self.buf += &text; self.buf += &text;
self.text_pos += TextUnit::of_str(&text); self.text_pos += TextUnit::of_str(&text);
} }
}
let text = SmolStr::new(self.buf.as_str()); let text = SmolStr::new(self.buf.as_str());
self.buf.clear(); self.buf.clear();
@ -583,7 +581,7 @@ mod tests {
let token_tree = ast::TokenTree::cast(token_tree).unwrap(); let token_tree = ast::TokenTree::cast(token_tree).unwrap();
let tt = ast_to_token_tree(&token_tree).unwrap().0; let tt = ast_to_token_tree(&token_tree).unwrap().0;
assert_eq!(tt.delimiter.map(|it| it.kind), Some(tt::DelimiterKind::Brace)); assert_eq!(tt.delimiter_kind(), Some(tt::DelimiterKind::Brace));
} }
#[test] #[test]

View file

@ -103,7 +103,7 @@ impl fmt::Display for TokenTree {
impl fmt::Display for Subtree { impl fmt::Display for Subtree {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let (l, r) = match self.delimiter.map(|it| it.kind) { let (l, r) = match self.delimiter_kind() {
Some(DelimiterKind::Parenthesis) => ("(", ")"), Some(DelimiterKind::Parenthesis) => ("(", ")"),
Some(DelimiterKind::Brace) => ("{", "}"), Some(DelimiterKind::Brace) => ("{", "}"),
Some(DelimiterKind::Bracket) => ("[", "]"), Some(DelimiterKind::Bracket) => ("[", "]"),
@ -171,6 +171,10 @@ impl Subtree {
self.token_trees.len() + children_count self.token_trees.len() + children_count
} }
pub fn delimiter_kind(&self) -> Option<DelimiterKind> {
self.delimiter.map(|it| it.kind)
}
} }
pub mod buffer; pub mod buffer;