mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 13:48:50 +00:00
more incremental work
This commit is contained in:
parent
19d933ba38
commit
da329c2e53
1 changed files with 41 additions and 8 deletions
|
@ -62,29 +62,35 @@ pub struct File {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl File {
|
impl File {
|
||||||
fn new(root: GreenNode, errors: Vec<SyntaxError>) -> File {
|
fn new(green: GreenNode, errors: Vec<SyntaxError>) -> File {
|
||||||
let root = SyntaxRoot::new(root, errors);
|
let root = SyntaxRoot::new(green, errors);
|
||||||
let root = SyntaxNode::new_owned(root);
|
let root = SyntaxNode::new_owned(root);
|
||||||
validate_block_structure(root.borrowed());
|
validate_block_structure(root.borrowed());
|
||||||
File { root }
|
File { root }
|
||||||
}
|
}
|
||||||
pub fn parse(text: &str) -> File {
|
pub fn parse(text: &str) -> File {
|
||||||
let tokens = tokenize(&text);
|
let tokens = tokenize(&text);
|
||||||
let (root, errors) = parser_impl::parse::<yellow::GreenBuilder>(text, &tokens);
|
let (green, errors) = parser_impl::parse::<yellow::GreenBuilder>(text, &tokens);
|
||||||
File::new(root, errors)
|
File::new(green, errors)
|
||||||
}
|
}
|
||||||
pub fn reparse(&self, edit: &AtomEdit) -> File {
|
pub fn reparse(&self, edit: &AtomEdit) -> File {
|
||||||
self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit))
|
self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit))
|
||||||
}
|
}
|
||||||
fn incremental_reparse(&self, edit: &AtomEdit) -> Option<File> {
|
fn incremental_reparse(&self, edit: &AtomEdit) -> Option<File> {
|
||||||
let (node, reparser) = find_reparsable_node(self.syntax(), edit.delete)?;
|
let (node, reparser) = find_reparsable_node(self.syntax(), edit.delete)?;
|
||||||
|
let text = replace_range(
|
||||||
|
node.text(),
|
||||||
|
edit.delete - node.range().start(),
|
||||||
|
&edit.insert,
|
||||||
|
);
|
||||||
|
let tokens = tokenize(&text);
|
||||||
|
if !is_balanced(&tokens) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
fn full_reparse(&self, edit: &AtomEdit) -> File {
|
fn full_reparse(&self, edit: &AtomEdit) -> File {
|
||||||
let start = u32::from(edit.delete.start()) as usize;
|
let text = replace_range(self.syntax().text(), edit.delete, &edit.insert);
|
||||||
let end = u32::from(edit.delete.end()) as usize;
|
|
||||||
let mut text = self.syntax().text();
|
|
||||||
text.replace_range(start..end, &edit.insert);
|
|
||||||
File::parse(&text)
|
File::parse(&text)
|
||||||
}
|
}
|
||||||
pub fn ast(&self) -> ast::Root {
|
pub fn ast(&self) -> ast::Root {
|
||||||
|
@ -166,3 +172,30 @@ fn find_reparsable_node(node: SyntaxNodeRef, range: TextRange) -> Option<(Syntax
|
||||||
Some(res)
|
Some(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn replace_range(mut text: String, range: TextRange, replace_with: &str) -> String {
|
||||||
|
let start = u32::from(range.start()) as usize;
|
||||||
|
let end = u32::from(range.end()) as usize;
|
||||||
|
text.replace_range(start..end, replace_with);
|
||||||
|
text
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_balanced(tokens: &[Token]) -> bool {
|
||||||
|
if tokens.len() == 0
|
||||||
|
|| tokens.first().unwrap().kind != L_CURLY
|
||||||
|
|| tokens.last().unwrap().kind != R_CURLY {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
let mut balance = 0usize;
|
||||||
|
for t in tokens.iter() {
|
||||||
|
match t.kind {
|
||||||
|
L_CURLY => balance += 1,
|
||||||
|
R_CURLY => balance = match balance.checked_sub(1) {
|
||||||
|
Some(b) => b,
|
||||||
|
None => return false,
|
||||||
|
},
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
balance == 0
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue