Skip to content

Commit bac1e0a

Browse files
committed
standardising the instantiation of variants using an object as a dictionary
1 parent 002ec6a commit bac1e0a

23 files changed

Lines changed: 364 additions & 434 deletions

src/slang-nodes/ArgumentsDeclaration.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,21 @@ import type { ParserOptions } from 'prettier';
88
import type { CollectedMetadata } from '../types.d.ts';
99
import type { AstNode } from './types.d.ts';
1010

11+
const variantConstructors = {
12+
[ast.PositionalArgumentsDeclaration.name]: PositionalArgumentsDeclaration,
13+
[ast.NamedArgumentsDeclaration.name]: NamedArgumentsDeclaration
14+
};
15+
1116
function createNonterminalVariant(
1217
variant: ast.ArgumentsDeclaration['variant'],
1318
collected: CollectedMetadata,
1419
options: ParserOptions<AstNode>
1520
): ArgumentsDeclaration['variant'] {
16-
if (variant instanceof ast.PositionalArgumentsDeclaration) {
17-
return new PositionalArgumentsDeclaration(variant, collected, options);
18-
}
19-
if (variant instanceof ast.NamedArgumentsDeclaration) {
20-
return new NamedArgumentsDeclaration(variant, collected, options);
21-
}
22-
const exhaustiveCheck: never = variant;
23-
throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`);
21+
const variantConstructor = variantConstructors[variant.constructor.name];
22+
if (variantConstructor !== undefined)
23+
return new variantConstructor(variant as never, collected, options);
24+
25+
throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`);
2426
}
2527

2628
export class ArgumentsDeclaration extends SlangNode {

src/slang-nodes/ContractMember.ts

Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -19,52 +19,32 @@ import type { ParserOptions } from 'prettier';
1919
import type { CollectedMetadata } from '../types.d.ts';
2020
import type { AstNode } from './types.d.ts';
2121

22+
const variantConstructors = {
23+
[ast.UsingDirective.name]: UsingDirective,
24+
[ast.FunctionDefinition.name]: FunctionDefinition,
25+
[ast.ConstructorDefinition.name]: ConstructorDefinition,
26+
[ast.ReceiveFunctionDefinition.name]: ReceiveFunctionDefinition,
27+
[ast.FallbackFunctionDefinition.name]: FallbackFunctionDefinition,
28+
[ast.UnnamedFunctionDefinition.name]: UnnamedFunctionDefinition,
29+
[ast.ModifierDefinition.name]: ModifierDefinition,
30+
[ast.StructDefinition.name]: StructDefinition,
31+
[ast.EnumDefinition.name]: EnumDefinition,
32+
[ast.EventDefinition.name]: EventDefinition,
33+
[ast.StateVariableDefinition.name]: StateVariableDefinition,
34+
[ast.ErrorDefinition.name]: ErrorDefinition,
35+
[ast.UserDefinedValueTypeDefinition.name]: UserDefinedValueTypeDefinition
36+
};
37+
2238
function createNonterminalVariant(
2339
variant: ast.ContractMember['variant'],
2440
collected: CollectedMetadata,
2541
options: ParserOptions<AstNode>
2642
): ContractMember['variant'] {
27-
if (variant instanceof ast.UsingDirective) {
28-
return new UsingDirective(variant, collected, options);
29-
}
30-
if (variant instanceof ast.FunctionDefinition) {
31-
return new FunctionDefinition(variant, collected, options);
32-
}
33-
if (variant instanceof ast.ConstructorDefinition) {
34-
return new ConstructorDefinition(variant, collected, options);
35-
}
36-
if (variant instanceof ast.ReceiveFunctionDefinition) {
37-
return new ReceiveFunctionDefinition(variant, collected, options);
38-
}
39-
if (variant instanceof ast.FallbackFunctionDefinition) {
40-
return new FallbackFunctionDefinition(variant, collected, options);
41-
}
42-
if (variant instanceof ast.UnnamedFunctionDefinition) {
43-
return new UnnamedFunctionDefinition(variant, collected, options);
44-
}
45-
if (variant instanceof ast.ModifierDefinition) {
46-
return new ModifierDefinition(variant, collected, options);
47-
}
48-
if (variant instanceof ast.StructDefinition) {
49-
return new StructDefinition(variant, collected, options);
50-
}
51-
if (variant instanceof ast.EnumDefinition) {
52-
return new EnumDefinition(variant, collected);
53-
}
54-
if (variant instanceof ast.EventDefinition) {
55-
return new EventDefinition(variant, collected, options);
56-
}
57-
if (variant instanceof ast.StateVariableDefinition) {
58-
return new StateVariableDefinition(variant, collected, options);
59-
}
60-
if (variant instanceof ast.ErrorDefinition) {
61-
return new ErrorDefinition(variant, collected, options);
62-
}
63-
if (variant instanceof ast.UserDefinedValueTypeDefinition) {
64-
return new UserDefinedValueTypeDefinition(variant, collected);
65-
}
66-
const exhaustiveCheck: never = variant;
67-
throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`);
43+
const variantConstructor = variantConstructors[variant.constructor.name];
44+
if (variantConstructor !== undefined)
45+
return new variantConstructor(variant as never, collected, options);
46+
47+
throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`);
6848
}
6949

