From 93a877d43467a2766051adc17979a9238dd87e30 Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 11 Feb 2026 14:15:45 -0300 Subject: [PATCH 01/22] standardising the instantiation of variants using an object as a dictionary --- src/slang-nodes/ArgumentsDeclaration.ts | 18 +-- src/slang-nodes/ContractMember.ts | 62 +++------ src/slang-nodes/ContractSpecifier.ts | 18 +-- src/slang-nodes/Expression.ts | 128 ++++++------------ src/slang-nodes/FallbackFunctionAttribute.ts | 18 +-- src/slang-nodes/ForStatementInitialization.ts | 22 +-- src/slang-nodes/FunctionAttribute.ts | 18 +-- src/slang-nodes/ImportClause.ts | 22 +-- src/slang-nodes/MappingKeyType.ts | 28 ++-- src/slang-nodes/Pragma.ts | 22 +-- src/slang-nodes/ReceiveFunctionAttribute.ts | 18 +-- src/slang-nodes/SourceUnitMember.ts | 62 +++------ src/slang-nodes/Statement.ts | 75 ++++------ src/slang-nodes/StringExpression.ts | 30 ++-- src/slang-nodes/TupleMember.ts | 18 +-- src/slang-nodes/TypeName.ts | 40 +++--- src/slang-nodes/UsingClause.ts | 18 +-- src/slang-nodes/VersionExpression.ts | 18 +-- src/slang-nodes/YulExpression.ts | 32 +++-- src/slang-nodes/YulLiteral.ts | 18 +-- src/slang-nodes/YulStatement.ts | 69 +++++----- src/slang-nodes/YulSwitchCase.ts | 18 +-- 22 files changed, 353 insertions(+), 419 deletions(-) diff --git a/src/slang-nodes/ArgumentsDeclaration.ts b/src/slang-nodes/ArgumentsDeclaration.ts index 5af16a582..2c1bf2a94 100644 --- a/src/slang-nodes/ArgumentsDeclaration.ts +++ b/src/slang-nodes/ArgumentsDeclaration.ts @@ -8,19 +8,21 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.PositionalArgumentsDeclaration.name]: PositionalArgumentsDeclaration, + [ast.NamedArgumentsDeclaration.name]: NamedArgumentsDeclaration +}; + function createNonterminalVariant( variant: ast.ArgumentsDeclaration['variant'], collected: CollectedMetadata, options: ParserOptions ): ArgumentsDeclaration['variant'] { - if (variant instanceof ast.PositionalArgumentsDeclaration) { - return new PositionalArgumentsDeclaration(variant, collected, options); - } - if (variant instanceof ast.NamedArgumentsDeclaration) { - return new NamedArgumentsDeclaration(variant, collected, options); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class ArgumentsDeclaration extends SlangNode { diff --git a/src/slang-nodes/ContractMember.ts b/src/slang-nodes/ContractMember.ts index c6ec4fa9a..4027212ed 100644 --- a/src/slang-nodes/ContractMember.ts +++ b/src/slang-nodes/ContractMember.ts @@ -19,52 +19,32 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.UsingDirective.name]: UsingDirective, + [ast.FunctionDefinition.name]: FunctionDefinition, + [ast.ConstructorDefinition.name]: ConstructorDefinition, + [ast.ReceiveFunctionDefinition.name]: ReceiveFunctionDefinition, + [ast.FallbackFunctionDefinition.name]: FallbackFunctionDefinition, + [ast.UnnamedFunctionDefinition.name]: UnnamedFunctionDefinition, + [ast.ModifierDefinition.name]: ModifierDefinition, + [ast.StructDefinition.name]: StructDefinition, + [ast.EnumDefinition.name]: EnumDefinition, + [ast.EventDefinition.name]: EventDefinition, + [ast.StateVariableDefinition.name]: StateVariableDefinition, + [ast.ErrorDefinition.name]: ErrorDefinition, + [ast.UserDefinedValueTypeDefinition.name]: UserDefinedValueTypeDefinition +}; + function createNonterminalVariant( variant: ast.ContractMember['variant'], collected: CollectedMetadata, options: ParserOptions ): ContractMember['variant'] { - if (variant instanceof ast.UsingDirective) { - return new UsingDirective(variant, collected, options); - } - if (variant instanceof ast.FunctionDefinition) { - return new FunctionDefinition(variant, collected, options); - } - if (variant instanceof ast.ConstructorDefinition) { - return new ConstructorDefinition(variant, collected, options); - } - if (variant instanceof ast.ReceiveFunctionDefinition) { - return new ReceiveFunctionDefinition(variant, collected, options); - } - if (variant instanceof ast.FallbackFunctionDefinition) { - return new FallbackFunctionDefinition(variant, collected, options); - } - if (variant instanceof ast.UnnamedFunctionDefinition) { - return new UnnamedFunctionDefinition(variant, collected, options); - } - if (variant instanceof ast.ModifierDefinition) { - return new ModifierDefinition(variant, collected, options); - } - if (variant instanceof ast.StructDefinition) { - return new StructDefinition(variant, collected, options); - } - if (variant instanceof ast.EnumDefinition) { - return new EnumDefinition(variant, collected); - } - if (variant instanceof ast.EventDefinition) { - return new EventDefinition(variant, collected, options); - } - if (variant instanceof ast.StateVariableDefinition) { - return new StateVariableDefinition(variant, collected, options); - } - if (variant instanceof ast.ErrorDefinition) { - return new ErrorDefinition(variant, collected, options); - } - if (variant instanceof ast.UserDefinedValueTypeDefinition) { - return new UserDefinedValueTypeDefinition(variant, collected); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class ContractMember extends SlangNode { diff --git a/src/slang-nodes/ContractSpecifier.ts b/src/slang-nodes/ContractSpecifier.ts index 6f75ef231..57fa7ece0 100644 --- a/src/slang-nodes/ContractSpecifier.ts +++ b/src/slang-nodes/ContractSpecifier.ts @@ -8,19 +8,21 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.InheritanceSpecifier.name]: InheritanceSpecifier, + [ast.StorageLayoutSpecifier.name]: StorageLayoutSpecifier +}; + function createNonterminalVariant( variant: ast.ContractSpecifier['variant'], collected: CollectedMetadata, options: ParserOptions ): ContractSpecifier['variant'] { - if (variant instanceof ast.InheritanceSpecifier) { - return new InheritanceSpecifier(variant, collected, options); - } - if (variant instanceof ast.StorageLayoutSpecifier) { - return new StorageLayoutSpecifier(variant, collected, options); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class ContractSpecifier extends SlangNode { diff --git a/src/slang-nodes/Expression.ts b/src/slang-nodes/Expression.ts index dea0bf1c0..59f937944 100644 --- a/src/slang-nodes/Expression.ts +++ b/src/slang-nodes/Expression.ts @@ -38,94 +38,56 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.AssignmentExpression.name]: AssignmentExpression, + [ast.ConditionalExpression.name]: ConditionalExpression, + [ast.OrExpression.name]: OrExpression, + [ast.AndExpression.name]: AndExpression, + [ast.EqualityExpression.name]: EqualityExpression, + [ast.InequalityExpression.name]: InequalityExpression, + [ast.BitwiseOrExpression.name]: BitwiseOrExpression, + [ast.BitwiseXorExpression.name]: BitwiseXorExpression, + [ast.BitwiseAndExpression.name]: BitwiseAndExpression, + [ast.ShiftExpression.name]: ShiftExpression, + [ast.AdditiveExpression.name]: AdditiveExpression, + [ast.MultiplicativeExpression.name]: MultiplicativeExpression, + [ast.ExponentiationExpression.name]: ExponentiationExpression, + [ast.PostfixExpression.name]: PostfixExpression, + [ast.PrefixExpression.name]: PrefixExpression, + [ast.FunctionCallExpression.name]: FunctionCallExpression, + [ast.CallOptionsExpression.name]: CallOptionsExpression, + [ast.MemberAccessExpression.name]: MemberAccessExpression, + [ast.IndexAccessExpression.name]: IndexAccessExpression, + [ast.NewExpression.name]: NewExpression, + [ast.TupleExpression.name]: TupleExpression, + [ast.TypeExpression.name]: TypeExpression, + [ast.ArrayExpression.name]: ArrayExpression, + [ast.HexNumberExpression.name]: HexNumberExpression, + [ast.DecimalNumberExpression.name]: DecimalNumberExpression +}; + +const variantWithVariantsConstructors = { + [ast.StringExpression.name]: StringExpression, + [ast.ElementaryType.name]: ElementaryType +}; + function createNonterminalVariant( variant: Exclude, collected: CollectedMetadata, options: ParserOptions ): Expression['variant'] { - if (variant instanceof ast.AssignmentExpression) { - return new AssignmentExpression(variant, collected, options); - } - if (variant instanceof ast.ConditionalExpression) { - return new ConditionalExpression(variant, collected, options); - } - if (variant instanceof ast.OrExpression) { - return new OrExpression(variant, collected, options); - } - if (variant instanceof ast.AndExpression) { - return new AndExpression(variant, collected, options); - } - if (variant instanceof ast.EqualityExpression) { - return new EqualityExpression(variant, collected, options); - } - if (variant instanceof ast.InequalityExpression) { - return new InequalityExpression(variant, collected, options); - } - if (variant instanceof ast.BitwiseOrExpression) { - return new BitwiseOrExpression(variant, collected, options); - } - if (variant instanceof ast.BitwiseXorExpression) { - return new BitwiseXorExpression(variant, collected, options); - } - if (variant instanceof ast.BitwiseAndExpression) { - return new BitwiseAndExpression(variant, collected, options); - } - if (variant instanceof ast.ShiftExpression) { - return new ShiftExpression(variant, collected, options); - } - if (variant instanceof ast.AdditiveExpression) { - return new AdditiveExpression(variant, collected, options); - } - if (variant instanceof ast.MultiplicativeExpression) { - return new MultiplicativeExpression(variant, collected, options); - } - if (variant instanceof ast.ExponentiationExpression) { - return new ExponentiationExpression(variant, collected, options); - } - if (variant instanceof ast.PostfixExpression) { - return new PostfixExpression(variant, collected, options); - } - if (variant instanceof ast.PrefixExpression) { - return new PrefixExpression(variant, collected, options); - } - if (variant instanceof ast.FunctionCallExpression) { - return new FunctionCallExpression(variant, collected, options); - } - if (variant instanceof ast.CallOptionsExpression) { - return new CallOptionsExpression(variant, collected, options); - } - if (variant instanceof ast.MemberAccessExpression) { - return new MemberAccessExpression(variant, collected, options); - } - if (variant instanceof ast.IndexAccessExpression) { - return new IndexAccessExpression(variant, collected, options); - } - if (variant instanceof ast.NewExpression) { - return new NewExpression(variant, collected, options); - } - if (variant instanceof ast.TupleExpression) { - return new TupleExpression(variant, collected, options); - } - if (variant instanceof ast.TypeExpression) { - return new TypeExpression(variant, collected, options); - } - if (variant instanceof ast.ArrayExpression) { - return new ArrayExpression(variant, collected, options); - } - if (variant instanceof ast.HexNumberExpression) { - return new HexNumberExpression(variant, collected); - } - if (variant instanceof ast.DecimalNumberExpression) { - return new DecimalNumberExpression(variant, collected); - } - if (variant instanceof ast.StringExpression) { - return extractVariant(new StringExpression(variant, collected, options)); - } - if (variant instanceof ast.ElementaryType) { - return extractVariant(new ElementaryType(variant, collected)); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + const variantWithVariantsConstructor = + variantWithVariantsConstructors[variant.constructor.name]; + if (variantWithVariantsConstructor !== undefined) + return extractVariant( + new variantWithVariantsConstructor(variant as never, collected, options) + ); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class Expression extends SlangNode { diff --git a/src/slang-nodes/FallbackFunctionAttribute.ts b/src/slang-nodes/FallbackFunctionAttribute.ts index 9af79da6e..73b7da4d9 100644 --- a/src/slang-nodes/FallbackFunctionAttribute.ts +++ b/src/slang-nodes/FallbackFunctionAttribute.ts @@ -12,19 +12,21 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.ModifierInvocation.name]: ModifierInvocation, + [ast.OverrideSpecifier.name]: OverrideSpecifier +}; + function createNonterminalVariant( variant: Exclude, collected: CollectedMetadata, options: ParserOptions ): Exclude { - if (variant instanceof ast.ModifierInvocation) { - return new ModifierInvocation(variant, collected, options); - } - if (variant instanceof ast.OverrideSpecifier) { - return new OverrideSpecifier(variant, collected); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class FallbackFunctionAttribute extends SlangNode { diff --git a/src/slang-nodes/ForStatementInitialization.ts b/src/slang-nodes/ForStatementInitialization.ts index bb7adadf5..5d597f0bf 100644 --- a/src/slang-nodes/ForStatementInitialization.ts +++ b/src/slang-nodes/ForStatementInitialization.ts @@ -13,6 +13,12 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.ExpressionStatement.name]: ExpressionStatement, + [ast.VariableDeclarationStatement.name]: VariableDeclarationStatement, + [ast.TupleDeconstructionStatement.name]: TupleDeconstructionStatement +}; + function createNonterminalVariant( variant: Exclude< ast.ForStatementInitialization['variant'], @@ -21,17 +27,11 @@ function createNonterminalVariant( collected: CollectedMetadata, options: ParserOptions ): Exclude { - if (variant instanceof ast.ExpressionStatement) { - return new ExpressionStatement(variant, collected, options); - } - if (variant instanceof ast.VariableDeclarationStatement) { - return new VariableDeclarationStatement(variant, collected, options); - } - if (variant instanceof ast.TupleDeconstructionStatement) { - return new TupleDeconstructionStatement(variant, collected, options); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class ForStatementInitialization extends SlangNode { diff --git a/src/slang-nodes/FunctionAttribute.ts b/src/slang-nodes/FunctionAttribute.ts index fe4b041d9..61195eb65 100644 --- a/src/slang-nodes/FunctionAttribute.ts +++ b/src/slang-nodes/FunctionAttribute.ts @@ -12,19 +12,21 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.ModifierInvocation.name]: ModifierInvocation, + [ast.OverrideSpecifier.name]: OverrideSpecifier +}; + function createNonterminalVariant( variant: Exclude, collected: CollectedMetadata, options: ParserOptions ): Exclude { - if (variant instanceof ast.ModifierInvocation) { - return new ModifierInvocation(variant, collected, options); - } - if (variant instanceof ast.OverrideSpecifier) { - return new OverrideSpecifier(variant, collected); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class FunctionAttribute extends SlangNode { diff --git a/src/slang-nodes/ImportClause.ts b/src/slang-nodes/ImportClause.ts index 73015ba8d..57a6aba43 100644 --- a/src/slang-nodes/ImportClause.ts +++ b/src/slang-nodes/ImportClause.ts @@ -9,22 +9,22 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.PathImport.name]: PathImport, + [ast.NamedImport.name]: NamedImport, + [ast.ImportDeconstruction.name]: ImportDeconstruction +}; + function createNonterminalVariant( variant: ast.ImportClause['variant'], collected: CollectedMetadata, options: ParserOptions ): ImportClause['variant'] { - if (variant instanceof ast.PathImport) { - return new PathImport(variant, collected, options); - } - if (variant instanceof ast.NamedImport) { - return new NamedImport(variant, collected, options); - } - if (variant instanceof ast.ImportDeconstruction) { - return new ImportDeconstruction(variant, collected, options); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class ImportClause extends SlangNode { diff --git a/src/slang-nodes/MappingKeyType.ts b/src/slang-nodes/MappingKeyType.ts index e14a4d56a..af1b1f8e1 100644 --- a/src/slang-nodes/MappingKeyType.ts +++ b/src/slang-nodes/MappingKeyType.ts @@ -7,18 +7,30 @@ import { IdentifierPath } from './IdentifierPath.js'; import type { CollectedMetadata } from '../types.d.ts'; +const variantConstructors = { + [ast.IdentifierPath.name]: IdentifierPath +}; + +const variantWithVariantsConstructors = { + [ast.ElementaryType.name]: ElementaryType +}; + function createNonterminalVariant( variant: ast.MappingKeyType['variant'], collected: CollectedMetadata ): MappingKeyType['variant'] { - if (variant instanceof ast.ElementaryType) { - return extractVariant(new ElementaryType(variant, collected)); - } - if (variant instanceof ast.IdentifierPath) { - return new IdentifierPath(variant, collected); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected); + + const variantWithVariantsConstructor = + variantWithVariantsConstructors[variant.constructor.name]; + if (variantWithVariantsConstructor !== undefined) + return extractVariant( + new variantWithVariantsConstructor(variant as never, collected) + ); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class MappingKeyType extends SlangNode { diff --git a/src/slang-nodes/Pragma.ts b/src/slang-nodes/Pragma.ts index fb8f2610e..415ed04fa 100644 --- a/src/slang-nodes/Pragma.ts +++ b/src/slang-nodes/Pragma.ts @@ -9,22 +9,22 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.AbicoderPragma.name]: AbicoderPragma, + [ast.ExperimentalPragma.name]: ExperimentalPragma, + [ast.VersionPragma.name]: VersionPragma +}; + function createNonterminalVariant( variant: ast.Pragma['variant'], collected: CollectedMetadata, options: ParserOptions ): Pragma['variant'] { - if (variant instanceof ast.AbicoderPragma) { - return new AbicoderPragma(variant, collected); - } - if (variant instanceof ast.ExperimentalPragma) { - return new ExperimentalPragma(variant, collected, options); - } - if (variant instanceof ast.VersionPragma) { - return new VersionPragma(variant, collected); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class Pragma extends SlangNode { diff --git a/src/slang-nodes/ReceiveFunctionAttribute.ts b/src/slang-nodes/ReceiveFunctionAttribute.ts index a99bd7750..5c42975a4 100644 --- a/src/slang-nodes/ReceiveFunctionAttribute.ts +++ b/src/slang-nodes/ReceiveFunctionAttribute.ts @@ -12,19 +12,21 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.ModifierInvocation.name]: ModifierInvocation, + [ast.OverrideSpecifier.name]: OverrideSpecifier +}; + function createNonterminalVariant( variant: Exclude, collected: CollectedMetadata, options: ParserOptions ): Exclude { - if (variant instanceof ast.ModifierInvocation) { - return new ModifierInvocation(variant, collected, options); - } - if (variant instanceof ast.OverrideSpecifier) { - return new OverrideSpecifier(variant, collected); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class ReceiveFunctionAttribute extends SlangNode { diff --git a/src/slang-nodes/SourceUnitMember.ts b/src/slang-nodes/SourceUnitMember.ts index 95ab0c96e..44dbad6a4 100644 --- a/src/slang-nodes/SourceUnitMember.ts +++ b/src/slang-nodes/SourceUnitMember.ts @@ -19,52 +19,32 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.PragmaDirective.name]: PragmaDirective, + [ast.ImportDirective.name]: ImportDirective, + [ast.ContractDefinition.name]: ContractDefinition, + [ast.InterfaceDefinition.name]: InterfaceDefinition, + [ast.LibraryDefinition.name]: LibraryDefinition, + [ast.StructDefinition.name]: StructDefinition, + [ast.EnumDefinition.name]: EnumDefinition, + [ast.FunctionDefinition.name]: FunctionDefinition, + [ast.ConstantDefinition.name]: ConstantDefinition, + [ast.ErrorDefinition.name]: ErrorDefinition, + [ast.UserDefinedValueTypeDefinition.name]: UserDefinedValueTypeDefinition, + [ast.UsingDirective.name]: UsingDirective, + [ast.EventDefinition.name]: EventDefinition +}; + function createNonterminalVariant( variant: ast.SourceUnitMember['variant'], collected: CollectedMetadata, options: ParserOptions ): SourceUnitMember['variant'] { - if (variant instanceof ast.PragmaDirective) { - return new PragmaDirective(variant, collected, options); - } - if (variant instanceof ast.ImportDirective) { - return new ImportDirective(variant, collected, options); - } - if (variant instanceof ast.ContractDefinition) { - return new ContractDefinition(variant, collected, options); - } - if (variant instanceof ast.InterfaceDefinition) { - return new InterfaceDefinition(variant, collected, options); - } - if (variant instanceof ast.LibraryDefinition) { - return new LibraryDefinition(variant, collected, options); - } - if (variant instanceof ast.StructDefinition) { - return new StructDefinition(variant, collected, options); - } - if (variant instanceof ast.EnumDefinition) { - return new EnumDefinition(variant, collected); - } - if (variant instanceof ast.FunctionDefinition) { - return new FunctionDefinition(variant, collected, options); - } - if (variant instanceof ast.ConstantDefinition) { - return new ConstantDefinition(variant, collected, options); - } - if (variant instanceof ast.ErrorDefinition) { - return new ErrorDefinition(variant, collected, options); - } - if (variant instanceof ast.UserDefinedValueTypeDefinition) { - return new UserDefinedValueTypeDefinition(variant, collected); - } - if (variant instanceof ast.UsingDirective) { - return new UsingDirective(variant, collected, options); - } - if (variant instanceof ast.EventDefinition) { - return new EventDefinition(variant, collected, options); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class SourceUnitMember extends SlangNode { diff --git a/src/slang-nodes/Statement.ts b/src/slang-nodes/Statement.ts index 174ec0a2a..d574c436f 100644 --- a/src/slang-nodes/Statement.ts +++ b/src/slang-nodes/Statement.ts @@ -23,64 +23,39 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.ExpressionStatement.name]: ExpressionStatement, + [ast.VariableDeclarationStatement.name]: VariableDeclarationStatement, + [ast.TupleDeconstructionStatement.name]: TupleDeconstructionStatement, + [ast.IfStatement.name]: IfStatement, + [ast.ForStatement.name]: ForStatement, + [ast.WhileStatement.name]: WhileStatement, + [ast.DoWhileStatement.name]: DoWhileStatement, + [ast.ContinueStatement.name]: ContinueStatement, + [ast.BreakStatement.name]: BreakStatement, + [ast.ReturnStatement.name]: ReturnStatement, + [ast.ThrowStatement.name]: ThrowStatement, + [ast.EmitStatement.name]: EmitStatement, + [ast.TryStatement.name]: TryStatement, + [ast.RevertStatement.name]: RevertStatement, + [ast.AssemblyStatement.name]: AssemblyStatement, + [ast.UncheckedBlock.name]: UncheckedBlock +} as const; + function createNonterminalVariant( variant: ast.Statement['variant'], collected: CollectedMetadata, options: ParserOptions ): Statement['variant'] { - if (variant instanceof ast.ExpressionStatement) { - return new ExpressionStatement(variant, collected, options); - } - if (variant instanceof ast.VariableDeclarationStatement) { - return new VariableDeclarationStatement(variant, collected, options); - } - if (variant instanceof ast.TupleDeconstructionStatement) { - return new TupleDeconstructionStatement(variant, collected, options); - } - if (variant instanceof ast.IfStatement) { - return new IfStatement(variant, collected, options); - } - if (variant instanceof ast.ForStatement) { - return new ForStatement(variant, collected, options); - } - if (variant instanceof ast.WhileStatement) { - return new WhileStatement(variant, collected, options); - } - if (variant instanceof ast.DoWhileStatement) { - return new DoWhileStatement(variant, collected, options); - } - if (variant instanceof ast.ContinueStatement) { - return new ContinueStatement(variant, collected); - } - if (variant instanceof ast.BreakStatement) { - return new BreakStatement(variant, collected); - } - if (variant instanceof ast.ReturnStatement) { - return new ReturnStatement(variant, collected, options); - } - if (variant instanceof ast.ThrowStatement) { - return new ThrowStatement(variant, collected); - } - if (variant instanceof ast.EmitStatement) { - return new EmitStatement(variant, collected, options); - } - if (variant instanceof ast.TryStatement) { - return new TryStatement(variant, collected, options); - } - if (variant instanceof ast.RevertStatement) { - return new RevertStatement(variant, collected, options); - } - if (variant instanceof ast.AssemblyStatement) { - return new AssemblyStatement(variant, collected, options); - } if (variant instanceof ast.Block) { return new Block(variant, collected, options); } - if (variant instanceof ast.UncheckedBlock) { - return new UncheckedBlock(variant, collected, options); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class Statement extends SlangNode { diff --git a/src/slang-nodes/StringExpression.ts b/src/slang-nodes/StringExpression.ts index f13b54423..14afde128 100644 --- a/src/slang-nodes/StringExpression.ts +++ b/src/slang-nodes/StringExpression.ts @@ -11,28 +11,24 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.StringLiteral.name]: StringLiteral, + [ast.StringLiterals.name]: StringLiterals, + [ast.HexStringLiteral.name]: HexStringLiteral, + [ast.HexStringLiterals.name]: HexStringLiterals, + [ast.UnicodeStringLiterals.name]: UnicodeStringLiterals +}; + function createNonterminalVariant( variant: ast.StringExpression['variant'], collected: CollectedMetadata, options: ParserOptions ): StringExpression['variant'] { - if (variant instanceof ast.StringLiteral) { - return new StringLiteral(variant, collected, options); - } - if (variant instanceof ast.StringLiterals) { - return new StringLiterals(variant, collected, options); - } - if (variant instanceof ast.HexStringLiteral) { - return new HexStringLiteral(variant, collected, options); - } - if (variant instanceof ast.HexStringLiterals) { - return new HexStringLiterals(variant, collected, options); - } - if (variant instanceof ast.UnicodeStringLiterals) { - return new UnicodeStringLiterals(variant, collected, options); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class StringExpression extends SlangNode { diff --git a/src/slang-nodes/TupleMember.ts b/src/slang-nodes/TupleMember.ts index 23eb06c1c..9e62bc438 100644 --- a/src/slang-nodes/TupleMember.ts +++ b/src/slang-nodes/TupleMember.ts @@ -8,19 +8,21 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.TypedTupleMember.name]: TypedTupleMember, + [ast.UntypedTupleMember.name]: UntypedTupleMember +}; + function createNonterminalVariant( variant: ast.TupleMember['variant'], collected: CollectedMetadata, options: ParserOptions ): TupleMember['variant'] { - if (variant instanceof ast.TypedTupleMember) { - return new TypedTupleMember(variant, collected, options); - } - if (variant instanceof ast.UntypedTupleMember) { - return new UntypedTupleMember(variant, collected); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class TupleMember extends SlangNode { diff --git a/src/slang-nodes/TypeName.ts b/src/slang-nodes/TypeName.ts index 5f1a31850..9b4723a81 100644 --- a/src/slang-nodes/TypeName.ts +++ b/src/slang-nodes/TypeName.ts @@ -12,28 +12,34 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.ArrayTypeName.name]: ArrayTypeName, + [ast.FunctionType.name]: FunctionType, + [ast.MappingType.name]: MappingType, + [ast.IdentifierPath.name]: IdentifierPath +}; + +const variantWithVariantsConstructors = { + [ast.ElementaryType.name]: ElementaryType +}; + function createNonterminalVariant( variant: ast.TypeName['variant'], collected: CollectedMetadata, options: ParserOptions ): TypeName['variant'] { - if (variant instanceof ast.ArrayTypeName) { - return new ArrayTypeName(variant, collected, options); - } - if (variant instanceof ast.FunctionType) { - return new FunctionType(variant, collected, options); - } - if (variant instanceof ast.MappingType) { - return new MappingType(variant, collected, options); - } - if (variant instanceof ast.ElementaryType) { - return extractVariant(new ElementaryType(variant, collected)); - } - if (variant instanceof ast.IdentifierPath) { - return new IdentifierPath(variant, collected); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + const variantWithVariantsConstructor = + variantWithVariantsConstructors[variant.constructor.name]; + if (variantWithVariantsConstructor !== undefined) + return extractVariant( + new variantWithVariantsConstructor(variant as never, collected) + ); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class TypeName extends SlangNode { diff --git a/src/slang-nodes/UsingClause.ts b/src/slang-nodes/UsingClause.ts index 53f05044a..126e2ef1a 100644 --- a/src/slang-nodes/UsingClause.ts +++ b/src/slang-nodes/UsingClause.ts @@ -6,18 +6,20 @@ import { UsingDeconstruction } from './UsingDeconstruction.js'; import type { CollectedMetadata } from '../types.d.ts'; +const variantConstructors = { + [ast.IdentifierPath.name]: IdentifierPath, + [ast.UsingDeconstruction.name]: UsingDeconstruction +}; + function createNonterminalVariant( variant: ast.UsingClause['variant'], collected: CollectedMetadata ): UsingClause['variant'] { - if (variant instanceof ast.IdentifierPath) { - return new IdentifierPath(variant, collected); - } - if (variant instanceof ast.UsingDeconstruction) { - return new UsingDeconstruction(variant, collected); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class UsingClause extends SlangNode { diff --git a/src/slang-nodes/VersionExpression.ts b/src/slang-nodes/VersionExpression.ts index ac1339e0d..f64246df2 100644 --- a/src/slang-nodes/VersionExpression.ts +++ b/src/slang-nodes/VersionExpression.ts @@ -6,18 +6,20 @@ import { VersionTerm } from './VersionTerm.js'; import type { CollectedMetadata } from '../types.d.ts'; +const variantConstructors = { + [ast.VersionRange.name]: VersionRange, + [ast.VersionTerm.name]: VersionTerm +}; + function createNonterminalVariant( variant: ast.VersionExpression['variant'], collected: CollectedMetadata ): VersionExpression['variant'] { - if (variant instanceof ast.VersionRange) { - return new VersionRange(variant, collected); - } - if (variant instanceof ast.VersionTerm) { - return new VersionTerm(variant, collected); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class VersionExpression extends SlangNode { diff --git a/src/slang-nodes/YulExpression.ts b/src/slang-nodes/YulExpression.ts index 8b1312906..50c93a604 100644 --- a/src/slang-nodes/YulExpression.ts +++ b/src/slang-nodes/YulExpression.ts @@ -10,22 +10,32 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.YulFunctionCallExpression.name]: YulFunctionCallExpression, + [ast.YulPath.name]: YulPath +}; + +const variantWithVariantsConstructors = { + [ast.YulLiteral.name]: YulLiteral +}; + function createNonterminalVariant( variant: ast.YulExpression['variant'], collected: CollectedMetadata, options: ParserOptions ): YulExpression['variant'] { - if (variant instanceof ast.YulFunctionCallExpression) { - return new YulFunctionCallExpression(variant, collected, options); - } - if (variant instanceof ast.YulLiteral) { - return extractVariant(new YulLiteral(variant, collected, options)); - } - if (variant instanceof ast.YulPath) { - return new YulPath(variant, collected); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + const variantWithVariantsConstructor = + variantWithVariantsConstructors[variant.constructor.name]; + if (variantWithVariantsConstructor !== undefined) + return extractVariant( + new variantWithVariantsConstructor(variant as never, collected, options) + ); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class YulExpression extends SlangNode { diff --git a/src/slang-nodes/YulLiteral.ts b/src/slang-nodes/YulLiteral.ts index cbfb0194d..c36597d01 100644 --- a/src/slang-nodes/YulLiteral.ts +++ b/src/slang-nodes/YulLiteral.ts @@ -12,19 +12,21 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.HexStringLiteral.name]: HexStringLiteral, + [ast.StringLiteral.name]: StringLiteral +}; + function createNonterminalVariant( variant: Exclude, collected: CollectedMetadata, options: ParserOptions ): Exclude { - if (variant instanceof ast.HexStringLiteral) { - return new HexStringLiteral(variant, collected, options); - } - if (variant instanceof ast.StringLiteral) { - return new StringLiteral(variant, collected, options); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class YulLiteral extends SlangNode { diff --git a/src/slang-nodes/YulStatement.ts b/src/slang-nodes/YulStatement.ts index 146378877..4b2bbf74e 100644 --- a/src/slang-nodes/YulStatement.ts +++ b/src/slang-nodes/YulStatement.ts @@ -20,6 +20,24 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.YulFunctionDefinition.name]: YulFunctionDefinition, + [ast.YulVariableDeclarationStatement.name]: YulVariableDeclarationStatement, + [ast.YulVariableAssignmentStatement.name]: YulVariableAssignmentStatement, + [ast.YulStackAssignmentStatement.name]: YulStackAssignmentStatement, + [ast.YulIfStatement.name]: YulIfStatement, + [ast.YulForStatement.name]: YulForStatement, + [ast.YulSwitchStatement.name]: YulSwitchStatement, + [ast.YulLeaveStatement.name]: YulLeaveStatement, + [ast.YulBreakStatement.name]: YulBreakStatement, + [ast.YulContinueStatement.name]: YulContinueStatement, + [ast.YulLabel.name]: YulLabel +}; + +const variantWithVariantsConstructors = { + [ast.YulExpression.name]: YulExpression +}; + function createNonterminalVariant( variant: ast.YulStatement['variant'], collected: CollectedMetadata, @@ -28,44 +46,19 @@ function createNonterminalVariant( if (variant instanceof ast.YulBlock) { return new YulBlock(variant, collected, options); } - if (variant instanceof ast.YulFunctionDefinition) { - return new YulFunctionDefinition(variant, collected, options); - } - if (variant instanceof ast.YulVariableDeclarationStatement) { - return new YulVariableDeclarationStatement(variant, collected, options); - } - if (variant instanceof ast.YulVariableAssignmentStatement) { - return new YulVariableAssignmentStatement(variant, collected, options); - } - if (variant instanceof ast.YulStackAssignmentStatement) { - return new YulStackAssignmentStatement(variant, collected); - } - if (variant instanceof ast.YulIfStatement) { - return new YulIfStatement(variant, collected, options); - } - if (variant instanceof ast.YulForStatement) { - return new YulForStatement(variant, collected, options); - } - if (variant instanceof ast.YulSwitchStatement) { - return new YulSwitchStatement(variant, collected, options); - } - if (variant instanceof ast.YulLeaveStatement) { - return new YulLeaveStatement(variant, collected); - } - if (variant instanceof ast.YulBreakStatement) { - return new YulBreakStatement(variant, collected); - } - if (variant instanceof ast.YulContinueStatement) { - return new YulContinueStatement(variant, collected); - } - if (variant instanceof ast.YulLabel) { - return new YulLabel(variant, collected); - } - if (variant instanceof ast.YulExpression) { - return extractVariant(new YulExpression(variant, collected, options)); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + const variantWithVariantsConstructor = + variantWithVariantsConstructors[variant.constructor.name]; + if (variantWithVariantsConstructor !== undefined) + return extractVariant( + new variantWithVariantsConstructor(variant as never, collected, options) + ); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class YulStatement extends SlangNode { diff --git a/src/slang-nodes/YulSwitchCase.ts b/src/slang-nodes/YulSwitchCase.ts index acde4dbcb..11ac9b3a7 100644 --- a/src/slang-nodes/YulSwitchCase.ts +++ b/src/slang-nodes/YulSwitchCase.ts @@ -8,19 +8,21 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; +const variantConstructors = { + [ast.YulDefaultCase.name]: YulDefaultCase, + [ast.YulValueCase.name]: YulValueCase +}; + function createNonterminalVariant( variant: ast.YulSwitchCase['variant'], collected: CollectedMetadata, options: ParserOptions ): YulSwitchCase['variant'] { - if (variant instanceof ast.YulDefaultCase) { - return new YulDefaultCase(variant, collected, options); - } - if (variant instanceof ast.YulValueCase) { - return new YulValueCase(variant, collected, options); - } - const exhaustiveCheck: never = variant; - throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`); + const variantConstructor = variantConstructors[variant.constructor.name]; + if (variantConstructor !== undefined) + return new variantConstructor(variant as never, collected, options); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); } export class YulSwitchCase extends SlangNode { From e3ab9abc5c2a3d9629d33d7375cd25779618ba9c Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 11 Feb 2026 14:54:26 -0300 Subject: [PATCH 02/22] using Map instead --- src/slang-nodes/ArgumentsDeclaration.ts | 18 ++- src/slang-nodes/ContractMember.ts | 51 ++++++--- src/slang-nodes/ContractSpecifier.ts | 12 +- src/slang-nodes/Expression.ts | 108 ++++++++++++------ src/slang-nodes/FallbackFunctionAttribute.ts | 12 +- src/slang-nodes/ForStatementInitialization.ts | 21 +++- src/slang-nodes/FunctionAttribute.ts | 12 +- src/slang-nodes/ImportClause.ts | 13 ++- src/slang-nodes/MappingKeyType.ts | 33 ++++-- src/slang-nodes/Pragma.ts | 13 ++- src/slang-nodes/ReceiveFunctionAttribute.ts | 12 +- src/slang-nodes/SourceUnitMember.ts | 51 ++++++--- src/slang-nodes/Statement.ts | 60 +++++++--- src/slang-nodes/StringExpression.ts | 27 +++-- src/slang-nodes/TupleMember.ts | 12 +- src/slang-nodes/TypeName.ts | 39 +++++-- src/slang-nodes/UsingClause.ts | 12 +- src/slang-nodes/VersionExpression.ts | 12 +- src/slang-nodes/YulExpression.ts | 32 ++++-- src/slang-nodes/YulLiteral.ts | 12 +- src/slang-nodes/YulStatement.ts | 65 ++++++++--- src/slang-nodes/YulSwitchCase.ts | 12 +- 22 files changed, 427 insertions(+), 212 deletions(-) diff --git a/src/slang-nodes/ArgumentsDeclaration.ts b/src/slang-nodes/ArgumentsDeclaration.ts index 2c1bf2a94..034cf0486 100644 --- a/src/slang-nodes/ArgumentsDeclaration.ts +++ b/src/slang-nodes/ArgumentsDeclaration.ts @@ -8,17 +8,25 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.PositionalArgumentsDeclaration.name]: PositionalArgumentsDeclaration, - [ast.NamedArgumentsDeclaration.name]: NamedArgumentsDeclaration -}; +const keys = [ + ast.PositionalArgumentsDeclaration, + ast.NamedArgumentsDeclaration +]; +const constructors = [ + PositionalArgumentsDeclaration, + NamedArgumentsDeclaration +]; + +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); function createNonterminalVariant( variant: ast.ArgumentsDeclaration['variant'], collected: CollectedMetadata, options: ParserOptions ): ArgumentsDeclaration['variant'] { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); diff --git a/src/slang-nodes/ContractMember.ts b/src/slang-nodes/ContractMember.ts index 4027212ed..7e7e86298 100644 --- a/src/slang-nodes/ContractMember.ts +++ b/src/slang-nodes/ContractMember.ts @@ -19,28 +19,47 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.UsingDirective.name]: UsingDirective, - [ast.FunctionDefinition.name]: FunctionDefinition, - [ast.ConstructorDefinition.name]: ConstructorDefinition, - [ast.ReceiveFunctionDefinition.name]: ReceiveFunctionDefinition, - [ast.FallbackFunctionDefinition.name]: FallbackFunctionDefinition, - [ast.UnnamedFunctionDefinition.name]: UnnamedFunctionDefinition, - [ast.ModifierDefinition.name]: ModifierDefinition, - [ast.StructDefinition.name]: StructDefinition, - [ast.EnumDefinition.name]: EnumDefinition, - [ast.EventDefinition.name]: EventDefinition, - [ast.StateVariableDefinition.name]: StateVariableDefinition, - [ast.ErrorDefinition.name]: ErrorDefinition, - [ast.UserDefinedValueTypeDefinition.name]: UserDefinedValueTypeDefinition -}; +const keys = [ + ast.UsingDirective, + ast.FunctionDefinition, + ast.ConstructorDefinition, + ast.ReceiveFunctionDefinition, + ast.FallbackFunctionDefinition, + ast.UnnamedFunctionDefinition, + ast.ModifierDefinition, + ast.StructDefinition, + ast.EnumDefinition, + ast.EventDefinition, + ast.StateVariableDefinition, + ast.ErrorDefinition, + ast.UserDefinedValueTypeDefinition +]; +const constructors = [ + UsingDirective, + FunctionDefinition, + ConstructorDefinition, + ReceiveFunctionDefinition, + FallbackFunctionDefinition, + UnnamedFunctionDefinition, + ModifierDefinition, + StructDefinition, + EnumDefinition, + EventDefinition, + StateVariableDefinition, + ErrorDefinition, + UserDefinedValueTypeDefinition +]; + +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); function createNonterminalVariant( variant: ast.ContractMember['variant'], collected: CollectedMetadata, options: ParserOptions ): ContractMember['variant'] { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); diff --git a/src/slang-nodes/ContractSpecifier.ts b/src/slang-nodes/ContractSpecifier.ts index 57fa7ece0..0fc9acb84 100644 --- a/src/slang-nodes/ContractSpecifier.ts +++ b/src/slang-nodes/ContractSpecifier.ts @@ -8,17 +8,19 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.InheritanceSpecifier.name]: InheritanceSpecifier, - [ast.StorageLayoutSpecifier.name]: StorageLayoutSpecifier -}; +const keys = [ast.InheritanceSpecifier, ast.StorageLayoutSpecifier]; +const constructors = [InheritanceSpecifier, StorageLayoutSpecifier]; + +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); function createNonterminalVariant( variant: ast.ContractSpecifier['variant'], collected: CollectedMetadata, options: ParserOptions ): ContractSpecifier['variant'] { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); diff --git a/src/slang-nodes/Expression.ts b/src/slang-nodes/Expression.ts index 59f937944..9337a3aa2 100644 --- a/src/slang-nodes/Expression.ts +++ b/src/slang-nodes/Expression.ts @@ -38,50 +38,90 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.AssignmentExpression.name]: AssignmentExpression, - [ast.ConditionalExpression.name]: ConditionalExpression, - [ast.OrExpression.name]: OrExpression, - [ast.AndExpression.name]: AndExpression, - [ast.EqualityExpression.name]: EqualityExpression, - [ast.InequalityExpression.name]: InequalityExpression, - [ast.BitwiseOrExpression.name]: BitwiseOrExpression, - [ast.BitwiseXorExpression.name]: BitwiseXorExpression, - [ast.BitwiseAndExpression.name]: BitwiseAndExpression, - [ast.ShiftExpression.name]: ShiftExpression, - [ast.AdditiveExpression.name]: AdditiveExpression, - [ast.MultiplicativeExpression.name]: MultiplicativeExpression, - [ast.ExponentiationExpression.name]: ExponentiationExpression, - [ast.PostfixExpression.name]: PostfixExpression, - [ast.PrefixExpression.name]: PrefixExpression, - [ast.FunctionCallExpression.name]: FunctionCallExpression, - [ast.CallOptionsExpression.name]: CallOptionsExpression, - [ast.MemberAccessExpression.name]: MemberAccessExpression, - [ast.IndexAccessExpression.name]: IndexAccessExpression, - [ast.NewExpression.name]: NewExpression, - [ast.TupleExpression.name]: TupleExpression, - [ast.TypeExpression.name]: TypeExpression, - [ast.ArrayExpression.name]: ArrayExpression, - [ast.HexNumberExpression.name]: HexNumberExpression, - [ast.DecimalNumberExpression.name]: DecimalNumberExpression -}; +const keys = [ + ast.AssignmentExpression, + ast.ConditionalExpression, + ast.OrExpression, + ast.AndExpression, + ast.EqualityExpression, + ast.InequalityExpression, + ast.BitwiseOrExpression, + ast.BitwiseXorExpression, + ast.BitwiseAndExpression, + ast.ShiftExpression, + ast.AdditiveExpression, + ast.MultiplicativeExpression, + ast.ExponentiationExpression, + ast.PostfixExpression, + ast.PrefixExpression, + ast.FunctionCallExpression, + ast.CallOptionsExpression, + ast.MemberAccessExpression, + ast.IndexAccessExpression, + ast.NewExpression, + ast.TupleExpression, + ast.TypeExpression, + ast.ArrayExpression, + ast.HexNumberExpression, + ast.DecimalNumberExpression +]; +const constructors = [ + AssignmentExpression, + ConditionalExpression, + OrExpression, + AndExpression, + EqualityExpression, + InequalityExpression, + BitwiseOrExpression, + BitwiseXorExpression, + BitwiseAndExpression, + ShiftExpression, + AdditiveExpression, + MultiplicativeExpression, + ExponentiationExpression, + PostfixExpression, + PrefixExpression, + FunctionCallExpression, + CallOptionsExpression, + MemberAccessExpression, + IndexAccessExpression, + NewExpression, + TupleExpression, + TypeExpression, + ArrayExpression, + HexNumberExpression, + DecimalNumberExpression +]; -const variantWithVariantsConstructors = { - [ast.StringExpression.name]: StringExpression, - [ast.ElementaryType.name]: ElementaryType -}; +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); + +const keysWithVariants = [ast.StringExpression, ast.ElementaryType]; +const constructorsWithVariants = [StringExpression, ElementaryType]; + +const variantWithVariantsConstructors = new Map< + string, + (typeof constructorsWithVariants)[number] +>( + keysWithVariants.map((key, index) => [ + key.name, + constructorsWithVariants[index] + ]) +); function createNonterminalVariant( variant: Exclude, collected: CollectedMetadata, options: ParserOptions ): Expression['variant'] { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); - const variantWithVariantsConstructor = - variantWithVariantsConstructors[variant.constructor.name]; + const variantWithVariantsConstructor = variantWithVariantsConstructors.get( + variant.constructor.name + ); if (variantWithVariantsConstructor !== undefined) return extractVariant( new variantWithVariantsConstructor(variant as never, collected, options) diff --git a/src/slang-nodes/FallbackFunctionAttribute.ts b/src/slang-nodes/FallbackFunctionAttribute.ts index 73b7da4d9..92019758c 100644 --- a/src/slang-nodes/FallbackFunctionAttribute.ts +++ b/src/slang-nodes/FallbackFunctionAttribute.ts @@ -12,17 +12,19 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.ModifierInvocation.name]: ModifierInvocation, - [ast.OverrideSpecifier.name]: OverrideSpecifier -}; +const keys = [ast.ModifierInvocation, ast.OverrideSpecifier]; +const constructors = [ModifierInvocation, OverrideSpecifier]; + +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); function createNonterminalVariant( variant: Exclude, collected: CollectedMetadata, options: ParserOptions ): Exclude { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); diff --git a/src/slang-nodes/ForStatementInitialization.ts b/src/slang-nodes/ForStatementInitialization.ts index 5d597f0bf..0c40d2b5e 100644 --- a/src/slang-nodes/ForStatementInitialization.ts +++ b/src/slang-nodes/ForStatementInitialization.ts @@ -13,11 +13,20 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.ExpressionStatement.name]: ExpressionStatement, - [ast.VariableDeclarationStatement.name]: VariableDeclarationStatement, - [ast.TupleDeconstructionStatement.name]: TupleDeconstructionStatement -}; +const keys = [ + ast.ExpressionStatement, + ast.VariableDeclarationStatement, + ast.TupleDeconstructionStatement +]; +const constructors = [ + ExpressionStatement, + VariableDeclarationStatement, + TupleDeconstructionStatement +]; + +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); function createNonterminalVariant( variant: Exclude< @@ -27,7 +36,7 @@ function createNonterminalVariant( collected: CollectedMetadata, options: ParserOptions ): Exclude { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); diff --git a/src/slang-nodes/FunctionAttribute.ts b/src/slang-nodes/FunctionAttribute.ts index 61195eb65..4ac26d565 100644 --- a/src/slang-nodes/FunctionAttribute.ts +++ b/src/slang-nodes/FunctionAttribute.ts @@ -12,17 +12,19 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.ModifierInvocation.name]: ModifierInvocation, - [ast.OverrideSpecifier.name]: OverrideSpecifier -}; +const keys = [ast.ModifierInvocation, ast.OverrideSpecifier]; +const constructors = [ModifierInvocation, OverrideSpecifier]; + +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); function createNonterminalVariant( variant: Exclude, collected: CollectedMetadata, options: ParserOptions ): Exclude { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); diff --git a/src/slang-nodes/ImportClause.ts b/src/slang-nodes/ImportClause.ts index 57a6aba43..3e0f66033 100644 --- a/src/slang-nodes/ImportClause.ts +++ b/src/slang-nodes/ImportClause.ts @@ -9,18 +9,19 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.PathImport.name]: PathImport, - [ast.NamedImport.name]: NamedImport, - [ast.ImportDeconstruction.name]: ImportDeconstruction -}; +const keys = [ast.PathImport, ast.NamedImport, ast.ImportDeconstruction]; +const constructors = [PathImport, NamedImport, ImportDeconstruction]; + +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); function createNonterminalVariant( variant: ast.ImportClause['variant'], collected: CollectedMetadata, options: ParserOptions ): ImportClause['variant'] { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); diff --git a/src/slang-nodes/MappingKeyType.ts b/src/slang-nodes/MappingKeyType.ts index af1b1f8e1..ea08b3652 100644 --- a/src/slang-nodes/MappingKeyType.ts +++ b/src/slang-nodes/MappingKeyType.ts @@ -7,24 +7,37 @@ import { IdentifierPath } from './IdentifierPath.js'; import type { CollectedMetadata } from '../types.d.ts'; -const variantConstructors = { - [ast.IdentifierPath.name]: IdentifierPath -}; - -const variantWithVariantsConstructors = { - [ast.ElementaryType.name]: ElementaryType -}; +const keys = [ast.IdentifierPath]; +const constructors = [IdentifierPath]; + +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); + +const keysWithVariants = [ast.ElementaryType]; +const constructorsWithVariants = [ElementaryType]; + +const variantWithVariantsConstructors = new Map< + string, + (typeof constructorsWithVariants)[number] +>( + keysWithVariants.map((key, index) => [ + key.name, + constructorsWithVariants[index] + ]) +); function createNonterminalVariant( variant: ast.MappingKeyType['variant'], collected: CollectedMetadata ): MappingKeyType['variant'] { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected); - const variantWithVariantsConstructor = - variantWithVariantsConstructors[variant.constructor.name]; + const variantWithVariantsConstructor = variantWithVariantsConstructors.get( + variant.constructor.name + ); if (variantWithVariantsConstructor !== undefined) return extractVariant( new variantWithVariantsConstructor(variant as never, collected) diff --git a/src/slang-nodes/Pragma.ts b/src/slang-nodes/Pragma.ts index 415ed04fa..a1e654beb 100644 --- a/src/slang-nodes/Pragma.ts +++ b/src/slang-nodes/Pragma.ts @@ -9,18 +9,19 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.AbicoderPragma.name]: AbicoderPragma, - [ast.ExperimentalPragma.name]: ExperimentalPragma, - [ast.VersionPragma.name]: VersionPragma -}; +const keys = [ast.AbicoderPragma, ast.ExperimentalPragma, ast.VersionPragma]; +const constructors = [AbicoderPragma, ExperimentalPragma, VersionPragma]; + +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); function createNonterminalVariant( variant: ast.Pragma['variant'], collected: CollectedMetadata, options: ParserOptions ): Pragma['variant'] { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); diff --git a/src/slang-nodes/ReceiveFunctionAttribute.ts b/src/slang-nodes/ReceiveFunctionAttribute.ts index 5c42975a4..63e376751 100644 --- a/src/slang-nodes/ReceiveFunctionAttribute.ts +++ b/src/slang-nodes/ReceiveFunctionAttribute.ts @@ -12,17 +12,19 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.ModifierInvocation.name]: ModifierInvocation, - [ast.OverrideSpecifier.name]: OverrideSpecifier -}; +const keys = [ast.ModifierInvocation, ast.OverrideSpecifier]; +const constructors = [ModifierInvocation, OverrideSpecifier]; + +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); function createNonterminalVariant( variant: Exclude, collected: CollectedMetadata, options: ParserOptions ): Exclude { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); diff --git a/src/slang-nodes/SourceUnitMember.ts b/src/slang-nodes/SourceUnitMember.ts index 44dbad6a4..c8487cdd9 100644 --- a/src/slang-nodes/SourceUnitMember.ts +++ b/src/slang-nodes/SourceUnitMember.ts @@ -19,28 +19,47 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.PragmaDirective.name]: PragmaDirective, - [ast.ImportDirective.name]: ImportDirective, - [ast.ContractDefinition.name]: ContractDefinition, - [ast.InterfaceDefinition.name]: InterfaceDefinition, - [ast.LibraryDefinition.name]: LibraryDefinition, - [ast.StructDefinition.name]: StructDefinition, - [ast.EnumDefinition.name]: EnumDefinition, - [ast.FunctionDefinition.name]: FunctionDefinition, - [ast.ConstantDefinition.name]: ConstantDefinition, - [ast.ErrorDefinition.name]: ErrorDefinition, - [ast.UserDefinedValueTypeDefinition.name]: UserDefinedValueTypeDefinition, - [ast.UsingDirective.name]: UsingDirective, - [ast.EventDefinition.name]: EventDefinition -}; +const keys = [ + ast.PragmaDirective, + ast.ImportDirective, + ast.ContractDefinition, + ast.InterfaceDefinition, + ast.LibraryDefinition, + ast.StructDefinition, + ast.EnumDefinition, + ast.FunctionDefinition, + ast.ConstantDefinition, + ast.ErrorDefinition, + ast.UserDefinedValueTypeDefinition, + ast.UsingDirective, + ast.EventDefinition +]; +const constructors = [ + PragmaDirective, + ImportDirective, + ContractDefinition, + InterfaceDefinition, + LibraryDefinition, + StructDefinition, + EnumDefinition, + FunctionDefinition, + ConstantDefinition, + ErrorDefinition, + UserDefinedValueTypeDefinition, + UsingDirective, + EventDefinition +]; + +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); function createNonterminalVariant( variant: ast.SourceUnitMember['variant'], collected: CollectedMetadata, options: ParserOptions ): SourceUnitMember['variant'] { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); diff --git a/src/slang-nodes/Statement.ts b/src/slang-nodes/Statement.ts index d574c436f..e3a5eb6b1 100644 --- a/src/slang-nodes/Statement.ts +++ b/src/slang-nodes/Statement.ts @@ -23,24 +23,46 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.ExpressionStatement.name]: ExpressionStatement, - [ast.VariableDeclarationStatement.name]: VariableDeclarationStatement, - [ast.TupleDeconstructionStatement.name]: TupleDeconstructionStatement, - [ast.IfStatement.name]: IfStatement, - [ast.ForStatement.name]: ForStatement, - [ast.WhileStatement.name]: WhileStatement, - [ast.DoWhileStatement.name]: DoWhileStatement, - [ast.ContinueStatement.name]: ContinueStatement, - [ast.BreakStatement.name]: BreakStatement, - [ast.ReturnStatement.name]: ReturnStatement, - [ast.ThrowStatement.name]: ThrowStatement, - [ast.EmitStatement.name]: EmitStatement, - [ast.TryStatement.name]: TryStatement, - [ast.RevertStatement.name]: RevertStatement, - [ast.AssemblyStatement.name]: AssemblyStatement, - [ast.UncheckedBlock.name]: UncheckedBlock -} as const; +const keys = [ + ast.ExpressionStatement, + ast.VariableDeclarationStatement, + ast.TupleDeconstructionStatement, + ast.IfStatement, + ast.ForStatement, + ast.WhileStatement, + ast.DoWhileStatement, + ast.ContinueStatement, + ast.BreakStatement, + ast.ReturnStatement, + ast.ThrowStatement, + ast.EmitStatement, + ast.TryStatement, + ast.RevertStatement, + ast.AssemblyStatement, + ast.UncheckedBlock +]; +const constructors = [ + ExpressionStatement, + VariableDeclarationStatement, + TupleDeconstructionStatement, + IfStatement, + ForStatement, + WhileStatement, + DoWhileStatement, + ContinueStatement, + BreakStatement, + ReturnStatement, + ThrowStatement, + EmitStatement, + TryStatement, + RevertStatement, + AssemblyStatement, + UncheckedBlock +]; + +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); function createNonterminalVariant( variant: ast.Statement['variant'], @@ -51,7 +73,7 @@ function createNonterminalVariant( return new Block(variant, collected, options); } - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); diff --git a/src/slang-nodes/StringExpression.ts b/src/slang-nodes/StringExpression.ts index 14afde128..a81339fac 100644 --- a/src/slang-nodes/StringExpression.ts +++ b/src/slang-nodes/StringExpression.ts @@ -11,20 +11,31 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.StringLiteral.name]: StringLiteral, - [ast.StringLiterals.name]: StringLiterals, - [ast.HexStringLiteral.name]: HexStringLiteral, - [ast.HexStringLiterals.name]: HexStringLiterals, - [ast.UnicodeStringLiterals.name]: UnicodeStringLiterals -}; +const keys = [ + ast.StringLiteral, + ast.StringLiterals, + ast.HexStringLiteral, + ast.HexStringLiterals, + ast.UnicodeStringLiterals +]; +const constructors = [ + StringLiteral, + StringLiterals, + HexStringLiteral, + HexStringLiterals, + UnicodeStringLiterals +]; + +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); function createNonterminalVariant( variant: ast.StringExpression['variant'], collected: CollectedMetadata, options: ParserOptions ): StringExpression['variant'] { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); diff --git a/src/slang-nodes/TupleMember.ts b/src/slang-nodes/TupleMember.ts index 9e62bc438..fd6fa6351 100644 --- a/src/slang-nodes/TupleMember.ts +++ b/src/slang-nodes/TupleMember.ts @@ -8,17 +8,19 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.TypedTupleMember.name]: TypedTupleMember, - [ast.UntypedTupleMember.name]: UntypedTupleMember -}; +const keys = [ast.TypedTupleMember, ast.UntypedTupleMember]; +const constructors = [TypedTupleMember, UntypedTupleMember]; + +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); function createNonterminalVariant( variant: ast.TupleMember['variant'], collected: CollectedMetadata, options: ParserOptions ): TupleMember['variant'] { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); diff --git a/src/slang-nodes/TypeName.ts b/src/slang-nodes/TypeName.ts index 9b4723a81..4d39cf901 100644 --- a/src/slang-nodes/TypeName.ts +++ b/src/slang-nodes/TypeName.ts @@ -12,28 +12,43 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.ArrayTypeName.name]: ArrayTypeName, - [ast.FunctionType.name]: FunctionType, - [ast.MappingType.name]: MappingType, - [ast.IdentifierPath.name]: IdentifierPath -}; +const keys = [ + ast.ArrayTypeName, + ast.FunctionType, + ast.MappingType, + ast.IdentifierPath +]; +const constructors = [ArrayTypeName, FunctionType, MappingType, IdentifierPath]; -const variantWithVariantsConstructors = { - [ast.ElementaryType.name]: ElementaryType -}; +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); + +const keysWithVariants = [ast.ElementaryType]; +const constructorsWithVariants = [ElementaryType]; + +const variantWithVariantsConstructors = new Map< + string, + (typeof constructorsWithVariants)[number] +>( + keysWithVariants.map((key, index) => [ + key.name, + constructorsWithVariants[index] + ]) +); function createNonterminalVariant( variant: ast.TypeName['variant'], collected: CollectedMetadata, options: ParserOptions ): TypeName['variant'] { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); - const variantWithVariantsConstructor = - variantWithVariantsConstructors[variant.constructor.name]; + const variantWithVariantsConstructor = variantWithVariantsConstructors.get( + variant.constructor.name + ); if (variantWithVariantsConstructor !== undefined) return extractVariant( new variantWithVariantsConstructor(variant as never, collected) diff --git a/src/slang-nodes/UsingClause.ts b/src/slang-nodes/UsingClause.ts index 126e2ef1a..17dcfb8c7 100644 --- a/src/slang-nodes/UsingClause.ts +++ b/src/slang-nodes/UsingClause.ts @@ -6,16 +6,18 @@ import { UsingDeconstruction } from './UsingDeconstruction.js'; import type { CollectedMetadata } from '../types.d.ts'; -const variantConstructors = { - [ast.IdentifierPath.name]: IdentifierPath, - [ast.UsingDeconstruction.name]: UsingDeconstruction -}; +const keys = [ast.IdentifierPath, ast.UsingDeconstruction]; +const constructors = [IdentifierPath, UsingDeconstruction]; + +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); function createNonterminalVariant( variant: ast.UsingClause['variant'], collected: CollectedMetadata ): UsingClause['variant'] { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected); diff --git a/src/slang-nodes/VersionExpression.ts b/src/slang-nodes/VersionExpression.ts index f64246df2..5b953e27c 100644 --- a/src/slang-nodes/VersionExpression.ts +++ b/src/slang-nodes/VersionExpression.ts @@ -6,16 +6,18 @@ import { VersionTerm } from './VersionTerm.js'; import type { CollectedMetadata } from '../types.d.ts'; -const variantConstructors = { - [ast.VersionRange.name]: VersionRange, - [ast.VersionTerm.name]: VersionTerm -}; +const keys = [ast.VersionRange, ast.VersionTerm]; +const constructors = [VersionRange, VersionTerm]; + +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); function createNonterminalVariant( variant: ast.VersionExpression['variant'], collected: CollectedMetadata ): VersionExpression['variant'] { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected); diff --git a/src/slang-nodes/YulExpression.ts b/src/slang-nodes/YulExpression.ts index 50c93a604..7837fb404 100644 --- a/src/slang-nodes/YulExpression.ts +++ b/src/slang-nodes/YulExpression.ts @@ -10,26 +10,38 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.YulFunctionCallExpression.name]: YulFunctionCallExpression, - [ast.YulPath.name]: YulPath -}; +const keys = [ast.YulFunctionCallExpression, ast.YulPath]; +const constructors = [YulFunctionCallExpression, YulPath]; -const variantWithVariantsConstructors = { - [ast.YulLiteral.name]: YulLiteral -}; +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); + +const keysWithVariants = [ast.YulLiteral]; +const constructorsWithVariants = [YulLiteral]; + +const variantWithVariantsConstructors = new Map< + string, + (typeof constructorsWithVariants)[number] +>( + keysWithVariants.map((key, index) => [ + key.name, + constructorsWithVariants[index] + ]) +); function createNonterminalVariant( variant: ast.YulExpression['variant'], collected: CollectedMetadata, options: ParserOptions ): YulExpression['variant'] { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); - const variantWithVariantsConstructor = - variantWithVariantsConstructors[variant.constructor.name]; + const variantWithVariantsConstructor = variantWithVariantsConstructors.get( + variant.constructor.name + ); if (variantWithVariantsConstructor !== undefined) return extractVariant( new variantWithVariantsConstructor(variant as never, collected, options) diff --git a/src/slang-nodes/YulLiteral.ts b/src/slang-nodes/YulLiteral.ts index c36597d01..699410b1b 100644 --- a/src/slang-nodes/YulLiteral.ts +++ b/src/slang-nodes/YulLiteral.ts @@ -12,17 +12,19 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.HexStringLiteral.name]: HexStringLiteral, - [ast.StringLiteral.name]: StringLiteral -}; +const keys = [ast.HexStringLiteral, ast.StringLiteral]; +const constructors = [HexStringLiteral, StringLiteral]; + +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); function createNonterminalVariant( variant: Exclude, collected: CollectedMetadata, options: ParserOptions ): Exclude { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); diff --git a/src/slang-nodes/YulStatement.ts b/src/slang-nodes/YulStatement.ts index 4b2bbf74e..7bf4f07d6 100644 --- a/src/slang-nodes/YulStatement.ts +++ b/src/slang-nodes/YulStatement.ts @@ -20,23 +20,49 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.YulFunctionDefinition.name]: YulFunctionDefinition, - [ast.YulVariableDeclarationStatement.name]: YulVariableDeclarationStatement, - [ast.YulVariableAssignmentStatement.name]: YulVariableAssignmentStatement, - [ast.YulStackAssignmentStatement.name]: YulStackAssignmentStatement, - [ast.YulIfStatement.name]: YulIfStatement, - [ast.YulForStatement.name]: YulForStatement, - [ast.YulSwitchStatement.name]: YulSwitchStatement, - [ast.YulLeaveStatement.name]: YulLeaveStatement, - [ast.YulBreakStatement.name]: YulBreakStatement, - [ast.YulContinueStatement.name]: YulContinueStatement, - [ast.YulLabel.name]: YulLabel -}; +const keys = [ + ast.YulFunctionDefinition, + ast.YulVariableDeclarationStatement, + ast.YulVariableAssignmentStatement, + ast.YulStackAssignmentStatement, + ast.YulIfStatement, + ast.YulForStatement, + ast.YulSwitchStatement, + ast.YulLeaveStatement, + ast.YulBreakStatement, + ast.YulContinueStatement, + ast.YulLabel +]; +const constructors = [ + YulFunctionDefinition, + YulVariableDeclarationStatement, + YulVariableAssignmentStatement, + YulStackAssignmentStatement, + YulIfStatement, + YulForStatement, + YulSwitchStatement, + YulLeaveStatement, + YulBreakStatement, + YulContinueStatement, + YulLabel +]; -const variantWithVariantsConstructors = { - [ast.YulExpression.name]: YulExpression -}; +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); + +const keysWithVariants = [ast.YulExpression]; +const constructorsWithVariants = [YulExpression]; + +const variantWithVariantsConstructors = new Map< + string, + (typeof constructorsWithVariants)[number] +>( + keysWithVariants.map((key, index) => [ + key.name, + constructorsWithVariants[index] + ]) +); function createNonterminalVariant( variant: ast.YulStatement['variant'], @@ -47,12 +73,13 @@ function createNonterminalVariant( return new YulBlock(variant, collected, options); } - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); - const variantWithVariantsConstructor = - variantWithVariantsConstructors[variant.constructor.name]; + const variantWithVariantsConstructor = variantWithVariantsConstructors.get( + variant.constructor.name + ); if (variantWithVariantsConstructor !== undefined) return extractVariant( new variantWithVariantsConstructor(variant as never, collected, options) diff --git a/src/slang-nodes/YulSwitchCase.ts b/src/slang-nodes/YulSwitchCase.ts index 11ac9b3a7..cf45f7499 100644 --- a/src/slang-nodes/YulSwitchCase.ts +++ b/src/slang-nodes/YulSwitchCase.ts @@ -8,17 +8,19 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const variantConstructors = { - [ast.YulDefaultCase.name]: YulDefaultCase, - [ast.YulValueCase.name]: YulValueCase -}; +const keys = [ast.YulDefaultCase, ast.YulValueCase]; +const constructors = [YulDefaultCase, YulValueCase]; + +const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) +); function createNonterminalVariant( variant: ast.YulSwitchCase['variant'], collected: CollectedMetadata, options: ParserOptions ): YulSwitchCase['variant'] { - const variantConstructor = variantConstructors[variant.constructor.name]; + const variantConstructor = variantConstructors.get(variant.constructor.name); if (variantConstructor !== undefined) return new variantConstructor(variant as never, collected, options); From ac1e5f719888ad1f2ee991a98e7021615f4ff416 Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 12 Feb 2026 00:57:25 -0300 Subject: [PATCH 03/22] adding a factory for the same functionality --- src/slang-nodes/ArgumentsDeclaration.ts | 30 +--- src/slang-nodes/ContractMember.ts | 80 ++++------ src/slang-nodes/ContractSpecifier.ts | 24 +-- src/slang-nodes/Expression.ts | 150 +++++++----------- src/slang-nodes/FallbackFunctionAttribute.ts | 24 +-- src/slang-nodes/ForStatementInitialization.ts | 43 ++--- src/slang-nodes/FunctionAttribute.ts | 24 +-- src/slang-nodes/ImportClause.ts | 24 +-- src/slang-nodes/MappingKeyType.ts | 45 +----- src/slang-nodes/Pragma.ts | 24 +-- src/slang-nodes/ReceiveFunctionAttribute.ts | 24 +-- src/slang-nodes/SourceUnitMember.ts | 80 ++++------ src/slang-nodes/Statement.ts | 86 +++++----- src/slang-nodes/StringExpression.ts | 48 +++--- src/slang-nodes/TupleMember.ts | 24 +-- src/slang-nodes/TypeName.ts | 51 +----- src/slang-nodes/UsingClause.ts | 23 +-- src/slang-nodes/VersionExpression.ts | 22 +-- src/slang-nodes/YulExpression.ts | 46 +----- src/slang-nodes/YulLiteral.ts | 23 +-- src/slang-nodes/YulStatement.ts | 89 ++++------- src/slang-nodes/YulSwitchCase.ts | 23 +-- .../create-nonterminal-variant-creator.ts | 68 ++++++++ 23 files changed, 409 insertions(+), 666 deletions(-) create mode 100644 src/slang-utils/create-nonterminal-variant-creator.ts diff --git a/src/slang-nodes/ArgumentsDeclaration.ts b/src/slang-nodes/ArgumentsDeclaration.ts index 034cf0486..3f76cc1cf 100644 --- a/src/slang-nodes/ArgumentsDeclaration.ts +++ b/src/slang-nodes/ArgumentsDeclaration.ts @@ -1,5 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { PositionalArgumentsDeclaration } from './PositionalArgumentsDeclaration.js'; import { NamedArgumentsDeclaration } from './NamedArgumentsDeclaration.js'; @@ -8,31 +9,14 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ - ast.PositionalArgumentsDeclaration, - ast.NamedArgumentsDeclaration -]; -const constructors = [ - PositionalArgumentsDeclaration, - NamedArgumentsDeclaration -]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) +const createNonterminalVariant = createNonterminalVariantCreator< + ArgumentsDeclaration, + ast.ArgumentsDeclaration +>( + [ast.PositionalArgumentsDeclaration, ast.NamedArgumentsDeclaration], + [PositionalArgumentsDeclaration, NamedArgumentsDeclaration] ); -function createNonterminalVariant( - variant: ast.ArgumentsDeclaration['variant'], - collected: CollectedMetadata, - options: ParserOptions -): ArgumentsDeclaration['variant'] { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} - export class ArgumentsDeclaration extends SlangNode { readonly kind = NonterminalKind.ArgumentsDeclaration; diff --git a/src/slang-nodes/ContractMember.ts b/src/slang-nodes/ContractMember.ts index 7e7e86298..402e56fc3 100644 --- a/src/slang-nodes/ContractMember.ts +++ b/src/slang-nodes/ContractMember.ts @@ -1,5 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { UsingDirective } from './UsingDirective.js'; import { FunctionDefinition } from './FunctionDefinition.js'; @@ -19,53 +20,42 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ - ast.UsingDirective, - ast.FunctionDefinition, - ast.ConstructorDefinition, - ast.ReceiveFunctionDefinition, - ast.FallbackFunctionDefinition, - ast.UnnamedFunctionDefinition, - ast.ModifierDefinition, - ast.StructDefinition, - ast.EnumDefinition, - ast.EventDefinition, - ast.StateVariableDefinition, - ast.ErrorDefinition, - ast.UserDefinedValueTypeDefinition -]; -const constructors = [ - UsingDirective, - FunctionDefinition, - ConstructorDefinition, - ReceiveFunctionDefinition, - FallbackFunctionDefinition, - UnnamedFunctionDefinition, - ModifierDefinition, - StructDefinition, - EnumDefinition, - EventDefinition, - StateVariableDefinition, - ErrorDefinition, - UserDefinedValueTypeDefinition -]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) +const createNonterminalVariant = createNonterminalVariantCreator< + ContractMember, + ast.ContractMember +>( + [ + ast.UsingDirective, + ast.FunctionDefinition, + ast.ConstructorDefinition, + ast.ReceiveFunctionDefinition, + ast.FallbackFunctionDefinition, + ast.UnnamedFunctionDefinition, + ast.ModifierDefinition, + ast.StructDefinition, + ast.EnumDefinition, + ast.EventDefinition, + ast.StateVariableDefinition, + ast.ErrorDefinition, + ast.UserDefinedValueTypeDefinition + ], + [ + UsingDirective, + FunctionDefinition, + ConstructorDefinition, + ReceiveFunctionDefinition, + FallbackFunctionDefinition, + UnnamedFunctionDefinition, + ModifierDefinition, + StructDefinition, + EnumDefinition, + EventDefinition, + StateVariableDefinition, + ErrorDefinition, + UserDefinedValueTypeDefinition + ] ); -function createNonterminalVariant( - variant: ast.ContractMember['variant'], - collected: CollectedMetadata, - options: ParserOptions -): ContractMember['variant'] { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} - export class ContractMember extends SlangNode { readonly kind = NonterminalKind.ContractMember; diff --git a/src/slang-nodes/ContractSpecifier.ts b/src/slang-nodes/ContractSpecifier.ts index 0fc9acb84..9c7cb2146 100644 --- a/src/slang-nodes/ContractSpecifier.ts +++ b/src/slang-nodes/ContractSpecifier.ts @@ -1,5 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { InheritanceSpecifier } from './InheritanceSpecifier.js'; import { StorageLayoutSpecifier } from './StorageLayoutSpecifier.js'; @@ -8,25 +9,14 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ast.InheritanceSpecifier, ast.StorageLayoutSpecifier]; -const constructors = [InheritanceSpecifier, StorageLayoutSpecifier]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) +const createNonterminalVariant = createNonterminalVariantCreator< + ContractSpecifier, + ast.ContractSpecifier +>( + [ast.InheritanceSpecifier, ast.StorageLayoutSpecifier], + [InheritanceSpecifier, StorageLayoutSpecifier] ); -function createNonterminalVariant( - variant: ast.ContractSpecifier['variant'], - collected: CollectedMetadata, - options: ParserOptions -): ContractSpecifier['variant'] { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} - export class ContractSpecifier extends SlangNode { readonly kind = NonterminalKind.ContractSpecifier; diff --git a/src/slang-nodes/Expression.ts b/src/slang-nodes/Expression.ts index 9337a3aa2..d21d9312b 100644 --- a/src/slang-nodes/Expression.ts +++ b/src/slang-nodes/Expression.ts @@ -3,7 +3,7 @@ import { NonterminalKind, TerminalNode as SlangTerminalNode } from '@nomicfoundation/slang/cst'; -import { extractVariant } from '../slang-utils/extract-variant.js'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { AssignmentExpression } from './AssignmentExpression.js'; import { ConditionalExpression } from './ConditionalExpression.js'; @@ -38,98 +38,68 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ - ast.AssignmentExpression, - ast.ConditionalExpression, - ast.OrExpression, - ast.AndExpression, - ast.EqualityExpression, - ast.InequalityExpression, - ast.BitwiseOrExpression, - ast.BitwiseXorExpression, - ast.BitwiseAndExpression, - ast.ShiftExpression, - ast.AdditiveExpression, - ast.MultiplicativeExpression, - ast.ExponentiationExpression, - ast.PostfixExpression, - ast.PrefixExpression, - ast.FunctionCallExpression, - ast.CallOptionsExpression, - ast.MemberAccessExpression, - ast.IndexAccessExpression, - ast.NewExpression, - ast.TupleExpression, - ast.TypeExpression, - ast.ArrayExpression, - ast.HexNumberExpression, - ast.DecimalNumberExpression -]; -const constructors = [ - AssignmentExpression, - ConditionalExpression, - OrExpression, - AndExpression, - EqualityExpression, - InequalityExpression, - BitwiseOrExpression, - BitwiseXorExpression, - BitwiseAndExpression, - ShiftExpression, - AdditiveExpression, - MultiplicativeExpression, - ExponentiationExpression, - PostfixExpression, - PrefixExpression, - FunctionCallExpression, - CallOptionsExpression, - MemberAccessExpression, - IndexAccessExpression, - NewExpression, - TupleExpression, - TypeExpression, - ArrayExpression, - HexNumberExpression, - DecimalNumberExpression -]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) -); - -const keysWithVariants = [ast.StringExpression, ast.ElementaryType]; -const constructorsWithVariants = [StringExpression, ElementaryType]; - -const variantWithVariantsConstructors = new Map< - string, - (typeof constructorsWithVariants)[number] +const createNonterminalVariant = createNonterminalVariantCreator< + Expression, + ast.Expression >( - keysWithVariants.map((key, index) => [ - key.name, - constructorsWithVariants[index] - ]) + [ + ast.AssignmentExpression, + ast.ConditionalExpression, + ast.OrExpression, + ast.AndExpression, + ast.EqualityExpression, + ast.InequalityExpression, + ast.BitwiseOrExpression, + ast.BitwiseXorExpression, + ast.BitwiseAndExpression, + ast.ShiftExpression, + ast.AdditiveExpression, + ast.MultiplicativeExpression, + ast.ExponentiationExpression, + ast.PostfixExpression, + ast.PrefixExpression, + ast.FunctionCallExpression, + ast.CallOptionsExpression, + ast.MemberAccessExpression, + ast.IndexAccessExpression, + ast.NewExpression, + ast.TupleExpression, + ast.TypeExpression, + ast.ArrayExpression, + ast.HexNumberExpression, + ast.DecimalNumberExpression + ], + [ + AssignmentExpression, + ConditionalExpression, + OrExpression, + AndExpression, + EqualityExpression, + InequalityExpression, + BitwiseOrExpression, + BitwiseXorExpression, + BitwiseAndExpression, + ShiftExpression, + AdditiveExpression, + MultiplicativeExpression, + ExponentiationExpression, + PostfixExpression, + PrefixExpression, + FunctionCallExpression, + CallOptionsExpression, + MemberAccessExpression, + IndexAccessExpression, + NewExpression, + TupleExpression, + TypeExpression, + ArrayExpression, + HexNumberExpression, + DecimalNumberExpression + ], + [ast.StringExpression, ast.ElementaryType], + [StringExpression, ElementaryType] ); -function createNonterminalVariant( - variant: Exclude, - collected: CollectedMetadata, - options: ParserOptions -): Expression['variant'] { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - const variantWithVariantsConstructor = variantWithVariantsConstructors.get( - variant.constructor.name - ); - if (variantWithVariantsConstructor !== undefined) - return extractVariant( - new variantWithVariantsConstructor(variant as never, collected, options) - ); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} - export class Expression extends SlangNode { readonly kind = NonterminalKind.Expression; diff --git a/src/slang-nodes/FallbackFunctionAttribute.ts b/src/slang-nodes/FallbackFunctionAttribute.ts index 92019758c..a875d920b 100644 --- a/src/slang-nodes/FallbackFunctionAttribute.ts +++ b/src/slang-nodes/FallbackFunctionAttribute.ts @@ -3,6 +3,7 @@ import { NonterminalKind, TerminalNode as SlangTerminalNode } from '@nomicfoundation/slang/cst'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { ModifierInvocation } from './ModifierInvocation.js'; import { OverrideSpecifier } from './OverrideSpecifier.js'; @@ -12,25 +13,14 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ast.ModifierInvocation, ast.OverrideSpecifier]; -const constructors = [ModifierInvocation, OverrideSpecifier]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) +const createNonterminalVariant = createNonterminalVariantCreator< + FallbackFunctionAttribute, + ast.FallbackFunctionAttribute +>( + [ast.ModifierInvocation, ast.OverrideSpecifier], + [ModifierInvocation, OverrideSpecifier] ); -function createNonterminalVariant( - variant: Exclude, - collected: CollectedMetadata, - options: ParserOptions -): Exclude { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} - export class FallbackFunctionAttribute extends SlangNode { readonly kind = NonterminalKind.FallbackFunctionAttribute; diff --git a/src/slang-nodes/ForStatementInitialization.ts b/src/slang-nodes/ForStatementInitialization.ts index 0c40d2b5e..246b0befc 100644 --- a/src/slang-nodes/ForStatementInitialization.ts +++ b/src/slang-nodes/ForStatementInitialization.ts @@ -3,6 +3,7 @@ import { NonterminalKind, TerminalNode as SlangTerminalNode } from '@nomicfoundation/slang/cst'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { ExpressionStatement } from './ExpressionStatement.js'; import { VariableDeclarationStatement } from './VariableDeclarationStatement.js'; @@ -13,36 +14,22 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ - ast.ExpressionStatement, - ast.VariableDeclarationStatement, - ast.TupleDeconstructionStatement -]; -const constructors = [ - ExpressionStatement, - VariableDeclarationStatement, - TupleDeconstructionStatement -]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) +const createNonterminalVariant = createNonterminalVariantCreator< + ForStatementInitialization, + ast.ForStatementInitialization +>( + [ + ast.ExpressionStatement, + ast.VariableDeclarationStatement, + ast.TupleDeconstructionStatement + ], + [ + ExpressionStatement, + VariableDeclarationStatement, + TupleDeconstructionStatement + ] ); -function createNonterminalVariant( - variant: Exclude< - ast.ForStatementInitialization['variant'], - SlangTerminalNode - >, - collected: CollectedMetadata, - options: ParserOptions -): Exclude { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} - export class ForStatementInitialization extends SlangNode { readonly kind = NonterminalKind.ForStatementInitialization; diff --git a/src/slang-nodes/FunctionAttribute.ts b/src/slang-nodes/FunctionAttribute.ts index 4ac26d565..249d721ce 100644 --- a/src/slang-nodes/FunctionAttribute.ts +++ b/src/slang-nodes/FunctionAttribute.ts @@ -3,6 +3,7 @@ import { NonterminalKind, TerminalNode as SlangTerminalNode } from '@nomicfoundation/slang/cst'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { ModifierInvocation } from './ModifierInvocation.js'; import { OverrideSpecifier } from './OverrideSpecifier.js'; @@ -12,25 +13,14 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ast.ModifierInvocation, ast.OverrideSpecifier]; -const constructors = [ModifierInvocation, OverrideSpecifier]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) +const createNonterminalVariant = createNonterminalVariantCreator< + FunctionAttribute, + ast.FunctionAttribute +>( + [ast.ModifierInvocation, ast.OverrideSpecifier], + [ModifierInvocation, OverrideSpecifier] ); -function createNonterminalVariant( - variant: Exclude, - collected: CollectedMetadata, - options: ParserOptions -): Exclude { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} - export class FunctionAttribute extends SlangNode { readonly kind = NonterminalKind.FunctionAttribute; diff --git a/src/slang-nodes/ImportClause.ts b/src/slang-nodes/ImportClause.ts index 3e0f66033..a090a6076 100644 --- a/src/slang-nodes/ImportClause.ts +++ b/src/slang-nodes/ImportClause.ts @@ -1,5 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { PathImport } from './PathImport.js'; import { NamedImport } from './NamedImport.js'; @@ -9,25 +10,14 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ast.PathImport, ast.NamedImport, ast.ImportDeconstruction]; -const constructors = [PathImport, NamedImport, ImportDeconstruction]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) +const createNonterminalVariant = createNonterminalVariantCreator< + ImportClause, + ast.ImportClause +>( + [ast.PathImport, ast.NamedImport, ast.ImportDeconstruction], + [PathImport, NamedImport, ImportDeconstruction] ); -function createNonterminalVariant( - variant: ast.ImportClause['variant'], - collected: CollectedMetadata, - options: ParserOptions -): ImportClause['variant'] { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} - export class ImportClause extends SlangNode { readonly kind = NonterminalKind.ImportClause; diff --git a/src/slang-nodes/MappingKeyType.ts b/src/slang-nodes/MappingKeyType.ts index ea08b3652..e753184ef 100644 --- a/src/slang-nodes/MappingKeyType.ts +++ b/src/slang-nodes/MappingKeyType.ts @@ -1,51 +1,22 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { extractVariant } from '../slang-utils/extract-variant.js'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { ElementaryType } from './ElementaryType.js'; import { IdentifierPath } from './IdentifierPath.js'; import type { CollectedMetadata } from '../types.d.ts'; -const keys = [ast.IdentifierPath]; -const constructors = [IdentifierPath]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) -); - -const keysWithVariants = [ast.ElementaryType]; -const constructorsWithVariants = [ElementaryType]; - -const variantWithVariantsConstructors = new Map< - string, - (typeof constructorsWithVariants)[number] +const createNonterminalVariant = createNonterminalVariantCreator< + MappingKeyType, + ast.MappingKeyType >( - keysWithVariants.map((key, index) => [ - key.name, - constructorsWithVariants[index] - ]) + [ast.IdentifierPath], + [IdentifierPath], + [ast.ElementaryType], + [ElementaryType] ); -function createNonterminalVariant( - variant: ast.MappingKeyType['variant'], - collected: CollectedMetadata -): MappingKeyType['variant'] { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected); - - const variantWithVariantsConstructor = variantWithVariantsConstructors.get( - variant.constructor.name - ); - if (variantWithVariantsConstructor !== undefined) - return extractVariant( - new variantWithVariantsConstructor(variant as never, collected) - ); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} - export class MappingKeyType extends SlangNode { readonly kind = NonterminalKind.MappingKeyType; diff --git a/src/slang-nodes/Pragma.ts b/src/slang-nodes/Pragma.ts index a1e654beb..834312d15 100644 --- a/src/slang-nodes/Pragma.ts +++ b/src/slang-nodes/Pragma.ts @@ -1,5 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { AbicoderPragma } from './AbicoderPragma.js'; import { ExperimentalPragma } from './ExperimentalPragma.js'; @@ -9,25 +10,14 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ast.AbicoderPragma, ast.ExperimentalPragma, ast.VersionPragma]; -const constructors = [AbicoderPragma, ExperimentalPragma, VersionPragma]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) +const createNonterminalVariant = createNonterminalVariantCreator< + Pragma, + ast.Pragma +>( + [ast.AbicoderPragma, ast.ExperimentalPragma, ast.VersionPragma], + [AbicoderPragma, ExperimentalPragma, VersionPragma] ); -function createNonterminalVariant( - variant: ast.Pragma['variant'], - collected: CollectedMetadata, - options: ParserOptions -): Pragma['variant'] { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} - export class Pragma extends SlangNode { readonly kind = NonterminalKind.Pragma; diff --git a/src/slang-nodes/ReceiveFunctionAttribute.ts b/src/slang-nodes/ReceiveFunctionAttribute.ts index 63e376751..2aba6cbc5 100644 --- a/src/slang-nodes/ReceiveFunctionAttribute.ts +++ b/src/slang-nodes/ReceiveFunctionAttribute.ts @@ -3,6 +3,7 @@ import { NonterminalKind, TerminalNode as SlangTerminalNode } from '@nomicfoundation/slang/cst'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { ModifierInvocation } from './ModifierInvocation.js'; import { OverrideSpecifier } from './OverrideSpecifier.js'; @@ -12,25 +13,14 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ast.ModifierInvocation, ast.OverrideSpecifier]; -const constructors = [ModifierInvocation, OverrideSpecifier]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) +const createNonterminalVariant = createNonterminalVariantCreator< + ReceiveFunctionAttribute, + ast.ReceiveFunctionAttribute +>( + [ast.ModifierInvocation, ast.OverrideSpecifier], + [ModifierInvocation, OverrideSpecifier] ); -function createNonterminalVariant( - variant: Exclude, - collected: CollectedMetadata, - options: ParserOptions -): Exclude { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} - export class ReceiveFunctionAttribute extends SlangNode { readonly kind = NonterminalKind.ReceiveFunctionAttribute; diff --git a/src/slang-nodes/SourceUnitMember.ts b/src/slang-nodes/SourceUnitMember.ts index c8487cdd9..c745b75ad 100644 --- a/src/slang-nodes/SourceUnitMember.ts +++ b/src/slang-nodes/SourceUnitMember.ts @@ -1,5 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { PragmaDirective } from './PragmaDirective.js'; import { ImportDirective } from './ImportDirective.js'; @@ -19,53 +20,42 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ - ast.PragmaDirective, - ast.ImportDirective, - ast.ContractDefinition, - ast.InterfaceDefinition, - ast.LibraryDefinition, - ast.StructDefinition, - ast.EnumDefinition, - ast.FunctionDefinition, - ast.ConstantDefinition, - ast.ErrorDefinition, - ast.UserDefinedValueTypeDefinition, - ast.UsingDirective, - ast.EventDefinition -]; -const constructors = [ - PragmaDirective, - ImportDirective, - ContractDefinition, - InterfaceDefinition, - LibraryDefinition, - StructDefinition, - EnumDefinition, - FunctionDefinition, - ConstantDefinition, - ErrorDefinition, - UserDefinedValueTypeDefinition, - UsingDirective, - EventDefinition -]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) +const createNonterminalVariant = createNonterminalVariantCreator< + SourceUnitMember, + ast.SourceUnitMember +>( + [ + ast.PragmaDirective, + ast.ImportDirective, + ast.ContractDefinition, + ast.InterfaceDefinition, + ast.LibraryDefinition, + ast.StructDefinition, + ast.EnumDefinition, + ast.FunctionDefinition, + ast.ConstantDefinition, + ast.ErrorDefinition, + ast.UserDefinedValueTypeDefinition, + ast.UsingDirective, + ast.EventDefinition + ], + [ + PragmaDirective, + ImportDirective, + ContractDefinition, + InterfaceDefinition, + LibraryDefinition, + StructDefinition, + EnumDefinition, + FunctionDefinition, + ConstantDefinition, + ErrorDefinition, + UserDefinedValueTypeDefinition, + UsingDirective, + EventDefinition + ] ); -function createNonterminalVariant( - variant: ast.SourceUnitMember['variant'], - collected: CollectedMetadata, - options: ParserOptions -): SourceUnitMember['variant'] { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} - export class SourceUnitMember extends SlangNode { readonly kind = NonterminalKind.SourceUnitMember; diff --git a/src/slang-nodes/Statement.ts b/src/slang-nodes/Statement.ts index e3a5eb6b1..1aad6ef7a 100644 --- a/src/slang-nodes/Statement.ts +++ b/src/slang-nodes/Statement.ts @@ -1,5 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { ExpressionStatement } from './ExpressionStatement.js'; import { VariableDeclarationStatement } from './VariableDeclarationStatement.js'; @@ -23,45 +24,46 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ - ast.ExpressionStatement, - ast.VariableDeclarationStatement, - ast.TupleDeconstructionStatement, - ast.IfStatement, - ast.ForStatement, - ast.WhileStatement, - ast.DoWhileStatement, - ast.ContinueStatement, - ast.BreakStatement, - ast.ReturnStatement, - ast.ThrowStatement, - ast.EmitStatement, - ast.TryStatement, - ast.RevertStatement, - ast.AssemblyStatement, - ast.UncheckedBlock -]; -const constructors = [ - ExpressionStatement, - VariableDeclarationStatement, - TupleDeconstructionStatement, - IfStatement, - ForStatement, - WhileStatement, - DoWhileStatement, - ContinueStatement, - BreakStatement, - ReturnStatement, - ThrowStatement, - EmitStatement, - TryStatement, - RevertStatement, - AssemblyStatement, - UncheckedBlock -]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) +const createNonterminalVariantInternal = createNonterminalVariantCreator< + Statement, + ast.Statement +>( + [ + ast.ExpressionStatement, + ast.VariableDeclarationStatement, + ast.TupleDeconstructionStatement, + ast.IfStatement, + ast.ForStatement, + ast.WhileStatement, + ast.DoWhileStatement, + ast.ContinueStatement, + ast.BreakStatement, + ast.ReturnStatement, + ast.ThrowStatement, + ast.EmitStatement, + ast.TryStatement, + ast.RevertStatement, + ast.AssemblyStatement, + ast.UncheckedBlock + ], + [ + ExpressionStatement, + VariableDeclarationStatement, + TupleDeconstructionStatement, + IfStatement, + ForStatement, + WhileStatement, + DoWhileStatement, + ContinueStatement, + BreakStatement, + ReturnStatement, + ThrowStatement, + EmitStatement, + TryStatement, + RevertStatement, + AssemblyStatement, + UncheckedBlock + ] ); function createNonterminalVariant( @@ -73,11 +75,7 @@ function createNonterminalVariant( return new Block(variant, collected, options); } - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); + return createNonterminalVariantInternal(variant, collected, options); } export class Statement extends SlangNode { diff --git a/src/slang-nodes/StringExpression.ts b/src/slang-nodes/StringExpression.ts index a81339fac..849706a0e 100644 --- a/src/slang-nodes/StringExpression.ts +++ b/src/slang-nodes/StringExpression.ts @@ -1,5 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { StringLiteral } from './StringLiteral.js'; import { StringLiterals } from './StringLiterals.js'; @@ -11,37 +12,26 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ - ast.StringLiteral, - ast.StringLiterals, - ast.HexStringLiteral, - ast.HexStringLiterals, - ast.UnicodeStringLiterals -]; -const constructors = [ - StringLiteral, - StringLiterals, - HexStringLiteral, - HexStringLiterals, - UnicodeStringLiterals -]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) +const createNonterminalVariant = createNonterminalVariantCreator< + StringExpression, + ast.StringExpression +>( + [ + ast.StringLiteral, + ast.StringLiterals, + ast.HexStringLiteral, + ast.HexStringLiterals, + ast.UnicodeStringLiterals + ], + [ + StringLiteral, + StringLiterals, + HexStringLiteral, + HexStringLiterals, + UnicodeStringLiterals + ] ); -function createNonterminalVariant( - variant: ast.StringExpression['variant'], - collected: CollectedMetadata, - options: ParserOptions -): StringExpression['variant'] { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} - export class StringExpression extends SlangNode { readonly kind = NonterminalKind.StringExpression; diff --git a/src/slang-nodes/TupleMember.ts b/src/slang-nodes/TupleMember.ts index fd6fa6351..bae5249b2 100644 --- a/src/slang-nodes/TupleMember.ts +++ b/src/slang-nodes/TupleMember.ts @@ -1,5 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { TypedTupleMember } from './TypedTupleMember.js'; import { UntypedTupleMember } from './UntypedTupleMember.js'; @@ -8,25 +9,14 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ast.TypedTupleMember, ast.UntypedTupleMember]; -const constructors = [TypedTupleMember, UntypedTupleMember]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) +const createNonterminalVariant = createNonterminalVariantCreator< + TupleMember, + ast.TupleMember +>( + [ast.TypedTupleMember, ast.UntypedTupleMember], + [TypedTupleMember, UntypedTupleMember] ); -function createNonterminalVariant( - variant: ast.TupleMember['variant'], - collected: CollectedMetadata, - options: ParserOptions -): TupleMember['variant'] { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} - export class TupleMember extends SlangNode { readonly kind = NonterminalKind.TupleMember; diff --git a/src/slang-nodes/TypeName.ts b/src/slang-nodes/TypeName.ts index 4d39cf901..b6bcd562a 100644 --- a/src/slang-nodes/TypeName.ts +++ b/src/slang-nodes/TypeName.ts @@ -1,6 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { extractVariant } from '../slang-utils/extract-variant.js'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { ArrayTypeName } from './ArrayTypeName.js'; import { FunctionType } from './FunctionType.js'; @@ -12,51 +12,16 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ - ast.ArrayTypeName, - ast.FunctionType, - ast.MappingType, - ast.IdentifierPath -]; -const constructors = [ArrayTypeName, FunctionType, MappingType, IdentifierPath]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) -); - -const keysWithVariants = [ast.ElementaryType]; -const constructorsWithVariants = [ElementaryType]; - -const variantWithVariantsConstructors = new Map< - string, - (typeof constructorsWithVariants)[number] +const createNonterminalVariant = createNonterminalVariantCreator< + TypeName, + ast.TypeName >( - keysWithVariants.map((key, index) => [ - key.name, - constructorsWithVariants[index] - ]) + [ast.ArrayTypeName, ast.FunctionType, ast.MappingType, ast.IdentifierPath], + [ArrayTypeName, FunctionType, MappingType, IdentifierPath], + [ast.ElementaryType], + [ElementaryType] ); -function createNonterminalVariant( - variant: ast.TypeName['variant'], - collected: CollectedMetadata, - options: ParserOptions -): TypeName['variant'] { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - const variantWithVariantsConstructor = variantWithVariantsConstructors.get( - variant.constructor.name - ); - if (variantWithVariantsConstructor !== undefined) - return extractVariant( - new variantWithVariantsConstructor(variant as never, collected) - ); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} - export class TypeName extends SlangNode { readonly kind = NonterminalKind.TypeName; diff --git a/src/slang-nodes/UsingClause.ts b/src/slang-nodes/UsingClause.ts index 17dcfb8c7..c8e0849c1 100644 --- a/src/slang-nodes/UsingClause.ts +++ b/src/slang-nodes/UsingClause.ts @@ -1,29 +1,20 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { IdentifierPath } from './IdentifierPath.js'; import { UsingDeconstruction } from './UsingDeconstruction.js'; import type { CollectedMetadata } from '../types.d.ts'; -const keys = [ast.IdentifierPath, ast.UsingDeconstruction]; -const constructors = [IdentifierPath, UsingDeconstruction]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) +const createNonterminalVariant = createNonterminalVariantCreator< + UsingClause, + ast.UsingClause +>( + [ast.IdentifierPath, ast.UsingDeconstruction], + [IdentifierPath, UsingDeconstruction] ); -function createNonterminalVariant( - variant: ast.UsingClause['variant'], - collected: CollectedMetadata -): UsingClause['variant'] { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} - export class UsingClause extends SlangNode { readonly kind = NonterminalKind.UsingClause; diff --git a/src/slang-nodes/VersionExpression.ts b/src/slang-nodes/VersionExpression.ts index 5b953e27c..538e787f6 100644 --- a/src/slang-nodes/VersionExpression.ts +++ b/src/slang-nodes/VersionExpression.ts @@ -1,28 +1,16 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { VersionRange } from './VersionRange.js'; import { VersionTerm } from './VersionTerm.js'; import type { CollectedMetadata } from '../types.d.ts'; -const keys = [ast.VersionRange, ast.VersionTerm]; -const constructors = [VersionRange, VersionTerm]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) -); - -function createNonterminalVariant( - variant: ast.VersionExpression['variant'], - collected: CollectedMetadata -): VersionExpression['variant'] { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} +const createNonterminalVariant = createNonterminalVariantCreator< + VersionExpression, + ast.VersionExpression +>([ast.VersionRange, ast.VersionTerm], [VersionRange, VersionTerm]); export class VersionExpression extends SlangNode { readonly kind = NonterminalKind.VersionExpression; diff --git a/src/slang-nodes/YulExpression.ts b/src/slang-nodes/YulExpression.ts index 7837fb404..a4f25ad85 100644 --- a/src/slang-nodes/YulExpression.ts +++ b/src/slang-nodes/YulExpression.ts @@ -1,6 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { extractVariant } from '../slang-utils/extract-variant.js'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { YulFunctionCallExpression } from './YulFunctionCallExpression.js'; import { YulLiteral } from './YulLiteral.js'; @@ -10,46 +10,16 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ast.YulFunctionCallExpression, ast.YulPath]; -const constructors = [YulFunctionCallExpression, YulPath]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) -); - -const keysWithVariants = [ast.YulLiteral]; -const constructorsWithVariants = [YulLiteral]; - -const variantWithVariantsConstructors = new Map< - string, - (typeof constructorsWithVariants)[number] +const createNonterminalVariant = createNonterminalVariantCreator< + YulExpression, + ast.YulExpression >( - keysWithVariants.map((key, index) => [ - key.name, - constructorsWithVariants[index] - ]) + [ast.YulFunctionCallExpression, ast.YulPath], + [YulFunctionCallExpression, YulPath], + [ast.YulLiteral], + [YulLiteral] ); -function createNonterminalVariant( - variant: ast.YulExpression['variant'], - collected: CollectedMetadata, - options: ParserOptions -): YulExpression['variant'] { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - const variantWithVariantsConstructor = variantWithVariantsConstructors.get( - variant.constructor.name - ); - if (variantWithVariantsConstructor !== undefined) - return extractVariant( - new variantWithVariantsConstructor(variant as never, collected, options) - ); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} - export class YulExpression extends SlangNode { readonly kind = NonterminalKind.YulExpression; diff --git a/src/slang-nodes/YulLiteral.ts b/src/slang-nodes/YulLiteral.ts index 699410b1b..8fbe6b34a 100644 --- a/src/slang-nodes/YulLiteral.ts +++ b/src/slang-nodes/YulLiteral.ts @@ -3,6 +3,7 @@ import { NonterminalKind, TerminalNode as SlangTerminalNode } from '@nomicfoundation/slang/cst'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { HexStringLiteral } from './HexStringLiteral.js'; import { StringLiteral } from './StringLiteral.js'; @@ -12,24 +13,10 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ast.HexStringLiteral, ast.StringLiteral]; -const constructors = [HexStringLiteral, StringLiteral]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) -); - -function createNonterminalVariant( - variant: Exclude, - collected: CollectedMetadata, - options: ParserOptions -): Exclude { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} +const createNonterminalVariant = createNonterminalVariantCreator< + YulLiteral, + ast.YulLiteral +>([ast.HexStringLiteral, ast.StringLiteral], [HexStringLiteral, StringLiteral]); export class YulLiteral extends SlangNode { readonly kind = NonterminalKind.YulLiteral; diff --git a/src/slang-nodes/YulStatement.ts b/src/slang-nodes/YulStatement.ts index 7bf4f07d6..672d5664c 100644 --- a/src/slang-nodes/YulStatement.ts +++ b/src/slang-nodes/YulStatement.ts @@ -1,6 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { extractVariant } from '../slang-utils/extract-variant.js'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { YulBlock } from './YulBlock.js'; import { YulFunctionDefinition } from './YulFunctionDefinition.js'; @@ -20,48 +20,38 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ - ast.YulFunctionDefinition, - ast.YulVariableDeclarationStatement, - ast.YulVariableAssignmentStatement, - ast.YulStackAssignmentStatement, - ast.YulIfStatement, - ast.YulForStatement, - ast.YulSwitchStatement, - ast.YulLeaveStatement, - ast.YulBreakStatement, - ast.YulContinueStatement, - ast.YulLabel -]; -const constructors = [ - YulFunctionDefinition, - YulVariableDeclarationStatement, - YulVariableAssignmentStatement, - YulStackAssignmentStatement, - YulIfStatement, - YulForStatement, - YulSwitchStatement, - YulLeaveStatement, - YulBreakStatement, - YulContinueStatement, - YulLabel -]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) -); - -const keysWithVariants = [ast.YulExpression]; -const constructorsWithVariants = [YulExpression]; - -const variantWithVariantsConstructors = new Map< - string, - (typeof constructorsWithVariants)[number] +const createNonterminalVariantInternal = createNonterminalVariantCreator< + YulStatement, + ast.YulStatement >( - keysWithVariants.map((key, index) => [ - key.name, - constructorsWithVariants[index] - ]) + [ + ast.YulFunctionDefinition, + ast.YulVariableDeclarationStatement, + ast.YulVariableAssignmentStatement, + ast.YulStackAssignmentStatement, + ast.YulIfStatement, + ast.YulForStatement, + ast.YulSwitchStatement, + ast.YulLeaveStatement, + ast.YulBreakStatement, + ast.YulContinueStatement, + ast.YulLabel + ], + [ + YulFunctionDefinition, + YulVariableDeclarationStatement, + YulVariableAssignmentStatement, + YulStackAssignmentStatement, + YulIfStatement, + YulForStatement, + YulSwitchStatement, + YulLeaveStatement, + YulBreakStatement, + YulContinueStatement, + YulLabel + ], + [ast.YulExpression], + [YulExpression] ); function createNonterminalVariant( @@ -72,20 +62,7 @@ function createNonterminalVariant( if (variant instanceof ast.YulBlock) { return new YulBlock(variant, collected, options); } - - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - const variantWithVariantsConstructor = variantWithVariantsConstructors.get( - variant.constructor.name - ); - if (variantWithVariantsConstructor !== undefined) - return extractVariant( - new variantWithVariantsConstructor(variant as never, collected, options) - ); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); + return createNonterminalVariantInternal(variant, collected, options); } export class YulStatement extends SlangNode { diff --git a/src/slang-nodes/YulSwitchCase.ts b/src/slang-nodes/YulSwitchCase.ts index cf45f7499..f199609e0 100644 --- a/src/slang-nodes/YulSwitchCase.ts +++ b/src/slang-nodes/YulSwitchCase.ts @@ -1,5 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; +import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { YulDefaultCase } from './YulDefaultCase.js'; import { YulValueCase } from './YulValueCase.js'; @@ -8,24 +9,10 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const keys = [ast.YulDefaultCase, ast.YulValueCase]; -const constructors = [YulDefaultCase, YulValueCase]; - -const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) -); - -function createNonterminalVariant( - variant: ast.YulSwitchCase['variant'], - collected: CollectedMetadata, - options: ParserOptions -): YulSwitchCase['variant'] { - const variantConstructor = variantConstructors.get(variant.constructor.name); - if (variantConstructor !== undefined) - return new variantConstructor(variant as never, collected, options); - - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); -} +const createNonterminalVariant = createNonterminalVariantCreator< + YulSwitchCase, + ast.YulSwitchCase +>([ast.YulDefaultCase, ast.YulValueCase], [YulDefaultCase, YulValueCase]); export class YulSwitchCase extends SlangNode { readonly kind = NonterminalKind.YulSwitchCase; diff --git a/src/slang-utils/create-nonterminal-variant-creator.ts b/src/slang-utils/create-nonterminal-variant-creator.ts new file mode 100644 index 000000000..2164841ab --- /dev/null +++ b/src/slang-utils/create-nonterminal-variant-creator.ts @@ -0,0 +1,68 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { extractVariant } from './extract-variant.js'; + +import type { ParserOptions } from 'prettier'; +import type { AstNode, StrictPolymorphicNode } from '../slang-nodes/types.d.ts'; +import type { CollectedMetadata, SlangAstNode } from '../types.d.ts'; + +type Constructor = new (...args: any) => T; +type ConstructorsFromInstances = U extends any ? Constructor : never; + +export function createNonterminalVariantCreator< + T extends StrictPolymorphicNode, + U extends Extract +>( + keys: { name: string }[], + constructors: ConstructorsFromInstances[], + keysWithVariants?: { name: string }[], + constructorsWithVariants?: ConstructorsFromInstances[] +) { + const variantConstructors = new Map( + keys.map((key, index) => [key.name, constructors[index]]) + ); + + if ( + keysWithVariants === undefined || + constructorsWithVariants === undefined + ) { + return ( + variant: U['variant'], + collected: CollectedMetadata, + options?: ParserOptions + ): T['variant'] => { + const constructor = variantConstructors.get(variant.constructor.name); + if (constructor !== undefined) + return new constructor(variant, collected, options); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); + }; + } + + const variantWithVariantsConstructors = new Map< + string, + (typeof constructorsWithVariants)[number] + >( + keysWithVariants.map((key, index) => [ + key.name, + constructorsWithVariants[index] + ]) + ); + + return ( + variant: U['variant'] | StrictPolymorphicNode, + collected: CollectedMetadata, + options?: ParserOptions + ): T['variant'] => { + let constructor: + | ConstructorsFromInstances + | undefined = variantConstructors.get(variant.constructor.name); + if (constructor !== undefined) + return new constructor(variant, collected, options); + + constructor = variantWithVariantsConstructors.get(variant.constructor.name); + if (constructor !== undefined) + return extractVariant(new constructor(variant, collected, options)); + + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); + }; +} From 93216aeb28d0c0b210c4a5c3aec40f248658a92a Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 12 Feb 2026 02:24:32 -0300 Subject: [PATCH 04/22] key, value pair in the same array --- src/slang-nodes/ArgumentsDeclaration.ts | 8 +- src/slang-nodes/ContractMember.ts | 47 ++++------- src/slang-nodes/ContractSpecifier.ts | 8 +- src/slang-nodes/Expression.ts | 81 +++++++------------ src/slang-nodes/FallbackFunctionAttribute.ts | 8 +- src/slang-nodes/ForStatementInitialization.ts | 17 ++-- src/slang-nodes/FunctionAttribute.ts | 8 +- src/slang-nodes/ImportClause.ts | 9 ++- src/slang-nodes/MappingKeyType.ts | 6 +- src/slang-nodes/Pragma.ts | 9 ++- src/slang-nodes/ReceiveFunctionAttribute.ts | 8 +- src/slang-nodes/SourceUnitMember.ts | 47 ++++------- src/slang-nodes/Statement.ts | 56 +++++-------- src/slang-nodes/StringExpression.ts | 23 ++---- src/slang-nodes/TupleMember.ts | 8 +- src/slang-nodes/TypeName.ts | 11 ++- src/slang-nodes/UsingClause.ts | 8 +- src/slang-nodes/VersionExpression.ts | 5 +- src/slang-nodes/YulExpression.ts | 9 ++- src/slang-nodes/YulLiteral.ts | 5 +- src/slang-nodes/YulStatement.ts | 38 +++------ src/slang-nodes/YulSwitchCase.ts | 5 +- .../create-nonterminal-variant-creator.ts | 27 +++---- 23 files changed, 175 insertions(+), 276 deletions(-) diff --git a/src/slang-nodes/ArgumentsDeclaration.ts b/src/slang-nodes/ArgumentsDeclaration.ts index 3f76cc1cf..68dba5c4f 100644 --- a/src/slang-nodes/ArgumentsDeclaration.ts +++ b/src/slang-nodes/ArgumentsDeclaration.ts @@ -12,10 +12,10 @@ import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< ArgumentsDeclaration, ast.ArgumentsDeclaration ->( - [ast.PositionalArgumentsDeclaration, ast.NamedArgumentsDeclaration], - [PositionalArgumentsDeclaration, NamedArgumentsDeclaration] -); +>([ + [ast.PositionalArgumentsDeclaration, PositionalArgumentsDeclaration], + [ast.NamedArgumentsDeclaration, NamedArgumentsDeclaration] +]); export class ArgumentsDeclaration extends SlangNode { readonly kind = NonterminalKind.ArgumentsDeclaration; diff --git a/src/slang-nodes/ContractMember.ts b/src/slang-nodes/ContractMember.ts index 402e56fc3..e19e545c9 100644 --- a/src/slang-nodes/ContractMember.ts +++ b/src/slang-nodes/ContractMember.ts @@ -23,38 +23,21 @@ import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< ContractMember, ast.ContractMember ->( - [ - ast.UsingDirective, - ast.FunctionDefinition, - ast.ConstructorDefinition, - ast.ReceiveFunctionDefinition, - ast.FallbackFunctionDefinition, - ast.UnnamedFunctionDefinition, - ast.ModifierDefinition, - ast.StructDefinition, - ast.EnumDefinition, - ast.EventDefinition, - ast.StateVariableDefinition, - ast.ErrorDefinition, - ast.UserDefinedValueTypeDefinition - ], - [ - UsingDirective, - FunctionDefinition, - ConstructorDefinition, - ReceiveFunctionDefinition, - FallbackFunctionDefinition, - UnnamedFunctionDefinition, - ModifierDefinition, - StructDefinition, - EnumDefinition, - EventDefinition, - StateVariableDefinition, - ErrorDefinition, - UserDefinedValueTypeDefinition - ] -); +>([ + [ast.UsingDirective, UsingDirective], + [ast.FunctionDefinition, FunctionDefinition], + [ast.ConstructorDefinition, ConstructorDefinition], + [ast.ReceiveFunctionDefinition, ReceiveFunctionDefinition], + [ast.FallbackFunctionDefinition, FallbackFunctionDefinition], + [ast.UnnamedFunctionDefinition, UnnamedFunctionDefinition], + [ast.ModifierDefinition, ModifierDefinition], + [ast.StructDefinition, StructDefinition], + [ast.EnumDefinition, EnumDefinition], + [ast.EventDefinition, EventDefinition], + [ast.StateVariableDefinition, StateVariableDefinition], + [ast.ErrorDefinition, ErrorDefinition], + [ast.UserDefinedValueTypeDefinition, UserDefinedValueTypeDefinition] +]); export class ContractMember extends SlangNode { readonly kind = NonterminalKind.ContractMember; diff --git a/src/slang-nodes/ContractSpecifier.ts b/src/slang-nodes/ContractSpecifier.ts index 9c7cb2146..0da594a97 100644 --- a/src/slang-nodes/ContractSpecifier.ts +++ b/src/slang-nodes/ContractSpecifier.ts @@ -12,10 +12,10 @@ import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< ContractSpecifier, ast.ContractSpecifier ->( - [ast.InheritanceSpecifier, ast.StorageLayoutSpecifier], - [InheritanceSpecifier, StorageLayoutSpecifier] -); +>([ + [ast.InheritanceSpecifier, InheritanceSpecifier], + [ast.StorageLayoutSpecifier, StorageLayoutSpecifier] +]); export class ContractSpecifier extends SlangNode { readonly kind = NonterminalKind.ContractSpecifier; diff --git a/src/slang-nodes/Expression.ts b/src/slang-nodes/Expression.ts index d21d9312b..f8b48599d 100644 --- a/src/slang-nodes/Expression.ts +++ b/src/slang-nodes/Expression.ts @@ -43,61 +43,36 @@ const createNonterminalVariant = createNonterminalVariantCreator< ast.Expression >( [ - ast.AssignmentExpression, - ast.ConditionalExpression, - ast.OrExpression, - ast.AndExpression, - ast.EqualityExpression, - ast.InequalityExpression, - ast.BitwiseOrExpression, - ast.BitwiseXorExpression, - ast.BitwiseAndExpression, - ast.ShiftExpression, - ast.AdditiveExpression, - ast.MultiplicativeExpression, - ast.ExponentiationExpression, - ast.PostfixExpression, - ast.PrefixExpression, - ast.FunctionCallExpression, - ast.CallOptionsExpression, - ast.MemberAccessExpression, - ast.IndexAccessExpression, - ast.NewExpression, - ast.TupleExpression, - ast.TypeExpression, - ast.ArrayExpression, - ast.HexNumberExpression, - ast.DecimalNumberExpression + [ast.AssignmentExpression, AssignmentExpression], + [ast.ConditionalExpression, ConditionalExpression], + [ast.OrExpression, OrExpression], + [ast.AndExpression, AndExpression], + [ast.EqualityExpression, EqualityExpression], + [ast.InequalityExpression, InequalityExpression], + [ast.BitwiseOrExpression, BitwiseOrExpression], + [ast.BitwiseXorExpression, BitwiseXorExpression], + [ast.BitwiseAndExpression, BitwiseAndExpression], + [ast.ShiftExpression, ShiftExpression], + [ast.AdditiveExpression, AdditiveExpression], + [ast.MultiplicativeExpression, MultiplicativeExpression], + [ast.ExponentiationExpression, ExponentiationExpression], + [ast.PostfixExpression, PostfixExpression], + [ast.PrefixExpression, PrefixExpression], + [ast.FunctionCallExpression, FunctionCallExpression], + [ast.CallOptionsExpression, CallOptionsExpression], + [ast.MemberAccessExpression, MemberAccessExpression], + [ast.IndexAccessExpression, IndexAccessExpression], + [ast.NewExpression, NewExpression], + [ast.TupleExpression, TupleExpression], + [ast.TypeExpression, TypeExpression], + [ast.ArrayExpression, ArrayExpression], + [ast.HexNumberExpression, HexNumberExpression], + [ast.DecimalNumberExpression, DecimalNumberExpression] ], [ - AssignmentExpression, - ConditionalExpression, - OrExpression, - AndExpression, - EqualityExpression, - InequalityExpression, - BitwiseOrExpression, - BitwiseXorExpression, - BitwiseAndExpression, - ShiftExpression, - AdditiveExpression, - MultiplicativeExpression, - ExponentiationExpression, - PostfixExpression, - PrefixExpression, - FunctionCallExpression, - CallOptionsExpression, - MemberAccessExpression, - IndexAccessExpression, - NewExpression, - TupleExpression, - TypeExpression, - ArrayExpression, - HexNumberExpression, - DecimalNumberExpression - ], - [ast.StringExpression, ast.ElementaryType], - [StringExpression, ElementaryType] + [ast.StringExpression, StringExpression], + [ast.ElementaryType, ElementaryType] + ] ); export class Expression extends SlangNode { diff --git a/src/slang-nodes/FallbackFunctionAttribute.ts b/src/slang-nodes/FallbackFunctionAttribute.ts index a875d920b..d81750696 100644 --- a/src/slang-nodes/FallbackFunctionAttribute.ts +++ b/src/slang-nodes/FallbackFunctionAttribute.ts @@ -16,10 +16,10 @@ import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< FallbackFunctionAttribute, ast.FallbackFunctionAttribute ->( - [ast.ModifierInvocation, ast.OverrideSpecifier], - [ModifierInvocation, OverrideSpecifier] -); +>([ + [ast.ModifierInvocation, ModifierInvocation], + [ast.OverrideSpecifier, OverrideSpecifier] +]); export class FallbackFunctionAttribute extends SlangNode { readonly kind = NonterminalKind.FallbackFunctionAttribute; diff --git a/src/slang-nodes/ForStatementInitialization.ts b/src/slang-nodes/ForStatementInitialization.ts index 246b0befc..81cbc24d4 100644 --- a/src/slang-nodes/ForStatementInitialization.ts +++ b/src/slang-nodes/ForStatementInitialization.ts @@ -17,18 +17,11 @@ import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< ForStatementInitialization, ast.ForStatementInitialization ->( - [ - ast.ExpressionStatement, - ast.VariableDeclarationStatement, - ast.TupleDeconstructionStatement - ], - [ - ExpressionStatement, - VariableDeclarationStatement, - TupleDeconstructionStatement - ] -); +>([ + [ast.ExpressionStatement, ExpressionStatement], + [ast.VariableDeclarationStatement, VariableDeclarationStatement], + [ast.TupleDeconstructionStatement, TupleDeconstructionStatement] +]); export class ForStatementInitialization extends SlangNode { readonly kind = NonterminalKind.ForStatementInitialization; diff --git a/src/slang-nodes/FunctionAttribute.ts b/src/slang-nodes/FunctionAttribute.ts index 249d721ce..bf6f3f1a5 100644 --- a/src/slang-nodes/FunctionAttribute.ts +++ b/src/slang-nodes/FunctionAttribute.ts @@ -16,10 +16,10 @@ import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< FunctionAttribute, ast.FunctionAttribute ->( - [ast.ModifierInvocation, ast.OverrideSpecifier], - [ModifierInvocation, OverrideSpecifier] -); +>([ + [ast.ModifierInvocation, ModifierInvocation], + [ast.OverrideSpecifier, OverrideSpecifier] +]); export class FunctionAttribute extends SlangNode { readonly kind = NonterminalKind.FunctionAttribute; diff --git a/src/slang-nodes/ImportClause.ts b/src/slang-nodes/ImportClause.ts index a090a6076..058fe41de 100644 --- a/src/slang-nodes/ImportClause.ts +++ b/src/slang-nodes/ImportClause.ts @@ -13,10 +13,11 @@ import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< ImportClause, ast.ImportClause ->( - [ast.PathImport, ast.NamedImport, ast.ImportDeconstruction], - [PathImport, NamedImport, ImportDeconstruction] -); +>([ + [ast.PathImport, PathImport], + [ast.NamedImport, NamedImport], + [ast.ImportDeconstruction, ImportDeconstruction] +]); export class ImportClause extends SlangNode { readonly kind = NonterminalKind.ImportClause; diff --git a/src/slang-nodes/MappingKeyType.ts b/src/slang-nodes/MappingKeyType.ts index e753184ef..2201d3b0d 100644 --- a/src/slang-nodes/MappingKeyType.ts +++ b/src/slang-nodes/MappingKeyType.ts @@ -11,10 +11,8 @@ const createNonterminalVariant = createNonterminalVariantCreator< MappingKeyType, ast.MappingKeyType >( - [ast.IdentifierPath], - [IdentifierPath], - [ast.ElementaryType], - [ElementaryType] + [[ast.IdentifierPath, IdentifierPath]], + [[ast.ElementaryType, ElementaryType]] ); export class MappingKeyType extends SlangNode { diff --git a/src/slang-nodes/Pragma.ts b/src/slang-nodes/Pragma.ts index 834312d15..e2258512c 100644 --- a/src/slang-nodes/Pragma.ts +++ b/src/slang-nodes/Pragma.ts @@ -13,10 +13,11 @@ import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< Pragma, ast.Pragma ->( - [ast.AbicoderPragma, ast.ExperimentalPragma, ast.VersionPragma], - [AbicoderPragma, ExperimentalPragma, VersionPragma] -); +>([ + [ast.AbicoderPragma, AbicoderPragma], + [ast.ExperimentalPragma, ExperimentalPragma], + [ast.VersionPragma, VersionPragma] +]); export class Pragma extends SlangNode { readonly kind = NonterminalKind.Pragma; diff --git a/src/slang-nodes/ReceiveFunctionAttribute.ts b/src/slang-nodes/ReceiveFunctionAttribute.ts index 2aba6cbc5..c69ecdc53 100644 --- a/src/slang-nodes/ReceiveFunctionAttribute.ts +++ b/src/slang-nodes/ReceiveFunctionAttribute.ts @@ -16,10 +16,10 @@ import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< ReceiveFunctionAttribute, ast.ReceiveFunctionAttribute ->( - [ast.ModifierInvocation, ast.OverrideSpecifier], - [ModifierInvocation, OverrideSpecifier] -); +>([ + [ast.ModifierInvocation, ModifierInvocation], + [ast.OverrideSpecifier, OverrideSpecifier] +]); export class ReceiveFunctionAttribute extends SlangNode { readonly kind = NonterminalKind.ReceiveFunctionAttribute; diff --git a/src/slang-nodes/SourceUnitMember.ts b/src/slang-nodes/SourceUnitMember.ts index c745b75ad..3742debf8 100644 --- a/src/slang-nodes/SourceUnitMember.ts +++ b/src/slang-nodes/SourceUnitMember.ts @@ -23,38 +23,21 @@ import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< SourceUnitMember, ast.SourceUnitMember ->( - [ - ast.PragmaDirective, - ast.ImportDirective, - ast.ContractDefinition, - ast.InterfaceDefinition, - ast.LibraryDefinition, - ast.StructDefinition, - ast.EnumDefinition, - ast.FunctionDefinition, - ast.ConstantDefinition, - ast.ErrorDefinition, - ast.UserDefinedValueTypeDefinition, - ast.UsingDirective, - ast.EventDefinition - ], - [ - PragmaDirective, - ImportDirective, - ContractDefinition, - InterfaceDefinition, - LibraryDefinition, - StructDefinition, - EnumDefinition, - FunctionDefinition, - ConstantDefinition, - ErrorDefinition, - UserDefinedValueTypeDefinition, - UsingDirective, - EventDefinition - ] -); +>([ + [ast.PragmaDirective, PragmaDirective], + [ast.ImportDirective, ImportDirective], + [ast.ContractDefinition, ContractDefinition], + [ast.InterfaceDefinition, InterfaceDefinition], + [ast.LibraryDefinition, LibraryDefinition], + [ast.StructDefinition, StructDefinition], + [ast.EnumDefinition, EnumDefinition], + [ast.FunctionDefinition, FunctionDefinition], + [ast.ConstantDefinition, ConstantDefinition], + [ast.ErrorDefinition, ErrorDefinition], + [ast.UserDefinedValueTypeDefinition, UserDefinedValueTypeDefinition], + [ast.UsingDirective, UsingDirective], + [ast.EventDefinition, EventDefinition] +]); export class SourceUnitMember extends SlangNode { readonly kind = NonterminalKind.SourceUnitMember; diff --git a/src/slang-nodes/Statement.ts b/src/slang-nodes/Statement.ts index 1aad6ef7a..c5c01deff 100644 --- a/src/slang-nodes/Statement.ts +++ b/src/slang-nodes/Statement.ts @@ -27,44 +27,24 @@ import type { AstNode } from './types.d.ts'; const createNonterminalVariantInternal = createNonterminalVariantCreator< Statement, ast.Statement ->( - [ - ast.ExpressionStatement, - ast.VariableDeclarationStatement, - ast.TupleDeconstructionStatement, - ast.IfStatement, - ast.ForStatement, - ast.WhileStatement, - ast.DoWhileStatement, - ast.ContinueStatement, - ast.BreakStatement, - ast.ReturnStatement, - ast.ThrowStatement, - ast.EmitStatement, - ast.TryStatement, - ast.RevertStatement, - ast.AssemblyStatement, - ast.UncheckedBlock - ], - [ - ExpressionStatement, - VariableDeclarationStatement, - TupleDeconstructionStatement, - IfStatement, - ForStatement, - WhileStatement, - DoWhileStatement, - ContinueStatement, - BreakStatement, - ReturnStatement, - ThrowStatement, - EmitStatement, - TryStatement, - RevertStatement, - AssemblyStatement, - UncheckedBlock - ] -); +>([ + [ast.ExpressionStatement, ExpressionStatement], + [ast.VariableDeclarationStatement, VariableDeclarationStatement], + [ast.TupleDeconstructionStatement, TupleDeconstructionStatement], + [ast.IfStatement, IfStatement], + [ast.ForStatement, ForStatement], + [ast.WhileStatement, WhileStatement], + [ast.DoWhileStatement, DoWhileStatement], + [ast.ContinueStatement, ContinueStatement], + [ast.BreakStatement, BreakStatement], + [ast.ReturnStatement, ReturnStatement], + [ast.ThrowStatement, ThrowStatement], + [ast.EmitStatement, EmitStatement], + [ast.TryStatement, TryStatement], + [ast.RevertStatement, RevertStatement], + [ast.AssemblyStatement, AssemblyStatement], + [ast.UncheckedBlock, UncheckedBlock] +]); function createNonterminalVariant( variant: ast.Statement['variant'], diff --git a/src/slang-nodes/StringExpression.ts b/src/slang-nodes/StringExpression.ts index 849706a0e..be35e4da3 100644 --- a/src/slang-nodes/StringExpression.ts +++ b/src/slang-nodes/StringExpression.ts @@ -15,22 +15,13 @@ import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< StringExpression, ast.StringExpression ->( - [ - ast.StringLiteral, - ast.StringLiterals, - ast.HexStringLiteral, - ast.HexStringLiterals, - ast.UnicodeStringLiterals - ], - [ - StringLiteral, - StringLiterals, - HexStringLiteral, - HexStringLiterals, - UnicodeStringLiterals - ] -); +>([ + [ast.StringLiteral, StringLiteral], + [ast.StringLiterals, StringLiterals], + [ast.HexStringLiteral, HexStringLiteral], + [ast.HexStringLiterals, HexStringLiterals], + [ast.UnicodeStringLiterals, UnicodeStringLiterals] +]); export class StringExpression extends SlangNode { readonly kind = NonterminalKind.StringExpression; diff --git a/src/slang-nodes/TupleMember.ts b/src/slang-nodes/TupleMember.ts index bae5249b2..5ee081474 100644 --- a/src/slang-nodes/TupleMember.ts +++ b/src/slang-nodes/TupleMember.ts @@ -12,10 +12,10 @@ import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< TupleMember, ast.TupleMember ->( - [ast.TypedTupleMember, ast.UntypedTupleMember], - [TypedTupleMember, UntypedTupleMember] -); +>([ + [ast.TypedTupleMember, TypedTupleMember], + [ast.UntypedTupleMember, UntypedTupleMember] +]); export class TupleMember extends SlangNode { readonly kind = NonterminalKind.TupleMember; diff --git a/src/slang-nodes/TypeName.ts b/src/slang-nodes/TypeName.ts index b6bcd562a..af1edafbf 100644 --- a/src/slang-nodes/TypeName.ts +++ b/src/slang-nodes/TypeName.ts @@ -16,10 +16,13 @@ const createNonterminalVariant = createNonterminalVariantCreator< TypeName, ast.TypeName >( - [ast.ArrayTypeName, ast.FunctionType, ast.MappingType, ast.IdentifierPath], - [ArrayTypeName, FunctionType, MappingType, IdentifierPath], - [ast.ElementaryType], - [ElementaryType] + [ + [ast.ArrayTypeName, ArrayTypeName], + [ast.FunctionType, FunctionType], + [ast.MappingType, MappingType], + [ast.IdentifierPath, IdentifierPath] + ], + [[ast.ElementaryType, ElementaryType]] ); export class TypeName extends SlangNode { diff --git a/src/slang-nodes/UsingClause.ts b/src/slang-nodes/UsingClause.ts index c8e0849c1..252a822b6 100644 --- a/src/slang-nodes/UsingClause.ts +++ b/src/slang-nodes/UsingClause.ts @@ -10,10 +10,10 @@ import type { CollectedMetadata } from '../types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< UsingClause, ast.UsingClause ->( - [ast.IdentifierPath, ast.UsingDeconstruction], - [IdentifierPath, UsingDeconstruction] -); +>([ + [ast.IdentifierPath, IdentifierPath], + [ast.UsingDeconstruction, UsingDeconstruction] +]); export class UsingClause extends SlangNode { readonly kind = NonterminalKind.UsingClause; diff --git a/src/slang-nodes/VersionExpression.ts b/src/slang-nodes/VersionExpression.ts index 538e787f6..ffeaa76cb 100644 --- a/src/slang-nodes/VersionExpression.ts +++ b/src/slang-nodes/VersionExpression.ts @@ -10,7 +10,10 @@ import type { CollectedMetadata } from '../types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< VersionExpression, ast.VersionExpression ->([ast.VersionRange, ast.VersionTerm], [VersionRange, VersionTerm]); +>([ + [ast.VersionRange, VersionRange], + [ast.VersionTerm, VersionTerm] +]); export class VersionExpression extends SlangNode { readonly kind = NonterminalKind.VersionExpression; diff --git a/src/slang-nodes/YulExpression.ts b/src/slang-nodes/YulExpression.ts index a4f25ad85..323568b96 100644 --- a/src/slang-nodes/YulExpression.ts +++ b/src/slang-nodes/YulExpression.ts @@ -14,10 +14,11 @@ const createNonterminalVariant = createNonterminalVariantCreator< YulExpression, ast.YulExpression >( - [ast.YulFunctionCallExpression, ast.YulPath], - [YulFunctionCallExpression, YulPath], - [ast.YulLiteral], - [YulLiteral] + [ + [ast.YulFunctionCallExpression, YulFunctionCallExpression], + [ast.YulPath, YulPath] + ], + [[ast.YulLiteral, YulLiteral]] ); export class YulExpression extends SlangNode { diff --git a/src/slang-nodes/YulLiteral.ts b/src/slang-nodes/YulLiteral.ts index 8fbe6b34a..e048c74b5 100644 --- a/src/slang-nodes/YulLiteral.ts +++ b/src/slang-nodes/YulLiteral.ts @@ -16,7 +16,10 @@ import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< YulLiteral, ast.YulLiteral ->([ast.HexStringLiteral, ast.StringLiteral], [HexStringLiteral, StringLiteral]); +>([ + [ast.HexStringLiteral, HexStringLiteral], + [ast.StringLiteral, StringLiteral] +]); export class YulLiteral extends SlangNode { readonly kind = NonterminalKind.YulLiteral; diff --git a/src/slang-nodes/YulStatement.ts b/src/slang-nodes/YulStatement.ts index 672d5664c..3a4f0b3d0 100644 --- a/src/slang-nodes/YulStatement.ts +++ b/src/slang-nodes/YulStatement.ts @@ -25,33 +25,19 @@ const createNonterminalVariantInternal = createNonterminalVariantCreator< ast.YulStatement >( [ - ast.YulFunctionDefinition, - ast.YulVariableDeclarationStatement, - ast.YulVariableAssignmentStatement, - ast.YulStackAssignmentStatement, - ast.YulIfStatement, - ast.YulForStatement, - ast.YulSwitchStatement, - ast.YulLeaveStatement, - ast.YulBreakStatement, - ast.YulContinueStatement, - ast.YulLabel + [ast.YulFunctionDefinition, YulFunctionDefinition], + [ast.YulVariableDeclarationStatement, YulVariableDeclarationStatement], + [ast.YulVariableAssignmentStatement, YulVariableAssignmentStatement], + [ast.YulStackAssignmentStatement, YulStackAssignmentStatement], + [ast.YulIfStatement, YulIfStatement], + [ast.YulForStatement, YulForStatement], + [ast.YulSwitchStatement, YulSwitchStatement], + [ast.YulLeaveStatement, YulLeaveStatement], + [ast.YulBreakStatement, YulBreakStatement], + [ast.YulContinueStatement, YulContinueStatement], + [ast.YulLabel, YulLabel] ], - [ - YulFunctionDefinition, - YulVariableDeclarationStatement, - YulVariableAssignmentStatement, - YulStackAssignmentStatement, - YulIfStatement, - YulForStatement, - YulSwitchStatement, - YulLeaveStatement, - YulBreakStatement, - YulContinueStatement, - YulLabel - ], - [ast.YulExpression], - [YulExpression] + [[ast.YulExpression, YulExpression]] ); function createNonterminalVariant( diff --git a/src/slang-nodes/YulSwitchCase.ts b/src/slang-nodes/YulSwitchCase.ts index f199609e0..c976cefe3 100644 --- a/src/slang-nodes/YulSwitchCase.ts +++ b/src/slang-nodes/YulSwitchCase.ts @@ -12,7 +12,10 @@ import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< YulSwitchCase, ast.YulSwitchCase ->([ast.YulDefaultCase, ast.YulValueCase], [YulDefaultCase, YulValueCase]); +>([ + [ast.YulDefaultCase, YulDefaultCase], + [ast.YulValueCase, YulValueCase] +]); export class YulSwitchCase extends SlangNode { readonly kind = NonterminalKind.YulSwitchCase; diff --git a/src/slang-utils/create-nonterminal-variant-creator.ts b/src/slang-utils/create-nonterminal-variant-creator.ts index 2164841ab..6c530e0ad 100644 --- a/src/slang-utils/create-nonterminal-variant-creator.ts +++ b/src/slang-utils/create-nonterminal-variant-creator.ts @@ -12,19 +12,17 @@ export function createNonterminalVariantCreator< T extends StrictPolymorphicNode, U extends Extract >( - keys: { name: string }[], - constructors: ConstructorsFromInstances[], - keysWithVariants?: { name: string }[], - constructorsWithVariants?: ConstructorsFromInstances[] + constructors: [{ name: string }, ConstructorsFromInstances][], + constructorsWithVariants?: [ + { name: string }, + ConstructorsFromInstances + ][] ) { - const variantConstructors = new Map( - keys.map((key, index) => [key.name, constructors[index]]) + const variantConstructors = new Map( + constructors.map(([key, constructor]) => [key.name, constructor]) ); - if ( - keysWithVariants === undefined || - constructorsWithVariants === undefined - ) { + if (constructorsWithVariants === undefined) { return ( variant: U['variant'], collected: CollectedMetadata, @@ -38,13 +36,10 @@ export function createNonterminalVariantCreator< }; } - const variantWithVariantsConstructors = new Map< - string, - (typeof constructorsWithVariants)[number] - >( - keysWithVariants.map((key, index) => [ + const variantWithVariantsConstructors = new Map( + constructorsWithVariants.map(([key, constructor]) => [ key.name, - constructorsWithVariants[index] + constructor ]) ); From 605032498d2ff925602eaffbe4ec4300640b6801 Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 12 Feb 2026 10:51:51 -0300 Subject: [PATCH 05/22] we don't need to store a string as a key anymore, we can directly use the constructor from the Slang object --- .../create-nonterminal-variant-creator.ts | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/slang-utils/create-nonterminal-variant-creator.ts b/src/slang-utils/create-nonterminal-variant-creator.ts index 6c530e0ad..33d7dd90e 100644 --- a/src/slang-utils/create-nonterminal-variant-creator.ts +++ b/src/slang-utils/create-nonterminal-variant-creator.ts @@ -2,25 +2,33 @@ import { extractVariant } from './extract-variant.js'; import type { ParserOptions } from 'prettier'; -import type { AstNode, StrictPolymorphicNode } from '../slang-nodes/types.d.ts'; +import type { + AstNode, + StrictAstNode, + StrictPolymorphicNode +} from '../slang-nodes/types.d.ts'; import type { CollectedMetadata, SlangAstNode } from '../types.d.ts'; -type Constructor = new (...args: any) => T; +type Constructor = new (...args: any) => T; type ConstructorsFromInstances = U extends any ? Constructor : never; +type TypeofFromInstances = U extends any + ? { prototype: unknown; name: string } + : never; export function createNonterminalVariantCreator< T extends StrictPolymorphicNode, U extends Extract >( - constructors: [{ name: string }, ConstructorsFromInstances][], + constructors: [ + TypeofFromInstances, + ConstructorsFromInstances + ][], constructorsWithVariants?: [ - { name: string }, + TypeofFromInstances>, ConstructorsFromInstances ][] ) { - const variantConstructors = new Map( - constructors.map(([key, constructor]) => [key.name, constructor]) - ); + const variantConstructors = new Map(constructors); if (constructorsWithVariants === undefined) { return ( @@ -28,7 +36,7 @@ export function createNonterminalVariantCreator< collected: CollectedMetadata, options?: ParserOptions ): T['variant'] => { - const constructor = variantConstructors.get(variant.constructor.name); + const constructor = variantConstructors.get(variant.constructor); if (constructor !== undefined) return new constructor(variant, collected, options); @@ -36,12 +44,7 @@ export function createNonterminalVariantCreator< }; } - const variantWithVariantsConstructors = new Map( - constructorsWithVariants.map(([key, constructor]) => [ - key.name, - constructor - ]) - ); + const variantWithVariantsConstructors = new Map(constructorsWithVariants); return ( variant: U['variant'] | StrictPolymorphicNode, @@ -50,11 +53,11 @@ export function createNonterminalVariantCreator< ): T['variant'] => { let constructor: | ConstructorsFromInstances - | undefined = variantConstructors.get(variant.constructor.name); + | undefined = variantConstructors.get(variant.constructor); if (constructor !== undefined) return new constructor(variant, collected, options); - constructor = variantWithVariantsConstructors.get(variant.constructor.name); + constructor = variantWithVariantsConstructors.get(variant.constructor); if (constructor !== undefined) return extractVariant(new constructor(variant, collected, options)); From 5fb04f129d966f175651034aeaa33581e5b3ff37 Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 12 Feb 2026 11:20:01 -0300 Subject: [PATCH 06/22] cleaner types --- src/slang-utils/create-nonterminal-variant-creator.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/slang-utils/create-nonterminal-variant-creator.ts b/src/slang-utils/create-nonterminal-variant-creator.ts index 33d7dd90e..26108f777 100644 --- a/src/slang-utils/create-nonterminal-variant-creator.ts +++ b/src/slang-utils/create-nonterminal-variant-creator.ts @@ -11,20 +11,21 @@ import type { CollectedMetadata, SlangAstNode } from '../types.d.ts'; type Constructor = new (...args: any) => T; type ConstructorsFromInstances = U extends any ? Constructor : never; -type TypeofFromInstances = U extends any +type GenericFunction = U extends any ? { prototype: unknown; name: string } : never; +type SlangPolymorphicNode = Extract; export function createNonterminalVariantCreator< T extends StrictPolymorphicNode, - U extends Extract + U extends SlangPolymorphicNode >( constructors: [ - TypeofFromInstances, + GenericFunction, ConstructorsFromInstances ][], constructorsWithVariants?: [ - TypeofFromInstances>, + GenericFunction, ConstructorsFromInstances ][] ) { @@ -47,7 +48,7 @@ export function createNonterminalVariantCreator< const variantWithVariantsConstructors = new Map(constructorsWithVariants); return ( - variant: U['variant'] | StrictPolymorphicNode, + variant: U['variant'] | SlangPolymorphicNode, collected: CollectedMetadata, options?: ParserOptions ): T['variant'] => { From 6df8766626ee1286291112ab935486910bf351b7 Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 12 Feb 2026 11:26:47 -0300 Subject: [PATCH 07/22] reversing the order of the parameter types to match the key, value order in the Map --- src/slang-nodes/ArgumentsDeclaration.ts | 4 ++-- src/slang-nodes/ContractMember.ts | 4 ++-- src/slang-nodes/ContractSpecifier.ts | 4 ++-- src/slang-nodes/Expression.ts | 4 ++-- src/slang-nodes/FallbackFunctionAttribute.ts | 4 ++-- src/slang-nodes/ForStatementInitialization.ts | 4 ++-- src/slang-nodes/FunctionAttribute.ts | 4 ++-- src/slang-nodes/ImportClause.ts | 4 ++-- src/slang-nodes/MappingKeyType.ts | 4 ++-- src/slang-nodes/Pragma.ts | 4 ++-- src/slang-nodes/ReceiveFunctionAttribute.ts | 4 ++-- src/slang-nodes/SourceUnitMember.ts | 4 ++-- src/slang-nodes/Statement.ts | 4 ++-- src/slang-nodes/StringExpression.ts | 4 ++-- src/slang-nodes/TupleMember.ts | 4 ++-- src/slang-nodes/TypeName.ts | 4 ++-- src/slang-nodes/UsingClause.ts | 4 ++-- src/slang-nodes/VersionExpression.ts | 4 ++-- src/slang-nodes/YulExpression.ts | 4 ++-- src/slang-nodes/YulLiteral.ts | 4 ++-- src/slang-nodes/YulStatement.ts | 4 ++-- src/slang-nodes/YulSwitchCase.ts | 4 ++-- src/slang-utils/create-nonterminal-variant-creator.ts | 4 ++-- 23 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/slang-nodes/ArgumentsDeclaration.ts b/src/slang-nodes/ArgumentsDeclaration.ts index 68dba5c4f..30fc2c7ad 100644 --- a/src/slang-nodes/ArgumentsDeclaration.ts +++ b/src/slang-nodes/ArgumentsDeclaration.ts @@ -10,8 +10,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - ArgumentsDeclaration, - ast.ArgumentsDeclaration + ast.ArgumentsDeclaration, + ArgumentsDeclaration >([ [ast.PositionalArgumentsDeclaration, PositionalArgumentsDeclaration], [ast.NamedArgumentsDeclaration, NamedArgumentsDeclaration] diff --git a/src/slang-nodes/ContractMember.ts b/src/slang-nodes/ContractMember.ts index e19e545c9..b3cdbf513 100644 --- a/src/slang-nodes/ContractMember.ts +++ b/src/slang-nodes/ContractMember.ts @@ -21,8 +21,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - ContractMember, - ast.ContractMember + ast.ContractMember, + ContractMember >([ [ast.UsingDirective, UsingDirective], [ast.FunctionDefinition, FunctionDefinition], diff --git a/src/slang-nodes/ContractSpecifier.ts b/src/slang-nodes/ContractSpecifier.ts index 0da594a97..4b83a52fe 100644 --- a/src/slang-nodes/ContractSpecifier.ts +++ b/src/slang-nodes/ContractSpecifier.ts @@ -10,8 +10,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - ContractSpecifier, - ast.ContractSpecifier + ast.ContractSpecifier, + ContractSpecifier >([ [ast.InheritanceSpecifier, InheritanceSpecifier], [ast.StorageLayoutSpecifier, StorageLayoutSpecifier] diff --git a/src/slang-nodes/Expression.ts b/src/slang-nodes/Expression.ts index f8b48599d..c8239b971 100644 --- a/src/slang-nodes/Expression.ts +++ b/src/slang-nodes/Expression.ts @@ -39,8 +39,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - Expression, - ast.Expression + ast.Expression, + Expression >( [ [ast.AssignmentExpression, AssignmentExpression], diff --git a/src/slang-nodes/FallbackFunctionAttribute.ts b/src/slang-nodes/FallbackFunctionAttribute.ts index d81750696..d02c03d36 100644 --- a/src/slang-nodes/FallbackFunctionAttribute.ts +++ b/src/slang-nodes/FallbackFunctionAttribute.ts @@ -14,8 +14,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - FallbackFunctionAttribute, - ast.FallbackFunctionAttribute + ast.FallbackFunctionAttribute, + FallbackFunctionAttribute >([ [ast.ModifierInvocation, ModifierInvocation], [ast.OverrideSpecifier, OverrideSpecifier] diff --git a/src/slang-nodes/ForStatementInitialization.ts b/src/slang-nodes/ForStatementInitialization.ts index 81cbc24d4..e4d670035 100644 --- a/src/slang-nodes/ForStatementInitialization.ts +++ b/src/slang-nodes/ForStatementInitialization.ts @@ -15,8 +15,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - ForStatementInitialization, - ast.ForStatementInitialization + ast.ForStatementInitialization, + ForStatementInitialization >([ [ast.ExpressionStatement, ExpressionStatement], [ast.VariableDeclarationStatement, VariableDeclarationStatement], diff --git a/src/slang-nodes/FunctionAttribute.ts b/src/slang-nodes/FunctionAttribute.ts index bf6f3f1a5..fab5c11da 100644 --- a/src/slang-nodes/FunctionAttribute.ts +++ b/src/slang-nodes/FunctionAttribute.ts @@ -14,8 +14,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - FunctionAttribute, - ast.FunctionAttribute + ast.FunctionAttribute, + FunctionAttribute >([ [ast.ModifierInvocation, ModifierInvocation], [ast.OverrideSpecifier, OverrideSpecifier] diff --git a/src/slang-nodes/ImportClause.ts b/src/slang-nodes/ImportClause.ts index 058fe41de..6675ee374 100644 --- a/src/slang-nodes/ImportClause.ts +++ b/src/slang-nodes/ImportClause.ts @@ -11,8 +11,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - ImportClause, - ast.ImportClause + ast.ImportClause, + ImportClause >([ [ast.PathImport, PathImport], [ast.NamedImport, NamedImport], diff --git a/src/slang-nodes/MappingKeyType.ts b/src/slang-nodes/MappingKeyType.ts index 2201d3b0d..523244395 100644 --- a/src/slang-nodes/MappingKeyType.ts +++ b/src/slang-nodes/MappingKeyType.ts @@ -8,8 +8,8 @@ import { IdentifierPath } from './IdentifierPath.js'; import type { CollectedMetadata } from '../types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - MappingKeyType, - ast.MappingKeyType + ast.MappingKeyType, + MappingKeyType >( [[ast.IdentifierPath, IdentifierPath]], [[ast.ElementaryType, ElementaryType]] diff --git a/src/slang-nodes/Pragma.ts b/src/slang-nodes/Pragma.ts index e2258512c..f8a1761cf 100644 --- a/src/slang-nodes/Pragma.ts +++ b/src/slang-nodes/Pragma.ts @@ -11,8 +11,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - Pragma, - ast.Pragma + ast.Pragma, + Pragma >([ [ast.AbicoderPragma, AbicoderPragma], [ast.ExperimentalPragma, ExperimentalPragma], diff --git a/src/slang-nodes/ReceiveFunctionAttribute.ts b/src/slang-nodes/ReceiveFunctionAttribute.ts index c69ecdc53..9fa6724b1 100644 --- a/src/slang-nodes/ReceiveFunctionAttribute.ts +++ b/src/slang-nodes/ReceiveFunctionAttribute.ts @@ -14,8 +14,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - ReceiveFunctionAttribute, - ast.ReceiveFunctionAttribute + ast.ReceiveFunctionAttribute, + ReceiveFunctionAttribute >([ [ast.ModifierInvocation, ModifierInvocation], [ast.OverrideSpecifier, OverrideSpecifier] diff --git a/src/slang-nodes/SourceUnitMember.ts b/src/slang-nodes/SourceUnitMember.ts index 3742debf8..08d4369f3 100644 --- a/src/slang-nodes/SourceUnitMember.ts +++ b/src/slang-nodes/SourceUnitMember.ts @@ -21,8 +21,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - SourceUnitMember, - ast.SourceUnitMember + ast.SourceUnitMember, + SourceUnitMember >([ [ast.PragmaDirective, PragmaDirective], [ast.ImportDirective, ImportDirective], diff --git a/src/slang-nodes/Statement.ts b/src/slang-nodes/Statement.ts index c5c01deff..2406656fc 100644 --- a/src/slang-nodes/Statement.ts +++ b/src/slang-nodes/Statement.ts @@ -25,8 +25,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariantInternal = createNonterminalVariantCreator< - Statement, - ast.Statement + ast.Statement, + Statement >([ [ast.ExpressionStatement, ExpressionStatement], [ast.VariableDeclarationStatement, VariableDeclarationStatement], diff --git a/src/slang-nodes/StringExpression.ts b/src/slang-nodes/StringExpression.ts index be35e4da3..4013837c0 100644 --- a/src/slang-nodes/StringExpression.ts +++ b/src/slang-nodes/StringExpression.ts @@ -13,8 +13,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - StringExpression, - ast.StringExpression + ast.StringExpression, + StringExpression >([ [ast.StringLiteral, StringLiteral], [ast.StringLiterals, StringLiterals], diff --git a/src/slang-nodes/TupleMember.ts b/src/slang-nodes/TupleMember.ts index 5ee081474..69849d93a 100644 --- a/src/slang-nodes/TupleMember.ts +++ b/src/slang-nodes/TupleMember.ts @@ -10,8 +10,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - TupleMember, - ast.TupleMember + ast.TupleMember, + TupleMember >([ [ast.TypedTupleMember, TypedTupleMember], [ast.UntypedTupleMember, UntypedTupleMember] diff --git a/src/slang-nodes/TypeName.ts b/src/slang-nodes/TypeName.ts index af1edafbf..faccff25e 100644 --- a/src/slang-nodes/TypeName.ts +++ b/src/slang-nodes/TypeName.ts @@ -13,8 +13,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - TypeName, - ast.TypeName + ast.TypeName, + TypeName >( [ [ast.ArrayTypeName, ArrayTypeName], diff --git a/src/slang-nodes/UsingClause.ts b/src/slang-nodes/UsingClause.ts index 252a822b6..2ed7ab091 100644 --- a/src/slang-nodes/UsingClause.ts +++ b/src/slang-nodes/UsingClause.ts @@ -8,8 +8,8 @@ import { UsingDeconstruction } from './UsingDeconstruction.js'; import type { CollectedMetadata } from '../types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - UsingClause, - ast.UsingClause + ast.UsingClause, + UsingClause >([ [ast.IdentifierPath, IdentifierPath], [ast.UsingDeconstruction, UsingDeconstruction] diff --git a/src/slang-nodes/VersionExpression.ts b/src/slang-nodes/VersionExpression.ts index ffeaa76cb..bd4bccdff 100644 --- a/src/slang-nodes/VersionExpression.ts +++ b/src/slang-nodes/VersionExpression.ts @@ -8,8 +8,8 @@ import { VersionTerm } from './VersionTerm.js'; import type { CollectedMetadata } from '../types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - VersionExpression, - ast.VersionExpression + ast.VersionExpression, + VersionExpression >([ [ast.VersionRange, VersionRange], [ast.VersionTerm, VersionTerm] diff --git a/src/slang-nodes/YulExpression.ts b/src/slang-nodes/YulExpression.ts index 323568b96..1019d20a6 100644 --- a/src/slang-nodes/YulExpression.ts +++ b/src/slang-nodes/YulExpression.ts @@ -11,8 +11,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - YulExpression, - ast.YulExpression + ast.YulExpression, + YulExpression >( [ [ast.YulFunctionCallExpression, YulFunctionCallExpression], diff --git a/src/slang-nodes/YulLiteral.ts b/src/slang-nodes/YulLiteral.ts index e048c74b5..8f15af1c8 100644 --- a/src/slang-nodes/YulLiteral.ts +++ b/src/slang-nodes/YulLiteral.ts @@ -14,8 +14,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - YulLiteral, - ast.YulLiteral + ast.YulLiteral, + YulLiteral >([ [ast.HexStringLiteral, HexStringLiteral], [ast.StringLiteral, StringLiteral] diff --git a/src/slang-nodes/YulStatement.ts b/src/slang-nodes/YulStatement.ts index 3a4f0b3d0..eba16f4cb 100644 --- a/src/slang-nodes/YulStatement.ts +++ b/src/slang-nodes/YulStatement.ts @@ -21,8 +21,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariantInternal = createNonterminalVariantCreator< - YulStatement, - ast.YulStatement + ast.YulStatement, + YulStatement >( [ [ast.YulFunctionDefinition, YulFunctionDefinition], diff --git a/src/slang-nodes/YulSwitchCase.ts b/src/slang-nodes/YulSwitchCase.ts index c976cefe3..8130eb39b 100644 --- a/src/slang-nodes/YulSwitchCase.ts +++ b/src/slang-nodes/YulSwitchCase.ts @@ -10,8 +10,8 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - YulSwitchCase, - ast.YulSwitchCase + ast.YulSwitchCase, + YulSwitchCase >([ [ast.YulDefaultCase, YulDefaultCase], [ast.YulValueCase, YulValueCase] diff --git a/src/slang-utils/create-nonterminal-variant-creator.ts b/src/slang-utils/create-nonterminal-variant-creator.ts index 26108f777..32331e48b 100644 --- a/src/slang-utils/create-nonterminal-variant-creator.ts +++ b/src/slang-utils/create-nonterminal-variant-creator.ts @@ -17,8 +17,8 @@ type GenericFunction = U extends any type SlangPolymorphicNode = Extract; export function createNonterminalVariantCreator< - T extends StrictPolymorphicNode, - U extends SlangPolymorphicNode + U extends SlangPolymorphicNode, + T extends StrictPolymorphicNode >( constructors: [ GenericFunction, From 112edc8ef5e5444bd5378e5bfe9e72c746e20cab Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 12 Feb 2026 12:00:59 -0300 Subject: [PATCH 08/22] separating the complex factory into 2 specific ones --- src/slang-nodes/ArgumentsDeclaration.ts | 4 +- src/slang-nodes/ContractMember.ts | 4 +- src/slang-nodes/ContractSpecifier.ts | 4 +- src/slang-nodes/FallbackFunctionAttribute.ts | 4 +- src/slang-nodes/ForStatementInitialization.ts | 4 +- src/slang-nodes/FunctionAttribute.ts | 4 +- src/slang-nodes/ImportClause.ts | 4 +- src/slang-nodes/Pragma.ts | 4 +- src/slang-nodes/ReceiveFunctionAttribute.ts | 4 +- src/slang-nodes/SourceUnitMember.ts | 4 +- src/slang-nodes/Statement.ts | 4 +- src/slang-nodes/StringExpression.ts | 4 +- src/slang-nodes/TupleMember.ts | 4 +- src/slang-nodes/UsingClause.ts | 4 +- src/slang-nodes/VersionExpression.ts | 4 +- src/slang-nodes/YulLiteral.ts | 4 +- src/slang-nodes/YulSwitchCase.ts | 4 +- .../create-nonterminal-variant-creator.ts | 70 ++++++++++++------- 18 files changed, 78 insertions(+), 60 deletions(-) diff --git a/src/slang-nodes/ArgumentsDeclaration.ts b/src/slang-nodes/ArgumentsDeclaration.ts index 30fc2c7ad..106dae3c6 100644 --- a/src/slang-nodes/ArgumentsDeclaration.ts +++ b/src/slang-nodes/ArgumentsDeclaration.ts @@ -1,6 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; +import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { PositionalArgumentsDeclaration } from './PositionalArgumentsDeclaration.js'; import { NamedArgumentsDeclaration } from './NamedArgumentsDeclaration.js'; @@ -9,7 +9,7 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const createNonterminalVariant = createNonterminalVariantCreator< +const createNonterminalVariant = createNonterminalVariantSimpleCreator< ast.ArgumentsDeclaration, ArgumentsDeclaration >([ diff --git a/src/slang-nodes/ContractMember.ts b/src/slang-nodes/ContractMember.ts index b3cdbf513..767faa39c 100644 --- a/src/slang-nodes/ContractMember.ts +++ b/src/slang-nodes/ContractMember.ts @@ -1,6 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; +import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { UsingDirective } from './UsingDirective.js'; import { FunctionDefinition } from './FunctionDefinition.js'; @@ -20,7 +20,7 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const createNonterminalVariant = createNonterminalVariantCreator< +const createNonterminalVariant = createNonterminalVariantSimpleCreator< ast.ContractMember, ContractMember >([ diff --git a/src/slang-nodes/ContractSpecifier.ts b/src/slang-nodes/ContractSpecifier.ts index 4b83a52fe..fc18129bf 100644 --- a/src/slang-nodes/ContractSpecifier.ts +++ b/src/slang-nodes/ContractSpecifier.ts @@ -1,6 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; +import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { InheritanceSpecifier } from './InheritanceSpecifier.js'; import { StorageLayoutSpecifier } from './StorageLayoutSpecifier.js'; @@ -9,7 +9,7 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const createNonterminalVariant = createNonterminalVariantCreator< +const createNonterminalVariant = createNonterminalVariantSimpleCreator< ast.ContractSpecifier, ContractSpecifier >([ diff --git a/src/slang-nodes/FallbackFunctionAttribute.ts b/src/slang-nodes/FallbackFunctionAttribute.ts index d02c03d36..f757e2427 100644 --- a/src/slang-nodes/FallbackFunctionAttribute.ts +++ b/src/slang-nodes/FallbackFunctionAttribute.ts @@ -3,7 +3,7 @@ import { NonterminalKind, TerminalNode as SlangTerminalNode } from '@nomicfoundation/slang/cst'; -import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; +import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { ModifierInvocation } from './ModifierInvocation.js'; import { OverrideSpecifier } from './OverrideSpecifier.js'; @@ -13,7 +13,7 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const createNonterminalVariant = createNonterminalVariantCreator< +const createNonterminalVariant = createNonterminalVariantSimpleCreator< ast.FallbackFunctionAttribute, FallbackFunctionAttribute >([ diff --git a/src/slang-nodes/ForStatementInitialization.ts b/src/slang-nodes/ForStatementInitialization.ts index e4d670035..84ca74ae3 100644 --- a/src/slang-nodes/ForStatementInitialization.ts +++ b/src/slang-nodes/ForStatementInitialization.ts @@ -3,7 +3,7 @@ import { NonterminalKind, TerminalNode as SlangTerminalNode } from '@nomicfoundation/slang/cst'; -import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; +import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { ExpressionStatement } from './ExpressionStatement.js'; import { VariableDeclarationStatement } from './VariableDeclarationStatement.js'; @@ -14,7 +14,7 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const createNonterminalVariant = createNonterminalVariantCreator< +const createNonterminalVariant = createNonterminalVariantSimpleCreator< ast.ForStatementInitialization, ForStatementInitialization >([ diff --git a/src/slang-nodes/FunctionAttribute.ts b/src/slang-nodes/FunctionAttribute.ts index fab5c11da..c946ca94e 100644 --- a/src/slang-nodes/FunctionAttribute.ts +++ b/src/slang-nodes/FunctionAttribute.ts @@ -3,7 +3,7 @@ import { NonterminalKind, TerminalNode as SlangTerminalNode } from '@nomicfoundation/slang/cst'; -import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; +import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { ModifierInvocation } from './ModifierInvocation.js'; import { OverrideSpecifier } from './OverrideSpecifier.js'; @@ -13,7 +13,7 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const createNonterminalVariant = createNonterminalVariantCreator< +const createNonterminalVariant = createNonterminalVariantSimpleCreator< ast.FunctionAttribute, FunctionAttribute >([ diff --git a/src/slang-nodes/ImportClause.ts b/src/slang-nodes/ImportClause.ts index 6675ee374..1421e735d 100644 --- a/src/slang-nodes/ImportClause.ts +++ b/src/slang-nodes/ImportClause.ts @@ -1,6 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; +import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { PathImport } from './PathImport.js'; import { NamedImport } from './NamedImport.js'; @@ -10,7 +10,7 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const createNonterminalVariant = createNonterminalVariantCreator< +const createNonterminalVariant = createNonterminalVariantSimpleCreator< ast.ImportClause, ImportClause >([ diff --git a/src/slang-nodes/Pragma.ts b/src/slang-nodes/Pragma.ts index f8a1761cf..86a4ece4d 100644 --- a/src/slang-nodes/Pragma.ts +++ b/src/slang-nodes/Pragma.ts @@ -1,6 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; +import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { AbicoderPragma } from './AbicoderPragma.js'; import { ExperimentalPragma } from './ExperimentalPragma.js'; @@ -10,7 +10,7 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const createNonterminalVariant = createNonterminalVariantCreator< +const createNonterminalVariant = createNonterminalVariantSimpleCreator< ast.Pragma, Pragma >([ diff --git a/src/slang-nodes/ReceiveFunctionAttribute.ts b/src/slang-nodes/ReceiveFunctionAttribute.ts index 9fa6724b1..5e91580ab 100644 --- a/src/slang-nodes/ReceiveFunctionAttribute.ts +++ b/src/slang-nodes/ReceiveFunctionAttribute.ts @@ -3,7 +3,7 @@ import { NonterminalKind, TerminalNode as SlangTerminalNode } from '@nomicfoundation/slang/cst'; -import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; +import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { ModifierInvocation } from './ModifierInvocation.js'; import { OverrideSpecifier } from './OverrideSpecifier.js'; @@ -13,7 +13,7 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const createNonterminalVariant = createNonterminalVariantCreator< +const createNonterminalVariant = createNonterminalVariantSimpleCreator< ast.ReceiveFunctionAttribute, ReceiveFunctionAttribute >([ diff --git a/src/slang-nodes/SourceUnitMember.ts b/src/slang-nodes/SourceUnitMember.ts index 08d4369f3..d545dc29d 100644 --- a/src/slang-nodes/SourceUnitMember.ts +++ b/src/slang-nodes/SourceUnitMember.ts @@ -1,6 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; +import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { PragmaDirective } from './PragmaDirective.js'; import { ImportDirective } from './ImportDirective.js'; @@ -20,7 +20,7 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const createNonterminalVariant = createNonterminalVariantCreator< +const createNonterminalVariant = createNonterminalVariantSimpleCreator< ast.SourceUnitMember, SourceUnitMember >([ diff --git a/src/slang-nodes/Statement.ts b/src/slang-nodes/Statement.ts index 2406656fc..f52b34d71 100644 --- a/src/slang-nodes/Statement.ts +++ b/src/slang-nodes/Statement.ts @@ -1,6 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; +import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { ExpressionStatement } from './ExpressionStatement.js'; import { VariableDeclarationStatement } from './VariableDeclarationStatement.js'; @@ -24,7 +24,7 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const createNonterminalVariantInternal = createNonterminalVariantCreator< +const createNonterminalVariantInternal = createNonterminalVariantSimpleCreator< ast.Statement, Statement >([ diff --git a/src/slang-nodes/StringExpression.ts b/src/slang-nodes/StringExpression.ts index 4013837c0..93913a0fa 100644 --- a/src/slang-nodes/StringExpression.ts +++ b/src/slang-nodes/StringExpression.ts @@ -1,6 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; +import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { StringLiteral } from './StringLiteral.js'; import { StringLiterals } from './StringLiterals.js'; @@ -12,7 +12,7 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const createNonterminalVariant = createNonterminalVariantCreator< +const createNonterminalVariant = createNonterminalVariantSimpleCreator< ast.StringExpression, StringExpression >([ diff --git a/src/slang-nodes/TupleMember.ts b/src/slang-nodes/TupleMember.ts index 69849d93a..3b40666ea 100644 --- a/src/slang-nodes/TupleMember.ts +++ b/src/slang-nodes/TupleMember.ts @@ -1,6 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; +import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { TypedTupleMember } from './TypedTupleMember.js'; import { UntypedTupleMember } from './UntypedTupleMember.js'; @@ -9,7 +9,7 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const createNonterminalVariant = createNonterminalVariantCreator< +const createNonterminalVariant = createNonterminalVariantSimpleCreator< ast.TupleMember, TupleMember >([ diff --git a/src/slang-nodes/UsingClause.ts b/src/slang-nodes/UsingClause.ts index 2ed7ab091..dcaedb6d9 100644 --- a/src/slang-nodes/UsingClause.ts +++ b/src/slang-nodes/UsingClause.ts @@ -1,13 +1,13 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; +import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { IdentifierPath } from './IdentifierPath.js'; import { UsingDeconstruction } from './UsingDeconstruction.js'; import type { CollectedMetadata } from '../types.d.ts'; -const createNonterminalVariant = createNonterminalVariantCreator< +const createNonterminalVariant = createNonterminalVariantSimpleCreator< ast.UsingClause, UsingClause >([ diff --git a/src/slang-nodes/VersionExpression.ts b/src/slang-nodes/VersionExpression.ts index bd4bccdff..4b6757835 100644 --- a/src/slang-nodes/VersionExpression.ts +++ b/src/slang-nodes/VersionExpression.ts @@ -1,13 +1,13 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; +import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { VersionRange } from './VersionRange.js'; import { VersionTerm } from './VersionTerm.js'; import type { CollectedMetadata } from '../types.d.ts'; -const createNonterminalVariant = createNonterminalVariantCreator< +const createNonterminalVariant = createNonterminalVariantSimpleCreator< ast.VersionExpression, VersionExpression >([ diff --git a/src/slang-nodes/YulLiteral.ts b/src/slang-nodes/YulLiteral.ts index 8f15af1c8..1bffdd584 100644 --- a/src/slang-nodes/YulLiteral.ts +++ b/src/slang-nodes/YulLiteral.ts @@ -3,7 +3,7 @@ import { NonterminalKind, TerminalNode as SlangTerminalNode } from '@nomicfoundation/slang/cst'; -import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; +import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { HexStringLiteral } from './HexStringLiteral.js'; import { StringLiteral } from './StringLiteral.js'; @@ -13,7 +13,7 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const createNonterminalVariant = createNonterminalVariantCreator< +const createNonterminalVariant = createNonterminalVariantSimpleCreator< ast.YulLiteral, YulLiteral >([ diff --git a/src/slang-nodes/YulSwitchCase.ts b/src/slang-nodes/YulSwitchCase.ts index 8130eb39b..ecee949cd 100644 --- a/src/slang-nodes/YulSwitchCase.ts +++ b/src/slang-nodes/YulSwitchCase.ts @@ -1,6 +1,6 @@ import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; +import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; import { YulDefaultCase } from './YulDefaultCase.js'; import { YulValueCase } from './YulValueCase.js'; @@ -9,7 +9,7 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const createNonterminalVariant = createNonterminalVariantCreator< +const createNonterminalVariant = createNonterminalVariantSimpleCreator< ast.YulSwitchCase, YulSwitchCase >([ diff --git a/src/slang-utils/create-nonterminal-variant-creator.ts b/src/slang-utils/create-nonterminal-variant-creator.ts index 32331e48b..c44b7f6d0 100644 --- a/src/slang-utils/create-nonterminal-variant-creator.ts +++ b/src/slang-utils/create-nonterminal-variant-creator.ts @@ -16,35 +16,53 @@ type GenericFunction = U extends any : never; type SlangPolymorphicNode = Extract; -export function createNonterminalVariantCreator< +export function createNonterminalVariantSimpleCreator< U extends SlangPolymorphicNode, T extends StrictPolymorphicNode >( constructors: [ GenericFunction, ConstructorsFromInstances - ][], - constructorsWithVariants?: [ - GenericFunction, - ConstructorsFromInstances ][] -) { +): ( + variant: U['variant'], + collected: CollectedMetadata, + options?: ParserOptions +) => T['variant'] { const variantConstructors = new Map(constructors); - if (constructorsWithVariants === undefined) { - return ( - variant: U['variant'], - collected: CollectedMetadata, - options?: ParserOptions - ): T['variant'] => { - const constructor = variantConstructors.get(variant.constructor); - if (constructor !== undefined) - return new constructor(variant, collected, options); + return ( + variant: U['variant'], + collected: CollectedMetadata, + options?: ParserOptions + ): T['variant'] => { + const constructor = variantConstructors.get(variant.constructor); + if (constructor !== undefined) + return new constructor(variant, collected, options); - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); - }; - } + throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); + }; +} +export function createNonterminalVariantCreator< + U extends SlangPolymorphicNode, + T extends StrictPolymorphicNode +>( + constructors: [ + GenericFunction, + ConstructorsFromInstances + ][], + constructorsWithVariants: [ + GenericFunction, + ConstructorsFromInstances + ][] +): ( + variant: U['variant'] | SlangPolymorphicNode, + collected: CollectedMetadata, + options?: ParserOptions +) => T['variant'] { + const createNonterminalVariantSimple = + createNonterminalVariantSimpleCreator(constructors); const variantWithVariantsConstructors = new Map(constructorsWithVariants); return ( @@ -52,16 +70,16 @@ export function createNonterminalVariantCreator< collected: CollectedMetadata, options?: ParserOptions ): T['variant'] => { - let constructor: - | ConstructorsFromInstances - | undefined = variantConstructors.get(variant.constructor); - if (constructor !== undefined) - return new constructor(variant, collected, options); - - constructor = variantWithVariantsConstructors.get(variant.constructor); + const constructor = variantWithVariantsConstructors.get( + variant.constructor + ); if (constructor !== undefined) return extractVariant(new constructor(variant, collected, options)); - throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); + return createNonterminalVariantSimple( + variant as U['variant'], + collected, + options + ); }; } From 87102042d0e7deb6cc7a5a0f4c10341efdbd5fa7 Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 12 Feb 2026 12:05:14 -0300 Subject: [PATCH 09/22] cleaner name --- src/slang-utils/create-nonterminal-variant-creator.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/slang-utils/create-nonterminal-variant-creator.ts b/src/slang-utils/create-nonterminal-variant-creator.ts index c44b7f6d0..dccd9ffe2 100644 --- a/src/slang-utils/create-nonterminal-variant-creator.ts +++ b/src/slang-utils/create-nonterminal-variant-creator.ts @@ -52,7 +52,7 @@ export function createNonterminalVariantCreator< GenericFunction, ConstructorsFromInstances ][], - constructorsWithVariants: [ + extractVariantsConstructors: [ GenericFunction, ConstructorsFromInstances ][] @@ -63,16 +63,14 @@ export function createNonterminalVariantCreator< ) => T['variant'] { const createNonterminalVariantSimple = createNonterminalVariantSimpleCreator(constructors); - const variantWithVariantsConstructors = new Map(constructorsWithVariants); + const extractVariantsConstructor = new Map(extractVariantsConstructors); return ( variant: U['variant'] | SlangPolymorphicNode, collected: CollectedMetadata, options?: ParserOptions ): T['variant'] => { - const constructor = variantWithVariantsConstructors.get( - variant.constructor - ); + const constructor = extractVariantsConstructor.get(variant.constructor); if (constructor !== undefined) return extractVariant(new constructor(variant, collected, options)); From 8269515b0b1d0022fa4137ca65db21558017908c Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 12 Feb 2026 12:17:54 -0300 Subject: [PATCH 10/22] passing the types down to the second factory --- src/slang-utils/create-nonterminal-variant-creator.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/slang-utils/create-nonterminal-variant-creator.ts b/src/slang-utils/create-nonterminal-variant-creator.ts index dccd9ffe2..a1451dedf 100644 --- a/src/slang-utils/create-nonterminal-variant-creator.ts +++ b/src/slang-utils/create-nonterminal-variant-creator.ts @@ -61,8 +61,10 @@ export function createNonterminalVariantCreator< collected: CollectedMetadata, options?: ParserOptions ) => T['variant'] { - const createNonterminalVariantSimple = - createNonterminalVariantSimpleCreator(constructors); + const createNonterminalVariantSimple = createNonterminalVariantSimpleCreator< + U, + T + >(constructors); const extractVariantsConstructor = new Map(extractVariantsConstructors); return ( From c7ad4045a2303b36a6dbec77a17eed3f57f12585 Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 12 Feb 2026 12:43:31 -0300 Subject: [PATCH 11/22] shorter name so it fits better and it's easier to read --- .../create-nonterminal-variant-creator.ts | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/slang-utils/create-nonterminal-variant-creator.ts b/src/slang-utils/create-nonterminal-variant-creator.ts index a1451dedf..878b6302d 100644 --- a/src/slang-utils/create-nonterminal-variant-creator.ts +++ b/src/slang-utils/create-nonterminal-variant-creator.ts @@ -61,10 +61,9 @@ export function createNonterminalVariantCreator< collected: CollectedMetadata, options?: ParserOptions ) => T['variant'] { - const createNonterminalVariantSimple = createNonterminalVariantSimpleCreator< - U, - T - >(constructors); + const simpleCreator = createNonterminalVariantSimpleCreator( + constructors + ); const extractVariantsConstructor = new Map(extractVariantsConstructors); return ( @@ -76,10 +75,6 @@ export function createNonterminalVariantCreator< if (constructor !== undefined) return extractVariant(new constructor(variant, collected, options)); - return createNonterminalVariantSimple( - variant as U['variant'], - collected, - options - ); + return simpleCreator(variant as U['variant'], collected, options); }; } From 4d2fc90bb2d2309d2d0c0f22913ed7bf99b55c05 Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 12 Feb 2026 12:54:18 -0300 Subject: [PATCH 12/22] standardising the factory type --- .../create-nonterminal-variant-creator.ts | 35 ++++++++----------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/src/slang-utils/create-nonterminal-variant-creator.ts b/src/slang-utils/create-nonterminal-variant-creator.ts index 878b6302d..9ed8ad891 100644 --- a/src/slang-utils/create-nonterminal-variant-creator.ts +++ b/src/slang-utils/create-nonterminal-variant-creator.ts @@ -16,6 +16,15 @@ type GenericFunction = U extends any : never; type SlangPolymorphicNode = Extract; +type NonterminalVariantFactory< + U extends SlangPolymorphicNode, + T extends StrictPolymorphicNode +> = ( + variant: U['variant'], + collected: CollectedMetadata, + options?: ParserOptions +) => T['variant']; + export function createNonterminalVariantSimpleCreator< U extends SlangPolymorphicNode, T extends StrictPolymorphicNode @@ -24,18 +33,10 @@ export function createNonterminalVariantSimpleCreator< GenericFunction, ConstructorsFromInstances ][] -): ( - variant: U['variant'], - collected: CollectedMetadata, - options?: ParserOptions -) => T['variant'] { +): NonterminalVariantFactory { const variantConstructors = new Map(constructors); - return ( - variant: U['variant'], - collected: CollectedMetadata, - options?: ParserOptions - ): T['variant'] => { + return (variant, collected, options?) => { const constructor = variantConstructors.get(variant.constructor); if (constructor !== undefined) return new constructor(variant, collected, options); @@ -56,25 +57,17 @@ export function createNonterminalVariantCreator< GenericFunction, ConstructorsFromInstances ][] -): ( - variant: U['variant'] | SlangPolymorphicNode, - collected: CollectedMetadata, - options?: ParserOptions -) => T['variant'] { +): NonterminalVariantFactory { const simpleCreator = createNonterminalVariantSimpleCreator( constructors ); const extractVariantsConstructor = new Map(extractVariantsConstructors); - return ( - variant: U['variant'] | SlangPolymorphicNode, - collected: CollectedMetadata, - options?: ParserOptions - ): T['variant'] => { + return (variant, collected, options?) => { const constructor = extractVariantsConstructor.get(variant.constructor); if (constructor !== undefined) return extractVariant(new constructor(variant, collected, options)); - return simpleCreator(variant as U['variant'], collected, options); + return simpleCreator(variant, collected, options); }; } From 0f3af08c28293983ffda21bf12d72cb332d3c0d4 Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 12 Feb 2026 13:26:45 -0300 Subject: [PATCH 13/22] small typo --- src/slang-utils/create-nonterminal-variant-creator.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slang-utils/create-nonterminal-variant-creator.ts b/src/slang-utils/create-nonterminal-variant-creator.ts index 9ed8ad891..94d5738d1 100644 --- a/src/slang-utils/create-nonterminal-variant-creator.ts +++ b/src/slang-utils/create-nonterminal-variant-creator.ts @@ -53,7 +53,7 @@ export function createNonterminalVariantCreator< GenericFunction, ConstructorsFromInstances ][], - extractVariantsConstructors: [ + extractVariantConstructors: [ GenericFunction, ConstructorsFromInstances ][] @@ -61,10 +61,10 @@ export function createNonterminalVariantCreator< const simpleCreator = createNonterminalVariantSimpleCreator( constructors ); - const extractVariantsConstructor = new Map(extractVariantsConstructors); + const extractVariantConstructor = new Map(extractVariantConstructors); return (variant, collected, options?) => { - const constructor = extractVariantsConstructor.get(variant.constructor); + const constructor = extractVariantConstructor.get(variant.constructor); if (constructor !== undefined) return extractVariant(new constructor(variant, collected, options)); From 461ebb896afef9346a4544e44d968c29b98cc56e Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 12 Feb 2026 15:52:40 -0300 Subject: [PATCH 14/22] some cleanup --- src/slang-utils/create-nonterminal-variant-creator.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/slang-utils/create-nonterminal-variant-creator.ts b/src/slang-utils/create-nonterminal-variant-creator.ts index 94d5738d1..2ddfc6506 100644 --- a/src/slang-utils/create-nonterminal-variant-creator.ts +++ b/src/slang-utils/create-nonterminal-variant-creator.ts @@ -2,14 +2,10 @@ import { extractVariant } from './extract-variant.js'; import type { ParserOptions } from 'prettier'; -import type { - AstNode, - StrictAstNode, - StrictPolymorphicNode -} from '../slang-nodes/types.d.ts'; +import type { AstNode, StrictPolymorphicNode } from '../slang-nodes/types.d.ts'; import type { CollectedMetadata, SlangAstNode } from '../types.d.ts'; -type Constructor = new (...args: any) => T; +type Constructor = new (...args: any) => T; type ConstructorsFromInstances = U extends any ? Constructor : never; type GenericFunction = U extends any ? { prototype: unknown; name: string } From b7d873aa9276af1fe1a8ad358558c945ca7ed39a Mon Sep 17 00:00:00 2001 From: Klaus Date: Thu, 12 Feb 2026 20:33:54 -0300 Subject: [PATCH 15/22] deleting intermediate function in `Statement` and `YulStatement` --- src/slang-nodes/Statement.ts | 58 ++++++++++++++------------------- src/slang-nodes/YulStatement.ts | 49 ++++++++++++---------------- 2 files changed, 46 insertions(+), 61 deletions(-) diff --git a/src/slang-nodes/Statement.ts b/src/slang-nodes/Statement.ts index f52b34d71..546e04dc4 100644 --- a/src/slang-nodes/Statement.ts +++ b/src/slang-nodes/Statement.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -24,40 +24,28 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const createNonterminalVariantInternal = createNonterminalVariantSimpleCreator< - ast.Statement, +const createNonterminalVariant = createNonterminalVariantSimpleCreator< + slangAst.Statement, Statement >([ - [ast.ExpressionStatement, ExpressionStatement], - [ast.VariableDeclarationStatement, VariableDeclarationStatement], - [ast.TupleDeconstructionStatement, TupleDeconstructionStatement], - [ast.IfStatement, IfStatement], - [ast.ForStatement, ForStatement], - [ast.WhileStatement, WhileStatement], - [ast.DoWhileStatement, DoWhileStatement], - [ast.ContinueStatement, ContinueStatement], - [ast.BreakStatement, BreakStatement], - [ast.ReturnStatement, ReturnStatement], - [ast.ThrowStatement, ThrowStatement], - [ast.EmitStatement, EmitStatement], - [ast.TryStatement, TryStatement], - [ast.RevertStatement, RevertStatement], - [ast.AssemblyStatement, AssemblyStatement], - [ast.UncheckedBlock, UncheckedBlock] + [slangAst.ExpressionStatement, ExpressionStatement], + [slangAst.VariableDeclarationStatement, VariableDeclarationStatement], + [slangAst.TupleDeconstructionStatement, TupleDeconstructionStatement], + [slangAst.IfStatement, IfStatement], + [slangAst.ForStatement, ForStatement], + [slangAst.WhileStatement, WhileStatement], + [slangAst.DoWhileStatement, DoWhileStatement], + [slangAst.ContinueStatement, ContinueStatement], + [slangAst.BreakStatement, BreakStatement], + [slangAst.ReturnStatement, ReturnStatement], + [slangAst.ThrowStatement, ThrowStatement], + [slangAst.EmitStatement, EmitStatement], + [slangAst.TryStatement, TryStatement], + [slangAst.RevertStatement, RevertStatement], + [slangAst.AssemblyStatement, AssemblyStatement], + [slangAst.UncheckedBlock, UncheckedBlock] ]); -function createNonterminalVariant( - variant: ast.Statement['variant'], - collected: CollectedMetadata, - options: ParserOptions -): Statement['variant'] { - if (variant instanceof ast.Block) { - return new Block(variant, collected, options); - } - - return createNonterminalVariantInternal(variant, collected, options); -} - export class Statement extends SlangNode { readonly kind = NonterminalKind.Statement; @@ -81,13 +69,17 @@ export class Statement extends SlangNode { | UncheckedBlock; constructor( - ast: ast.Statement, + ast: slangAst.Statement, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); - this.variant = createNonterminalVariant(ast.variant, collected, options); + const variant = ast.variant; + this.variant = + variant instanceof slangAst.Block + ? new Block(variant, collected, options) + : createNonterminalVariant(variant, collected, options); this.updateMetadata(this.variant); } diff --git a/src/slang-nodes/YulStatement.ts b/src/slang-nodes/YulStatement.ts index eba16f4cb..f0342031f 100644 --- a/src/slang-nodes/YulStatement.ts +++ b/src/slang-nodes/YulStatement.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -20,37 +20,26 @@ import type { ParserOptions } from 'prettier'; import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; -const createNonterminalVariantInternal = createNonterminalVariantCreator< - ast.YulStatement, +const createNonterminalVariant = createNonterminalVariantCreator< + slangAst.YulStatement, YulStatement >( [ - [ast.YulFunctionDefinition, YulFunctionDefinition], - [ast.YulVariableDeclarationStatement, YulVariableDeclarationStatement], - [ast.YulVariableAssignmentStatement, YulVariableAssignmentStatement], - [ast.YulStackAssignmentStatement, YulStackAssignmentStatement], - [ast.YulIfStatement, YulIfStatement], - [ast.YulForStatement, YulForStatement], - [ast.YulSwitchStatement, YulSwitchStatement], - [ast.YulLeaveStatement, YulLeaveStatement], - [ast.YulBreakStatement, YulBreakStatement], - [ast.YulContinueStatement, YulContinueStatement], - [ast.YulLabel, YulLabel] + [slangAst.YulFunctionDefinition, YulFunctionDefinition], + [slangAst.YulVariableDeclarationStatement, YulVariableDeclarationStatement], + [slangAst.YulVariableAssignmentStatement, YulVariableAssignmentStatement], + [slangAst.YulStackAssignmentStatement, YulStackAssignmentStatement], + [slangAst.YulIfStatement, YulIfStatement], + [slangAst.YulForStatement, YulForStatement], + [slangAst.YulSwitchStatement, YulSwitchStatement], + [slangAst.YulLeaveStatement, YulLeaveStatement], + [slangAst.YulBreakStatement, YulBreakStatement], + [slangAst.YulContinueStatement, YulContinueStatement], + [slangAst.YulLabel, YulLabel] ], - [[ast.YulExpression, YulExpression]] + [[slangAst.YulExpression, YulExpression]] ); -function createNonterminalVariant( - variant: ast.YulStatement['variant'], - collected: CollectedMetadata, - options: ParserOptions -): YulStatement['variant'] { - if (variant instanceof ast.YulBlock) { - return new YulBlock(variant, collected, options); - } - return createNonterminalVariantInternal(variant, collected, options); -} - export class YulStatement extends SlangNode { readonly kind = NonterminalKind.YulStatement; @@ -70,13 +59,17 @@ export class YulStatement extends SlangNode { | YulExpression['variant']; constructor( - ast: ast.YulStatement, + ast: slangAst.YulStatement, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); - this.variant = createNonterminalVariant(ast.variant, collected, options); + const variant = ast.variant; + this.variant = + variant instanceof slangAst.YulBlock + ? new YulBlock(variant, collected, options) + : createNonterminalVariant(variant, collected, options); this.updateMetadata(this.variant); } From b9d322cbcc110214f5064bc2e1206eaf8b91c049 Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 17 Feb 2026 14:26:34 -0300 Subject: [PATCH 16/22] using `instanceof` instead of Map --- .../create-nonterminal-variant-creator.ts | 32 +++++++++---------- src/types.d.ts | 1 + 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/slang-utils/create-nonterminal-variant-creator.ts b/src/slang-utils/create-nonterminal-variant-creator.ts index 2ddfc6506..8e3586cc8 100644 --- a/src/slang-utils/create-nonterminal-variant-creator.ts +++ b/src/slang-utils/create-nonterminal-variant-creator.ts @@ -3,13 +3,14 @@ import { extractVariant } from './extract-variant.js'; import type { ParserOptions } from 'prettier'; import type { AstNode, StrictPolymorphicNode } from '../slang-nodes/types.d.ts'; -import type { CollectedMetadata, SlangAstNode } from '../types.d.ts'; +import type { + CollectedMetadata, + SlangAstNode, + SlangAstNodeConstructors +} from '../types.d.ts'; type Constructor = new (...args: any) => T; type ConstructorsFromInstances = U extends any ? Constructor : never; -type GenericFunction = U extends any - ? { prototype: unknown; name: string } - : never; type SlangPolymorphicNode = Extract; type NonterminalVariantFactory< @@ -26,16 +27,15 @@ export function createNonterminalVariantSimpleCreator< T extends StrictPolymorphicNode >( constructors: [ - GenericFunction, + SlangAstNodeConstructors, ConstructorsFromInstances ][] ): NonterminalVariantFactory { - const variantConstructors = new Map(constructors); - return (variant, collected, options?) => { - const constructor = variantConstructors.get(variant.constructor); - if (constructor !== undefined) - return new constructor(variant, collected, options); + for (const [instance, constructor] of constructors) { + if (variant instanceof instance) + return new constructor(variant, collected, options); + } throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`); }; @@ -46,23 +46,23 @@ export function createNonterminalVariantCreator< T extends StrictPolymorphicNode >( constructors: [ - GenericFunction, + SlangAstNodeConstructors, ConstructorsFromInstances ][], extractVariantConstructors: [ - GenericFunction, + SlangAstNodeConstructors, ConstructorsFromInstances ][] ): NonterminalVariantFactory { const simpleCreator = createNonterminalVariantSimpleCreator( constructors ); - const extractVariantConstructor = new Map(extractVariantConstructors); return (variant, collected, options?) => { - const constructor = extractVariantConstructor.get(variant.constructor); - if (constructor !== undefined) - return extractVariant(new constructor(variant, collected, options)); + for (const [instance, constructor] of extractVariantConstructors) { + if (variant instanceof instance) + return extractVariant(new constructor(variant, collected, options)); + } return simpleCreator(variant, collected, options); }; diff --git a/src/types.d.ts b/src/types.d.ts index 1aff0dff0..5d336cda5 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -32,3 +32,4 @@ type KeyOfAst = keyof TypeOfAst; type ValuesOf = E[keyof E]; type SlangAstNode = { [k in KeyOfAst]: ValuesOf }[KeyOfAst]; +type SlangAstNodeConstructors = { [k in KeyOfAst]: TypeOfAst[k] }[KeyOfAst]; From 1043a9a62a3b289cb6dd04db30130cdb5b9a5dd5 Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 17 Feb 2026 15:41:36 -0300 Subject: [PATCH 17/22] Clear names --- .../create-nonterminal-variant-creator.ts | 22 +++++++------------ src/types.d.ts | 2 +- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/slang-utils/create-nonterminal-variant-creator.ts b/src/slang-utils/create-nonterminal-variant-creator.ts index 8e3586cc8..df515d12d 100644 --- a/src/slang-utils/create-nonterminal-variant-creator.ts +++ b/src/slang-utils/create-nonterminal-variant-creator.ts @@ -6,7 +6,7 @@ import type { AstNode, StrictPolymorphicNode } from '../slang-nodes/types.d.ts'; import type { CollectedMetadata, SlangAstNode, - SlangAstNodeConstructors + SlangAstNodeClass } from '../types.d.ts'; type Constructor = new (...args: any) => T; @@ -26,14 +26,11 @@ export function createNonterminalVariantSimpleCreator< U extends SlangPolymorphicNode, T extends StrictPolymorphicNode >( - constructors: [ - SlangAstNodeConstructors, - ConstructorsFromInstances - ][] + constructors: [SlangAstNodeClass, ConstructorsFromInstances][] ): NonterminalVariantFactory { return (variant, collected, options?) => { - for (const [instance, constructor] of constructors) { - if (variant instanceof instance) + for (const [slangAstClass, constructor] of constructors) { + if (variant instanceof slangAstClass) return new constructor(variant, collected, options); } @@ -45,12 +42,9 @@ export function createNonterminalVariantCreator< U extends SlangPolymorphicNode, T extends StrictPolymorphicNode >( - constructors: [ - SlangAstNodeConstructors, - ConstructorsFromInstances - ][], + constructors: [SlangAstNodeClass, ConstructorsFromInstances][], extractVariantConstructors: [ - SlangAstNodeConstructors, + SlangAstNodeClass, ConstructorsFromInstances ][] ): NonterminalVariantFactory { @@ -59,8 +53,8 @@ export function createNonterminalVariantCreator< ); return (variant, collected, options?) => { - for (const [instance, constructor] of extractVariantConstructors) { - if (variant instanceof instance) + for (const [slangAstClass, constructor] of extractVariantConstructors) { + if (variant instanceof slangAstClass) return extractVariant(new constructor(variant, collected, options)); } diff --git a/src/types.d.ts b/src/types.d.ts index 5d336cda5..6af3f6cca 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -32,4 +32,4 @@ type KeyOfAst = keyof TypeOfAst; type ValuesOf = E[keyof E]; type SlangAstNode = { [k in KeyOfAst]: ValuesOf }[KeyOfAst]; -type SlangAstNodeConstructors = { [k in KeyOfAst]: TypeOfAst[k] }[KeyOfAst]; +type SlangAstNodeClass = { [k in KeyOfAst]: TypeOfAst[k] }[KeyOfAst]; From 230501668b3e0d8b07278b9fef0489b394a081ef Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 23 Feb 2026 23:52:53 -0300 Subject: [PATCH 18/22] adding coverage for all cases only on `test` environment --- src/slang-nodes/ArgumentsDeclaration.ts | 19 +++- src/slang-nodes/ContractMember.ts | 51 ++++++---- src/slang-nodes/ContractSpecifier.ts | 18 +++- src/slang-nodes/Expression.ts | 95 +++++++++++++------ src/slang-nodes/FallbackFunctionAttribute.ts | 24 ++++- src/slang-nodes/ForStatementInitialization.ts | 27 ++++-- src/slang-nodes/FunctionAttribute.ts | 23 ++++- src/slang-nodes/ImportClause.ts | 21 ++-- src/slang-nodes/MappingKeyType.ts | 18 +++- src/slang-nodes/Pragma.ts | 21 ++-- src/slang-nodes/ReceiveFunctionAttribute.ts | 24 ++++- src/slang-nodes/SourceUnitMember.ts | 51 ++++++---- src/slang-nodes/Statement.ts | 23 +++++ src/slang-nodes/StringExpression.ts | 27 ++++-- src/slang-nodes/TupleMember.ts | 18 +++- src/slang-nodes/TypeName.ts | 27 ++++-- src/slang-nodes/UsingClause.ts | 18 +++- src/slang-nodes/VersionExpression.ts | 18 +++- src/slang-nodes/YulExpression.ts | 21 ++-- src/slang-nodes/YulLiteral.ts | 20 +++- src/slang-nodes/YulStatement.ts | 19 ++++ src/slang-nodes/YulSwitchCase.ts | 18 +++- 22 files changed, 444 insertions(+), 157 deletions(-) diff --git a/src/slang-nodes/ArgumentsDeclaration.ts b/src/slang-nodes/ArgumentsDeclaration.ts index 106dae3c6..7eec1b2e2 100644 --- a/src/slang-nodes/ArgumentsDeclaration.ts +++ b/src/slang-nodes/ArgumentsDeclaration.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -10,11 +10,11 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - ast.ArgumentsDeclaration, + slangAst.ArgumentsDeclaration, ArgumentsDeclaration >([ - [ast.PositionalArgumentsDeclaration, PositionalArgumentsDeclaration], - [ast.NamedArgumentsDeclaration, NamedArgumentsDeclaration] + [slangAst.PositionalArgumentsDeclaration, PositionalArgumentsDeclaration], + [slangAst.NamedArgumentsDeclaration, NamedArgumentsDeclaration] ]); export class ArgumentsDeclaration extends SlangNode { @@ -23,12 +23,21 @@ export class ArgumentsDeclaration extends SlangNode { variant: PositionalArgumentsDeclaration | NamedArgumentsDeclaration; constructor( - ast: ast.ArgumentsDeclaration, + ast: slangAst.ArgumentsDeclaration, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of + // `ArgumentsDeclaration` in the `createNonterminalVariant` function + // above. + ((variant: slangAst.ArgumentsDeclaration['variant']): void => { + if (variant instanceof slangAst.PositionalArgumentsDeclaration) return; + if (variant instanceof slangAst.NamedArgumentsDeclaration) return; + })(ast.variant); + } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/ContractMember.ts b/src/slang-nodes/ContractMember.ts index 767faa39c..ed982586b 100644 --- a/src/slang-nodes/ContractMember.ts +++ b/src/slang-nodes/ContractMember.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -21,22 +21,22 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - ast.ContractMember, + slangAst.ContractMember, ContractMember >([ - [ast.UsingDirective, UsingDirective], - [ast.FunctionDefinition, FunctionDefinition], - [ast.ConstructorDefinition, ConstructorDefinition], - [ast.ReceiveFunctionDefinition, ReceiveFunctionDefinition], - [ast.FallbackFunctionDefinition, FallbackFunctionDefinition], - [ast.UnnamedFunctionDefinition, UnnamedFunctionDefinition], - [ast.ModifierDefinition, ModifierDefinition], - [ast.StructDefinition, StructDefinition], - [ast.EnumDefinition, EnumDefinition], - [ast.EventDefinition, EventDefinition], - [ast.StateVariableDefinition, StateVariableDefinition], - [ast.ErrorDefinition, ErrorDefinition], - [ast.UserDefinedValueTypeDefinition, UserDefinedValueTypeDefinition] + [slangAst.UsingDirective, UsingDirective], + [slangAst.FunctionDefinition, FunctionDefinition], + [slangAst.ConstructorDefinition, ConstructorDefinition], + [slangAst.ReceiveFunctionDefinition, ReceiveFunctionDefinition], + [slangAst.FallbackFunctionDefinition, FallbackFunctionDefinition], + [slangAst.UnnamedFunctionDefinition, UnnamedFunctionDefinition], + [slangAst.ModifierDefinition, ModifierDefinition], + [slangAst.StructDefinition, StructDefinition], + [slangAst.EnumDefinition, EnumDefinition], + [slangAst.EventDefinition, EventDefinition], + [slangAst.StateVariableDefinition, StateVariableDefinition], + [slangAst.ErrorDefinition, ErrorDefinition], + [slangAst.UserDefinedValueTypeDefinition, UserDefinedValueTypeDefinition] ]); export class ContractMember extends SlangNode { @@ -58,12 +58,31 @@ export class ContractMember extends SlangNode { | UserDefinedValueTypeDefinition; constructor( - ast: ast.ContractMember, + ast: slangAst.ContractMember, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of + // `ContractMember` in the `createNonterminalVariant` function above. + ((variant: slangAst.ContractMember['variant']): void => { + if (variant instanceof slangAst.UsingDirective) return; + if (variant instanceof slangAst.FunctionDefinition) return; + if (variant instanceof slangAst.ConstructorDefinition) return; + if (variant instanceof slangAst.ReceiveFunctionDefinition) return; + if (variant instanceof slangAst.FallbackFunctionDefinition) return; + if (variant instanceof slangAst.UnnamedFunctionDefinition) return; + if (variant instanceof slangAst.ModifierDefinition) return; + if (variant instanceof slangAst.StructDefinition) return; + if (variant instanceof slangAst.EnumDefinition) return; + if (variant instanceof slangAst.EventDefinition) return; + if (variant instanceof slangAst.StateVariableDefinition) return; + if (variant instanceof slangAst.ErrorDefinition) return; + if (variant instanceof slangAst.UserDefinedValueTypeDefinition) return; + })(ast.variant); + } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/ContractSpecifier.ts b/src/slang-nodes/ContractSpecifier.ts index fc18129bf..dc13c86a0 100644 --- a/src/slang-nodes/ContractSpecifier.ts +++ b/src/slang-nodes/ContractSpecifier.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -10,11 +10,11 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - ast.ContractSpecifier, + slangAst.ContractSpecifier, ContractSpecifier >([ - [ast.InheritanceSpecifier, InheritanceSpecifier], - [ast.StorageLayoutSpecifier, StorageLayoutSpecifier] + [slangAst.InheritanceSpecifier, InheritanceSpecifier], + [slangAst.StorageLayoutSpecifier, StorageLayoutSpecifier] ]); export class ContractSpecifier extends SlangNode { @@ -23,12 +23,20 @@ export class ContractSpecifier extends SlangNode { variant: InheritanceSpecifier | StorageLayoutSpecifier; constructor( - ast: ast.ContractSpecifier, + ast: slangAst.ContractSpecifier, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of + // `ContractSpecifier` in the `createNonterminalVariant` function above. + ((variant: slangAst.ContractSpecifier['variant']): void => { + if (variant instanceof slangAst.InheritanceSpecifier) return; + if (variant instanceof slangAst.StorageLayoutSpecifier) return; + })(ast.variant); + } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/Expression.ts b/src/slang-nodes/Expression.ts index c8239b971..6c8fbc93a 100644 --- a/src/slang-nodes/Expression.ts +++ b/src/slang-nodes/Expression.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind, TerminalNode as SlangTerminalNode @@ -39,39 +39,39 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - ast.Expression, + slangAst.Expression, Expression >( [ - [ast.AssignmentExpression, AssignmentExpression], - [ast.ConditionalExpression, ConditionalExpression], - [ast.OrExpression, OrExpression], - [ast.AndExpression, AndExpression], - [ast.EqualityExpression, EqualityExpression], - [ast.InequalityExpression, InequalityExpression], - [ast.BitwiseOrExpression, BitwiseOrExpression], - [ast.BitwiseXorExpression, BitwiseXorExpression], - [ast.BitwiseAndExpression, BitwiseAndExpression], - [ast.ShiftExpression, ShiftExpression], - [ast.AdditiveExpression, AdditiveExpression], - [ast.MultiplicativeExpression, MultiplicativeExpression], - [ast.ExponentiationExpression, ExponentiationExpression], - [ast.PostfixExpression, PostfixExpression], - [ast.PrefixExpression, PrefixExpression], - [ast.FunctionCallExpression, FunctionCallExpression], - [ast.CallOptionsExpression, CallOptionsExpression], - [ast.MemberAccessExpression, MemberAccessExpression], - [ast.IndexAccessExpression, IndexAccessExpression], - [ast.NewExpression, NewExpression], - [ast.TupleExpression, TupleExpression], - [ast.TypeExpression, TypeExpression], - [ast.ArrayExpression, ArrayExpression], - [ast.HexNumberExpression, HexNumberExpression], - [ast.DecimalNumberExpression, DecimalNumberExpression] + [slangAst.AssignmentExpression, AssignmentExpression], + [slangAst.ConditionalExpression, ConditionalExpression], + [slangAst.OrExpression, OrExpression], + [slangAst.AndExpression, AndExpression], + [slangAst.EqualityExpression, EqualityExpression], + [slangAst.InequalityExpression, InequalityExpression], + [slangAst.BitwiseOrExpression, BitwiseOrExpression], + [slangAst.BitwiseXorExpression, BitwiseXorExpression], + [slangAst.BitwiseAndExpression, BitwiseAndExpression], + [slangAst.ShiftExpression, ShiftExpression], + [slangAst.AdditiveExpression, AdditiveExpression], + [slangAst.MultiplicativeExpression, MultiplicativeExpression], + [slangAst.ExponentiationExpression, ExponentiationExpression], + [slangAst.PostfixExpression, PostfixExpression], + [slangAst.PrefixExpression, PrefixExpression], + [slangAst.FunctionCallExpression, FunctionCallExpression], + [slangAst.CallOptionsExpression, CallOptionsExpression], + [slangAst.MemberAccessExpression, MemberAccessExpression], + [slangAst.IndexAccessExpression, IndexAccessExpression], + [slangAst.NewExpression, NewExpression], + [slangAst.TupleExpression, TupleExpression], + [slangAst.TypeExpression, TypeExpression], + [slangAst.ArrayExpression, ArrayExpression], + [slangAst.HexNumberExpression, HexNumberExpression], + [slangAst.DecimalNumberExpression, DecimalNumberExpression] ], [ - [ast.StringExpression, StringExpression], - [ast.ElementaryType, ElementaryType] + [slangAst.StringExpression, StringExpression], + [slangAst.ElementaryType, ElementaryType] ] ); @@ -109,7 +109,7 @@ export class Expression extends SlangNode { | TerminalNode; constructor( - ast: ast.Expression, + ast: slangAst.Expression, collected: CollectedMetadata, options: ParserOptions ) { @@ -120,6 +120,41 @@ export class Expression extends SlangNode { this.variant = new TerminalNode(variant, collected); return; } + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of + // `Expression` in the `createNonterminalVariant` function above. + (( + variant: Exclude + ): void => { + if (variant instanceof slangAst.AssignmentExpression) return; + if (variant instanceof slangAst.ConditionalExpression) return; + if (variant instanceof slangAst.OrExpression) return; + if (variant instanceof slangAst.AndExpression) return; + if (variant instanceof slangAst.EqualityExpression) return; + if (variant instanceof slangAst.InequalityExpression) return; + if (variant instanceof slangAst.BitwiseOrExpression) return; + if (variant instanceof slangAst.BitwiseXorExpression) return; + if (variant instanceof slangAst.BitwiseAndExpression) return; + if (variant instanceof slangAst.ShiftExpression) return; + if (variant instanceof slangAst.AdditiveExpression) return; + if (variant instanceof slangAst.MultiplicativeExpression) return; + if (variant instanceof slangAst.ExponentiationExpression) return; + if (variant instanceof slangAst.PostfixExpression) return; + if (variant instanceof slangAst.PrefixExpression) return; + if (variant instanceof slangAst.FunctionCallExpression) return; + if (variant instanceof slangAst.CallOptionsExpression) return; + if (variant instanceof slangAst.MemberAccessExpression) return; + if (variant instanceof slangAst.IndexAccessExpression) return; + if (variant instanceof slangAst.NewExpression) return; + if (variant instanceof slangAst.TupleExpression) return; + if (variant instanceof slangAst.TypeExpression) return; + if (variant instanceof slangAst.ArrayExpression) return; + if (variant instanceof slangAst.HexNumberExpression) return; + if (variant instanceof slangAst.DecimalNumberExpression) return; + if (variant instanceof slangAst.StringExpression) return; + if (variant instanceof slangAst.ElementaryType) return; + })(variant); + } this.variant = createNonterminalVariant(variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/FallbackFunctionAttribute.ts b/src/slang-nodes/FallbackFunctionAttribute.ts index f757e2427..44fb1ab10 100644 --- a/src/slang-nodes/FallbackFunctionAttribute.ts +++ b/src/slang-nodes/FallbackFunctionAttribute.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind, TerminalNode as SlangTerminalNode @@ -14,11 +14,11 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - ast.FallbackFunctionAttribute, + slangAst.FallbackFunctionAttribute, FallbackFunctionAttribute >([ - [ast.ModifierInvocation, ModifierInvocation], - [ast.OverrideSpecifier, OverrideSpecifier] + [slangAst.ModifierInvocation, ModifierInvocation], + [slangAst.OverrideSpecifier, OverrideSpecifier] ]); export class FallbackFunctionAttribute extends SlangNode { @@ -27,7 +27,7 @@ export class FallbackFunctionAttribute extends SlangNode { variant: ModifierInvocation | OverrideSpecifier | TerminalNode; constructor( - ast: ast.FallbackFunctionAttribute, + ast: slangAst.FallbackFunctionAttribute, collected: CollectedMetadata, options: ParserOptions ) { @@ -38,6 +38,20 @@ export class FallbackFunctionAttribute extends SlangNode { this.variant = new TerminalNode(variant, collected); return; } + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of + // `FallbackFunctionAttribute` in the `createNonterminalVariant` function + // above. + (( + variant: Exclude< + slangAst.FallbackFunctionAttribute['variant'], + SlangTerminalNode + > + ): void => { + if (variant instanceof slangAst.ModifierInvocation) return; + if (variant instanceof slangAst.OverrideSpecifier) return; + })(variant); + } this.variant = createNonterminalVariant(variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/ForStatementInitialization.ts b/src/slang-nodes/ForStatementInitialization.ts index 84ca74ae3..dc3e9bcab 100644 --- a/src/slang-nodes/ForStatementInitialization.ts +++ b/src/slang-nodes/ForStatementInitialization.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind, TerminalNode as SlangTerminalNode @@ -15,12 +15,12 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - ast.ForStatementInitialization, + slangAst.ForStatementInitialization, ForStatementInitialization >([ - [ast.ExpressionStatement, ExpressionStatement], - [ast.VariableDeclarationStatement, VariableDeclarationStatement], - [ast.TupleDeconstructionStatement, TupleDeconstructionStatement] + [slangAst.ExpressionStatement, ExpressionStatement], + [slangAst.VariableDeclarationStatement, VariableDeclarationStatement], + [slangAst.TupleDeconstructionStatement, TupleDeconstructionStatement] ]); export class ForStatementInitialization extends SlangNode { @@ -33,7 +33,7 @@ export class ForStatementInitialization extends SlangNode { | TerminalNode; constructor( - ast: ast.ForStatementInitialization, + ast: slangAst.ForStatementInitialization, collected: CollectedMetadata, options: ParserOptions ) { @@ -44,6 +44,21 @@ export class ForStatementInitialization extends SlangNode { this.variant = new TerminalNode(variant, collected); return; } + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of + // `ForStatementInitialization` in the `createNonterminalVariant` + // function above. + (( + variant: Exclude< + slangAst.ForStatementInitialization['variant'], + SlangTerminalNode + > + ): void => { + if (variant instanceof slangAst.ExpressionStatement) return; + if (variant instanceof slangAst.VariableDeclarationStatement) return; + if (variant instanceof slangAst.TupleDeconstructionStatement) return; + })(variant); + } this.variant = createNonterminalVariant(variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/FunctionAttribute.ts b/src/slang-nodes/FunctionAttribute.ts index c946ca94e..bdbd01cb3 100644 --- a/src/slang-nodes/FunctionAttribute.ts +++ b/src/slang-nodes/FunctionAttribute.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind, TerminalNode as SlangTerminalNode @@ -14,11 +14,11 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - ast.FunctionAttribute, + slangAst.FunctionAttribute, FunctionAttribute >([ - [ast.ModifierInvocation, ModifierInvocation], - [ast.OverrideSpecifier, OverrideSpecifier] + [slangAst.ModifierInvocation, ModifierInvocation], + [slangAst.OverrideSpecifier, OverrideSpecifier] ]); export class FunctionAttribute extends SlangNode { @@ -27,7 +27,7 @@ export class FunctionAttribute extends SlangNode { variant: ModifierInvocation | OverrideSpecifier | TerminalNode; constructor( - ast: ast.FunctionAttribute, + ast: slangAst.FunctionAttribute, collected: CollectedMetadata, options: ParserOptions ) { @@ -38,6 +38,19 @@ export class FunctionAttribute extends SlangNode { this.variant = new TerminalNode(variant, collected); return; } + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of + // `FunctionAttribute` in the `createNonterminalVariant` function above. + (( + variant: Exclude< + slangAst.FunctionAttribute['variant'], + SlangTerminalNode + > + ): void => { + if (variant instanceof slangAst.ModifierInvocation) return; + if (variant instanceof slangAst.OverrideSpecifier) return; + })(variant); + } this.variant = createNonterminalVariant(variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/ImportClause.ts b/src/slang-nodes/ImportClause.ts index 1421e735d..a3c957d99 100644 --- a/src/slang-nodes/ImportClause.ts +++ b/src/slang-nodes/ImportClause.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -11,12 +11,12 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - ast.ImportClause, + slangAst.ImportClause, ImportClause >([ - [ast.PathImport, PathImport], - [ast.NamedImport, NamedImport], - [ast.ImportDeconstruction, ImportDeconstruction] + [slangAst.PathImport, PathImport], + [slangAst.NamedImport, NamedImport], + [slangAst.ImportDeconstruction, ImportDeconstruction] ]); export class ImportClause extends SlangNode { @@ -25,12 +25,21 @@ export class ImportClause extends SlangNode { variant: PathImport | NamedImport | ImportDeconstruction; constructor( - ast: ast.ImportClause, + ast: slangAst.ImportClause, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of `ImportClause` + // in the `createNonterminalVariant` function above. + ((variant: slangAst.ImportClause['variant']): void => { + if (variant instanceof slangAst.PathImport) return; + if (variant instanceof slangAst.NamedImport) return; + if (variant instanceof slangAst.ImportDeconstruction) return; + })(ast.variant); + } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/MappingKeyType.ts b/src/slang-nodes/MappingKeyType.ts index 523244395..5c943c9bf 100644 --- a/src/slang-nodes/MappingKeyType.ts +++ b/src/slang-nodes/MappingKeyType.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -8,11 +8,11 @@ import { IdentifierPath } from './IdentifierPath.js'; import type { CollectedMetadata } from '../types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - ast.MappingKeyType, + slangAst.MappingKeyType, MappingKeyType >( - [[ast.IdentifierPath, IdentifierPath]], - [[ast.ElementaryType, ElementaryType]] + [[slangAst.IdentifierPath, IdentifierPath]], + [[slangAst.ElementaryType, ElementaryType]] ); export class MappingKeyType extends SlangNode { @@ -20,9 +20,17 @@ export class MappingKeyType extends SlangNode { variant: ElementaryType['variant'] | IdentifierPath; - constructor(ast: ast.MappingKeyType, collected: CollectedMetadata) { + constructor(ast: slangAst.MappingKeyType, collected: CollectedMetadata) { super(ast, collected); + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of + // `MappingKeyType` in the `createNonterminalVariant` function above. + ((variant: slangAst.MappingKeyType['variant']): void => { + if (variant instanceof slangAst.IdentifierPath) return; + if (variant instanceof slangAst.ElementaryType) return; + })(ast.variant); + } this.variant = createNonterminalVariant(ast.variant, collected); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/Pragma.ts b/src/slang-nodes/Pragma.ts index 86a4ece4d..436a0f651 100644 --- a/src/slang-nodes/Pragma.ts +++ b/src/slang-nodes/Pragma.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -11,12 +11,12 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - ast.Pragma, + slangAst.Pragma, Pragma >([ - [ast.AbicoderPragma, AbicoderPragma], - [ast.ExperimentalPragma, ExperimentalPragma], - [ast.VersionPragma, VersionPragma] + [slangAst.AbicoderPragma, AbicoderPragma], + [slangAst.ExperimentalPragma, ExperimentalPragma], + [slangAst.VersionPragma, VersionPragma] ]); export class Pragma extends SlangNode { @@ -25,12 +25,21 @@ export class Pragma extends SlangNode { variant: AbicoderPragma | ExperimentalPragma | VersionPragma; constructor( - ast: ast.Pragma, + ast: slangAst.Pragma, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of `Pragma` in the + // `createNonterminalVariant` function above. + ((variant: slangAst.Pragma['variant']): void => { + if (variant instanceof slangAst.AbicoderPragma) return; + if (variant instanceof slangAst.ExperimentalPragma) return; + if (variant instanceof slangAst.VersionPragma) return; + })(ast.variant); + } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/ReceiveFunctionAttribute.ts b/src/slang-nodes/ReceiveFunctionAttribute.ts index 5e91580ab..d61ca3216 100644 --- a/src/slang-nodes/ReceiveFunctionAttribute.ts +++ b/src/slang-nodes/ReceiveFunctionAttribute.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind, TerminalNode as SlangTerminalNode @@ -14,11 +14,11 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - ast.ReceiveFunctionAttribute, + slangAst.ReceiveFunctionAttribute, ReceiveFunctionAttribute >([ - [ast.ModifierInvocation, ModifierInvocation], - [ast.OverrideSpecifier, OverrideSpecifier] + [slangAst.ModifierInvocation, ModifierInvocation], + [slangAst.OverrideSpecifier, OverrideSpecifier] ]); export class ReceiveFunctionAttribute extends SlangNode { @@ -27,7 +27,7 @@ export class ReceiveFunctionAttribute extends SlangNode { variant: ModifierInvocation | OverrideSpecifier | TerminalNode; constructor( - ast: ast.ReceiveFunctionAttribute, + ast: slangAst.ReceiveFunctionAttribute, collected: CollectedMetadata, options: ParserOptions ) { @@ -38,6 +38,20 @@ export class ReceiveFunctionAttribute extends SlangNode { this.variant = new TerminalNode(variant, collected); return; } + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of + // `ReceiveFunctionAttribute` in the `createNonterminalVariant` function + // above. + (( + variant: Exclude< + slangAst.ReceiveFunctionAttribute['variant'], + SlangTerminalNode + > + ): void => { + if (variant instanceof slangAst.ModifierInvocation) return; + if (variant instanceof slangAst.OverrideSpecifier) return; + })(variant); + } this.variant = createNonterminalVariant(variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/SourceUnitMember.ts b/src/slang-nodes/SourceUnitMember.ts index d545dc29d..043e1ba4d 100644 --- a/src/slang-nodes/SourceUnitMember.ts +++ b/src/slang-nodes/SourceUnitMember.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -21,22 +21,22 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - ast.SourceUnitMember, + slangAst.SourceUnitMember, SourceUnitMember >([ - [ast.PragmaDirective, PragmaDirective], - [ast.ImportDirective, ImportDirective], - [ast.ContractDefinition, ContractDefinition], - [ast.InterfaceDefinition, InterfaceDefinition], - [ast.LibraryDefinition, LibraryDefinition], - [ast.StructDefinition, StructDefinition], - [ast.EnumDefinition, EnumDefinition], - [ast.FunctionDefinition, FunctionDefinition], - [ast.ConstantDefinition, ConstantDefinition], - [ast.ErrorDefinition, ErrorDefinition], - [ast.UserDefinedValueTypeDefinition, UserDefinedValueTypeDefinition], - [ast.UsingDirective, UsingDirective], - [ast.EventDefinition, EventDefinition] + [slangAst.PragmaDirective, PragmaDirective], + [slangAst.ImportDirective, ImportDirective], + [slangAst.ContractDefinition, ContractDefinition], + [slangAst.InterfaceDefinition, InterfaceDefinition], + [slangAst.LibraryDefinition, LibraryDefinition], + [slangAst.StructDefinition, StructDefinition], + [slangAst.EnumDefinition, EnumDefinition], + [slangAst.FunctionDefinition, FunctionDefinition], + [slangAst.ConstantDefinition, ConstantDefinition], + [slangAst.ErrorDefinition, ErrorDefinition], + [slangAst.UserDefinedValueTypeDefinition, UserDefinedValueTypeDefinition], + [slangAst.UsingDirective, UsingDirective], + [slangAst.EventDefinition, EventDefinition] ]); export class SourceUnitMember extends SlangNode { @@ -58,12 +58,31 @@ export class SourceUnitMember extends SlangNode { | EventDefinition; constructor( - ast: ast.SourceUnitMember, + ast: slangAst.SourceUnitMember, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of + // `SourceUnitMember` in the `createNonterminalVariant` function above. + ((variant: slangAst.SourceUnitMember['variant']): void => { + if (variant instanceof slangAst.PragmaDirective) return; + if (variant instanceof slangAst.ImportDirective) return; + if (variant instanceof slangAst.ContractDefinition) return; + if (variant instanceof slangAst.InterfaceDefinition) return; + if (variant instanceof slangAst.LibraryDefinition) return; + if (variant instanceof slangAst.StructDefinition) return; + if (variant instanceof slangAst.EnumDefinition) return; + if (variant instanceof slangAst.FunctionDefinition) return; + if (variant instanceof slangAst.ConstantDefinition) return; + if (variant instanceof slangAst.ErrorDefinition) return; + if (variant instanceof slangAst.UserDefinedValueTypeDefinition) return; + if (variant instanceof slangAst.UsingDirective) return; + if (variant instanceof slangAst.EventDefinition) return; + })(ast.variant); + } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/Statement.ts b/src/slang-nodes/Statement.ts index 546e04dc4..d4e35a08f 100644 --- a/src/slang-nodes/Statement.ts +++ b/src/slang-nodes/Statement.ts @@ -76,6 +76,29 @@ export class Statement extends SlangNode { super(ast, collected); const variant = ast.variant; + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of `Statement` in + // the `createNonterminalVariant` function above. + ((variant: slangAst.Statement['variant']): void => { + if (variant instanceof slangAst.ExpressionStatement) return; + if (variant instanceof slangAst.VariableDeclarationStatement) return; + if (variant instanceof slangAst.TupleDeconstructionStatement) return; + if (variant instanceof slangAst.IfStatement) return; + if (variant instanceof slangAst.ForStatement) return; + if (variant instanceof slangAst.WhileStatement) return; + if (variant instanceof slangAst.DoWhileStatement) return; + if (variant instanceof slangAst.ContinueStatement) return; + if (variant instanceof slangAst.BreakStatement) return; + if (variant instanceof slangAst.ReturnStatement) return; + if (variant instanceof slangAst.ThrowStatement) return; + if (variant instanceof slangAst.EmitStatement) return; + if (variant instanceof slangAst.TryStatement) return; + if (variant instanceof slangAst.RevertStatement) return; + if (variant instanceof slangAst.AssemblyStatement) return; + if (variant instanceof slangAst.Block) return; + if (variant instanceof slangAst.UncheckedBlock) return; + })(variant); + } this.variant = variant instanceof slangAst.Block ? new Block(variant, collected, options) diff --git a/src/slang-nodes/StringExpression.ts b/src/slang-nodes/StringExpression.ts index 93913a0fa..e7999fc3c 100644 --- a/src/slang-nodes/StringExpression.ts +++ b/src/slang-nodes/StringExpression.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -13,14 +13,14 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - ast.StringExpression, + slangAst.StringExpression, StringExpression >([ - [ast.StringLiteral, StringLiteral], - [ast.StringLiterals, StringLiterals], - [ast.HexStringLiteral, HexStringLiteral], - [ast.HexStringLiterals, HexStringLiterals], - [ast.UnicodeStringLiterals, UnicodeStringLiterals] + [slangAst.StringLiteral, StringLiteral], + [slangAst.StringLiterals, StringLiterals], + [slangAst.HexStringLiteral, HexStringLiteral], + [slangAst.HexStringLiterals, HexStringLiterals], + [slangAst.UnicodeStringLiterals, UnicodeStringLiterals] ]); export class StringExpression extends SlangNode { @@ -34,12 +34,23 @@ export class StringExpression extends SlangNode { | UnicodeStringLiterals; constructor( - ast: ast.StringExpression, + ast: slangAst.StringExpression, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of + // `StringExpression` in the `createNonterminalVariant` function above. + ((variant: slangAst.StringExpression['variant']): void => { + if (variant instanceof slangAst.StringLiteral) return; + if (variant instanceof slangAst.StringLiterals) return; + if (variant instanceof slangAst.HexStringLiteral) return; + if (variant instanceof slangAst.HexStringLiterals) return; + if (variant instanceof slangAst.UnicodeStringLiterals) return; + })(ast.variant); + } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/TupleMember.ts b/src/slang-nodes/TupleMember.ts index 3b40666ea..5cd258d71 100644 --- a/src/slang-nodes/TupleMember.ts +++ b/src/slang-nodes/TupleMember.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -10,11 +10,11 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - ast.TupleMember, + slangAst.TupleMember, TupleMember >([ - [ast.TypedTupleMember, TypedTupleMember], - [ast.UntypedTupleMember, UntypedTupleMember] + [slangAst.TypedTupleMember, TypedTupleMember], + [slangAst.UntypedTupleMember, UntypedTupleMember] ]); export class TupleMember extends SlangNode { @@ -23,12 +23,20 @@ export class TupleMember extends SlangNode { variant: TypedTupleMember | UntypedTupleMember; constructor( - ast: ast.TupleMember, + ast: slangAst.TupleMember, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of `TupleMember` + // in the `createNonterminalVariant` function above. + ((variant: slangAst.TupleMember['variant']): void => { + if (variant instanceof slangAst.TypedTupleMember) return; + if (variant instanceof slangAst.UntypedTupleMember) return; + })(ast.variant); + } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/TypeName.ts b/src/slang-nodes/TypeName.ts index faccff25e..7de0f6716 100644 --- a/src/slang-nodes/TypeName.ts +++ b/src/slang-nodes/TypeName.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -13,16 +13,16 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - ast.TypeName, + slangAst.TypeName, TypeName >( [ - [ast.ArrayTypeName, ArrayTypeName], - [ast.FunctionType, FunctionType], - [ast.MappingType, MappingType], - [ast.IdentifierPath, IdentifierPath] + [slangAst.ArrayTypeName, ArrayTypeName], + [slangAst.FunctionType, FunctionType], + [slangAst.MappingType, MappingType], + [slangAst.IdentifierPath, IdentifierPath] ], - [[ast.ElementaryType, ElementaryType]] + [[slangAst.ElementaryType, ElementaryType]] ); export class TypeName extends SlangNode { @@ -36,12 +36,23 @@ export class TypeName extends SlangNode { | IdentifierPath; constructor( - ast: ast.TypeName, + ast: slangAst.TypeName, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of `TypeName` in + // the `createNonterminalVariant` function above. + ((variant: slangAst.TypeName['variant']): void => { + if (variant instanceof slangAst.ArrayTypeName) return; + if (variant instanceof slangAst.FunctionType) return; + if (variant instanceof slangAst.MappingType) return; + if (variant instanceof slangAst.IdentifierPath) return; + if (variant instanceof slangAst.ElementaryType) return; + })(ast.variant); + } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/UsingClause.ts b/src/slang-nodes/UsingClause.ts index dcaedb6d9..11ab568bd 100644 --- a/src/slang-nodes/UsingClause.ts +++ b/src/slang-nodes/UsingClause.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -8,11 +8,11 @@ import { UsingDeconstruction } from './UsingDeconstruction.js'; import type { CollectedMetadata } from '../types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - ast.UsingClause, + slangAst.UsingClause, UsingClause >([ - [ast.IdentifierPath, IdentifierPath], - [ast.UsingDeconstruction, UsingDeconstruction] + [slangAst.IdentifierPath, IdentifierPath], + [slangAst.UsingDeconstruction, UsingDeconstruction] ]); export class UsingClause extends SlangNode { @@ -20,9 +20,17 @@ export class UsingClause extends SlangNode { variant: IdentifierPath | UsingDeconstruction; - constructor(ast: ast.UsingClause, collected: CollectedMetadata) { + constructor(ast: slangAst.UsingClause, collected: CollectedMetadata) { super(ast, collected); + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of `UsingClause` + // in the `createNonterminalVariant` function above. + ((variant: slangAst.UsingClause['variant']): void => { + if (variant instanceof slangAst.IdentifierPath) return; + if (variant instanceof slangAst.UsingDeconstruction) return; + })(ast.variant); + } this.variant = createNonterminalVariant(ast.variant, collected); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/VersionExpression.ts b/src/slang-nodes/VersionExpression.ts index 4b6757835..4ebffbd45 100644 --- a/src/slang-nodes/VersionExpression.ts +++ b/src/slang-nodes/VersionExpression.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -8,11 +8,11 @@ import { VersionTerm } from './VersionTerm.js'; import type { CollectedMetadata } from '../types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - ast.VersionExpression, + slangAst.VersionExpression, VersionExpression >([ - [ast.VersionRange, VersionRange], - [ast.VersionTerm, VersionTerm] + [slangAst.VersionRange, VersionRange], + [slangAst.VersionTerm, VersionTerm] ]); export class VersionExpression extends SlangNode { @@ -20,9 +20,17 @@ export class VersionExpression extends SlangNode { variant: VersionRange | VersionTerm; - constructor(ast: ast.VersionExpression, collected: CollectedMetadata) { + constructor(ast: slangAst.VersionExpression, collected: CollectedMetadata) { super(ast, collected); + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of + // `VersionExpression` in the `createNonterminalVariant` function above. + ((variant: slangAst.VersionExpression['variant']): void => { + if (variant instanceof slangAst.VersionRange) return; + if (variant instanceof slangAst.VersionTerm) return; + })(ast.variant); + } this.variant = createNonterminalVariant(ast.variant, collected); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/YulExpression.ts b/src/slang-nodes/YulExpression.ts index 1019d20a6..8be3ba702 100644 --- a/src/slang-nodes/YulExpression.ts +++ b/src/slang-nodes/YulExpression.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -11,14 +11,14 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - ast.YulExpression, + slangAst.YulExpression, YulExpression >( [ - [ast.YulFunctionCallExpression, YulFunctionCallExpression], - [ast.YulPath, YulPath] + [slangAst.YulFunctionCallExpression, YulFunctionCallExpression], + [slangAst.YulPath, YulPath] ], - [[ast.YulLiteral, YulLiteral]] + [[slangAst.YulLiteral, YulLiteral]] ); export class YulExpression extends SlangNode { @@ -27,12 +27,21 @@ export class YulExpression extends SlangNode { variant: YulFunctionCallExpression | YulLiteral['variant'] | YulPath; constructor( - ast: ast.YulExpression, + ast: slangAst.YulExpression, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of `YulExpression` + // in the `createNonterminalVariant` function above. + ((variant: slangAst.YulExpression['variant']): void => { + if (variant instanceof slangAst.YulFunctionCallExpression) return; + if (variant instanceof slangAst.YulLiteral) return; + if (variant instanceof slangAst.YulPath) return; + })(ast.variant); + } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/YulLiteral.ts b/src/slang-nodes/YulLiteral.ts index 1bffdd584..3f673e822 100644 --- a/src/slang-nodes/YulLiteral.ts +++ b/src/slang-nodes/YulLiteral.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind, TerminalNode as SlangTerminalNode @@ -14,11 +14,11 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - ast.YulLiteral, + slangAst.YulLiteral, YulLiteral >([ - [ast.HexStringLiteral, HexStringLiteral], - [ast.StringLiteral, StringLiteral] + [slangAst.HexStringLiteral, HexStringLiteral], + [slangAst.StringLiteral, StringLiteral] ]); export class YulLiteral extends SlangNode { @@ -27,7 +27,7 @@ export class YulLiteral extends SlangNode { variant: HexStringLiteral | StringLiteral | TerminalNode; constructor( - ast: ast.YulLiteral, + ast: slangAst.YulLiteral, collected: CollectedMetadata, options: ParserOptions ) { @@ -38,6 +38,16 @@ export class YulLiteral extends SlangNode { this.variant = new TerminalNode(variant, collected); return; } + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of `YulLiteral` + // in the `createNonterminalVariant` function above. + (( + variant: Exclude + ): void => { + if (variant instanceof slangAst.HexStringLiteral) return; + if (variant instanceof slangAst.StringLiteral) return; + })(variant); + } this.variant = createNonterminalVariant(variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/YulStatement.ts b/src/slang-nodes/YulStatement.ts index f0342031f..2c306641b 100644 --- a/src/slang-nodes/YulStatement.ts +++ b/src/slang-nodes/YulStatement.ts @@ -66,6 +66,25 @@ export class YulStatement extends SlangNode { super(ast, collected); const variant = ast.variant; + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of `YulStatement` + // in the `createNonterminalVariant` function above. + ((variant: slangAst.YulStatement['variant']): void => { + if (variant instanceof slangAst.YulBlock) return; + if (variant instanceof slangAst.YulFunctionDefinition) return; + if (variant instanceof slangAst.YulVariableDeclarationStatement) return; + if (variant instanceof slangAst.YulVariableAssignmentStatement) return; + if (variant instanceof slangAst.YulStackAssignmentStatement) return; + if (variant instanceof slangAst.YulIfStatement) return; + if (variant instanceof slangAst.YulForStatement) return; + if (variant instanceof slangAst.YulSwitchStatement) return; + if (variant instanceof slangAst.YulLeaveStatement) return; + if (variant instanceof slangAst.YulBreakStatement) return; + if (variant instanceof slangAst.YulContinueStatement) return; + if (variant instanceof slangAst.YulLabel) return; + if (variant instanceof slangAst.YulExpression) return; + })(variant); + } this.variant = variant instanceof slangAst.YulBlock ? new YulBlock(variant, collected, options) diff --git a/src/slang-nodes/YulSwitchCase.ts b/src/slang-nodes/YulSwitchCase.ts index ecee949cd..3d277c956 100644 --- a/src/slang-nodes/YulSwitchCase.ts +++ b/src/slang-nodes/YulSwitchCase.ts @@ -1,4 +1,4 @@ -import * as ast from '@nomicfoundation/slang/ast'; +import * as slangAst from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -10,11 +10,11 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - ast.YulSwitchCase, + slangAst.YulSwitchCase, YulSwitchCase >([ - [ast.YulDefaultCase, YulDefaultCase], - [ast.YulValueCase, YulValueCase] + [slangAst.YulDefaultCase, YulDefaultCase], + [slangAst.YulValueCase, YulValueCase] ]); export class YulSwitchCase extends SlangNode { @@ -23,12 +23,20 @@ export class YulSwitchCase extends SlangNode { variant: YulDefaultCase | YulValueCase; constructor( - ast: ast.YulSwitchCase, + ast: slangAst.YulSwitchCase, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); + if (process.env.NODE_ENV === 'test') { + // This is to ensure that we have handled all variants of `YulSwitchCase` + // in the `createNonterminalVariant` function above. + ((variant: slangAst.YulSwitchCase['variant']): void => { + if (variant instanceof slangAst.YulDefaultCase) return; + if (variant instanceof slangAst.YulValueCase) return; + })(ast.variant); + } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); From 47b9a4ae7800dbad550ef0f7b9eb3146da16d00a Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 24 Feb 2026 00:34:16 -0300 Subject: [PATCH 19/22] adding an _exhaustiveCheck to make sure we check for every possible `variant` --- src/slang-nodes/ArgumentsDeclaration.ts | 2 ++ src/slang-nodes/ContractMember.ts | 2 ++ src/slang-nodes/ContractSpecifier.ts | 2 ++ src/slang-nodes/Expression.ts | 2 ++ src/slang-nodes/FallbackFunctionAttribute.ts | 2 ++ src/slang-nodes/ForStatementInitialization.ts | 2 ++ src/slang-nodes/FunctionAttribute.ts | 2 ++ src/slang-nodes/ImportClause.ts | 2 ++ src/slang-nodes/MappingKeyType.ts | 2 ++ src/slang-nodes/Pragma.ts | 2 ++ src/slang-nodes/ReceiveFunctionAttribute.ts | 2 ++ src/slang-nodes/SourceUnitMember.ts | 2 ++ src/slang-nodes/Statement.ts | 2 ++ src/slang-nodes/StringExpression.ts | 2 ++ src/slang-nodes/TupleMember.ts | 2 ++ src/slang-nodes/TypeName.ts | 2 ++ src/slang-nodes/UsingClause.ts | 2 ++ src/slang-nodes/VersionExpression.ts | 2 ++ src/slang-nodes/YulExpression.ts | 2 ++ src/slang-nodes/YulLiteral.ts | 2 ++ src/slang-nodes/YulStatement.ts | 2 ++ src/slang-nodes/YulSwitchCase.ts | 2 ++ 22 files changed, 44 insertions(+) diff --git a/src/slang-nodes/ArgumentsDeclaration.ts b/src/slang-nodes/ArgumentsDeclaration.ts index 7eec1b2e2..3682cfaed 100644 --- a/src/slang-nodes/ArgumentsDeclaration.ts +++ b/src/slang-nodes/ArgumentsDeclaration.ts @@ -36,6 +36,8 @@ export class ArgumentsDeclaration extends SlangNode { ((variant: slangAst.ArgumentsDeclaration['variant']): void => { if (variant instanceof slangAst.PositionalArgumentsDeclaration) return; if (variant instanceof slangAst.NamedArgumentsDeclaration) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(ast.variant); } this.variant = createNonterminalVariant(ast.variant, collected, options); diff --git a/src/slang-nodes/ContractMember.ts b/src/slang-nodes/ContractMember.ts index ed982586b..e3ba6f89a 100644 --- a/src/slang-nodes/ContractMember.ts +++ b/src/slang-nodes/ContractMember.ts @@ -81,6 +81,8 @@ export class ContractMember extends SlangNode { if (variant instanceof slangAst.StateVariableDefinition) return; if (variant instanceof slangAst.ErrorDefinition) return; if (variant instanceof slangAst.UserDefinedValueTypeDefinition) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(ast.variant); } this.variant = createNonterminalVariant(ast.variant, collected, options); diff --git a/src/slang-nodes/ContractSpecifier.ts b/src/slang-nodes/ContractSpecifier.ts index dc13c86a0..2c3c01663 100644 --- a/src/slang-nodes/ContractSpecifier.ts +++ b/src/slang-nodes/ContractSpecifier.ts @@ -35,6 +35,8 @@ export class ContractSpecifier extends SlangNode { ((variant: slangAst.ContractSpecifier['variant']): void => { if (variant instanceof slangAst.InheritanceSpecifier) return; if (variant instanceof slangAst.StorageLayoutSpecifier) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(ast.variant); } this.variant = createNonterminalVariant(ast.variant, collected, options); diff --git a/src/slang-nodes/Expression.ts b/src/slang-nodes/Expression.ts index 6c8fbc93a..334d7267d 100644 --- a/src/slang-nodes/Expression.ts +++ b/src/slang-nodes/Expression.ts @@ -153,6 +153,8 @@ export class Expression extends SlangNode { if (variant instanceof slangAst.DecimalNumberExpression) return; if (variant instanceof slangAst.StringExpression) return; if (variant instanceof slangAst.ElementaryType) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(variant); } this.variant = createNonterminalVariant(variant, collected, options); diff --git a/src/slang-nodes/FallbackFunctionAttribute.ts b/src/slang-nodes/FallbackFunctionAttribute.ts index 44fb1ab10..77acbbd01 100644 --- a/src/slang-nodes/FallbackFunctionAttribute.ts +++ b/src/slang-nodes/FallbackFunctionAttribute.ts @@ -50,6 +50,8 @@ export class FallbackFunctionAttribute extends SlangNode { ): void => { if (variant instanceof slangAst.ModifierInvocation) return; if (variant instanceof slangAst.OverrideSpecifier) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(variant); } this.variant = createNonterminalVariant(variant, collected, options); diff --git a/src/slang-nodes/ForStatementInitialization.ts b/src/slang-nodes/ForStatementInitialization.ts index dc3e9bcab..fe0ea4002 100644 --- a/src/slang-nodes/ForStatementInitialization.ts +++ b/src/slang-nodes/ForStatementInitialization.ts @@ -57,6 +57,8 @@ export class ForStatementInitialization extends SlangNode { if (variant instanceof slangAst.ExpressionStatement) return; if (variant instanceof slangAst.VariableDeclarationStatement) return; if (variant instanceof slangAst.TupleDeconstructionStatement) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(variant); } this.variant = createNonterminalVariant(variant, collected, options); diff --git a/src/slang-nodes/FunctionAttribute.ts b/src/slang-nodes/FunctionAttribute.ts index bdbd01cb3..e82db4c6c 100644 --- a/src/slang-nodes/FunctionAttribute.ts +++ b/src/slang-nodes/FunctionAttribute.ts @@ -49,6 +49,8 @@ export class FunctionAttribute extends SlangNode { ): void => { if (variant instanceof slangAst.ModifierInvocation) return; if (variant instanceof slangAst.OverrideSpecifier) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(variant); } this.variant = createNonterminalVariant(variant, collected, options); diff --git a/src/slang-nodes/ImportClause.ts b/src/slang-nodes/ImportClause.ts index a3c957d99..458acf0e6 100644 --- a/src/slang-nodes/ImportClause.ts +++ b/src/slang-nodes/ImportClause.ts @@ -38,6 +38,8 @@ export class ImportClause extends SlangNode { if (variant instanceof slangAst.PathImport) return; if (variant instanceof slangAst.NamedImport) return; if (variant instanceof slangAst.ImportDeconstruction) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(ast.variant); } this.variant = createNonterminalVariant(ast.variant, collected, options); diff --git a/src/slang-nodes/MappingKeyType.ts b/src/slang-nodes/MappingKeyType.ts index 5c943c9bf..8a6364dc7 100644 --- a/src/slang-nodes/MappingKeyType.ts +++ b/src/slang-nodes/MappingKeyType.ts @@ -29,6 +29,8 @@ export class MappingKeyType extends SlangNode { ((variant: slangAst.MappingKeyType['variant']): void => { if (variant instanceof slangAst.IdentifierPath) return; if (variant instanceof slangAst.ElementaryType) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(ast.variant); } this.variant = createNonterminalVariant(ast.variant, collected); diff --git a/src/slang-nodes/Pragma.ts b/src/slang-nodes/Pragma.ts index 436a0f651..18a8dbb6c 100644 --- a/src/slang-nodes/Pragma.ts +++ b/src/slang-nodes/Pragma.ts @@ -38,6 +38,8 @@ export class Pragma extends SlangNode { if (variant instanceof slangAst.AbicoderPragma) return; if (variant instanceof slangAst.ExperimentalPragma) return; if (variant instanceof slangAst.VersionPragma) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(ast.variant); } this.variant = createNonterminalVariant(ast.variant, collected, options); diff --git a/src/slang-nodes/ReceiveFunctionAttribute.ts b/src/slang-nodes/ReceiveFunctionAttribute.ts index d61ca3216..bcfca63cd 100644 --- a/src/slang-nodes/ReceiveFunctionAttribute.ts +++ b/src/slang-nodes/ReceiveFunctionAttribute.ts @@ -50,6 +50,8 @@ export class ReceiveFunctionAttribute extends SlangNode { ): void => { if (variant instanceof slangAst.ModifierInvocation) return; if (variant instanceof slangAst.OverrideSpecifier) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(variant); } this.variant = createNonterminalVariant(variant, collected, options); diff --git a/src/slang-nodes/SourceUnitMember.ts b/src/slang-nodes/SourceUnitMember.ts index 043e1ba4d..f91fd9d01 100644 --- a/src/slang-nodes/SourceUnitMember.ts +++ b/src/slang-nodes/SourceUnitMember.ts @@ -81,6 +81,8 @@ export class SourceUnitMember extends SlangNode { if (variant instanceof slangAst.UserDefinedValueTypeDefinition) return; if (variant instanceof slangAst.UsingDirective) return; if (variant instanceof slangAst.EventDefinition) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(ast.variant); } this.variant = createNonterminalVariant(ast.variant, collected, options); diff --git a/src/slang-nodes/Statement.ts b/src/slang-nodes/Statement.ts index d4e35a08f..16bcf0f92 100644 --- a/src/slang-nodes/Statement.ts +++ b/src/slang-nodes/Statement.ts @@ -97,6 +97,8 @@ export class Statement extends SlangNode { if (variant instanceof slangAst.AssemblyStatement) return; if (variant instanceof slangAst.Block) return; if (variant instanceof slangAst.UncheckedBlock) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(variant); } this.variant = diff --git a/src/slang-nodes/StringExpression.ts b/src/slang-nodes/StringExpression.ts index e7999fc3c..9928dc7a2 100644 --- a/src/slang-nodes/StringExpression.ts +++ b/src/slang-nodes/StringExpression.ts @@ -49,6 +49,8 @@ export class StringExpression extends SlangNode { if (variant instanceof slangAst.HexStringLiteral) return; if (variant instanceof slangAst.HexStringLiterals) return; if (variant instanceof slangAst.UnicodeStringLiterals) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(ast.variant); } this.variant = createNonterminalVariant(ast.variant, collected, options); diff --git a/src/slang-nodes/TupleMember.ts b/src/slang-nodes/TupleMember.ts index 5cd258d71..3ec7e346d 100644 --- a/src/slang-nodes/TupleMember.ts +++ b/src/slang-nodes/TupleMember.ts @@ -35,6 +35,8 @@ export class TupleMember extends SlangNode { ((variant: slangAst.TupleMember['variant']): void => { if (variant instanceof slangAst.TypedTupleMember) return; if (variant instanceof slangAst.UntypedTupleMember) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(ast.variant); } this.variant = createNonterminalVariant(ast.variant, collected, options); diff --git a/src/slang-nodes/TypeName.ts b/src/slang-nodes/TypeName.ts index 7de0f6716..e1006fa60 100644 --- a/src/slang-nodes/TypeName.ts +++ b/src/slang-nodes/TypeName.ts @@ -51,6 +51,8 @@ export class TypeName extends SlangNode { if (variant instanceof slangAst.MappingType) return; if (variant instanceof slangAst.IdentifierPath) return; if (variant instanceof slangAst.ElementaryType) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(ast.variant); } this.variant = createNonterminalVariant(ast.variant, collected, options); diff --git a/src/slang-nodes/UsingClause.ts b/src/slang-nodes/UsingClause.ts index 11ab568bd..3168f1516 100644 --- a/src/slang-nodes/UsingClause.ts +++ b/src/slang-nodes/UsingClause.ts @@ -29,6 +29,8 @@ export class UsingClause extends SlangNode { ((variant: slangAst.UsingClause['variant']): void => { if (variant instanceof slangAst.IdentifierPath) return; if (variant instanceof slangAst.UsingDeconstruction) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(ast.variant); } this.variant = createNonterminalVariant(ast.variant, collected); diff --git a/src/slang-nodes/VersionExpression.ts b/src/slang-nodes/VersionExpression.ts index 4ebffbd45..1f85b80bd 100644 --- a/src/slang-nodes/VersionExpression.ts +++ b/src/slang-nodes/VersionExpression.ts @@ -29,6 +29,8 @@ export class VersionExpression extends SlangNode { ((variant: slangAst.VersionExpression['variant']): void => { if (variant instanceof slangAst.VersionRange) return; if (variant instanceof slangAst.VersionTerm) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(ast.variant); } this.variant = createNonterminalVariant(ast.variant, collected); diff --git a/src/slang-nodes/YulExpression.ts b/src/slang-nodes/YulExpression.ts index 8be3ba702..f6a620a4b 100644 --- a/src/slang-nodes/YulExpression.ts +++ b/src/slang-nodes/YulExpression.ts @@ -40,6 +40,8 @@ export class YulExpression extends SlangNode { if (variant instanceof slangAst.YulFunctionCallExpression) return; if (variant instanceof slangAst.YulLiteral) return; if (variant instanceof slangAst.YulPath) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(ast.variant); } this.variant = createNonterminalVariant(ast.variant, collected, options); diff --git a/src/slang-nodes/YulLiteral.ts b/src/slang-nodes/YulLiteral.ts index 3f673e822..e60a8101f 100644 --- a/src/slang-nodes/YulLiteral.ts +++ b/src/slang-nodes/YulLiteral.ts @@ -46,6 +46,8 @@ export class YulLiteral extends SlangNode { ): void => { if (variant instanceof slangAst.HexStringLiteral) return; if (variant instanceof slangAst.StringLiteral) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(variant); } this.variant = createNonterminalVariant(variant, collected, options); diff --git a/src/slang-nodes/YulStatement.ts b/src/slang-nodes/YulStatement.ts index 2c306641b..037a94d20 100644 --- a/src/slang-nodes/YulStatement.ts +++ b/src/slang-nodes/YulStatement.ts @@ -83,6 +83,8 @@ export class YulStatement extends SlangNode { if (variant instanceof slangAst.YulContinueStatement) return; if (variant instanceof slangAst.YulLabel) return; if (variant instanceof slangAst.YulExpression) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(variant); } this.variant = diff --git a/src/slang-nodes/YulSwitchCase.ts b/src/slang-nodes/YulSwitchCase.ts index 3d277c956..e16987df2 100644 --- a/src/slang-nodes/YulSwitchCase.ts +++ b/src/slang-nodes/YulSwitchCase.ts @@ -35,6 +35,8 @@ export class YulSwitchCase extends SlangNode { ((variant: slangAst.YulSwitchCase['variant']): void => { if (variant instanceof slangAst.YulDefaultCase) return; if (variant instanceof slangAst.YulValueCase) return; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _exhaustiveCheck: never = variant; })(ast.variant); } this.variant = createNonterminalVariant(ast.variant, collected, options); From 32198402b43dd0c246f0fe8302fde4475ef348a6 Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 24 Feb 2026 09:35:37 -0300 Subject: [PATCH 20/22] adding a c8 ignore comment to exhaustiveCkecks since we know they'll never be reached --- src/slang-nodes/ArgumentsDeclaration.ts | 1 + src/slang-nodes/ContractMember.ts | 1 + src/slang-nodes/ContractSpecifier.ts | 1 + src/slang-nodes/Expression.ts | 1 + src/slang-nodes/FallbackFunctionAttribute.ts | 1 + src/slang-nodes/ForStatementInitialization.ts | 1 + src/slang-nodes/FunctionAttribute.ts | 1 + src/slang-nodes/ImportClause.ts | 1 + src/slang-nodes/MappingKeyType.ts | 1 + src/slang-nodes/Pragma.ts | 1 + src/slang-nodes/ReceiveFunctionAttribute.ts | 1 + src/slang-nodes/SourceUnitMember.ts | 1 + src/slang-nodes/Statement.ts | 1 + src/slang-nodes/StringExpression.ts | 1 + src/slang-nodes/TupleMember.ts | 1 + src/slang-nodes/TypeName.ts | 1 + src/slang-nodes/UsingClause.ts | 1 + src/slang-nodes/VersionExpression.ts | 1 + src/slang-nodes/YulExpression.ts | 1 + src/slang-nodes/YulLiteral.ts | 1 + src/slang-nodes/YulStatement.ts | 1 + src/slang-nodes/YulSwitchCase.ts | 1 + 22 files changed, 22 insertions(+) diff --git a/src/slang-nodes/ArgumentsDeclaration.ts b/src/slang-nodes/ArgumentsDeclaration.ts index 3682cfaed..d50600984 100644 --- a/src/slang-nodes/ArgumentsDeclaration.ts +++ b/src/slang-nodes/ArgumentsDeclaration.ts @@ -36,6 +36,7 @@ export class ArgumentsDeclaration extends SlangNode { ((variant: slangAst.ArgumentsDeclaration['variant']): void => { if (variant instanceof slangAst.PositionalArgumentsDeclaration) return; if (variant instanceof slangAst.NamedArgumentsDeclaration) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(ast.variant); diff --git a/src/slang-nodes/ContractMember.ts b/src/slang-nodes/ContractMember.ts index e3ba6f89a..d19faf4ea 100644 --- a/src/slang-nodes/ContractMember.ts +++ b/src/slang-nodes/ContractMember.ts @@ -81,6 +81,7 @@ export class ContractMember extends SlangNode { if (variant instanceof slangAst.StateVariableDefinition) return; if (variant instanceof slangAst.ErrorDefinition) return; if (variant instanceof slangAst.UserDefinedValueTypeDefinition) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(ast.variant); diff --git a/src/slang-nodes/ContractSpecifier.ts b/src/slang-nodes/ContractSpecifier.ts index 2c3c01663..16701d2a1 100644 --- a/src/slang-nodes/ContractSpecifier.ts +++ b/src/slang-nodes/ContractSpecifier.ts @@ -35,6 +35,7 @@ export class ContractSpecifier extends SlangNode { ((variant: slangAst.ContractSpecifier['variant']): void => { if (variant instanceof slangAst.InheritanceSpecifier) return; if (variant instanceof slangAst.StorageLayoutSpecifier) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(ast.variant); diff --git a/src/slang-nodes/Expression.ts b/src/slang-nodes/Expression.ts index 334d7267d..dc3060875 100644 --- a/src/slang-nodes/Expression.ts +++ b/src/slang-nodes/Expression.ts @@ -153,6 +153,7 @@ export class Expression extends SlangNode { if (variant instanceof slangAst.DecimalNumberExpression) return; if (variant instanceof slangAst.StringExpression) return; if (variant instanceof slangAst.ElementaryType) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(variant); diff --git a/src/slang-nodes/FallbackFunctionAttribute.ts b/src/slang-nodes/FallbackFunctionAttribute.ts index 77acbbd01..0601fecdd 100644 --- a/src/slang-nodes/FallbackFunctionAttribute.ts +++ b/src/slang-nodes/FallbackFunctionAttribute.ts @@ -50,6 +50,7 @@ export class FallbackFunctionAttribute extends SlangNode { ): void => { if (variant instanceof slangAst.ModifierInvocation) return; if (variant instanceof slangAst.OverrideSpecifier) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(variant); diff --git a/src/slang-nodes/ForStatementInitialization.ts b/src/slang-nodes/ForStatementInitialization.ts index fe0ea4002..807980336 100644 --- a/src/slang-nodes/ForStatementInitialization.ts +++ b/src/slang-nodes/ForStatementInitialization.ts @@ -57,6 +57,7 @@ export class ForStatementInitialization extends SlangNode { if (variant instanceof slangAst.ExpressionStatement) return; if (variant instanceof slangAst.VariableDeclarationStatement) return; if (variant instanceof slangAst.TupleDeconstructionStatement) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(variant); diff --git a/src/slang-nodes/FunctionAttribute.ts b/src/slang-nodes/FunctionAttribute.ts index e82db4c6c..0e761c813 100644 --- a/src/slang-nodes/FunctionAttribute.ts +++ b/src/slang-nodes/FunctionAttribute.ts @@ -49,6 +49,7 @@ export class FunctionAttribute extends SlangNode { ): void => { if (variant instanceof slangAst.ModifierInvocation) return; if (variant instanceof slangAst.OverrideSpecifier) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(variant); diff --git a/src/slang-nodes/ImportClause.ts b/src/slang-nodes/ImportClause.ts index 458acf0e6..d3a72657a 100644 --- a/src/slang-nodes/ImportClause.ts +++ b/src/slang-nodes/ImportClause.ts @@ -38,6 +38,7 @@ export class ImportClause extends SlangNode { if (variant instanceof slangAst.PathImport) return; if (variant instanceof slangAst.NamedImport) return; if (variant instanceof slangAst.ImportDeconstruction) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(ast.variant); diff --git a/src/slang-nodes/MappingKeyType.ts b/src/slang-nodes/MappingKeyType.ts index 8a6364dc7..3bcfd395c 100644 --- a/src/slang-nodes/MappingKeyType.ts +++ b/src/slang-nodes/MappingKeyType.ts @@ -29,6 +29,7 @@ export class MappingKeyType extends SlangNode { ((variant: slangAst.MappingKeyType['variant']): void => { if (variant instanceof slangAst.IdentifierPath) return; if (variant instanceof slangAst.ElementaryType) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(ast.variant); diff --git a/src/slang-nodes/Pragma.ts b/src/slang-nodes/Pragma.ts index 18a8dbb6c..9be27511b 100644 --- a/src/slang-nodes/Pragma.ts +++ b/src/slang-nodes/Pragma.ts @@ -38,6 +38,7 @@ export class Pragma extends SlangNode { if (variant instanceof slangAst.AbicoderPragma) return; if (variant instanceof slangAst.ExperimentalPragma) return; if (variant instanceof slangAst.VersionPragma) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(ast.variant); diff --git a/src/slang-nodes/ReceiveFunctionAttribute.ts b/src/slang-nodes/ReceiveFunctionAttribute.ts index bcfca63cd..640e08b4c 100644 --- a/src/slang-nodes/ReceiveFunctionAttribute.ts +++ b/src/slang-nodes/ReceiveFunctionAttribute.ts @@ -50,6 +50,7 @@ export class ReceiveFunctionAttribute extends SlangNode { ): void => { if (variant instanceof slangAst.ModifierInvocation) return; if (variant instanceof slangAst.OverrideSpecifier) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(variant); diff --git a/src/slang-nodes/SourceUnitMember.ts b/src/slang-nodes/SourceUnitMember.ts index f91fd9d01..545b782ce 100644 --- a/src/slang-nodes/SourceUnitMember.ts +++ b/src/slang-nodes/SourceUnitMember.ts @@ -81,6 +81,7 @@ export class SourceUnitMember extends SlangNode { if (variant instanceof slangAst.UserDefinedValueTypeDefinition) return; if (variant instanceof slangAst.UsingDirective) return; if (variant instanceof slangAst.EventDefinition) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(ast.variant); diff --git a/src/slang-nodes/Statement.ts b/src/slang-nodes/Statement.ts index 16bcf0f92..8c436b2b0 100644 --- a/src/slang-nodes/Statement.ts +++ b/src/slang-nodes/Statement.ts @@ -97,6 +97,7 @@ export class Statement extends SlangNode { if (variant instanceof slangAst.AssemblyStatement) return; if (variant instanceof slangAst.Block) return; if (variant instanceof slangAst.UncheckedBlock) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(variant); diff --git a/src/slang-nodes/StringExpression.ts b/src/slang-nodes/StringExpression.ts index 9928dc7a2..441ca1e74 100644 --- a/src/slang-nodes/StringExpression.ts +++ b/src/slang-nodes/StringExpression.ts @@ -49,6 +49,7 @@ export class StringExpression extends SlangNode { if (variant instanceof slangAst.HexStringLiteral) return; if (variant instanceof slangAst.HexStringLiterals) return; if (variant instanceof slangAst.UnicodeStringLiterals) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(ast.variant); diff --git a/src/slang-nodes/TupleMember.ts b/src/slang-nodes/TupleMember.ts index 3ec7e346d..d15797864 100644 --- a/src/slang-nodes/TupleMember.ts +++ b/src/slang-nodes/TupleMember.ts @@ -35,6 +35,7 @@ export class TupleMember extends SlangNode { ((variant: slangAst.TupleMember['variant']): void => { if (variant instanceof slangAst.TypedTupleMember) return; if (variant instanceof slangAst.UntypedTupleMember) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(ast.variant); diff --git a/src/slang-nodes/TypeName.ts b/src/slang-nodes/TypeName.ts index e1006fa60..1f22a99cb 100644 --- a/src/slang-nodes/TypeName.ts +++ b/src/slang-nodes/TypeName.ts @@ -51,6 +51,7 @@ export class TypeName extends SlangNode { if (variant instanceof slangAst.MappingType) return; if (variant instanceof slangAst.IdentifierPath) return; if (variant instanceof slangAst.ElementaryType) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(ast.variant); diff --git a/src/slang-nodes/UsingClause.ts b/src/slang-nodes/UsingClause.ts index 3168f1516..f939ea809 100644 --- a/src/slang-nodes/UsingClause.ts +++ b/src/slang-nodes/UsingClause.ts @@ -29,6 +29,7 @@ export class UsingClause extends SlangNode { ((variant: slangAst.UsingClause['variant']): void => { if (variant instanceof slangAst.IdentifierPath) return; if (variant instanceof slangAst.UsingDeconstruction) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(ast.variant); diff --git a/src/slang-nodes/VersionExpression.ts b/src/slang-nodes/VersionExpression.ts index 1f85b80bd..2bb32230a 100644 --- a/src/slang-nodes/VersionExpression.ts +++ b/src/slang-nodes/VersionExpression.ts @@ -29,6 +29,7 @@ export class VersionExpression extends SlangNode { ((variant: slangAst.VersionExpression['variant']): void => { if (variant instanceof slangAst.VersionRange) return; if (variant instanceof slangAst.VersionTerm) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(ast.variant); diff --git a/src/slang-nodes/YulExpression.ts b/src/slang-nodes/YulExpression.ts index f6a620a4b..787b8e048 100644 --- a/src/slang-nodes/YulExpression.ts +++ b/src/slang-nodes/YulExpression.ts @@ -40,6 +40,7 @@ export class YulExpression extends SlangNode { if (variant instanceof slangAst.YulFunctionCallExpression) return; if (variant instanceof slangAst.YulLiteral) return; if (variant instanceof slangAst.YulPath) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(ast.variant); diff --git a/src/slang-nodes/YulLiteral.ts b/src/slang-nodes/YulLiteral.ts index e60a8101f..44e7b277a 100644 --- a/src/slang-nodes/YulLiteral.ts +++ b/src/slang-nodes/YulLiteral.ts @@ -46,6 +46,7 @@ export class YulLiteral extends SlangNode { ): void => { if (variant instanceof slangAst.HexStringLiteral) return; if (variant instanceof slangAst.StringLiteral) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(variant); diff --git a/src/slang-nodes/YulStatement.ts b/src/slang-nodes/YulStatement.ts index 037a94d20..d63a2c4d2 100644 --- a/src/slang-nodes/YulStatement.ts +++ b/src/slang-nodes/YulStatement.ts @@ -83,6 +83,7 @@ export class YulStatement extends SlangNode { if (variant instanceof slangAst.YulContinueStatement) return; if (variant instanceof slangAst.YulLabel) return; if (variant instanceof slangAst.YulExpression) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(variant); diff --git a/src/slang-nodes/YulSwitchCase.ts b/src/slang-nodes/YulSwitchCase.ts index e16987df2..36c866934 100644 --- a/src/slang-nodes/YulSwitchCase.ts +++ b/src/slang-nodes/YulSwitchCase.ts @@ -35,6 +35,7 @@ export class YulSwitchCase extends SlangNode { ((variant: slangAst.YulSwitchCase['variant']): void => { if (variant instanceof slangAst.YulDefaultCase) return; if (variant instanceof slangAst.YulValueCase) return; + /* c8 ignore next 2 */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const _exhaustiveCheck: never = variant; })(ast.variant); From 0025a48f96770446a916facdc5633f7f6d677f88 Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 25 Feb 2026 23:01:02 -0300 Subject: [PATCH 21/22] Moving all the exhaustive coverage check to the tests --- .c8rc | 2 +- check-coverage/ArgumentsDeclaration.ts | 12 ++ check-coverage/ContractMember.ts | 22 ++++ check-coverage/ContractSpecifier.ts | 11 ++ check-coverage/Expression.ts | 38 ++++++ check-coverage/FallbackFunctionAttribute.ts | 14 +++ check-coverage/ForStatementInitialization.ts | 15 +++ check-coverage/FunctionAttribute.ts | 13 +++ check-coverage/ImportClause.ts | 12 ++ check-coverage/MappingKeyType.ts | 11 ++ check-coverage/Pragma.ts | 10 ++ check-coverage/ReceiveFunctionAttribute.ts | 14 +++ check-coverage/SourceUnitMember.ts | 22 ++++ check-coverage/Statement.ts | 24 ++++ check-coverage/StringExpression.ts | 14 +++ check-coverage/TupleMember.ts | 11 ++ check-coverage/TypeName.ts | 12 ++ check-coverage/UsingClause.ts | 11 ++ check-coverage/VersionExpression.ts | 11 ++ check-coverage/YulExpression.ts | 12 ++ check-coverage/YulLiteral.ts | 13 +++ check-coverage/YulStatement.ts | 22 ++++ check-coverage/YulSwitchCase.ts | 11 ++ check-coverage/index.ts | 109 ++++++++++++++++++ eslint.config.mjs | 1 + src/slang-nodes/ArgumentsDeclaration.ts | 22 +--- src/slang-nodes/ContractMember.ts | 54 +++------ src/slang-nodes/ContractSpecifier.ts | 21 +--- src/slang-nodes/Expression.ts | 98 +++++----------- src/slang-nodes/FallbackFunctionAttribute.ts | 27 +---- src/slang-nodes/ForStatementInitialization.ts | 30 +---- src/slang-nodes/FunctionAttribute.ts | 26 +---- src/slang-nodes/ImportClause.ts | 24 +--- src/slang-nodes/MappingKeyType.ts | 21 +--- src/slang-nodes/Pragma.ts | 24 +--- src/slang-nodes/ReceiveFunctionAttribute.ts | 27 +---- src/slang-nodes/SourceUnitMember.ts | 54 +++------ src/slang-nodes/Statement.ts | 26 ----- src/slang-nodes/StringExpression.ts | 30 ++--- src/slang-nodes/TupleMember.ts | 21 +--- src/slang-nodes/TypeName.ts | 30 ++--- src/slang-nodes/UsingClause.ts | 21 +--- src/slang-nodes/VersionExpression.ts | 21 +--- src/slang-nodes/YulExpression.ts | 24 +--- src/slang-nodes/YulLiteral.ts | 23 +--- src/slang-nodes/YulStatement.ts | 22 ---- src/slang-nodes/YulSwitchCase.ts | 21 +--- test.config.js | 3 +- tests/config/get-check-coverage.js | 16 +++ tests/config/run-format-test.js | 38 +++--- 50 files changed, 642 insertions(+), 529 deletions(-) create mode 100644 check-coverage/ArgumentsDeclaration.ts create mode 100644 check-coverage/ContractMember.ts create mode 100644 check-coverage/ContractSpecifier.ts create mode 100644 check-coverage/Expression.ts create mode 100644 check-coverage/FallbackFunctionAttribute.ts create mode 100644 check-coverage/ForStatementInitialization.ts create mode 100644 check-coverage/FunctionAttribute.ts create mode 100644 check-coverage/ImportClause.ts create mode 100644 check-coverage/MappingKeyType.ts create mode 100644 check-coverage/Pragma.ts create mode 100644 check-coverage/ReceiveFunctionAttribute.ts create mode 100644 check-coverage/SourceUnitMember.ts create mode 100644 check-coverage/Statement.ts create mode 100644 check-coverage/StringExpression.ts create mode 100644 check-coverage/TupleMember.ts create mode 100644 check-coverage/TypeName.ts create mode 100644 check-coverage/UsingClause.ts create mode 100644 check-coverage/VersionExpression.ts create mode 100644 check-coverage/YulExpression.ts create mode 100644 check-coverage/YulLiteral.ts create mode 100644 check-coverage/YulStatement.ts create mode 100644 check-coverage/YulSwitchCase.ts create mode 100644 check-coverage/index.ts create mode 100644 tests/config/get-check-coverage.js diff --git a/.c8rc b/.c8rc index 8510c2fd2..963c0cde1 100644 --- a/.c8rc +++ b/.c8rc @@ -5,7 +5,7 @@ "functions": 90, "statements": 90, "exclude": ["/node_modules/"], - "include": ["src/**/*.ts"], + "include": ["src/**/*.ts", "check-coverage/**/*.ts"], "reporter": ["lcov", "text"], "temp-dir": "./coverage/" } diff --git a/check-coverage/ArgumentsDeclaration.ts b/check-coverage/ArgumentsDeclaration.ts new file mode 100644 index 000000000..1d276bf1d --- /dev/null +++ b/check-coverage/ArgumentsDeclaration.ts @@ -0,0 +1,12 @@ +import * as ast from '@nomicfoundation/slang/ast'; + +// This is to ensure that we have handled all variants of +// `ArgumentsDeclaration`. +export function checkArgumentsDeclarationVariant( + variant: ast.ArgumentsDeclaration['variant'] +): void { + if (variant instanceof ast.PositionalArgumentsDeclaration) return; + if (variant instanceof ast.NamedArgumentsDeclaration) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/ContractMember.ts b/check-coverage/ContractMember.ts new file mode 100644 index 000000000..101cf9a71 --- /dev/null +++ b/check-coverage/ContractMember.ts @@ -0,0 +1,22 @@ +import * as ast from '@nomicfoundation/slang/ast'; + +// This is to ensure that we have handled all variants of `ContractMember`. +export function checkContractMemberVariant( + variant: ast.ContractMember['variant'] +): void { + if (variant instanceof ast.UsingDirective) return; + if (variant instanceof ast.FunctionDefinition) return; + if (variant instanceof ast.ConstructorDefinition) return; + if (variant instanceof ast.ReceiveFunctionDefinition) return; + if (variant instanceof ast.FallbackFunctionDefinition) return; + if (variant instanceof ast.UnnamedFunctionDefinition) return; + if (variant instanceof ast.ModifierDefinition) return; + if (variant instanceof ast.StructDefinition) return; + if (variant instanceof ast.EnumDefinition) return; + if (variant instanceof ast.EventDefinition) return; + if (variant instanceof ast.StateVariableDefinition) return; + if (variant instanceof ast.ErrorDefinition) return; + if (variant instanceof ast.UserDefinedValueTypeDefinition) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/ContractSpecifier.ts b/check-coverage/ContractSpecifier.ts new file mode 100644 index 000000000..849f9bf00 --- /dev/null +++ b/check-coverage/ContractSpecifier.ts @@ -0,0 +1,11 @@ +import * as ast from '@nomicfoundation/slang/ast'; + +// This is to ensure that we have handled all variants of `ContractSpecifier`. +export function checkContractSpecifierVariant( + variant: ast.ContractSpecifier['variant'] +): void { + if (variant instanceof ast.InheritanceSpecifier) return; + if (variant instanceof ast.StorageLayoutSpecifier) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/Expression.ts b/check-coverage/Expression.ts new file mode 100644 index 000000000..e35eff6c2 --- /dev/null +++ b/check-coverage/Expression.ts @@ -0,0 +1,38 @@ +import * as ast from '@nomicfoundation/slang/ast'; +import { TerminalNode } from '@nomicfoundation/slang/cst'; + +// This is to ensure that we have handled all variants of `Expression`. +export function checkExpressionVariant( + variant: ast.Expression['variant'] +): void { + if (variant instanceof TerminalNode) return; + if (variant instanceof ast.AssignmentExpression) return; + if (variant instanceof ast.ConditionalExpression) return; + if (variant instanceof ast.OrExpression) return; + if (variant instanceof ast.AndExpression) return; + if (variant instanceof ast.EqualityExpression) return; + if (variant instanceof ast.InequalityExpression) return; + if (variant instanceof ast.BitwiseOrExpression) return; + if (variant instanceof ast.BitwiseXorExpression) return; + if (variant instanceof ast.BitwiseAndExpression) return; + if (variant instanceof ast.ShiftExpression) return; + if (variant instanceof ast.AdditiveExpression) return; + if (variant instanceof ast.MultiplicativeExpression) return; + if (variant instanceof ast.ExponentiationExpression) return; + if (variant instanceof ast.PostfixExpression) return; + if (variant instanceof ast.PrefixExpression) return; + if (variant instanceof ast.FunctionCallExpression) return; + if (variant instanceof ast.CallOptionsExpression) return; + if (variant instanceof ast.MemberAccessExpression) return; + if (variant instanceof ast.IndexAccessExpression) return; + if (variant instanceof ast.NewExpression) return; + if (variant instanceof ast.TupleExpression) return; + if (variant instanceof ast.TypeExpression) return; + if (variant instanceof ast.ArrayExpression) return; + if (variant instanceof ast.HexNumberExpression) return; + if (variant instanceof ast.DecimalNumberExpression) return; + if (variant instanceof ast.StringExpression) return; + if (variant instanceof ast.ElementaryType) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/FallbackFunctionAttribute.ts b/check-coverage/FallbackFunctionAttribute.ts new file mode 100644 index 000000000..3dfb70ecb --- /dev/null +++ b/check-coverage/FallbackFunctionAttribute.ts @@ -0,0 +1,14 @@ +import * as ast from '@nomicfoundation/slang/ast'; +import { TerminalNode } from '@nomicfoundation/slang/cst'; + +// This is to ensure that we have handled all variants of +// `FallbackFunctionAttribute`. +export function checkFallbackFunctionAttributeVariant( + variant: ast.FallbackFunctionAttribute['variant'] +): void { + if (variant instanceof TerminalNode) return; + if (variant instanceof ast.ModifierInvocation) return; + if (variant instanceof ast.OverrideSpecifier) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/ForStatementInitialization.ts b/check-coverage/ForStatementInitialization.ts new file mode 100644 index 000000000..1c87d4f4c --- /dev/null +++ b/check-coverage/ForStatementInitialization.ts @@ -0,0 +1,15 @@ +import * as ast from '@nomicfoundation/slang/ast'; +import { TerminalNode } from '@nomicfoundation/slang/cst'; + +// This is to ensure that we have handled all variants of +// `ForStatementInitialization`. +export function checkForStatementInitializationVariant( + variant: ast.ForStatementInitialization['variant'] +): void { + if (variant instanceof TerminalNode) return; + if (variant instanceof ast.ExpressionStatement) return; + if (variant instanceof ast.VariableDeclarationStatement) return; + if (variant instanceof ast.TupleDeconstructionStatement) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/FunctionAttribute.ts b/check-coverage/FunctionAttribute.ts new file mode 100644 index 000000000..ad31eebb1 --- /dev/null +++ b/check-coverage/FunctionAttribute.ts @@ -0,0 +1,13 @@ +import * as ast from '@nomicfoundation/slang/ast'; +import { TerminalNode } from '@nomicfoundation/slang/cst'; + +// This is to ensure that we have handled all variants of `FunctionAttribute`. +export function checkFunctionAttributeVariant( + variant: ast.FunctionAttribute['variant'] +): void { + if (variant instanceof TerminalNode) return; + if (variant instanceof ast.ModifierInvocation) return; + if (variant instanceof ast.OverrideSpecifier) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/ImportClause.ts b/check-coverage/ImportClause.ts new file mode 100644 index 000000000..e73c338c3 --- /dev/null +++ b/check-coverage/ImportClause.ts @@ -0,0 +1,12 @@ +import * as ast from '@nomicfoundation/slang/ast'; + +// This is to ensure that we have handled all variants of `ImportClause`. +export function checkImportClauseVariant( + variant: ast.ImportClause['variant'] +): void { + if (variant instanceof ast.PathImport) return; + if (variant instanceof ast.NamedImport) return; + if (variant instanceof ast.ImportDeconstruction) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/MappingKeyType.ts b/check-coverage/MappingKeyType.ts new file mode 100644 index 000000000..dd151e410 --- /dev/null +++ b/check-coverage/MappingKeyType.ts @@ -0,0 +1,11 @@ +import * as ast from '@nomicfoundation/slang/ast'; + +// This is to ensure that we have handled all variants of `MappingKeyType`. +export function checkMappingKeyTypeVariant( + variant: ast.MappingKeyType['variant'] +): void { + if (variant instanceof ast.IdentifierPath) return; + if (variant instanceof ast.ElementaryType) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/Pragma.ts b/check-coverage/Pragma.ts new file mode 100644 index 000000000..ba9fbfd25 --- /dev/null +++ b/check-coverage/Pragma.ts @@ -0,0 +1,10 @@ +import * as ast from '@nomicfoundation/slang/ast'; + +// This is to ensure that we have handled all variants of `Pragma`. +export function checkPragmaVariant(variant: ast.Pragma['variant']): void { + if (variant instanceof ast.AbicoderPragma) return; + if (variant instanceof ast.ExperimentalPragma) return; + if (variant instanceof ast.VersionPragma) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/ReceiveFunctionAttribute.ts b/check-coverage/ReceiveFunctionAttribute.ts new file mode 100644 index 000000000..7ff3090a3 --- /dev/null +++ b/check-coverage/ReceiveFunctionAttribute.ts @@ -0,0 +1,14 @@ +import * as ast from '@nomicfoundation/slang/ast'; +import { TerminalNode } from '@nomicfoundation/slang/cst'; + +// This is to ensure that we have handled all variants of +// `ReceiveFunctionAttribute`. +export function checkReceiveFunctionAttributeVariant( + variant: ast.ReceiveFunctionAttribute['variant'] +): void { + if (variant instanceof TerminalNode) return; + if (variant instanceof ast.ModifierInvocation) return; + if (variant instanceof ast.OverrideSpecifier) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/SourceUnitMember.ts b/check-coverage/SourceUnitMember.ts new file mode 100644 index 000000000..57235613d --- /dev/null +++ b/check-coverage/SourceUnitMember.ts @@ -0,0 +1,22 @@ +import * as ast from '@nomicfoundation/slang/ast'; + +// This is to ensure that we have handled all variants of `SourceUnitMember`. +export function checkSourceUnitMemberVariant( + variant: ast.SourceUnitMember['variant'] +): void { + if (variant instanceof ast.PragmaDirective) return; + if (variant instanceof ast.ImportDirective) return; + if (variant instanceof ast.ContractDefinition) return; + if (variant instanceof ast.InterfaceDefinition) return; + if (variant instanceof ast.LibraryDefinition) return; + if (variant instanceof ast.StructDefinition) return; + if (variant instanceof ast.EnumDefinition) return; + if (variant instanceof ast.FunctionDefinition) return; + if (variant instanceof ast.ConstantDefinition) return; + if (variant instanceof ast.ErrorDefinition) return; + if (variant instanceof ast.UserDefinedValueTypeDefinition) return; + if (variant instanceof ast.UsingDirective) return; + if (variant instanceof ast.EventDefinition) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/Statement.ts b/check-coverage/Statement.ts new file mode 100644 index 000000000..ea8be26c9 --- /dev/null +++ b/check-coverage/Statement.ts @@ -0,0 +1,24 @@ +import * as ast from '@nomicfoundation/slang/ast'; + +// This is to ensure that we have handled all variants of `Statement`. +export function checkStatementVariant(variant: ast.Statement['variant']): void { + if (variant instanceof ast.ExpressionStatement) return; + if (variant instanceof ast.VariableDeclarationStatement) return; + if (variant instanceof ast.TupleDeconstructionStatement) return; + if (variant instanceof ast.IfStatement) return; + if (variant instanceof ast.ForStatement) return; + if (variant instanceof ast.WhileStatement) return; + if (variant instanceof ast.DoWhileStatement) return; + if (variant instanceof ast.ContinueStatement) return; + if (variant instanceof ast.BreakStatement) return; + if (variant instanceof ast.ReturnStatement) return; + if (variant instanceof ast.ThrowStatement) return; + if (variant instanceof ast.EmitStatement) return; + if (variant instanceof ast.TryStatement) return; + if (variant instanceof ast.RevertStatement) return; + if (variant instanceof ast.AssemblyStatement) return; + if (variant instanceof ast.Block) return; + if (variant instanceof ast.UncheckedBlock) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/StringExpression.ts b/check-coverage/StringExpression.ts new file mode 100644 index 000000000..0b6cec709 --- /dev/null +++ b/check-coverage/StringExpression.ts @@ -0,0 +1,14 @@ +import * as ast from '@nomicfoundation/slang/ast'; + +// This is to ensure that we have handled all variants of `StringExpression`. +export function checkStringExpressionVariant( + variant: ast.StringExpression['variant'] +): void { + if (variant instanceof ast.StringLiteral) return; + if (variant instanceof ast.StringLiterals) return; + if (variant instanceof ast.HexStringLiteral) return; + if (variant instanceof ast.HexStringLiterals) return; + if (variant instanceof ast.UnicodeStringLiterals) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/TupleMember.ts b/check-coverage/TupleMember.ts new file mode 100644 index 000000000..f01e00b33 --- /dev/null +++ b/check-coverage/TupleMember.ts @@ -0,0 +1,11 @@ +import * as ast from '@nomicfoundation/slang/ast'; + +// This is to ensure that we have handled all variants of `TupleMember`. +export function checkTupleMemberVariant( + variant: ast.TupleMember['variant'] +): void { + if (variant instanceof ast.TypedTupleMember) return; + if (variant instanceof ast.UntypedTupleMember) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/TypeName.ts b/check-coverage/TypeName.ts new file mode 100644 index 000000000..257770e72 --- /dev/null +++ b/check-coverage/TypeName.ts @@ -0,0 +1,12 @@ +import * as ast from '@nomicfoundation/slang/ast'; + +// This is to ensure that we have handled all variants of `TypeName`. +export function checkTypeNameVariant(variant: ast.TypeName['variant']): void { + if (variant instanceof ast.ArrayTypeName) return; + if (variant instanceof ast.FunctionType) return; + if (variant instanceof ast.MappingType) return; + if (variant instanceof ast.IdentifierPath) return; + if (variant instanceof ast.ElementaryType) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/UsingClause.ts b/check-coverage/UsingClause.ts new file mode 100644 index 000000000..f45f0ba78 --- /dev/null +++ b/check-coverage/UsingClause.ts @@ -0,0 +1,11 @@ +import * as ast from '@nomicfoundation/slang/ast'; + +// This is to ensure that we have handled all variants of `UsingClause`. +export function checkUsingClauseVariant( + variant: ast.UsingClause['variant'] +): void { + if (variant instanceof ast.IdentifierPath) return; + if (variant instanceof ast.UsingDeconstruction) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/VersionExpression.ts b/check-coverage/VersionExpression.ts new file mode 100644 index 000000000..4de8195c6 --- /dev/null +++ b/check-coverage/VersionExpression.ts @@ -0,0 +1,11 @@ +import * as ast from '@nomicfoundation/slang/ast'; + +// This is to ensure that we have handled all variants of `VersionExpression`. +export function checkVersionExpressionVariant( + variant: ast.VersionExpression['variant'] +): void { + if (variant instanceof ast.VersionRange) return; + if (variant instanceof ast.VersionTerm) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/YulExpression.ts b/check-coverage/YulExpression.ts new file mode 100644 index 000000000..0a148347e --- /dev/null +++ b/check-coverage/YulExpression.ts @@ -0,0 +1,12 @@ +import * as ast from '@nomicfoundation/slang/ast'; + +// This is to ensure that we have handled all variants of `YulExpression`. +export function checkYulExpressionVariant( + variant: ast.YulExpression['variant'] +): void { + if (variant instanceof ast.YulFunctionCallExpression) return; + if (variant instanceof ast.YulLiteral) return; + if (variant instanceof ast.YulPath) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/YulLiteral.ts b/check-coverage/YulLiteral.ts new file mode 100644 index 000000000..8a5b2c5be --- /dev/null +++ b/check-coverage/YulLiteral.ts @@ -0,0 +1,13 @@ +import * as ast from '@nomicfoundation/slang/ast'; +import { TerminalNode } from '@nomicfoundation/slang/cst'; + +// This is to ensure that we have handled all variants of `YulLiteral`. +export function checkYulLiteralVariant( + variant: ast.YulLiteral['variant'] +): void { + if (variant instanceof TerminalNode) return; + if (variant instanceof ast.HexStringLiteral) return; + if (variant instanceof ast.StringLiteral) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/YulStatement.ts b/check-coverage/YulStatement.ts new file mode 100644 index 000000000..e0464f394 --- /dev/null +++ b/check-coverage/YulStatement.ts @@ -0,0 +1,22 @@ +import * as ast from '@nomicfoundation/slang/ast'; + +// This is to ensure that we have handled all variants of `YulStatement`. +export function checkYulStatementVariant( + variant: ast.YulStatement['variant'] +): void { + if (variant instanceof ast.YulBlock) return; + if (variant instanceof ast.YulFunctionDefinition) return; + if (variant instanceof ast.YulVariableDeclarationStatement) return; + if (variant instanceof ast.YulVariableAssignmentStatement) return; + if (variant instanceof ast.YulStackAssignmentStatement) return; + if (variant instanceof ast.YulIfStatement) return; + if (variant instanceof ast.YulForStatement) return; + if (variant instanceof ast.YulSwitchStatement) return; + if (variant instanceof ast.YulLeaveStatement) return; + if (variant instanceof ast.YulBreakStatement) return; + if (variant instanceof ast.YulContinueStatement) return; + if (variant instanceof ast.YulLabel) return; + if (variant instanceof ast.YulExpression) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/YulSwitchCase.ts b/check-coverage/YulSwitchCase.ts new file mode 100644 index 000000000..2bf005cdc --- /dev/null +++ b/check-coverage/YulSwitchCase.ts @@ -0,0 +1,11 @@ +import * as ast from '@nomicfoundation/slang/ast'; + +// This is to ensure that we have handled all variants of `YulSwitchCase`. +export function checkYulSwitchCaseVariant( + variant: ast.YulSwitchCase['variant'] +): void { + if (variant instanceof ast.YulDefaultCase) return; + if (variant instanceof ast.YulValueCase) return; + /* c8 ignore next 2 */ + const _exhaustiveCheck: never = variant; +} diff --git a/check-coverage/index.ts b/check-coverage/index.ts new file mode 100644 index 000000000..86c1ff077 --- /dev/null +++ b/check-coverage/index.ts @@ -0,0 +1,109 @@ +import * as ast from '@nomicfoundation/slang/ast'; +import { NonterminalKind, NonterminalNode } from '@nomicfoundation/slang/cst'; +import { checkArgumentsDeclarationVariant } from './ArgumentsDeclaration.js'; +import { checkContractMemberVariant } from './ContractMember.js'; +import { checkContractSpecifierVariant } from './ContractSpecifier.js'; +import { checkExpressionVariant } from './Expression.js'; +import { checkFallbackFunctionAttributeVariant } from './FallbackFunctionAttribute.js'; +import { checkForStatementInitializationVariant } from './ForStatementInitialization.js'; +import { checkFunctionAttributeVariant } from './FunctionAttribute.js'; +import { checkImportClauseVariant } from './ImportClause.js'; +import { checkMappingKeyTypeVariant } from './MappingKeyType.js'; +import { checkPragmaVariant } from './Pragma.js'; +import { checkReceiveFunctionAttributeVariant } from './ReceiveFunctionAttribute.js'; +import { checkSourceUnitMemberVariant } from './SourceUnitMember.js'; +import { checkStatementVariant } from './Statement.js'; +import { checkStringExpressionVariant } from './StringExpression.js'; +import { checkTupleMemberVariant } from './TupleMember.js'; +import { checkTypeNameVariant } from './TypeName.js'; +import { checkUsingClauseVariant } from './UsingClause.js'; +import { checkVersionExpressionVariant } from './VersionExpression.js'; +import { checkYulExpressionVariant } from './YulExpression.js'; +import { checkYulLiteralVariant } from './YulLiteral.js'; +import { checkYulStatementVariant } from './YulStatement.js'; +import { checkYulSwitchCaseVariant } from './YulSwitchCase.js'; + +export function checkCoverage(cst: NonterminalNode): void { + switch (cst.kind) { + case NonterminalKind.ArgumentsDeclaration: + checkArgumentsDeclarationVariant( + new ast.ArgumentsDeclaration(cst).variant + ); + break; + case NonterminalKind.ContractMember: + checkContractMemberVariant(new ast.ContractMember(cst).variant); + break; + case NonterminalKind.ContractSpecifier: + checkContractSpecifierVariant(new ast.ContractSpecifier(cst).variant); + break; + case NonterminalKind.Expression: + checkExpressionVariant(new ast.Expression(cst).variant); + break; + case NonterminalKind.FallbackFunctionAttribute: + checkFallbackFunctionAttributeVariant( + new ast.FallbackFunctionAttribute(cst).variant + ); + break; + case NonterminalKind.ForStatementInitialization: + checkForStatementInitializationVariant( + new ast.ForStatementInitialization(cst).variant + ); + break; + case NonterminalKind.FunctionAttribute: + checkFunctionAttributeVariant(new ast.FunctionAttribute(cst).variant); + break; + case NonterminalKind.ImportClause: + checkImportClauseVariant(new ast.ImportClause(cst).variant); + break; + case NonterminalKind.MappingKeyType: + checkMappingKeyTypeVariant(new ast.MappingKeyType(cst).variant); + break; + case NonterminalKind.Pragma: + checkPragmaVariant(new ast.Pragma(cst).variant); + break; + case NonterminalKind.ReceiveFunctionAttribute: + checkReceiveFunctionAttributeVariant( + new ast.ReceiveFunctionAttribute(cst).variant + ); + break; + case NonterminalKind.SourceUnitMember: + checkSourceUnitMemberVariant(new ast.SourceUnitMember(cst).variant); + break; + case NonterminalKind.Statement: + checkStatementVariant(new ast.Statement(cst).variant); + break; + case NonterminalKind.StringExpression: + checkStringExpressionVariant(new ast.StringExpression(cst).variant); + break; + case NonterminalKind.TupleMember: + checkTupleMemberVariant(new ast.TupleMember(cst).variant); + break; + case NonterminalKind.TypeName: + checkTypeNameVariant(new ast.TypeName(cst).variant); + break; + case NonterminalKind.UsingClause: + checkUsingClauseVariant(new ast.UsingClause(cst).variant); + break; + case NonterminalKind.VersionExpression: + checkVersionExpressionVariant(new ast.VersionExpression(cst).variant); + break; + case NonterminalKind.YulExpression: + checkYulExpressionVariant(new ast.YulExpression(cst).variant); + break; + case NonterminalKind.YulLiteral: + checkYulLiteralVariant(new ast.YulLiteral(cst).variant); + break; + case NonterminalKind.YulStatement: + checkYulStatementVariant(new ast.YulStatement(cst).variant); + break; + case NonterminalKind.YulSwitchCase: + checkYulSwitchCaseVariant(new ast.YulSwitchCase(cst).variant); + break; + } + + for (const { node } of cst.children()) { + if (node instanceof NonterminalNode) { + checkCoverage(node); + } + } +} diff --git a/eslint.config.mjs b/eslint.config.mjs index 94a8a4ecd..5b3050a23 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -18,6 +18,7 @@ const compat = new FlatCompat({ export default [ { ignores: [ + 'check-coverage/**/*.ts', 'coverage/**/*.js', 'dist/**/*.cjs', 'dist/**/*.js', diff --git a/src/slang-nodes/ArgumentsDeclaration.ts b/src/slang-nodes/ArgumentsDeclaration.ts index d50600984..106dae3c6 100644 --- a/src/slang-nodes/ArgumentsDeclaration.ts +++ b/src/slang-nodes/ArgumentsDeclaration.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -10,11 +10,11 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - slangAst.ArgumentsDeclaration, + ast.ArgumentsDeclaration, ArgumentsDeclaration >([ - [slangAst.PositionalArgumentsDeclaration, PositionalArgumentsDeclaration], - [slangAst.NamedArgumentsDeclaration, NamedArgumentsDeclaration] + [ast.PositionalArgumentsDeclaration, PositionalArgumentsDeclaration], + [ast.NamedArgumentsDeclaration, NamedArgumentsDeclaration] ]); export class ArgumentsDeclaration extends SlangNode { @@ -23,24 +23,12 @@ export class ArgumentsDeclaration extends SlangNode { variant: PositionalArgumentsDeclaration | NamedArgumentsDeclaration; constructor( - ast: slangAst.ArgumentsDeclaration, + ast: ast.ArgumentsDeclaration, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of - // `ArgumentsDeclaration` in the `createNonterminalVariant` function - // above. - ((variant: slangAst.ArgumentsDeclaration['variant']): void => { - if (variant instanceof slangAst.PositionalArgumentsDeclaration) return; - if (variant instanceof slangAst.NamedArgumentsDeclaration) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(ast.variant); - } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/ContractMember.ts b/src/slang-nodes/ContractMember.ts index d19faf4ea..767faa39c 100644 --- a/src/slang-nodes/ContractMember.ts +++ b/src/slang-nodes/ContractMember.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -21,22 +21,22 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - slangAst.ContractMember, + ast.ContractMember, ContractMember >([ - [slangAst.UsingDirective, UsingDirective], - [slangAst.FunctionDefinition, FunctionDefinition], - [slangAst.ConstructorDefinition, ConstructorDefinition], - [slangAst.ReceiveFunctionDefinition, ReceiveFunctionDefinition], - [slangAst.FallbackFunctionDefinition, FallbackFunctionDefinition], - [slangAst.UnnamedFunctionDefinition, UnnamedFunctionDefinition], - [slangAst.ModifierDefinition, ModifierDefinition], - [slangAst.StructDefinition, StructDefinition], - [slangAst.EnumDefinition, EnumDefinition], - [slangAst.EventDefinition, EventDefinition], - [slangAst.StateVariableDefinition, StateVariableDefinition], - [slangAst.ErrorDefinition, ErrorDefinition], - [slangAst.UserDefinedValueTypeDefinition, UserDefinedValueTypeDefinition] + [ast.UsingDirective, UsingDirective], + [ast.FunctionDefinition, FunctionDefinition], + [ast.ConstructorDefinition, ConstructorDefinition], + [ast.ReceiveFunctionDefinition, ReceiveFunctionDefinition], + [ast.FallbackFunctionDefinition, FallbackFunctionDefinition], + [ast.UnnamedFunctionDefinition, UnnamedFunctionDefinition], + [ast.ModifierDefinition, ModifierDefinition], + [ast.StructDefinition, StructDefinition], + [ast.EnumDefinition, EnumDefinition], + [ast.EventDefinition, EventDefinition], + [ast.StateVariableDefinition, StateVariableDefinition], + [ast.ErrorDefinition, ErrorDefinition], + [ast.UserDefinedValueTypeDefinition, UserDefinedValueTypeDefinition] ]); export class ContractMember extends SlangNode { @@ -58,34 +58,12 @@ export class ContractMember extends SlangNode { | UserDefinedValueTypeDefinition; constructor( - ast: slangAst.ContractMember, + ast: ast.ContractMember, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of - // `ContractMember` in the `createNonterminalVariant` function above. - ((variant: slangAst.ContractMember['variant']): void => { - if (variant instanceof slangAst.UsingDirective) return; - if (variant instanceof slangAst.FunctionDefinition) return; - if (variant instanceof slangAst.ConstructorDefinition) return; - if (variant instanceof slangAst.ReceiveFunctionDefinition) return; - if (variant instanceof slangAst.FallbackFunctionDefinition) return; - if (variant instanceof slangAst.UnnamedFunctionDefinition) return; - if (variant instanceof slangAst.ModifierDefinition) return; - if (variant instanceof slangAst.StructDefinition) return; - if (variant instanceof slangAst.EnumDefinition) return; - if (variant instanceof slangAst.EventDefinition) return; - if (variant instanceof slangAst.StateVariableDefinition) return; - if (variant instanceof slangAst.ErrorDefinition) return; - if (variant instanceof slangAst.UserDefinedValueTypeDefinition) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(ast.variant); - } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/ContractSpecifier.ts b/src/slang-nodes/ContractSpecifier.ts index 16701d2a1..fc18129bf 100644 --- a/src/slang-nodes/ContractSpecifier.ts +++ b/src/slang-nodes/ContractSpecifier.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -10,11 +10,11 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - slangAst.ContractSpecifier, + ast.ContractSpecifier, ContractSpecifier >([ - [slangAst.InheritanceSpecifier, InheritanceSpecifier], - [slangAst.StorageLayoutSpecifier, StorageLayoutSpecifier] + [ast.InheritanceSpecifier, InheritanceSpecifier], + [ast.StorageLayoutSpecifier, StorageLayoutSpecifier] ]); export class ContractSpecifier extends SlangNode { @@ -23,23 +23,12 @@ export class ContractSpecifier extends SlangNode { variant: InheritanceSpecifier | StorageLayoutSpecifier; constructor( - ast: slangAst.ContractSpecifier, + ast: ast.ContractSpecifier, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of - // `ContractSpecifier` in the `createNonterminalVariant` function above. - ((variant: slangAst.ContractSpecifier['variant']): void => { - if (variant instanceof slangAst.InheritanceSpecifier) return; - if (variant instanceof slangAst.StorageLayoutSpecifier) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(ast.variant); - } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/Expression.ts b/src/slang-nodes/Expression.ts index dc3060875..c8239b971 100644 --- a/src/slang-nodes/Expression.ts +++ b/src/slang-nodes/Expression.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind, TerminalNode as SlangTerminalNode @@ -39,39 +39,39 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - slangAst.Expression, + ast.Expression, Expression >( [ - [slangAst.AssignmentExpression, AssignmentExpression], - [slangAst.ConditionalExpression, ConditionalExpression], - [slangAst.OrExpression, OrExpression], - [slangAst.AndExpression, AndExpression], - [slangAst.EqualityExpression, EqualityExpression], - [slangAst.InequalityExpression, InequalityExpression], - [slangAst.BitwiseOrExpression, BitwiseOrExpression], - [slangAst.BitwiseXorExpression, BitwiseXorExpression], - [slangAst.BitwiseAndExpression, BitwiseAndExpression], - [slangAst.ShiftExpression, ShiftExpression], - [slangAst.AdditiveExpression, AdditiveExpression], - [slangAst.MultiplicativeExpression, MultiplicativeExpression], - [slangAst.ExponentiationExpression, ExponentiationExpression], - [slangAst.PostfixExpression, PostfixExpression], - [slangAst.PrefixExpression, PrefixExpression], - [slangAst.FunctionCallExpression, FunctionCallExpression], - [slangAst.CallOptionsExpression, CallOptionsExpression], - [slangAst.MemberAccessExpression, MemberAccessExpression], - [slangAst.IndexAccessExpression, IndexAccessExpression], - [slangAst.NewExpression, NewExpression], - [slangAst.TupleExpression, TupleExpression], - [slangAst.TypeExpression, TypeExpression], - [slangAst.ArrayExpression, ArrayExpression], - [slangAst.HexNumberExpression, HexNumberExpression], - [slangAst.DecimalNumberExpression, DecimalNumberExpression] + [ast.AssignmentExpression, AssignmentExpression], + [ast.ConditionalExpression, ConditionalExpression], + [ast.OrExpression, OrExpression], + [ast.AndExpression, AndExpression], + [ast.EqualityExpression, EqualityExpression], + [ast.InequalityExpression, InequalityExpression], + [ast.BitwiseOrExpression, BitwiseOrExpression], + [ast.BitwiseXorExpression, BitwiseXorExpression], + [ast.BitwiseAndExpression, BitwiseAndExpression], + [ast.ShiftExpression, ShiftExpression], + [ast.AdditiveExpression, AdditiveExpression], + [ast.MultiplicativeExpression, MultiplicativeExpression], + [ast.ExponentiationExpression, ExponentiationExpression], + [ast.PostfixExpression, PostfixExpression], + [ast.PrefixExpression, PrefixExpression], + [ast.FunctionCallExpression, FunctionCallExpression], + [ast.CallOptionsExpression, CallOptionsExpression], + [ast.MemberAccessExpression, MemberAccessExpression], + [ast.IndexAccessExpression, IndexAccessExpression], + [ast.NewExpression, NewExpression], + [ast.TupleExpression, TupleExpression], + [ast.TypeExpression, TypeExpression], + [ast.ArrayExpression, ArrayExpression], + [ast.HexNumberExpression, HexNumberExpression], + [ast.DecimalNumberExpression, DecimalNumberExpression] ], [ - [slangAst.StringExpression, StringExpression], - [slangAst.ElementaryType, ElementaryType] + [ast.StringExpression, StringExpression], + [ast.ElementaryType, ElementaryType] ] ); @@ -109,7 +109,7 @@ export class Expression extends SlangNode { | TerminalNode; constructor( - ast: slangAst.Expression, + ast: ast.Expression, collected: CollectedMetadata, options: ParserOptions ) { @@ -120,44 +120,6 @@ export class Expression extends SlangNode { this.variant = new TerminalNode(variant, collected); return; } - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of - // `Expression` in the `createNonterminalVariant` function above. - (( - variant: Exclude - ): void => { - if (variant instanceof slangAst.AssignmentExpression) return; - if (variant instanceof slangAst.ConditionalExpression) return; - if (variant instanceof slangAst.OrExpression) return; - if (variant instanceof slangAst.AndExpression) return; - if (variant instanceof slangAst.EqualityExpression) return; - if (variant instanceof slangAst.InequalityExpression) return; - if (variant instanceof slangAst.BitwiseOrExpression) return; - if (variant instanceof slangAst.BitwiseXorExpression) return; - if (variant instanceof slangAst.BitwiseAndExpression) return; - if (variant instanceof slangAst.ShiftExpression) return; - if (variant instanceof slangAst.AdditiveExpression) return; - if (variant instanceof slangAst.MultiplicativeExpression) return; - if (variant instanceof slangAst.ExponentiationExpression) return; - if (variant instanceof slangAst.PostfixExpression) return; - if (variant instanceof slangAst.PrefixExpression) return; - if (variant instanceof slangAst.FunctionCallExpression) return; - if (variant instanceof slangAst.CallOptionsExpression) return; - if (variant instanceof slangAst.MemberAccessExpression) return; - if (variant instanceof slangAst.IndexAccessExpression) return; - if (variant instanceof slangAst.NewExpression) return; - if (variant instanceof slangAst.TupleExpression) return; - if (variant instanceof slangAst.TypeExpression) return; - if (variant instanceof slangAst.ArrayExpression) return; - if (variant instanceof slangAst.HexNumberExpression) return; - if (variant instanceof slangAst.DecimalNumberExpression) return; - if (variant instanceof slangAst.StringExpression) return; - if (variant instanceof slangAst.ElementaryType) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(variant); - } this.variant = createNonterminalVariant(variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/FallbackFunctionAttribute.ts b/src/slang-nodes/FallbackFunctionAttribute.ts index 0601fecdd..f757e2427 100644 --- a/src/slang-nodes/FallbackFunctionAttribute.ts +++ b/src/slang-nodes/FallbackFunctionAttribute.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind, TerminalNode as SlangTerminalNode @@ -14,11 +14,11 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - slangAst.FallbackFunctionAttribute, + ast.FallbackFunctionAttribute, FallbackFunctionAttribute >([ - [slangAst.ModifierInvocation, ModifierInvocation], - [slangAst.OverrideSpecifier, OverrideSpecifier] + [ast.ModifierInvocation, ModifierInvocation], + [ast.OverrideSpecifier, OverrideSpecifier] ]); export class FallbackFunctionAttribute extends SlangNode { @@ -27,7 +27,7 @@ export class FallbackFunctionAttribute extends SlangNode { variant: ModifierInvocation | OverrideSpecifier | TerminalNode; constructor( - ast: slangAst.FallbackFunctionAttribute, + ast: ast.FallbackFunctionAttribute, collected: CollectedMetadata, options: ParserOptions ) { @@ -38,23 +38,6 @@ export class FallbackFunctionAttribute extends SlangNode { this.variant = new TerminalNode(variant, collected); return; } - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of - // `FallbackFunctionAttribute` in the `createNonterminalVariant` function - // above. - (( - variant: Exclude< - slangAst.FallbackFunctionAttribute['variant'], - SlangTerminalNode - > - ): void => { - if (variant instanceof slangAst.ModifierInvocation) return; - if (variant instanceof slangAst.OverrideSpecifier) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(variant); - } this.variant = createNonterminalVariant(variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/ForStatementInitialization.ts b/src/slang-nodes/ForStatementInitialization.ts index 807980336..84ca74ae3 100644 --- a/src/slang-nodes/ForStatementInitialization.ts +++ b/src/slang-nodes/ForStatementInitialization.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind, TerminalNode as SlangTerminalNode @@ -15,12 +15,12 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - slangAst.ForStatementInitialization, + ast.ForStatementInitialization, ForStatementInitialization >([ - [slangAst.ExpressionStatement, ExpressionStatement], - [slangAst.VariableDeclarationStatement, VariableDeclarationStatement], - [slangAst.TupleDeconstructionStatement, TupleDeconstructionStatement] + [ast.ExpressionStatement, ExpressionStatement], + [ast.VariableDeclarationStatement, VariableDeclarationStatement], + [ast.TupleDeconstructionStatement, TupleDeconstructionStatement] ]); export class ForStatementInitialization extends SlangNode { @@ -33,7 +33,7 @@ export class ForStatementInitialization extends SlangNode { | TerminalNode; constructor( - ast: slangAst.ForStatementInitialization, + ast: ast.ForStatementInitialization, collected: CollectedMetadata, options: ParserOptions ) { @@ -44,24 +44,6 @@ export class ForStatementInitialization extends SlangNode { this.variant = new TerminalNode(variant, collected); return; } - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of - // `ForStatementInitialization` in the `createNonterminalVariant` - // function above. - (( - variant: Exclude< - slangAst.ForStatementInitialization['variant'], - SlangTerminalNode - > - ): void => { - if (variant instanceof slangAst.ExpressionStatement) return; - if (variant instanceof slangAst.VariableDeclarationStatement) return; - if (variant instanceof slangAst.TupleDeconstructionStatement) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(variant); - } this.variant = createNonterminalVariant(variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/FunctionAttribute.ts b/src/slang-nodes/FunctionAttribute.ts index 0e761c813..c946ca94e 100644 --- a/src/slang-nodes/FunctionAttribute.ts +++ b/src/slang-nodes/FunctionAttribute.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind, TerminalNode as SlangTerminalNode @@ -14,11 +14,11 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - slangAst.FunctionAttribute, + ast.FunctionAttribute, FunctionAttribute >([ - [slangAst.ModifierInvocation, ModifierInvocation], - [slangAst.OverrideSpecifier, OverrideSpecifier] + [ast.ModifierInvocation, ModifierInvocation], + [ast.OverrideSpecifier, OverrideSpecifier] ]); export class FunctionAttribute extends SlangNode { @@ -27,7 +27,7 @@ export class FunctionAttribute extends SlangNode { variant: ModifierInvocation | OverrideSpecifier | TerminalNode; constructor( - ast: slangAst.FunctionAttribute, + ast: ast.FunctionAttribute, collected: CollectedMetadata, options: ParserOptions ) { @@ -38,22 +38,6 @@ export class FunctionAttribute extends SlangNode { this.variant = new TerminalNode(variant, collected); return; } - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of - // `FunctionAttribute` in the `createNonterminalVariant` function above. - (( - variant: Exclude< - slangAst.FunctionAttribute['variant'], - SlangTerminalNode - > - ): void => { - if (variant instanceof slangAst.ModifierInvocation) return; - if (variant instanceof slangAst.OverrideSpecifier) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(variant); - } this.variant = createNonterminalVariant(variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/ImportClause.ts b/src/slang-nodes/ImportClause.ts index d3a72657a..1421e735d 100644 --- a/src/slang-nodes/ImportClause.ts +++ b/src/slang-nodes/ImportClause.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -11,12 +11,12 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - slangAst.ImportClause, + ast.ImportClause, ImportClause >([ - [slangAst.PathImport, PathImport], - [slangAst.NamedImport, NamedImport], - [slangAst.ImportDeconstruction, ImportDeconstruction] + [ast.PathImport, PathImport], + [ast.NamedImport, NamedImport], + [ast.ImportDeconstruction, ImportDeconstruction] ]); export class ImportClause extends SlangNode { @@ -25,24 +25,12 @@ export class ImportClause extends SlangNode { variant: PathImport | NamedImport | ImportDeconstruction; constructor( - ast: slangAst.ImportClause, + ast: ast.ImportClause, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of `ImportClause` - // in the `createNonterminalVariant` function above. - ((variant: slangAst.ImportClause['variant']): void => { - if (variant instanceof slangAst.PathImport) return; - if (variant instanceof slangAst.NamedImport) return; - if (variant instanceof slangAst.ImportDeconstruction) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(ast.variant); - } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/MappingKeyType.ts b/src/slang-nodes/MappingKeyType.ts index 3bcfd395c..523244395 100644 --- a/src/slang-nodes/MappingKeyType.ts +++ b/src/slang-nodes/MappingKeyType.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -8,11 +8,11 @@ import { IdentifierPath } from './IdentifierPath.js'; import type { CollectedMetadata } from '../types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - slangAst.MappingKeyType, + ast.MappingKeyType, MappingKeyType >( - [[slangAst.IdentifierPath, IdentifierPath]], - [[slangAst.ElementaryType, ElementaryType]] + [[ast.IdentifierPath, IdentifierPath]], + [[ast.ElementaryType, ElementaryType]] ); export class MappingKeyType extends SlangNode { @@ -20,20 +20,9 @@ export class MappingKeyType extends SlangNode { variant: ElementaryType['variant'] | IdentifierPath; - constructor(ast: slangAst.MappingKeyType, collected: CollectedMetadata) { + constructor(ast: ast.MappingKeyType, collected: CollectedMetadata) { super(ast, collected); - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of - // `MappingKeyType` in the `createNonterminalVariant` function above. - ((variant: slangAst.MappingKeyType['variant']): void => { - if (variant instanceof slangAst.IdentifierPath) return; - if (variant instanceof slangAst.ElementaryType) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(ast.variant); - } this.variant = createNonterminalVariant(ast.variant, collected); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/Pragma.ts b/src/slang-nodes/Pragma.ts index 9be27511b..86a4ece4d 100644 --- a/src/slang-nodes/Pragma.ts +++ b/src/slang-nodes/Pragma.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -11,12 +11,12 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - slangAst.Pragma, + ast.Pragma, Pragma >([ - [slangAst.AbicoderPragma, AbicoderPragma], - [slangAst.ExperimentalPragma, ExperimentalPragma], - [slangAst.VersionPragma, VersionPragma] + [ast.AbicoderPragma, AbicoderPragma], + [ast.ExperimentalPragma, ExperimentalPragma], + [ast.VersionPragma, VersionPragma] ]); export class Pragma extends SlangNode { @@ -25,24 +25,12 @@ export class Pragma extends SlangNode { variant: AbicoderPragma | ExperimentalPragma | VersionPragma; constructor( - ast: slangAst.Pragma, + ast: ast.Pragma, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of `Pragma` in the - // `createNonterminalVariant` function above. - ((variant: slangAst.Pragma['variant']): void => { - if (variant instanceof slangAst.AbicoderPragma) return; - if (variant instanceof slangAst.ExperimentalPragma) return; - if (variant instanceof slangAst.VersionPragma) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(ast.variant); - } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/ReceiveFunctionAttribute.ts b/src/slang-nodes/ReceiveFunctionAttribute.ts index 640e08b4c..5e91580ab 100644 --- a/src/slang-nodes/ReceiveFunctionAttribute.ts +++ b/src/slang-nodes/ReceiveFunctionAttribute.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind, TerminalNode as SlangTerminalNode @@ -14,11 +14,11 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - slangAst.ReceiveFunctionAttribute, + ast.ReceiveFunctionAttribute, ReceiveFunctionAttribute >([ - [slangAst.ModifierInvocation, ModifierInvocation], - [slangAst.OverrideSpecifier, OverrideSpecifier] + [ast.ModifierInvocation, ModifierInvocation], + [ast.OverrideSpecifier, OverrideSpecifier] ]); export class ReceiveFunctionAttribute extends SlangNode { @@ -27,7 +27,7 @@ export class ReceiveFunctionAttribute extends SlangNode { variant: ModifierInvocation | OverrideSpecifier | TerminalNode; constructor( - ast: slangAst.ReceiveFunctionAttribute, + ast: ast.ReceiveFunctionAttribute, collected: CollectedMetadata, options: ParserOptions ) { @@ -38,23 +38,6 @@ export class ReceiveFunctionAttribute extends SlangNode { this.variant = new TerminalNode(variant, collected); return; } - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of - // `ReceiveFunctionAttribute` in the `createNonterminalVariant` function - // above. - (( - variant: Exclude< - slangAst.ReceiveFunctionAttribute['variant'], - SlangTerminalNode - > - ): void => { - if (variant instanceof slangAst.ModifierInvocation) return; - if (variant instanceof slangAst.OverrideSpecifier) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(variant); - } this.variant = createNonterminalVariant(variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/SourceUnitMember.ts b/src/slang-nodes/SourceUnitMember.ts index 545b782ce..d545dc29d 100644 --- a/src/slang-nodes/SourceUnitMember.ts +++ b/src/slang-nodes/SourceUnitMember.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -21,22 +21,22 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - slangAst.SourceUnitMember, + ast.SourceUnitMember, SourceUnitMember >([ - [slangAst.PragmaDirective, PragmaDirective], - [slangAst.ImportDirective, ImportDirective], - [slangAst.ContractDefinition, ContractDefinition], - [slangAst.InterfaceDefinition, InterfaceDefinition], - [slangAst.LibraryDefinition, LibraryDefinition], - [slangAst.StructDefinition, StructDefinition], - [slangAst.EnumDefinition, EnumDefinition], - [slangAst.FunctionDefinition, FunctionDefinition], - [slangAst.ConstantDefinition, ConstantDefinition], - [slangAst.ErrorDefinition, ErrorDefinition], - [slangAst.UserDefinedValueTypeDefinition, UserDefinedValueTypeDefinition], - [slangAst.UsingDirective, UsingDirective], - [slangAst.EventDefinition, EventDefinition] + [ast.PragmaDirective, PragmaDirective], + [ast.ImportDirective, ImportDirective], + [ast.ContractDefinition, ContractDefinition], + [ast.InterfaceDefinition, InterfaceDefinition], + [ast.LibraryDefinition, LibraryDefinition], + [ast.StructDefinition, StructDefinition], + [ast.EnumDefinition, EnumDefinition], + [ast.FunctionDefinition, FunctionDefinition], + [ast.ConstantDefinition, ConstantDefinition], + [ast.ErrorDefinition, ErrorDefinition], + [ast.UserDefinedValueTypeDefinition, UserDefinedValueTypeDefinition], + [ast.UsingDirective, UsingDirective], + [ast.EventDefinition, EventDefinition] ]); export class SourceUnitMember extends SlangNode { @@ -58,34 +58,12 @@ export class SourceUnitMember extends SlangNode { | EventDefinition; constructor( - ast: slangAst.SourceUnitMember, + ast: ast.SourceUnitMember, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of - // `SourceUnitMember` in the `createNonterminalVariant` function above. - ((variant: slangAst.SourceUnitMember['variant']): void => { - if (variant instanceof slangAst.PragmaDirective) return; - if (variant instanceof slangAst.ImportDirective) return; - if (variant instanceof slangAst.ContractDefinition) return; - if (variant instanceof slangAst.InterfaceDefinition) return; - if (variant instanceof slangAst.LibraryDefinition) return; - if (variant instanceof slangAst.StructDefinition) return; - if (variant instanceof slangAst.EnumDefinition) return; - if (variant instanceof slangAst.FunctionDefinition) return; - if (variant instanceof slangAst.ConstantDefinition) return; - if (variant instanceof slangAst.ErrorDefinition) return; - if (variant instanceof slangAst.UserDefinedValueTypeDefinition) return; - if (variant instanceof slangAst.UsingDirective) return; - if (variant instanceof slangAst.EventDefinition) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(ast.variant); - } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/Statement.ts b/src/slang-nodes/Statement.ts index 8c436b2b0..546e04dc4 100644 --- a/src/slang-nodes/Statement.ts +++ b/src/slang-nodes/Statement.ts @@ -76,32 +76,6 @@ export class Statement extends SlangNode { super(ast, collected); const variant = ast.variant; - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of `Statement` in - // the `createNonterminalVariant` function above. - ((variant: slangAst.Statement['variant']): void => { - if (variant instanceof slangAst.ExpressionStatement) return; - if (variant instanceof slangAst.VariableDeclarationStatement) return; - if (variant instanceof slangAst.TupleDeconstructionStatement) return; - if (variant instanceof slangAst.IfStatement) return; - if (variant instanceof slangAst.ForStatement) return; - if (variant instanceof slangAst.WhileStatement) return; - if (variant instanceof slangAst.DoWhileStatement) return; - if (variant instanceof slangAst.ContinueStatement) return; - if (variant instanceof slangAst.BreakStatement) return; - if (variant instanceof slangAst.ReturnStatement) return; - if (variant instanceof slangAst.ThrowStatement) return; - if (variant instanceof slangAst.EmitStatement) return; - if (variant instanceof slangAst.TryStatement) return; - if (variant instanceof slangAst.RevertStatement) return; - if (variant instanceof slangAst.AssemblyStatement) return; - if (variant instanceof slangAst.Block) return; - if (variant instanceof slangAst.UncheckedBlock) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(variant); - } this.variant = variant instanceof slangAst.Block ? new Block(variant, collected, options) diff --git a/src/slang-nodes/StringExpression.ts b/src/slang-nodes/StringExpression.ts index 441ca1e74..93913a0fa 100644 --- a/src/slang-nodes/StringExpression.ts +++ b/src/slang-nodes/StringExpression.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -13,14 +13,14 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - slangAst.StringExpression, + ast.StringExpression, StringExpression >([ - [slangAst.StringLiteral, StringLiteral], - [slangAst.StringLiterals, StringLiterals], - [slangAst.HexStringLiteral, HexStringLiteral], - [slangAst.HexStringLiterals, HexStringLiterals], - [slangAst.UnicodeStringLiterals, UnicodeStringLiterals] + [ast.StringLiteral, StringLiteral], + [ast.StringLiterals, StringLiterals], + [ast.HexStringLiteral, HexStringLiteral], + [ast.HexStringLiterals, HexStringLiterals], + [ast.UnicodeStringLiterals, UnicodeStringLiterals] ]); export class StringExpression extends SlangNode { @@ -34,26 +34,12 @@ export class StringExpression extends SlangNode { | UnicodeStringLiterals; constructor( - ast: slangAst.StringExpression, + ast: ast.StringExpression, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of - // `StringExpression` in the `createNonterminalVariant` function above. - ((variant: slangAst.StringExpression['variant']): void => { - if (variant instanceof slangAst.StringLiteral) return; - if (variant instanceof slangAst.StringLiterals) return; - if (variant instanceof slangAst.HexStringLiteral) return; - if (variant instanceof slangAst.HexStringLiterals) return; - if (variant instanceof slangAst.UnicodeStringLiterals) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(ast.variant); - } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/TupleMember.ts b/src/slang-nodes/TupleMember.ts index d15797864..3b40666ea 100644 --- a/src/slang-nodes/TupleMember.ts +++ b/src/slang-nodes/TupleMember.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -10,11 +10,11 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - slangAst.TupleMember, + ast.TupleMember, TupleMember >([ - [slangAst.TypedTupleMember, TypedTupleMember], - [slangAst.UntypedTupleMember, UntypedTupleMember] + [ast.TypedTupleMember, TypedTupleMember], + [ast.UntypedTupleMember, UntypedTupleMember] ]); export class TupleMember extends SlangNode { @@ -23,23 +23,12 @@ export class TupleMember extends SlangNode { variant: TypedTupleMember | UntypedTupleMember; constructor( - ast: slangAst.TupleMember, + ast: ast.TupleMember, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of `TupleMember` - // in the `createNonterminalVariant` function above. - ((variant: slangAst.TupleMember['variant']): void => { - if (variant instanceof slangAst.TypedTupleMember) return; - if (variant instanceof slangAst.UntypedTupleMember) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(ast.variant); - } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/TypeName.ts b/src/slang-nodes/TypeName.ts index 1f22a99cb..faccff25e 100644 --- a/src/slang-nodes/TypeName.ts +++ b/src/slang-nodes/TypeName.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -13,16 +13,16 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - slangAst.TypeName, + ast.TypeName, TypeName >( [ - [slangAst.ArrayTypeName, ArrayTypeName], - [slangAst.FunctionType, FunctionType], - [slangAst.MappingType, MappingType], - [slangAst.IdentifierPath, IdentifierPath] + [ast.ArrayTypeName, ArrayTypeName], + [ast.FunctionType, FunctionType], + [ast.MappingType, MappingType], + [ast.IdentifierPath, IdentifierPath] ], - [[slangAst.ElementaryType, ElementaryType]] + [[ast.ElementaryType, ElementaryType]] ); export class TypeName extends SlangNode { @@ -36,26 +36,12 @@ export class TypeName extends SlangNode { | IdentifierPath; constructor( - ast: slangAst.TypeName, + ast: ast.TypeName, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of `TypeName` in - // the `createNonterminalVariant` function above. - ((variant: slangAst.TypeName['variant']): void => { - if (variant instanceof slangAst.ArrayTypeName) return; - if (variant instanceof slangAst.FunctionType) return; - if (variant instanceof slangAst.MappingType) return; - if (variant instanceof slangAst.IdentifierPath) return; - if (variant instanceof slangAst.ElementaryType) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(ast.variant); - } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/UsingClause.ts b/src/slang-nodes/UsingClause.ts index f939ea809..dcaedb6d9 100644 --- a/src/slang-nodes/UsingClause.ts +++ b/src/slang-nodes/UsingClause.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -8,11 +8,11 @@ import { UsingDeconstruction } from './UsingDeconstruction.js'; import type { CollectedMetadata } from '../types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - slangAst.UsingClause, + ast.UsingClause, UsingClause >([ - [slangAst.IdentifierPath, IdentifierPath], - [slangAst.UsingDeconstruction, UsingDeconstruction] + [ast.IdentifierPath, IdentifierPath], + [ast.UsingDeconstruction, UsingDeconstruction] ]); export class UsingClause extends SlangNode { @@ -20,20 +20,9 @@ export class UsingClause extends SlangNode { variant: IdentifierPath | UsingDeconstruction; - constructor(ast: slangAst.UsingClause, collected: CollectedMetadata) { + constructor(ast: ast.UsingClause, collected: CollectedMetadata) { super(ast, collected); - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of `UsingClause` - // in the `createNonterminalVariant` function above. - ((variant: slangAst.UsingClause['variant']): void => { - if (variant instanceof slangAst.IdentifierPath) return; - if (variant instanceof slangAst.UsingDeconstruction) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(ast.variant); - } this.variant = createNonterminalVariant(ast.variant, collected); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/VersionExpression.ts b/src/slang-nodes/VersionExpression.ts index 2bb32230a..4b6757835 100644 --- a/src/slang-nodes/VersionExpression.ts +++ b/src/slang-nodes/VersionExpression.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -8,11 +8,11 @@ import { VersionTerm } from './VersionTerm.js'; import type { CollectedMetadata } from '../types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - slangAst.VersionExpression, + ast.VersionExpression, VersionExpression >([ - [slangAst.VersionRange, VersionRange], - [slangAst.VersionTerm, VersionTerm] + [ast.VersionRange, VersionRange], + [ast.VersionTerm, VersionTerm] ]); export class VersionExpression extends SlangNode { @@ -20,20 +20,9 @@ export class VersionExpression extends SlangNode { variant: VersionRange | VersionTerm; - constructor(ast: slangAst.VersionExpression, collected: CollectedMetadata) { + constructor(ast: ast.VersionExpression, collected: CollectedMetadata) { super(ast, collected); - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of - // `VersionExpression` in the `createNonterminalVariant` function above. - ((variant: slangAst.VersionExpression['variant']): void => { - if (variant instanceof slangAst.VersionRange) return; - if (variant instanceof slangAst.VersionTerm) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(ast.variant); - } this.variant = createNonterminalVariant(ast.variant, collected); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/YulExpression.ts b/src/slang-nodes/YulExpression.ts index 787b8e048..1019d20a6 100644 --- a/src/slang-nodes/YulExpression.ts +++ b/src/slang-nodes/YulExpression.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -11,14 +11,14 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantCreator< - slangAst.YulExpression, + ast.YulExpression, YulExpression >( [ - [slangAst.YulFunctionCallExpression, YulFunctionCallExpression], - [slangAst.YulPath, YulPath] + [ast.YulFunctionCallExpression, YulFunctionCallExpression], + [ast.YulPath, YulPath] ], - [[slangAst.YulLiteral, YulLiteral]] + [[ast.YulLiteral, YulLiteral]] ); export class YulExpression extends SlangNode { @@ -27,24 +27,12 @@ export class YulExpression extends SlangNode { variant: YulFunctionCallExpression | YulLiteral['variant'] | YulPath; constructor( - ast: slangAst.YulExpression, + ast: ast.YulExpression, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of `YulExpression` - // in the `createNonterminalVariant` function above. - ((variant: slangAst.YulExpression['variant']): void => { - if (variant instanceof slangAst.YulFunctionCallExpression) return; - if (variant instanceof slangAst.YulLiteral) return; - if (variant instanceof slangAst.YulPath) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(ast.variant); - } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/YulLiteral.ts b/src/slang-nodes/YulLiteral.ts index 44e7b277a..1bffdd584 100644 --- a/src/slang-nodes/YulLiteral.ts +++ b/src/slang-nodes/YulLiteral.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind, TerminalNode as SlangTerminalNode @@ -14,11 +14,11 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - slangAst.YulLiteral, + ast.YulLiteral, YulLiteral >([ - [slangAst.HexStringLiteral, HexStringLiteral], - [slangAst.StringLiteral, StringLiteral] + [ast.HexStringLiteral, HexStringLiteral], + [ast.StringLiteral, StringLiteral] ]); export class YulLiteral extends SlangNode { @@ -27,7 +27,7 @@ export class YulLiteral extends SlangNode { variant: HexStringLiteral | StringLiteral | TerminalNode; constructor( - ast: slangAst.YulLiteral, + ast: ast.YulLiteral, collected: CollectedMetadata, options: ParserOptions ) { @@ -38,19 +38,6 @@ export class YulLiteral extends SlangNode { this.variant = new TerminalNode(variant, collected); return; } - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of `YulLiteral` - // in the `createNonterminalVariant` function above. - (( - variant: Exclude - ): void => { - if (variant instanceof slangAst.HexStringLiteral) return; - if (variant instanceof slangAst.StringLiteral) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(variant); - } this.variant = createNonterminalVariant(variant, collected, options); this.updateMetadata(this.variant); diff --git a/src/slang-nodes/YulStatement.ts b/src/slang-nodes/YulStatement.ts index d63a2c4d2..f0342031f 100644 --- a/src/slang-nodes/YulStatement.ts +++ b/src/slang-nodes/YulStatement.ts @@ -66,28 +66,6 @@ export class YulStatement extends SlangNode { super(ast, collected); const variant = ast.variant; - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of `YulStatement` - // in the `createNonterminalVariant` function above. - ((variant: slangAst.YulStatement['variant']): void => { - if (variant instanceof slangAst.YulBlock) return; - if (variant instanceof slangAst.YulFunctionDefinition) return; - if (variant instanceof slangAst.YulVariableDeclarationStatement) return; - if (variant instanceof slangAst.YulVariableAssignmentStatement) return; - if (variant instanceof slangAst.YulStackAssignmentStatement) return; - if (variant instanceof slangAst.YulIfStatement) return; - if (variant instanceof slangAst.YulForStatement) return; - if (variant instanceof slangAst.YulSwitchStatement) return; - if (variant instanceof slangAst.YulLeaveStatement) return; - if (variant instanceof slangAst.YulBreakStatement) return; - if (variant instanceof slangAst.YulContinueStatement) return; - if (variant instanceof slangAst.YulLabel) return; - if (variant instanceof slangAst.YulExpression) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(variant); - } this.variant = variant instanceof slangAst.YulBlock ? new YulBlock(variant, collected, options) diff --git a/src/slang-nodes/YulSwitchCase.ts b/src/slang-nodes/YulSwitchCase.ts index 36c866934..ecee949cd 100644 --- a/src/slang-nodes/YulSwitchCase.ts +++ b/src/slang-nodes/YulSwitchCase.ts @@ -1,4 +1,4 @@ -import * as slangAst from '@nomicfoundation/slang/ast'; +import * as ast from '@nomicfoundation/slang/ast'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createNonterminalVariantSimpleCreator } from '../slang-utils/create-nonterminal-variant-creator.js'; import { SlangNode } from './SlangNode.js'; @@ -10,11 +10,11 @@ import type { CollectedMetadata } from '../types.d.ts'; import type { AstNode } from './types.d.ts'; const createNonterminalVariant = createNonterminalVariantSimpleCreator< - slangAst.YulSwitchCase, + ast.YulSwitchCase, YulSwitchCase >([ - [slangAst.YulDefaultCase, YulDefaultCase], - [slangAst.YulValueCase, YulValueCase] + [ast.YulDefaultCase, YulDefaultCase], + [ast.YulValueCase, YulValueCase] ]); export class YulSwitchCase extends SlangNode { @@ -23,23 +23,12 @@ export class YulSwitchCase extends SlangNode { variant: YulDefaultCase | YulValueCase; constructor( - ast: slangAst.YulSwitchCase, + ast: ast.YulSwitchCase, collected: CollectedMetadata, options: ParserOptions ) { super(ast, collected); - if (process.env.NODE_ENV === 'test') { - // This is to ensure that we have handled all variants of `YulSwitchCase` - // in the `createNonterminalVariant` function above. - ((variant: slangAst.YulSwitchCase['variant']): void => { - if (variant instanceof slangAst.YulDefaultCase) return; - if (variant instanceof slangAst.YulValueCase) return; - /* c8 ignore next 2 */ - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const _exhaustiveCheck: never = variant; - })(ast.variant); - } this.variant = createNonterminalVariant(ast.variant, collected, options); this.updateMetadata(this.variant); diff --git a/test.config.js b/test.config.js index 0e367e7c2..3b77f63e6 100644 --- a/test.config.js +++ b/test.config.js @@ -6,7 +6,8 @@ const { __dirname } = createEsmUtils(import.meta); export default { entry: { test: './tests/integration/test-app.js', - 'create-parser': './src/slang-utils/create-parser.js' + 'create-parser': './src/slang-utils/create-parser.js', + 'check-coverage': './check-coverage/index.js' }, mode: 'production', bail: true, diff --git a/tests/config/get-check-coverage.js b/tests/config/get-check-coverage.js new file mode 100644 index 000000000..e35e8de88 --- /dev/null +++ b/tests/config/get-check-coverage.js @@ -0,0 +1,16 @@ +function getCheckCoverageInternal() { + const entry = process.env.TEST_STANDALONE + ? "../../dist/check-coverage.js" + : "../../check-coverage/index.js"; + + return import(entry).then((module) => module.checkCoverage); +} + +let promise; +function getCheckCoverage() { + promise = promise ?? getCheckCoverageInternal(); + + return promise; +} + +export default getCheckCoverage; diff --git a/tests/config/run-format-test.js b/tests/config/run-format-test.js index 284528efa..ee3648ffe 100644 --- a/tests/config/run-format-test.js +++ b/tests/config/run-format-test.js @@ -4,6 +4,7 @@ import url from "node:url"; import createEsmUtils from "esm-utils"; import getPrettier from "./get-prettier.js"; import getCreateParser from "./get-create-parser.js"; +import getCheckCoverage from "./get-check-coverage.js"; import getPlugins from "./get-plugins.js"; import compileContract from "./utils/compile-contract.js"; import consistentEndOfLine from "./utils/consistent-end-of-line.js"; @@ -321,24 +322,27 @@ async function runTest({ return; } - if ( - formatOptions.parser === "slang" && - !isAntlrMismatch(filename, formatOptions) - ) { - // Compare with ANTLR's format - const prettier = await getPrettier(); + if (formatOptions.parser === "slang") { const createParser = await getCreateParser(); - const { formatted: antlrOutput } = await prettier.formatWithCursor(code, { - ...formatOptions, - // Since Slang forces us to decide on a compiler version, we need to do the - // same for ANTLR unless it was already given as an option. - compiler: - formatOptions.compiler || - createParser(code, formatOptions).parser.languageVersion, - parser: "antlr", - plugins: await getPlugins(), - }); - expect(antlrOutput).toEqual(formatResult.output); + const checkCoverage = await getCheckCoverage(); + const { parser, parseOutput } = createParser(code, formatOptions); + + // Check coverage + checkCoverage(parseOutput.tree.asNonterminalNode()); + + if (!isAntlrMismatch(filename, formatOptions)) { + // Compare with ANTLR's format + const prettier = await getPrettier(); + const { formatted: antlrOutput } = await prettier.formatWithCursor(code, { + ...formatOptions, + // Since Slang forces us to decide on a compiler version, we need to do the + // same for ANTLR unless it was already given as an option. + compiler: formatOptions.compiler || parser.languageVersion, + parser: "antlr", + plugins: await getPlugins(), + }); + expect(antlrOutput).toEqual(formatResult.output); + } } const isUnstableTest = isUnstable(filename, formatOptions); From 10441319165ebb703c95560e7141bb7fb0cf7066 Mon Sep 17 00:00:00 2001 From: Klaus Date: Wed, 25 Feb 2026 23:50:02 -0300 Subject: [PATCH 22/22] renaming `check-coverage` to `variant-coverage` --- .c8rc | 2 +- eslint.config.mjs | 2 +- test.config.js | 2 +- tests/config/get-check-coverage.js | 16 ---------------- tests/config/get-variant-coverage.js | 16 ++++++++++++++++ tests/config/run-format-test.js | 6 +++--- .../ArgumentsDeclaration.ts | 0 .../ContractMember.ts | 0 .../ContractSpecifier.ts | 0 .../Expression.ts | 0 .../FallbackFunctionAttribute.ts | 0 .../ForStatementInitialization.ts | 0 .../FunctionAttribute.ts | 0 .../ImportClause.ts | 0 .../MappingKeyType.ts | 0 {check-coverage => variant-coverage}/Pragma.ts | 0 .../ReceiveFunctionAttribute.ts | 0 .../SourceUnitMember.ts | 0 .../Statement.ts | 0 .../StringExpression.ts | 0 .../TupleMember.ts | 0 {check-coverage => variant-coverage}/TypeName.ts | 0 .../UsingClause.ts | 0 .../VersionExpression.ts | 0 .../YulExpression.ts | 0 .../YulLiteral.ts | 0 .../YulStatement.ts | 0 .../YulSwitchCase.ts | 0 {check-coverage => variant-coverage}/index.ts | 4 ++-- 29 files changed, 24 insertions(+), 24 deletions(-) delete mode 100644 tests/config/get-check-coverage.js create mode 100644 tests/config/get-variant-coverage.js rename {check-coverage => variant-coverage}/ArgumentsDeclaration.ts (100%) rename {check-coverage => variant-coverage}/ContractMember.ts (100%) rename {check-coverage => variant-coverage}/ContractSpecifier.ts (100%) rename {check-coverage => variant-coverage}/Expression.ts (100%) rename {check-coverage => variant-coverage}/FallbackFunctionAttribute.ts (100%) rename {check-coverage => variant-coverage}/ForStatementInitialization.ts (100%) rename {check-coverage => variant-coverage}/FunctionAttribute.ts (100%) rename {check-coverage => variant-coverage}/ImportClause.ts (100%) rename {check-coverage => variant-coverage}/MappingKeyType.ts (100%) rename {check-coverage => variant-coverage}/Pragma.ts (100%) rename {check-coverage => variant-coverage}/ReceiveFunctionAttribute.ts (100%) rename {check-coverage => variant-coverage}/SourceUnitMember.ts (100%) rename {check-coverage => variant-coverage}/Statement.ts (100%) rename {check-coverage => variant-coverage}/StringExpression.ts (100%) rename {check-coverage => variant-coverage}/TupleMember.ts (100%) rename {check-coverage => variant-coverage}/TypeName.ts (100%) rename {check-coverage => variant-coverage}/UsingClause.ts (100%) rename {check-coverage => variant-coverage}/VersionExpression.ts (100%) rename {check-coverage => variant-coverage}/YulExpression.ts (100%) rename {check-coverage => variant-coverage}/YulLiteral.ts (100%) rename {check-coverage => variant-coverage}/YulStatement.ts (100%) rename {check-coverage => variant-coverage}/YulSwitchCase.ts (100%) rename {check-coverage => variant-coverage}/index.ts (98%) diff --git a/.c8rc b/.c8rc index 963c0cde1..315fdc955 100644 --- a/.c8rc +++ b/.c8rc @@ -5,7 +5,7 @@ "functions": 90, "statements": 90, "exclude": ["/node_modules/"], - "include": ["src/**/*.ts", "check-coverage/**/*.ts"], + "include": ["src/**/*.ts", "variant-coverage/**/*.ts"], "reporter": ["lcov", "text"], "temp-dir": "./coverage/" } diff --git a/eslint.config.mjs b/eslint.config.mjs index 5b3050a23..769e54f6b 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -18,7 +18,7 @@ const compat = new FlatCompat({ export default [ { ignores: [ - 'check-coverage/**/*.ts', + 'variant-coverage/**/*.ts', 'coverage/**/*.js', 'dist/**/*.cjs', 'dist/**/*.js', diff --git a/test.config.js b/test.config.js index 3b77f63e6..99f93a10e 100644 --- a/test.config.js +++ b/test.config.js @@ -7,7 +7,7 @@ export default { entry: { test: './tests/integration/test-app.js', 'create-parser': './src/slang-utils/create-parser.js', - 'check-coverage': './check-coverage/index.js' + 'variant-coverage': './variant-coverage/index.js' }, mode: 'production', bail: true, diff --git a/tests/config/get-check-coverage.js b/tests/config/get-check-coverage.js deleted file mode 100644 index e35e8de88..000000000 --- a/tests/config/get-check-coverage.js +++ /dev/null @@ -1,16 +0,0 @@ -function getCheckCoverageInternal() { - const entry = process.env.TEST_STANDALONE - ? "../../dist/check-coverage.js" - : "../../check-coverage/index.js"; - - return import(entry).then((module) => module.checkCoverage); -} - -let promise; -function getCheckCoverage() { - promise = promise ?? getCheckCoverageInternal(); - - return promise; -} - -export default getCheckCoverage; diff --git a/tests/config/get-variant-coverage.js b/tests/config/get-variant-coverage.js new file mode 100644 index 000000000..0d2bc62b1 --- /dev/null +++ b/tests/config/get-variant-coverage.js @@ -0,0 +1,16 @@ +function getVariantCoverageInternal() { + const entry = process.env.TEST_STANDALONE + ? "../../dist/variant-coverage.js" + : "../../variant-coverage/index.js"; + + return import(entry).then((module) => module.variantCoverage); +} + +let promise; +function getVariantCoverage() { + promise = promise ?? getVariantCoverageInternal(); + + return promise; +} + +export default getVariantCoverage; diff --git a/tests/config/run-format-test.js b/tests/config/run-format-test.js index ee3648ffe..5d425c556 100644 --- a/tests/config/run-format-test.js +++ b/tests/config/run-format-test.js @@ -4,7 +4,7 @@ import url from "node:url"; import createEsmUtils from "esm-utils"; import getPrettier from "./get-prettier.js"; import getCreateParser from "./get-create-parser.js"; -import getCheckCoverage from "./get-check-coverage.js"; +import getVariantCoverage from "./get-variant-coverage.js"; import getPlugins from "./get-plugins.js"; import compileContract from "./utils/compile-contract.js"; import consistentEndOfLine from "./utils/consistent-end-of-line.js"; @@ -324,11 +324,11 @@ async function runTest({ if (formatOptions.parser === "slang") { const createParser = await getCreateParser(); - const checkCoverage = await getCheckCoverage(); + const variantCoverage = await getVariantCoverage(); const { parser, parseOutput } = createParser(code, formatOptions); // Check coverage - checkCoverage(parseOutput.tree.asNonterminalNode()); + variantCoverage(parseOutput.tree.asNonterminalNode()); if (!isAntlrMismatch(filename, formatOptions)) { // Compare with ANTLR's format diff --git a/check-coverage/ArgumentsDeclaration.ts b/variant-coverage/ArgumentsDeclaration.ts similarity index 100% rename from check-coverage/ArgumentsDeclaration.ts rename to variant-coverage/ArgumentsDeclaration.ts diff --git a/check-coverage/ContractMember.ts b/variant-coverage/ContractMember.ts similarity index 100% rename from check-coverage/ContractMember.ts rename to variant-coverage/ContractMember.ts diff --git a/check-coverage/ContractSpecifier.ts b/variant-coverage/ContractSpecifier.ts similarity index 100% rename from check-coverage/ContractSpecifier.ts rename to variant-coverage/ContractSpecifier.ts diff --git a/check-coverage/Expression.ts b/variant-coverage/Expression.ts similarity index 100% rename from check-coverage/Expression.ts rename to variant-coverage/Expression.ts diff --git a/check-coverage/FallbackFunctionAttribute.ts b/variant-coverage/FallbackFunctionAttribute.ts similarity index 100% rename from check-coverage/FallbackFunctionAttribute.ts rename to variant-coverage/FallbackFunctionAttribute.ts diff --git a/check-coverage/ForStatementInitialization.ts b/variant-coverage/ForStatementInitialization.ts similarity index 100% rename from check-coverage/ForStatementInitialization.ts rename to variant-coverage/ForStatementInitialization.ts diff --git a/check-coverage/FunctionAttribute.ts b/variant-coverage/FunctionAttribute.ts similarity index 100% rename from check-coverage/FunctionAttribute.ts rename to variant-coverage/FunctionAttribute.ts diff --git a/check-coverage/ImportClause.ts b/variant-coverage/ImportClause.ts similarity index 100% rename from check-coverage/ImportClause.ts rename to variant-coverage/ImportClause.ts diff --git a/check-coverage/MappingKeyType.ts b/variant-coverage/MappingKeyType.ts similarity index 100% rename from check-coverage/MappingKeyType.ts rename to variant-coverage/MappingKeyType.ts diff --git a/check-coverage/Pragma.ts b/variant-coverage/Pragma.ts similarity index 100% rename from check-coverage/Pragma.ts rename to variant-coverage/Pragma.ts diff --git a/check-coverage/ReceiveFunctionAttribute.ts b/variant-coverage/ReceiveFunctionAttribute.ts similarity index 100% rename from check-coverage/ReceiveFunctionAttribute.ts rename to variant-coverage/ReceiveFunctionAttribute.ts diff --git a/check-coverage/SourceUnitMember.ts b/variant-coverage/SourceUnitMember.ts similarity index 100% rename from check-coverage/SourceUnitMember.ts rename to variant-coverage/SourceUnitMember.ts diff --git a/check-coverage/Statement.ts b/variant-coverage/Statement.ts similarity index 100% rename from check-coverage/Statement.ts rename to variant-coverage/Statement.ts diff --git a/check-coverage/StringExpression.ts b/variant-coverage/StringExpression.ts similarity index 100% rename from check-coverage/StringExpression.ts rename to variant-coverage/StringExpression.ts diff --git a/check-coverage/TupleMember.ts b/variant-coverage/TupleMember.ts similarity index 100% rename from check-coverage/TupleMember.ts rename to variant-coverage/TupleMember.ts diff --git a/check-coverage/TypeName.ts b/variant-coverage/TypeName.ts similarity index 100% rename from check-coverage/TypeName.ts rename to variant-coverage/TypeName.ts diff --git a/check-coverage/UsingClause.ts b/variant-coverage/UsingClause.ts similarity index 100% rename from check-coverage/UsingClause.ts rename to variant-coverage/UsingClause.ts diff --git a/check-coverage/VersionExpression.ts b/variant-coverage/VersionExpression.ts similarity index 100% rename from check-coverage/VersionExpression.ts rename to variant-coverage/VersionExpression.ts diff --git a/check-coverage/YulExpression.ts b/variant-coverage/YulExpression.ts similarity index 100% rename from check-coverage/YulExpression.ts rename to variant-coverage/YulExpression.ts diff --git a/check-coverage/YulLiteral.ts b/variant-coverage/YulLiteral.ts similarity index 100% rename from check-coverage/YulLiteral.ts rename to variant-coverage/YulLiteral.ts diff --git a/check-coverage/YulStatement.ts b/variant-coverage/YulStatement.ts similarity index 100% rename from check-coverage/YulStatement.ts rename to variant-coverage/YulStatement.ts diff --git a/check-coverage/YulSwitchCase.ts b/variant-coverage/YulSwitchCase.ts similarity index 100% rename from check-coverage/YulSwitchCase.ts rename to variant-coverage/YulSwitchCase.ts diff --git a/check-coverage/index.ts b/variant-coverage/index.ts similarity index 98% rename from check-coverage/index.ts rename to variant-coverage/index.ts index 86c1ff077..8f0bd1b43 100644 --- a/check-coverage/index.ts +++ b/variant-coverage/index.ts @@ -23,7 +23,7 @@ import { checkYulLiteralVariant } from './YulLiteral.js'; import { checkYulStatementVariant } from './YulStatement.js'; import { checkYulSwitchCaseVariant } from './YulSwitchCase.js'; -export function checkCoverage(cst: NonterminalNode): void { +export function variantCoverage(cst: NonterminalNode): void { switch (cst.kind) { case NonterminalKind.ArgumentsDeclaration: checkArgumentsDeclarationVariant( @@ -103,7 +103,7 @@ export function checkCoverage(cst: NonterminalNode): void { for (const { node } of cst.children()) { if (node instanceof NonterminalNode) { - checkCoverage(node); + variantCoverage(node); } } }