Make inner node and node data private

This commit is contained in:
Laurenz 2022-11-22 14:40:56 +01:00
parent dd9c323941
commit 2ce727fc95
6 changed files with 187 additions and 213 deletions

View File

@ -5,7 +5,7 @@
use std::num::NonZeroUsize; use std::num::NonZeroUsize;
use std::ops::Deref; use std::ops::Deref;
use super::{NodeData, NodeKind, RawFields, Span, SyntaxNode, Unit}; use super::{NodeKind, RawFields, Span, SyntaxNode, Unit};
use crate::util::EcoString; use crate::util::EcoString;
/// A typed AST node. /// A typed AST node.
@ -1557,8 +1557,8 @@ impl Ident {
/// Take out the container identifier. /// Take out the container identifier.
pub fn take(self) -> EcoString { pub fn take(self) -> EcoString {
match self.0 { match self.0.take() {
SyntaxNode::Leaf(NodeData { kind: NodeKind::Ident(id), .. }) => id, NodeKind::Ident(id) => id,
_ => panic!("identifier is of wrong kind"), _ => panic!("identifier is of wrong kind"),
} }
} }

View File

@ -1,9 +1,8 @@
use std::ops::Range; use std::ops::Range;
use std::sync::Arc;
use super::{ use super::{
is_newline, parse, reparse_code_block, reparse_content_block, 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. /// Refresh the given syntax node with as little parsing as possible.
@ -18,11 +17,9 @@ pub fn reparse(
replaced: Range<usize>, replaced: Range<usize>,
replacement_len: usize, replacement_len: usize,
) -> Range<usize> { ) -> Range<usize> {
if let SyntaxNode::Inner(inner) = root { let change = Change { text, replaced, replacement_len };
let change = Change { text, replaced, replacement_len }; if let Some(range) = try_reparse(&change, root, 0, true, true) {
if let Some(range) = try_reparse(&change, Arc::make_mut(inner), 0, true, true) { return range;
return range;
}
} }
let id = root.span().source(); let id = root.span().source();
@ -34,7 +31,7 @@ pub fn reparse(
/// Try to reparse inside the given node. /// Try to reparse inside the given node.
fn try_reparse( fn try_reparse(
change: &Change, change: &Change,
node: &mut InnerNode, node: &mut SyntaxNode,
mut offset: usize, mut offset: usize,
outermost: bool, outermost: bool,
safe_to_replace: bool, safe_to_replace: bool,
@ -143,20 +140,15 @@ fn try_reparse(
let prev_len = child.len(); let prev_len = child.len();
let prev_descendants = child.descendants(); let prev_descendants = child.descendants();
if let Some(range) = match child { if !child.is_leaf() {
SyntaxNode::Inner(node) => try_reparse( if let Some(range) =
change, try_reparse(change, child, pos.offset, child_outermost, safe_inside)
Arc::make_mut(node), {
pos.offset, let new_len = child.len();
child_outermost, let new_descendants = child.descendants();
safe_inside, node.update_parent(prev_len, new_len, prev_descendants, new_descendants);
), return Some(range);
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);
} }
let superseded_span = pos.offset..pos.offset + prev_len; let superseded_span = pos.offset..pos.offset + prev_len;
@ -215,7 +207,7 @@ fn try_reparse(
/// Reparse the superseded nodes and replace them. /// Reparse the superseded nodes and replace them.
fn replace( fn replace(
change: &Change, change: &Change,
node: &mut InnerNode, node: &mut SyntaxNode,
mode: ReparseMode, mode: ReparseMode,
superseded_idx: Range<usize>, superseded_idx: Range<usize>,
superseded_span: Range<usize>, superseded_span: Range<usize>,

View File

@ -6,78 +6,66 @@ use super::ast::TypedNode;
use super::{NodeKind, NumberingResult, SourceId, Span, Unnumberable}; use super::{NodeKind, NumberingResult, SourceId, Span, Unnumberable};
use crate::diag::SourceError; 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)] #[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. /// A reference-counted inner node.
Inner(Arc<InnerNode>), Inner(Arc<InnerNode>),
/// A leaf token.
Leaf(NodeData),
} }
impl SyntaxNode { impl SyntaxNode {
/// The metadata of the node. /// Create a new leaf node.
pub fn data(&self) -> &NodeData { pub fn leaf(kind: NodeKind, len: usize) -> Self {
match self { Self(Repr::Leaf(NodeData::new(kind, len)))
Self::Inner(inner) => &inner.data, }
Self::Leaf(leaf) => leaf,
} /// Create a new inner node with children.
pub fn inner(kind: NodeKind, children: Vec<SyntaxNode>) -> Self {
Self(Repr::Inner(Arc::new(InnerNode::with_children(kind, children))))
} }
/// The type of the node. /// The type of the node.
pub fn kind(&self) -> &NodeKind { 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. /// The length of the node.
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.data().len() 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,
}
} }
/// The span of the node. /// The span of the node.
pub fn span(&self) -> Span { pub fn span(&self) -> Span {
self.data().span() self.data().span
} }
/// Whether the node or its children contain an error. /// The number of descendants, including the node itself.
pub fn erroneous(&self) -> bool { pub fn descendants(&self) -> usize {
match self { match &self.0 {
Self::Inner(node) => node.erroneous, Repr::Inner(inner) => inner.descendants,
Self::Leaf(data) => data.kind.is_error(), Repr::Leaf(_) => 1,
}
}
/// The error messages for this node and its descendants.
pub fn errors(&self) -> Vec<SourceError> {
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 node's children. /// The node's children.
pub fn children(&self) -> std::slice::Iter<'_, SyntaxNode> { pub fn children(&self) -> std::slice::Iter<'_, SyntaxNode> {
match self { match &self.0 {
Self::Inner(inner) => inner.children(), Repr::Inner(inner) => inner.children.iter(),
Self::Leaf(_) => [].iter(), Repr::Leaf(_) => [].iter(),
} }
} }
@ -99,37 +87,49 @@ impl SyntaxNode {
self.children().rev().find_map(Self::cast) self.children().rev().find_map(Self::cast)
} }
/// Returns all leaf descendants of this node (may include itself). /// Whether the node or its children contain an error.
/// pub fn erroneous(&self) -> bool {
/// This method is slow and only intended for testing. match &self.0 {
pub fn leafs(&self) -> Vec<Self> { Repr::Inner(node) => node.erroneous,
if match self { Repr::Leaf(data) => data.kind.is_error(),
Self::Inner(inner) => inner.children.is_empty(), }
Self::Leaf(_) => true, }
} {
vec![self.clone()] /// The error messages for this node and its descendants.
} else { pub fn errors(&self) -> Vec<SourceError> {
self.children().flat_map(Self::leafs).collect() 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. /// Change the type of the node.
pub(super) fn convert(&mut self, kind: NodeKind) { pub(super) fn convert(&mut self, kind: NodeKind) {
match self { match &mut self.0 {
Self::Inner(inner) => { Repr::Inner(inner) => {
let node = Arc::make_mut(inner); let node = Arc::make_mut(inner);
node.erroneous |= kind.is_error(); node.erroneous |= kind.is_error();
node.data.kind = kind; 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. /// Set a synthetic span for the node and all its descendants.
pub(super) fn synthesize(&mut self, span: Span) { pub(super) fn synthesize(&mut self, span: Span) {
match self { match &mut self.0 {
Self::Inner(inner) => Arc::make_mut(inner).synthesize(span), Repr::Inner(inner) => Arc::make_mut(inner).synthesize(span),
Self::Leaf(leaf) => leaf.synthesize(span), Repr::Leaf(leaf) => leaf.synthesize(span),
} }
} }
@ -139,47 +139,100 @@ impl SyntaxNode {
id: SourceId, id: SourceId,
within: Range<u64>, within: Range<u64>,
) -> NumberingResult { ) -> NumberingResult {
match self { match &mut self.0 {
Self::Inner(inner) => Arc::make_mut(inner).numberize(id, None, within), Repr::Inner(inner) => Arc::make_mut(inner).numberize(id, None, within),
Self::Leaf(leaf) => leaf.numberize(id, within), Repr::Leaf(leaf) => leaf.numberize(id, within),
} }
} }
/// If the span points into this node, convert it to a byte range. /// If the span points into this node, convert it to a byte range.
pub(super) fn range(&self, span: Span, offset: usize) -> Option<Range<usize>> { pub(super) fn range(&self, span: Span, offset: usize) -> Option<Range<usize>> {
match self { match &self.0 {
Self::Inner(inner) => inner.range(span, offset), Repr::Inner(inner) => inner.range(span, offset),
Self::Leaf(leaf) => leaf.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<usize>,
replacement: Vec<SyntaxNode>,
) -> 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. /// The upper bound of assigned numbers in this subtree.
fn upper(&self) -> u64 { fn upper(&self) -> u64 {
match self { match &self.0 {
Self::Inner(inner) => inner.upper(), Repr::Inner(inner) => inner.upper,
Self::Leaf(leaf) => leaf.span().number() + 1, 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 { impl Default for SyntaxNode {
fn default() -> Self { fn default() -> Self {
Self::Leaf(NodeData::new(NodeKind::None, 0)) Self::leaf(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),
}
} }
} }
/// An inner node in the untyped syntax tree. /// An inner node in the untyped syntax tree.
#[derive(Clone, Hash)] #[derive(Clone, Hash)]
pub struct InnerNode { struct InnerNode {
/// Node metadata. /// Node metadata.
data: NodeData, data: NodeData,
/// The number of nodes in the whole subtree, including this node. /// The number of nodes in the whole subtree, including this node.
@ -193,13 +246,8 @@ pub struct InnerNode {
} }
impl InnerNode { impl InnerNode {
/// Creates a new node with the given kind and a single child. /// Create a new inner node with the given kind and children.
pub fn with_child(kind: NodeKind, child: impl Into<SyntaxNode>) -> Self { fn with_children(kind: NodeKind, children: Vec<SyntaxNode>) -> 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<SyntaxNode>) -> Self {
let mut len = 0; let mut len = 0;
let mut descendants = 1; let mut descendants = 1;
let mut erroneous = kind.is_error(); 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. /// Set a synthetic span for the node and all its descendants.
fn synthesize(&mut self, span: Span) { fn synthesize(&mut self, span: Span) {
self.data.synthesize(span); self.data.synthesize(span);
@ -307,11 +325,6 @@ impl InnerNode {
Ok(()) 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. /// If the span points into this node, convert it to a byte range.
fn range(&self, span: Span, mut offset: usize) -> Option<Range<usize>> { fn range(&self, span: Span, mut offset: usize) -> Option<Range<usize>> {
// Check whether we found it. // 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 // 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 // descendants. Therefore, we can bail out early if the target span's
// number is smaller than our number. // number is smaller than our number.
if span.number() < self.span().number() { if span.number() < self.data.span.number() {
return None; return None;
} }
@ -346,15 +359,10 @@ impl InnerNode {
None 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. /// Replaces a range of children with a replacement.
/// ///
/// May have mutated the children if it returns `Err(_)`. /// May have mutated the children if it returns `Err(_)`.
pub(super) fn replace_children( fn replace_children(
&mut self, &mut self,
mut range: Range<usize>, mut range: Range<usize>,
replacement: Vec<SyntaxNode>, replacement: Vec<SyntaxNode>,
@ -403,7 +411,7 @@ impl InnerNode {
.start .start
.checked_sub(1) .checked_sub(1)
.and_then(|i| self.children.get(i)) .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 upper bound for renumbering is either
// - the span number of the first child after the to-be-renumbered // - the span number of the first child after the to-be-renumbered
@ -413,11 +421,11 @@ impl InnerNode {
let end_number = self let end_number = self
.children .children
.get(renumber.end) .get(renumber.end)
.map_or(self.upper(), |next| next.span().number()); .map_or(self.upper, |next| next.span().number());
// Try to renumber. // Try to renumber.
let within = start_number..end_number; 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() { if self.numberize(id, Some(renumber), within).is_ok() {
return Ok(()); return Ok(());
} }
@ -434,7 +442,7 @@ impl InnerNode {
} }
/// Update this node after changes were made to one of its children. /// Update this node after changes were made to one of its children.
pub(super) fn update_parent( fn update_parent(
&mut self, &mut self,
prev_len: usize, prev_len: usize,
new_len: usize, new_len: usize,
@ -447,18 +455,6 @@ impl InnerNode {
} }
} }
impl From<InnerNode> for SyntaxNode {
fn from(node: InnerNode) -> Self {
Arc::new(node).into()
}
}
impl From<Arc<InnerNode>> for SyntaxNode {
fn from(node: Arc<InnerNode>) -> Self {
Self::Inner(node)
}
}
impl Debug for InnerNode { impl Debug for InnerNode {
fn fmt(&self, f: &mut Formatter) -> fmt::Result { fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.data.fmt(f)?; 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)] #[derive(Clone, Hash)]
pub struct NodeData { struct NodeData {
/// What kind of node this is (each kind would have its own struct in a /// What kind of node this is (each kind would have its own struct in a
/// strongly typed AST). /// strongly typed AST).
pub(super) kind: NodeKind, kind: NodeKind,
/// The byte length of the node in the source. /// The byte length of the node in the source.
len: usize, len: usize,
/// The node's span. /// The node's span.
@ -493,25 +489,10 @@ pub struct NodeData {
impl NodeData { impl NodeData {
/// Create new node metadata. /// 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() } 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. /// Set a synthetic span for the node.
fn synthesize(&mut self, span: Span) { fn synthesize(&mut self, span: Span) {
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. /// If the span points into this node, convert it to a byte range.
fn range(&self, span: Span, offset: usize) -> Option<Range<usize>> { fn range(&self, span: Span, offset: usize) -> Option<Range<usize>> {
(self.span == span).then(|| offset..offset + self.len()) (self.span == span).then(|| offset..offset + self.len)
}
}
impl From<NodeData> for SyntaxNode {
fn from(token: NodeData) -> Self {
Self::Leaf(token)
} }
} }

View File

@ -2,7 +2,7 @@ use std::fmt::{self, Display, Formatter};
use std::mem; use std::mem;
use std::ops::Range; 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}; use crate::util::{format_eco, EcoString};
/// A convenient token-based parser. /// A convenient token-based parser.
@ -92,13 +92,13 @@ impl<'s> Parser<'s> {
let mut children = mem::replace(&mut self.children, prev); let mut children = mem::replace(&mut self.children, prev);
if self.tokens.mode() == TokenMode::Markup { if self.tokens.mode() == TokenMode::Markup {
self.children.push(InnerNode::with_children(kind, children).into()); self.children.push(SyntaxNode::inner(kind, children));
} else { } else {
// Trailing trivia should not be wrapped into the new node. // Trailing trivia should not be wrapped into the new node.
let idx = self.children.len(); let idx = self.children.len();
self.children.push(SyntaxNode::default()); self.children.push(SyntaxNode::default());
self.children.extend(children.drain(until.0..)); self.children.extend(children.drain(until.0..));
self.children[idx] = InnerNode::with_children(kind, children).into(); self.children[idx] = SyntaxNode::inner(kind, children);
} }
output output
@ -330,7 +330,7 @@ impl<'s> Parser<'s> {
fn bump(&mut self) { fn bump(&mut self) {
let kind = self.current.take().unwrap(); let kind = self.current.take().unwrap();
let len = self.tokens.cursor() - self.current_start; 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_start = self.tokens.cursor();
self.current = self.tokens.next(); self.current = self.tokens.next();
} }
@ -416,7 +416,7 @@ impl Parser<'_> {
pub fn expected_at(&mut self, marker: Marker, what: &str) { pub fn expected_at(&mut self, marker: Marker, what: &str) {
let msg = format_eco!("expected {}", what); let msg = format_eco!("expected {}", what);
let error = NodeKind::Error(ErrorPos::Full, msg); 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 /// 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) { pub fn end(self, p: &mut Parser, kind: NodeKind) {
let until = p.trivia_start().0.max(self.0); let until = p.trivia_start().0.max(self.0);
let children = p.children.drain(self.0..until).collect(); let children = p.children.drain(self.0..until).collect();
p.children p.children.insert(self.0, SyntaxNode::inner(kind, children));
.insert(self.0, InnerNode::with_children(kind, children).into());
} }
/// Wrap all children that do not fulfill the predicate in error nodes. /// 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 error = NodeKind::Error(ErrorPos::Full, msg);
let inner = mem::take(child); let inner = mem::take(child);
*child = InnerNode::with_child(error, inner).into(); *child = SyntaxNode::inner(error, vec![inner]);
} }
} }
} }

View File

@ -95,7 +95,7 @@ impl Source {
self.text.get(range) 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) { pub fn replace(&mut self, text: String) {
self.text = Prehashed::new(text); self.text = Prehashed::new(text);
self.lines = vec![Line { byte_idx: 0, utf16_idx: 0 }]; self.lines = vec![Line { byte_idx: 0, utf16_idx: 0 }];
@ -105,8 +105,7 @@ impl Source {
self.root = Prehashed::new(root); self.root = Prehashed::new(root);
} }
/// Edit the source file by replacing the given range and increase the /// Edit the source file by replacing the given range.
/// revision number.
/// ///
/// Returns the range in the new source that was ultimately reparsed. /// Returns the range in the new source that was ultimately reparsed.
/// ///

View File

@ -606,7 +606,7 @@ fn test_reparse(text: &str, i: usize, rng: &mut LinearShift) -> bool {
} }
let source = Source::detached(text); 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 start = source.range(leafs[pick(0..leafs.len())].span()).start;
let supplement = supplements[pick(0..supplements.len())]; let supplement = supplements[pick(0..supplements.len())];
ok &= apply(start..start, supplement); ok &= apply(start..start, supplement);
@ -614,6 +614,15 @@ fn test_reparse(text: &str, i: usize, rng: &mut LinearShift) -> bool {
ok ok
} }
/// Returns all leaf descendants of a node (may include itself).
fn leafs(node: &SyntaxNode) -> Vec<SyntaxNode> {
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). /// Ensure that all spans are properly ordered (and therefore unique).
#[track_caller] #[track_caller]
fn test_spans(root: &SyntaxNode) -> bool { fn test_spans(root: &SyntaxNode) -> bool {