diff options
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r-- | crates/ra_syntax/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/parsing/text_tree_sink.rs | 28 | ||||
-rw-r--r-- | crates/ra_syntax/src/syntax_node.rs | 51 |
3 files changed, 61 insertions, 20 deletions
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index e7d402446..7334d53ef 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs | |||
@@ -36,7 +36,7 @@ pub use crate::{ | |||
36 | ast::AstNode, | 36 | ast::AstNode, |
37 | syntax_error::{SyntaxError, SyntaxErrorKind, Location}, | 37 | syntax_error::{SyntaxError, SyntaxErrorKind, Location}, |
38 | syntax_text::SyntaxText, | 38 | syntax_text::SyntaxText, |
39 | syntax_node::{Direction, SyntaxNode, WalkEvent, TreeArc}, | 39 | syntax_node::{Direction, SyntaxNode, WalkEvent, TreeArc, SyntaxTreeBuilder}, |
40 | ptr::{SyntaxNodePtr, AstPtr}, | 40 | ptr::{SyntaxNodePtr, AstPtr}, |
41 | parsing::{tokenize, Token}, | 41 | parsing::{tokenize, Token}, |
42 | }; | 42 | }; |
diff --git a/crates/ra_syntax/src/parsing/text_tree_sink.rs b/crates/ra_syntax/src/parsing/text_tree_sink.rs index 8c1d78deb..961a91d41 100644 --- a/crates/ra_syntax/src/parsing/text_tree_sink.rs +++ b/crates/ra_syntax/src/parsing/text_tree_sink.rs | |||
@@ -1,13 +1,12 @@ | |||
1 | use std::mem; | 1 | use std::mem; |
2 | 2 | ||
3 | use ra_parser::{TreeSink, ParseError}; | 3 | use ra_parser::{TreeSink, ParseError}; |
4 | use rowan::GreenNodeBuilder; | ||
5 | 4 | ||
6 | use crate::{ | 5 | use crate::{ |
7 | SmolStr, SyntaxError, SyntaxErrorKind, TextUnit, TextRange, | 6 | SmolStr, SyntaxError, TextUnit, TextRange, SyntaxTreeBuilder, |
8 | SyntaxKind::{self, *}, | 7 | SyntaxKind::{self, *}, |
9 | parsing::Token, | 8 | parsing::Token, |
10 | syntax_node::{GreenNode, RaTypes}, | 9 | syntax_node::GreenNode, |
11 | }; | 10 | }; |
12 | 11 | ||
13 | /// Bridges the parser with our specific syntax tree representation. | 12 | /// Bridges the parser with our specific syntax tree representation. |
@@ -19,8 +18,7 @@ pub(crate) struct TextTreeSink<'a> { | |||
19 | text_pos: TextUnit, | 18 | text_pos: TextUnit, |
20 | token_pos: usize, | 19 | token_pos: usize, |
21 | state: State, | 20 | state: State, |
22 | errors: Vec<SyntaxError>, | 21 | inner: SyntaxTreeBuilder, |
23 | inner: GreenNodeBuilder<RaTypes>, | ||
24 | } | 22 | } |
25 | 23 | ||
26 | enum State { | 24 | enum State { |
@@ -33,7 +31,7 @@ impl<'a> TreeSink for TextTreeSink<'a> { | |||
33 | fn leaf(&mut self, kind: SyntaxKind, n_tokens: u8) { | 31 | fn leaf(&mut self, kind: SyntaxKind, n_tokens: u8) { |
34 | match mem::replace(&mut self.state, State::Normal) { | 32 | match mem::replace(&mut self.state, State::Normal) { |
35 | State::PendingStart => unreachable!(), | 33 | State::PendingStart => unreachable!(), |
36 | State::PendingFinish => self.inner.finish_internal(), | 34 | State::PendingFinish => self.inner.finish_branch(), |
37 | State::Normal => (), | 35 | State::Normal => (), |
38 | } | 36 | } |
39 | self.eat_trivias(); | 37 | self.eat_trivias(); |
@@ -48,12 +46,12 @@ impl<'a> TreeSink for TextTreeSink<'a> { | |||
48 | fn start_branch(&mut self, kind: SyntaxKind) { | 46 | fn start_branch(&mut self, kind: SyntaxKind) { |
49 | match mem::replace(&mut self.state, State::Normal) { | 47 | match mem::replace(&mut self.state, State::Normal) { |
50 | State::PendingStart => { | 48 | State::PendingStart => { |
51 | self.inner.start_internal(kind); | 49 | self.inner.start_branch(kind); |
52 | // No need to attach trivias to previous node: there is no | 50 | // No need to attach trivias to previous node: there is no |
53 | // previous node. | 51 | // previous node. |
54 | return; | 52 | return; |
55 | } | 53 | } |
56 | State::PendingFinish => self.inner.finish_internal(), | 54 | State::PendingFinish => self.inner.finish_branch(), |
57 | State::Normal => (), | 55 | State::Normal => (), |
58 | } | 56 | } |
59 | 57 | ||
@@ -73,21 +71,20 @@ impl<'a> TreeSink for TextTreeSink<'a> { | |||
73 | n_attached_trivias(kind, leading_trivias) | 71 | n_attached_trivias(kind, leading_trivias) |
74 | }; | 72 | }; |
75 | self.eat_n_trivias(n_trivias - n_attached_trivias); | 73 | self.eat_n_trivias(n_trivias - n_attached_trivias); |
76 | self.inner.start_internal(kind); | 74 | self.inner.start_branch(kind); |
77 | self.eat_n_trivias(n_attached_trivias); | 75 | self.eat_n_trivias(n_attached_trivias); |
78 | } | 76 | } |
79 | 77 | ||
80 | fn finish_branch(&mut self) { | 78 | fn finish_branch(&mut self) { |
81 | match mem::replace(&mut self.state, State::PendingFinish) { | 79 | match mem::replace(&mut self.state, State::PendingFinish) { |
82 | State::PendingStart => unreachable!(), | 80 | State::PendingStart => unreachable!(), |
83 | State::PendingFinish => self.inner.finish_internal(), | 81 | State::PendingFinish => self.inner.finish_branch(), |
84 | State::Normal => (), | 82 | State::Normal => (), |
85 | } | 83 | } |
86 | } | 84 | } |
87 | 85 | ||
88 | fn error(&mut self, error: ParseError) { | 86 | fn error(&mut self, error: ParseError) { |
89 | let error = SyntaxError::new(SyntaxErrorKind::ParseError(error), self.text_pos); | 87 | self.inner.error(error, self.text_pos) |
90 | self.errors.push(error) | ||
91 | } | 88 | } |
92 | } | 89 | } |
93 | 90 | ||
@@ -99,8 +96,7 @@ impl<'a> TextTreeSink<'a> { | |||
99 | text_pos: 0.into(), | 96 | text_pos: 0.into(), |
100 | token_pos: 0, | 97 | token_pos: 0, |
101 | state: State::PendingStart, | 98 | state: State::PendingStart, |
102 | errors: Vec::new(), | 99 | inner: SyntaxTreeBuilder::default(), |
103 | inner: GreenNodeBuilder::new(), | ||
104 | } | 100 | } |
105 | } | 101 | } |
106 | 102 | ||
@@ -108,12 +104,12 @@ impl<'a> TextTreeSink<'a> { | |||
108 | match mem::replace(&mut self.state, State::Normal) { | 104 | match mem::replace(&mut self.state, State::Normal) { |
109 | State::PendingFinish => { | 105 | State::PendingFinish => { |
110 | self.eat_trivias(); | 106 | self.eat_trivias(); |
111 | self.inner.finish_internal() | 107 | self.inner.finish_branch() |
112 | } | 108 | } |
113 | State::PendingStart | State::Normal => unreachable!(), | 109 | State::PendingStart | State::Normal => unreachable!(), |
114 | } | 110 | } |
115 | 111 | ||
116 | (self.inner.finish(), self.errors) | 112 | self.inner.finish_raw() |
117 | } | 113 | } |
118 | 114 | ||
119 | fn eat_trivias(&mut self) { | 115 | fn eat_trivias(&mut self) { |
diff --git a/crates/ra_syntax/src/syntax_node.rs b/crates/ra_syntax/src/syntax_node.rs index 4d54ae614..e5b4cdb11 100644 --- a/crates/ra_syntax/src/syntax_node.rs +++ b/crates/ra_syntax/src/syntax_node.rs | |||
@@ -11,11 +11,12 @@ use std::{ | |||
11 | borrow::Borrow, | 11 | borrow::Borrow, |
12 | }; | 12 | }; |
13 | 13 | ||
14 | use rowan::{Types, TransparentNewType}; | 14 | use ra_parser::ParseError; |
15 | use rowan::{Types, TransparentNewType, GreenNodeBuilder}; | ||
15 | 16 | ||
16 | use crate::{ | 17 | use crate::{ |
17 | SmolStr, SyntaxKind, TextRange, SyntaxText, SourceFile, AstNode, | 18 | SmolStr, SyntaxKind, TextUnit, TextRange, SyntaxText, SourceFile, AstNode, |
18 | syntax_error::SyntaxError, | 19 | syntax_error::{SyntaxError, SyntaxErrorKind}, |
19 | }; | 20 | }; |
20 | 21 | ||
21 | pub use rowan::WalkEvent; | 22 | pub use rowan::WalkEvent; |
@@ -276,3 +277,47 @@ fn has_short_text(kind: SyntaxKind) -> bool { | |||
276 | _ => false, | 277 | _ => false, |
277 | } | 278 | } |
278 | } | 279 | } |
280 | |||
281 | pub struct SyntaxTreeBuilder { | ||
282 | errors: Vec<SyntaxError>, | ||
283 | inner: GreenNodeBuilder<RaTypes>, | ||
284 | } | ||
285 | |||
286 | impl Default for SyntaxTreeBuilder { | ||
287 | fn default() -> SyntaxTreeBuilder { | ||
288 | SyntaxTreeBuilder { errors: Vec::new(), inner: GreenNodeBuilder::new() } | ||
289 | } | ||
290 | } | ||
291 | |||
292 | impl SyntaxTreeBuilder { | ||
293 | pub(crate) fn finish_raw(self) -> (GreenNode, Vec<SyntaxError>) { | ||
294 | let green = self.inner.finish(); | ||
295 | (green, self.errors) | ||
296 | } | ||
297 | |||
298 | pub fn finish(self) -> TreeArc<SyntaxNode> { | ||
299 | let (green, errors) = self.finish_raw(); | ||
300 | let node = SyntaxNode::new(green, errors); | ||
301 | if cfg!(debug_assertions) { | ||
302 | crate::validation::validate_block_structure(&node); | ||
303 | } | ||
304 | node | ||
305 | } | ||
306 | |||
307 | pub fn leaf(&mut self, kind: SyntaxKind, text: SmolStr) { | ||
308 | self.inner.leaf(kind, text) | ||
309 | } | ||
310 | |||
311 | pub fn start_branch(&mut self, kind: SyntaxKind) { | ||
312 | self.inner.start_internal(kind) | ||
313 | } | ||
314 | |||
315 | pub fn finish_branch(&mut self) { | ||
316 | self.inner.finish_internal() | ||
317 | } | ||
318 | |||
319 | pub fn error(&mut self, error: ParseError, text_pos: TextUnit) { | ||
320 | let error = SyntaxError::new(SyntaxErrorKind::ParseError(error), text_pos); | ||
321 | self.errors.push(error) | ||
322 | } | ||
323 | } | ||