diff options
author | Aleksey Kladov <[email protected]> | 2018-10-08 15:33:13 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-10-08 15:36:38 +0100 |
commit | a05e09e9c514878148ddf26aa76d6b9183583d0f (patch) | |
tree | f9d1d3baaa8aead60d356f0e60ca8f5e0fdcd308 /crates/ra_syntax/src/parser_impl/event.rs | |
parent | b642e6c6451b21d9b3fc719472a1802ea70a83d8 (diff) |
Attach comments smartly
Diffstat (limited to 'crates/ra_syntax/src/parser_impl/event.rs')
-rw-r--r-- | crates/ra_syntax/src/parser_impl/event.rs | 93 |
1 files changed, 75 insertions, 18 deletions
diff --git a/crates/ra_syntax/src/parser_impl/event.rs b/crates/ra_syntax/src/parser_impl/event.rs index 4e6e25cfb..95e5ce4cc 100644 --- a/crates/ra_syntax/src/parser_impl/event.rs +++ b/crates/ra_syntax/src/parser_impl/event.rs | |||
@@ -12,7 +12,7 @@ use { | |||
12 | TextUnit, TextRange, SmolStr, | 12 | TextUnit, TextRange, SmolStr, |
13 | lexer::Token, | 13 | lexer::Token, |
14 | parser_impl::Sink, | 14 | parser_impl::Sink, |
15 | SyntaxKind::{self, TOMBSTONE}, | 15 | SyntaxKind::{self, *}, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | 18 | ||
@@ -104,7 +104,6 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
104 | fn tombstone() -> Event { | 104 | fn tombstone() -> Event { |
105 | Event::Start { kind: TOMBSTONE, forward_parent: None } | 105 | Event::Start { kind: TOMBSTONE, forward_parent: None } |
106 | } | 106 | } |
107 | let mut depth = 0; | ||
108 | let mut forward_parents = Vec::new(); | 107 | let mut forward_parents = Vec::new(); |
109 | 108 | ||
110 | for i in 0..self.events.len() { | 109 | for i in 0..self.events.len() { |
@@ -131,25 +130,14 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
131 | }; | 130 | }; |
132 | } | 131 | } |
133 | for kind in forward_parents.drain(..).rev() { | 132 | for kind in forward_parents.drain(..).rev() { |
134 | if depth > 0 { | 133 | self.start(kind); |
135 | self.eat_ws(); | ||
136 | } | ||
137 | depth += 1; | ||
138 | self.sink.start_internal(kind); | ||
139 | } | 134 | } |
140 | } | 135 | } |
141 | Event::Finish => { | 136 | Event::Finish => { |
142 | depth -= 1; | 137 | let last = i == self.events.len() - 1; |
143 | if depth == 0 { | 138 | self.finish(last); |
144 | self.eat_ws(); | 139 | }, |
145 | } | 140 | Event::Token { kind, n_raw_tokens } => { |
146 | |||
147 | self.sink.finish_internal(); | ||
148 | } | ||
149 | Event::Token { | ||
150 | kind, | ||
151 | n_raw_tokens, | ||
152 | } => { | ||
153 | self.eat_ws(); | 141 | self.eat_ws(); |
154 | let n_raw_tokens = n_raw_tokens as usize; | 142 | let n_raw_tokens = n_raw_tokens as usize; |
155 | let len = self.tokens[self.token_pos..self.token_pos + n_raw_tokens] | 143 | let len = self.tokens[self.token_pos..self.token_pos + n_raw_tokens] |
@@ -164,6 +152,43 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
164 | self.sink | 152 | self.sink |
165 | } | 153 | } |
166 | 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 | } | ||
184 | |||
185 | fn finish(&mut self, last: bool) { | ||
186 | if last { | ||
187 | self.eat_ws() | ||
188 | } | ||
189 | self.sink.finish_internal(); | ||
190 | } | ||
191 | |||
167 | fn eat_ws(&mut self) { | 192 | fn eat_ws(&mut self) { |
168 | while let Some(&token) = self.tokens.get(self.token_pos) { | 193 | while let Some(&token) = self.tokens.get(self.token_pos) { |
169 | if !token.kind.is_trivia() { | 194 | if !token.kind.is_trivia() { |
@@ -173,6 +198,14 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
173 | } | 198 | } |
174 | } | 199 | } |
175 | 200 | ||
201 | fn eat_n_trivias(&mut self, n: usize) { | ||
202 | for _ in 0..n { | ||
203 | let token = self.tokens[self.token_pos]; | ||
204 | assert!(token.kind.is_trivia()); | ||
205 | self.leaf(token.kind, token.len, 1); | ||
206 | } | ||
207 | } | ||
208 | |||
176 | fn leaf(&mut self, kind: SyntaxKind, len: TextUnit, n_tokens: usize) { | 209 | fn leaf(&mut self, kind: SyntaxKind, len: TextUnit, n_tokens: usize) { |
177 | let range = TextRange::offset_len(self.text_pos, len); | 210 | let range = TextRange::offset_len(self.text_pos, len); |
178 | let text: SmolStr = self.text[range].into(); | 211 | let text: SmolStr = self.text[range].into(); |
@@ -181,3 +214,27 @@ impl<'a, S: Sink> EventProcessor<'a, S> { | |||
181 | self.sink.leaf(kind, text); | 214 | self.sink.leaf(kind, text); |
182 | } | 215 | } |
183 | } | 216 | } |
217 | |||
218 | fn 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 | _ => (), | ||
233 | } | ||
234 | } | ||
235 | res | ||
236 | } | ||
237 | _ => 0, | ||
238 | } | ||
239 | |||
240 | } | ||