start incremental reparse

This commit is contained in:
Aleksey Kladov 2018-08-25 13:17:54 +03:00
parent 32c8ea9307
commit fed5727ea2
5 changed files with 46 additions and 4 deletions

View file

@ -50,7 +50,11 @@ pub use {
yellow::{SyntaxNode, SyntaxNodeRef, OwnedRoot, RefRoot, TreeRoot, SyntaxError},
};
use yellow::{GreenNode, SyntaxRoot};
use {
SyntaxKind::*,
yellow::{GreenNode, SyntaxRoot},
parser_api::Parser,
};
#[derive(Clone, Debug)]
pub struct File {
@ -69,6 +73,22 @@ impl File {
let (root, errors) = parser_impl::parse::<yellow::GreenBuilder>(text, &tokens);
File::new(root, errors)
}
pub fn reparse(&self, edit: &AtomEdit) -> File {
self.incremental_reparse(edit).unwrap_or_else(|| {
self.full_reparse(edit)
})
}
fn incremental_reparse(&self, edit: &AtomEdit) -> Option<File> {
let (node, reparser) = find_reparsable_node(self.syntax(), edit.delete)?;
None
}
fn full_reparse(&self, edit: &AtomEdit) -> File {
let start = u32::from(edit.delete.start()) as usize;
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)
}
pub fn ast(&self) -> ast::Root {
ast::Root::cast(self.syntax()).unwrap()
}
@ -132,3 +152,19 @@ impl AtomEdit {
AtomEdit::replace(TextRange::offset_len(offset, 0.into()), text)
}
}
fn find_reparsable_node(node: SyntaxNodeRef, range: TextRange) -> Option<(SyntaxNodeRef, fn(&mut Parser))> {
let node = algo::find_covering_node(node, range);
return algo::ancestors(node)
.filter_map(|node| reparser(node).map(|r| (node, r)))
.next();
fn reparser(node: SyntaxNodeRef) -> Option<fn(&mut Parser)> {
let res = match node.kind() {
BLOCK => grammar::block,
NAMED_FIELD_DEF_LIST => grammar::named_field_def_list,
_ => return None,
};
Some(res)
}
}