diff options
Diffstat (limited to 'crates/ra_syntax/src/parsing/reparsing.rs')
-rw-r--r-- | crates/ra_syntax/src/parsing/reparsing.rs | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/crates/ra_syntax/src/parsing/reparsing.rs b/crates/ra_syntax/src/parsing/reparsing.rs index a86da0675..41a355ec7 100644 --- a/crates/ra_syntax/src/parsing/reparsing.rs +++ b/crates/ra_syntax/src/parsing/reparsing.rs | |||
@@ -87,7 +87,7 @@ fn reparse_block<'node>( | |||
87 | edit: &AtomTextEdit, | 87 | edit: &AtomTextEdit, |
88 | ) -> Option<(GreenNode, Vec<SyntaxError>, TextRange)> { | 88 | ) -> Option<(GreenNode, Vec<SyntaxError>, TextRange)> { |
89 | let (node, reparser) = find_reparsable_node(root, edit.delete)?; | 89 | let (node, reparser) = find_reparsable_node(root, edit.delete)?; |
90 | let text = get_text_after_edit(node.clone().into(), &edit); | 90 | let text = get_text_after_edit(node.clone().into(), edit); |
91 | 91 | ||
92 | let (tokens, new_lexer_errors) = tokenize(&text); | 92 | let (tokens, new_lexer_errors) = tokenize(&text); |
93 | if !is_balanced(&tokens) { | 93 | if !is_balanced(&tokens) { |
@@ -162,20 +162,27 @@ fn is_balanced(tokens: &[Token]) -> bool { | |||
162 | fn merge_errors( | 162 | fn merge_errors( |
163 | old_errors: Vec<SyntaxError>, | 163 | old_errors: Vec<SyntaxError>, |
164 | new_errors: Vec<SyntaxError>, | 164 | new_errors: Vec<SyntaxError>, |
165 | old_range: TextRange, | 165 | range_before_reparse: TextRange, |
166 | edit: &AtomTextEdit, | 166 | edit: &AtomTextEdit, |
167 | ) -> Vec<SyntaxError> { | 167 | ) -> Vec<SyntaxError> { |
168 | let mut res = Vec::new(); | 168 | let mut res = Vec::new(); |
169 | for e in old_errors { | 169 | |
170 | if e.offset() <= old_range.start() { | 170 | for old_err in old_errors { |
171 | res.push(e) | 171 | let old_err_range = *old_err.range(); |
172 | } else if e.offset() >= old_range.end() { | 172 | // FIXME: make sure that .start() was here previously by a mistake |
173 | res.push(e.add_offset(TextUnit::of_str(&edit.insert), edit.delete.len())); | 173 | if old_err_range.end() <= range_before_reparse.start() { |
174 | res.push(old_err); | ||
175 | } else if old_err_range.start() >= range_before_reparse.end() { | ||
176 | let inserted_len = TextUnit::of_str(&edit.insert); | ||
177 | res.push(old_err.with_range((old_err_range + inserted_len) - edit.delete.len())); | ||
178 | // Note: extra parens are intentional to prevent uint underflow, HWAB (here was a bug) | ||
174 | } | 179 | } |
175 | } | 180 | } |
176 | for e in new_errors { | 181 | res.extend(new_errors.into_iter().map(|new_err| { |
177 | res.push(e.add_offset(old_range.start(), 0.into())); | 182 | // fighting borrow checker with a variable ;) |
178 | } | 183 | let offseted_range = *new_err.range() + range_before_reparse.start(); |
184 | new_err.with_range(offseted_range) | ||
185 | })); | ||
179 | res | 186 | res |
180 | } | 187 | } |
181 | 188 | ||