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

@ -25,7 +25,7 @@ fn expr_no_struct(p: &mut Parser) {
// fn b() { let _ = 1; } // fn b() { let _ = 1; }
// fn c() { 1; 2; } // fn c() { 1; 2; }
// fn d() { 1; 2 } // fn d() { 1; 2 }
pub(super) fn block(p: &mut Parser) { pub(crate) fn block(p: &mut Parser) {
assert!(p.at(L_CURLY)); assert!(p.at(L_CURLY));
let m = p.start(); let m = p.start();
p.bump(); p.bump();

View file

@ -1,10 +1,12 @@
use super::*;
mod consts; mod consts;
mod structs; mod structs;
mod traits; mod traits;
mod use_item; mod use_item;
use super::*;
pub(crate) use self::structs::named_field_def_list;
// test mod_contents // test mod_contents
// fn foo() {} // fn foo() {}
// macro_rules! foo {} // macro_rules! foo {}

View file

@ -82,7 +82,7 @@ fn enum_variant_list(p: &mut Parser) {
m.complete(p, ENUM_VARIANT_LIST); m.complete(p, ENUM_VARIANT_LIST);
} }
fn named_field_def_list(p: &mut Parser) { pub(crate) fn named_field_def_list(p: &mut Parser) {
assert!(p.at(L_CURLY)); assert!(p.at(L_CURLY));
let m = p.start(); let m = p.start();
p.bump(); p.bump();

View file

@ -35,6 +35,10 @@ use {
parser_api::{Marker, CompletedMarker, Parser, TokenSet}, parser_api::{Marker, CompletedMarker, Parser, TokenSet},
SyntaxKind::{self, *}, SyntaxKind::{self, *},
}; };
pub(crate) use self::{
expressions::block,
items::named_field_def_list,
};
pub(crate) fn file(p: &mut Parser) { pub(crate) fn file(p: &mut Parser) {
let file = p.start(); let file = p.start();

View file

@ -50,7 +50,11 @@ pub use {
yellow::{SyntaxNode, SyntaxNodeRef, OwnedRoot, RefRoot, TreeRoot, SyntaxError}, yellow::{SyntaxNode, SyntaxNodeRef, OwnedRoot, RefRoot, TreeRoot, SyntaxError},
}; };
use yellow::{GreenNode, SyntaxRoot}; use {
SyntaxKind::*,
yellow::{GreenNode, SyntaxRoot},
parser_api::Parser,
};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct File { pub struct File {
@ -69,6 +73,22 @@ impl File {
let (root, errors) = parser_impl::parse::<yellow::GreenBuilder>(text, &tokens); let (root, errors) = parser_impl::parse::<yellow::GreenBuilder>(text, &tokens);
File::new(root, errors) 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 { pub fn ast(&self) -> ast::Root {
ast::Root::cast(self.syntax()).unwrap() ast::Root::cast(self.syntax()).unwrap()
} }
@ -132,3 +152,19 @@ impl AtomEdit {
AtomEdit::replace(TextRange::offset_len(offset, 0.into()), text) 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)
}
}