diff options
author | Aleksey Kladov <[email protected]> | 2018-08-25 12:45:17 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-25 12:45:17 +0100 |
commit | c3e5987c433cdd0ea95a6b1057b442f4f0fe1ffc (patch) | |
tree | 1ef2814a3ddc800ef6976aa0459c6b5cf0c3b621 /crates/libsyntax2/src/lib.rs | |
parent | 5211e7d97771aa7f8d7cc99e5131fb3cc71a1627 (diff) |
incremental reparse
Diffstat (limited to 'crates/libsyntax2/src/lib.rs')
-rw-r--r-- | crates/libsyntax2/src/lib.rs | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/crates/libsyntax2/src/lib.rs b/crates/libsyntax2/src/lib.rs index bb060cbae..d43d26c4c 100644 --- a/crates/libsyntax2/src/lib.rs +++ b/crates/libsyntax2/src/lib.rs | |||
@@ -70,13 +70,15 @@ impl File { | |||
70 | } | 70 | } |
71 | pub fn parse(text: &str) -> File { | 71 | pub fn parse(text: &str) -> File { |
72 | let tokens = tokenize(&text); | 72 | let tokens = tokenize(&text); |
73 | let (green, errors) = parser_impl::parse::<yellow::GreenBuilder>(text, &tokens); | 73 | let (green, errors) = parser_impl::parse_with::<yellow::GreenBuilder>( |
74 | text, &tokens, grammar::root, | ||
75 | ); | ||
74 | File::new(green, errors) | 76 | File::new(green, errors) |
75 | } | 77 | } |
76 | pub fn reparse(&self, edit: &AtomEdit) -> File { | 78 | pub fn reparse(&self, edit: &AtomEdit) -> File { |
77 | self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) | 79 | self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) |
78 | } | 80 | } |
79 | fn incremental_reparse(&self, edit: &AtomEdit) -> Option<File> { | 81 | pub fn incremental_reparse(&self, edit: &AtomEdit) -> Option<File> { |
80 | let (node, reparser) = find_reparsable_node(self.syntax(), edit.delete)?; | 82 | let (node, reparser) = find_reparsable_node(self.syntax(), edit.delete)?; |
81 | let text = replace_range( | 83 | let text = replace_range( |
82 | node.text(), | 84 | node.text(), |
@@ -87,7 +89,12 @@ impl File { | |||
87 | if !is_balanced(&tokens) { | 89 | if !is_balanced(&tokens) { |
88 | return None; | 90 | return None; |
89 | } | 91 | } |
90 | None | 92 | let (green, new_errors) = parser_impl::parse_with::<yellow::GreenBuilder>( |
93 | &text, &tokens, reparser, | ||
94 | ); | ||
95 | let green_root = node.replace_with(green); | ||
96 | let errors = merge_errors(self.errors(), new_errors, edit, node.range().start()); | ||
97 | Some(File::new(green_root, errors)) | ||
91 | } | 98 | } |
92 | fn full_reparse(&self, edit: &AtomEdit) -> File { | 99 | fn full_reparse(&self, edit: &AtomEdit) -> File { |
93 | let text = replace_range(self.syntax().text(), edit.delete, &edit.insert); | 100 | let text = replace_range(self.syntax().text(), edit.delete, &edit.insert); |
@@ -173,7 +180,7 @@ fn find_reparsable_node(node: SyntaxNodeRef, range: TextRange) -> Option<(Syntax | |||
173 | } | 180 | } |
174 | } | 181 | } |
175 | 182 | ||
176 | fn replace_range(mut text: String, range: TextRange, replace_with: &str) -> String { | 183 | pub /*(meh)*/ fn replace_range(mut text: String, range: TextRange, replace_with: &str) -> String { |
177 | let start = u32::from(range.start()) as usize; | 184 | let start = u32::from(range.start()) as usize; |
178 | let end = u32::from(range.end()) as usize; | 185 | let end = u32::from(range.end()) as usize; |
179 | text.replace_range(start..end, replace_with); | 186 | text.replace_range(start..end, replace_with); |
@@ -199,3 +206,29 @@ fn is_balanced(tokens: &[Token]) -> bool { | |||
199 | } | 206 | } |
200 | balance == 0 | 207 | balance == 0 |
201 | } | 208 | } |
209 | |||
210 | fn merge_errors( | ||
211 | old_errors: Vec<SyntaxError>, | ||
212 | new_errors: Vec<SyntaxError>, | ||
213 | edit: &AtomEdit, | ||
214 | node_offset: TextUnit, | ||
215 | ) -> Vec<SyntaxError> { | ||
216 | let mut res = Vec::new(); | ||
217 | for e in old_errors { | ||
218 | if e.offset < edit.delete.start() { | ||
219 | res.push(e) | ||
220 | } else if e.offset > edit.delete.end() { | ||
221 | res.push(SyntaxError { | ||
222 | msg: e.msg, | ||
223 | offset: e.offset + TextUnit::of_str(&edit.insert) - edit.delete.len(), | ||
224 | }) | ||
225 | } | ||
226 | } | ||
227 | for e in new_errors { | ||
228 | res.push(SyntaxError { | ||
229 | msg: e.msg, | ||
230 | offset: e.offset + node_offset, | ||
231 | }) | ||
232 | } | ||
233 | res | ||
234 | } | ||