7050
export class ContractMember extends SlangNode {

src/slang-nodes/ContractSpecifier.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,21 @@ import type { ParserOptions } from 'prettier';
88
import type { CollectedMetadata } from '../types.d.ts';
99
import type { AstNode } from './types.d.ts';
1010

11+
const variantConstructors = {
12+
[ast.InheritanceSpecifier.name]: InheritanceSpecifier,
13+
[ast.StorageLayoutSpecifier.name]: StorageLayoutSpecifier
14+
};
15+
1116
function createNonterminalVariant(
1217
variant: ast.ContractSpecifier['variant'],
1318
collected: CollectedMetadata,
1419
options: ParserOptions<AstNode>
1520
): ContractSpecifier['variant'] {
16-
if (variant instanceof ast.InheritanceSpecifier) {
17-
return new InheritanceSpecifier(variant, collected, options);
18-
}
19-
if (variant instanceof ast.StorageLayoutSpecifier) {
20-
return new StorageLayoutSpecifier(variant, collected, options);
21-
}
22-
const exhaustiveCheck: never = variant;
23-
throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`);
21+
const variantConstructor = variantConstructors[variant.constructor.name];
22+
if (variantConstructor !== undefined)
23+
return new variantConstructor(variant as never, collected, options);
24+
25+
throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`);
2426
}
2527

