diff options
| author | astrale-sharp <ash4567@outlook.fr> | 2024-06-12 14:00:22 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-12 12:00:22 +0000 |
| commit | ad4ef68a112dedabf80f885a02bcb574eb9af9e4 (patch) | |
| tree | a5de8e9f9de8e4ac64efa4a30b343fe70fda9656 /crates/typst-syntax/src/lexer.rs | |
| parent | 20b8d2c121c713cb32f6048df6435735a0c0262f (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.rs | 22 |
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 { |
