From fb77128423b4732c349620cef886f2cfecf8bf50 Mon Sep 17 00:00:00 2001 From: PgBiel <9021226+PgBiel@users.noreply.github.com> Date: Tue, 16 Jul 2024 16:51:00 -0300 Subject: [PATCH] decorator -> annotation --- crates/typst-syntax/src/ast.rs | 20 ++--- crates/typst-syntax/src/highlight.rs | 6 +- crates/typst-syntax/src/kind.rs | 20 ++--- crates/typst-syntax/src/lexer.rs | 84 +++++++++---------- crates/typst-syntax/src/node.rs | 12 +-- crates/typst-syntax/src/parser.rs | 2 +- crates/typst-syntax/src/set.rs | 2 +- crates/typst/src/diag.rs | 22 ++--- .../syntax/{decorator.typ => annotation.typ} | 34 ++++---- 9 files changed, 101 insertions(+), 101 deletions(-) rename tests/suite/syntax/{decorator.typ => annotation.typ} (77%) diff --git a/crates/typst-syntax/src/ast.rs b/crates/typst-syntax/src/ast.rs index 892040b7b..88a08e0a0 100644 --- a/crates/typst-syntax/src/ast.rs +++ b/crates/typst-syntax/src/ast.rs @@ -81,33 +81,33 @@ impl<'a> Markup<'a> { } node! { - DecoratorName + AnnotationName } -impl<'a> DecoratorName<'a> { - /// Get the decorator name. +impl<'a> AnnotationName<'a> { + /// Get the annotation name. pub fn get(self) -> &'a EcoString { self.0.text() } - /// Get the decorator name as a string slice. + /// Get the annotation name as a string slice. pub fn as_str(self) -> &'a str { self.get() } } node! { - /// A decorator: `/! allow("warning")`. - Decorator + /// An annotation: `/! allow("warning")`. + Annotation } -impl<'a> Decorator<'a> { - /// The name of the decorator, e.g. `allow`. - pub fn name(self) -> DecoratorName<'a> { +impl<'a> Annotation<'a> { + /// The name of the annotation, e.g. `allow`. + pub fn name(self) -> AnnotationName<'a> { self.0.cast_first_match().unwrap_or_default() } - /// The decorator's arguments. Currently, they are always strings. + /// The annotation's arguments. Currently, they are always strings. pub fn arguments(self) -> impl DoubleEndedIterator> { self.0.children().filter_map(Str::from_untyped) } diff --git a/crates/typst-syntax/src/highlight.rs b/crates/typst-syntax/src/highlight.rs index c78ec6941..d825e2403 100644 --- a/crates/typst-syntax/src/highlight.rs +++ b/crates/typst-syntax/src/highlight.rs @@ -286,9 +286,9 @@ pub fn highlight(node: &LinkedNode) -> Option { SyntaxKind::Destructuring => None, SyntaxKind::DestructAssignment => None, - SyntaxKind::Decorator => None, - SyntaxKind::DecoratorMarker => None, - SyntaxKind::DecoratorName => None, + SyntaxKind::Annotation => None, + SyntaxKind::AnnotationMarker => None, + SyntaxKind::AnnotationName => None, SyntaxKind::LineComment => Some(Tag::Comment), SyntaxKind::BlockComment => Some(Tag::Comment), diff --git a/crates/typst-syntax/src/kind.rs b/crates/typst-syntax/src/kind.rs index fbe0b5028..9597f2a2e 100644 --- a/crates/typst-syntax/src/kind.rs +++ b/crates/typst-syntax/src/kind.rs @@ -13,8 +13,8 @@ pub enum SyntaxKind { LineComment, /// A block comment: `/* ... */`. BlockComment, - /// A decorator: `// @allow("warning")`. - Decorator, + /// An annotation: `// @allow("warning")`. + Annotation, /// The contents of a file or content block. Markup, @@ -281,10 +281,10 @@ pub enum SyntaxKind { /// A destructuring assignment expression: `(x, y) = (1, 2)`. DestructAssignment, - /// A decorator's marker: `// @`. - DecoratorMarker, - /// A decorator's name: `allow`. - DecoratorName, + /// An annotation's marker: `// @`. + AnnotationMarker, + /// An annotation's name: `allow`. + AnnotationName, } impl SyntaxKind { @@ -366,7 +366,7 @@ impl SyntaxKind { | Self::BlockComment | Self::Space | Self::Parbreak - | Self::Decorator + | Self::Annotation ) } @@ -382,7 +382,7 @@ impl SyntaxKind { Self::Error => "syntax error", Self::LineComment => "line comment", Self::BlockComment => "block comment", - Self::Decorator => "decorator", + Self::Annotation => "annotation", Self::Markup => "markup", Self::Text => "text", Self::Space => "space", @@ -510,8 +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", + Self::AnnotationMarker => "annotation marker", + Self::AnnotationName => "annotation name", } } } diff --git a/crates/typst-syntax/src/lexer.rs b/crates/typst-syntax/src/lexer.rs index fd057dc46..af64333bb 100644 --- a/crates/typst-syntax/src/lexer.rs +++ b/crates/typst-syntax/src/lexer.rs @@ -103,7 +103,7 @@ impl Lexer<'_> { /// syntax node returned might not always be a leaf, but could actually /// come with a subtree (could be an inner node). This happens when it is /// preferred to perform parsing at the character level instead of at the - /// token level, as seen, for example, in [`decorator`](Lexer::decorator). + /// token level, as seen, for example, in [`annotation`](Lexer::annotation). pub fn next(&mut self) -> SyntaxNode { if self.mode == LexMode::Raw { let Some((kind, end)) = self.raw.pop() else { @@ -120,7 +120,7 @@ impl Lexer<'_> { let token = match self.s.eat() { Some(c) if is_space(c, self.mode) => self.whitespace(start, c), Some('/') if self.s.eat_if('/') => { - return self.line_comment_or_decorator(start); + return self.line_comment_or_annotation(start); } Some('/') if self.s.eat_if('*') => self.block_comment(), Some('*') if self.s.eat_if('/') => { @@ -185,14 +185,14 @@ impl Lexer<'_> { } } - /// Parses a decorator if the line comment has the form + /// Parses an annotation if the line comment has the form /// `// @something` /// /// Otherwise, parses a regular line comment. - fn line_comment_or_decorator(&mut self, start: usize) -> SyntaxNode { + fn line_comment_or_annotation(&mut self, start: usize) -> SyntaxNode { self.s.eat_while(is_inline_whitespace); if self.s.eat_if('@') { - return self.decorator(start); + return self.annotation(start); } self.s.eat_until(is_newline); self.emit_token(SyntaxKind::LineComment, start) @@ -224,18 +224,18 @@ impl Lexer<'_> { } } -/// Decorator lexing and auxiliary methods. +/// Annotation lexing and auxiliary methods. impl Lexer<'_> { - /// Lexes and parses a decorator into a complete syntax subtree. + /// Lexes and parses an annotation into a complete syntax subtree. /// - /// The lexer is fully responsible for the decorator, as it is simpler to + /// The lexer is fully responsible for the annotation, as it is simpler to /// parse them at the character level, given they follow a very simple /// and rigid structure, in the form - /// `/! decorator-name("string argument1", "string argument2")` + /// `/! annotation-name("string argument1", "string argument2")` /// with optional whitespaces and comments between arguments. - fn decorator(&mut self, start: usize) -> SyntaxNode { + fn annotation(&mut self, start: usize) -> SyntaxNode { // Start by lexing the marker. - let marker = self.emit_token(SyntaxKind::DecoratorMarker, start); + let marker = self.emit_token(SyntaxKind::AnnotationMarker, start); let mut subtree = vec![marker]; let current_start = self.s.cursor(); @@ -245,35 +245,35 @@ impl Lexer<'_> { subtree.push(self.emit_token(SyntaxKind::Space, current_start)); } - // Lex the decorator name. + // Lex the annotation name. let current_start = self.s.cursor(); if !self.s.eat_if(is_id_start) { self.s.eat_until(is_newline); subtree.push(self.emit_error("expected identifier", current_start)); - // Return a single error node until the end of the decorator. - return SyntaxNode::inner(SyntaxKind::Decorator, subtree); + // Return a single error node until the end of the annotation. + return SyntaxNode::inner(SyntaxKind::Annotation, subtree); } - let decorator_name = self.decorator_name(current_start); - subtree.push(self.emit_token(decorator_name, current_start)); + let annotation_name = self.annotation_name(current_start); + subtree.push(self.emit_token(annotation_name, current_start)); - // Left parenthesis before decorator arguments. + // Left parenthesis before annotation arguments. let current_start = self.s.cursor(); if !self.s.eat_if('(') { self.s.eat_until(is_newline); subtree.push(self.emit_error("expected opening paren", current_start)); - // Return a single error node until the end of the decorator. - return SyntaxNode::inner(SyntaxKind::Decorator, subtree); + // Return a single error node until the end of the annotation. + return SyntaxNode::inner(SyntaxKind::Annotation, subtree); } subtree.push(self.emit_token(SyntaxKind::LeftParen, current_start)); - // Decorator arguments: + // Annotation arguments: // Keep reading until we find a right parenthesis or newline. We have // to check the newline before eating (through '.peek()') to ensure it - // is not considered part of the decorator. + // is not considered part of the annotation. let mut current_start = self.s.cursor(); let mut expecting_comma = false; let mut finished = false; @@ -284,9 +284,9 @@ impl Lexer<'_> { SyntaxKind::Space } 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") + let node = self.line_comment_or_annotation(current_start); + if node.kind() == SyntaxKind::Annotation { + self.error("cannot have multiple annotations per line") } else { subtree.push(node); current_start = self.s.cursor(); @@ -298,7 +298,7 @@ impl Lexer<'_> { // After we finished specifying arguments, there must only // be whitespaces until the line ends. self.s.eat_until(char::is_whitespace); - self.error("expected end of decorator") + self.error("expected end of annotation") } Some('"') if expecting_comma => { self.s.eat_until(|c| c == ',' || c == ')' || is_newline(c)); @@ -306,7 +306,7 @@ impl Lexer<'_> { } Some('"') => { expecting_comma = true; - self.decorator_string() + self.annotation_string() } Some(',') if expecting_comma => { expecting_comma = false; @@ -318,7 +318,7 @@ impl Lexer<'_> { SyntaxKind::RightParen } Some(c) => self.error(eco_format!( - "the character '{c}' is not valid in a decorator" + "the character '{c}' is not valid in an annotation" )), None => break, }; @@ -334,34 +334,34 @@ impl Lexer<'_> { subtree.push(self.emit_error("expected closing paren", self.s.cursor())); } - SyntaxNode::inner(SyntaxKind::Decorator, subtree) + SyntaxNode::inner(SyntaxKind::Annotation, subtree) } - /// Lexes a decorator name. + /// Lexes an annotation 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 { + /// An annotation name is an identifier within a specific subset of allowed + /// identifiers. Currently, `allow` is the only valid annotation name. + fn annotation_name(&mut self, start: usize) -> SyntaxKind { self.s.eat_while(is_id_continue); let ident = self.s.from(start); if ident == "allow" { - SyntaxKind::DecoratorName + SyntaxKind::AnnotationName } else { - let error = self.error(eco_format!("invalid decorator name")); + let error = self.error(eco_format!("invalid annotation name")); self.hint("must be 'allow'"); error } } - /// Lexes a string in a decorator. + /// Lexes a string in an annotation. /// /// 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 + fn annotation_string(&mut self) -> SyntaxKind { + // TODO: Allow more characters in annotations' strings, perhaps allowing // newlines somehow. - // Could perhaps use one //! per line so we can break a decorator into + // Could perhaps use one //! per line so we can break an annotation into // multiple lines in a sensible way. let start = self.s.cursor(); self.s.eat_while(|c| !is_newline(c) && c != '"'); @@ -371,9 +371,9 @@ impl Lexer<'_> { return self.error("unclosed string"); } - if let Some(c) = content.chars().find(|c| !is_valid_in_decorator_string(*c)) { + if let Some(c) = content.chars().find(|c| !is_valid_in_annotation_string(*c)) { return self - .error(eco_format!("invalid character '{c}' in a decorator's string")); + .error(eco_format!("invalid character '{c}' in an annotation's string")); } SyntaxKind::Str @@ -1160,9 +1160,9 @@ fn is_valid_in_label_literal(c: char) -> bool { is_id_continue(c) || matches!(c, ':' | '.') } -/// Whether a character can be part of a string in a decorator. +/// Whether a character can be part of a string in an annotation. #[inline] -fn is_valid_in_decorator_string(c: char) -> bool { +fn is_valid_in_annotation_string(c: char) -> bool { is_id_continue(c) || c == '@' || c == '/' } diff --git a/crates/typst-syntax/src/node.rs b/crates/typst-syntax/src/node.rs index 488b1084b..9a55ca5c7 100644 --- a/crates/typst-syntax/src/node.rs +++ b/crates/typst-syntax/src/node.rs @@ -818,15 +818,15 @@ impl<'a> LinkedNode<'a> { } } - /// Get the first sibling decorator node at the line above this node. - /// This is done by moving backwards, checking for decorators, until we hit + /// Get the first sibling annotation node at the line above this node. + /// This is done by moving backwards, checking for annotations, until we hit /// a second newline (that is, we only check, at most, the line before this /// node). - pub fn prev_attached_decorator(&self) -> Option { + pub fn prev_attached_annotation(&self) -> Option { let mut cursor = self.prev_sibling_inner()?; let mut newlines = cursor.capped_newlines(); while newlines < 2 { - if cursor.kind() == SyntaxKind::Decorator { + if cursor.kind() == SyntaxKind::Annotation { return Some(cursor); } @@ -834,8 +834,8 @@ impl<'a> LinkedNode<'a> { newlines += cursor.capped_newlines(); } - // Decorators are attached if they're in the previous line. - // If we counted at least two newlines, no decorators are attached to + // Annotations are attached if they're in the previous line. + // If we counted at least two newlines, no annotations are attached to // this node. None } diff --git a/crates/typst-syntax/src/parser.rs b/crates/typst-syntax/src/parser.rs index 30e08de7a..62904fc70 100644 --- a/crates/typst-syntax/src/parser.rs +++ b/crates/typst-syntax/src/parser.rs @@ -109,7 +109,7 @@ fn markup_expr(p: &mut Parser, at_start: &mut bool) { | SyntaxKind::Parbreak | SyntaxKind::LineComment | SyntaxKind::BlockComment - | SyntaxKind::Decorator => { + | SyntaxKind::Annotation => { p.eat(); return; } diff --git a/crates/typst-syntax/src/set.rs b/crates/typst-syntax/src/set.rs index 3f5a26061..55f710385 100644 --- a/crates/typst-syntax/src/set.rs +++ b/crates/typst-syntax/src/set.rs @@ -54,7 +54,7 @@ pub const MARKUP_EXPR: SyntaxSet = SyntaxSet::new() .add(SyntaxKind::Parbreak) .add(SyntaxKind::LineComment) .add(SyntaxKind::BlockComment) - .add(SyntaxKind::Decorator) + .add(SyntaxKind::Annotation) .add(SyntaxKind::Text) .add(SyntaxKind::Linebreak) .add(SyntaxKind::Escape) diff --git a/crates/typst/src/diag.rs b/crates/typst/src/diag.rs index 52f1c411c..ef488e999 100644 --- a/crates/typst/src/diag.rs +++ b/crates/typst/src/diag.rs @@ -542,7 +542,7 @@ pub fn deduplicate_and_suppress_warnings( /// Checks if a given warning is suppressed given one span it has a tracepoint /// in. If one of the ancestors of the node where the warning occurred has a -/// warning suppression decorator sibling right before it suppressing this +/// warning suppression annotation sibling right before it suppressing this /// particular warning, the warning is considered suppressed. fn is_warning_suppressed(span: Span, world: &dyn World, identifier: &Identifier) -> bool { // Don't suppress detached warnings. @@ -556,13 +556,13 @@ fn is_warning_suppressed(span: Span, world: &dyn World, identifier: &Identifier) // Walk the parent nodes to check for a warning suppression in the // previous line. while let Some(node) = searched_node { - let mut searched_decorator = node.prev_attached_decorator(); - while let Some(sibling) = searched_decorator { - let decorator = sibling.cast::().unwrap(); - if check_decorator_suppresses_warning(decorator, identifier) { + let mut searched_annotation = node.prev_attached_annotation(); + while let Some(sibling) = searched_annotation { + let annotation = sibling.cast::().unwrap(); + if check_annotation_suppresses_warning(annotation, identifier) { return true; } - searched_decorator = sibling.prev_attached_decorator(); + searched_annotation = sibling.prev_attached_annotation(); } searched_node = node.parent(); } @@ -570,17 +570,17 @@ fn is_warning_suppressed(span: Span, world: &dyn World, identifier: &Identifier) false } -/// Checks if an 'allow' decorator would cause a warning with a particular +/// Checks if an 'allow' annotation would cause a warning with a particular /// identifier to be suppressed. -fn check_decorator_suppresses_warning( - decorator: ast::Decorator, +fn check_annotation_suppresses_warning( + annotation: ast::Annotation, warning: &Identifier, ) -> bool { - if decorator.name().as_str() != "allow" { + if annotation.name().as_str() != "allow" { return false; } - for argument in decorator.arguments() { + for argument in annotation.arguments() { if warning.name() == argument.get() { return true; } diff --git a/tests/suite/syntax/decorator.typ b/tests/suite/syntax/annotation.typ similarity index 77% rename from tests/suite/syntax/decorator.typ rename to tests/suite/syntax/annotation.typ index 58ac77127..9ebf8add3 100644 --- a/tests/suite/syntax/decorator.typ +++ b/tests/suite/syntax/annotation.typ @@ -1,6 +1,6 @@ -// Test decorators. +// Test annotations. ---- basic-decorators --- +--- basic-annotations --- // @allow() // @allow("A") @@ -19,7 +19,7 @@ h(#0em) $ ---- decorator-comments --- +--- annotation-comments --- // @allow("abc") // this is ok @@ -31,22 +31,22 @@ $ this is ok */, "abc") ---- decorator-strings --- +--- annotation-strings --- // @allow("@some/thing-there123") ---- unknown-decorator --- -// Error: 2:5-2:13 invalid decorator name +--- unknown-annotation --- +// Error: 2:5-2:13 invalid annotation name // Hint: 2:5-2:13 must be 'allow' // @whatever() ---- invalid-decorator-syntax --- -// Error: 2:11-2:12 the character '*' is not valid in a decorator +--- invalid-annotation-syntax --- +// Error: 2:11-2:12 the character '*' is not valid in an annotation // @allow(*) -// Error: 2:11-2:12 the character '5' is not valid in a decorator +// Error: 2:11-2:12 the character '5' is not valid in an annotation // @allow(5) @@ -63,12 +63,12 @@ this is ok // @allow("abc -// Error: 2:18-2:21 expected end of decorator +// Error: 2:18-2:21 expected end of annotation // @allow("abc") abc // Error: 2:17-2:22 expected comma -// Error: 2:24-2:27 expected end of decorator +// Error: 2:24-2:27 expected end of annotation // @allow("abc" "abc") abc @@ -80,23 +80,23 @@ this is ok // @allow(, "abc", "abc", "abc") ---- invalid-decorator-strings --- +--- invalid-annotation-strings --- -// Error: 2:11-2:16 invalid character ' ' in a decorator's string +// Error: 2:11-2:16 invalid character ' ' in an annotation's string // @allow("a b") -// Error: 2:11-2:19 invalid character '|' in a decorator's string +// Error: 2:11-2:19 invalid character '|' in an annotation's string // @allow("aaaaa|") // TODO: Why does this print / instead of \? -// Error: 2:11-2:19 invalid character '/' in a decorator's string +// Error: 2:11-2:19 invalid character '/' in an annotation's string // @allow("aaaaa\") ---- invalid-decorator-in-decorator --- -// Error: 2:18-2:34 cannot have multiple decorators per line +--- invalid-annotation-in-annotation --- +// Error: 2:18-2:34 cannot have multiple annotations per line // @allow("aaa") // @allow("bbb")