diff options
author | pcpthm <[email protected]> | 2019-03-19 09:44:23 +0000 |
---|---|---|
committer | pcpthm <[email protected]> | 2019-03-19 09:44:23 +0000 |
commit | 4cf179c089aeed381cd67bcd265e76a27f11facd (patch) | |
tree | a47ced34b0861ba6179f6644e5284eac628301c4 /crates/ra_parser/src/parser.rs | |
parent | e2ed813e8951517f59552323c55a0ff05167c945 (diff) |
Replace `contract_child` to a less ad-hoc API
Diffstat (limited to 'crates/ra_parser/src/parser.rs')
-rw-r--r-- | crates/ra_parser/src/parser.rs | 57 |
1 files changed, 27 insertions, 30 deletions
diff --git a/crates/ra_parser/src/parser.rs b/crates/ra_parser/src/parser.rs index fa036bdbf..3c326452b 100644 --- a/crates/ra_parser/src/parser.rs +++ b/crates/ra_parser/src/parser.rs | |||
@@ -212,8 +212,9 @@ impl Marker { | |||
212 | } | 212 | } |
213 | _ => unreachable!(), | 213 | _ => unreachable!(), |
214 | } | 214 | } |
215 | let finish_pos = p.events.len() as u32; | ||
215 | p.push_event(Event::Finish); | 216 | p.push_event(Event::Finish); |
216 | CompletedMarker::new(self.pos, kind) | 217 | CompletedMarker::new(self.pos, finish_pos, kind) |
217 | } | 218 | } |
218 | 219 | ||
219 | /// Abandons the syntax tree node. All its children | 220 | /// Abandons the syntax tree node. All its children |
@@ -228,36 +229,17 @@ impl Marker { | |||
228 | } | 229 | } |
229 | } | 230 | } |
230 | } | 231 | } |
231 | |||
232 | /// Contract a node `cm` and complete as `cm`'s `kind`. | ||
233 | /// `cm` must be a child of `m` to work correctly. | ||
234 | /// ```text | ||
235 | /// m--A m--A | ||
236 | /// +--cm--B -> +--B | ||
237 | /// +--C C | ||
238 | /// | ||
239 | /// [m: TOMBSTONE, A, cm: Start(k), B, Finish, C] | ||
240 | /// [m: Start(k), A, cm: TOMBSTONE, B, Finish, C] | ||
241 | /// ``` | ||
242 | pub(crate) fn contract_child(mut self, p: &mut Parser, cm: CompletedMarker) -> CompletedMarker { | ||
243 | self.bomb.defuse(); | ||
244 | match p.events[self.pos as usize] { | ||
245 | Event::Start { kind: ref mut slot, .. } => *slot = cm.kind(), | ||
246 | _ => unreachable!(), | ||
247 | }; | ||
248 | match p.events[cm.0 as usize] { | ||
249 | Event::Start { kind: ref mut slot, .. } => *slot = TOMBSTONE, | ||
250 | _ => unreachable!(), | ||
251 | }; | ||
252 | CompletedMarker::new(self.pos, cm.kind()) | ||
253 | } | ||
254 | } | 232 | } |
255 | 233 | ||
256 | pub(crate) struct CompletedMarker(u32, SyntaxKind); | 234 | pub(crate) struct CompletedMarker { |
235 | start_pos: u32, | ||
236 | finish_pos: u32, | ||
237 | kind: SyntaxKind, | ||
238 | } | ||
257 | 239 | ||
258 | impl CompletedMarker { | 240 | impl CompletedMarker { |
259 | fn new(pos: u32, kind: SyntaxKind) -> Self { | 241 | fn new(start_pos: u32, finish_pos: u32, kind: SyntaxKind) -> Self { |
260 | CompletedMarker(pos, kind) | 242 | CompletedMarker { start_pos, finish_pos, kind } |
261 | } | 243 | } |
262 | 244 | ||
263 | /// This method allows to create a new node which starts | 245 | /// This method allows to create a new node which starts |
@@ -274,17 +256,32 @@ impl CompletedMarker { | |||
274 | /// distance to `NEWSTART` into forward_parent(=2 in this case); | 256 | /// distance to `NEWSTART` into forward_parent(=2 in this case); |
275 | pub(crate) fn precede(self, p: &mut Parser) -> Marker { | 257 | pub(crate) fn precede(self, p: &mut Parser) -> Marker { |
276 | let new_pos = p.start(); | 258 | let new_pos = p.start(); |
277 | let idx = self.0 as usize; | 259 | let idx = self.start_pos as usize; |
278 | match p.events[idx] { | 260 | match p.events[idx] { |
279 | Event::Start { ref mut forward_parent, .. } => { | 261 | Event::Start { ref mut forward_parent, .. } => { |
280 | *forward_parent = Some(new_pos.pos - self.0); | 262 | *forward_parent = Some(new_pos.pos - self.start_pos); |
281 | } | 263 | } |
282 | _ => unreachable!(), | 264 | _ => unreachable!(), |
283 | } | 265 | } |
284 | new_pos | 266 | new_pos |
285 | } | 267 | } |
286 | 268 | ||
269 | /// Undo this completion and turns into a `Marker` | ||
270 | pub(crate) fn undo_completion(self, p: &mut Parser) -> Marker { | ||
271 | let start_idx = self.start_pos as usize; | ||
272 | let finish_idx = self.finish_pos as usize; | ||
273 | match p.events[start_idx] { | ||
274 | Event::Start { ref mut kind, forward_parent: None } => *kind = TOMBSTONE, | ||
275 | _ => unreachable!(), | ||
276 | } | ||
277 | match p.events[finish_idx] { | ||
278 | ref mut slot @ Event::Finish => *slot = Event::tombstone(), | ||
279 | _ => unreachable!(), | ||
280 | } | ||
281 | Marker::new(self.start_pos) | ||
282 | } | ||
283 | |||
287 | pub(crate) fn kind(&self) -> SyntaxKind { | 284 | pub(crate) fn kind(&self) -> SyntaxKind { |
288 | self.1 | 285 | self.kind |
289 | } | 286 | } |
290 | } | 287 | } |