summaryrefslogtreecommitdiff
path: root/crates/typst-syntax/src/node.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/typst-syntax/src/node.rs')
-rw-r--r--crates/typst-syntax/src/node.rs37
1 files changed, 26 insertions, 11 deletions
diff --git a/crates/typst-syntax/src/node.rs b/crates/typst-syntax/src/node.rs
index fed7049c..3c93cd84 100644
--- a/crates/typst-syntax/src/node.rs
+++ b/crates/typst-syntax/src/node.rs
@@ -3,7 +3,7 @@ use std::ops::{Deref, Range};
use std::rc::Rc;
use std::sync::Arc;
-use ecow::{eco_vec, EcoString, EcoVec};
+use ecow::{eco_format, eco_vec, EcoString, EcoVec};
use crate::ast::AstNode;
use crate::{FileId, Span, SyntaxKind};
@@ -177,14 +177,9 @@ impl SyntaxNode {
}
impl SyntaxNode {
- /// Mark this node as erroneous.
- pub(super) fn make_erroneous(&mut self) {
- if let Repr::Inner(inner) = &mut self.0 {
- Arc::make_mut(inner).erroneous = true;
- }
- }
-
/// Convert the child to another kind.
+ ///
+ /// Don't use this for converting to an error!
#[track_caller]
pub(super) fn convert_to_kind(&mut self, kind: SyntaxKind) {
debug_assert!(!kind.is_error());
@@ -195,10 +190,30 @@ impl SyntaxNode {
}
}
- /// Convert the child to an error.
+ /// Convert the child to an error, if it isn't already one.
pub(super) fn convert_to_error(&mut self, message: impl Into<EcoString>) {
- let text = std::mem::take(self).into_text();
- *self = SyntaxNode::error(message, text);
+ if !self.kind().is_error() {
+ let text = std::mem::take(self).into_text();
+ *self = SyntaxNode::error(message, text);
+ }
+ }
+
+ /// Convert the child to an error stating that the given thing was
+ /// expected, but the current kind was found.
+ pub(super) fn expected(&mut self, expected: &str) {
+ let kind = self.kind();
+ self.convert_to_error(eco_format!("expected {expected}, found {}", kind.name()));
+ if kind.is_keyword() && matches!(expected, "identifier" | "pattern") {
+ self.hint(eco_format!(
+ "keyword `{text}` is not allowed as an identifier; try `{text}_` instead",
+ text = self.text(),
+ ));
+ }
+ }
+
+ /// Convert the child to an error stating it was unexpected.
+ pub(super) fn unexpected(&mut self) {
+ self.convert_to_error(eco_format!("unexpected {}", self.kind().name()));
}
/// Assign spans to each node.