create DecoratorMarker and DecoratorName

This commit is contained in:
PgBiel 2024-06-24 19:21:33 -03:00
parent d35a563b3c
commit 14dfb3f630
5 changed files with 56 additions and 17 deletions

View File

@ -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! {
/// A decorator: `/! allow("warning")`.
Decorator
@ -87,7 +103,7 @@ node! {
impl<'a> Decorator<'a> {
/// 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()
}

View File

@ -287,6 +287,8 @@ pub fn highlight(node: &LinkedNode) -> Option<Tag> {
SyntaxKind::DestructAssignment => None,
SyntaxKind::Decorator => None,
SyntaxKind::DecoratorMarker => None,
SyntaxKind::DecoratorName => None,
SyntaxKind::LineComment => Some(Tag::Comment),
SyntaxKind::BlockComment => Some(Tag::Comment),

View File

@ -280,6 +280,11 @@ pub enum SyntaxKind {
Destructuring,
/// A destructuring assignment expression: `(x, y) = (1, 2)`.
DestructAssignment,
/// A decorator's marker: `/!`.
DecoratorMarker,
/// A decorator's name: `allow`.
DecoratorName,
}
impl SyntaxKind {
@ -505,6 +510,8 @@ impl SyntaxKind {
Self::FuncReturn => "`return` expression",
Self::Destructuring => "destructuring pattern",
Self::DestructAssignment => "destructuring assignment expression",
Self::DecoratorMarker => "decorator marker",
Self::DecoratorName => "decorator name",
}
}
}

View File

@ -222,16 +222,18 @@ impl Lexer<'_> {
/// `/! decorator-name("string argument1", "string argument2")`
/// with optional whitespaces and comments between arguments.
fn decorator(&mut self, start: usize) -> SyntaxNode {
// TODO: DecoratorMarker node
let current_start = start;
let mut subtree = vec![];
// Start by lexing the marker.
let marker = self.emit_token(SyntaxKind::DecoratorMarker, start);
let mut subtree = vec![marker];
let current_start = self.s.cursor();
// Ignore initial non-newline whitespaces
if !self.s.eat_while(is_inline_whitespace).is_empty() {
subtree.push(self.emit_token(SyntaxKind::Space, current_start));
}
// Decorator's name
// Lex the decorator name
let current_start = self.s.cursor();
if !self.s.eat_if(is_id_start) {
self.s.eat_until(is_newline);
@ -241,17 +243,8 @@ impl Lexer<'_> {
return SyntaxNode::inner(SyntaxKind::Decorator, subtree);
}
self.s.eat_while(is_id_continue);
let ident = self.s.from(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,
)
});
let decorator_name = self.decorator_name(current_start);
subtree.push(self.emit_token(decorator_name, current_start));
// Left parenthesis before decorator arguments
let current_start = self.s.cursor();
@ -323,6 +316,26 @@ impl Lexer<'_> {
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 {
// TODO: Allow more characters in decorators' strings, perhaps allowing
// newlines somehow.

View File

@ -36,7 +36,8 @@ this is ok
/! allow("@some/thing-there123")
--- unknown-decorator ---
// Error: 4-12 expected decorator name 'allow', found 'whatever'
// Error: 4-12 invalid decorator name
// Hint: 4-12 must be 'allow'
/! whatever()
--- invalid-decorator-syntax ---