aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/parsing/reparsing.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/parsing/reparsing.rs')
-rw-r--r--crates/ra_syntax/src/parsing/reparsing.rs27
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 {
162fn merge_errors( 162fn 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