diff options
Diffstat (limited to 'crates/ra_syntax/src/parser_impl/event.rs')
-rw-r--r-- | crates/ra_syntax/src/parser_impl/event.rs | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/crates/ra_syntax/src/parser_impl/event.rs b/crates/ra_syntax/src/parser_impl/event.rs index 3d8b062d5..73dd6e02b 100644 --- a/crates/ra_syntax/src/parser_impl/event.rs +++ b/crates/ra_syntax/src/parser_impl/event.rs | |||
@@ -36,7 +36,7 @@ pub(crate) enum Event { | |||
36 | /// | 36 | /// |
37 | /// For left-recursive syntactic constructs, the parser produces | 37 | /// For left-recursive syntactic constructs, the parser produces |
38 | /// a child node before it sees a parent. `forward_parent` | 38 | /// a child node before it sees a parent. `forward_parent` |
39 | /// exists to allow to tweak parent-child relationships. | 39 | /// saves the position of current event's parent. |
40 | /// | 40 | /// |
41 | /// Consider this path | 41 | /// Consider this path |
42 | /// | 42 | /// |
@@ -84,6 +84,15 @@ pub(crate) enum Event { | |||
84 | }, | 84 | }, |
85 | } | 85 | } |
86 | 86 | ||
87 | impl Event { | ||
88 | pub(crate) fn tombstone() -> Self { | ||
89 | Event::Start { | ||
90 | kind: TOMBSTONE, | ||
91 | forward_parent: None, | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | |||
87 | pub(super) struct EventProcessor<'a, S: Sink> { | 96 | pub(super) struct EventProcessor<'a, S: Sink> { |
88 | sink: S, | 97 | sink: S, |
89 | text_pos: TextUnit, | 98 | text_pos: TextUnit, |
@@ -110,17 +119,12 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
110 | } | 119 | } |
111 | } | 120 | } |
112 | 121 | ||
122 | /// Generate the syntax tree with the control of events. | ||
113 | pub(super) fn process(mut self) -> S { | 123 | pub(super) fn process(mut self) -> S { |
114 | fn tombstone() -> Event { | ||
115 | Event::Start { | ||
116 | kind: TOMBSTONE, | ||
117 | forward_parent: None, | ||
118 | } | ||
119 | } | ||
120 | let mut forward_parents = Vec::new(); | 124 | let mut forward_parents = Vec::new(); |
121 | 125 | ||
122 | for i in 0..self.events.len() { | 126 | for i in 0..self.events.len() { |
123 | match mem::replace(&mut self.events[i], tombstone()) { | 127 | match mem::replace(&mut self.events[i], Event::tombstone()) { |
124 | Event::Start { | 128 | Event::Start { |
125 | kind: TOMBSTONE, .. | 129 | kind: TOMBSTONE, .. |
126 | } => (), | 130 | } => (), |
@@ -129,12 +133,18 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
129 | kind, | 133 | kind, |
130 | forward_parent, | 134 | forward_parent, |
131 | } => { | 135 | } => { |
136 | // For events[A, B, C], B is A's forward_parent, C is B's forward_parent, | ||
137 | // in the normal control flow, the parent-child relation: `A -> B -> C`, | ||
138 | // while with the magic forward_parent, it writes: `C <- B <- A`. | ||
139 | |||
140 | // append `A` into parents. | ||
132 | forward_parents.push(kind); | 141 | forward_parents.push(kind); |
133 | let mut idx = i; | 142 | let mut idx = i; |
134 | let mut fp = forward_parent; | 143 | let mut fp = forward_parent; |
135 | while let Some(fwd) = fp { | 144 | while let Some(fwd) = fp { |
136 | idx += fwd as usize; | 145 | idx += fwd as usize; |
137 | fp = match mem::replace(&mut self.events[idx], tombstone()) { | 146 | // append `A`'s forward_parent `B` |
147 | fp = match mem::replace(&mut self.events[idx], Event::tombstone()) { | ||
138 | Event::Start { | 148 | Event::Start { |
139 | kind, | 149 | kind, |
140 | forward_parent, | 150 | forward_parent, |
@@ -144,17 +154,19 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
144 | } | 154 | } |
145 | _ => unreachable!(), | 155 | _ => unreachable!(), |
146 | }; | 156 | }; |
157 | // append `B`'s forward_parent `C` in the next stage. | ||
147 | } | 158 | } |
159 | |||
148 | for kind in forward_parents.drain(..).rev() { | 160 | for kind in forward_parents.drain(..).rev() { |
149 | self.start(kind); | 161 | self.start(kind); |
150 | } | 162 | } |
151 | } | 163 | } |
152 | Event::Finish => { | 164 | Event::Finish => { |
153 | let last = i == self.events.len() - 1; | 165 | let is_last = i == self.events.len() - 1; |
154 | self.finish(last); | 166 | self.finish(is_last); |
155 | } | 167 | } |
156 | Event::Token { kind, n_raw_tokens } => { | 168 | Event::Token { kind, n_raw_tokens } => { |
157 | self.eat_ws(); | 169 | self.eat_trivias(); |
158 | let n_raw_tokens = n_raw_tokens as usize; | 170 | let n_raw_tokens = n_raw_tokens as usize; |
159 | let len = self.tokens[self.token_pos..self.token_pos + n_raw_tokens] | 171 | let len = self.tokens[self.token_pos..self.token_pos + n_raw_tokens] |
160 | .iter() | 172 | .iter() |
@@ -171,9 +183,10 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
171 | self.sink | 183 | self.sink |
172 | } | 184 | } |
173 | 185 | ||
186 | /// Add the node into syntax tree but discard the comments/whitespaces. | ||
174 | fn start(&mut self, kind: SyntaxKind) { | 187 | fn start(&mut self, kind: SyntaxKind) { |
175 | if kind == SOURCE_FILE { | 188 | if kind == SOURCE_FILE { |
176 | self.sink.start_internal(kind); | 189 | self.sink.start_branch(kind); |
177 | return; | 190 | return; |
178 | } | 191 | } |
179 | let n_trivias = self.tokens[self.token_pos..] | 192 | let n_trivias = self.tokens[self.token_pos..] |
@@ -194,18 +207,18 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
194 | n_attached_trivias(kind, leading_trivias) | 207 | n_attached_trivias(kind, leading_trivias) |
195 | }; | 208 | }; |
196 | self.eat_n_trivias(n_trivias - n_attached_trivias); | 209 | self.eat_n_trivias(n_trivias - n_attached_trivias); |
197 | self.sink.start_internal(kind); | 210 | self.sink.start_branch(kind); |
198 | self.eat_n_trivias(n_attached_trivias); | 211 | self.eat_n_trivias(n_attached_trivias); |
199 | } | 212 | } |
200 | 213 | ||
201 | fn finish(&mut self, last: bool) { | 214 | fn finish(&mut self, is_last: bool) { |
202 | if last { | 215 | if is_last { |
203 | self.eat_ws() | 216 | self.eat_trivias() |
204 | } | 217 | } |
205 | self.sink.finish_internal(); | 218 | self.sink.finish_branch(); |
206 | } | 219 | } |
207 | 220 | ||
208 | fn eat_ws(&mut self) { | 221 | fn eat_trivias(&mut self) { |
209 | while let Some(&token) = self.tokens.get(self.token_pos) { | 222 | while let Some(&token) = self.tokens.get(self.token_pos) { |
210 | if !token.kind.is_trivia() { | 223 | if !token.kind.is_trivia() { |
211 | break; | 224 | break; |
@@ -236,7 +249,7 @@ fn n_attached_trivias<'a>( | |||
236 | trivias: impl Iterator<Item = (SyntaxKind, &'a str)>, | 249 | trivias: impl Iterator<Item = (SyntaxKind, &'a str)>, |
237 | ) -> usize { | 250 | ) -> usize { |
238 | match kind { | 251 | match kind { |
239 | STRUCT_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | MODULE => { | 252 | CONST_DEF | TYPE_DEF | STRUCT_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | MODULE => { |
240 | let mut res = 0; | 253 | let mut res = 0; |
241 | for (i, (kind, text)) in trivias.enumerate() { | 254 | for (i, (kind, text)) in trivias.enumerate() { |
242 | match kind { | 255 | match kind { |