From 754b9f7ed8d0f7f31fd87c25b5096ef1d465fecb Mon Sep 17 00:00:00 2001 From: Steve Dignam Date: Fri, 10 Oct 2025 21:25:08 -0400 Subject: [PATCH 1/2] parser: fill out `create type as enum` nodes --- crates/squawk_ide/src/expand_selection.rs | 2 + .../src/generated/syntax_kind.rs | 2 + crates/squawk_parser/src/grammar.rs | 34 +++++-- .../snapshots/tests__create_type_ok.snap | 43 +++++---- .../squawk_syntax/src/ast/generated/nodes.rs | 90 +++++++++++++++++++ crates/squawk_syntax/src/postgresql.ungram | 13 +++ crates/squawk_wasm/src/lib.rs | 2 +- 7 files changed, 158 insertions(+), 28 deletions(-) diff --git a/crates/squawk_ide/src/expand_selection.rs b/crates/squawk_ide/src/expand_selection.rs index e5e9b94b..8d840073 100644 --- a/crates/squawk_ide/src/expand_selection.rs +++ b/crates/squawk_ide/src/expand_selection.rs @@ -54,6 +54,7 @@ const ALL_LIST_KINDS: &[SyntaxKind] = &[ // only separated by whitespace // SyntaxKind::XML_COLUMN_OPTION_LIST, SyntaxKind::XML_TABLE_COLUMN_LIST, + SyntaxKind::VARIANT_LIST, ]; pub fn extend_selection(root: &SyntaxNode, range: TextRange) -> TextRange { @@ -572,6 +573,7 @@ $0 TARGET_LIST, TRANSACTION_MODE_LIST, VACUUM_OPTION_LIST, + VARIANT_LIST, XML_TABLE_COLUMN_LIST, ] "); diff --git a/crates/squawk_parser/src/generated/syntax_kind.rs b/crates/squawk_parser/src/generated/syntax_kind.rs index 853afea6..0bffdd23 100644 --- a/crates/squawk_parser/src/generated/syntax_kind.rs +++ b/crates/squawk_parser/src/generated/syntax_kind.rs @@ -1011,6 +1011,8 @@ pub enum SyntaxKind { VACUUM_OPTION_LIST, VALIDATE_CONSTRAINT, VALUES, + VARIANT, + VARIANT_LIST, VOLATILITY_FUNC_OPTION, WHEN_CLAUSE, WHERE_CLAUSE, diff --git a/crates/squawk_parser/src/grammar.rs b/crates/squawk_parser/src/grammar.rs index c802d335..26a68de5 100644 --- a/crates/squawk_parser/src/grammar.rs +++ b/crates/squawk_parser/src/grammar.rs @@ -12926,15 +12926,7 @@ fn create_type(p: &mut Parser<'_>) -> CompletedMarker { if p.eat(AS_KW) { // AS ENUM if p.eat(ENUM_KW) { - delimited( - p, - L_PAREN, - R_PAREN, - COMMA, - || "unexpected comma".to_string(), - STRING_FIRST, - |p| opt_string_literal(p).is_some(), - ); + variant_list(p); // AS RANGE } else if p.eat(RANGE_KW) { attribute_list(p); @@ -12959,6 +12951,30 @@ fn create_type(p: &mut Parser<'_>) -> CompletedMarker { m.complete(p, CREATE_TYPE) } +fn opt_variant(p: &mut Parser<'_>) -> bool { + let m = p.start(); + if opt_string_literal(p).is_none() { + m.abandon(p); + return false; + } + m.complete(p, VARIANT); + true +} + +fn variant_list(p: &mut Parser<'_>) { + let m = p.start(); + delimited( + p, + L_PAREN, + R_PAREN, + COMMA, + || "unexpected comma".to_string(), + STRING_FIRST, + opt_variant, + ); + m.complete(p, VARIANT_LIST); +} + // CREATE EXTENSION [ IF NOT EXISTS ] extension_name // [ WITH ] [ SCHEMA schema_name ] // [ VERSION version ] diff --git a/crates/squawk_parser/tests/snapshots/tests__create_type_ok.snap b/crates/squawk_parser/tests/snapshots/tests__create_type_ok.snap index 4fd93d8a..36ebc79d 100644 --- a/crates/squawk_parser/tests/snapshots/tests__create_type_ok.snap +++ b/crates/squawk_parser/tests/snapshots/tests__create_type_ok.snap @@ -125,8 +125,9 @@ SOURCE_FILE WHITESPACE " " ENUM_KW "enum" WHITESPACE " " - L_PAREN "(" - R_PAREN ")" + VARIANT_LIST + L_PAREN "(" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" CREATE_TYPE @@ -143,10 +144,12 @@ SOURCE_FILE WHITESPACE " " ENUM_KW "enum" WHITESPACE " " - L_PAREN "(" - LITERAL - STRING "'a'" - R_PAREN ")" + VARIANT_LIST + L_PAREN "(" + VARIANT + LITERAL + STRING "'a'" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" CREATE_TYPE @@ -163,18 +166,22 @@ SOURCE_FILE WHITESPACE " " ENUM_KW "enum" WHITESPACE " " - L_PAREN "(" - LITERAL - STRING "'a'" - COMMA "," - WHITESPACE " " - LITERAL - STRING "'b'" - COMMA "," - WHITESPACE " " - LITERAL - STRING "'c'" - R_PAREN ")" + VARIANT_LIST + L_PAREN "(" + VARIANT + LITERAL + STRING "'a'" + COMMA "," + WHITESPACE " " + VARIANT + LITERAL + STRING "'b'" + COMMA "," + WHITESPACE " " + VARIANT + LITERAL + STRING "'c'" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- create_type_as_range" diff --git a/crates/squawk_syntax/src/ast/generated/nodes.rs b/crates/squawk_syntax/src/ast/generated/nodes.rs index 8e9f8d90..b63c35dd 100644 --- a/crates/squawk_syntax/src/ast/generated/nodes.rs +++ b/crates/squawk_syntax/src/ast/generated/nodes.rs @@ -2856,10 +2856,34 @@ impl CreateType { support::child(&self.syntax) } #[inline] + pub fn variant_list(&self) -> Option { + support::child(&self.syntax) + } + #[inline] + pub fn l_paren_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::L_PAREN) + } + #[inline] + pub fn r_paren_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::R_PAREN) + } + #[inline] + pub fn as_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::AS_KW) + } + #[inline] pub fn create_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::CREATE_KW) } #[inline] + pub fn enum_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::ENUM_KW) + } + #[inline] + pub fn range_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::RANGE_KW) + } + #[inline] pub fn type_token(&self) -> Option { support::token(&self.syntax, SyntaxKind::TYPE_KW) } @@ -9625,6 +9649,36 @@ impl Values { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Variant { + pub(crate) syntax: SyntaxNode, +} +impl Variant { + #[inline] + pub fn literal(&self) -> Option { + support::child(&self.syntax) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct VariantList { + pub(crate) syntax: SyntaxNode, +} +impl VariantList { + #[inline] + pub fn variants(&self) -> AstChildren { + support::children(&self.syntax) + } + #[inline] + pub fn l_paren_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::L_PAREN) + } + #[inline] + pub fn r_paren_token(&self) -> Option { + support::token(&self.syntax, SyntaxKind::R_PAREN) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct VolatilityFuncOption { pub(crate) syntax: SyntaxNode, @@ -18940,6 +18994,42 @@ impl AstNode for Values { &self.syntax } } +impl AstNode for Variant { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::VARIANT + } + #[inline] + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + #[inline] + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } +} +impl AstNode for VariantList { + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { + kind == SyntaxKind::VARIANT_LIST + } + #[inline] + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + #[inline] + fn syntax(&self) -> &SyntaxNode { + &self.syntax + } +} impl AstNode for VolatilityFuncOption { #[inline] fn can_cast(kind: SyntaxKind) -> bool { diff --git a/crates/squawk_syntax/src/postgresql.ungram b/crates/squawk_syntax/src/postgresql.ungram index bba51536..eeb58122 100644 --- a/crates/squawk_syntax/src/postgresql.ungram +++ b/crates/squawk_syntax/src/postgresql.ungram @@ -1627,6 +1627,19 @@ IndexParams = CreateType = 'create' 'type' Type + (('as' 'enum' VariantList) +| ('as' 'range' ) +| ('as' '(' ')') +| ('(' ')')) + +VariantList = + '(' + (Variant (',' Variant)*) + ')' + +Variant = + Literal + CreateExtension = 'create' 'extension' diff --git a/crates/squawk_wasm/src/lib.rs b/crates/squawk_wasm/src/lib.rs index 0d05b551..a20b5052 100644 --- a/crates/squawk_wasm/src/lib.rs +++ b/crates/squawk_wasm/src/lib.rs @@ -40,7 +40,7 @@ pub fn dump_tokens(text: String) -> String { out } -#[allow(dead_code)] +#[expect(unused)] #[derive(Serialize)] enum Severity { Hint, From 2c2952feebe90bdf4807b845365d91c6160e1e31 Mon Sep 17 00:00:00 2001 From: Steve Dignam Date: Fri, 10 Oct 2025 21:28:44 -0400 Subject: [PATCH 2/2] fix --- crates/squawk_ide/src/expand_selection.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/squawk_ide/src/expand_selection.rs b/crates/squawk_ide/src/expand_selection.rs index 8d840073..ce37ee06 100644 --- a/crates/squawk_ide/src/expand_selection.rs +++ b/crates/squawk_ide/src/expand_selection.rs @@ -51,10 +51,10 @@ const ALL_LIST_KINDS: &[SyntaxKind] = &[ SyntaxKind::TARGET_LIST, SyntaxKind::TRANSACTION_MODE_LIST, SyntaxKind::VACUUM_OPTION_LIST, + SyntaxKind::VARIANT_LIST, // only separated by whitespace // SyntaxKind::XML_COLUMN_OPTION_LIST, SyntaxKind::XML_TABLE_COLUMN_LIST, - SyntaxKind::VARIANT_LIST, ]; pub fn extend_selection(root: &SyntaxNode, range: TextRange) -> TextRange {