summaryrefslogtreecommitdiff
path: root/crates/typst-syntax/src/lexer.rs
diff options
context:
space:
mode:
authorastrale-sharp <ash4567@outlook.fr>2024-06-12 14:00:22 +0200
committerGitHub <noreply@github.com>2024-06-12 12:00:22 +0000
commitad4ef68a112dedabf80f885a02bcb574eb9af9e4 (patch)
treea5de8e9f9de8e4ac64efa4a30b343fe70fda9656 /crates/typst-syntax/src/lexer.rs
parent20b8d2c121c713cb32f6048df6435735a0c0262f (diff)
Lexer hint (#4346)
Co-authored-by: Laurenz <laurmaedje@gmail.com>
Diffstat (limited to 'crates/typst-syntax/src/lexer.rs')
-rw-r--r--crates/typst-syntax/src/lexer.rs22
1 files changed, 17 insertions, 5 deletions
diff --git a/crates/typst-syntax/src/lexer.rs b/crates/typst-syntax/src/lexer.rs
index 3f409b2d..dd05e73f 100644
--- a/crates/typst-syntax/src/lexer.rs
+++ b/crates/typst-syntax/src/lexer.rs
@@ -4,7 +4,7 @@ use unicode_script::{Script, UnicodeScript};
use unicode_segmentation::UnicodeSegmentation;
use unscanny::Scanner;
-use crate::SyntaxKind;
+use crate::{SyntaxError, SyntaxKind};
/// Splits up a string of source code into tokens.
#[derive(Clone)]
@@ -19,7 +19,7 @@ pub(super) struct Lexer<'s> {
/// The state held by raw line lexing.
raw: Vec<(SyntaxKind, usize)>,
/// An error for the last token.
- error: Option<EcoString>,
+ error: Option<SyntaxError>,
}
/// What kind of tokens to emit.
@@ -75,7 +75,7 @@ impl<'s> Lexer<'s> {
}
/// Take out the last error, if any.
- pub fn take_error(&mut self) -> Option<EcoString> {
+ pub fn take_error(&mut self) -> Option<SyntaxError> {
self.error.take()
}
}
@@ -83,9 +83,16 @@ impl<'s> Lexer<'s> {
impl Lexer<'_> {
/// Construct a full-positioned syntax error.
fn error(&mut self, message: impl Into<EcoString>) -> SyntaxKind {
- self.error = Some(message.into());
+ self.error = Some(SyntaxError::new(message));
SyntaxKind::Error
}
+
+ /// If the current node is an error, adds a hint.
+ fn hint(&mut self, message: impl Into<EcoString>) {
+ if let Some(error) = &mut self.error {
+ error.hints.push(message.into());
+ }
+ }
}
/// Shared methods with all [`LexMode`].
@@ -109,7 +116,12 @@ impl Lexer<'_> {
Some('/') if self.s.eat_if('/') => self.line_comment(),
Some('/') if self.s.eat_if('*') => self.block_comment(),
Some('*') if self.s.eat_if('/') => {
- self.error("unexpected end of block comment")
+ let kind = self.error("unexpected end of block comment");
+ self.hint(
+ "consider escaping the `*` with a backslash or \
+ opening the block comment with `/*`",
+ );
+ kind
}
Some(c) => match self.mode {