2628
export class ContractSpecifier extends SlangNode {

src/slang-nodes/Expression.ts

Lines changed: 45 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -38,94 +38,56 @@ import type { ParserOptions } from 'prettier';
3838
import type { CollectedMetadata } from '../types.d.ts';
3939
import type { AstNode } from './types.d.ts';
4040

41+
const variantConstructors = {
42+
[ast.AssignmentExpression.name]: AssignmentExpression,
43+
[ast.ConditionalExpression.name]: ConditionalExpression,
44+
[ast.OrExpression.name]: OrExpression,
45+
[ast.AndExpression.name]: AndExpression,
46+
[ast.EqualityExpression.name]: EqualityExpression,
47+
[ast.InequalityExpression.name]: InequalityExpression,
48+
[ast.BitwiseOrExpression.name]: BitwiseOrExpression,
49+
[ast.BitwiseXorExpression.name]: BitwiseXorExpression,
50+
[ast.BitwiseAndExpression.name]: BitwiseAndExpression,
51+
[ast.ShiftExpression.name]: ShiftExpression,
52+
[ast.AdditiveExpression.name]: AdditiveExpression,
53+
[ast.MultiplicativeExpression.name]: MultiplicativeExpression,
54+
[ast.ExponentiationExpression.name]: ExponentiationExpression,
55+
[ast.PostfixExpression.name]: PostfixExpression,
56+
[ast.PrefixExpression.name]: PrefixExpression,
57+
[ast.FunctionCallExpression.name]: FunctionCallExpression,
58+
[ast.CallOptionsExpression.name]: CallOptionsExpression,
59+
[ast.MemberAccessExpression.name]: MemberAccessExpression,
60+
[ast.IndexAccessExpression.name]: IndexAccessExpression,
61+
[ast.NewExpression.name]: NewExpression,
62+
[ast.TupleExpression.name]: TupleExpression,
63+
[ast.TypeExpression.name]: TypeExpression,
64+
[ast.ArrayExpression.name]: ArrayExpression,
65+
[ast.HexNumberExpression.name]: HexNumberExpression,
66+
[ast.DecimalNumberExpression.name]: DecimalNumberExpression
67+
};
68+
69+
const variantWithVariantsConstructors = {
70+
[ast.StringExpression.name]: StringExpression,
71+
[ast.ElementaryType.name]: ElementaryType
72+
};
73+
4174
function createNonterminalVariant(
4275
variant: Exclude<ast.Expression['variant'], SlangTerminalNode>,
4376
collected: CollectedMetadata,
4477
options: ParserOptions<AstNode>
4578
): Expression['variant'] {
46-
if (variant instanceof ast.AssignmentExpression) {
47-
return new AssignmentExpression(variant, collected, options);
48-
}
49-
if (variant instanceof ast.ConditionalExpression) {
50-
return new ConditionalExpression(variant, collected, options);
51-
}
52-
if (variant instanceof ast.OrExpression) {
53-
return new OrExpression(variant, collected, options);
54-
}
55-
if (variant instanceof ast.AndExpression) {
56-
return new AndExpression(variant, collected, options);
57-
}
58-
if (variant instanceof ast.EqualityExpression) {
59-
return new EqualityExpression(variant, collected, options);
60-
}
61-
if (variant instanceof ast.InequalityExpression) {
62-
return new InequalityExpression(variant, collected, options);
63-
}
64-
if (variant instanceof ast.BitwiseOrExpression) {
65-
return new BitwiseOrExpression(variant, collected, options);
66-
}
67-
if (variant instanceof ast.BitwiseXorExpression) {
68-
return new BitwiseXorExpression(variant, collected, options);
69-
}
70-
if (variant instanceof ast.BitwiseAndExpression) {
71-
return new BitwiseAndExpression(variant, collected, options);
72-
}
73-
if (variant instanceof ast.ShiftExpression) {
74-
return new ShiftExpression(variant, collected, options);
75-
}
76-
if (variant instanceof ast.AdditiveExpression) {
77-
return new AdditiveExpression(variant, collected, options);
78-
}
79-
if (variant instanceof ast.MultiplicativeExpression) {
80-
return new MultiplicativeExpression(variant, collected, options);
81-
}
82-
if (variant instanceof ast.ExponentiationExpression) {
83-
return new ExponentiationExpression(variant, collected, options);
84-
}
85-
if (variant instanceof ast.PostfixExpression) {
86-
return new PostfixExpression(variant, collected, options);
87-
}
88-
if (variant instanceof ast.PrefixExpression) {
89-
return new PrefixExpression(variant, collected, options);
90-
}
91-
if (variant instanceof ast.FunctionCallExpression) {
92-
return new FunctionCallExpression(variant, collected, options);
93-
}
94-
if (variant instanceof ast.CallOptionsExpression) {
95-
return new CallOptionsExpression(variant, collected, options);
96-
}
97-
if (variant instanceof ast.MemberAccessExpression) {
98-
return new MemberAccessExpression(variant, collected, options);
99-
}
100-
if (variant instanceof ast.IndexAccessExpression) {
101-
return new IndexAccessExpression(variant, collected, options);
102-
}
103-
if (variant instanceof ast.NewExpression) {
104-
return new NewExpression(variant, collected, options);
105-
}
106-
if (variant instanceof ast.TupleExpression) {
107-
return new TupleExpression(variant, collected, options);
108-
}
109-
if (variant instanceof ast.TypeExpression) {
110-
return new TypeExpression(variant, collected, options);
111-
}
112-
if (variant instanceof ast.ArrayExpression) {
113-
return new ArrayExpression(variant, collected, options);
114-
}
115-
if (variant instanceof ast.HexNumberExpression) {
116-
return new HexNumberExpression(variant, collected);
117-
}
118-
if (variant instanceof ast.DecimalNumberExpression) {
119-
return new DecimalNumberExpression(variant, collected);
120-
}
121-
if (variant instanceof ast.StringExpression) {
122-
return extractVariant(new StringExpression(variant, collected, options));
123-
}
124-
if (variant instanceof ast.ElementaryType) {
125-
return extractVariant(new ElementaryType(variant, collected));
126-
}
127-
const exhaustiveCheck: never = variant;
128-
throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`);
79+
const variantConstructor = variantConstructors[variant.constructor.name];
80+
if (variantConstructor !== undefined)
81+
return new variantConstructor(variant as never, collected, options);
82+
83+
const variantWithVariantsConstructor =
84+
variantWithVariantsConstructors[variant.constructor.name];
85+
if (variantWithVariantsConstructor !== undefined)
86+
return extractVariant(
87+
new variantWithVariantsConstructor(variant as never, collected, options)
88+
);
89+
90+
throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`);
12991
}
13092

