mirror of
https://github.com/typst/typst
synced 2025-05-19 11:35:27 +08:00
create DecoratorMarker and DecoratorName
This commit is contained in:
parent
d35a563b3c
commit
14dfb3f630
@ -80,6 +80,22 @@ impl<'a> Markup<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node! {
|
||||||
|
DecoratorName
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DecoratorName<'a> {
|
||||||
|
/// Get the decorator name.
|
||||||
|
pub fn get(self) -> &'a EcoString {
|
||||||
|
self.0.text()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the decorator name as a string slice.
|
||||||
|
pub fn as_str(self) -> &'a str {
|
||||||
|
self.get()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
node! {
|
node! {
|
||||||
/// A decorator: `/! allow("warning")`.
|
/// A decorator: `/! allow("warning")`.
|
||||||
Decorator
|
Decorator
|
||||||
@ -87,7 +103,7 @@ node! {
|
|||||||
|
|
||||||
impl<'a> Decorator<'a> {
|
impl<'a> Decorator<'a> {
|
||||||
/// The name of the decorator, e.g. `allow`.
|
/// The name of the decorator, e.g. `allow`.
|
||||||
pub fn name(self) -> Ident<'a> {
|
pub fn name(self) -> DecoratorName<'a> {
|
||||||
self.0.cast_first_match().unwrap_or_default()
|
self.0.cast_first_match().unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,6 +287,8 @@ pub fn highlight(node: &LinkedNode) -> Option<Tag> {
|
|||||||
SyntaxKind::DestructAssignment => None,
|
SyntaxKind::DestructAssignment => None,
|
||||||
|
|
||||||
SyntaxKind::Decorator => None,
|
SyntaxKind::Decorator => None,
|
||||||
|
SyntaxKind::DecoratorMarker => None,
|
||||||
|
SyntaxKind::DecoratorName => None,
|
||||||
|
|
||||||
SyntaxKind::LineComment => Some(Tag::Comment),
|
SyntaxKind::LineComment => Some(Tag::Comment),
|
||||||
SyntaxKind::BlockComment => Some(Tag::Comment),
|
SyntaxKind::BlockComment => Some(Tag::Comment),
|
||||||
|
@ -280,6 +280,11 @@ pub enum SyntaxKind {
|
|||||||
Destructuring,
|
Destructuring,
|
||||||
/// A destructuring assignment expression: `(x, y) = (1, 2)`.
|
/// A destructuring assignment expression: `(x, y) = (1, 2)`.
|
||||||
DestructAssignment,
|
DestructAssignment,
|
||||||
|
|
||||||
|
/// A decorator's marker: `/!`.
|
||||||
|
DecoratorMarker,
|
||||||
|
/// A decorator's name: `allow`.
|
||||||
|
DecoratorName,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SyntaxKind {
|
impl SyntaxKind {
|
||||||
@ -505,6 +510,8 @@ impl SyntaxKind {
|
|||||||
Self::FuncReturn => "`return` expression",
|
Self::FuncReturn => "`return` expression",
|
||||||
Self::Destructuring => "destructuring pattern",
|
Self::Destructuring => "destructuring pattern",
|
||||||
Self::DestructAssignment => "destructuring assignment expression",
|
Self::DestructAssignment => "destructuring assignment expression",
|
||||||
|
Self::DecoratorMarker => "decorator marker",
|
||||||
|
Self::DecoratorName => "decorator name",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,16 +222,18 @@ impl Lexer<'_> {
|
|||||||
/// `/! decorator-name("string argument1", "string argument2")`
|
/// `/! decorator-name("string argument1", "string argument2")`
|
||||||
/// with optional whitespaces and comments between arguments.
|
/// with optional whitespaces and comments between arguments.
|
||||||
fn decorator(&mut self, start: usize) -> SyntaxNode {
|
fn decorator(&mut self, start: usize) -> SyntaxNode {
|
||||||
// TODO: DecoratorMarker node
|
// Start by lexing the marker.
|
||||||
let current_start = start;
|
let marker = self.emit_token(SyntaxKind::DecoratorMarker, start);
|
||||||
let mut subtree = vec![];
|
let mut subtree = vec![marker];
|
||||||
|
|
||||||
|
let current_start = self.s.cursor();
|
||||||
|
|
||||||
// Ignore initial non-newline whitespaces
|
// Ignore initial non-newline whitespaces
|
||||||
if !self.s.eat_while(is_inline_whitespace).is_empty() {
|
if !self.s.eat_while(is_inline_whitespace).is_empty() {
|
||||||
subtree.push(self.emit_token(SyntaxKind::Space, current_start));
|
subtree.push(self.emit_token(SyntaxKind::Space, current_start));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decorator's name
|
// Lex the decorator name
|
||||||
let current_start = self.s.cursor();
|
let current_start = self.s.cursor();
|
||||||
if !self.s.eat_if(is_id_start) {
|
if !self.s.eat_if(is_id_start) {
|
||||||
self.s.eat_until(is_newline);
|
self.s.eat_until(is_newline);
|
||||||
@ -241,17 +243,8 @@ impl Lexer<'_> {
|
|||||||
return SyntaxNode::inner(SyntaxKind::Decorator, subtree);
|
return SyntaxNode::inner(SyntaxKind::Decorator, subtree);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.s.eat_while(is_id_continue);
|
let decorator_name = self.decorator_name(current_start);
|
||||||
let ident = self.s.from(current_start);
|
subtree.push(self.emit_token(decorator_name, current_start));
|
||||||
|
|
||||||
subtree.push(if ident == "allow" {
|
|
||||||
self.emit_token(SyntaxKind::Ident, current_start)
|
|
||||||
} else {
|
|
||||||
self.emit_error(
|
|
||||||
eco_format!("expected decorator name 'allow', found '{ident}'"),
|
|
||||||
current_start,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
// Left parenthesis before decorator arguments
|
// Left parenthesis before decorator arguments
|
||||||
let current_start = self.s.cursor();
|
let current_start = self.s.cursor();
|
||||||
@ -323,6 +316,26 @@ impl Lexer<'_> {
|
|||||||
SyntaxNode::inner(SyntaxKind::Decorator, subtree)
|
SyntaxNode::inner(SyntaxKind::Decorator, subtree)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Lexes a decorator name.
|
||||||
|
/// A decorator name is an identifier within a specific subset of allowed
|
||||||
|
/// identifiers.
|
||||||
|
/// Currently, `allow` is the only valid decorator name.
|
||||||
|
fn decorator_name(&mut self, start: usize) -> SyntaxKind {
|
||||||
|
self.s.eat_while(is_id_continue);
|
||||||
|
let ident = self.s.from(start);
|
||||||
|
|
||||||
|
if ident == "allow" {
|
||||||
|
SyntaxKind::DecoratorName
|
||||||
|
} else {
|
||||||
|
let error = self.error(eco_format!("invalid decorator name"));
|
||||||
|
self.hint("must be 'allow'");
|
||||||
|
error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Lexes a string in a decorator.
|
||||||
|
/// Currently, such strings only allow a very restricted set of characters.
|
||||||
|
/// These restrictions may be lifted in the future.
|
||||||
fn decorator_string(&mut self) -> SyntaxKind {
|
fn decorator_string(&mut self) -> SyntaxKind {
|
||||||
// TODO: Allow more characters in decorators' strings, perhaps allowing
|
// TODO: Allow more characters in decorators' strings, perhaps allowing
|
||||||
// newlines somehow.
|
// newlines somehow.
|
||||||
|
@ -36,7 +36,8 @@ this is ok
|
|||||||
/! allow("@some/thing-there123")
|
/! allow("@some/thing-there123")
|
||||||
|
|
||||||
--- unknown-decorator ---
|
--- unknown-decorator ---
|
||||||
// Error: 4-12 expected decorator name 'allow', found 'whatever'
|
// Error: 4-12 invalid decorator name
|
||||||
|
// Hint: 4-12 must be 'allow'
|
||||||
/! whatever()
|
/! whatever()
|
||||||
|
|
||||||
--- invalid-decorator-syntax ---
|
--- invalid-decorator-syntax ---
|
||||||
|
Loading…
x
Reference in New Issue
Block a user