diff --git a/crates/biome_grit_factory/src/generated/node_factory.rs b/crates/biome_grit_factory/src/generated/node_factory.rs index 573f447a823e..828ce2b5fc43 100644 --- a/crates/biome_grit_factory/src/generated/node_factory.rs +++ b/crates/biome_grit_factory/src/generated/node_factory.rs @@ -198,6 +198,12 @@ pub fn grit_double_literal(value_token: SyntaxToken) -> GritDoubleLiteral { [Some(SyntaxElement::Token(value_token))], )) } +pub fn grit_engine_name(engine_kind_token: SyntaxToken) -> GritEngineName { + GritEngineName::unwrap_cast(SyntaxNode::new_detached( + GritSyntaxKind::GRIT_ENGINE_NAME, + [Some(SyntaxElement::Token(engine_kind_token))], + )) +} pub fn grit_every(every_token: SyntaxToken, pattern: AnyGritMaybeCurlyPattern) -> GritEvery { GritEvery::unwrap_cast(SyntaxNode::new_detached( GritSyntaxKind::GRIT_EVERY, @@ -251,7 +257,7 @@ pub fn grit_int_literal(value_token: SyntaxToken) -> GritIntLiteral { } pub fn grit_language_declaration( language_token: SyntaxToken, - name: GritLanguageName, + name: AnyGritLanguageName, ) -> GritLanguageDeclarationBuilder { GritLanguageDeclarationBuilder { language_token, @@ -262,7 +268,7 @@ pub fn grit_language_declaration( } pub struct GritLanguageDeclarationBuilder { language_token: SyntaxToken, - name: GritLanguageName, + name: AnyGritLanguageName, flavor: Option, semicolon_token: Option, } @@ -316,7 +322,7 @@ pub fn grit_language_name(language_kind_token: SyntaxToken) -> GritLanguageName )) } pub fn grit_language_specific_snippet( - language: GritLanguageName, + language: AnyGritLanguageName, snippet_token: SyntaxToken, ) -> GritLanguageSpecificSnippet { GritLanguageSpecificSnippet::unwrap_cast(SyntaxNode::new_detached( @@ -1468,7 +1474,7 @@ pub fn grit_variable(value_token: SyntaxToken) -> GritVariable { } pub fn grit_version( engine_token: SyntaxToken, - biome_token: SyntaxToken, + engine_name: GritEngineName, l_paren_token: SyntaxToken, version: GritDoubleLiteral, r_paren_token: SyntaxToken, @@ -1477,7 +1483,7 @@ pub fn grit_version( GritSyntaxKind::GRIT_VERSION, [ Some(SyntaxElement::Token(engine_token)), - Some(SyntaxElement::Token(biome_token)), + Some(SyntaxElement::Node(engine_name.into_syntax())), Some(SyntaxElement::Token(l_paren_token)), Some(SyntaxElement::Node(version.into_syntax())), Some(SyntaxElement::Token(r_paren_token)), @@ -1708,6 +1714,16 @@ where slots, )) } +pub fn grit_bogus_language_name(slots: I) -> GritBogusLanguageName +where + I: IntoIterator>, + I::IntoIter: ExactSizeIterator, +{ + GritBogusLanguageName::unwrap_cast(SyntaxNode::new_detached( + GritSyntaxKind::GRIT_BOGUS_LANGUAGE_NAME, + slots, + )) +} pub fn grit_bogus_literal(slots: I) -> GritBogusLiteral where I: IntoIterator>, diff --git a/crates/biome_grit_factory/src/generated/syntax_factory.rs b/crates/biome_grit_factory/src/generated/syntax_factory.rs index d96383826506..42f7c96004a1 100644 --- a/crates/biome_grit_factory/src/generated/syntax_factory.rs +++ b/crates/biome_grit_factory/src/generated/syntax_factory.rs @@ -19,6 +19,7 @@ impl SyntaxFactory for GritSyntaxFactory { | GRIT_BOGUS_DEFINITION | GRIT_BOGUS_LANGUAGE_DECLARATION | GRIT_BOGUS_LANGUAGE_FLAVOR_KIND + | GRIT_BOGUS_LANGUAGE_NAME | GRIT_BOGUS_LITERAL | GRIT_BOGUS_MAP_ELEMENT | GRIT_BOGUS_NAMED_ARG @@ -426,6 +427,25 @@ impl SyntaxFactory for GritSyntaxFactory { } slots.into_node(GRIT_DOUBLE_LITERAL, children) } + GRIT_ENGINE_NAME => { + let mut elements = (&children).into_iter(); + let mut slots: RawNodeSlots<1usize> = RawNodeSlots::default(); + let mut current_element = elements.next(); + if let Some(element) = ¤t_element { + if matches!(element.kind(), T![biome] | T![marzano]) { + slots.mark_present(); + current_element = elements.next(); + } + } + slots.next_slot(); + if current_element.is_some() { + return RawSyntaxNode::new( + GRIT_ENGINE_NAME.to_bogus(), + children.into_iter().map(Some), + ); + } + slots.into_node(GRIT_ENGINE_NAME, children) + } GRIT_EVERY => { let mut elements = (&children).into_iter(); let mut slots: RawNodeSlots<2usize> = RawNodeSlots::default(); @@ -577,7 +597,7 @@ impl SyntaxFactory for GritSyntaxFactory { } slots.next_slot(); if let Some(element) = ¤t_element { - if GritLanguageName::can_cast(element.kind()) { + if AnyGritLanguageName::can_cast(element.kind()) { slots.mark_present(); current_element = elements.next(); } @@ -684,7 +704,7 @@ impl SyntaxFactory for GritSyntaxFactory { let mut slots: RawNodeSlots<2usize> = RawNodeSlots::default(); let mut current_element = elements.next(); if let Some(element) = ¤t_element { - if GritLanguageName::can_cast(element.kind()) { + if AnyGritLanguageName::can_cast(element.kind()) { slots.mark_present(); current_element = elements.next(); } @@ -2948,7 +2968,7 @@ impl SyntaxFactory for GritSyntaxFactory { } slots.next_slot(); if let Some(element) = ¤t_element { - if element.kind() == T![biome] { + if GritEngineName::can_cast(element.kind()) { slots.mark_present(); current_element = elements.next(); } diff --git a/crates/biome_grit_formatter/src/generated.rs b/crates/biome_grit_formatter/src/generated.rs index 6459a1203cb8..526d4d6f0932 100644 --- a/crates/biome_grit_formatter/src/generated.rs +++ b/crates/biome_grit_formatter/src/generated.rs @@ -559,6 +559,44 @@ impl IntoFormat for biome_grit_syntax::GritDoubleLiteral { ) } } +impl FormatRule + for crate::grit::auxiliary::engine_name::FormatGritEngineName +{ + type Context = GritFormatContext; + #[inline(always)] + fn fmt( + &self, + node: &biome_grit_syntax::GritEngineName, + f: &mut GritFormatter, + ) -> FormatResult<()> { + FormatNodeRule::::fmt(self, node, f) + } +} +impl AsFormat for biome_grit_syntax::GritEngineName { + type Format<'a> = FormatRefWithRule< + 'a, + biome_grit_syntax::GritEngineName, + crate::grit::auxiliary::engine_name::FormatGritEngineName, + >; + fn format(&self) -> Self::Format<'_> { + FormatRefWithRule::new( + self, + crate::grit::auxiliary::engine_name::FormatGritEngineName::default(), + ) + } +} +impl IntoFormat for biome_grit_syntax::GritEngineName { + type Format = FormatOwnedWithRule< + biome_grit_syntax::GritEngineName, + crate::grit::auxiliary::engine_name::FormatGritEngineName, + >; + fn into_format(self) -> Self::Format { + FormatOwnedWithRule::new( + self, + crate::grit::auxiliary::engine_name::FormatGritEngineName::default(), + ) + } +} impl FormatRule for crate::grit::auxiliary::every::FormatGritEvery { type Context = GritFormatContext; #[inline(always)] @@ -3819,6 +3857,44 @@ impl IntoFormat for biome_grit_syntax::GritBogusLanguageFlavo FormatOwnedWithRule :: new (self , crate :: grit :: bogus :: bogus_language_flavor_kind :: FormatGritBogusLanguageFlavorKind :: default ()) } } +impl FormatRule + for crate::grit::bogus::bogus_language_name::FormatGritBogusLanguageName +{ + type Context = GritFormatContext; + #[inline(always)] + fn fmt( + &self, + node: &biome_grit_syntax::GritBogusLanguageName, + f: &mut GritFormatter, + ) -> FormatResult<()> { + FormatBogusNodeRule::::fmt(self, node, f) + } +} +impl AsFormat for biome_grit_syntax::GritBogusLanguageName { + type Format<'a> = FormatRefWithRule< + 'a, + biome_grit_syntax::GritBogusLanguageName, + crate::grit::bogus::bogus_language_name::FormatGritBogusLanguageName, + >; + fn format(&self) -> Self::Format<'_> { + FormatRefWithRule::new( + self, + crate::grit::bogus::bogus_language_name::FormatGritBogusLanguageName::default(), + ) + } +} +impl IntoFormat for biome_grit_syntax::GritBogusLanguageName { + type Format = FormatOwnedWithRule< + biome_grit_syntax::GritBogusLanguageName, + crate::grit::bogus::bogus_language_name::FormatGritBogusLanguageName, + >; + fn into_format(self) -> Self::Format { + FormatOwnedWithRule::new( + self, + crate::grit::bogus::bogus_language_name::FormatGritBogusLanguageName::default(), + ) + } +} impl FormatRule for crate::grit::bogus::bogus_literal::FormatGritBogusLiteral { @@ -4172,6 +4248,31 @@ impl IntoFormat for biome_grit_syntax::AnyGritLanguageFlavorK ) } } +impl AsFormat for biome_grit_syntax::AnyGritLanguageName { + type Format<'a> = FormatRefWithRule< + 'a, + biome_grit_syntax::AnyGritLanguageName, + crate::grit::any::language_name::FormatAnyGritLanguageName, + >; + fn format(&self) -> Self::Format<'_> { + FormatRefWithRule::new( + self, + crate::grit::any::language_name::FormatAnyGritLanguageName::default(), + ) + } +} +impl IntoFormat for biome_grit_syntax::AnyGritLanguageName { + type Format = FormatOwnedWithRule< + biome_grit_syntax::AnyGritLanguageName, + crate::grit::any::language_name::FormatAnyGritLanguageName, + >; + fn into_format(self) -> Self::Format { + FormatOwnedWithRule::new( + self, + crate::grit::any::language_name::FormatAnyGritLanguageName::default(), + ) + } +} impl AsFormat for biome_grit_syntax::AnyGritListAccessorSubject { type Format<'a> = FormatRefWithRule< 'a, diff --git a/crates/biome_grit_formatter/src/grit/any/language_name.rs b/crates/biome_grit_formatter/src/grit/any/language_name.rs new file mode 100644 index 000000000000..2865a0382149 --- /dev/null +++ b/crates/biome_grit_formatter/src/grit/any/language_name.rs @@ -0,0 +1,15 @@ +//! This is a generated file. Don't modify it by hand! Run 'cargo codegen formatter' to re-generate the file. + +use crate::prelude::*; +use biome_grit_syntax::AnyGritLanguageName; +#[derive(Debug, Clone, Default)] +pub(crate) struct FormatAnyGritLanguageName; +impl FormatRule for FormatAnyGritLanguageName { + type Context = GritFormatContext; + fn fmt(&self, node: &AnyGritLanguageName, f: &mut GritFormatter) -> FormatResult<()> { + match node { + AnyGritLanguageName::GritBogusLanguageName(node) => node.format().fmt(f), + AnyGritLanguageName::GritLanguageName(node) => node.format().fmt(f), + } + } +} diff --git a/crates/biome_grit_formatter/src/grit/any/mod.rs b/crates/biome_grit_formatter/src/grit/any/mod.rs index 017f93a503e7..086d0a93bdc2 100644 --- a/crates/biome_grit_formatter/src/grit/any/mod.rs +++ b/crates/biome_grit_formatter/src/grit/any/mod.rs @@ -5,6 +5,7 @@ pub(crate) mod container; pub(crate) mod definition; pub(crate) mod language_declaration; pub(crate) mod language_flavor_kind; +pub(crate) mod language_name; pub(crate) mod list_accessor_subject; pub(crate) mod list_index; pub(crate) mod list_pattern; diff --git a/crates/biome_grit_formatter/src/grit/auxiliary/engine_name.rs b/crates/biome_grit_formatter/src/grit/auxiliary/engine_name.rs new file mode 100644 index 000000000000..bd367c5d4c72 --- /dev/null +++ b/crates/biome_grit_formatter/src/grit/auxiliary/engine_name.rs @@ -0,0 +1,10 @@ +use crate::prelude::*; +use biome_formatter::write; +use biome_grit_syntax::GritEngineName; +#[derive(Debug, Clone, Default)] +pub(crate) struct FormatGritEngineName; +impl FormatNodeRule for FormatGritEngineName { + fn fmt_fields(&self, node: &GritEngineName, f: &mut GritFormatter) -> FormatResult<()> { + write!(f, [node.engine_kind().format()]) + } +} diff --git a/crates/biome_grit_formatter/src/grit/auxiliary/mod.rs b/crates/biome_grit_formatter/src/grit/auxiliary/mod.rs index e03696158abd..1b6f294b87af 100644 --- a/crates/biome_grit_formatter/src/grit/auxiliary/mod.rs +++ b/crates/biome_grit_formatter/src/grit/auxiliary/mod.rs @@ -5,6 +5,7 @@ pub(crate) mod bubble; pub(crate) mod bubble_scope; pub(crate) mod dot; pub(crate) mod dotdotdot; +pub(crate) mod engine_name; pub(crate) mod every; pub(crate) mod files; pub(crate) mod language_declaration; diff --git a/crates/biome_grit_formatter/src/grit/auxiliary/version.rs b/crates/biome_grit_formatter/src/grit/auxiliary/version.rs index 40527bb801bc..c65ee841d132 100644 --- a/crates/biome_grit_formatter/src/grit/auxiliary/version.rs +++ b/crates/biome_grit_formatter/src/grit/auxiliary/version.rs @@ -7,7 +7,7 @@ impl FormatNodeRule for FormatGritVersion { fn fmt_fields(&self, node: &GritVersion, f: &mut GritFormatter) -> FormatResult<()> { let GritVersionFields { engine_token, - biome_token, + engine_name, l_paren_token, version, r_paren_token, @@ -18,7 +18,7 @@ impl FormatNodeRule for FormatGritVersion { [ engine_token.format(), space(), - biome_token.format(), + engine_name.format(), l_paren_token.format(), version.format(), r_paren_token.format() diff --git a/crates/biome_grit_formatter/src/grit/bogus/bogus_language_name.rs b/crates/biome_grit_formatter/src/grit/bogus/bogus_language_name.rs new file mode 100644 index 000000000000..baa0d0005495 --- /dev/null +++ b/crates/biome_grit_formatter/src/grit/bogus/bogus_language_name.rs @@ -0,0 +1,5 @@ +use crate::FormatBogusNodeRule; +use biome_grit_syntax::GritBogusLanguageName; +#[derive(Debug, Clone, Default)] +pub(crate) struct FormatGritBogusLanguageName; +impl FormatBogusNodeRule for FormatGritBogusLanguageName {} diff --git a/crates/biome_grit_formatter/src/grit/bogus/mod.rs b/crates/biome_grit_formatter/src/grit/bogus/mod.rs index a674483f83e5..f63e34624fde 100644 --- a/crates/biome_grit_formatter/src/grit/bogus/mod.rs +++ b/crates/biome_grit_formatter/src/grit/bogus/mod.rs @@ -6,6 +6,7 @@ pub(crate) mod bogus_container; pub(crate) mod bogus_definition; pub(crate) mod bogus_language_declaration; pub(crate) mod bogus_language_flavor_kind; +pub(crate) mod bogus_language_name; pub(crate) mod bogus_literal; pub(crate) mod bogus_map_element; pub(crate) mod bogus_named_arg; diff --git a/crates/biome_grit_formatter/tests/specs/grit/marzano/engine.grit b/crates/biome_grit_formatter/tests/specs/grit/marzano/engine.grit new file mode 100644 index 000000000000..778c026957a3 --- /dev/null +++ b/crates/biome_grit_formatter/tests/specs/grit/marzano/engine.grit @@ -0,0 +1,3 @@ +engine marzano(0.1) + +`console.log($var)` => `console.log($var)` diff --git a/crates/biome_grit_formatter/tests/specs/grit/marzano/engine.grit.snap b/crates/biome_grit_formatter/tests/specs/grit/marzano/engine.grit.snap new file mode 100644 index 000000000000..7323eead3891 --- /dev/null +++ b/crates/biome_grit_formatter/tests/specs/grit/marzano/engine.grit.snap @@ -0,0 +1,32 @@ +--- +source: crates/biome_formatter_test/src/snapshot_builder.rs +info: grit/marzano/engine.grit +--- +# Input + +```grit +engine marzano(0.1) + +`console.log($var)` => `console.log($var)` + +``` + + +============================= + +# Outputs + +## Output 1 + +----- +Indent style: Tab +Indent width: 2 +Line ending: LF +Line width: 80 +Attribute Position: Auto +----- + +```grit +engine marzano(0.1) +`console.log($var)` => `console.log($var)` +``` diff --git a/crates/biome_grit_formatter/tests/specs/grit/marzano/python.grit b/crates/biome_grit_formatter/tests/specs/grit/marzano/python.grit new file mode 100644 index 000000000000..e4fc2f68b123 --- /dev/null +++ b/crates/biome_grit_formatter/tests/specs/grit/marzano/python.grit @@ -0,0 +1,4 @@ +engine biome(0.1) +language python + +`$var in $dict.keys()` => `$var in $dict` diff --git a/crates/biome_grit_formatter/tests/specs/grit/marzano/python.grit.snap b/crates/biome_grit_formatter/tests/specs/grit/marzano/python.grit.snap new file mode 100644 index 000000000000..f17ff18300a7 --- /dev/null +++ b/crates/biome_grit_formatter/tests/specs/grit/marzano/python.grit.snap @@ -0,0 +1,34 @@ +--- +source: crates/biome_formatter_test/src/snapshot_builder.rs +info: grit/marzano/python.grit +--- +# Input + +```grit +engine biome(0.1) +language python + +`$var in $dict.keys()` => `$var in $dict` + +``` + + +============================= + +# Outputs + +## Output 1 + +----- +Indent style: Tab +Indent width: 2 +Line ending: LF +Line width: 80 +Attribute Position: Auto +----- + +```grit +engine biome(0.1) +language python; +`$var in $dict.keys()` => `$var in $dict` +``` diff --git a/crates/biome_grit_parser/src/constants.rs b/crates/biome_grit_parser/src/constants.rs index 420023af507a..3d38a4e4ab5e 100644 --- a/crates/biome_grit_parser/src/constants.rs +++ b/crates/biome_grit_parser/src/constants.rs @@ -50,6 +50,10 @@ pub(crate) const NOT_SET: TokenSet = token_set![NOT_KW, T![!]]; pub(crate) const REGEX_SET: TokenSet = token_set![GRIT_REGEX, GRIT_SNIPPET_REGEX]; +// Engine names we can parse for formatting purposes +pub(crate) const SUPPORTED_ENGINE_SET: TokenSet = + token_set![T![biome], T![marzano]]; + pub(crate) const SUPPORTED_LANGUAGE_SET: TokenSet = token_set![T![js], T![json], T![css], T![grit], T![html]]; diff --git a/crates/biome_grit_parser/src/lexer/mod.rs b/crates/biome_grit_parser/src/lexer/mod.rs index 0aad07a61a50..4435900044bf 100644 --- a/crates/biome_grit_parser/src/lexer/mod.rs +++ b/crates/biome_grit_parser/src/lexer/mod.rs @@ -777,6 +777,7 @@ impl<'src> GritLexer<'src> { b"multifile" => MULTIFILE_KW, b"engine" => ENGINE_KW, b"biome" => BIOME_KW, + b"marzano" => MARZANO_KW, b"language" => LANGUAGE_KW, b"js" => JS_KW, b"css" => CSS_KW, diff --git a/crates/biome_grit_parser/src/parser/mod.rs b/crates/biome_grit_parser/src/parser/mod.rs index 0acdca036468..49ceb97cdc29 100644 --- a/crates/biome_grit_parser/src/parser/mod.rs +++ b/crates/biome_grit_parser/src/parser/mod.rs @@ -104,7 +104,8 @@ fn parse_version(p: &mut GritParser) -> ParsedSyntax { let mut is_supported = true; let engine_range = p.cur_range(); - if p.eat(T![biome]) { + + if parse_engine_name(p) != Absent { if p.eat(T!['(']) { match parse_double_literal(p) { Present(_) => { @@ -144,6 +145,16 @@ fn parse_version(p: &mut GritParser) -> ParsedSyntax { )) } +fn parse_engine_name(p: &mut GritParser) -> ParsedSyntax { + if !p.at_ts(SUPPORTED_ENGINE_SET) { + return Absent; + } + + let m = p.start(); + p.bump_ts(SUPPORTED_ENGINE_SET); + Present(m.complete(p, GRIT_ENGINE_NAME)) +} + fn parse_language_declaration(p: &mut GritParser) -> ParsedSyntax { if !p.at(T![language]) { return Absent; @@ -222,7 +233,10 @@ impl ParseSeparatedList for LanguageFlavorList { fn parse_language_name(p: &mut GritParser) -> ParsedSyntax { if !p.at_ts(SUPPORTED_LANGUAGE_SET) { - return Absent; + let m = p.start(); + p.error(expected_language_name(p, p.cur_range())); + p.bump_any(); + return Present(m.complete(p, GRIT_BOGUS_LANGUAGE_NAME)); } let m = p.start(); diff --git a/crates/biome_grit_parser/tests/grit_test_suite/err/incorrect_engine.grit b/crates/biome_grit_parser/tests/grit_test_suite/err/incorrect_engine.grit index ddc662cab0ce..0afd3dc72901 100644 --- a/crates/biome_grit_parser/tests/grit_test_suite/err/incorrect_engine.grit +++ b/crates/biome_grit_parser/tests/grit_test_suite/err/incorrect_engine.grit @@ -1 +1 @@ -engine marzano (1.0) +engine marzani (1.0) diff --git a/crates/biome_grit_parser/tests/grit_test_suite/err/incorrect_engine.grit.snap b/crates/biome_grit_parser/tests/grit_test_suite/err/incorrect_engine.grit.snap index 721bdb8302fe..6d6c130e4afc 100644 --- a/crates/biome_grit_parser/tests/grit_test_suite/err/incorrect_engine.grit.snap +++ b/crates/biome_grit_parser/tests/grit_test_suite/err/incorrect_engine.grit.snap @@ -4,7 +4,7 @@ expression: snapshot --- ## Input ```grit -engine marzano (1.0) +engine marzani (1.0) ``` @@ -22,7 +22,7 @@ GritRoot { definitions: GritDefinitionList [ GritNodeLike { name: GritName { - value_token: GRIT_NAME@7..15 "marzano" [] [Whitespace(" ")], + value_token: GRIT_NAME@7..15 "marzani" [] [Whitespace(" ")], }, l_paren_token: L_PAREN@15..16 "(" [] [], named_args: GritNamedArgList [ @@ -48,7 +48,7 @@ GritRoot { 3: GRIT_DEFINITION_LIST@7..20 0: GRIT_NODE_LIKE@7..20 0: GRIT_NAME@7..15 - 0: GRIT_NAME@7..15 "marzano" [] [Whitespace(" ")] + 0: GRIT_NAME@7..15 "marzani" [] [Whitespace(" ")] 1: L_PAREN@15..16 "(" [] [] 2: GRIT_NAMED_ARG_LIST@16..19 0: GRIT_DOUBLE_LITERAL@16..19 @@ -65,7 +65,7 @@ incorrect_engine.grit:1:8 parse ━━━━━━━━━━━━━━━━ × Engine must be `biome` - > 1 │ engine marzano (1.0) + > 1 │ engine marzani (1.0) │ ^^^^^^^ 2 │ diff --git a/crates/biome_grit_parser/tests/grit_test_suite/err/incorrect_version.grit.snap b/crates/biome_grit_parser/tests/grit_test_suite/err/incorrect_version.grit.snap index 2bf6775ab133..2cbac6ea659d 100644 --- a/crates/biome_grit_parser/tests/grit_test_suite/err/incorrect_version.grit.snap +++ b/crates/biome_grit_parser/tests/grit_test_suite/err/incorrect_version.grit.snap @@ -15,7 +15,9 @@ GritRoot { version: GritBogusVersion { items: [ ENGINE_KW@0..7 "engine" [] [Whitespace(" ")], - BIOME_KW@7..13 "biome" [] [Whitespace(" ")], + GritEngineName { + engine_kind: BIOME_KW@7..13 "biome" [] [Whitespace(" ")], + }, L_PAREN@13..14 "(" [] [], GRIT_STRING@14..19 "\"1.0\"" [] [], R_PAREN@19..20 ")" [] [], @@ -34,7 +36,8 @@ GritRoot { 0: (empty) 1: GRIT_BOGUS_VERSION@0..20 0: ENGINE_KW@0..7 "engine" [] [Whitespace(" ")] - 1: BIOME_KW@7..13 "biome" [] [Whitespace(" ")] + 1: GRIT_ENGINE_NAME@7..13 + 0: BIOME_KW@7..13 "biome" [] [Whitespace(" ")] 2: L_PAREN@13..14 "(" [] [] 3: GRIT_STRING@14..19 "\"1.0\"" [] [] 4: R_PAREN@19..20 ")" [] [] diff --git a/crates/biome_grit_parser/tests/grit_test_suite/err/invalid_language.grit.snap b/crates/biome_grit_parser/tests/grit_test_suite/err/invalid_language.grit.snap index ad776baa379a..e6fc6b7b5494 100644 --- a/crates/biome_grit_parser/tests/grit_test_suite/err/invalid_language.grit.snap +++ b/crates/biome_grit_parser/tests/grit_test_suite/err/invalid_language.grit.snap @@ -14,12 +14,15 @@ language non_existing; GritRoot { bom_token: missing (optional), version: missing (optional), - language: GritBogusLanguageDeclaration { - items: [ - LANGUAGE_KW@0..9 "language" [] [Whitespace(" ")], - GRIT_NAME@9..21 "non_existing" [] [], - SEMICOLON@21..22 ";" [] [], - ], + language: GritLanguageDeclaration { + language_token: LANGUAGE_KW@0..9 "language" [] [Whitespace(" ")], + name: GritBogusLanguageName { + items: [ + GRIT_NAME@9..21 "non_existing" [] [], + ], + }, + flavor: missing (optional), + semicolon_token: SEMICOLON@21..22 ";" [] [], }, definitions: GritDefinitionList [], eof_token: EOF@22..23 "" [Newline("\n")] [], @@ -32,10 +35,12 @@ GritRoot { 0: GRIT_ROOT@0..23 0: (empty) 1: (empty) - 2: GRIT_BOGUS_LANGUAGE_DECLARATION@0..22 + 2: GRIT_LANGUAGE_DECLARATION@0..22 0: LANGUAGE_KW@0..9 "language" [] [Whitespace(" ")] - 1: GRIT_NAME@9..21 "non_existing" [] [] - 2: SEMICOLON@21..22 ";" [] [] + 1: GRIT_BOGUS_LANGUAGE_NAME@9..21 + 0: GRIT_NAME@9..21 "non_existing" [] [] + 2: (empty) + 3: SEMICOLON@21..22 ";" [] [] 3: GRIT_DEFINITION_LIST@22..22 4: EOF@22..23 "" [Newline("\n")] [] diff --git a/crates/biome_grit_parser/tests/grit_test_suite/err/missing_version.grit.snap b/crates/biome_grit_parser/tests/grit_test_suite/err/missing_version.grit.snap index fc85099becd1..65bbc062dc55 100644 --- a/crates/biome_grit_parser/tests/grit_test_suite/err/missing_version.grit.snap +++ b/crates/biome_grit_parser/tests/grit_test_suite/err/missing_version.grit.snap @@ -16,7 +16,9 @@ GritRoot { version: GritBogusVersion { items: [ ENGINE_KW@0..7 "engine" [] [Whitespace(" ")], - BIOME_KW@7..12 "biome" [] [], + GritEngineName { + engine_kind: BIOME_KW@7..12 "biome" [] [], + }, ], }, language: missing (optional), @@ -32,7 +34,8 @@ GritRoot { 0: (empty) 1: GRIT_BOGUS_VERSION@0..12 0: ENGINE_KW@0..7 "engine" [] [Whitespace(" ")] - 1: BIOME_KW@7..12 "biome" [] [] + 1: GRIT_ENGINE_NAME@7..12 + 0: BIOME_KW@7..12 "biome" [] [] 2: (empty) 3: GRIT_DEFINITION_LIST@12..12 4: EOF@12..13 "" [Newline("\n")] [] diff --git a/crates/biome_grit_parser/tests/grit_test_suite/err/python_language.grit b/crates/biome_grit_parser/tests/grit_test_suite/err/python_language.grit new file mode 100644 index 000000000000..2894bad828d3 --- /dev/null +++ b/crates/biome_grit_parser/tests/grit_test_suite/err/python_language.grit @@ -0,0 +1,4 @@ +engine biome(0.1) +language python; + +`$var in $dict.keys()` => `$var in $dict` diff --git a/crates/biome_grit_parser/tests/grit_test_suite/err/python_language.grit.snap b/crates/biome_grit_parser/tests/grit_test_suite/err/python_language.grit.snap new file mode 100644 index 000000000000..336e9f623c89 --- /dev/null +++ b/crates/biome_grit_parser/tests/grit_test_suite/err/python_language.grit.snap @@ -0,0 +1,114 @@ +--- +source: crates/biome_grit_parser/tests/spec_test.rs +expression: snapshot +--- +## Input +```grit +engine biome(0.1) +language python; + +`$var in $dict.keys()` => `$var in $dict` + +``` + +## AST + +``` +GritRoot { + bom_token: missing (optional), + version: GritVersion { + engine_token: ENGINE_KW@0..7 "engine" [] [Whitespace(" ")], + engine_name: GritEngineName { + engine_kind: BIOME_KW@7..12 "biome" [] [], + }, + l_paren_token: L_PAREN@12..13 "(" [] [], + version: GritDoubleLiteral { + value_token: GRIT_DOUBLE@13..16 "0.1" [] [], + }, + r_paren_token: R_PAREN@16..17 ")" [] [], + }, + language: GritLanguageDeclaration { + language_token: LANGUAGE_KW@17..27 "language" [Newline("\n")] [Whitespace(" ")], + name: GritBogusLanguageName { + items: [ + GRIT_NAME@27..33 "python" [] [], + ], + }, + flavor: missing (optional), + semicolon_token: SEMICOLON@33..34 ";" [] [], + }, + definitions: GritDefinitionList [ + GritRewrite { + left: GritCodeSnippet { + source: GritBacktickSnippetLiteral { + value_token: GRIT_BACKTICK_SNIPPET@34..59 "`$var in $dict.keys()`" [Newline("\n"), Newline("\n")] [Whitespace(" ")], + }, + }, + annotation: missing (optional), + fat_arrow_token: FAT_ARROW@59..62 "=>" [] [Whitespace(" ")], + right: GritCodeSnippet { + source: GritBacktickSnippetLiteral { + value_token: GRIT_BACKTICK_SNIPPET@62..77 "`$var in $dict`" [] [], + }, + }, + }, + ], + eof_token: EOF@77..78 "" [Newline("\n")] [], +} +``` + +## CST + +``` +0: GRIT_ROOT@0..78 + 0: (empty) + 1: GRIT_VERSION@0..17 + 0: ENGINE_KW@0..7 "engine" [] [Whitespace(" ")] + 1: GRIT_ENGINE_NAME@7..12 + 0: BIOME_KW@7..12 "biome" [] [] + 2: L_PAREN@12..13 "(" [] [] + 3: GRIT_DOUBLE_LITERAL@13..16 + 0: GRIT_DOUBLE@13..16 "0.1" [] [] + 4: R_PAREN@16..17 ")" [] [] + 2: GRIT_LANGUAGE_DECLARATION@17..34 + 0: LANGUAGE_KW@17..27 "language" [Newline("\n")] [Whitespace(" ")] + 1: GRIT_BOGUS_LANGUAGE_NAME@27..33 + 0: GRIT_NAME@27..33 "python" [] [] + 2: (empty) + 3: SEMICOLON@33..34 ";" [] [] + 3: GRIT_DEFINITION_LIST@34..77 + 0: GRIT_REWRITE@34..77 + 0: GRIT_CODE_SNIPPET@34..59 + 0: GRIT_BACKTICK_SNIPPET_LITERAL@34..59 + 0: GRIT_BACKTICK_SNIPPET@34..59 "`$var in $dict.keys()`" [Newline("\n"), Newline("\n")] [Whitespace(" ")] + 1: (empty) + 2: FAT_ARROW@59..62 "=>" [] [Whitespace(" ")] + 3: GRIT_CODE_SNIPPET@62..77 + 0: GRIT_BACKTICK_SNIPPET_LITERAL@62..77 + 0: GRIT_BACKTICK_SNIPPET@62..77 "`$var in $dict`" [] [] + 4: EOF@77..78 "" [Newline("\n")] [] + +``` + +## Diagnostics + +``` +python_language.grit:2:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Unexpected language. + + 1 │ engine biome(0.1) + > 2 │ language python; + │ ^^^^^^ + 3 │ + 4 │ `$var in $dict.keys()` => `$var in $dict` + + i Expected one of: + + - js + - json + - css + - grit + - html + +``` diff --git a/crates/biome_grit_parser/tests/grit_test_suite/ok/marzano_pattern.grit b/crates/biome_grit_parser/tests/grit_test_suite/ok/marzano_pattern.grit new file mode 100644 index 000000000000..1318ffef92ac --- /dev/null +++ b/crates/biome_grit_parser/tests/grit_test_suite/ok/marzano_pattern.grit @@ -0,0 +1 @@ +engine marzano(1.0) diff --git a/crates/biome_grit_parser/tests/grit_test_suite/ok/marzano_pattern.grit.snap b/crates/biome_grit_parser/tests/grit_test_suite/ok/marzano_pattern.grit.snap new file mode 100644 index 000000000000..c1aecc3c05b6 --- /dev/null +++ b/crates/biome_grit_parser/tests/grit_test_suite/ok/marzano_pattern.grit.snap @@ -0,0 +1,50 @@ +--- +source: crates/biome_grit_parser/tests/spec_test.rs +expression: snapshot +--- +## Input +```grit +engine marzano(1.0) + +``` + +## AST + +``` +GritRoot { + bom_token: missing (optional), + version: GritVersion { + engine_token: ENGINE_KW@0..7 "engine" [] [Whitespace(" ")], + engine_name: GritEngineName { + engine_kind: MARZANO_KW@7..14 "marzano" [] [], + }, + l_paren_token: L_PAREN@14..15 "(" [] [], + version: GritDoubleLiteral { + value_token: GRIT_DOUBLE@15..18 "1.0" [] [], + }, + r_paren_token: R_PAREN@18..19 ")" [] [], + }, + language: missing (optional), + definitions: GritDefinitionList [], + eof_token: EOF@19..20 "" [Newline("\n")] [], +} +``` + +## CST + +``` +0: GRIT_ROOT@0..20 + 0: (empty) + 1: GRIT_VERSION@0..19 + 0: ENGINE_KW@0..7 "engine" [] [Whitespace(" ")] + 1: GRIT_ENGINE_NAME@7..14 + 0: MARZANO_KW@7..14 "marzano" [] [] + 2: L_PAREN@14..15 "(" [] [] + 3: GRIT_DOUBLE_LITERAL@15..18 + 0: GRIT_DOUBLE@15..18 "1.0" [] [] + 4: R_PAREN@18..19 ")" [] [] + 2: (empty) + 3: GRIT_DEFINITION_LIST@19..19 + 4: EOF@19..20 "" [Newline("\n")] [] + +``` diff --git a/crates/biome_grit_parser/tests/grit_test_suite/ok/pattern_with_version.grit.snap b/crates/biome_grit_parser/tests/grit_test_suite/ok/pattern_with_version.grit.snap index 96636cb758f3..1d7a3d171075 100644 --- a/crates/biome_grit_parser/tests/grit_test_suite/ok/pattern_with_version.grit.snap +++ b/crates/biome_grit_parser/tests/grit_test_suite/ok/pattern_with_version.grit.snap @@ -15,7 +15,9 @@ GritRoot { bom_token: missing (optional), version: GritVersion { engine_token: ENGINE_KW@0..7 "engine" [] [Whitespace(" ")], - biome_token: BIOME_KW@7..13 "biome" [] [Whitespace(" ")], + engine_name: GritEngineName { + engine_kind: BIOME_KW@7..13 "biome" [] [Whitespace(" ")], + }, l_paren_token: L_PAREN@13..14 "(" [] [], version: GritDoubleLiteral { value_token: GRIT_DOUBLE@14..17 "1.0" [] [], @@ -35,7 +37,8 @@ GritRoot { 0: (empty) 1: GRIT_VERSION@0..18 0: ENGINE_KW@0..7 "engine" [] [Whitespace(" ")] - 1: BIOME_KW@7..13 "biome" [] [Whitespace(" ")] + 1: GRIT_ENGINE_NAME@7..13 + 0: BIOME_KW@7..13 "biome" [] [Whitespace(" ")] 2: L_PAREN@13..14 "(" [] [] 3: GRIT_DOUBLE_LITERAL@14..17 0: GRIT_DOUBLE@14..17 "1.0" [] [] diff --git a/crates/biome_grit_parser/tests/grit_test_suite/ok/rewrite_in_where.grit.snap b/crates/biome_grit_parser/tests/grit_test_suite/ok/rewrite_in_where.grit.snap index 81e71c8c4727..9b90111d6909 100644 --- a/crates/biome_grit_parser/tests/grit_test_suite/ok/rewrite_in_where.grit.snap +++ b/crates/biome_grit_parser/tests/grit_test_suite/ok/rewrite_in_where.grit.snap @@ -20,7 +20,9 @@ GritRoot { bom_token: missing (optional), version: GritVersion { engine_token: ENGINE_KW@0..7 "engine" [] [Whitespace(" ")], - biome_token: BIOME_KW@7..12 "biome" [] [], + engine_name: GritEngineName { + engine_kind: BIOME_KW@7..12 "biome" [] [], + }, l_paren_token: L_PAREN@12..13 "(" [] [], version: GritDoubleLiteral { value_token: GRIT_DOUBLE@13..16 "0.1" [] [], @@ -89,7 +91,8 @@ GritRoot { 0: (empty) 1: GRIT_VERSION@0..17 0: ENGINE_KW@0..7 "engine" [] [Whitespace(" ")] - 1: BIOME_KW@7..12 "biome" [] [] + 1: GRIT_ENGINE_NAME@7..12 + 0: BIOME_KW@7..12 "biome" [] [] 2: L_PAREN@12..13 "(" [] [] 3: GRIT_DOUBLE_LITERAL@13..16 0: GRIT_DOUBLE@13..16 "0.1" [] [] diff --git a/crates/biome_grit_syntax/src/generated/kind.rs b/crates/biome_grit_syntax/src/generated/kind.rs index fd65ee49ccdc..b1f9acefa168 100644 --- a/crates/biome_grit_syntax/src/generated/kind.rs +++ b/crates/biome_grit_syntax/src/generated/kind.rs @@ -44,8 +44,9 @@ pub enum GritSyntaxKind { SEQUENTIAL_KW, MULTIFILE_KW, ENGINE_KW, - BIOME_KW, LANGUAGE_KW, + BIOME_KW, + MARZANO_KW, JS_KW, CSS_KW, JSON_KW, @@ -107,6 +108,7 @@ pub enum GritSyntaxKind { GRIT_FILES, GRIT_DEFINITION_LIST, GRIT_VERSION, + GRIT_ENGINE_NAME, GRIT_LANGUAGE_DECLARATION, GRIT_LANGUAGE_FLAVOR, GRIT_LANGUAGE_FLAVOR_LIST, @@ -205,6 +207,7 @@ pub enum GritSyntaxKind { GRIT_BOGUS_MAP_ELEMENT, GRIT_BOGUS_LANGUAGE_DECLARATION, GRIT_BOGUS_LANGUAGE_FLAVOR_KIND, + GRIT_BOGUS_LANGUAGE_NAME, GRIT_BOGUS_LITERAL, GRIT_BOGUS_NAMED_ARG, GRIT_BOGUS_PATTERN, @@ -279,8 +282,9 @@ impl GritSyntaxKind { "sequential" => SEQUENTIAL_KW, "multifile" => MULTIFILE_KW, "engine" => ENGINE_KW, - "biome" => BIOME_KW, "language" => LANGUAGE_KW, + "biome" => BIOME_KW, + "marzano" => MARZANO_KW, "js" => JS_KW, "css" => CSS_KW, "json" => JSON_KW, @@ -356,8 +360,9 @@ impl GritSyntaxKind { SEQUENTIAL_KW => "sequential", MULTIFILE_KW => "multifile", ENGINE_KW => "engine", - BIOME_KW => "biome", LANGUAGE_KW => "language", + BIOME_KW => "biome", + MARZANO_KW => "marzano", JS_KW => "js", CSS_KW => "css", JSON_KW => "json", @@ -403,4 +408,4 @@ impl GritSyntaxKind { } #[doc = r" Utility macro for creating a SyntaxKind through simple macro syntax"] #[macro_export] -macro_rules ! T { [...] => { $ crate :: GritSyntaxKind :: DOT3 } ; ["$_"] => { $ crate :: GritSyntaxKind :: DOLLAR_UNDERSCORE } ; [<:] => { $ crate :: GritSyntaxKind :: MATCH } ; [;] => { $ crate :: GritSyntaxKind :: SEMICOLON } ; [,] => { $ crate :: GritSyntaxKind :: COMMA } ; ['('] => { $ crate :: GritSyntaxKind :: L_PAREN } ; [')'] => { $ crate :: GritSyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: GritSyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: GritSyntaxKind :: R_CURLY } ; ['['] => { $ crate :: GritSyntaxKind :: L_BRACK } ; [']'] => { $ crate :: GritSyntaxKind :: R_BRACK } ; [<] => { $ crate :: GritSyntaxKind :: L_ANGLE } ; [>] => { $ crate :: GritSyntaxKind :: R_ANGLE } ; [+] => { $ crate :: GritSyntaxKind :: PLUS } ; [*] => { $ crate :: GritSyntaxKind :: STAR } ; [/] => { $ crate :: GritSyntaxKind :: SLASH } ; [%] => { $ crate :: GritSyntaxKind :: PERCENT } ; [.] => { $ crate :: GritSyntaxKind :: DOT } ; [:] => { $ crate :: GritSyntaxKind :: COLON } ; [=] => { $ crate :: GritSyntaxKind :: EQ } ; [==] => { $ crate :: GritSyntaxKind :: EQ2 } ; [=>] => { $ crate :: GritSyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: GritSyntaxKind :: BANG } ; [!=] => { $ crate :: GritSyntaxKind :: NEQ } ; [-] => { $ crate :: GritSyntaxKind :: MINUS } ; [<=] => { $ crate :: GritSyntaxKind :: LTEQ } ; [>=] => { $ crate :: GritSyntaxKind :: GTEQ } ; [+=] => { $ crate :: GritSyntaxKind :: PLUSEQ } ; ['`'] => { $ crate :: GritSyntaxKind :: BACKTICK } ; [sequential] => { $ crate :: GritSyntaxKind :: SEQUENTIAL_KW } ; [multifile] => { $ crate :: GritSyntaxKind :: MULTIFILE_KW } ; [engine] => { $ crate :: GritSyntaxKind :: ENGINE_KW } ; [biome] => { $ crate :: GritSyntaxKind :: BIOME_KW } ; [language] => { $ crate :: GritSyntaxKind :: LANGUAGE_KW } ; [js] => { $ crate :: GritSyntaxKind :: JS_KW } ; [css] => { $ crate :: GritSyntaxKind :: CSS_KW } ; [json] => { $ crate :: GritSyntaxKind :: JSON_KW } ; [grit] => { $ crate :: GritSyntaxKind :: GRIT_KW } ; [html] => { $ crate :: GritSyntaxKind :: HTML_KW } ; [typescript] => { $ crate :: GritSyntaxKind :: TYPESCRIPT_KW } ; [jsx] => { $ crate :: GritSyntaxKind :: JSX_KW } ; [js_do_not_use] => { $ crate :: GritSyntaxKind :: JS_DO_NOT_USE_KW } ; [as] => { $ crate :: GritSyntaxKind :: AS_KW } ; [limit] => { $ crate :: GritSyntaxKind :: LIMIT_KW } ; [where] => { $ crate :: GritSyntaxKind :: WHERE_KW } ; [orelse] => { $ crate :: GritSyntaxKind :: ORELSE_KW } ; [maybe] => { $ crate :: GritSyntaxKind :: MAYBE_KW } ; [after] => { $ crate :: GritSyntaxKind :: AFTER_KW } ; [before] => { $ crate :: GritSyntaxKind :: BEFORE_KW } ; [contains] => { $ crate :: GritSyntaxKind :: CONTAINS_KW } ; [until] => { $ crate :: GritSyntaxKind :: UNTIL_KW } ; [includes] => { $ crate :: GritSyntaxKind :: INCLUDES_KW } ; [if] => { $ crate :: GritSyntaxKind :: IF_KW } ; [else] => { $ crate :: GritSyntaxKind :: ELSE_KW } ; [within] => { $ crate :: GritSyntaxKind :: WITHIN_KW } ; [bubble] => { $ crate :: GritSyntaxKind :: BUBBLE_KW } ; [not] => { $ crate :: GritSyntaxKind :: NOT_KW } ; [or] => { $ crate :: GritSyntaxKind :: OR_KW } ; [and] => { $ crate :: GritSyntaxKind :: AND_KW } ; [any] => { $ crate :: GritSyntaxKind :: ANY_KW } ; [some] => { $ crate :: GritSyntaxKind :: SOME_KW } ; [every] => { $ crate :: GritSyntaxKind :: EVERY_KW } ; [private] => { $ crate :: GritSyntaxKind :: PRIVATE_KW } ; [pattern] => { $ crate :: GritSyntaxKind :: PATTERN_KW } ; [predicate] => { $ crate :: GritSyntaxKind :: PREDICATE_KW } ; [function] => { $ crate :: GritSyntaxKind :: FUNCTION_KW } ; [true] => { $ crate :: GritSyntaxKind :: TRUE_KW } ; [false] => { $ crate :: GritSyntaxKind :: FALSE_KW } ; [undefined] => { $ crate :: GritSyntaxKind :: UNDEFINED_KW } ; [like] => { $ crate :: GritSyntaxKind :: LIKE_KW } ; [return] => { $ crate :: GritSyntaxKind :: RETURN_KW } ; [ident] => { $ crate :: GritSyntaxKind :: IDENT } ; [EOF] => { $ crate :: GritSyntaxKind :: EOF } ; [UNICODE_BOM] => { $ crate :: GritSyntaxKind :: UNICODE_BOM } ; [#] => { $ crate :: GritSyntaxKind :: HASH } ; } +macro_rules ! T { [...] => { $ crate :: GritSyntaxKind :: DOT3 } ; ["$_"] => { $ crate :: GritSyntaxKind :: DOLLAR_UNDERSCORE } ; [<:] => { $ crate :: GritSyntaxKind :: MATCH } ; [;] => { $ crate :: GritSyntaxKind :: SEMICOLON } ; [,] => { $ crate :: GritSyntaxKind :: COMMA } ; ['('] => { $ crate :: GritSyntaxKind :: L_PAREN } ; [')'] => { $ crate :: GritSyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: GritSyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: GritSyntaxKind :: R_CURLY } ; ['['] => { $ crate :: GritSyntaxKind :: L_BRACK } ; [']'] => { $ crate :: GritSyntaxKind :: R_BRACK } ; [<] => { $ crate :: GritSyntaxKind :: L_ANGLE } ; [>] => { $ crate :: GritSyntaxKind :: R_ANGLE } ; [+] => { $ crate :: GritSyntaxKind :: PLUS } ; [*] => { $ crate :: GritSyntaxKind :: STAR } ; [/] => { $ crate :: GritSyntaxKind :: SLASH } ; [%] => { $ crate :: GritSyntaxKind :: PERCENT } ; [.] => { $ crate :: GritSyntaxKind :: DOT } ; [:] => { $ crate :: GritSyntaxKind :: COLON } ; [=] => { $ crate :: GritSyntaxKind :: EQ } ; [==] => { $ crate :: GritSyntaxKind :: EQ2 } ; [=>] => { $ crate :: GritSyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: GritSyntaxKind :: BANG } ; [!=] => { $ crate :: GritSyntaxKind :: NEQ } ; [-] => { $ crate :: GritSyntaxKind :: MINUS } ; [<=] => { $ crate :: GritSyntaxKind :: LTEQ } ; [>=] => { $ crate :: GritSyntaxKind :: GTEQ } ; [+=] => { $ crate :: GritSyntaxKind :: PLUSEQ } ; ['`'] => { $ crate :: GritSyntaxKind :: BACKTICK } ; [sequential] => { $ crate :: GritSyntaxKind :: SEQUENTIAL_KW } ; [multifile] => { $ crate :: GritSyntaxKind :: MULTIFILE_KW } ; [engine] => { $ crate :: GritSyntaxKind :: ENGINE_KW } ; [language] => { $ crate :: GritSyntaxKind :: LANGUAGE_KW } ; [biome] => { $ crate :: GritSyntaxKind :: BIOME_KW } ; [marzano] => { $ crate :: GritSyntaxKind :: MARZANO_KW } ; [js] => { $ crate :: GritSyntaxKind :: JS_KW } ; [css] => { $ crate :: GritSyntaxKind :: CSS_KW } ; [json] => { $ crate :: GritSyntaxKind :: JSON_KW } ; [grit] => { $ crate :: GritSyntaxKind :: GRIT_KW } ; [html] => { $ crate :: GritSyntaxKind :: HTML_KW } ; [typescript] => { $ crate :: GritSyntaxKind :: TYPESCRIPT_KW } ; [jsx] => { $ crate :: GritSyntaxKind :: JSX_KW } ; [js_do_not_use] => { $ crate :: GritSyntaxKind :: JS_DO_NOT_USE_KW } ; [as] => { $ crate :: GritSyntaxKind :: AS_KW } ; [limit] => { $ crate :: GritSyntaxKind :: LIMIT_KW } ; [where] => { $ crate :: GritSyntaxKind :: WHERE_KW } ; [orelse] => { $ crate :: GritSyntaxKind :: ORELSE_KW } ; [maybe] => { $ crate :: GritSyntaxKind :: MAYBE_KW } ; [after] => { $ crate :: GritSyntaxKind :: AFTER_KW } ; [before] => { $ crate :: GritSyntaxKind :: BEFORE_KW } ; [contains] => { $ crate :: GritSyntaxKind :: CONTAINS_KW } ; [until] => { $ crate :: GritSyntaxKind :: UNTIL_KW } ; [includes] => { $ crate :: GritSyntaxKind :: INCLUDES_KW } ; [if] => { $ crate :: GritSyntaxKind :: IF_KW } ; [else] => { $ crate :: GritSyntaxKind :: ELSE_KW } ; [within] => { $ crate :: GritSyntaxKind :: WITHIN_KW } ; [bubble] => { $ crate :: GritSyntaxKind :: BUBBLE_KW } ; [not] => { $ crate :: GritSyntaxKind :: NOT_KW } ; [or] => { $ crate :: GritSyntaxKind :: OR_KW } ; [and] => { $ crate :: GritSyntaxKind :: AND_KW } ; [any] => { $ crate :: GritSyntaxKind :: ANY_KW } ; [some] => { $ crate :: GritSyntaxKind :: SOME_KW } ; [every] => { $ crate :: GritSyntaxKind :: EVERY_KW } ; [private] => { $ crate :: GritSyntaxKind :: PRIVATE_KW } ; [pattern] => { $ crate :: GritSyntaxKind :: PATTERN_KW } ; [predicate] => { $ crate :: GritSyntaxKind :: PREDICATE_KW } ; [function] => { $ crate :: GritSyntaxKind :: FUNCTION_KW } ; [true] => { $ crate :: GritSyntaxKind :: TRUE_KW } ; [false] => { $ crate :: GritSyntaxKind :: FALSE_KW } ; [undefined] => { $ crate :: GritSyntaxKind :: UNDEFINED_KW } ; [like] => { $ crate :: GritSyntaxKind :: LIKE_KW } ; [return] => { $ crate :: GritSyntaxKind :: RETURN_KW } ; [ident] => { $ crate :: GritSyntaxKind :: IDENT } ; [EOF] => { $ crate :: GritSyntaxKind :: EOF } ; [UNICODE_BOM] => { $ crate :: GritSyntaxKind :: UNICODE_BOM } ; [#] => { $ crate :: GritSyntaxKind :: HASH } ; } diff --git a/crates/biome_grit_syntax/src/generated/macros.rs b/crates/biome_grit_syntax/src/generated/macros.rs index 5de9f8c84e0a..d91f9088563f 100644 --- a/crates/biome_grit_syntax/src/generated/macros.rs +++ b/crates/biome_grit_syntax/src/generated/macros.rs @@ -77,6 +77,10 @@ macro_rules! map_syntax_node { let $pattern = unsafe { $crate::GritDoubleLiteral::new_unchecked(node) }; $body } + $crate::GritSyntaxKind::GRIT_ENGINE_NAME => { + let $pattern = unsafe { $crate::GritEngineName::new_unchecked(node) }; + $body + } $crate::GritSyntaxKind::GRIT_EVERY => { let $pattern = unsafe { $crate::GritEvery::new_unchecked(node) }; $body @@ -421,6 +425,10 @@ macro_rules! map_syntax_node { unsafe { $crate::GritBogusLanguageFlavorKind::new_unchecked(node) }; $body } + $crate::GritSyntaxKind::GRIT_BOGUS_LANGUAGE_NAME => { + let $pattern = unsafe { $crate::GritBogusLanguageName::new_unchecked(node) }; + $body + } $crate::GritSyntaxKind::GRIT_BOGUS_LITERAL => { let $pattern = unsafe { $crate::GritBogusLiteral::new_unchecked(node) }; $body diff --git a/crates/biome_grit_syntax/src/generated/nodes.rs b/crates/biome_grit_syntax/src/generated/nodes.rs index 07edb225c814..8e20f9a4a902 100644 --- a/crates/biome_grit_syntax/src/generated/nodes.rs +++ b/crates/biome_grit_syntax/src/generated/nodes.rs @@ -630,6 +630,41 @@ pub struct GritDoubleLiteralFields { pub value_token: SyntaxResult, } #[derive(Clone, PartialEq, Eq, Hash)] +pub struct GritEngineName { + pub(crate) syntax: SyntaxNode, +} +impl GritEngineName { + #[doc = r" Create an AstNode from a SyntaxNode without checking its kind"] + #[doc = r""] + #[doc = r" # Safety"] + #[doc = r" This function must be guarded with a call to [AstNode::can_cast]"] + #[doc = r" or a match on [SyntaxNode::kind]"] + #[inline] + pub const unsafe fn new_unchecked(syntax: SyntaxNode) -> Self { + Self { syntax } + } + pub fn as_fields(&self) -> GritEngineNameFields { + GritEngineNameFields { + engine_kind: self.engine_kind(), + } + } + pub fn engine_kind(&self) -> SyntaxResult { + support::required_token(&self.syntax, 0usize) + } +} +impl Serialize for GritEngineName { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.as_fields().serialize(serializer) + } +} +#[derive(Serialize)] +pub struct GritEngineNameFields { + pub engine_kind: SyntaxResult, +} +#[derive(Clone, PartialEq, Eq, Hash)] pub struct GritEvery { pub(crate) syntax: SyntaxNode, } @@ -839,7 +874,7 @@ impl GritLanguageDeclaration { pub fn language_token(&self) -> SyntaxResult { support::required_token(&self.syntax, 0usize) } - pub fn name(&self) -> SyntaxResult { + pub fn name(&self) -> SyntaxResult { support::required_node(&self.syntax, 1usize) } pub fn flavor(&self) -> Option { @@ -860,7 +895,7 @@ impl Serialize for GritLanguageDeclaration { #[derive(Serialize)] pub struct GritLanguageDeclarationFields { pub language_token: SyntaxResult, - pub name: SyntaxResult, + pub name: SyntaxResult, pub flavor: Option, pub semicolon_token: Option, } @@ -999,7 +1034,7 @@ impl GritLanguageSpecificSnippet { snippet_token: self.snippet_token(), } } - pub fn language(&self) -> SyntaxResult { + pub fn language(&self) -> SyntaxResult { support::required_node(&self.syntax, 0usize) } pub fn snippet_token(&self) -> SyntaxResult { @@ -1016,7 +1051,7 @@ impl Serialize for GritLanguageSpecificSnippet { } #[derive(Serialize)] pub struct GritLanguageSpecificSnippetFields { - pub language: SyntaxResult, + pub language: SyntaxResult, pub snippet_token: SyntaxResult, } #[derive(Clone, PartialEq, Eq, Hash)] @@ -4091,7 +4126,7 @@ impl GritVersion { pub fn as_fields(&self) -> GritVersionFields { GritVersionFields { engine_token: self.engine_token(), - biome_token: self.biome_token(), + engine_name: self.engine_name(), l_paren_token: self.l_paren_token(), version: self.version(), r_paren_token: self.r_paren_token(), @@ -4100,8 +4135,8 @@ impl GritVersion { pub fn engine_token(&self) -> SyntaxResult { support::required_token(&self.syntax, 0usize) } - pub fn biome_token(&self) -> SyntaxResult { - support::required_token(&self.syntax, 1usize) + pub fn engine_name(&self) -> SyntaxResult { + support::required_node(&self.syntax, 1usize) } pub fn l_paren_token(&self) -> SyntaxResult { support::required_token(&self.syntax, 2usize) @@ -4124,7 +4159,7 @@ impl Serialize for GritVersion { #[derive(Serialize)] pub struct GritVersionFields { pub engine_token: SyntaxResult, - pub biome_token: SyntaxResult, + pub engine_name: SyntaxResult, pub l_paren_token: SyntaxResult, pub version: SyntaxResult, pub r_paren_token: SyntaxResult, @@ -4307,6 +4342,25 @@ impl AnyGritLanguageFlavorKind { } } #[derive(Clone, PartialEq, Eq, Hash, Serialize)] +pub enum AnyGritLanguageName { + GritBogusLanguageName(GritBogusLanguageName), + GritLanguageName(GritLanguageName), +} +impl AnyGritLanguageName { + pub fn as_grit_bogus_language_name(&self) -> Option<&GritBogusLanguageName> { + match &self { + AnyGritLanguageName::GritBogusLanguageName(item) => Some(item), + _ => None, + } + } + pub fn as_grit_language_name(&self) -> Option<&GritLanguageName> { + match &self { + AnyGritLanguageName::GritLanguageName(item) => Some(item), + _ => None, + } + } +} +#[derive(Clone, PartialEq, Eq, Hash, Serialize)] pub enum AnyGritListAccessorSubject { AnyGritContainer(AnyGritContainer), GritList(GritList), @@ -5656,6 +5710,47 @@ impl From for SyntaxElement { n.syntax.into() } } +impl AstNode for GritEngineName { + type Language = Language; + const KIND_SET: SyntaxKindSet = + SyntaxKindSet::from_raw(RawSyntaxKind(GRIT_ENGINE_NAME as u16)); + fn can_cast(kind: SyntaxKind) -> bool { + kind == GRIT_ENGINE_NAME + } + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } + fn into_syntax(self) -> SyntaxNode { + self.syntax + } +} +impl std::fmt::Debug for GritEngineName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("GritEngineName") + .field( + "engine_kind", + &support::DebugSyntaxResult(self.engine_kind()), + ) + .finish() + } +} +impl From for SyntaxNode { + fn from(n: GritEngineName) -> SyntaxNode { + n.syntax + } +} +impl From for SyntaxElement { + fn from(n: GritEngineName) -> SyntaxElement { + n.syntax.into() + } +} impl AstNode for GritEvery { type Language = Language; const KIND_SET: SyntaxKindSet = @@ -9100,8 +9195,8 @@ impl std::fmt::Debug for GritVersion { &support::DebugSyntaxResult(self.engine_token()), ) .field( - "biome_token", - &support::DebugSyntaxResult(self.biome_token()), + "engine_name", + &support::DebugSyntaxResult(self.engine_name()), ) .field( "l_paren_token", @@ -9597,6 +9692,70 @@ impl From for SyntaxElement { node.into() } } +impl From for AnyGritLanguageName { + fn from(node: GritBogusLanguageName) -> AnyGritLanguageName { + AnyGritLanguageName::GritBogusLanguageName(node) + } +} +impl From for AnyGritLanguageName { + fn from(node: GritLanguageName) -> AnyGritLanguageName { + AnyGritLanguageName::GritLanguageName(node) + } +} +impl AstNode for AnyGritLanguageName { + type Language = Language; + const KIND_SET: SyntaxKindSet = + GritBogusLanguageName::KIND_SET.union(GritLanguageName::KIND_SET); + fn can_cast(kind: SyntaxKind) -> bool { + matches!(kind, GRIT_BOGUS_LANGUAGE_NAME | GRIT_LANGUAGE_NAME) + } + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + GRIT_BOGUS_LANGUAGE_NAME => { + AnyGritLanguageName::GritBogusLanguageName(GritBogusLanguageName { syntax }) + } + GRIT_LANGUAGE_NAME => { + AnyGritLanguageName::GritLanguageName(GritLanguageName { syntax }) + } + _ => return None, + }; + Some(res) + } + fn syntax(&self) -> &SyntaxNode { + match self { + AnyGritLanguageName::GritBogusLanguageName(it) => &it.syntax, + AnyGritLanguageName::GritLanguageName(it) => &it.syntax, + } + } + fn into_syntax(self) -> SyntaxNode { + match self { + AnyGritLanguageName::GritBogusLanguageName(it) => it.syntax, + AnyGritLanguageName::GritLanguageName(it) => it.syntax, + } + } +} +impl std::fmt::Debug for AnyGritLanguageName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AnyGritLanguageName::GritBogusLanguageName(it) => std::fmt::Debug::fmt(it, f), + AnyGritLanguageName::GritLanguageName(it) => std::fmt::Debug::fmt(it, f), + } + } +} +impl From for SyntaxNode { + fn from(n: AnyGritLanguageName) -> SyntaxNode { + match n { + AnyGritLanguageName::GritBogusLanguageName(it) => it.into(), + AnyGritLanguageName::GritLanguageName(it) => it.into(), + } + } +} +impl From for SyntaxElement { + fn from(n: AnyGritLanguageName) -> SyntaxElement { + let node: SyntaxNode = n.into(); + node.into() + } +} impl From for AnyGritListAccessorSubject { fn from(node: GritList) -> AnyGritListAccessorSubject { AnyGritListAccessorSubject::GritList(node) @@ -11330,6 +11489,11 @@ impl std::fmt::Display for AnyGritLanguageFlavorKind { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for AnyGritLanguageName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for AnyGritListAccessorSubject { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -11475,6 +11639,11 @@ impl std::fmt::Display for GritDoubleLiteral { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for GritEngineName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for GritEvery { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) @@ -12151,6 +12320,62 @@ impl From for SyntaxElement { } } #[derive(Clone, PartialEq, Eq, Hash, Serialize)] +pub struct GritBogusLanguageName { + syntax: SyntaxNode, +} +impl GritBogusLanguageName { + #[doc = r" Create an AstNode from a SyntaxNode without checking its kind"] + #[doc = r""] + #[doc = r" # Safety"] + #[doc = r" This function must be guarded with a call to [AstNode::can_cast]"] + #[doc = r" or a match on [SyntaxNode::kind]"] + #[inline] + pub const unsafe fn new_unchecked(syntax: SyntaxNode) -> Self { + Self { syntax } + } + pub fn items(&self) -> SyntaxElementChildren { + support::elements(&self.syntax) + } +} +impl AstNode for GritBogusLanguageName { + type Language = Language; + const KIND_SET: SyntaxKindSet = + SyntaxKindSet::from_raw(RawSyntaxKind(GRIT_BOGUS_LANGUAGE_NAME as u16)); + fn can_cast(kind: SyntaxKind) -> bool { + kind == GRIT_BOGUS_LANGUAGE_NAME + } + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } + fn into_syntax(self) -> SyntaxNode { + self.syntax + } +} +impl std::fmt::Debug for GritBogusLanguageName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("GritBogusLanguageName") + .field("items", &DebugSyntaxElementChildren(self.items())) + .finish() + } +} +impl From for SyntaxNode { + fn from(n: GritBogusLanguageName) -> SyntaxNode { + n.syntax + } +} +impl From for SyntaxElement { + fn from(n: GritBogusLanguageName) -> SyntaxElement { + n.syntax.into() + } +} +#[derive(Clone, PartialEq, Eq, Hash, Serialize)] pub struct GritBogusLiteral { syntax: SyntaxNode, } diff --git a/crates/biome_grit_syntax/src/generated/nodes_mut.rs b/crates/biome_grit_syntax/src/generated/nodes_mut.rs index d5152f505e5a..fa26e3f4f31c 100644 --- a/crates/biome_grit_syntax/src/generated/nodes_mut.rs +++ b/crates/biome_grit_syntax/src/generated/nodes_mut.rs @@ -225,6 +225,14 @@ impl GritDoubleLiteral { ) } } +impl GritEngineName { + pub fn with_engine_kind_token(self, element: SyntaxToken) -> Self { + Self::unwrap_cast( + self.syntax + .splice_slots(0usize..=0usize, once(Some(element.into()))), + ) + } +} impl GritEvery { pub fn with_every_token(self, element: SyntaxToken) -> Self { Self::unwrap_cast( @@ -318,7 +326,7 @@ impl GritLanguageDeclaration { .splice_slots(0usize..=0usize, once(Some(element.into()))), ) } - pub fn with_name(self, element: GritLanguageName) -> Self { + pub fn with_name(self, element: AnyGritLanguageName) -> Self { Self::unwrap_cast( self.syntax .splice_slots(1usize..=1usize, once(Some(element.into_syntax().into()))), @@ -374,7 +382,7 @@ impl GritLanguageName { } } impl GritLanguageSpecificSnippet { - pub fn with_language(self, element: GritLanguageName) -> Self { + pub fn with_language(self, element: AnyGritLanguageName) -> Self { Self::unwrap_cast( self.syntax .splice_slots(0usize..=0usize, once(Some(element.into_syntax().into()))), @@ -1748,10 +1756,10 @@ impl GritVersion { .splice_slots(0usize..=0usize, once(Some(element.into()))), ) } - pub fn with_biome_token(self, element: SyntaxToken) -> Self { + pub fn with_engine_name(self, element: GritEngineName) -> Self { Self::unwrap_cast( self.syntax - .splice_slots(1usize..=1usize, once(Some(element.into()))), + .splice_slots(1usize..=1usize, once(Some(element.into_syntax().into()))), ) } pub fn with_l_paren_token(self, element: SyntaxToken) -> Self { diff --git a/xtask/codegen/gritql.ungram b/xtask/codegen/gritql.ungram index 1ceca6d02985..ca875335e3a5 100644 --- a/xtask/codegen/gritql.ungram +++ b/xtask/codegen/gritql.ungram @@ -43,6 +43,7 @@ GritBogusDefinition = SyntaxElement* GritBogusMapElement = SyntaxElement* GritBogusLanguageDeclaration = SyntaxElement* GritBogusLanguageFlavorKind = SyntaxElement* +GritBogusLanguageName = SyntaxElement* GritBogusLiteral = SyntaxElement* GritBogusNamedArg = SyntaxElement* GritBogusPattern = SyntaxElement* @@ -62,7 +63,12 @@ AnyGritVersion = // engine biome(1.0) // ^^^^^^ ^^^^^^^^^^ -GritVersion = 'engine' 'biome' '(' version: GritDoubleLiteral ')' +GritVersion = + 'engine' + engine_name: GritEngineName + '(' version: GritDoubleLiteral ')' + +GritEngineName = engine_kind: ('biome' | 'marzano') AnyGritLanguageDeclaration = GritLanguageDeclaration @@ -72,7 +78,7 @@ AnyGritLanguageDeclaration = // ^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^ GritLanguageDeclaration = 'language' - name: GritLanguageName + name: AnyGritLanguageName flavor: GritLanguageFlavor? ';'? @@ -580,6 +586,10 @@ GritVariableList = GritVariable (',' GritVariable)* ','? GritName = value: 'grit_name' // These are target languages +AnyGritLanguageName = + GritLanguageName + | GritBogusLanguageName + GritLanguageName = language_kind: ('js' | 'css' | 'json' | 'grit' | 'html') @@ -588,7 +598,7 @@ GritBacktickSnippetLiteral = value: 'grit_backtick_snippet' GritRawBacktickSnippetLiteral = value: 'grit_raw_backtick_snippet' GritLanguageSpecificSnippet = - language: GritLanguageName + language: AnyGritLanguageName snippet: 'grit_string' // a code snippet may be prefixed by a label; diff --git a/xtask/codegen/src/grit_kinds_src.rs b/xtask/codegen/src/grit_kinds_src.rs index ab6a5977c704..c0fd07cdcf27 100644 --- a/xtask/codegen/src/grit_kinds_src.rs +++ b/xtask/codegen/src/grit_kinds_src.rs @@ -40,8 +40,10 @@ pub const GRIT_KINDS_SRC: KindsSrc = KindsSrc { "sequential", "multifile", "engine", - "biome", "language", + // engine names: + "biome", + "marzano", // languages: "js", "css", @@ -117,6 +119,7 @@ pub const GRIT_KINDS_SRC: KindsSrc = KindsSrc { "GRIT_FILES", "GRIT_DEFINITION_LIST", "GRIT_VERSION", + "GRIT_ENGINE_NAME", "GRIT_LANGUAGE_DECLARATION", "GRIT_LANGUAGE_FLAVOR", "GRIT_LANGUAGE_FLAVOR_LIST", @@ -217,6 +220,7 @@ pub const GRIT_KINDS_SRC: KindsSrc = KindsSrc { "GRIT_BOGUS_MAP_ELEMENT", "GRIT_BOGUS_LANGUAGE_DECLARATION", "GRIT_BOGUS_LANGUAGE_FLAVOR_KIND", + "GRIT_BOGUS_LANGUAGE_NAME", "GRIT_BOGUS_LITERAL", "GRIT_BOGUS_NAMED_ARG", "GRIT_BOGUS_PATTERN",