diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-04-01 10:30:25 +0100 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-04-01 10:30:25 +0100 |
commit | 42a883f06c28ddeab22e5703a578f19110dde7f3 (patch) | |
tree | fe57697b54ccfb791fe96c13cb553a8570516270 /crates/ra_mbe/src | |
parent | dec9bde10868b5e459535449476d17a6a0987b3e (diff) | |
parent | 9e213385c9d06db3c8ca20812779e2b8f8ad2c71 (diff) |
Merge #1078
1078: rewrite syntax trees r=matklad a=matklad
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_mbe/src')
-rw-r--r-- | crates/ra_mbe/src/syntax_bridge.rs | 86 |
1 files changed, 47 insertions, 39 deletions
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs index 4b1d1d3ca..05f9817da 100644 --- a/crates/ra_mbe/src/syntax_bridge.rs +++ b/crates/ra_mbe/src/syntax_bridge.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use ra_parser::{TokenSource, TreeSink, ParseError}; | 1 | use ra_parser::{TokenSource, TreeSink, ParseError}; |
2 | use ra_syntax::{ | 2 | use ra_syntax::{ |
3 | AstNode, SyntaxNode, TextRange, SyntaxKind, SmolStr, SyntaxTreeBuilder, TreeArc, | 3 | AstNode, SyntaxNode, TextRange, SyntaxKind, SmolStr, SyntaxTreeBuilder, TreeArc, SyntaxElement, |
4 | ast, SyntaxKind::*, TextUnit | 4 | ast, SyntaxKind::*, TextUnit |
5 | }; | 5 | }; |
6 | 6 | ||
@@ -47,8 +47,8 @@ fn convert_tt( | |||
47 | global_offset: TextUnit, | 47 | global_offset: TextUnit, |
48 | tt: &SyntaxNode, | 48 | tt: &SyntaxNode, |
49 | ) -> Option<tt::Subtree> { | 49 | ) -> Option<tt::Subtree> { |
50 | let first_child = tt.first_child()?; | 50 | let first_child = tt.first_child_or_token()?; |
51 | let last_child = tt.last_child()?; | 51 | let last_child = tt.last_child_or_token()?; |
52 | let delimiter = match (first_child.kind(), last_child.kind()) { | 52 | let delimiter = match (first_child.kind(), last_child.kind()) { |
53 | (L_PAREN, R_PAREN) => tt::Delimiter::Parenthesis, | 53 | (L_PAREN, R_PAREN) => tt::Delimiter::Parenthesis, |
54 | (L_CURLY, R_CURLY) => tt::Delimiter::Brace, | 54 | (L_CURLY, R_CURLY) => tt::Delimiter::Brace, |
@@ -56,39 +56,47 @@ fn convert_tt( | |||
56 | _ => return None, | 56 | _ => return None, |
57 | }; | 57 | }; |
58 | let mut token_trees = Vec::new(); | 58 | let mut token_trees = Vec::new(); |
59 | for child in tt.children().skip(1) { | 59 | for child in tt.children_with_tokens().skip(1) { |
60 | if child == first_child || child == last_child || child.kind().is_trivia() { | 60 | if child == first_child || child == last_child || child.kind().is_trivia() { |
61 | continue; | 61 | continue; |
62 | } | 62 | } |
63 | if child.kind().is_punct() { | 63 | match child { |
64 | let mut prev = None; | 64 | SyntaxElement::Token(token) => { |
65 | for char in child.leaf_text().unwrap().chars() { | 65 | if token.kind().is_punct() { |
66 | if let Some(char) = prev { | 66 | let mut prev = None; |
67 | token_trees.push( | 67 | for char in token.text().chars() { |
68 | tt::Leaf::from(tt::Punct { char, spacing: tt::Spacing::Joint }).into(), | 68 | if let Some(char) = prev { |
69 | ); | 69 | token_trees.push( |
70 | tt::Leaf::from(tt::Punct { char, spacing: tt::Spacing::Joint }) | ||
71 | .into(), | ||
72 | ); | ||
73 | } | ||
74 | prev = Some(char) | ||
75 | } | ||
76 | if let Some(char) = prev { | ||
77 | token_trees.push( | ||
78 | tt::Leaf::from(tt::Punct { char, spacing: tt::Spacing::Alone }).into(), | ||
79 | ); | ||
80 | } | ||
81 | } else { | ||
82 | let child = if token.kind().is_keyword() || token.kind() == IDENT { | ||
83 | let relative_range = token.range() - global_offset; | ||
84 | let id = token_map.alloc(relative_range); | ||
85 | let text = token.text().clone(); | ||
86 | tt::Leaf::from(tt::Ident { text, id }).into() | ||
87 | } else if token.kind().is_literal() { | ||
88 | tt::Leaf::from(tt::Literal { text: token.text().clone() }).into() | ||
89 | } else { | ||
90 | return None; | ||
91 | }; | ||
92 | token_trees.push(child); | ||
70 | } | 93 | } |
71 | prev = Some(char) | ||
72 | } | 94 | } |
73 | if let Some(char) = prev { | 95 | SyntaxElement::Node(node) => { |
74 | token_trees | 96 | let child = convert_tt(token_map, global_offset, node)?.into(); |
75 | .push(tt::Leaf::from(tt::Punct { char, spacing: tt::Spacing::Alone }).into()); | 97 | token_trees.push(child); |
76 | } | 98 | } |
77 | } else { | 99 | }; |
78 | let child: tt::TokenTree = if child.kind() == TOKEN_TREE { | ||
79 | convert_tt(token_map, global_offset, child)?.into() | ||
80 | } else if child.kind().is_keyword() || child.kind() == IDENT { | ||
81 | let relative_range = child.range() - global_offset; | ||
82 | let id = token_map.alloc(relative_range); | ||
83 | let text = child.leaf_text().unwrap().clone(); | ||
84 | tt::Leaf::from(tt::Ident { text, id }).into() | ||
85 | } else if child.kind().is_literal() { | ||
86 | tt::Leaf::from(tt::Literal { text: child.leaf_text().unwrap().clone() }).into() | ||
87 | } else { | ||
88 | return None; | ||
89 | }; | ||
90 | token_trees.push(child) | ||
91 | } | ||
92 | } | 100 | } |
93 | 101 | ||
94 | let res = tt::Subtree { delimiter, token_trees }; | 102 | let res = tt::Subtree { delimiter, token_trees }; |
@@ -118,12 +126,12 @@ impl TtTokenSource { | |||
118 | } | 126 | } |
119 | fn convert_tt(&mut self, tt: &tt::TokenTree) { | 127 | fn convert_tt(&mut self, tt: &tt::TokenTree) { |
120 | match tt { | 128 | match tt { |
121 | tt::TokenTree::Leaf(leaf) => self.convert_leaf(leaf), | 129 | tt::TokenTree::Leaf(token) => self.convert_token(token), |
122 | tt::TokenTree::Subtree(sub) => self.convert_subtree(sub), | 130 | tt::TokenTree::Subtree(sub) => self.convert_subtree(sub), |
123 | } | 131 | } |
124 | } | 132 | } |
125 | fn convert_leaf(&mut self, leaf: &tt::Leaf) { | 133 | fn convert_token(&mut self, token: &tt::Leaf) { |
126 | let tok = match leaf { | 134 | let tok = match token { |
127 | tt::Leaf::Literal(l) => TtToken { | 135 | tt::Leaf::Literal(l) => TtToken { |
128 | kind: SyntaxKind::INT_NUMBER, // FIXME | 136 | kind: SyntaxKind::INT_NUMBER, // FIXME |
129 | is_joint_to_next: false, | 137 | is_joint_to_next: false, |
@@ -206,7 +214,7 @@ impl<'a> TtTreeSink<'a> { | |||
206 | } | 214 | } |
207 | 215 | ||
208 | impl<'a> TreeSink for TtTreeSink<'a> { | 216 | impl<'a> TreeSink for TtTreeSink<'a> { |
209 | fn leaf(&mut self, kind: SyntaxKind, n_tokens: u8) { | 217 | fn token(&mut self, kind: SyntaxKind, n_tokens: u8) { |
210 | for _ in 0..n_tokens { | 218 | for _ in 0..n_tokens { |
211 | self.buf += self.tokens[self.token_pos].text.as_str(); | 219 | self.buf += self.tokens[self.token_pos].text.as_str(); |
212 | self.token_pos += 1; | 220 | self.token_pos += 1; |
@@ -214,15 +222,15 @@ impl<'a> TreeSink for TtTreeSink<'a> { | |||
214 | self.text_pos += TextUnit::of_str(&self.buf); | 222 | self.text_pos += TextUnit::of_str(&self.buf); |
215 | let text = SmolStr::new(self.buf.as_str()); | 223 | let text = SmolStr::new(self.buf.as_str()); |
216 | self.buf.clear(); | 224 | self.buf.clear(); |
217 | self.inner.leaf(kind, text) | 225 | self.inner.token(kind, text) |
218 | } | 226 | } |
219 | 227 | ||
220 | fn start_branch(&mut self, kind: SyntaxKind) { | 228 | fn start_node(&mut self, kind: SyntaxKind) { |
221 | self.inner.start_branch(kind); | 229 | self.inner.start_node(kind); |
222 | } | 230 | } |
223 | 231 | ||
224 | fn finish_branch(&mut self) { | 232 | fn finish_node(&mut self) { |
225 | self.inner.finish_branch(); | 233 | self.inner.finish_node(); |
226 | } | 234 | } |
227 | 235 | ||
228 | fn error(&mut self, error: ParseError) { | 236 | fn error(&mut self, error: ParseError) { |