aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/parser_impl
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/parser_impl')
-rw-r--r--crates/ra_syntax/src/parser_impl/event.rs210
-rw-r--r--crates/ra_syntax/src/parser_impl/mod.rs25
2 files changed, 160 insertions, 75 deletions
diff --git a/crates/ra_syntax/src/parser_impl/event.rs b/crates/ra_syntax/src/parser_impl/event.rs
index 9fd56b996..95e5ce4cc 100644
--- a/crates/ra_syntax/src/parser_impl/event.rs
+++ b/crates/ra_syntax/src/parser_impl/event.rs
@@ -9,9 +9,10 @@
9//! this stream to a real tree. 9//! this stream to a real tree.
10use std::mem; 10use std::mem;
11use { 11use {
12 TextUnit, TextRange, SmolStr,
12 lexer::Token, 13 lexer::Token,
13 parser_impl::Sink, 14 parser_impl::Sink,
14 SyntaxKind::{self, TOMBSTONE}, 15 SyntaxKind::{self, *},
15}; 16};
16 17
17 18
@@ -78,77 +79,162 @@ pub(crate) enum Event {
78 }, 79 },
79} 80}
80 81
82pub(super) struct EventProcessor<'a, S: Sink> {
83 sink: S,
84 text_pos: TextUnit,
85 text: &'a str,
86 token_pos: usize,
87 tokens: &'a [Token],
88 events: &'a mut [Event],
89}
81 90
82pub(super) fn process<'a, S: Sink<'a>>(builder: &mut S, tokens: &[Token], mut events: Vec<Event>) { 91impl<'a, S: Sink> EventProcessor<'a, S> {
83 fn tombstone() -> Event { 92 pub(super) fn new(sink: S, text: &'a str, tokens: &'a[Token], events: &'a mut [Event]) -> EventProcessor<'a, S> {
84 Event::Start { kind: TOMBSTONE, forward_parent: None } 93 EventProcessor {
94 sink,
95 text_pos: 0.into(),
96 text,
97 token_pos: 0,
98 tokens,
99 events
100 }
85 } 101 }
86 let eat_ws = |idx: &mut usize, builder: &mut S| { 102
87 while let Some(token) = tokens.get(*idx) { 103 pub(super) fn process(mut self) -> S {
88 if !token.kind.is_trivia() { 104 fn tombstone() -> Event {
89 break; 105 Event::Start { kind: TOMBSTONE, forward_parent: None }
90 }
91 builder.leaf(token.kind, token.len);
92 *idx += 1
93 } 106 }
94 }; 107 let mut forward_parents = Vec::new();
95 108
96 let events: &mut [Event] = &mut events; 109 for i in 0..self.events.len() {
97 let mut depth = 0; 110 match mem::replace(&mut self.events[i], tombstone()) {
98 let mut forward_parents = Vec::new(); 111 Event::Start {
99 let mut next_tok_idx = 0; 112 kind: TOMBSTONE, ..
100 for i in 0..events.len() { 113 } => (),
101 match mem::replace(&mut events[i], tombstone()) { 114
102 Event::Start { 115 Event::Start { kind, forward_parent } => {
103 kind: TOMBSTONE, .. 116 forward_parents.push(kind);
104 } => (), 117 let mut idx = i;
105 118 let mut fp = forward_parent;
106 Event::Start { kind, forward_parent } => { 119 while let Some(fwd) = fp {
107 forward_parents.push(kind); 120 idx += fwd as usize;
108 let mut idx = i; 121 fp = match mem::replace(&mut self.events[idx], tombstone()) {
109 let mut fp = forward_parent; 122 Event::Start {
110 while let Some(fwd) = fp { 123 kind,
111 idx += fwd as usize; 124 forward_parent,
112 fp = match mem::replace(&mut events[idx], tombstone()) { 125 } => {
113 Event::Start { 126 forward_parents.push(kind);
114 kind, 127 forward_parent
115 forward_parent, 128 },
116 } => { 129 _ => unreachable!(),
117 forward_parents.push(kind); 130 };
118 forward_parent 131 }
119 }, 132 for kind in forward_parents.drain(..).rev() {
120 _ => unreachable!(), 133 self.start(kind);
121 };
122 }
123 for kind in forward_parents.drain(..).rev() {
124 if depth > 0 {
125 eat_ws(&mut next_tok_idx, builder);
126 } 134 }
127 depth += 1;
128 builder.start_internal(kind);
129 } 135 }
130 } 136 Event::Finish => {
131 Event::Finish => { 137 let last = i == self.events.len() - 1;
132 depth -= 1; 138 self.finish(last);
133 if depth == 0 { 139 },
134 eat_ws(&mut next_tok_idx, builder); 140 Event::Token { kind, n_raw_tokens } => {
141 self.eat_ws();
142 let n_raw_tokens = n_raw_tokens as usize;
143 let len = self.tokens[self.token_pos..self.token_pos + n_raw_tokens]
144 .iter()
145 .map(|it| it.len)
146 .sum::<TextUnit>();
147 self.leaf(kind, len, n_raw_tokens);
135 } 148 }
149 Event::Error { msg } => self.sink.error(msg, self.text_pos),
150 }
151 }
152 self.sink
153 }
154
155 fn start(&mut self, kind: SyntaxKind) {
156 if kind == ROOT {
157 self.sink.start_internal(kind);
158 return;
159 }
160 let n_trivias = self.tokens[self.token_pos..]
161 .iter()
162 .take_while(|it| it.kind.is_trivia())
163 .count();
164 let leading_trivias = &self.tokens[self.token_pos..self.token_pos + n_trivias];
165 let mut trivia_end = self.text_pos + leading_trivias
166 .iter()
167 .map(|it| it.len)
168 .sum::<TextUnit>();
169
170 let n_attached_trivias = {
171 let leading_trivias = leading_trivias.iter().rev()
172 .map(|it| {
173 let next_end = trivia_end - it.len;
174 let range = TextRange::from_to(next_end, trivia_end);
175 trivia_end = next_end;
176 (it.kind, &self.text[range])
177 });
178 n_attached_trivias(kind, leading_trivias)
179 };
180 self.eat_n_trivias(n_trivias - n_attached_trivias);
181 self.sink.start_internal(kind);
182 self.eat_n_trivias(n_attached_trivias);
183 }
136 184
137 builder.finish_internal(); 185 fn finish(&mut self, last: bool) {
186 if last {
187 self.eat_ws()
188 }
189 self.sink.finish_internal();
190 }
191
192 fn eat_ws(&mut self) {
193 while let Some(&token) = self.tokens.get(self.token_pos) {
194 if !token.kind.is_trivia() {
195 break;
138 } 196 }
139 Event::Token { 197 self.leaf(token.kind, token.len, 1);
140 kind, 198 }
141 mut n_raw_tokens, 199 }
142 } => { 200
143 eat_ws(&mut next_tok_idx, builder); 201 fn eat_n_trivias(&mut self, n: usize) {
144 let mut len = 0.into(); 202 for _ in 0..n {
145 for _ in 0..n_raw_tokens { 203 let token = self.tokens[self.token_pos];
146 len += tokens[next_tok_idx].len; 204 assert!(token.kind.is_trivia());
147 next_tok_idx += 1; 205 self.leaf(token.kind, token.len, 1);
206 }
207 }
208
209 fn leaf(&mut self, kind: SyntaxKind, len: TextUnit, n_tokens: usize) {
210 let range = TextRange::offset_len(self.text_pos, len);
211 let text: SmolStr = self.text[range].into();
212 self.text_pos += len;
213 self.token_pos += n_tokens;
214 self.sink.leaf(kind, text);
215 }
216}
217
218fn n_attached_trivias<'a>(kind: SyntaxKind, trivias: impl Iterator<Item=(SyntaxKind, &'a str)>) -> usize {
219 match kind {
220 STRUCT_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | MODULE => {
221 let mut res = 0;
222 for (i, (kind, text)) in trivias.enumerate() {
223 match kind {
224 WHITESPACE => {
225 if text.contains("\n\n") {
226 break;
227 }
228 }
229 COMMENT => {
230 res = i + 1;
231 }
232 _ => (),
148 } 233 }
149 builder.leaf(kind, len);
150 } 234 }
151 Event::Error { msg } => builder.error(msg), 235 res
152 } 236 }
237 _ => 0,
153 } 238 }
239
154} 240}
diff --git a/crates/ra_syntax/src/parser_impl/mod.rs b/crates/ra_syntax/src/parser_impl/mod.rs
index b343b404f..8d74cef0e 100644
--- a/crates/ra_syntax/src/parser_impl/mod.rs
+++ b/crates/ra_syntax/src/parser_impl/mod.rs
@@ -4,45 +4,44 @@ mod input;
4use std::cell::Cell; 4use std::cell::Cell;
5 5
6use { 6use {
7 TextUnit, SmolStr,
7 lexer::Token, 8 lexer::Token,
8 parser_api::Parser, 9 parser_api::Parser,
9 parser_impl::{ 10 parser_impl::{
10 event::{process, Event}, 11 event::{EventProcessor, Event},
11 input::{InputPosition, ParserInput}, 12 input::{InputPosition, ParserInput},
12 }, 13 },
13 TextUnit,
14}; 14};
15 15
16use SyntaxKind::{self, EOF, TOMBSTONE}; 16use SyntaxKind::{self, EOF, TOMBSTONE};
17 17
18pub(crate) trait Sink<'a> { 18pub(crate) trait Sink {
19 type Tree; 19 type Tree;
20 20
21 fn new(text: &'a str) -> Self; 21 fn leaf(&mut self, kind: SyntaxKind, text: SmolStr);
22
23 fn leaf(&mut self, kind: SyntaxKind, len: TextUnit);
24 fn start_internal(&mut self, kind: SyntaxKind); 22 fn start_internal(&mut self, kind: SyntaxKind);
25 fn finish_internal(&mut self); 23 fn finish_internal(&mut self);
26 fn error(&mut self, err: String); 24 fn error(&mut self, message: String, offset: TextUnit);
27 fn finish(self) -> Self::Tree; 25 fn finish(self) -> Self::Tree;
28} 26}
29 27
30/// Parse a sequence of tokens into the representative node tree 28/// Parse a sequence of tokens into the representative node tree
31pub(crate) fn parse_with<'a, S: Sink<'a>>( 29pub(crate) fn parse_with<S: Sink>(
32 text: &'a str, 30 sink: S,
31 text: &str,
33 tokens: &[Token], 32 tokens: &[Token],
34 parser: fn(&mut Parser), 33 parser: fn(&mut Parser),
35) -> S::Tree { 34) -> S::Tree {
36 let events = { 35 let mut events = {
37 let input = input::ParserInput::new(text, tokens); 36 let input = input::ParserInput::new(text, tokens);
38 let parser_impl = ParserImpl::new(&input); 37 let parser_impl = ParserImpl::new(&input);
39 let mut parser_api = Parser(parser_impl); 38 let mut parser_api = Parser(parser_impl);
40 parser(&mut parser_api); 39 parser(&mut parser_api);
41 parser_api.0.into_events() 40 parser_api.0.into_events()
42 }; 41 };
43 let mut sink = S::new(text); 42 EventProcessor::new(sink, text, tokens, &mut events)
44 process(&mut sink, tokens, events); 43 .process()
45 sink.finish() 44 .finish()
46} 45}
47 46
48/// Implementation details of `Parser`, extracted 47/// Implementation details of `Parser`, extracted