diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-05-31 10:40:30 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-05-31 10:40:30 +0200 |
| commit | 08a6188123ad0806986fa4f5477b728a07d081cc (patch) | |
| tree | 3338f1d64ebdd6df734bcc9ae0172bda2e075a2a /src/syntax | |
| parent | 665ed12825918bd02a6d6dbcb67860a83dd41600 (diff) | |
Remove green/red distinction
Diffstat (limited to 'src/syntax')
| -rw-r--r-- | src/syntax/ast.rs | 153 | ||||
| -rw-r--r-- | src/syntax/highlight.rs | 26 | ||||
| -rw-r--r-- | src/syntax/mod.rs | 433 |
3 files changed, 209 insertions, 403 deletions
diff --git a/src/syntax/ast.rs b/src/syntax/ast.rs index 0f575f31..99c6b39f 100644 --- a/src/syntax/ast.rs +++ b/src/syntax/ast.rs @@ -1,25 +1,25 @@ -//! A typed layer over the red-green tree. +//! A typed layer over the untyped syntax tree. //! //! The AST is rooted in the [`Markup`] node. use std::num::NonZeroUsize; use std::ops::Deref; -use super::{Green, GreenData, NodeKind, RedNode, RedRef, Span, Spanned}; +use super::{NodeData, NodeKind, Span, Spanned, SyntaxNode}; use crate::geom::{AngleUnit, LengthUnit}; use crate::util::EcoString; /// A typed AST node. pub trait TypedNode: Sized { - /// Convert from a red node to a typed node. - fn from_red(value: RedRef) -> Option<Self>; + /// Convert a node into its typed variant. + fn from_untyped(node: &SyntaxNode) -> Option<Self>; - /// A reference to the underlying red node. - fn as_red(&self) -> RedRef<'_>; + /// A reference to the underlying syntax node. + fn as_untyped(&self) -> &SyntaxNode; /// The source code location. fn span(&self) -> Span { - self.as_red().span() + self.as_untyped().span() } } @@ -34,19 +34,19 @@ macro_rules! node { #[derive(Debug, Clone, PartialEq, Hash)] #[repr(transparent)] $(#[$attr])* - pub struct $name(RedNode); + pub struct $name(SyntaxNode); impl TypedNode for $name { - fn from_red(node: RedRef) -> Option<Self> { + fn from_untyped(node: &SyntaxNode) -> Option<Self> { if matches!(node.kind(), $variants) { - Some(Self(node.own())) + Some(Self(node.clone())) } else { None } } - fn as_red(&self) -> RedRef<'_> { - self.0.as_ref() + fn as_untyped(&self) -> &SyntaxNode { + &self.0 } } }; @@ -77,7 +77,10 @@ impl Markup { NodeKind::Strong => node.cast().map(MarkupNode::Strong), NodeKind::Emph => node.cast().map(MarkupNode::Emph), NodeKind::Raw(raw) => Some(MarkupNode::Raw(raw.as_ref().clone())), - NodeKind::Math(math) => Some(MarkupNode::Math(Spanned::new(math.as_ref().clone(), node.span()))), + NodeKind::Math(math) => Some(MarkupNode::Math(Spanned::new( + math.as_ref().clone(), + node.span(), + ))), NodeKind::Heading => node.cast().map(MarkupNode::Heading), NodeKind::List => node.cast().map(MarkupNode::List), NodeKind::Enum => node.cast().map(MarkupNode::Enum), @@ -279,7 +282,7 @@ pub enum Expr { } impl TypedNode for Expr { - fn from_red(node: RedRef) -> Option<Self> { + fn from_untyped(node: &SyntaxNode) -> Option<Self> { match node.kind() { NodeKind::Ident(_) => node.cast().map(Self::Ident), NodeKind::CodeBlock => node.cast().map(Self::Code), @@ -309,33 +312,33 @@ impl TypedNode for Expr { } } - fn as_red(&self) -> RedRef<'_> { + fn as_untyped(&self) -> &SyntaxNode { match self { - Self::Lit(v) => v.as_red(), - Self::Code(v) => v.as_red(), - Self::Content(v) => v.as_red(), - Self::Ident(v) => v.as_red(), - Self::Array(v) => v.as_red(), - Self::Dict(v) => v.as_red(), - Self::Group(v) => v.as_red(), - Self::Unary(v) => v.as_red(), - Self::Binary(v) => v.as_red(), - Self::FieldAccess(v) => v.as_red(), - Self::FuncCall(v) => v.as_red(), - Self::MethodCall(v) => v.as_red(), - Self::Closure(v) => v.as_red(), - Self::Let(v) => v.as_red(), - Self::Set(v) => v.as_red(), - Self::Show(v) => v.as_red(), - Self::Wrap(v) => v.as_red(), - Self::If(v) => v.as_red(), - Self::While(v) => v.as_red(), - Self::For(v) => v.as_red(), - Self::Import(v) => v.as_red(), - Self::Include(v) => v.as_red(), - Self::Break(v) => v.as_red(), - Self::Continue(v) => v.as_red(), - Self::Return(v) => v.as_red(), + Self::Lit(v) => v.as_untyped(), + Self::Code(v) => v.as_untyped(), + Self::Content(v) => v.as_untyped(), + Self::Ident(v) => v.as_untyped(), + Self::Array(v) => v.as_untyped(), + Self::Dict(v) => v.as_untyped(), + Self::Group(v) => v.as_untyped(), + Self::Unary(v) => v.as_untyped(), + Self::Binary(v) => v.as_untyped(), + Self::FieldAccess(v) => v.as_untyped(), + Self::FuncCall(v) => v.as_untyped(), + Self::MethodCall(v) => v.as_untyped(), + Self::Closure(v) => v.as_untyped(), + Self::Let(v) => v.as_untyped(), + Self::Set(v) => v.as_untyped(), + Self::Show(v) => v.as_untyped(), + Self::Wrap(v) => v.as_untyped(), + Self::If(v) => v.as_untyped(), + Self::While(v) => v.as_untyped(), + Self::For(v) => v.as_untyped(), + Self::Import(v) => v.as_untyped(), + Self::Include(v) => v.as_untyped(), + Self::Break(v) => v.as_untyped(), + Self::Continue(v) => v.as_untyped(), + Self::Return(v) => v.as_untyped(), } } } @@ -429,7 +432,7 @@ node! { impl CodeBlock { /// The list of expressions contained in the block. pub fn exprs(&self) -> impl Iterator<Item = Expr> + '_ { - self.0.children().filter_map(RedRef::cast) + self.0.children().filter_map(SyntaxNode::cast) } } @@ -465,7 +468,7 @@ node! { impl ArrayExpr { /// The array items. pub fn items(&self) -> impl Iterator<Item = ArrayItem> + '_ { - self.0.children().filter_map(RedRef::cast) + self.0.children().filter_map(SyntaxNode::cast) } } @@ -479,17 +482,17 @@ pub enum ArrayItem { } impl TypedNode for ArrayItem { - fn from_red(node: RedRef) -> Option<Self> { + fn from_untyped(node: &SyntaxNode) -> Option<Self> { match node.kind() { NodeKind::Spread => node.cast_first_child().map(Self::Spread), _ => node.cast().map(Self::Pos), } } - fn as_red(&self) -> RedRef<'_> { + fn as_untyped(&self) -> &SyntaxNode { match self { - Self::Pos(v) => v.as_red(), - Self::Spread(v) => v.as_red(), + Self::Pos(v) => v.as_untyped(), + Self::Spread(v) => v.as_untyped(), } } } @@ -502,7 +505,7 @@ node! { impl DictExpr { /// The named dictionary items. pub fn items(&self) -> impl Iterator<Item = DictItem> + '_ { - self.0.children().filter_map(RedRef::cast) + self.0.children().filter_map(SyntaxNode::cast) } } @@ -518,7 +521,7 @@ pub enum DictItem { } impl TypedNode for DictItem { - fn from_red(node: RedRef) -> Option<Self> { + fn from_untyped(node: &SyntaxNode) -> Option<Self> { match node.kind() { NodeKind::Named => node.cast().map(Self::Named), NodeKind::Keyed => node.cast().map(Self::Keyed), @@ -527,11 +530,11 @@ impl TypedNode for DictItem { } } - fn as_red(&self) -> RedRef<'_> { + fn as_untyped(&self) -> &SyntaxNode { match self { - Self::Named(v) => v.as_red(), - Self::Keyed(v) => v.as_red(), - Self::Spread(v) => v.as_red(), + Self::Named(v) => v.as_untyped(), + Self::Keyed(v) => v.as_untyped(), + Self::Spread(v) => v.as_untyped(), } } } @@ -895,7 +898,7 @@ node! { impl CallArgs { /// The positional and named arguments. pub fn items(&self) -> impl Iterator<Item = CallArg> + '_ { - self.0.children().filter_map(RedRef::cast) + self.0.children().filter_map(SyntaxNode::cast) } } @@ -911,7 +914,7 @@ pub enum CallArg { } impl TypedNode for CallArg { - fn from_red(node: RedRef) -> Option<Self> { + fn from_untyped(node: &SyntaxNode) -> Option<Self> { match node.kind() { NodeKind::Named => node.cast().map(Self::Named), NodeKind::Spread => node.cast_first_child().map(Self::Spread), @@ -919,11 +922,11 @@ impl TypedNode for CallArg { } } - fn as_red(&self) -> RedRef<'_> { + fn as_untyped(&self) -> &SyntaxNode { match self { - Self::Pos(v) => v.as_red(), - Self::Named(v) => v.as_red(), - Self::Spread(v) => v.as_red(), + Self::Pos(v) => v.as_untyped(), + Self::Named(v) => v.as_untyped(), + Self::Spread(v) => v.as_untyped(), } } } @@ -948,7 +951,7 @@ impl ClosureExpr { .find(|x| x.kind() == &NodeKind::ClosureParams) .expect("closure is missing parameter list") .children() - .filter_map(RedRef::cast) + .filter_map(SyntaxNode::cast) } /// The body of the closure. @@ -969,7 +972,7 @@ pub enum ClosureParam { } impl TypedNode for ClosureParam { - fn from_red(node: RedRef) -> Option<Self> { + fn from_untyped(node: &SyntaxNode) -> Option<Self> { match node.kind() { NodeKind::Ident(_) => node.cast().map(Self::Pos), NodeKind::Named => node.cast().map(Self::Named), @@ -978,11 +981,11 @@ impl TypedNode for ClosureParam { } } - fn as_red(&self) -> RedRef<'_> { + fn as_untyped(&self) -> &SyntaxNode { match self { - Self::Pos(v) => v.as_red(), - Self::Named(v) => v.as_red(), - Self::Sink(v) => v.as_red(), + Self::Pos(v) => v.as_untyped(), + Self::Named(v) => v.as_untyped(), + Self::Sink(v) => v.as_untyped(), } } } @@ -1007,7 +1010,7 @@ impl LetExpr { /// The expression the binding is initialized with. pub fn init(&self) -> Option<Expr> { if self.0.cast_first_child::<Ident>().is_some() { - self.0.children().filter_map(RedRef::cast).nth(1) + self.0.children().filter_map(SyntaxNode::cast).nth(1) } else { // This is a let .. with expression. self.0.cast_first_child() @@ -1042,7 +1045,7 @@ impl ShowExpr { pub fn binding(&self) -> Option<Ident> { let mut children = self.0.children(); children - .find_map(RedRef::cast) + .find_map(SyntaxNode::cast) .filter(|_| children.any(|child| child.kind() == &NodeKind::Colon)) } @@ -1052,7 +1055,7 @@ impl ShowExpr { .children() .rev() .skip_while(|child| child.kind() != &NodeKind::As) - .find_map(RedRef::cast) + .find_map(SyntaxNode::cast) .expect("show rule is missing pattern") } @@ -1094,14 +1097,14 @@ impl IfExpr { pub fn if_body(&self) -> Expr { self.0 .children() - .filter_map(RedRef::cast) + .filter_map(SyntaxNode::cast) .nth(1) .expect("if expression is missing body") } /// The expression to evaluate if the condition is false. pub fn else_body(&self) -> Option<Expr> { - self.0.children().filter_map(RedRef::cast).nth(2) + self.0.children().filter_map(SyntaxNode::cast).nth(2) } } @@ -1152,7 +1155,7 @@ node! { impl ForPattern { /// The key part of the pattern: index for arrays, name for dictionaries. pub fn key(&self) -> Option<Ident> { - let mut children = self.0.children().filter_map(RedRef::cast); + let mut children = self.0.children().filter_map(SyntaxNode::cast); let key = children.next(); if children.next().is_some() { key } else { None } } @@ -1176,7 +1179,7 @@ impl ImportExpr { .find_map(|node| match node.kind() { NodeKind::Star => Some(Imports::Wildcard), NodeKind::ImportItems => { - let items = node.children().filter_map(RedRef::cast).collect(); + let items = node.children().filter_map(SyntaxNode::cast).collect(); Some(Imports::Items(items)) } _ => None, @@ -1241,8 +1244,8 @@ node! { impl Ident { /// Take out the contained [`EcoString`]. pub fn take(self) -> EcoString { - match self.0.green { - Green::Token(GreenData { kind: NodeKind::Ident(id), .. }) => id, + match self.0 { + SyntaxNode::Leaf(NodeData { kind: NodeKind::Ident(id), .. }) => id, _ => panic!("identifier is of wrong kind"), } } @@ -1252,8 +1255,8 @@ impl Deref for Ident { type Target = str; fn deref(&self) -> &Self::Target { - match &self.0.green { - Green::Token(GreenData { kind: NodeKind::Ident(id), .. }) => id, + match &self.0 { + SyntaxNode::Leaf(NodeData { kind: NodeKind::Ident(id), .. }) => id, _ => panic!("identifier is of wrong kind"), } } diff --git a/src/syntax/highlight.rs b/src/syntax/highlight.rs index 94abc238..1b84fdba 100644 --- a/src/syntax/highlight.rs +++ b/src/syntax/highlight.rs @@ -5,13 +5,12 @@ use std::sync::Arc; use syntect::highlighting::{Color, FontStyle, Highlighter, Style, Theme}; use syntect::parsing::Scope; -use super::{GreenNode, NodeKind, RedNode, RedRef}; +use super::{InnerNode, NodeKind, SyntaxNode}; use crate::parse::TokenMode; -use crate::source::SourceId; /// Provide highlighting categories for the descendants of a node that fall into /// a range. -pub fn highlight_node<F>(node: RedRef, range: Range<usize>, f: &mut F) +pub fn highlight_node<F>(node: &SyntaxNode, range: Range<usize>, f: &mut F) where F: FnMut(Range<usize>, Category), { @@ -36,20 +35,21 @@ where TokenMode::Markup => crate::parse::parse(text), TokenMode::Code => { let children = crate::parse::parse_code(text); - Arc::new(GreenNode::with_children(NodeKind::CodeBlock, children)) + SyntaxNode::Inner(Arc::new(InnerNode::with_children( + NodeKind::CodeBlock, + children, + ))) } }; - let root = RedNode::from_root(root, SourceId::from_raw(0)); let highlighter = Highlighter::new(&theme); - - highlight_themed_impl(text, root.as_ref(), vec![], &highlighter, f); + highlight_themed_impl(text, &root, vec![], &highlighter, f); } /// Recursive implementation for returning syntect styles. fn highlight_themed_impl<F>( text: &str, - node: RedRef, + node: &SyntaxNode, scopes: Vec<Scope>, highlighter: &Highlighter, f: &mut F, @@ -178,7 +178,11 @@ pub enum Category { impl Category { /// Determine the highlighting category of a node given its parent and its /// index in its siblings. - pub fn determine(child: RedRef, parent: RedRef, i: usize) -> Option<Category> { + pub fn determine( + child: &SyntaxNode, + parent: &SyntaxNode, + i: usize, + ) -> Option<Category> { match child.kind() { NodeKind::LeftBrace => Some(Category::Bracket), NodeKind::RightBrace => Some(Category::Bracket), @@ -262,7 +266,7 @@ impl Category { if parent .children() .filter(|c| matches!(c.kind(), NodeKind::Ident(_))) - .map(RedRef::span) + .map(SyntaxNode::span) .nth(1) .map_or(false, |span| span == child.span()) => { @@ -359,7 +363,7 @@ mod tests { let mut vec = vec![]; let source = SourceFile::detached(src); let full = 0 .. src.len(); - highlight_node(source.red().as_ref(), full, &mut |range, category| { + highlight_node(source.root(), full, &mut |range, category| { vec.push((range, category)); }); assert_eq!(vec, goal); diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index 69bcb0a0..841c16ff 100644 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -14,24 +14,23 @@ pub use span::*; use self::ast::{MathNode, RawNode, TypedNode, Unit}; use crate::diag::Error; -use crate::source::SourceId; use crate::util::EcoString; -/// An inner or leaf node in the untyped green tree. +/// An inner or leaf node in the untyped syntax tree. #[derive(Clone, PartialEq, Hash)] -pub enum Green { +pub enum SyntaxNode { /// A reference-counted inner node. - Node(Arc<GreenNode>), - /// A terminal, owned token. - Token(GreenData), + Inner(Arc<InnerNode>), + /// A leaf token. + Leaf(NodeData), } -impl Green { +impl SyntaxNode { /// Returns the metadata of the node. - fn data(&self) -> &GreenData { + pub fn data(&self) -> &NodeData { match self { - Green::Node(n) => &n.data, - Green::Token(t) => t, + SyntaxNode::Inner(n) => &n.data, + SyntaxNode::Leaf(t) => t, } } @@ -45,106 +44,146 @@ impl Green { self.data().len() } - /// Whether the node or its children contain an error. - pub fn erroneous(&self) -> bool { - match self { - Self::Node(node) => node.erroneous, - Self::Token(data) => data.kind.is_error(), - } + /// The span of the node. + pub fn span(&self) -> Span { + todo!() } /// The node's children. - pub fn children(&self) -> &[Green] { + pub fn children(&self) -> std::slice::Iter<'_, SyntaxNode> { match self { - Green::Node(n) => n.children(), - Green::Token(_) => &[], + SyntaxNode::Inner(n) => n.children(), + SyntaxNode::Leaf(_) => [].iter(), + } + } + + /// Returns all leaf descendants of this node (may include itself). + /// + /// This method is slow and only intended for testing. + pub fn leafs(&self) -> Vec<Self> { + if match self { + SyntaxNode::Inner(n) => n.children().len() == 0, + SyntaxNode::Leaf(_) => true, + } { + vec![self.clone()] + } else { + self.children().flat_map(Self::leafs).collect() } } - /// Whether the node is a leaf node in the green tree. - pub fn is_leaf(&self) -> bool { + /// Whether the node or its children contain an error. + pub fn erroneous(&self) -> bool { match self { - Green::Node(n) => n.children().is_empty(), - Green::Token(_) => true, + 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<Error> { + if !self.erroneous() { + return vec![]; + } + + match self.kind() { + NodeKind::Error(..) => todo!(), + _ => self + .children() + .filter(|node| node.erroneous()) + .flat_map(|node| node.errors()) + .collect(), } } + /// Convert the node to a typed AST node. + pub fn cast<T>(&self) -> Option<T> + where + T: TypedNode, + { + T::from_untyped(self) + } + + /// Get the first child that can cast to some AST type. + pub fn cast_first_child<T: TypedNode>(&self) -> Option<T> { + self.children().find_map(Self::cast) + } + + /// Get the last child that can cast to some AST type. + pub fn cast_last_child<T: TypedNode>(&self) -> Option<T> { + self.children().rev().find_map(Self::cast) + } + /// Change the type of the node. pub fn convert(&mut self, kind: NodeKind) { match self { - Self::Node(node) => { + Self::Inner(node) => { let node = Arc::make_mut(node); node.erroneous |= kind.is_error(); node.data.kind = kind; } - Self::Token(data) => data.kind = kind, + Self::Leaf(data) => data.kind = kind, } } /// Set a synthetic span for the node and all its children. pub fn synthesize(&mut self, span: Arc<Span>) { match self { - Green::Node(n) => Arc::make_mut(n).synthesize(span), - Green::Token(t) => t.synthesize(span), + SyntaxNode::Inner(n) => Arc::make_mut(n).synthesize(span), + SyntaxNode::Leaf(t) => t.synthesize(span), } } } -impl Default for Green { +impl Default for SyntaxNode { fn default() -> Self { - Self::Token(GreenData::new(NodeKind::None, 0)) + Self::Leaf(NodeData::new(NodeKind::None, 0)) } } -impl Debug for Green { +impl Debug for SyntaxNode { fn fmt(&self, f: &mut Formatter) -> fmt::Result { match self { - Self::Node(node) => node.fmt(f), - Self::Token(token) => token.fmt(f), + Self::Inner(node) => node.fmt(f), + Self::Leaf(token) => token.fmt(f), } } } -/// An inner node in the untyped green tree. +/// An inner node in the untyped syntax tree. #[derive(Clone, PartialEq, Hash)] -pub struct GreenNode { +pub struct InnerNode { /// Node metadata. - data: GreenData, + data: NodeData, /// This node's children, losslessly make up this node. - children: Vec<Green>, + children: Vec<SyntaxNode>, /// Whether this node or any of its children are erroneous. erroneous: bool, } -impl GreenNode { +impl InnerNode { /// Creates a new node with the given kind and a single child. - pub fn with_child(kind: NodeKind, child: impl Into<Green>) -> Self { + pub fn with_child(kind: NodeKind, child: impl Into<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<Green>) -> Self { + pub fn with_children(kind: NodeKind, children: Vec<SyntaxNode>) -> Self { let mut erroneous = kind.is_error(); let len = children .iter() .inspect(|c| erroneous |= c.erroneous()) - .map(Green::len) + .map(SyntaxNode::len) .sum(); Self { - data: GreenData::new(kind, len), + data: NodeData::new(kind, len), children, erroneous, } } - /// The node's children. - pub fn children(&self) -> &[Green] { - &self.children - } - /// The node's metadata. - fn data(&self) -> &GreenData { + pub fn data(&self) -> &NodeData { &self.data } @@ -158,6 +197,11 @@ impl GreenNode { self.data().len() } + /// 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 children. pub fn synthesize(&mut self, span: Arc<Span>) { self.data.synthesize(span.clone()); @@ -167,7 +211,7 @@ impl GreenNode { } /// The node's children, mutably. - pub(crate) fn children_mut(&mut self) -> &mut [Green] { + pub(crate) fn children_mut(&mut self) -> &mut [SyntaxNode] { &mut self.children } @@ -175,42 +219,44 @@ impl GreenNode { pub(crate) fn replace_children( &mut self, range: Range<usize>, - replacement: Vec<Green>, + replacement: Vec<SyntaxNode>, ) { let superseded = &self.children[range.clone()]; - let superseded_len: usize = superseded.iter().map(Green::len).sum(); - let replacement_len: usize = replacement.iter().map(Green::len).sum(); + let superseded_len: usize = superseded.iter().map(SyntaxNode::len).sum(); + let replacement_len: usize = replacement.iter().map(SyntaxNode::len).sum(); // If we're erroneous, but not due to the superseded range, then we will // still be erroneous after the replacement. - let still_erroneous = self.erroneous && !superseded.iter().any(Green::erroneous); + let still_erroneous = + self.erroneous && !superseded.iter().any(SyntaxNode::erroneous); self.children.splice(range, replacement); self.data.len = self.data.len + replacement_len - superseded_len; - self.erroneous = still_erroneous || self.children.iter().any(Green::erroneous); + self.erroneous = + still_erroneous || self.children.iter().any(SyntaxNode::erroneous); } /// Update the length of this node given the old and new length of /// replaced children. pub(crate) fn update_parent(&mut self, new_len: usize, old_len: usize) { self.data.len = self.data.len() + new_len - old_len; - self.erroneous = self.children.iter().any(Green::erroneous); + self.erroneous = self.children.iter().any(SyntaxNode::erroneous); } } -impl From<GreenNode> for Green { - fn from(node: GreenNode) -> Self { +impl From<InnerNode> for SyntaxNode { + fn from(node: InnerNode) -> Self { Arc::new(node).into() } } -impl From<Arc<GreenNode>> for Green { - fn from(node: Arc<GreenNode>) -> Self { - Self::Node(node) +impl From<Arc<InnerNode>> for SyntaxNode { + fn from(node: Arc<InnerNode>) -> Self { + Self::Inner(node) } } -impl Debug for GreenNode { +impl Debug for InnerNode { fn fmt(&self, f: &mut Formatter) -> fmt::Result { self.data.fmt(f)?; if !self.children.is_empty() { @@ -223,20 +269,18 @@ impl Debug for GreenNode { /// Data shared between inner and leaf nodes. #[derive(Clone, PartialEq, Hash)] -pub struct GreenData { +pub struct NodeData { /// What kind of node this is (each kind would have its own struct in a /// strongly typed AST). kind: NodeKind, /// The byte length of the node in the source. len: usize, - /// A synthetic span for the node, usually this is `None`. - span: Option<Arc<Span>>, } -impl GreenData { +impl NodeData { /// Create new node metadata. pub fn new(kind: NodeKind, len: usize) -> Self { - Self { len, kind, span: None } + Self { len, kind } } /// The type of the node. @@ -250,271 +294,26 @@ impl GreenData { } /// Set a synthetic span for the node. - pub fn synthesize(&mut self, span: Arc<Span>) { - self.span = Some(span) + pub fn synthesize(&mut self, _: Arc<Span>) { + todo!() } } -impl From<GreenData> for Green { - fn from(token: GreenData) -> Self { - Self::Token(token) +impl From<NodeData> for SyntaxNode { + fn from(token: NodeData) -> Self { + Self::Leaf(token) } } -impl Debug for GreenData { +impl Debug for NodeData { fn fmt(&self, f: &mut Formatter) -> fmt::Result { write!(f, "{:?}: {}", self.kind, self.len) } } -/// A owned wrapper for a green node with span information. -/// -/// Owned variant of [`RedRef`]. Can be [cast](Self::cast) to an AST node. -#[derive(Clone, PartialEq, Hash)] -pub struct RedNode { - id: SourceId, - offset: usize, - green: Green, -} - -impl RedNode { - /// Create a new red node from a root [`GreenNode`]. - pub fn from_root(root: Arc<GreenNode>, id: SourceId) -> Self { - Self { id, offset: 0, green: root.into() } - } - - /// Convert to a borrowed representation. - pub fn as_ref(&self) -> RedRef<'_> { - RedRef { - id: self.id, - offset: self.offset, - green: &self.green, - } - } - - /// The node's metadata. - pub fn data(&self) -> &GreenData { - self.as_ref().data() - } - - /// The type of the node. - pub fn kind(&self) -> &NodeKind { - self.as_ref().kind() - } - - /// The length of the node. - pub fn len(&self) -> usize { - self.as_ref().len() - } - - /// The span of the node. - pub fn span(&self) -> Span { - self.as_ref().span() - } - - /// The error messages for this node and its descendants. - pub fn errors(&self) -> Vec<Error> { - self.as_ref().errors() - } - - /// Convert the node to a typed AST node. - pub fn cast<T>(self) -> Option<T> - where - T: TypedNode, - { - self.as_ref().cast() - } - - /// The children of the node. - pub fn children(&self) -> Children<'_> { - self.as_ref().children() - } - - /// Get the first child that can cast to some AST type. - pub fn cast_first_child<T: TypedNode>(&self) -> Option<T> { - self.as_ref().cast_first_child() - } - - /// Get the last child that can cast to some AST type. - pub fn cast_last_child<T: TypedNode>(&self) -> Option<T> { - self.as_ref().cast_last_child() - } -} - -impl Debug for RedNode { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - self.as_ref().fmt(f) - } -} - -/// A borrowed wrapper for a [`GreenNode`] with span information. -/// -/// Borrowed variant of [`RedNode`]. Can be [cast](Self::cast) to an AST node. -#[derive(Copy, Clone, PartialEq, Hash)] -pub struct RedRef<'a> { - id: SourceId, - offset: usize, - green: &'a Green, -} - -impl<'a> RedRef<'a> { - /// Convert to an owned representation. - pub fn own(self) -> RedNode { - RedNode { - id: self.id, - offset: self.offset, - green: self.green.clone(), - } - } - - /// The node's metadata. - pub fn data(self) -> &'a GreenData { - self.green.data() - } - - /// The type of the node. - pub fn kind(self) -> &'a NodeKind { - self.green.kind() - } - - /// The length of the node. - pub fn len(self) -> usize { - self.green.len() - } - - /// The span of the node. - pub fn span(self) -> Span { - match self.data().span.as_deref() { - Some(&span) => span, - None => Span::new(self.id, self.offset, self.offset + self.len()), - } - } - - /// Whether the node is a leaf node. - pub fn is_leaf(self) -> bool { - self.green.is_leaf() - } - - /// The error messages for this node and its descendants. - pub fn errors(self) -> Vec<Error> { - if !self.green.erroneous() { - return vec![]; - } - - match self.kind() { - NodeKind::Error(pos, msg) => { - let mut span = self.span(); - if self.data().span.is_none() { - span = match pos { - ErrorPos::Start => span.at_start(), - ErrorPos::Full => span, - ErrorPos::End => span.at_end(), - }; - } - - vec![Error::new(span, msg.to_string())] - } - _ => self - .children() - .filter(|red| red.green.erroneous()) - .flat_map(|red| red.errors()) - .collect(), - } - } - - /// Returns all leaf descendants of this node (may include itself). - pub fn leafs(self) -> Vec<Self> { - if self.is_leaf() { - vec![self] - } else { - self.children().flat_map(Self::leafs).collect() - } - } - - /// Convert the node to a typed AST node. - pub fn cast<T>(self) -> Option<T> - where - T: TypedNode, - { - T::from_red(self) - } - - /// The node's children. - pub fn children(self) -> Children<'a> { - let children = match &self.green { - Green::Node(node) => node.children(), - Green::Token(_) => &[], - }; - - Children { - id: self.id, - iter: children.iter(), - front: self.offset, - back: self.offset + self.len(), - } - } - - /// Get the first child that can cast to some AST type. - pub fn cast_first_child<T: TypedNode>(self) -> Option<T> { - self.children().find_map(RedRef::cast) - } - - /// Get the last child that can cast to some AST type. - pub fn cast_last_child<T: TypedNode>(self) -> Option<T> { - self.children().rev().find_map(RedRef::cast) - } -} - -impl Debug for RedRef<'_> { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - write!(f, "{:?}: {:?}", self.kind(), self.span())?; - let mut children = self.children().peekable(); - if children.peek().is_some() { - f.write_str(" ")?; - f.debug_list().entries(children.map(RedRef::own)).finish()?; - } - Ok(()) - } -} - -/// An iterator over the children of a red node. -pub struct Children<'a> { - id: SourceId, - iter: std::slice::Iter<'a, Green>, - front: usize, - back: usize, -} - -impl<'a> Iterator for Children<'a> { - type Item = RedRef<'a>; - - fn next(&mut self) -> Option<Self::Item> { - self.iter.next().map(|green| { - let offset = self.front; - self.front += green.len(); - RedRef { id: self.id, offset, green } - }) - } - - fn size_hint(&self) -> (usize, Option<usize>) { - self.iter.size_hint() - } -} - -impl DoubleEndedIterator for Children<'_> { - fn next_back(&mut self) -> Option<Self::Item> { - self.iter.next_back().map(|green| { - self.back -= green.len(); - RedRef { id: self.id, offset: self.back, green } - }) - } -} - -impl ExactSizeIterator for Children<'_> {} - /// All syntactical building blocks that can be part of a Typst document. /// -/// Can be emitted as a token by the tokenizer or as part of a green node by +/// Can be emitted as a token by the tokenizer or as part of a syntax node by /// the parser. #[derive(Debug, Clone, PartialEq)] pub enum NodeKind { |
