summaryrefslogtreecommitdiff
path: root/src/syntax/mod.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-06-13 23:16:40 +0200
committerLaurenz <laurmaedje@gmail.com>2022-06-14 13:53:02 +0200
commitc81e2a5f56eb262663f292578c683fba7f18251f (patch)
tree6c045a8dcbec5e75e01a15f970ef8cee6ff042d0 /src/syntax/mod.rs
parent891af17260a6750a74a102388a05e59cf1ffc3c1 (diff)
Many fixes
Diffstat (limited to 'src/syntax/mod.rs')
-rw-r--r--src/syntax/mod.rs157
1 files changed, 73 insertions, 84 deletions
diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs
index 7086ad4c..4bae7a4b 100644
--- a/src/syntax/mod.rs
+++ b/src/syntax/mod.rs
@@ -27,7 +27,7 @@ pub enum SyntaxNode {
}
impl SyntaxNode {
- /// Returns the metadata of the node.
+ /// The metadata of the node.
pub fn data(&self) -> &NodeData {
match self {
Self::Inner(inner) => &inner.data,
@@ -58,14 +58,6 @@ impl SyntaxNode {
self.data().span()
}
- /// The node's children.
- pub fn children(&self) -> std::slice::Iter<'_, SyntaxNode> {
- match self {
- Self::Inner(inner) => inner.children(),
- Self::Leaf(_) => [].iter(),
- }
- }
-
/// Whether the node or its children contain an error.
pub fn erroneous(&self) -> bool {
match self {
@@ -92,6 +84,14 @@ impl SyntaxNode {
}
}
+ /// The node's children.
+ pub fn children(&self) -> std::slice::Iter<'_, SyntaxNode> {
+ match self {
+ Self::Inner(inner) => inner.children(),
+ Self::Leaf(_) => [].iter(),
+ }
+ }
+
/// Convert the node to a typed AST node.
pub fn cast<T>(&self) -> Option<T>
where
@@ -100,12 +100,12 @@ impl SyntaxNode {
T::from_untyped(self)
}
- /// Get the first child that can cast to some AST type.
+ /// Get the first child that can cast to the AST type `T`.
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.
+ /// Get the last child that can cast to the AST type `T`.
pub fn cast_last_child<T: TypedNode>(&self) -> Option<T> {
self.children().rev().find_map(Self::cast)
}
@@ -358,7 +358,7 @@ impl InnerNode {
&mut self.children
}
- /// Replaces a range of children with some replacement.
+ /// Replaces a range of children with a replacement.
///
/// May have mutated the children if it returns `Err(_)`.
pub(crate) fn replace_children(
@@ -440,8 +440,7 @@ impl InnerNode {
}
}
- /// Update the this node given after changes were made to one of its
- /// children.
+ /// Update this node after changes were made to one of its children.
pub(crate) fn update_parent(
&mut self,
prev_len: usize,
@@ -572,57 +571,61 @@ impl PartialEq for NodeData {
/// the parser.
#[derive(Debug, Clone, PartialEq)]
pub enum NodeKind {
- /// A left curly brace: `{`.
+ /// A left curly brace, starting a code block: `{`.
LeftBrace,
- /// A right curly brace: `}`.
+ /// A right curly brace, terminating a code block: `}`.
RightBrace,
- /// A left square bracket: `[`.
+ /// A left square bracket, starting a content block: `[`.
LeftBracket,
- /// A right square bracket: `]`.
+ /// A right square bracket, terminating a content block: `]`.
RightBracket,
- /// A left round parenthesis: `(`.
+ /// A left round parenthesis, starting a grouped expression, collection,
+ /// argument or parameter list: `(`.
LeftParen,
- /// A right round parenthesis: `)`.
+ /// A right round parenthesis, terminating a grouped expression, collection,
+ /// argument or parameter list: `)`.
RightParen,
- /// An asterisk: `*`.
+ /// The strong text toggle, multiplication operator, and wildcard import
+ /// symbol: `*`.
Star,
- /// An underscore: `_`.
+ /// Toggles emphasized text: `_`.
Underscore,
- /// A comma: `,`.
+ /// A comma separator in a sequence: `,`.
Comma,
- /// A semicolon: `;`.
+ /// A semicolon terminating an expression: `;`.
Semicolon,
- /// A colon: `:`.
+ /// A colon between name / key and value in a dictionary, argument or
+ /// parameter list: `:`.
Colon,
- /// A plus: `+`.
+ /// The unary plus and addition operator: `+`.
Plus,
- /// A hyphen: `-`.
+ /// The unary negation and subtraction operator: `-`.
Minus,
- /// A slash: `/`.
+ /// The division operator: `/`.
Slash,
- /// A dot: `.`.
+ /// A field access and method call operator: `.`.
Dot,
- /// A single equals sign: `=`.
+ /// The assignment operator: `=`.
Eq,
- /// Two equals signs: `==`.
+ /// The equality operator: `==`.
EqEq,
- /// An exclamation mark followed by an equals sign: `!=`.
+ /// The inequality operator: `!=`.
ExclEq,
- /// A less-than sign: `<`.
+ /// The less-than operator: `<`.
Lt,
- /// A less-than sign followed by an equals sign: `<=`.
+ /// The less-than or equal operator: `<=`.
LtEq,
- /// A greater-than sign: `>`.
+ /// The greater-than operator: `>`.
Gt,
- /// A greater-than sign followed by an equals sign: `>=`.
+ /// The greater-than or equal operator: `>=`.
GtEq,
- /// A plus followed by an equals sign: `+=`.
+ /// The add-assign operator: `+=`.
PlusEq,
- /// A hyphen followed by an equals sign: `-=`.
+ /// The subtract-assign operator: `-=`.
HyphEq,
- /// An asterisk followed by an equals sign: `*=`.
+ /// The multiply-assign operator: `*=`.
StarEq,
- /// A slash followed by an equals sign: `/=`.
+ /// The divide-assign operator: `/=`.
SlashEq,
/// The `not` operator.
Not,
@@ -630,9 +633,9 @@ pub enum NodeKind {
And,
/// The `or` operator.
Or,
- /// Two dots: `..`.
+ /// The spread operator: `..`.
Dots,
- /// An equals sign followed by a greater-than sign: `=>`.
+ /// An arrow between a closure's parameters and body: `=>`.
Arrow,
/// The none literal: `none`.
None,
@@ -670,15 +673,20 @@ pub enum NodeKind {
From,
/// The `as` keyword.
As,
- /// Markup of which all lines must start in some column.
+ /// Markup of which all lines must have a minimal indentation.
///
/// Notably, the number does not determine in which column the markup
/// started, but to the right of which column all markup elements must be,
/// so it is zero except for headings and lists.
- Markup(usize),
- /// One or more whitespace characters.
- Space(usize),
- /// A consecutive non-markup string.
+ Markup { min_indent: usize },
+ /// One or more whitespace characters. Single spaces are collapsed into text
+ /// nodes if they would otherwise be surrounded by text nodes.
+ ///
+ /// Also stores how many newlines are contained.
+ Space { newlines: usize },
+ /// Consecutive text without markup. While basic text with just single
+ /// spaces is collapsed into a single node, certain symbols that could
+ /// possibly be markup force text into multiple nodes.
Text(EcoString),
/// A forced line break: `\` or `\+` if justified.
Linebreak { justified: bool },
@@ -701,10 +709,9 @@ pub enum NodeKind {
Strong,
/// Emphasized content: `_Emphasized_`.
Emph,
- /// An arbitrary number of backticks followed by inner contents, terminated
- /// with the same number of backticks: `` `...` ``.
+ /// A raw block with optional syntax highlighting: `` `...` ``.
Raw(Arc<RawNode>),
- /// Dollar signs surrounding inner contents.
+ /// A math formula: `$x$`, `$[x^2]$`.
Math(Arc<MathNode>),
/// A section heading: `= Introduction`.
Heading,
@@ -740,7 +747,7 @@ pub enum NodeKind {
DictExpr,
/// A named pair: `thickness: 3pt`.
Named,
- /// A keyed pair: `"spaced key": true`.
+ /// A keyed pair: `"spacy key": true`.
Keyed,
/// A unary operation: `-x`.
UnaryExpr,
@@ -803,24 +810,14 @@ pub enum NodeKind {
}
impl NodeKind {
- /// Whether this is some kind of brace.
- pub fn is_brace(&self) -> bool {
- matches!(self, Self::LeftBrace | Self::RightBrace)
- }
-
- /// Whether this is some kind of bracket.
- pub fn is_bracket(&self) -> bool {
- matches!(self, Self::LeftBracket | Self::RightBracket)
- }
-
- /// Whether this is some kind of parenthesis.
+ /// Whether this is a kind of parenthesis.
pub fn is_paren(&self) -> bool {
matches!(self, Self::LeftParen | Self::RightParen)
}
/// Whether this is a space.
pub fn is_space(&self) -> bool {
- matches!(self, Self::Space(_))
+ matches!(self, Self::Space { .. })
}
/// Whether this is trivia.
@@ -828,31 +825,23 @@ impl NodeKind {
self.is_space() || matches!(self, Self::LineComment | Self::BlockComment)
}
- /// Whether this is some kind of error.
+ /// Whether this is a kind of error.
pub fn is_error(&self) -> bool {
matches!(self, NodeKind::Error(_, _) | NodeKind::Unknown(_))
}
- /// Whether this node is `at_start` given the previous value of the property.
+ /// Whether `at_start` would still be true after this node given the
+ /// previous value of the property.
pub fn is_at_start(&self, prev: bool) -> bool {
match self {
- Self::Space(1 ..) => true,
- Self::Space(_) | Self::LineComment | Self::BlockComment => prev,
- _ => false,
- }
- }
-
- /// Whether this node has to appear at the start of a line.
- pub fn only_at_start(&self) -> bool {
- match self {
- Self::Heading | Self::Enum | Self::List => true,
- Self::Text(t) => t == "-" || t.ends_with('.'),
+ Self::Space { newlines: (1 ..) } => true,
+ Self::Space { .. } | Self::LineComment | Self::BlockComment => prev,
_ => false,
}
}
- /// Whether this is a node that is clearly delimited by a character and may
- /// appear in markup.
+ /// Whether changes _inside_ this node are safely encapuslated, so that only
+ /// this node must be reparsed.
pub fn is_bounded(&self) -> bool {
match self {
Self::CodeBlock
@@ -865,7 +854,7 @@ impl NodeKind {
| Self::Ellipsis
| Self::Quote { .. }
| Self::BlockComment
- | Self::Space(_)
+ | Self::Space { .. }
| Self::Escape(_) => true,
Self::Text(t) => t != "-" && !t.ends_with('.'),
_ => false,
@@ -924,9 +913,9 @@ impl NodeKind {
Self::Import => "keyword `import`",
Self::Include => "keyword `include`",
Self::From => "keyword `from`",
- Self::Markup(_) => "markup",
- Self::Space(2 ..) => "paragraph break",
- Self::Space(_) => "space",
+ Self::Markup { .. } => "markup",
+ Self::Space { newlines: (2 ..) } => "paragraph break",
+ Self::Space { .. } => "space",
Self::Linebreak { justified: false } => "linebreak",
Self::Linebreak { justified: true } => "justified linebreak",
Self::Text(_) => "text",
@@ -1052,8 +1041,8 @@ impl Hash for NodeKind {
Self::Import => {}
Self::Include => {}
Self::From => {}
- Self::Markup(c) => c.hash(state),
- Self::Space(n) => n.hash(state),
+ Self::Markup { min_indent } => min_indent.hash(state),
+ Self::Space { newlines } => newlines.hash(state),
Self::Linebreak { justified } => justified.hash(state),
Self::Text(s) => s.hash(state),
Self::NonBreakingSpace => {}