13193
export class Expression extends SlangNode {

src/slang-nodes/FallbackFunctionAttribute.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,21 @@ import type { ParserOptions } from 'prettier';
1212
import type { CollectedMetadata } from '../types.d.ts';
1313
import type { AstNode } from './types.d.ts';
1414

15+
const variantConstructors = {
16+
[ast.ModifierInvocation.name]: ModifierInvocation,
17+
[ast.OverrideSpecifier.name]: OverrideSpecifier
18+
};
19+
1520
function createNonterminalVariant(
1621
variant: Exclude<ast.FallbackFunctionAttribute['variant'], SlangTerminalNode>,
1722
collected: CollectedMetadata,
1823
options: ParserOptions<AstNode>
1924
): Exclude<FallbackFunctionAttribute['variant'], TerminalNode> {
20-
if (variant instanceof ast.ModifierInvocation) {
21-
return new ModifierInvocation(variant, collected, options);
22-
}
23-
if (variant instanceof ast.OverrideSpecifier) {
24-
return new OverrideSpecifier(variant, collected);
25-
}
26-
const exhaustiveCheck: never = variant;
27-
throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`);
25+
const variantConstructor = variantConstructors[variant.constructor.name];
26+
if (variantConstructor !== undefined)
27+
return new variantConstructor(variant as never, collected, options);
28+
29+
throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`);
2830
}
2931

3032
export class FallbackFunctionAttribute extends SlangNode {

src/slang-nodes/ForStatementInitialization.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ import type { ParserOptions } from 'prettier';
1313
import type { CollectedMetadata } from '../types.d.ts';
1414
import type { AstNode } from './types.d.ts';
1515

16+
const variantConstructors = {
17+
[ast.ExpressionStatement.name]: ExpressionStatement,
18+
[ast.VariableDeclarationStatement.name]: VariableDeclarationStatement,
19+
[ast.TupleDeconstructionStatement.name]: TupleDeconstructionStatement
20+
};
21+
1622
function createNonterminalVariant(
1723
variant: Exclude<
1824
ast.ForStatementInitialization['variant'],
@@ -21,17 +27,11 @@ function createNonterminalVariant(
2127
collected: CollectedMetadata,
2228
options: ParserOptions<AstNode>
2329
): Exclude<ForStatementInitialization['variant'], TerminalNode> {
24-
if (variant instanceof ast.ExpressionStatement) {
25-
return new ExpressionStatement(variant, collected, options);
26-
}
27-
if (variant instanceof ast.VariableDeclarationStatement) {
28-
return new VariableDeclarationStatement(variant, collected, options);
29-
}
30-
if (variant instanceof ast.TupleDeconstructionStatement) {
31-
return new TupleDeconstructionStatement(variant, collected, options);
32-
}
33-
const exhaustiveCheck: never = variant;
34-
throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`);
30+
const variantConstructor = variantConstructors[variant.constructor.name];
31+
if (variantConstructor !== undefined)
32+
return new variantConstructor(variant as never, collected, options);
33+
34+
throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`);
3535
}
3636

3737
export class ForStatementInitialization extends SlangNode {

src/slang-nodes/FunctionAttribute.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,21 @@ import type { ParserOptions } from 'prettier';
1212
import type { CollectedMetadata } from '../types.d.ts';
1313
import type { AstNode } from './types.d.ts';
1414

15+
const variantConstructors = {
16+
[ast.ModifierInvocation.name]: ModifierInvocation,
17+
[ast.OverrideSpecifier.name]: OverrideSpecifier
18+
};
19+
1520
function createNonterminalVariant(
1621
variant: Exclude<ast.FunctionAttribute['variant'], SlangTerminalNode>,
1722
collected: CollectedMetadata,
1823
options: ParserOptions<AstNode>
1924
): Exclude<FunctionAttribute['variant'], TerminalNode> {
20-
if (variant instanceof ast.ModifierInvocation) {
21-
return new ModifierInvocation(variant, collected, options);
22-
}
23-
if (variant instanceof ast.OverrideSpecifier) {
24-
return new OverrideSpecifier(variant, collected);
25-
}
26-
const exhaustiveCheck: never = variant;
27-
throw new Error(`Unexpected variant: ${JSON.stringify(exhaustiveCheck)}`);
25+
const variantConstructor = variantConstructors[variant.constructor.name];
26+
if (variantConstructor !== undefined)
27+
return new variantConstructor(variant as never, collected, options);
28+
29+
throw new Error(`Unexpected variant: ${JSON.stringify(variant)}`);
2830
}
2931

3032
export class FunctionAttribute extends SlangNode {

0 commit comments

Comments
 (0)