aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/parser_impl/event.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/parser_impl/event.rs')
-rw-r--r--crates/ra_syntax/src/parser_impl/event.rs53
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
87impl Event {
88 pub(crate) fn tombstone() -> Self {
89 Event::Start {
90 kind: TOMBSTONE,
91 forward_parent: None,
92 }
93 }
94}
95
87pub(super) struct EventProcessor<'a, S: Sink> { 96pub(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 {