From fed5727ea2669712e5d85502767b5c150203ecfc Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 25 Aug 2018 13:17:54 +0300 Subject: start incremental reparse --- crates/libsyntax2/src/grammar/expressions/mod.rs | 2 +- crates/libsyntax2/src/grammar/items/mod.rs | 4 ++- crates/libsyntax2/src/grammar/items/structs.rs | 2 +- crates/libsyntax2/src/grammar/mod.rs | 4 +++ crates/libsyntax2/src/lib.rs | 38 +++++++++++++++++++++++- 5 files changed, 46 insertions(+), 4 deletions(-) diff --git a/crates/libsyntax2/src/grammar/expressions/mod.rs b/crates/libsyntax2/src/grammar/expressions/mod.rs index 59a0564d9..bd6c84886 100644 --- a/crates/libsyntax2/src/grammar/expressions/mod.rs +++ b/crates/libsyntax2/src/grammar/expressions/mod.rs @@ -25,7 +25,7 @@ fn expr_no_struct(p: &mut Parser) { // fn b() { let _ = 1; } // fn c() { 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)); let m = p.start(); p.bump(); diff --git a/crates/libsyntax2/src/grammar/items/mod.rs b/crates/libsyntax2/src/grammar/items/mod.rs index 206c85280..44ab92c63 100644 --- a/crates/libsyntax2/src/grammar/items/mod.rs +++ b/crates/libsyntax2/src/grammar/items/mod.rs @@ -1,10 +1,12 @@ -use super::*; mod consts; mod structs; mod traits; mod use_item; +use super::*; +pub(crate) use self::structs::named_field_def_list; + // test mod_contents // fn foo() {} // macro_rules! foo {} diff --git a/crates/libsyntax2/src/grammar/items/structs.rs b/crates/libsyntax2/src/grammar/items/structs.rs index ca027d718..93d3381f8 100644 --- a/crates/libsyntax2/src/grammar/items/structs.rs +++ b/crates/libsyntax2/src/grammar/items/structs.rs @@ -82,7 +82,7 @@ fn enum_variant_list(p: &mut Parser) { 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)); let m = p.start(); p.bump(); diff --git a/crates/libsyntax2/src/grammar/mod.rs b/crates/libsyntax2/src/grammar/mod.rs index e3ca2714c..46ba8a89a 100644 --- a/crates/libsyntax2/src/grammar/mod.rs +++ b/crates/libsyntax2/src/grammar/mod.rs @@ -35,6 +35,10 @@ use { parser_api::{Marker, CompletedMarker, Parser, TokenSet}, SyntaxKind::{self, *}, }; +pub(crate) use self::{ + expressions::block, + items::named_field_def_list, +}; pub(crate) fn file(p: &mut Parser) { let file = p.start(); diff --git a/crates/libsyntax2/src/lib.rs b/crates/libsyntax2/src/lib.rs index 86fdbd23f..3a36a57b1 100644 --- a/crates/libsyntax2/src/lib.rs +++ b/crates/libsyntax2/src/lib.rs @@ -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::(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 { + 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 { + let res = match node.kind() { + BLOCK => grammar::block, + NAMED_FIELD_DEF_LIST => grammar::named_field_def_list, + _ => return None, + }; + Some(res) + } +} -- cgit v1.2.3