diff options
| author | PgBiel <9021226+PgBiel@users.noreply.github.com> | 2024-07-15 18:23:56 -0300 |
|---|---|---|
| committer | PgBiel <9021226+PgBiel@users.noreply.github.com> | 2024-07-16 16:49:03 -0300 |
| commit | c1bb41dc9cadab596041d942bbaf7c7e8f8a14a5 (patch) | |
| tree | 7c2dec35e747c3dffa955ef0a29cc5fc2249b7b9 /crates/typst-syntax | |
| parent | 2b442eae5e1bdedd29ee650e6a367c81a5ed9ce1 (diff) | |
new decorator syntax: '// @'
Diffstat (limited to 'crates/typst-syntax')
| -rw-r--r-- | crates/typst-syntax/src/kind.rs | 4 | ||||
| -rw-r--r-- | crates/typst-syntax/src/lexer.rs | 28 |
2 files changed, 25 insertions, 7 deletions
diff --git a/crates/typst-syntax/src/kind.rs b/crates/typst-syntax/src/kind.rs index 8f0e806c..fbe0b502 100644 --- a/crates/typst-syntax/src/kind.rs +++ b/crates/typst-syntax/src/kind.rs @@ -13,7 +13,7 @@ pub enum SyntaxKind { LineComment, /// A block comment: `/* ... */`. BlockComment, - /// A decorator: `/! allow("warning")`. + /// A decorator: `// @allow("warning")`. Decorator, /// The contents of a file or content block. @@ -281,7 +281,7 @@ pub enum SyntaxKind { /// A destructuring assignment expression: `(x, y) = (1, 2)`. DestructAssignment, - /// A decorator's marker: `/!`. + /// A decorator's marker: `// @`. DecoratorMarker, /// A decorator's name: `allow`. DecoratorName, diff --git a/crates/typst-syntax/src/lexer.rs b/crates/typst-syntax/src/lexer.rs index 0e4b5b4b..fd057dc4 100644 --- a/crates/typst-syntax/src/lexer.rs +++ b/crates/typst-syntax/src/lexer.rs @@ -119,9 +119,10 @@ impl Lexer<'_> { let start = self.s.cursor(); let token = match self.s.eat() { Some(c) if is_space(c, self.mode) => self.whitespace(start, c), - Some('/') if self.s.eat_if('/') => self.line_comment(), + Some('/') if self.s.eat_if('/') => { + return self.line_comment_or_decorator(start); + } Some('/') if self.s.eat_if('*') => self.block_comment(), - Some('/') if self.s.eat_if('!') => return self.decorator(start), Some('*') if self.s.eat_if('/') => { let kind = self.error("unexpected end of block comment"); self.hint( @@ -184,9 +185,17 @@ impl Lexer<'_> { } } - fn line_comment(&mut self) -> SyntaxKind { + /// Parses a decorator if the line comment has the form + /// `// @something` + /// + /// Otherwise, parses a regular line comment. + fn line_comment_or_decorator(&mut self, start: usize) -> SyntaxNode { + self.s.eat_while(is_inline_whitespace); + if self.s.eat_if('@') { + return self.decorator(start); + } self.s.eat_until(is_newline); - SyntaxKind::LineComment + self.emit_token(SyntaxKind::LineComment, start) } fn block_comment(&mut self) -> SyntaxKind { @@ -274,7 +283,16 @@ impl Lexer<'_> { self.s.eat_while(is_inline_whitespace); SyntaxKind::Space } - Some('/') if self.s.eat_if('/') => self.line_comment(), + Some('/') if self.s.eat_if('/') => { + let node = self.line_comment_or_decorator(current_start); + if node.kind() == SyntaxKind::Decorator { + self.error("cannot have multiple decorators per line") + } else { + subtree.push(node); + current_start = self.s.cursor(); + continue; + } + } Some('/') if self.s.eat_if('*') => self.block_comment(), Some(_) if finished => { // After we finished specifying arguments, there must only |
