diff --git a/src/syntax/ast.rs b/src/syntax/ast.rs index 46ce40c80..10b8c263b 100644 --- a/src/syntax/ast.rs +++ b/src/syntax/ast.rs @@ -5,7 +5,7 @@ use std::num::NonZeroUsize; use std::ops::Deref; -use super::{NodeData, NodeKind, RawFields, Span, SyntaxNode, Unit}; +use super::{NodeKind, RawFields, Span, SyntaxNode, Unit}; use crate::util::EcoString; /// A typed AST node. @@ -1557,8 +1557,8 @@ impl Ident { /// Take out the container identifier. pub fn take(self) -> EcoString { - match self.0 { - SyntaxNode::Leaf(NodeData { kind: NodeKind::Ident(id), .. }) => id, + match self.0.take() { + NodeKind::Ident(id) => id, _ => panic!("identifier is of wrong kind"), } } diff --git a/src/syntax/incremental.rs b/src/syntax/incremental.rs index 6c9145a2e..5b96f86bd 100644 --- a/src/syntax/incremental.rs +++ b/src/syntax/incremental.rs @@ -1,9 +1,8 @@ use std::ops::Range; -use std::sync::Arc; use super::{ is_newline, parse, reparse_code_block, reparse_content_block, - reparse_markup_elements, InnerNode, NodeKind, Span, SyntaxNode, + reparse_markup_elements, NodeKind, Span, SyntaxNode, }; /// Refresh the given syntax node with as little parsing as possible. @@ -18,11 +17,9 @@ pub fn reparse( replaced: Range, replacement_len: usize, ) -> Range { - if let SyntaxNode::Inner(inner) = root { - let change = Change { text, replaced, replacement_len }; - if let Some(range) = try_reparse(&change, Arc::make_mut(inner), 0, true, true) { - return range; - } + let change = Change { text, replaced, replacement_len }; + if let Some(range) = try_reparse(&change, root, 0, true, true) { + return range; } let id = root.span().source(); @@ -34,7 +31,7 @@ pub fn reparse( /// Try to reparse inside the given node. fn try_reparse( change: &Change, - node: &mut InnerNode, + node: &mut SyntaxNode, mut offset: usize, outermost: bool, safe_to_replace: bool, @@ -143,20 +140,15 @@ fn try_reparse( let prev_len = child.len(); let prev_descendants = child.descendants(); - if let Some(range) = match child { - SyntaxNode::Inner(node) => try_reparse( - change, - Arc::make_mut(node), - pos.offset, - child_outermost, - safe_inside, - ), - SyntaxNode::Leaf(_) => None, - } { - let new_len = child.len(); - let new_descendants = child.descendants(); - node.update_parent(prev_len, new_len, prev_descendants, new_descendants); - return Some(range); + if !child.is_leaf() { + if let Some(range) = + try_reparse(change, child, pos.offset, child_outermost, safe_inside) + { + let new_len = child.len(); + let new_descendants = child.descendants(); + node.update_parent(prev_len, new_len, prev_descendants, new_descendants); + return Some(range); + } } let superseded_span = pos.offset..pos.offset + prev_len; @@ -215,7 +207,7 @@ fn try_reparse( /// Reparse the superseded nodes and replace them. fn replace( change: &Change, - node: &mut InnerNode, + node: &mut SyntaxNode, mode: ReparseMode, superseded_idx: Range, superseded_span: Range, diff --git a/src/syntax/node.rs b/src/syntax/node.rs index 5758a4bfc..1222928c3 100644 --- a/src/syntax/node.rs +++ b/src/syntax/node.rs @@ -6,78 +6,66 @@ use super::ast::TypedNode; use super::{NodeKind, NumberingResult, SourceId, Span, Unnumberable}; use crate::diag::SourceError; -/// An inner or leaf node in the untyped syntax tree. +/// A node in the untyped syntax tree. #[derive(Clone, PartialEq, Hash)] -pub enum SyntaxNode { +pub struct SyntaxNode(Repr); + +/// The two internal representations. +#[derive(Clone, PartialEq, Hash)] +enum Repr { + /// A leaf node. + Leaf(NodeData), /// A reference-counted inner node. Inner(Arc), - /// A leaf token. - Leaf(NodeData), } impl SyntaxNode { - /// The metadata of the node. - pub fn data(&self) -> &NodeData { - match self { - Self::Inner(inner) => &inner.data, - Self::Leaf(leaf) => leaf, - } + /// Create a new leaf node. + pub fn leaf(kind: NodeKind, len: usize) -> Self { + Self(Repr::Leaf(NodeData::new(kind, len))) + } + + /// Create a new inner node with children. + pub fn inner(kind: NodeKind, children: Vec) -> Self { + Self(Repr::Inner(Arc::new(InnerNode::with_children(kind, children)))) } /// The type of the node. pub fn kind(&self) -> &NodeKind { - self.data().kind() + &self.data().kind + } + + /// Take the kind out of the node. + pub fn take(self) -> NodeKind { + match self.0 { + Repr::Leaf(leaf) => leaf.kind, + Repr::Inner(inner) => inner.data.kind.clone(), + } } /// The length of the node. pub fn len(&self) -> usize { - self.data().len() - } - - /// The number of descendants, including the node itself. - pub fn descendants(&self) -> usize { - match self { - Self::Inner(inner) => inner.descendants(), - Self::Leaf(_) => 1, - } + self.data().len } /// The span of the node. pub fn span(&self) -> Span { - self.data().span() + self.data().span } - /// Whether the node or its children contain an error. - pub fn erroneous(&self) -> bool { - match self { - Self::Inner(node) => node.erroneous, - Self::Leaf(data) => data.kind.is_error(), - } - } - - /// The error messages for this node and its descendants. - pub fn errors(&self) -> Vec { - if !self.erroneous() { - return vec![]; - } - - match self.kind() { - NodeKind::Error(pos, message) => { - vec![SourceError::new(self.span(), message.clone()).with_pos(*pos)] - } - _ => self - .children() - .filter(|node| node.erroneous()) - .flat_map(|node| node.errors()) - .collect(), + /// The number of descendants, including the node itself. + pub fn descendants(&self) -> usize { + match &self.0 { + Repr::Inner(inner) => inner.descendants, + Repr::Leaf(_) => 1, } } /// The node's children. pub fn children(&self) -> std::slice::Iter<'_, SyntaxNode> { - match self { - Self::Inner(inner) => inner.children(), - Self::Leaf(_) => [].iter(), + match &self.0 { + Repr::Inner(inner) => inner.children.iter(), + Repr::Leaf(_) => [].iter(), } } @@ -99,37 +87,49 @@ impl SyntaxNode { self.children().rev().find_map(Self::cast) } - /// Returns all leaf descendants of this node (may include itself). - /// - /// This method is slow and only intended for testing. - pub fn leafs(&self) -> Vec { - if match self { - Self::Inner(inner) => inner.children.is_empty(), - Self::Leaf(_) => true, - } { - vec![self.clone()] - } else { - self.children().flat_map(Self::leafs).collect() + /// Whether the node or its children contain an error. + pub fn erroneous(&self) -> bool { + match &self.0 { + Repr::Inner(node) => node.erroneous, + Repr::Leaf(data) => data.kind.is_error(), + } + } + + /// The error messages for this node and its descendants. + pub fn errors(&self) -> Vec { + if !self.erroneous() { + return vec![]; + } + + match self.kind() { + NodeKind::Error(pos, message) => { + vec![SourceError::new(self.span(), message.clone()).with_pos(*pos)] + } + _ => self + .children() + .filter(|node| node.erroneous()) + .flat_map(|node| node.errors()) + .collect(), } } /// Change the type of the node. pub(super) fn convert(&mut self, kind: NodeKind) { - match self { - Self::Inner(inner) => { + match &mut self.0 { + Repr::Inner(inner) => { let node = Arc::make_mut(inner); node.erroneous |= kind.is_error(); node.data.kind = kind; } - Self::Leaf(leaf) => leaf.kind = kind, + Repr::Leaf(leaf) => leaf.kind = kind, } } /// Set a synthetic span for the node and all its descendants. pub(super) fn synthesize(&mut self, span: Span) { - match self { - Self::Inner(inner) => Arc::make_mut(inner).synthesize(span), - Self::Leaf(leaf) => leaf.synthesize(span), + match &mut self.0 { + Repr::Inner(inner) => Arc::make_mut(inner).synthesize(span), + Repr::Leaf(leaf) => leaf.synthesize(span), } } @@ -139,47 +139,100 @@ impl SyntaxNode { id: SourceId, within: Range, ) -> NumberingResult { - match self { - Self::Inner(inner) => Arc::make_mut(inner).numberize(id, None, within), - Self::Leaf(leaf) => leaf.numberize(id, within), + match &mut self.0 { + Repr::Inner(inner) => Arc::make_mut(inner).numberize(id, None, within), + Repr::Leaf(leaf) => leaf.numberize(id, within), } } /// If the span points into this node, convert it to a byte range. pub(super) fn range(&self, span: Span, offset: usize) -> Option> { - match self { - Self::Inner(inner) => inner.range(span, offset), - Self::Leaf(leaf) => leaf.range(span, offset), + match &self.0 { + Repr::Inner(inner) => inner.range(span, offset), + Repr::Leaf(leaf) => leaf.range(span, offset), + } + } + + /// Whether this is a leaf node. + pub(super) fn is_leaf(&self) -> bool { + matches!(self.0, Repr::Leaf(_)) + } + + /// The node's children, mutably. + pub(super) fn children_mut(&mut self) -> &mut [SyntaxNode] { + match &mut self.0 { + Repr::Leaf(_) => &mut [], + Repr::Inner(inner) => &mut Arc::make_mut(inner).children, + } + } + + /// Replaces a range of children with a replacement. + /// + /// May have mutated the children if it returns `Err(_)`. + pub(super) fn replace_children( + &mut self, + range: Range, + replacement: Vec, + ) -> NumberingResult { + if let Repr::Inner(inner) = &mut self.0 { + Arc::make_mut(inner).replace_children(range, replacement)?; + } + Ok(()) + } + + /// Update this node after changes were made to one of its children. + pub(super) fn update_parent( + &mut self, + prev_len: usize, + new_len: usize, + prev_descendants: usize, + new_descendants: usize, + ) { + if let Repr::Inner(inner) = &mut self.0 { + Arc::make_mut(inner).update_parent( + prev_len, + new_len, + prev_descendants, + new_descendants, + ); + } + } + + /// The metadata of the node. + fn data(&self) -> &NodeData { + match &self.0 { + Repr::Inner(inner) => &inner.data, + Repr::Leaf(leaf) => leaf, } } /// The upper bound of assigned numbers in this subtree. fn upper(&self) -> u64 { - match self { - Self::Inner(inner) => inner.upper(), - Self::Leaf(leaf) => leaf.span().number() + 1, + match &self.0 { + Repr::Inner(inner) => inner.upper, + Repr::Leaf(leaf) => leaf.span.number() + 1, + } + } +} + +impl Debug for SyntaxNode { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + match &self.0 { + Repr::Inner(node) => node.fmt(f), + Repr::Leaf(node) => node.fmt(f), } } } impl Default for SyntaxNode { fn default() -> Self { - Self::Leaf(NodeData::new(NodeKind::None, 0)) - } -} - -impl Debug for SyntaxNode { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - match self { - Self::Inner(node) => node.fmt(f), - Self::Leaf(token) => token.fmt(f), - } + Self::leaf(NodeKind::None, 0) } } /// An inner node in the untyped syntax tree. #[derive(Clone, Hash)] -pub struct InnerNode { +struct InnerNode { /// Node metadata. data: NodeData, /// The number of nodes in the whole subtree, including this node. @@ -193,13 +246,8 @@ pub struct InnerNode { } impl InnerNode { - /// Creates a new node with the given kind and a single child. - pub fn with_child(kind: NodeKind, child: impl Into) -> Self { - Self::with_children(kind, vec![child.into()]) - } - - /// Creates a new node with the given kind and children. - pub fn with_children(kind: NodeKind, children: Vec) -> Self { + /// Create a new inner node with the given kind and children. + fn with_children(kind: NodeKind, children: Vec) -> Self { let mut len = 0; let mut descendants = 1; let mut erroneous = kind.is_error(); @@ -219,36 +267,6 @@ impl InnerNode { } } - /// The node's metadata. - pub fn data(&self) -> &NodeData { - &self.data - } - - /// The node's type. - pub fn kind(&self) -> &NodeKind { - self.data().kind() - } - - /// The node's length. - pub fn len(&self) -> usize { - self.data().len() - } - - /// The node's span. - pub fn span(&self) -> Span { - self.data().span() - } - - /// The number of descendants, including the node itself. - pub fn descendants(&self) -> usize { - self.descendants - } - - /// The node's children. - pub fn children(&self) -> std::slice::Iter<'_, SyntaxNode> { - self.children.iter() - } - /// Set a synthetic span for the node and all its descendants. fn synthesize(&mut self, span: Span) { self.data.synthesize(span); @@ -307,11 +325,6 @@ impl InnerNode { Ok(()) } - /// The upper bound of assigned numbers in this subtree. - fn upper(&self) -> u64 { - self.upper - } - /// If the span points into this node, convert it to a byte range. fn range(&self, span: Span, mut offset: usize) -> Option> { // Check whether we found it. @@ -322,7 +335,7 @@ impl InnerNode { // The parent of a subtree has a smaller span number than all of its // descendants. Therefore, we can bail out early if the target span's // number is smaller than our number. - if span.number() < self.span().number() { + if span.number() < self.data.span.number() { return None; } @@ -346,15 +359,10 @@ impl InnerNode { None } - /// The node's children, mutably. - pub(super) fn children_mut(&mut self) -> &mut [SyntaxNode] { - &mut self.children - } - /// Replaces a range of children with a replacement. /// /// May have mutated the children if it returns `Err(_)`. - pub(super) fn replace_children( + fn replace_children( &mut self, mut range: Range, replacement: Vec, @@ -403,7 +411,7 @@ impl InnerNode { .start .checked_sub(1) .and_then(|i| self.children.get(i)) - .map_or(self.span().number() + 1, |child| child.upper()); + .map_or(self.data.span.number() + 1, |child| child.upper()); // The upper bound for renumbering is either // - the span number of the first child after the to-be-renumbered @@ -413,11 +421,11 @@ impl InnerNode { let end_number = self .children .get(renumber.end) - .map_or(self.upper(), |next| next.span().number()); + .map_or(self.upper, |next| next.span().number()); // Try to renumber. let within = start_number..end_number; - let id = self.span().source(); + let id = self.data.span.source(); if self.numberize(id, Some(renumber), within).is_ok() { return Ok(()); } @@ -434,7 +442,7 @@ impl InnerNode { } /// Update this node after changes were made to one of its children. - pub(super) fn update_parent( + fn update_parent( &mut self, prev_len: usize, new_len: usize, @@ -447,18 +455,6 @@ impl InnerNode { } } -impl From for SyntaxNode { - fn from(node: InnerNode) -> Self { - Arc::new(node).into() - } -} - -impl From> for SyntaxNode { - fn from(node: Arc) -> Self { - Self::Inner(node) - } -} - impl Debug for InnerNode { fn fmt(&self, f: &mut Formatter) -> fmt::Result { self.data.fmt(f)?; @@ -479,12 +475,12 @@ impl PartialEq for InnerNode { } } -/// Data shared between inner and leaf nodes. +/// Data shared between leaf and inner nodes. #[derive(Clone, Hash)] -pub struct NodeData { +struct NodeData { /// What kind of node this is (each kind would have its own struct in a /// strongly typed AST). - pub(super) kind: NodeKind, + kind: NodeKind, /// The byte length of the node in the source. len: usize, /// The node's span. @@ -493,25 +489,10 @@ pub struct NodeData { impl NodeData { /// Create new node metadata. - pub fn new(kind: NodeKind, len: usize) -> Self { + fn new(kind: NodeKind, len: usize) -> Self { Self { len, kind, span: Span::detached() } } - /// The node's type. - pub fn kind(&self) -> &NodeKind { - &self.kind - } - - /// The node's length. - pub fn len(&self) -> usize { - self.len - } - - /// The node's span. - pub fn span(&self) -> Span { - self.span - } - /// Set a synthetic span for the node. fn synthesize(&mut self, span: Span) { self.span = span; @@ -529,13 +510,7 @@ impl NodeData { /// If the span points into this node, convert it to a byte range. fn range(&self, span: Span, offset: usize) -> Option> { - (self.span == span).then(|| offset..offset + self.len()) - } -} - -impl From for SyntaxNode { - fn from(token: NodeData) -> Self { - Self::Leaf(token) + (self.span == span).then(|| offset..offset + self.len) } } diff --git a/src/syntax/parser.rs b/src/syntax/parser.rs index 8d51f7ebe..9d8248564 100644 --- a/src/syntax/parser.rs +++ b/src/syntax/parser.rs @@ -2,7 +2,7 @@ use std::fmt::{self, Display, Formatter}; use std::mem; use std::ops::Range; -use super::{ErrorPos, InnerNode, NodeData, NodeKind, SyntaxNode, TokenMode, Tokens}; +use super::{ErrorPos, NodeKind, SyntaxNode, TokenMode, Tokens}; use crate::util::{format_eco, EcoString}; /// A convenient token-based parser. @@ -92,13 +92,13 @@ impl<'s> Parser<'s> { let mut children = mem::replace(&mut self.children, prev); if self.tokens.mode() == TokenMode::Markup { - self.children.push(InnerNode::with_children(kind, children).into()); + self.children.push(SyntaxNode::inner(kind, children)); } else { // Trailing trivia should not be wrapped into the new node. let idx = self.children.len(); self.children.push(SyntaxNode::default()); self.children.extend(children.drain(until.0..)); - self.children[idx] = InnerNode::with_children(kind, children).into(); + self.children[idx] = SyntaxNode::inner(kind, children); } output @@ -330,7 +330,7 @@ impl<'s> Parser<'s> { fn bump(&mut self) { let kind = self.current.take().unwrap(); let len = self.tokens.cursor() - self.current_start; - self.children.push(NodeData::new(kind, len).into()); + self.children.push(SyntaxNode::leaf(kind, len)); self.current_start = self.tokens.cursor(); self.current = self.tokens.next(); } @@ -416,7 +416,7 @@ impl Parser<'_> { pub fn expected_at(&mut self, marker: Marker, what: &str) { let msg = format_eco!("expected {}", what); let error = NodeKind::Error(ErrorPos::Full, msg); - self.children.insert(marker.0, NodeData::new(error, 0).into()); + self.children.insert(marker.0, SyntaxNode::leaf(error, 0)); } /// Eat the current token and add an error that it is not the expected @@ -471,8 +471,7 @@ impl Marker { pub fn end(self, p: &mut Parser, kind: NodeKind) { let until = p.trivia_start().0.max(self.0); let children = p.children.drain(self.0..until).collect(); - p.children - .insert(self.0, InnerNode::with_children(kind, children).into()); + p.children.insert(self.0, SyntaxNode::inner(kind, children)); } /// Wrap all children that do not fulfill the predicate in error nodes. @@ -499,7 +498,7 @@ impl Marker { } let error = NodeKind::Error(ErrorPos::Full, msg); let inner = mem::take(child); - *child = InnerNode::with_child(error, inner).into(); + *child = SyntaxNode::inner(error, vec![inner]); } } } diff --git a/src/syntax/source.rs b/src/syntax/source.rs index 48b0ff0e9..08b526859 100644 --- a/src/syntax/source.rs +++ b/src/syntax/source.rs @@ -95,7 +95,7 @@ impl Source { self.text.get(range) } - /// Fully replace the source text and increase the revision number. + /// Fully replace the source text. pub fn replace(&mut self, text: String) { self.text = Prehashed::new(text); self.lines = vec![Line { byte_idx: 0, utf16_idx: 0 }]; @@ -105,8 +105,7 @@ impl Source { self.root = Prehashed::new(root); } - /// Edit the source file by replacing the given range and increase the - /// revision number. + /// Edit the source file by replacing the given range. /// /// Returns the range in the new source that was ultimately reparsed. /// diff --git a/tests/src/tests.rs b/tests/src/tests.rs index a867f065e..52cc54db1 100644 --- a/tests/src/tests.rs +++ b/tests/src/tests.rs @@ -606,7 +606,7 @@ fn test_reparse(text: &str, i: usize, rng: &mut LinearShift) -> bool { } let source = Source::detached(text); - let leafs = source.root().leafs(); + let leafs = leafs(source.root()); let start = source.range(leafs[pick(0..leafs.len())].span()).start; let supplement = supplements[pick(0..supplements.len())]; ok &= apply(start..start, supplement); @@ -614,6 +614,15 @@ fn test_reparse(text: &str, i: usize, rng: &mut LinearShift) -> bool { ok } +/// Returns all leaf descendants of a node (may include itself). +fn leafs(node: &SyntaxNode) -> Vec { + if node.children().len() == 0 { + vec![node.clone()] + } else { + node.children().flat_map(leafs).collect() + } +} + /// Ensure that all spans are properly ordered (and therefore unique). #[track_caller] fn test_spans(root: &SyntaxNode) -> bool {