Simplify node mode management

This commit is contained in:
Martin Haug 2021-11-09 13:07:55 +01:00
parent 9141cba6a9
commit 7a631d8b09
3 changed files with 30 additions and 54 deletions

View File

@ -772,6 +772,6 @@ fn comment(p: &mut Parser) -> ParseResult {
p.eat(); p.eat();
Ok(()) Ok(())
} }
_ => Err(()), _ => Err(ParseError),
} }
} }

View File

@ -286,22 +286,15 @@ impl SourceFile {
.extend(newlines(&self.src[start ..]).map(|idx| start + idx)); .extend(newlines(&self.src[start ..]).map(|idx| start + idx));
// Update the root node. // Update the root node.
let insertion_span = Span::new(self.id, replace.start, replace.end); let span = Span::new(self.id, replace.start, replace.end);
let source = self.src().to_string(); if Rc::make_mut(&mut self.root).incremental(&self.src, span, with.len()) {
if Rc::make_mut(&mut self.root).incremental(&source, insertion_span, with.len()) {
self.was_incremental = true; self.was_incremental = true;
} else { } else {
self.root = parse(self.src()); self.root = parse(&self.src);
self.was_incremental = false; self.was_incremental = false;
} }
} }
/// Forces a non-incremental reparsing of the source file.
fn force_reparse(&mut self) {
self.root = parse(self.src());
self.was_incremental = false;
}
/// Provide highlighting categories for the given range of the source file. /// Provide highlighting categories for the given range of the source file.
pub fn highlight<F>(&self, range: Range<usize>, mut f: F) pub fn highlight<F>(&self, range: Range<usize>, mut f: F)
where where
@ -499,8 +492,7 @@ mod tests {
if incr { if incr {
assert!(source.was_incremental); assert!(source.was_incremental);
let incr_tree = source.root.clone(); let incr_tree = source.root.clone();
source.force_reparse(); assert_eq!(parse(source.src()), incr_tree);
assert_eq!(source.root, incr_tree);
} else { } else {
assert!(!source.was_incremental); assert!(!source.was_incremental);
} }

View File

@ -94,7 +94,7 @@ impl Green {
replace: Span, replace: Span,
replacement_len: usize, replacement_len: usize,
offset: usize, offset: usize,
parent_mode: NodeMode, parent_mode: TokenMode,
outermost: bool, outermost: bool,
) -> bool { ) -> bool {
match self { match self {
@ -221,7 +221,7 @@ impl GreenNode {
return false; return false;
} }
self.incremental_int(src, replace, replacement_len, 0, NodeMode::Markup, true) self.incremental_int(src, replace, replacement_len, 0, TokenMode::Markup, true)
} }
fn incremental_int( fn incremental_int(
@ -230,11 +230,11 @@ impl GreenNode {
replace: Span, replace: Span,
replacement_len: usize, replacement_len: usize,
mut offset: usize, mut offset: usize,
parent_mode: NodeMode, parent_mode: TokenMode,
outermost: bool, outermost: bool,
) -> bool { ) -> bool {
let kind = self.kind().clone(); let kind = self.kind().clone();
let mode = kind.mode().apply(parent_mode); let mode = kind.mode().contextualize(parent_mode);
eprintln!("in {:?} (mode {:?})", kind, mode); eprintln!("in {:?} (mode {:?})", kind, mode);
let mut loop_result = None; let mut loop_result = None;
@ -266,15 +266,11 @@ impl GreenNode {
// This didn't work, so we try to replace the child at this // This didn't work, so we try to replace the child at this
// level. // level.
let (function, policy) = match child let (function, policy) =
.kind() match child.kind().reparsing_function(kind.mode().child_mode()) {
.reparsing_function(mode.child_mode().as_token_mode()) Ok(p) => p,
{ _ => return false,
Ok(p) => p, };
_ => {
return false;
}
};
loop_result = loop_result =
Some((i, child_span, i == last && outermost, function, policy)); Some((i, child_span, i == last && outermost, function, policy));
break; break;
@ -320,8 +316,7 @@ impl GreenNode {
eprintln!("function failed"); eprintln!("function failed");
return false; return false;
}; };
let child_mode = let child_mode = self.children[child_idx].kind().mode().child_mode();
self.children[child_idx].kind().mode().child_mode().as_token_mode();
eprintln!("child mode {:?}", child_mode); eprintln!("child mode {:?}", child_mode);
// Check if the children / child has the right type. // Check if the children / child has the right type.
@ -365,7 +360,7 @@ impl GreenNode {
} }
// Check if the neighbor invariants are still true. // Check if the neighbor invariants are still true.
if mode.as_token_mode() == TokenMode::Markup { if mode == TokenMode::Markup {
if child_idx > 0 { if child_idx > 0 {
if self.children[child_idx - 1].kind().incremental_safety() if self.children[child_idx - 1].kind().incremental_safety()
== IncrementalSafety::EnsureRightWhitespace == IncrementalSafety::EnsureRightWhitespace
@ -1023,10 +1018,10 @@ impl NodeKind {
return Err(policy); return Err(policy);
} }
let mode = self.mode(); let contextualized = self.mode().contextualize(parent_mode);
let is_code = mode == NodeMode::Universal && parent_mode == TokenMode::Code let is_code = contextualized == TokenMode::Code;
|| mode == NodeMode::Code;
if mode == NodeMode::Code && policy == IncrementalSafety::UnsafeLayer { if is_code && policy == IncrementalSafety::UnsafeLayer {
return Err(policy); return Err(policy);
} }
@ -1047,12 +1042,9 @@ impl NodeKind {
return Ok((parser, policy)); return Ok((parser, policy));
} }
let parser: fn(&str, bool) -> _ = match mode { let parser: fn(&str, bool) -> _ = match contextualized {
NodeMode::Markup if self == &Self::Markup => parse_markup, TokenMode::Markup if self == &Self::Markup => parse_markup,
NodeMode::Markup => parse_markup_elements, TokenMode::Markup => parse_markup_elements,
NodeMode::Universal if parent_mode == TokenMode::Markup => {
parse_markup_elements
}
_ => return Err(policy), _ => return Err(policy),
}; };
@ -1403,28 +1395,20 @@ pub enum NodeMode {
impl NodeMode { impl NodeMode {
/// Returns a new mode considering the parent node. /// Returns a new mode considering the parent node.
pub fn apply(&self, old: Self) -> Self { pub fn contextualize(&self, old: TokenMode) -> TokenMode {
match self { match self {
Self::Markup => Self::Markup, Self::Markup => TokenMode::Markup,
Self::Code => Self::Code,
Self::Universal if old != Self::Markup => Self::Code,
Self::Universal => Self::Universal,
}
}
/// Return the corresponding token mode.
pub fn as_token_mode(&self) -> TokenMode {
match self {
Self::Markup | Self::Universal => TokenMode::Markup,
Self::Code => TokenMode::Code, Self::Code => TokenMode::Code,
Self::Universal if old != TokenMode::Markup => TokenMode::Code,
Self::Universal => TokenMode::Markup,
} }
} }
/// The mode of the children of this node. /// The mode of the children of this node.
pub fn child_mode(&self) -> Self { pub fn child_mode(&self) -> TokenMode {
match self { match self {
Self::Markup => Self::Markup, Self::Markup => TokenMode::Markup,
Self::Code | Self::Universal => Self::Code, Self::Code | Self::Universal => TokenMode::Code,
} }
} }
} }