diff options
-rw-r--r-- | crates/ra_editor/src/extend_selection.rs | 16 | ||||
-rw-r--r-- | crates/ra_syntax/src/parser_impl/event.rs | 93 | ||||
-rw-r--r-- | crates/ra_syntax/tests/data/parser/err/0025_nope.txt | 6 | ||||
-rw-r--r-- | crates/ra_syntax/tests/data/parser/ok/0033_label_break.txt | 6 |
4 files changed, 97 insertions, 24 deletions
diff --git a/crates/ra_editor/src/extend_selection.rs b/crates/ra_editor/src/extend_selection.rs index 6977900e6..e12346cb6 100644 --- a/crates/ra_editor/src/extend_selection.rs +++ b/crates/ra_editor/src/extend_selection.rs | |||
@@ -154,6 +154,22 @@ impl S { | |||
154 | } | 154 | } |
155 | 155 | ||
156 | #[test] | 156 | #[test] |
157 | fn test_extend_selection_doc_comments() { | ||
158 | do_check( | ||
159 | r#" | ||
160 | struct A; | ||
161 | |||
162 | /// bla | ||
163 | /// bla | ||
164 | struct B { | ||
165 | <|> | ||
166 | } | ||
167 | "#, | ||
168 | &["\n \n", "{\n \n}", "/// bla\n/// bla\nstruct B {\n \n}"] | ||
169 | ) | ||
170 | } | ||
171 | |||
172 | #[test] | ||
157 | fn test_extend_selection_comments() { | 173 | fn test_extend_selection_comments() { |
158 | do_check( | 174 | do_check( |
159 | r#" | 175 | r#" |
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 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0025_nope.txt b/crates/ra_syntax/tests/data/parser/err/0025_nope.txt index c30b8585f..6879c8d0a 100644 --- a/crates/ra_syntax/tests/data/parser/err/0025_nope.txt +++ b/crates/ra_syntax/tests/data/parser/err/0025_nope.txt | |||
@@ -137,9 +137,9 @@ ROOT@[0; 575) | |||
137 | BLOCK@[306; 459) | 137 | BLOCK@[306; 459) |
138 | L_CURLY@[306; 307) | 138 | L_CURLY@[306; 307) |
139 | WHITESPACE@[307; 316) | 139 | WHITESPACE@[307; 316) |
140 | COMMENT@[316; 329) | 140 | ENUM_DEF@[316; 453) |
141 | WHITESPACE@[329; 338) | 141 | COMMENT@[316; 329) |
142 | ENUM_DEF@[338; 453) | 142 | WHITESPACE@[329; 338) |
143 | ENUM_KW@[338; 342) | 143 | ENUM_KW@[338; 342) |
144 | WHITESPACE@[342; 343) | 144 | WHITESPACE@[342; 343) |
145 | NAME@[343; 348) | 145 | NAME@[343; 348) |
diff --git a/crates/ra_syntax/tests/data/parser/ok/0033_label_break.txt b/crates/ra_syntax/tests/data/parser/ok/0033_label_break.txt index 6abb9234c..201eca644 100644 --- a/crates/ra_syntax/tests/data/parser/ok/0033_label_break.txt +++ b/crates/ra_syntax/tests/data/parser/ok/0033_label_break.txt | |||
@@ -1,7 +1,7 @@ | |||
1 | ROOT@[0; 506) | 1 | ROOT@[0; 506) |
2 | COMMENT@[0; 33) | 2 | FN_DEF@[0; 505) |
3 | WHITESPACE@[33; 34) | 3 | COMMENT@[0; 33) |
4 | FN_DEF@[34; 505) | 4 | WHITESPACE@[33; 34) |
5 | FN_KW@[34; 36) | 5 | FN_KW@[34; 36) |
6 | WHITESPACE@[36; 37) | 6 | WHITESPACE@[36; 37) |
7 | NAME@[37; 41) | 7 | NAME@[37; 41) |