diff --git a/src/slang-nodes/AbicoderPragma.ts b/src/slang-nodes/AbicoderPragma.ts index f851f6633..4ac460a1f 100644 --- a/src/slang-nodes/AbicoderPragma.ts +++ b/src/slang-nodes/AbicoderPragma.ts @@ -1,27 +1,20 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Identifier } from './Identifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class AbicoderPragma implements SlangNode { +export class AbicoderPragma extends SlangNode { readonly kind = NonterminalKind.AbicoderPragma; - comments; - - loc; - version: Identifier; constructor(ast: ast.AbicoderPragma) { - const metadata = getNodeMetadata(ast); + super(ast); this.version = new Identifier(ast.version); - - this.comments = metadata.comments; - this.loc = metadata.loc; } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/AdditiveExpression.ts b/src/slang-nodes/AdditiveExpression.ts index a85f31b73..e31d346b3 100644 --- a/src/slang-nodes/AdditiveExpression.ts +++ b/src/slang-nodes/AdditiveExpression.ts @@ -2,13 +2,13 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printBinaryOperation } from '../slang-printers/print-binary-operation.js'; import { createHugFunction } from '../slang-utils/create-hug-function.js'; import { createKindCheckFunction } from '../slang-utils/create-kind-check-function.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const tryToHug = createHugFunction(['%']); @@ -25,13 +25,9 @@ const printAdditiveExpression = printBinaryOperation( ]) ); -export class AdditiveExpression implements SlangNode { +export class AdditiveExpression extends SlangNode { readonly kind = NonterminalKind.AdditiveExpression; - comments; - - loc; - leftOperand: Expression; operator: string; @@ -39,16 +35,13 @@ export class AdditiveExpression implements SlangNode { rightOperand: Expression; constructor(ast: ast.AdditiveExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.leftOperand = new Expression(ast.leftOperand, options); this.operator = ast.operator.unparse(); this.rightOperand = new Expression(ast.rightOperand, options); - metadata = updateMetadata(metadata, [this.leftOperand, this.rightOperand]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.leftOperand, this.rightOperand); this.leftOperand = tryToHug(this.leftOperand); this.rightOperand = tryToHug(this.rightOperand); diff --git a/src/slang-nodes/AddressType.ts b/src/slang-nodes/AddressType.ts index 32b87d403..735bb13cb 100644 --- a/src/slang-nodes/AddressType.ts +++ b/src/slang-nodes/AddressType.ts @@ -1,27 +1,19 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; import { joinExisting } from '../slang-utils/join-existing.js'; +import { SlangNode } from './SlangNode.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { Doc } from 'prettier'; -import type { SlangNode } from '../types.d.ts'; -export class AddressType implements SlangNode { +export class AddressType extends SlangNode { readonly kind = NonterminalKind.AddressType; - comments; - - loc; - payableKeyword?: string; constructor(ast: ast.AddressType) { - const metadata = getNodeMetadata(ast); + super(ast); this.payableKeyword = ast.payableKeyword?.unparse(); - - this.comments = metadata.comments; - this.loc = metadata.loc; } print(): Doc { diff --git a/src/slang-nodes/AndExpression.ts b/src/slang-nodes/AndExpression.ts index 83230738d..cdd916aee 100644 --- a/src/slang-nodes/AndExpression.ts +++ b/src/slang-nodes/AndExpression.ts @@ -1,20 +1,16 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printLogicalOperation } from '../slang-printers/print-logical-operation.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class AndExpression implements SlangNode { +export class AndExpression extends SlangNode { readonly kind = NonterminalKind.AndExpression; - comments; - - loc; - leftOperand: Expression; operator: string; @@ -22,16 +18,13 @@ export class AndExpression implements SlangNode { rightOperand: Expression; constructor(ast: ast.AndExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.leftOperand = new Expression(ast.leftOperand, options); this.operator = ast.operator.unparse(); this.rightOperand = new Expression(ast.rightOperand, options); - metadata = updateMetadata(metadata, [this.leftOperand, this.rightOperand]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.leftOperand, this.rightOperand); } print( diff --git a/src/slang-nodes/ArgumentsDeclaration.ts b/src/slang-nodes/ArgumentsDeclaration.ts index fa695e482..5c2967544 100644 --- a/src/slang-nodes/ArgumentsDeclaration.ts +++ b/src/slang-nodes/ArgumentsDeclaration.ts @@ -1,24 +1,20 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { PositionalArgumentsDeclaration } from './PositionalArgumentsDeclaration.js'; import { NamedArgumentsDeclaration } from './NamedArgumentsDeclaration.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ArgumentsDeclaration implements SlangNode { +export class ArgumentsDeclaration extends SlangNode { readonly kind = NonterminalKind.ArgumentsDeclaration; - comments; - - loc; - variant: PositionalArgumentsDeclaration | NamedArgumentsDeclaration; constructor(ast: ast.ArgumentsDeclaration, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); switch (ast.variant.cst.kind) { case NonterminalKind.PositionalArgumentsDeclaration: @@ -37,10 +33,7 @@ export class ArgumentsDeclaration implements SlangNode { throw new Error(`Unexpected variant: ${ast.variant.cst.kind}`); } - metadata = updateMetadata(metadata, [this.variant]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ArrayExpression.ts b/src/slang-nodes/ArrayExpression.ts index 74ead1b95..0f7bb46f2 100644 --- a/src/slang-nodes/ArrayExpression.ts +++ b/src/slang-nodes/ArrayExpression.ts @@ -1,33 +1,26 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ArrayValues } from './ArrayValues.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group } = doc.builders; -export class ArrayExpression implements SlangNode { +export class ArrayExpression extends SlangNode { readonly kind = NonterminalKind.ArrayExpression; - comments; - - loc; - items: ArrayValues; constructor(ast: ast.ArrayExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.items = new ArrayValues(ast.items, options); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ArrayTypeName.ts b/src/slang-nodes/ArrayTypeName.ts index 27be21000..fb6fc2417 100644 --- a/src/slang-nodes/ArrayTypeName.ts +++ b/src/slang-nodes/ArrayTypeName.ts @@ -1,36 +1,29 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { TypeName } from './TypeName.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ArrayTypeName implements SlangNode { +export class ArrayTypeName extends SlangNode { readonly kind = NonterminalKind.ArrayTypeName; - comments; - - loc; - operand: TypeName; index?: Expression; constructor(ast: ast.ArrayTypeName, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.operand = new TypeName(ast.operand, options); if (ast.index) { this.index = new Expression(ast.index, options); } - metadata = updateMetadata(metadata, [this.operand, this.index]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.operand, this.index); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ArrayValues.ts b/src/slang-nodes/ArrayValues.ts index bd93d6c03..b985034ab 100644 --- a/src/slang-nodes/ArrayValues.ts +++ b/src/slang-nodes/ArrayValues.ts @@ -1,31 +1,24 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ArrayValues implements SlangNode { +export class ArrayValues extends SlangNode { readonly kind = NonterminalKind.ArrayValues; - comments; - - loc; - items: Expression[]; constructor(ast: ast.ArrayValues, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new Expression(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/AssemblyFlags.ts b/src/slang-nodes/AssemblyFlags.ts index bd0a75982..3ca2c8013 100644 --- a/src/slang-nodes/AssemblyFlags.ts +++ b/src/slang-nodes/AssemblyFlags.ts @@ -1,31 +1,24 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { StringLiteral } from './StringLiteral.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class AssemblyFlags implements SlangNode { +export class AssemblyFlags extends SlangNode { readonly kind = NonterminalKind.AssemblyFlags; - comments; - - loc; - items: StringLiteral[]; constructor(ast: ast.AssemblyFlags, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new StringLiteral(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/AssemblyFlagsDeclaration.ts b/src/slang-nodes/AssemblyFlagsDeclaration.ts index 52557175f..4b2b382ac 100644 --- a/src/slang-nodes/AssemblyFlagsDeclaration.ts +++ b/src/slang-nodes/AssemblyFlagsDeclaration.ts @@ -1,33 +1,26 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { AssemblyFlags } from './AssemblyFlags.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class AssemblyFlagsDeclaration implements SlangNode { +export class AssemblyFlagsDeclaration extends SlangNode { readonly kind = NonterminalKind.AssemblyFlagsDeclaration; - comments; - - loc; - flags: AssemblyFlags; constructor( ast: ast.AssemblyFlagsDeclaration, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.flags = new AssemblyFlags(ast.flags, options); - metadata = updateMetadata(metadata, [this.flags]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.flags); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/AssemblyStatement.ts b/src/slang-nodes/AssemblyStatement.ts index 9b6ab9d21..9a3535fdb 100644 --- a/src/slang-nodes/AssemblyStatement.ts +++ b/src/slang-nodes/AssemblyStatement.ts @@ -1,6 +1,6 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { joinExisting } from '../slang-utils/join-existing.js'; +import { SlangNode } from './SlangNode.js'; import { StringLiteral } from './StringLiteral.js'; import { AssemblyFlagsDeclaration } from './AssemblyFlagsDeclaration.js'; import { YulBlock } from './YulBlock.js'; @@ -8,15 +8,11 @@ import { YulBlock } from './YulBlock.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class AssemblyStatement implements SlangNode { +export class AssemblyStatement extends SlangNode { readonly kind = NonterminalKind.AssemblyStatement; - comments; - - loc; - label?: StringLiteral; flags?: AssemblyFlagsDeclaration; @@ -24,7 +20,7 @@ export class AssemblyStatement implements SlangNode { body: YulBlock; constructor(ast: ast.AssemblyStatement, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); if (ast.label) { this.label = new StringLiteral(ast.label, options); @@ -34,10 +30,7 @@ export class AssemblyStatement implements SlangNode { } this.body = new YulBlock(ast.body, options); - metadata = updateMetadata(metadata, [this.label, this.flags, this.body]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.label, this.flags, this.body); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/AssignmentExpression.ts b/src/slang-nodes/AssignmentExpression.ts index f971deefa..aecb2ad64 100644 --- a/src/slang-nodes/AssignmentExpression.ts +++ b/src/slang-nodes/AssignmentExpression.ts @@ -1,23 +1,19 @@ import { NonterminalKind, TerminalKind } from '@nomicfoundation/slang/cst'; import { doc } from 'prettier'; import { isBinaryOperation } from '../slang-utils/is-binary-operation.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, indent, line } = doc.builders; -export class AssignmentExpression implements SlangNode { +export class AssignmentExpression extends SlangNode { readonly kind = NonterminalKind.AssignmentExpression; - comments; - - loc; - leftOperand: Expression; operator: string; @@ -25,16 +21,13 @@ export class AssignmentExpression implements SlangNode { rightOperand: Expression; constructor(ast: ast.AssignmentExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.leftOperand = new Expression(ast.leftOperand, options); this.operator = ast.operator.unparse(); this.rightOperand = new Expression(ast.rightOperand, options); - metadata = updateMetadata(metadata, [this.leftOperand, this.rightOperand]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.leftOperand, this.rightOperand); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/BitwiseAndExpression.ts b/src/slang-nodes/BitwiseAndExpression.ts index e936c83a8..b2e721fc0 100644 --- a/src/slang-nodes/BitwiseAndExpression.ts +++ b/src/slang-nodes/BitwiseAndExpression.ts @@ -2,13 +2,13 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printBinaryOperation } from '../slang-printers/print-binary-operation.js'; import { createHugFunction } from '../slang-utils/create-hug-function.js'; import { createKindCheckFunction } from '../slang-utils/create-kind-check-function.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const tryToHug = createHugFunction(['+', '-', '*', '/', '**', '<<', '>>']); @@ -21,13 +21,9 @@ const printBitwiseAndExpression = printBinaryOperation( ]) ); -export class BitwiseAndExpression implements SlangNode { +export class BitwiseAndExpression extends SlangNode { readonly kind = NonterminalKind.BitwiseAndExpression; - comments; - - loc; - leftOperand: Expression; operator: string; @@ -35,16 +31,13 @@ export class BitwiseAndExpression implements SlangNode { rightOperand: Expression; constructor(ast: ast.BitwiseAndExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.leftOperand = new Expression(ast.leftOperand, options); this.operator = ast.operator.unparse(); this.rightOperand = new Expression(ast.rightOperand, options); - metadata = updateMetadata(metadata, [this.leftOperand, this.rightOperand]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.leftOperand, this.rightOperand); this.leftOperand = tryToHug(this.leftOperand); this.rightOperand = tryToHug(this.rightOperand); diff --git a/src/slang-nodes/BitwiseOrExpression.ts b/src/slang-nodes/BitwiseOrExpression.ts index 3c51cfa64..34b6ac9f2 100644 --- a/src/slang-nodes/BitwiseOrExpression.ts +++ b/src/slang-nodes/BitwiseOrExpression.ts @@ -2,13 +2,13 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printBinaryOperation } from '../slang-printers/print-binary-operation.js'; import { createHugFunction } from '../slang-utils/create-hug-function.js'; import { createKindCheckFunction } from '../slang-utils/create-kind-check-function.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const tryToHug = createHugFunction([ '+', @@ -31,13 +31,9 @@ const printBitwiseOrExpression = printBinaryOperation( ]) ); -export class BitwiseOrExpression implements SlangNode { +export class BitwiseOrExpression extends SlangNode { readonly kind = NonterminalKind.BitwiseOrExpression; - comments; - - loc; - leftOperand: Expression; operator: string; @@ -45,16 +41,13 @@ export class BitwiseOrExpression implements SlangNode { rightOperand: Expression; constructor(ast: ast.BitwiseOrExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.leftOperand = new Expression(ast.leftOperand, options); this.operator = ast.operator.unparse(); this.rightOperand = new Expression(ast.rightOperand, options); - metadata = updateMetadata(metadata, [this.leftOperand, this.rightOperand]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.leftOperand, this.rightOperand); this.leftOperand = tryToHug(this.leftOperand); this.rightOperand = tryToHug(this.rightOperand); diff --git a/src/slang-nodes/BitwiseXorExpression.ts b/src/slang-nodes/BitwiseXorExpression.ts index f341e8155..443ce60c5 100644 --- a/src/slang-nodes/BitwiseXorExpression.ts +++ b/src/slang-nodes/BitwiseXorExpression.ts @@ -2,13 +2,13 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printBinaryOperation } from '../slang-printers/print-binary-operation.js'; import { createHugFunction } from '../slang-utils/create-hug-function.js'; import { createKindCheckFunction } from '../slang-utils/create-kind-check-function.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const tryToHug = createHugFunction(['+', '-', '*', '/', '**', '<<', '>>', '&']); @@ -21,13 +21,9 @@ const printBitwiseXorExpression = printBinaryOperation( ]) ); -export class BitwiseXorExpression implements SlangNode { +export class BitwiseXorExpression extends SlangNode { readonly kind = NonterminalKind.BitwiseXorExpression; - comments; - - loc; - leftOperand: Expression; operator: string; @@ -35,16 +31,13 @@ export class BitwiseXorExpression implements SlangNode { rightOperand: Expression; constructor(ast: ast.BitwiseXorExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.leftOperand = new Expression(ast.leftOperand, options); this.operator = ast.operator.unparse(); this.rightOperand = new Expression(ast.rightOperand, options); - metadata = updateMetadata(metadata, [this.leftOperand, this.rightOperand]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.leftOperand, this.rightOperand); this.leftOperand = tryToHug(this.leftOperand); this.rightOperand = tryToHug(this.rightOperand); diff --git a/src/slang-nodes/Block.ts b/src/slang-nodes/Block.ts index ef6f4c0a1..c7e72ddc9 100644 --- a/src/slang-nodes/Block.ts +++ b/src/slang-nodes/Block.ts @@ -1,30 +1,23 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Statements } from './Statements.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class Block implements SlangNode { +export class Block extends SlangNode { readonly kind = NonterminalKind.Block; - comments; - - loc; - statements: Statements; constructor(ast: ast.Block, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.statements = new Statements(ast.statements, options); - metadata = updateMetadata(metadata, [this.statements]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.statements); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/BreakStatement.ts b/src/slang-nodes/BreakStatement.ts index fe7a837f2..2e8eb523d 100644 --- a/src/slang-nodes/BreakStatement.ts +++ b/src/slang-nodes/BreakStatement.ts @@ -1,22 +1,14 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { Doc } from 'prettier'; -import type { SlangNode } from '../types.d.ts'; -export class BreakStatement implements SlangNode { +export class BreakStatement extends SlangNode { readonly kind = NonterminalKind.BreakStatement; - comments; - - loc; - constructor(ast: ast.BreakStatement) { - const metadata = getNodeMetadata(ast); - - this.comments = metadata.comments; - this.loc = metadata.loc; + super(ast); } print(): Doc { diff --git a/src/slang-nodes/CallOptions.ts b/src/slang-nodes/CallOptions.ts index 6b2389b16..936af9da6 100644 --- a/src/slang-nodes/CallOptions.ts +++ b/src/slang-nodes/CallOptions.ts @@ -1,34 +1,27 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { NamedArgument } from './NamedArgument.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line, softline } = doc.builders; -export class CallOptions implements SlangNode { +export class CallOptions extends SlangNode { readonly kind = NonterminalKind.CallOptions; - comments; - - loc; - items: NamedArgument[]; constructor(ast: ast.CallOptions, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new NamedArgument(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print( diff --git a/src/slang-nodes/CallOptionsExpression.ts b/src/slang-nodes/CallOptionsExpression.ts index 60f6f8d06..c13270aea 100644 --- a/src/slang-nodes/CallOptionsExpression.ts +++ b/src/slang-nodes/CallOptionsExpression.ts @@ -1,34 +1,27 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import { CallOptions } from './CallOptions.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class CallOptionsExpression implements SlangNode { +export class CallOptionsExpression extends SlangNode { readonly kind = NonterminalKind.CallOptionsExpression; - comments; - - loc; - operand: Expression; options: CallOptions; constructor(ast: ast.CallOptionsExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.operand = new Expression(ast.operand, options); this.options = new CallOptions(ast.options, options); - metadata = updateMetadata(metadata, [this.operand, this.options]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.operand, this.options); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/CatchClause.ts b/src/slang-nodes/CatchClause.ts index 8e529500c..caecbb096 100644 --- a/src/slang-nodes/CatchClause.ts +++ b/src/slang-nodes/CatchClause.ts @@ -1,36 +1,29 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { CatchClauseError } from './CatchClauseError.js'; import { Block } from './Block.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class CatchClause implements SlangNode { +export class CatchClause extends SlangNode { readonly kind = NonterminalKind.CatchClause; - comments; - - loc; - error?: CatchClauseError; body: Block; constructor(ast: ast.CatchClause, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); if (ast.error) { this.error = new CatchClauseError(ast.error, options); } this.body = new Block(ast.body, options); - metadata = updateMetadata(metadata, [this.error, this.body]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.error, this.body); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/CatchClauseError.ts b/src/slang-nodes/CatchClauseError.ts index 8fbe4a1e0..5646f2534 100644 --- a/src/slang-nodes/CatchClauseError.ts +++ b/src/slang-nodes/CatchClauseError.ts @@ -1,39 +1,32 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Identifier } from './Identifier.js'; import { ParametersDeclaration } from './ParametersDeclaration.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group } = doc.builders; -export class CatchClauseError implements SlangNode { +export class CatchClauseError extends SlangNode { readonly kind = NonterminalKind.CatchClauseError; - comments; - - loc; - name?: Identifier; parameters: ParametersDeclaration; constructor(ast: ast.CatchClauseError, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); if (ast.name) { this.name = new Identifier(ast.name); } this.parameters = new ParametersDeclaration(ast.parameters, options); - metadata = updateMetadata(metadata, [this.parameters]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.parameters); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/CatchClauses.ts b/src/slang-nodes/CatchClauses.ts index 6ece00d34..dbac2e255 100644 --- a/src/slang-nodes/CatchClauses.ts +++ b/src/slang-nodes/CatchClauses.ts @@ -1,33 +1,26 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { CatchClause } from './CatchClause.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { join } = doc.builders; -export class CatchClauses implements SlangNode { +export class CatchClauses extends SlangNode { readonly kind = NonterminalKind.CatchClauses; - comments; - - loc; - items: CatchClause[]; constructor(ast: ast.CatchClauses, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new CatchClause(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/CommentNode.ts b/src/slang-nodes/CommentNode.ts new file mode 100644 index 000000000..bb274020c --- /dev/null +++ b/src/slang-nodes/CommentNode.ts @@ -0,0 +1,28 @@ +import type { TerminalNode } from '@nomicfoundation/slang/cst'; +import type { Location } from '../types.d.ts'; +import type { StrictAstNode } from './types.d.ts'; + +export class CommentNode { + loc: Location; + + leading?: boolean; + + trailing?: boolean; + + printed?: boolean; + + placement?: 'endOfLine' | 'ownLine' | 'remaining'; + + precedingNode?: StrictAstNode; + + enclosingNode?: StrictAstNode; + + followingNode?: StrictAstNode; + + constructor(ast: TerminalNode, offset: number) { + this.loc = { + start: offset, + end: offset + ast.textLength.utf16 + }; + } +} diff --git a/src/slang-nodes/ConditionalExpression.ts b/src/slang-nodes/ConditionalExpression.ts index d8098c3fe..102635b5b 100644 --- a/src/slang-nodes/ConditionalExpression.ts +++ b/src/slang-nodes/ConditionalExpression.ts @@ -1,13 +1,13 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedItem } from '../slang-printers/print-separated-item.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode, StrictAstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, hardline, ifBreak, indent, line, softline } = doc.builders; @@ -108,13 +108,9 @@ function getOperandSingleExpression({ : undefined; } -export class ConditionalExpression implements SlangNode { +export class ConditionalExpression extends SlangNode { readonly kind = NonterminalKind.ConditionalExpression; - comments; - - loc; - operand: Expression; trueExpression: Expression; @@ -122,20 +118,17 @@ export class ConditionalExpression implements SlangNode { falseExpression: Expression; constructor(ast: ast.ConditionalExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.operand = new Expression(ast.operand, options); this.trueExpression = new Expression(ast.trueExpression, options); this.falseExpression = new Expression(ast.falseExpression, options); - metadata = updateMetadata(metadata, [ + this.updateMetadata( this.operand, this.trueExpression, this.falseExpression - ]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + ); if (options.experimentalTernaries) { // We can remove parentheses only because we are sure that the diff --git a/src/slang-nodes/ConstantDefinition.ts b/src/slang-nodes/ConstantDefinition.ts index f047600db..529bd2eb5 100644 --- a/src/slang-nodes/ConstantDefinition.ts +++ b/src/slang-nodes/ConstantDefinition.ts @@ -1,5 +1,5 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { TypeName } from './TypeName.js'; import { Identifier } from './Identifier.js'; import { Expression } from './Expression.js'; @@ -7,15 +7,11 @@ import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ConstantDefinition implements SlangNode { +export class ConstantDefinition extends SlangNode { readonly kind = NonterminalKind.ConstantDefinition; - comments; - - loc; - typeName: TypeName; name: Identifier; @@ -23,16 +19,13 @@ export class ConstantDefinition implements SlangNode { value: Expression; constructor(ast: ast.ConstantDefinition, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.typeName = new TypeName(ast.typeName, options); this.name = new Identifier(ast.name); this.value = new Expression(ast.value, options); - metadata = updateMetadata(metadata, [this.typeName, this.value]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.typeName, this.value); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ConstructorAttribute.ts b/src/slang-nodes/ConstructorAttribute.ts index db6dd0ec2..b050d45cf 100644 --- a/src/slang-nodes/ConstructorAttribute.ts +++ b/src/slang-nodes/ConstructorAttribute.ts @@ -1,36 +1,26 @@ import { NonterminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ModifierInvocation } from './ModifierInvocation.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ConstructorAttribute implements SlangNode { +export class ConstructorAttribute extends SlangNode { readonly kind = NonterminalKind.ConstructorAttribute; - comments; - - loc; - variant: ModifierInvocation | string; constructor(ast: ast.ConstructorAttribute, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant instanceof TerminalNode ? ast.variant.unparse() : new ModifierInvocation(ast.variant, options); - metadata = updateMetadata( - metadata, - typeof this.variant === 'string' ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (typeof this.variant !== 'string') this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ConstructorAttributes.ts b/src/slang-nodes/ConstructorAttributes.ts index 325e3bde7..003b4dbe2 100644 --- a/src/slang-nodes/ConstructorAttributes.ts +++ b/src/slang-nodes/ConstructorAttributes.ts @@ -1,36 +1,29 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { sortFunctionAttributes } from '../slang-utils/sort-function-attributes.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ConstructorAttribute } from './ConstructorAttribute.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line } = doc.builders; -export class ConstructorAttributes implements SlangNode { +export class ConstructorAttributes extends SlangNode { readonly kind = NonterminalKind.ConstructorAttributes; - comments; - - loc; - items: ConstructorAttribute[]; constructor(ast: ast.ConstructorAttributes, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map( (item) => new ConstructorAttribute(item, options) ); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); this.items = this.items.sort(sortFunctionAttributes); } diff --git a/src/slang-nodes/ConstructorDefinition.ts b/src/slang-nodes/ConstructorDefinition.ts index e0823786f..7bc9759e1 100644 --- a/src/slang-nodes/ConstructorDefinition.ts +++ b/src/slang-nodes/ConstructorDefinition.ts @@ -1,6 +1,6 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printFunction } from '../slang-printers/print-function.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ParametersDeclaration } from './ParametersDeclaration.js'; import { ConstructorAttributes } from './ConstructorAttributes.js'; import { Block } from './Block.js'; @@ -8,15 +8,11 @@ import { Block } from './Block.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ConstructorDefinition implements SlangNode { +export class ConstructorDefinition extends SlangNode { readonly kind = NonterminalKind.ConstructorDefinition; - comments; - - loc; - parameters: ParametersDeclaration; attributes: ConstructorAttributes; @@ -24,20 +20,13 @@ export class ConstructorDefinition implements SlangNode { body: Block; constructor(ast: ast.ConstructorDefinition, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.parameters = new ParametersDeclaration(ast.parameters, options); this.attributes = new ConstructorAttributes(ast.attributes, options); this.body = new Block(ast.body, options); - metadata = updateMetadata(metadata, [ - this.parameters, - this.attributes, - this.body - ]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.parameters, this.attributes, this.body); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ContinueStatement.ts b/src/slang-nodes/ContinueStatement.ts index a93c1613c..5e856cb49 100644 --- a/src/slang-nodes/ContinueStatement.ts +++ b/src/slang-nodes/ContinueStatement.ts @@ -1,22 +1,14 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { Doc } from 'prettier'; -import type { SlangNode } from '../types.d.ts'; -export class ContinueStatement implements SlangNode { +export class ContinueStatement extends SlangNode { readonly kind = NonterminalKind.ContinueStatement; - comments; - - loc; - constructor(ast: ast.ContinueStatement) { - const metadata = getNodeMetadata(ast); - - this.comments = metadata.comments; - this.loc = metadata.loc; + super(ast); } print(): Doc { diff --git a/src/slang-nodes/ContractDefinition.ts b/src/slang-nodes/ContractDefinition.ts index c158eb0bf..363746997 100644 --- a/src/slang-nodes/ContractDefinition.ts +++ b/src/slang-nodes/ContractDefinition.ts @@ -1,7 +1,7 @@ import { doc } from 'prettier'; import { satisfies } from 'semver'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Identifier } from './Identifier.js'; import { ContractSpecifiers } from './ContractSpecifiers.js'; import { ContractMembers } from './ContractMembers.js'; @@ -9,17 +9,13 @@ import { ContractMembers } from './ContractMembers.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, line } = doc.builders; -export class ContractDefinition implements SlangNode { +export class ContractDefinition extends SlangNode { readonly kind = NonterminalKind.ContractDefinition; - comments; - - loc; - abstractKeyword?: string; name: Identifier; @@ -29,17 +25,14 @@ export class ContractDefinition implements SlangNode { members: ContractMembers; constructor(ast: ast.ContractDefinition, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.abstractKeyword = ast.abstractKeyword?.unparse(); this.name = new Identifier(ast.name); this.specifiers = new ContractSpecifiers(ast.specifiers, options); this.members = new ContractMembers(ast.members, options); - metadata = updateMetadata(metadata, [this.specifiers, this.members]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.specifiers, this.members); this.cleanModifierInvocationArguments(options); } diff --git a/src/slang-nodes/ContractMember.ts b/src/slang-nodes/ContractMember.ts index 00e7845d8..b74ed3393 100644 --- a/src/slang-nodes/ContractMember.ts +++ b/src/slang-nodes/ContractMember.ts @@ -1,5 +1,5 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { UsingDirective } from './UsingDirective.js'; import { FunctionDefinition } from './FunctionDefinition.js'; import { ConstructorDefinition } from './ConstructorDefinition.js'; @@ -17,15 +17,11 @@ import { UserDefinedValueTypeDefinition } from './UserDefinedValueTypeDefinition import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ContractMember implements SlangNode { +export class ContractMember extends SlangNode { readonly kind = NonterminalKind.ContractMember; - comments; - - loc; - variant: | UsingDirective | FunctionDefinition @@ -42,7 +38,7 @@ export class ContractMember implements SlangNode { | UserDefinedValueTypeDefinition; constructor(ast: ast.ContractMember, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); switch (ast.variant.cst.kind) { case NonterminalKind.UsingDirective: @@ -123,10 +119,7 @@ export class ContractMember implements SlangNode { throw new Error(`Unexpected variant: ${ast.variant.cst.kind}`); } - metadata = updateMetadata(metadata, [this.variant]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ContractMembers.ts b/src/slang-nodes/ContractMembers.ts index 935839d5a..cd82c186c 100644 --- a/src/slang-nodes/ContractMembers.ts +++ b/src/slang-nodes/ContractMembers.ts @@ -3,34 +3,27 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedItem } from '../slang-printers/print-separated-item.js'; import { printComments } from '../slang-printers/print-comments.js'; import { printPreservingEmptyLines } from '../slang-printers/print-preserving-empty-lines.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ContractMember } from './ContractMember.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { hardline } = doc.builders; -export class ContractMembers implements SlangNode { +export class ContractMembers extends SlangNode { readonly kind = NonterminalKind.ContractMembers; - comments; - - loc; - items: ContractMember[]; constructor(ast: ast.ContractMembers, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new ContractMember(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print( diff --git a/src/slang-nodes/ContractSpecifier.ts b/src/slang-nodes/ContractSpecifier.ts index bfa0970fd..0b0030378 100644 --- a/src/slang-nodes/ContractSpecifier.ts +++ b/src/slang-nodes/ContractSpecifier.ts @@ -1,24 +1,20 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { InheritanceSpecifier } from './InheritanceSpecifier.js'; import { StorageLayoutSpecifier } from './StorageLayoutSpecifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ContractSpecifier implements SlangNode { +export class ContractSpecifier extends SlangNode { readonly kind = NonterminalKind.ContractSpecifier; - comments; - - loc; - variant: InheritanceSpecifier | StorageLayoutSpecifier; constructor(ast: ast.ContractSpecifier, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); switch (ast.variant.cst.kind) { case NonterminalKind.InheritanceSpecifier: @@ -36,10 +32,7 @@ export class ContractSpecifier implements SlangNode { default: throw new Error(`Unexpected variant: ${ast.variant.cst.kind}`); } - metadata = updateMetadata(metadata, [this.variant]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ContractSpecifiers.ts b/src/slang-nodes/ContractSpecifiers.ts index 60065bd2d..fc3cae149 100644 --- a/src/slang-nodes/ContractSpecifiers.ts +++ b/src/slang-nodes/ContractSpecifiers.ts @@ -2,34 +2,27 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { sortContractSpecifiers } from '../slang-utils/sort-contract-specifiers.js'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ContractSpecifier } from './ContractSpecifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, ifBreak, line, softline } = doc.builders; -export class ContractSpecifiers implements SlangNode { +export class ContractSpecifiers extends SlangNode { readonly kind = NonterminalKind.ContractSpecifiers; - comments; - - loc; - items: ContractSpecifier[]; constructor(ast: ast.ContractSpecifiers, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new ContractSpecifier(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); this.items = this.items.sort(sortContractSpecifiers); } diff --git a/src/slang-nodes/DecimalNumberExpression.ts b/src/slang-nodes/DecimalNumberExpression.ts index f5fc3cd2a..211fb2bee 100644 --- a/src/slang-nodes/DecimalNumberExpression.ts +++ b/src/slang-nodes/DecimalNumberExpression.ts @@ -1,35 +1,28 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { joinExisting } from '../slang-utils/join-existing.js'; +import { SlangNode } from './SlangNode.js'; import { NumberUnit } from './NumberUnit.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class DecimalNumberExpression implements SlangNode { +export class DecimalNumberExpression extends SlangNode { readonly kind = NonterminalKind.DecimalNumberExpression; - comments; - - loc; - literal: string; unit?: NumberUnit; constructor(ast: ast.DecimalNumberExpression) { - let metadata = getNodeMetadata(ast); + super(ast); this.literal = ast.literal.unparse(); if (ast.unit) { this.unit = new NumberUnit(ast.unit); } - metadata = updateMetadata(metadata, [this.unit]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.unit); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/DoWhileStatement.ts b/src/slang-nodes/DoWhileStatement.ts index ee4dc794a..2685f206b 100644 --- a/src/slang-nodes/DoWhileStatement.ts +++ b/src/slang-nodes/DoWhileStatement.ts @@ -1,38 +1,31 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedItem } from '../slang-printers/print-separated-item.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Statement } from './Statement.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, indent, line } = doc.builders; -export class DoWhileStatement implements SlangNode { +export class DoWhileStatement extends SlangNode { readonly kind = NonterminalKind.DoWhileStatement; - comments; - - loc; - body: Statement; condition: Expression; constructor(ast: ast.DoWhileStatement, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.body = new Statement(ast.body, options); this.condition = new Expression(ast.condition, options); - metadata = updateMetadata(metadata, [this.body, this.condition]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.body, this.condition); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ElementaryType.ts b/src/slang-nodes/ElementaryType.ts index b2fb6c469..1e28c45b1 100644 --- a/src/slang-nodes/ElementaryType.ts +++ b/src/slang-nodes/ElementaryType.ts @@ -1,35 +1,25 @@ import { NonterminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { AddressType } from './AddressType.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ElementaryType implements SlangNode { +export class ElementaryType extends SlangNode { readonly kind = NonterminalKind.ElementaryType; - comments; - - loc; - variant: AddressType | string; constructor(ast: ast.ElementaryType) { - let metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant instanceof TerminalNode ? ast.variant.unparse() : new AddressType(ast.variant); - metadata = updateMetadata( - metadata, - typeof this.variant === 'string' ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (typeof this.variant !== 'string') this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ElseBranch.ts b/src/slang-nodes/ElseBranch.ts index b5db67980..dc657f05f 100644 --- a/src/slang-nodes/ElseBranch.ts +++ b/src/slang-nodes/ElseBranch.ts @@ -1,13 +1,13 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createKindCheckFunction } from '../slang-utils/create-kind-check-function.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Statement } from './Statement.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, indent, line } = doc.builders; @@ -16,24 +16,17 @@ const isIfStatementOrBlock = createKindCheckFunction([ NonterminalKind.IfStatement ]); -export class ElseBranch implements SlangNode { +export class ElseBranch extends SlangNode { readonly kind = NonterminalKind.ElseBranch; - comments; - - loc; - body: Statement; constructor(ast: ast.ElseBranch, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.body = new Statement(ast.body, options); - metadata = updateMetadata(metadata, [this.body]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.body); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/EmitStatement.ts b/src/slang-nodes/EmitStatement.ts index e883dbefc..6b3d217b0 100644 --- a/src/slang-nodes/EmitStatement.ts +++ b/src/slang-nodes/EmitStatement.ts @@ -1,34 +1,27 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { IdentifierPath } from './IdentifierPath.js'; import { ArgumentsDeclaration } from './ArgumentsDeclaration.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class EmitStatement implements SlangNode { +export class EmitStatement extends SlangNode { readonly kind = NonterminalKind.EmitStatement; - comments; - - loc; - event: IdentifierPath; arguments: ArgumentsDeclaration; constructor(ast: ast.EmitStatement, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.event = new IdentifierPath(ast.event); this.arguments = new ArgumentsDeclaration(ast.arguments, options); - metadata = updateMetadata(metadata, [this.event, this.arguments]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.event, this.arguments); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/EnumDefinition.ts b/src/slang-nodes/EnumDefinition.ts index 22c5c37c1..7df5b8fe7 100644 --- a/src/slang-nodes/EnumDefinition.ts +++ b/src/slang-nodes/EnumDefinition.ts @@ -1,33 +1,26 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Identifier } from './Identifier.js'; import { EnumMembers } from './EnumMembers.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class EnumDefinition implements SlangNode { +export class EnumDefinition extends SlangNode { readonly kind = NonterminalKind.EnumDefinition; - comments; - - loc; - name: Identifier; members: EnumMembers; constructor(ast: ast.EnumDefinition) { - let metadata = getNodeMetadata(ast); + super(ast); this.name = new Identifier(ast.name); this.members = new EnumMembers(ast.members); - metadata = updateMetadata(metadata, [this.members]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.members); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/EnumMembers.ts b/src/slang-nodes/EnumMembers.ts index 81dcdf3bd..1925635d6 100644 --- a/src/slang-nodes/EnumMembers.ts +++ b/src/slang-nodes/EnumMembers.ts @@ -1,31 +1,24 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Identifier } from './Identifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { hardline } = doc.builders; -export class EnumMembers implements SlangNode { +export class EnumMembers extends SlangNode { readonly kind = NonterminalKind.EnumMembers; - comments; - - loc; - items: Identifier[]; constructor(ast: ast.EnumMembers) { - const metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new Identifier(item)); - - this.comments = metadata.comments; - this.loc = metadata.loc; } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/EqualityExpression.ts b/src/slang-nodes/EqualityExpression.ts index f34aa0812..6dd6bf401 100644 --- a/src/slang-nodes/EqualityExpression.ts +++ b/src/slang-nodes/EqualityExpression.ts @@ -2,13 +2,13 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createHugFunction } from '../slang-utils/create-hug-function.js'; import { createKindCheckFunction } from '../slang-utils/create-kind-check-function.js'; import { printBinaryOperation } from '../slang-printers/print-binary-operation.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const tryToHug = createHugFunction(['==', '!=']); @@ -19,13 +19,9 @@ const printEqualityExpression = printBinaryOperation( ]) ); -export class EqualityExpression implements SlangNode { +export class EqualityExpression extends SlangNode { readonly kind = NonterminalKind.EqualityExpression; - comments; - - loc; - leftOperand: Expression; operator: string; @@ -33,16 +29,13 @@ export class EqualityExpression implements SlangNode { rightOperand: Expression; constructor(ast: ast.EqualityExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.leftOperand = new Expression(ast.leftOperand, options); this.operator = ast.operator.unparse(); this.rightOperand = new Expression(ast.rightOperand, options); - metadata = updateMetadata(metadata, [this.leftOperand, this.rightOperand]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.leftOperand, this.rightOperand); this.leftOperand = tryToHug(this.leftOperand); } diff --git a/src/slang-nodes/ErrorDefinition.ts b/src/slang-nodes/ErrorDefinition.ts index 8a3dfb409..e1534cd3c 100644 --- a/src/slang-nodes/ErrorDefinition.ts +++ b/src/slang-nodes/ErrorDefinition.ts @@ -1,34 +1,27 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Identifier } from './Identifier.js'; import { ErrorParametersDeclaration } from './ErrorParametersDeclaration.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ErrorDefinition implements SlangNode { +export class ErrorDefinition extends SlangNode { readonly kind = NonterminalKind.ErrorDefinition; - comments; - - loc; - name: Identifier; members: ErrorParametersDeclaration; constructor(ast: ast.ErrorDefinition, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.name = new Identifier(ast.name); this.members = new ErrorParametersDeclaration(ast.members, options); - metadata = updateMetadata(metadata, [this.members]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.members); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ErrorParameter.ts b/src/slang-nodes/ErrorParameter.ts index 858305f12..4f65a94f4 100644 --- a/src/slang-nodes/ErrorParameter.ts +++ b/src/slang-nodes/ErrorParameter.ts @@ -1,37 +1,30 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { joinExisting } from '../slang-utils/join-existing.js'; +import { SlangNode } from './SlangNode.js'; import { TypeName } from './TypeName.js'; import { Identifier } from './Identifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ErrorParameter implements SlangNode { +export class ErrorParameter extends SlangNode { readonly kind = NonterminalKind.ErrorParameter; - comments; - - loc; - typeName: TypeName; name?: Identifier; constructor(ast: ast.ErrorParameter, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.typeName = new TypeName(ast.typeName, options); if (ast.name) { this.name = new Identifier(ast.name); } - metadata = updateMetadata(metadata, [this.typeName]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.typeName); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ErrorParameters.ts b/src/slang-nodes/ErrorParameters.ts index 701d7bfb5..bbbdaf711 100644 --- a/src/slang-nodes/ErrorParameters.ts +++ b/src/slang-nodes/ErrorParameters.ts @@ -1,31 +1,24 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ErrorParameter } from './ErrorParameter.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ErrorParameters implements SlangNode { +export class ErrorParameters extends SlangNode { readonly kind = NonterminalKind.ErrorParameters; - comments; - - loc; - items: ErrorParameter[]; constructor(ast: ast.ErrorParameters, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new ErrorParameter(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ErrorParametersDeclaration.ts b/src/slang-nodes/ErrorParametersDeclaration.ts index fe04aa54f..39a0784fe 100644 --- a/src/slang-nodes/ErrorParametersDeclaration.ts +++ b/src/slang-nodes/ErrorParametersDeclaration.ts @@ -1,33 +1,26 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ErrorParameters } from './ErrorParameters.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ErrorParametersDeclaration implements SlangNode { +export class ErrorParametersDeclaration extends SlangNode { readonly kind = NonterminalKind.ErrorParametersDeclaration; - comments; - - loc; - parameters: ErrorParameters; constructor( ast: ast.ErrorParametersDeclaration, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.parameters = new ErrorParameters(ast.parameters, options); - metadata = updateMetadata(metadata, [this.parameters]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.parameters); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/EventDefinition.ts b/src/slang-nodes/EventDefinition.ts index 0cb1e3898..77837800e 100644 --- a/src/slang-nodes/EventDefinition.ts +++ b/src/slang-nodes/EventDefinition.ts @@ -1,20 +1,16 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { EventParametersDeclaration } from './EventParametersDeclaration.js'; import { Identifier } from './Identifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class EventDefinition implements SlangNode { +export class EventDefinition extends SlangNode { readonly kind = NonterminalKind.EventDefinition; - comments; - - loc; - name: Identifier; parameters: EventParametersDeclaration; @@ -22,16 +18,13 @@ export class EventDefinition implements SlangNode { anonymousKeyword?: string; constructor(ast: ast.EventDefinition, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.name = new Identifier(ast.name); this.parameters = new EventParametersDeclaration(ast.parameters, options); this.anonymousKeyword = ast.anonymousKeyword?.unparse(); - metadata = updateMetadata(metadata, [this.parameters]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.parameters); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/EventParameter.ts b/src/slang-nodes/EventParameter.ts index ce310f219..43b917691 100644 --- a/src/slang-nodes/EventParameter.ts +++ b/src/slang-nodes/EventParameter.ts @@ -1,21 +1,17 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { joinExisting } from '../slang-utils/join-existing.js'; +import { SlangNode } from './SlangNode.js'; import { TypeName } from './TypeName.js'; import { Identifier } from './Identifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class EventParameter implements SlangNode { +export class EventParameter extends SlangNode { readonly kind = NonterminalKind.EventParameter; - comments; - - loc; - typeName: TypeName; indexedKeyword?: string; @@ -23,7 +19,7 @@ export class EventParameter implements SlangNode { name?: Identifier; constructor(ast: ast.EventParameter, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.typeName = new TypeName(ast.typeName, options); this.indexedKeyword = ast.indexedKeyword?.unparse(); @@ -31,10 +27,7 @@ export class EventParameter implements SlangNode { this.name = new Identifier(ast.name); } - metadata = updateMetadata(metadata, [this.typeName]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.typeName); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/EventParameters.ts b/src/slang-nodes/EventParameters.ts index bcc303f32..6c03aaba1 100644 --- a/src/slang-nodes/EventParameters.ts +++ b/src/slang-nodes/EventParameters.ts @@ -1,31 +1,24 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { EventParameter } from './EventParameter.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class EventParameters implements SlangNode { +export class EventParameters extends SlangNode { readonly kind = NonterminalKind.EventParameters; - comments; - - loc; - items: EventParameter[]; constructor(ast: ast.EventParameters, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new EventParameter(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/EventParametersDeclaration.ts b/src/slang-nodes/EventParametersDeclaration.ts index 5f3194f93..f6fc717f0 100644 --- a/src/slang-nodes/EventParametersDeclaration.ts +++ b/src/slang-nodes/EventParametersDeclaration.ts @@ -1,33 +1,26 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { EventParameters } from './EventParameters.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class EventParametersDeclaration implements SlangNode { +export class EventParametersDeclaration extends SlangNode { readonly kind = NonterminalKind.EventParametersDeclaration; - comments; - - loc; - parameters: EventParameters; constructor( ast: ast.EventParametersDeclaration, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.parameters = new EventParameters(ast.parameters, options); - metadata = updateMetadata(metadata, [this.parameters]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.parameters); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ExperimentalFeature.ts b/src/slang-nodes/ExperimentalFeature.ts index a513b9ecd..fbf84674a 100644 --- a/src/slang-nodes/ExperimentalFeature.ts +++ b/src/slang-nodes/ExperimentalFeature.ts @@ -3,39 +3,30 @@ import { TerminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { StringLiteral } from './StringLiteral.js'; import { Identifier } from './Identifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ExperimentalFeature implements SlangNode { +export class ExperimentalFeature extends SlangNode { readonly kind = NonterminalKind.ExperimentalFeature; - comments; - - loc; - variant: StringLiteral | Identifier; constructor(ast: ast.ExperimentalFeature, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant instanceof TerminalNode ? new Identifier(ast.variant) : new StringLiteral(ast.variant, options); - metadata = updateMetadata( - metadata, - this.variant.kind === TerminalKind.Identifier ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (this.variant.kind !== TerminalKind.Identifier) + this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ExperimentalPragma.ts b/src/slang-nodes/ExperimentalPragma.ts index d31e14056..5ba3a05f4 100644 --- a/src/slang-nodes/ExperimentalPragma.ts +++ b/src/slang-nodes/ExperimentalPragma.ts @@ -1,30 +1,23 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ExperimentalFeature } from './ExperimentalFeature.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ExperimentalPragma implements SlangNode { +export class ExperimentalPragma extends SlangNode { readonly kind = NonterminalKind.ExperimentalPragma; - comments; - - loc; - feature: ExperimentalFeature; constructor(ast: ast.ExperimentalPragma, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.feature = new ExperimentalFeature(ast.feature, options); - metadata = updateMetadata(metadata, [this.feature]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.feature); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ExponentiationExpression.ts b/src/slang-nodes/ExponentiationExpression.ts index 0a0e7a979..9d8d82448 100644 --- a/src/slang-nodes/ExponentiationExpression.ts +++ b/src/slang-nodes/ExponentiationExpression.ts @@ -4,13 +4,13 @@ import { createBinaryOperationPrinter } from '../slang-printers/create-binary-op import { binaryIndentRulesBuilder } from '../slang-printers/print-binary-operation.js'; import { createHugFunction } from '../slang-utils/create-hug-function.js'; import { createKindCheckFunction } from '../slang-utils/create-kind-check-function.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group } = doc.builders; @@ -36,13 +36,9 @@ const printExponentiationExpression = createBinaryOperationPrinter( binaryIndentRulesBuilder(shouldIndent) // indent as a binary operation with some exceptions ); -export class ExponentiationExpression implements SlangNode { +export class ExponentiationExpression extends SlangNode { readonly kind = NonterminalKind.ExponentiationExpression; - comments; - - loc; - leftOperand: Expression; operator: string; @@ -53,16 +49,13 @@ export class ExponentiationExpression implements SlangNode { ast: ast.ExponentiationExpression, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.leftOperand = new Expression(ast.leftOperand, options); this.operator = ast.operator.unparse(); this.rightOperand = new Expression(ast.rightOperand, options); - metadata = updateMetadata(metadata, [this.leftOperand, this.rightOperand]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.leftOperand, this.rightOperand); this.rightOperand = tryToHug(this.rightOperand); this.leftOperand = tryToHug(this.leftOperand); diff --git a/src/slang-nodes/Expression.ts b/src/slang-nodes/Expression.ts index 25f303709..008c52e44 100644 --- a/src/slang-nodes/Expression.ts +++ b/src/slang-nodes/Expression.ts @@ -3,7 +3,7 @@ import { TerminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { AssignmentExpression } from './AssignmentExpression.js'; import { ConditionalExpression } from './ConditionalExpression.js'; import { OrExpression } from './OrExpression.js'; @@ -36,15 +36,11 @@ import { Identifier } from './Identifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class Expression implements SlangNode { +export class Expression extends SlangNode { readonly kind = NonterminalKind.Expression; - comments; - - loc; - variant: | AssignmentExpression | ConditionalExpression @@ -76,7 +72,7 @@ export class Expression implements SlangNode { | Identifier; constructor(ast: ast.Expression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); if (ast.variant instanceof TerminalNode) { this.variant = new Identifier(ast.variant); @@ -244,13 +240,8 @@ export class Expression implements SlangNode { } } - metadata = updateMetadata( - metadata, - this.variant.kind === TerminalKind.Identifier ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (this.variant.kind !== TerminalKind.Identifier) + this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ExpressionStatement.ts b/src/slang-nodes/ExpressionStatement.ts index ec4a51ab2..bc3e17f25 100644 --- a/src/slang-nodes/ExpressionStatement.ts +++ b/src/slang-nodes/ExpressionStatement.ts @@ -1,30 +1,23 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ExpressionStatement implements SlangNode { +export class ExpressionStatement extends SlangNode { readonly kind = NonterminalKind.ExpressionStatement; - comments; - - loc; - expression: Expression; constructor(ast: ast.ExpressionStatement, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.expression = new Expression(ast.expression, options); - metadata = updateMetadata(metadata, [this.expression]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.expression); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/FallbackFunctionAttribute.ts b/src/slang-nodes/FallbackFunctionAttribute.ts index c5a4acf1d..e346aef99 100644 --- a/src/slang-nodes/FallbackFunctionAttribute.ts +++ b/src/slang-nodes/FallbackFunctionAttribute.ts @@ -1,27 +1,23 @@ import { NonterminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ModifierInvocation } from './ModifierInvocation.js'; import { OverrideSpecifier } from './OverrideSpecifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class FallbackFunctionAttribute implements SlangNode { +export class FallbackFunctionAttribute extends SlangNode { readonly kind = NonterminalKind.FallbackFunctionAttribute; - comments; - - loc; - variant: ModifierInvocation | OverrideSpecifier | string; constructor( ast: ast.FallbackFunctionAttribute, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); if (ast.variant instanceof TerminalNode) { this.variant = ast.variant.unparse(); @@ -43,13 +39,7 @@ export class FallbackFunctionAttribute implements SlangNode { } } - metadata = updateMetadata( - metadata, - typeof this.variant === 'string' ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (typeof this.variant !== 'string') this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/FallbackFunctionAttributes.ts b/src/slang-nodes/FallbackFunctionAttributes.ts index aeb578f81..0f48bfdb6 100644 --- a/src/slang-nodes/FallbackFunctionAttributes.ts +++ b/src/slang-nodes/FallbackFunctionAttributes.ts @@ -1,39 +1,32 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { sortFunctionAttributes } from '../slang-utils/sort-function-attributes.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { FallbackFunctionAttribute } from './FallbackFunctionAttribute.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line } = doc.builders; -export class FallbackFunctionAttributes implements SlangNode { +export class FallbackFunctionAttributes extends SlangNode { readonly kind = NonterminalKind.FallbackFunctionAttributes; - comments; - - loc; - items: FallbackFunctionAttribute[]; constructor( ast: ast.FallbackFunctionAttributes, options: ParserOptions ) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map( (item) => new FallbackFunctionAttribute(item, options) ); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); this.items = this.items.sort(sortFunctionAttributes); } diff --git a/src/slang-nodes/FallbackFunctionDefinition.ts b/src/slang-nodes/FallbackFunctionDefinition.ts index 8ed12dfb6..4504370b5 100644 --- a/src/slang-nodes/FallbackFunctionDefinition.ts +++ b/src/slang-nodes/FallbackFunctionDefinition.ts @@ -1,6 +1,6 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printFunction } from '../slang-printers/print-function.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ParametersDeclaration } from './ParametersDeclaration.js'; import { FallbackFunctionAttributes } from './FallbackFunctionAttributes.js'; import { ReturnsDeclaration } from './ReturnsDeclaration.js'; @@ -9,15 +9,11 @@ import { FunctionBody } from './FunctionBody.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class FallbackFunctionDefinition implements SlangNode { +export class FallbackFunctionDefinition extends SlangNode { readonly kind = NonterminalKind.FallbackFunctionDefinition; - comments; - - loc; - parameters: ParametersDeclaration; attributes: FallbackFunctionAttributes; @@ -30,7 +26,7 @@ export class FallbackFunctionDefinition implements SlangNode { ast: ast.FallbackFunctionDefinition, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.parameters = new ParametersDeclaration(ast.parameters, options); this.attributes = new FallbackFunctionAttributes(ast.attributes, options); @@ -39,15 +35,12 @@ export class FallbackFunctionDefinition implements SlangNode { } this.body = new FunctionBody(ast.body, options); - metadata = updateMetadata(metadata, [ + this.updateMetadata( this.parameters, this.attributes, this.returns, this.body - ]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + ); this.cleanModifierInvocationArguments(); } diff --git a/src/slang-nodes/ForStatement.ts b/src/slang-nodes/ForStatement.ts index 77b3cfa2a..26d3cb9ca 100644 --- a/src/slang-nodes/ForStatement.ts +++ b/src/slang-nodes/ForStatement.ts @@ -1,7 +1,7 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { doc } from 'prettier'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ForStatementInitialization } from './ForStatementInitialization.js'; import { ForStatementCondition } from './ForStatementCondition.js'; import { Expression } from './Expression.js'; @@ -10,17 +10,13 @@ import { Statement } from './Statement.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, indent, line } = doc.builders; -export class ForStatement implements SlangNode { +export class ForStatement extends SlangNode { readonly kind = NonterminalKind.ForStatement; - comments; - - loc; - initialization: ForStatementInitialization; condition: ForStatementCondition; @@ -30,7 +26,7 @@ export class ForStatement implements SlangNode { body: Statement; constructor(ast: ast.ForStatement, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.initialization = new ForStatementInitialization( ast.initialization, @@ -42,15 +38,12 @@ export class ForStatement implements SlangNode { } this.body = new Statement(ast.body, options); - metadata = updateMetadata(metadata, [ + this.updateMetadata( this.initialization, this.condition, this.iterator, this.body - ]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + ); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ForStatementCondition.ts b/src/slang-nodes/ForStatementCondition.ts index ba9cb87f9..4aae16e23 100644 --- a/src/slang-nodes/ForStatementCondition.ts +++ b/src/slang-nodes/ForStatementCondition.ts @@ -1,36 +1,26 @@ import { NonterminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ExpressionStatement } from './ExpressionStatement.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ForStatementCondition implements SlangNode { +export class ForStatementCondition extends SlangNode { readonly kind = NonterminalKind.ForStatementCondition; - comments; - - loc; - variant: ExpressionStatement | string; constructor(ast: ast.ForStatementCondition, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant instanceof TerminalNode ? ast.variant.unparse() : new ExpressionStatement(ast.variant, options); - metadata = updateMetadata( - metadata, - typeof this.variant === 'string' ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (typeof this.variant !== 'string') this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ForStatementInitialization.ts b/src/slang-nodes/ForStatementInitialization.ts index 761c2d654..95a7a879d 100644 --- a/src/slang-nodes/ForStatementInitialization.ts +++ b/src/slang-nodes/ForStatementInitialization.ts @@ -1,5 +1,5 @@ import { NonterminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ExpressionStatement } from './ExpressionStatement.js'; import { VariableDeclarationStatement } from './VariableDeclarationStatement.js'; import { TupleDeconstructionStatement } from './TupleDeconstructionStatement.js'; @@ -7,15 +7,11 @@ import { TupleDeconstructionStatement } from './TupleDeconstructionStatement.js' import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ForStatementInitialization implements SlangNode { +export class ForStatementInitialization extends SlangNode { readonly kind = NonterminalKind.ForStatementInitialization; - comments; - - loc; - variant: | ExpressionStatement | VariableDeclarationStatement @@ -26,7 +22,7 @@ export class ForStatementInitialization implements SlangNode { ast: ast.ForStatementInitialization, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); if (ast.variant instanceof TerminalNode) { this.variant = ast.variant.unparse(); @@ -55,13 +51,7 @@ export class ForStatementInitialization implements SlangNode { } } - metadata = updateMetadata( - metadata, - typeof this.variant === 'string' ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (typeof this.variant !== 'string') this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/FunctionAttribute.ts b/src/slang-nodes/FunctionAttribute.ts index 5f54367fb..55769bb44 100644 --- a/src/slang-nodes/FunctionAttribute.ts +++ b/src/slang-nodes/FunctionAttribute.ts @@ -1,24 +1,20 @@ import { NonterminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ModifierInvocation } from './ModifierInvocation.js'; import { OverrideSpecifier } from './OverrideSpecifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class FunctionAttribute implements SlangNode { +export class FunctionAttribute extends SlangNode { readonly kind = NonterminalKind.FunctionAttribute; - comments; - - loc; - variant: ModifierInvocation | OverrideSpecifier | string; constructor(ast: ast.FunctionAttribute, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); if (ast.variant instanceof TerminalNode) { this.variant = ast.variant.unparse(); @@ -40,13 +36,7 @@ export class FunctionAttribute implements SlangNode { } } - metadata = updateMetadata( - metadata, - typeof this.variant === 'string' ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (typeof this.variant !== 'string') this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/FunctionAttributes.ts b/src/slang-nodes/FunctionAttributes.ts index 0cef35a7d..6ecac12b4 100644 --- a/src/slang-nodes/FunctionAttributes.ts +++ b/src/slang-nodes/FunctionAttributes.ts @@ -1,34 +1,27 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { sortFunctionAttributes } from '../slang-utils/sort-function-attributes.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { FunctionAttribute } from './FunctionAttribute.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line } = doc.builders; -export class FunctionAttributes implements SlangNode { +export class FunctionAttributes extends SlangNode { readonly kind = NonterminalKind.FunctionAttributes; - comments; - - loc; - items: FunctionAttribute[]; constructor(ast: ast.FunctionAttributes, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new FunctionAttribute(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); this.items = this.items.sort(sortFunctionAttributes); } diff --git a/src/slang-nodes/FunctionBody.ts b/src/slang-nodes/FunctionBody.ts index 27ecf8b42..9ab675215 100644 --- a/src/slang-nodes/FunctionBody.ts +++ b/src/slang-nodes/FunctionBody.ts @@ -1,36 +1,26 @@ import { NonterminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Block } from './Block.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class FunctionBody implements SlangNode { +export class FunctionBody extends SlangNode { readonly kind = NonterminalKind.FunctionBody; - comments; - - loc; - variant: Block | string; constructor(ast: ast.FunctionBody, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant instanceof TerminalNode ? ast.variant.unparse() : new Block(ast.variant, options); - metadata = updateMetadata( - metadata, - typeof this.variant === 'string' ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (typeof this.variant !== 'string') this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/FunctionCallExpression.ts b/src/slang-nodes/FunctionCallExpression.ts index 029c6561e..7facaa062 100644 --- a/src/slang-nodes/FunctionCallExpression.ts +++ b/src/slang-nodes/FunctionCallExpression.ts @@ -1,24 +1,20 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { isLabel } from '../slang-utils/is-label.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import { ArgumentsDeclaration } from './ArgumentsDeclaration.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, indentIfBreak, label } = doc.builders; -export class FunctionCallExpression implements SlangNode { +export class FunctionCallExpression extends SlangNode { readonly kind = NonterminalKind.FunctionCallExpression; - comments; - - loc; - operand: Expression; arguments: ArgumentsDeclaration; @@ -27,15 +23,12 @@ export class FunctionCallExpression implements SlangNode { ast: ast.FunctionCallExpression, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.operand = new Expression(ast.operand, options); this.arguments = new ArgumentsDeclaration(ast.arguments, options); - metadata = updateMetadata(metadata, [this.operand, this.arguments]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.operand, this.arguments); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/FunctionDefinition.ts b/src/slang-nodes/FunctionDefinition.ts index 95eaefd89..077e79d82 100644 --- a/src/slang-nodes/FunctionDefinition.ts +++ b/src/slang-nodes/FunctionDefinition.ts @@ -1,7 +1,7 @@ import { satisfies } from 'semver'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printFunction } from '../slang-printers/print-function.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { FunctionName } from './FunctionName.js'; import { ParametersDeclaration } from './ParametersDeclaration.js'; import { FunctionAttributes } from './FunctionAttributes.js'; @@ -11,15 +11,11 @@ import { FunctionBody } from './FunctionBody.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class FunctionDefinition implements SlangNode { +export class FunctionDefinition extends SlangNode { readonly kind = NonterminalKind.FunctionDefinition; - comments; - - loc; - name: FunctionName; parameters: ParametersDeclaration; @@ -31,7 +27,7 @@ export class FunctionDefinition implements SlangNode { body: FunctionBody; constructor(ast: ast.FunctionDefinition, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.name = new FunctionName(ast.name); this.parameters = new ParametersDeclaration(ast.parameters, options); @@ -41,16 +37,13 @@ export class FunctionDefinition implements SlangNode { } this.body = new FunctionBody(ast.body, options); - metadata = updateMetadata(metadata, [ + this.updateMetadata( this.name, this.parameters, this.attributes, this.returns, this.body - ]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + ); // Older versions of Solidity defined a constructor as a function having // the same name as the contract. diff --git a/src/slang-nodes/FunctionName.ts b/src/slang-nodes/FunctionName.ts index 85e7fdf4c..aadb33458 100644 --- a/src/slang-nodes/FunctionName.ts +++ b/src/slang-nodes/FunctionName.ts @@ -1,27 +1,20 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Identifier } from './Identifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class FunctionName implements SlangNode { +export class FunctionName extends SlangNode { readonly kind = NonterminalKind.FunctionName; - comments; - - loc; - variant: Identifier; constructor(ast: ast.FunctionName) { - const metadata = getNodeMetadata(ast); + super(ast); this.variant = new Identifier(ast.variant); - - this.comments = metadata.comments; - this.loc = metadata.loc; } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/FunctionType.ts b/src/slang-nodes/FunctionType.ts index 6705f5dc9..5480767e0 100644 --- a/src/slang-nodes/FunctionType.ts +++ b/src/slang-nodes/FunctionType.ts @@ -1,6 +1,6 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printFunction } from '../slang-printers/print-function.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ParametersDeclaration } from './ParametersDeclaration.js'; import { FunctionTypeAttributes } from './FunctionTypeAttributes.js'; import { ReturnsDeclaration } from './ReturnsDeclaration.js'; @@ -8,15 +8,11 @@ import { ReturnsDeclaration } from './ReturnsDeclaration.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class FunctionType implements SlangNode { +export class FunctionType extends SlangNode { readonly kind = NonterminalKind.FunctionType; - comments; - - loc; - parameters: ParametersDeclaration; attributes: FunctionTypeAttributes; @@ -24,7 +20,7 @@ export class FunctionType implements SlangNode { returns?: ReturnsDeclaration; constructor(ast: ast.FunctionType, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.parameters = new ParametersDeclaration(ast.parameters, options); this.attributes = new FunctionTypeAttributes(ast.attributes); @@ -32,14 +28,7 @@ export class FunctionType implements SlangNode { this.returns = new ReturnsDeclaration(ast.returns, options); } - metadata = updateMetadata(metadata, [ - this.parameters, - this.attributes, - this.returns - ]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.parameters, this.attributes, this.returns); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/FunctionTypeAttribute.ts b/src/slang-nodes/FunctionTypeAttribute.ts index 0dbd804d4..a0c4efb8f 100644 --- a/src/slang-nodes/FunctionTypeAttribute.ts +++ b/src/slang-nodes/FunctionTypeAttribute.ts @@ -1,26 +1,18 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { Doc } from 'prettier'; -import type { SlangNode } from '../types.d.ts'; -export class FunctionTypeAttribute implements SlangNode { +export class FunctionTypeAttribute extends SlangNode { readonly kind = NonterminalKind.FunctionTypeAttribute; - comments; - - loc; - variant: string; constructor(ast: ast.FunctionTypeAttribute) { - const metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant.unparse(); - - this.comments = metadata.comments; - this.loc = metadata.loc; } print(): Doc { diff --git a/src/slang-nodes/FunctionTypeAttributes.ts b/src/slang-nodes/FunctionTypeAttributes.ts index 1d204e68b..06a17acfe 100644 --- a/src/slang-nodes/FunctionTypeAttributes.ts +++ b/src/slang-nodes/FunctionTypeAttributes.ts @@ -1,33 +1,26 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { sortFunctionAttributes } from '../slang-utils/sort-function-attributes.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { FunctionTypeAttribute } from './FunctionTypeAttribute.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line } = doc.builders; -export class FunctionTypeAttributes implements SlangNode { +export class FunctionTypeAttributes extends SlangNode { readonly kind = NonterminalKind.FunctionTypeAttributes; - comments; - - loc; - items: FunctionTypeAttribute[]; constructor(ast: ast.FunctionTypeAttributes) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new FunctionTypeAttribute(item)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); this.items = this.items.sort(sortFunctionAttributes); } diff --git a/src/slang-nodes/HexNumberExpression.ts b/src/slang-nodes/HexNumberExpression.ts index b76752dc0..1308f9c5f 100644 --- a/src/slang-nodes/HexNumberExpression.ts +++ b/src/slang-nodes/HexNumberExpression.ts @@ -1,35 +1,28 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { joinExisting } from '../slang-utils/join-existing.js'; +import { SlangNode } from './SlangNode.js'; import { NumberUnit } from './NumberUnit.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class HexNumberExpression implements SlangNode { +export class HexNumberExpression extends SlangNode { readonly kind = NonterminalKind.HexNumberExpression; - comments; - - loc; - literal: string; unit?: NumberUnit; constructor(ast: ast.HexNumberExpression) { - let metadata = getNodeMetadata(ast); + super(ast); this.literal = ast.literal.unparse(); if (ast.unit) { this.unit = new NumberUnit(ast.unit); } - metadata = updateMetadata(metadata, [this.unit]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.unit); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/HexStringLiteral.ts b/src/slang-nodes/HexStringLiteral.ts index 81e4d64ec..d2f0b767c 100644 --- a/src/slang-nodes/HexStringLiteral.ts +++ b/src/slang-nodes/HexStringLiteral.ts @@ -1,29 +1,21 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printString } from '../slang-printers/print-string.js'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { SlangNode } from '../types.d.ts'; -export class HexStringLiteral implements SlangNode { +export class HexStringLiteral extends SlangNode { readonly kind = NonterminalKind.HexStringLiteral; - comments; - - loc; - variant: string; constructor(ast: ast.HexStringLiteral, options: ParserOptions) { - const metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant.unparse(); - this.comments = metadata.comments; - this.loc = metadata.loc; - this.variant = `hex${printString(this.variant.slice(4, -1), options)}`; } diff --git a/src/slang-nodes/HexStringLiterals.ts b/src/slang-nodes/HexStringLiterals.ts index ab13d777d..1b6fefed9 100644 --- a/src/slang-nodes/HexStringLiterals.ts +++ b/src/slang-nodes/HexStringLiterals.ts @@ -1,33 +1,26 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { HexStringLiteral } from './HexStringLiteral.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { join, hardline } = doc.builders; -export class HexStringLiterals implements SlangNode { +export class HexStringLiterals extends SlangNode { readonly kind = NonterminalKind.HexStringLiterals; - comments; - - loc; - items: HexStringLiteral[]; constructor(ast: ast.HexStringLiterals, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new HexStringLiteral(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/Identifier.ts b/src/slang-nodes/Identifier.ts index 1e0f8d837..4adeef1b0 100644 --- a/src/slang-nodes/Identifier.ts +++ b/src/slang-nodes/Identifier.ts @@ -1,26 +1,17 @@ import { TerminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type { Doc } from 'prettier'; -import type { Location, SlangNode } from '../types.d.ts'; -import type { Comment } from './types.d.ts'; -export class Identifier implements SlangNode { +export class Identifier extends SlangNode { readonly kind = TerminalKind.Identifier; - comments: Comment[]; - - loc: Location; - value: string; constructor(ast: TerminalNode) { - const metadata = getNodeMetadata(ast); + super(ast); this.value = ast.unparse(); - - this.comments = metadata.comments; - this.loc = metadata.loc; } print(): Doc { diff --git a/src/slang-nodes/IdentifierPath.ts b/src/slang-nodes/IdentifierPath.ts index 8bdbeb471..5406c7909 100644 --- a/src/slang-nodes/IdentifierPath.ts +++ b/src/slang-nodes/IdentifierPath.ts @@ -1,30 +1,23 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { doc } from 'prettier'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Identifier } from './Identifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { join } = doc.builders; -export class IdentifierPath implements SlangNode { +export class IdentifierPath extends SlangNode { readonly kind = NonterminalKind.IdentifierPath; - comments; - - loc; - items: Identifier[]; constructor(ast: ast.IdentifierPath) { - const metadata = getNodeMetadata(ast); + super(ast); this.items = ast.items.map((item) => new Identifier(item)); - - this.comments = metadata.comments; - this.loc = metadata.loc; } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/IfStatement.ts b/src/slang-nodes/IfStatement.ts index be3af109c..ddbf54446 100644 --- a/src/slang-nodes/IfStatement.ts +++ b/src/slang-nodes/IfStatement.ts @@ -1,8 +1,8 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedItem } from '../slang-printers/print-separated-item.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { isBlockComment } from '../slang-utils/is-comment.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import { Statement } from './Statement.js'; import { ElseBranch } from './ElseBranch.js'; @@ -10,17 +10,13 @@ import { ElseBranch } from './ElseBranch.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, hardline, indent, line } = doc.builders; -export class IfStatement implements SlangNode { +export class IfStatement extends SlangNode { readonly kind = NonterminalKind.IfStatement; - comments; - - loc; - condition: Expression; body: Statement; @@ -28,7 +24,7 @@ export class IfStatement implements SlangNode { elseBranch?: ElseBranch; constructor(ast: ast.IfStatement, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.condition = new Expression(ast.condition, options); this.body = new Statement(ast.body, options); @@ -36,14 +32,7 @@ export class IfStatement implements SlangNode { this.elseBranch = new ElseBranch(ast.elseBranch, options); } - metadata = updateMetadata(metadata, [ - this.condition, - this.body, - this.elseBranch - ]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.condition, this.body, this.elseBranch); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ImportAlias.ts b/src/slang-nodes/ImportAlias.ts index 0116cc428..0287674d5 100644 --- a/src/slang-nodes/ImportAlias.ts +++ b/src/slang-nodes/ImportAlias.ts @@ -1,27 +1,20 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Identifier } from './Identifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ImportAlias implements SlangNode { +export class ImportAlias extends SlangNode { readonly kind = NonterminalKind.ImportAlias; - comments; - - loc; - identifier: Identifier; constructor(ast: ast.ImportAlias) { - const metadata = getNodeMetadata(ast); + super(ast); this.identifier = new Identifier(ast.identifier); - - this.comments = metadata.comments; - this.loc = metadata.loc; } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ImportClause.ts b/src/slang-nodes/ImportClause.ts index 5077a50fb..945229810 100644 --- a/src/slang-nodes/ImportClause.ts +++ b/src/slang-nodes/ImportClause.ts @@ -1,5 +1,5 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { PathImport } from './PathImport.js'; import { NamedImport } from './NamedImport.js'; import { ImportDeconstruction } from './ImportDeconstruction.js'; @@ -7,19 +7,15 @@ import { ImportDeconstruction } from './ImportDeconstruction.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ImportClause implements SlangNode { +export class ImportClause extends SlangNode { readonly kind = NonterminalKind.ImportClause; - comments; - - loc; - variant: PathImport | NamedImport | ImportDeconstruction; constructor(ast: ast.ImportClause, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); switch (ast.variant.cst.kind) { case NonterminalKind.PathImport: @@ -38,10 +34,7 @@ export class ImportClause implements SlangNode { throw new Error(`Unexpected variant: ${ast.variant.cst.kind}`); } - metadata = updateMetadata(metadata, [this.variant]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ImportDeconstruction.ts b/src/slang-nodes/ImportDeconstruction.ts index df0daa2f5..c8a6ff140 100644 --- a/src/slang-nodes/ImportDeconstruction.ts +++ b/src/slang-nodes/ImportDeconstruction.ts @@ -1,34 +1,27 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ImportDeconstructionSymbols } from './ImportDeconstructionSymbols.js'; import { StringLiteral } from './StringLiteral.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ImportDeconstruction implements SlangNode { +export class ImportDeconstruction extends SlangNode { readonly kind = NonterminalKind.ImportDeconstruction; - comments; - - loc; - symbols: ImportDeconstructionSymbols; path: StringLiteral; constructor(ast: ast.ImportDeconstruction, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.symbols = new ImportDeconstructionSymbols(ast.symbols); this.path = new StringLiteral(ast.path, options); - metadata = updateMetadata(metadata, [this.symbols, this.path]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.symbols, this.path); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ImportDeconstructionSymbol.ts b/src/slang-nodes/ImportDeconstructionSymbol.ts index 8b005464a..250a28c1d 100644 --- a/src/slang-nodes/ImportDeconstructionSymbol.ts +++ b/src/slang-nodes/ImportDeconstructionSymbol.ts @@ -1,35 +1,28 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Identifier } from './Identifier.js'; import { ImportAlias } from './ImportAlias.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ImportDeconstructionSymbol implements SlangNode { +export class ImportDeconstructionSymbol extends SlangNode { readonly kind = NonterminalKind.ImportDeconstructionSymbol; - comments; - - loc; - name: Identifier; alias?: ImportAlias; constructor(ast: ast.ImportDeconstructionSymbol) { - let metadata = getNodeMetadata(ast); + super(ast); this.name = new Identifier(ast.name); if (ast.alias) { this.alias = new ImportAlias(ast.alias); } - metadata = updateMetadata(metadata, [this.alias]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.alias); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ImportDeconstructionSymbols.ts b/src/slang-nodes/ImportDeconstructionSymbols.ts index 10ba7adea..a5ebf0f7b 100644 --- a/src/slang-nodes/ImportDeconstructionSymbols.ts +++ b/src/slang-nodes/ImportDeconstructionSymbols.ts @@ -2,34 +2,27 @@ import { doc } from 'prettier'; import { satisfies } from 'semver'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ImportDeconstructionSymbol } from './ImportDeconstructionSymbol.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line, softline } = doc.builders; -export class ImportDeconstructionSymbols implements SlangNode { +export class ImportDeconstructionSymbols extends SlangNode { readonly kind = NonterminalKind.ImportDeconstructionSymbols; - comments; - - loc; - items: ImportDeconstructionSymbol[]; constructor(ast: ast.ImportDeconstructionSymbols) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new ImportDeconstructionSymbol(item)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print( diff --git a/src/slang-nodes/ImportDirective.ts b/src/slang-nodes/ImportDirective.ts index 470df6c26..1ae6051b3 100644 --- a/src/slang-nodes/ImportDirective.ts +++ b/src/slang-nodes/ImportDirective.ts @@ -1,30 +1,23 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ImportClause } from './ImportClause.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ImportDirective implements SlangNode { +export class ImportDirective extends SlangNode { readonly kind = NonterminalKind.ImportDirective; - comments; - - loc; - clause: ImportClause; constructor(ast: ast.ImportDirective, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.clause = new ImportClause(ast.clause, options); - metadata = updateMetadata(metadata, [this.clause]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.clause); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/IndexAccessEnd.ts b/src/slang-nodes/IndexAccessEnd.ts index f8f698378..a90194910 100644 --- a/src/slang-nodes/IndexAccessEnd.ts +++ b/src/slang-nodes/IndexAccessEnd.ts @@ -1,32 +1,25 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class IndexAccessEnd implements SlangNode { +export class IndexAccessEnd extends SlangNode { readonly kind = NonterminalKind.IndexAccessEnd; - comments; - - loc; - end?: Expression; constructor(ast: ast.IndexAccessEnd, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); if (ast.end) { this.end = new Expression(ast.end, options); } - metadata = updateMetadata(metadata, [this.end]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.end); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/IndexAccessExpression.ts b/src/slang-nodes/IndexAccessExpression.ts index 73077fe39..4efc5a4dc 100644 --- a/src/slang-nodes/IndexAccessExpression.ts +++ b/src/slang-nodes/IndexAccessExpression.ts @@ -2,24 +2,20 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedItem } from '../slang-printers/print-separated-item.js'; import { isLabel } from '../slang-utils/is-label.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import { IndexAccessEnd } from './IndexAccessEnd.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, indentIfBreak, label } = doc.builders; -export class IndexAccessExpression implements SlangNode { +export class IndexAccessExpression extends SlangNode { readonly kind = NonterminalKind.IndexAccessExpression; - comments; - - loc; - operand: Expression; start?: Expression; @@ -27,7 +23,7 @@ export class IndexAccessExpression implements SlangNode { end?: IndexAccessEnd; constructor(ast: ast.IndexAccessExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.operand = new Expression(ast.operand, options); if (ast.start) { @@ -37,10 +33,7 @@ export class IndexAccessExpression implements SlangNode { this.end = new IndexAccessEnd(ast.end, options); } - metadata = updateMetadata(metadata, [this.operand, this.start, this.end]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.operand, this.start, this.end); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/InequalityExpression.ts b/src/slang-nodes/InequalityExpression.ts index c80930265..5af48cc66 100644 --- a/src/slang-nodes/InequalityExpression.ts +++ b/src/slang-nodes/InequalityExpression.ts @@ -1,13 +1,13 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { createKindCheckFunction } from '../slang-utils/create-kind-check-function.js'; import { printBinaryOperation } from '../slang-printers/print-binary-operation.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const printComparisonExpression = printBinaryOperation( createKindCheckFunction([ @@ -17,13 +17,9 @@ const printComparisonExpression = printBinaryOperation( ]) ); -export class InequalityExpression implements SlangNode { +export class InequalityExpression extends SlangNode { readonly kind = NonterminalKind.InequalityExpression; - comments; - - loc; - leftOperand: Expression; operator: string; @@ -31,16 +27,13 @@ export class InequalityExpression implements SlangNode { rightOperand: Expression; constructor(ast: ast.InequalityExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.leftOperand = new Expression(ast.leftOperand, options); this.operator = ast.operator.unparse(); this.rightOperand = new Expression(ast.rightOperand, options); - metadata = updateMetadata(metadata, [this.leftOperand, this.rightOperand]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.leftOperand, this.rightOperand); } print( diff --git a/src/slang-nodes/InheritanceSpecifier.ts b/src/slang-nodes/InheritanceSpecifier.ts index f25834495..48bf09f8d 100644 --- a/src/slang-nodes/InheritanceSpecifier.ts +++ b/src/slang-nodes/InheritanceSpecifier.ts @@ -1,30 +1,23 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { InheritanceTypes } from './InheritanceTypes.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class InheritanceSpecifier implements SlangNode { +export class InheritanceSpecifier extends SlangNode { readonly kind = NonterminalKind.InheritanceSpecifier; - comments; - - loc; - types: InheritanceTypes; constructor(ast: ast.InheritanceSpecifier, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.types = new InheritanceTypes(ast.types, options); - metadata = updateMetadata(metadata, [this.types]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.types); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/InheritanceType.ts b/src/slang-nodes/InheritanceType.ts index b63fefd8e..e66839012 100644 --- a/src/slang-nodes/InheritanceType.ts +++ b/src/slang-nodes/InheritanceType.ts @@ -1,36 +1,29 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { IdentifierPath } from './IdentifierPath.js'; import { ArgumentsDeclaration } from './ArgumentsDeclaration.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class InheritanceType implements SlangNode { +export class InheritanceType extends SlangNode { readonly kind = NonterminalKind.InheritanceType; - comments; - - loc; - typeName: IdentifierPath; arguments?: ArgumentsDeclaration; constructor(ast: ast.InheritanceType, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.typeName = new IdentifierPath(ast.typeName); if (ast.arguments) { this.arguments = new ArgumentsDeclaration(ast.arguments, options); } - metadata = updateMetadata(metadata, [this.typeName, this.arguments]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.typeName, this.arguments); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/InheritanceTypes.ts b/src/slang-nodes/InheritanceTypes.ts index 55b7ad671..e9b04e66d 100644 --- a/src/slang-nodes/InheritanceTypes.ts +++ b/src/slang-nodes/InheritanceTypes.ts @@ -1,34 +1,27 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { InheritanceType } from './InheritanceType.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line } = doc.builders; -export class InheritanceTypes implements SlangNode { +export class InheritanceTypes extends SlangNode { readonly kind = NonterminalKind.InheritanceTypes; - comments; - - loc; - items: InheritanceType[]; constructor(ast: ast.InheritanceTypes, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new InheritanceType(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/InterfaceDefinition.ts b/src/slang-nodes/InterfaceDefinition.ts index 12b9ebf22..547668125 100644 --- a/src/slang-nodes/InterfaceDefinition.ts +++ b/src/slang-nodes/InterfaceDefinition.ts @@ -1,6 +1,6 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Identifier } from './Identifier.js'; import { InheritanceSpecifier } from './InheritanceSpecifier.js'; import { InterfaceMembers } from './InterfaceMembers.js'; @@ -8,17 +8,13 @@ import { InterfaceMembers } from './InterfaceMembers.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, line } = doc.builders; -export class InterfaceDefinition implements SlangNode { +export class InterfaceDefinition extends SlangNode { readonly kind = NonterminalKind.InterfaceDefinition; - comments; - - loc; - name: Identifier; inheritance?: InheritanceSpecifier; @@ -26,7 +22,7 @@ export class InterfaceDefinition implements SlangNode { members: InterfaceMembers; constructor(ast: ast.InterfaceDefinition, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.name = new Identifier(ast.name); if (ast.inheritance) { @@ -34,10 +30,7 @@ export class InterfaceDefinition implements SlangNode { } this.members = new InterfaceMembers(ast.members, options); - metadata = updateMetadata(metadata, [this.inheritance, this.members]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.inheritance, this.members); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/InterfaceMembers.ts b/src/slang-nodes/InterfaceMembers.ts index 31e949682..6ee398a26 100644 --- a/src/slang-nodes/InterfaceMembers.ts +++ b/src/slang-nodes/InterfaceMembers.ts @@ -2,34 +2,27 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedItem } from '../slang-printers/print-separated-item.js'; import { printPreservingEmptyLines } from '../slang-printers/print-preserving-empty-lines.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ContractMember } from './ContractMember.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { hardline } = doc.builders; -export class InterfaceMembers implements SlangNode { +export class InterfaceMembers extends SlangNode { readonly kind = NonterminalKind.InterfaceMembers; - comments; - - loc; - items: ContractMember[]; constructor(ast: ast.InterfaceMembers, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new ContractMember(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print( diff --git a/src/slang-nodes/LibraryDefinition.ts b/src/slang-nodes/LibraryDefinition.ts index 24267a5e8..01fff5014 100644 --- a/src/slang-nodes/LibraryDefinition.ts +++ b/src/slang-nodes/LibraryDefinition.ts @@ -1,37 +1,30 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Identifier } from './Identifier.js'; import { LibraryMembers } from './LibraryMembers.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, line } = doc.builders; -export class LibraryDefinition implements SlangNode { +export class LibraryDefinition extends SlangNode { readonly kind = NonterminalKind.LibraryDefinition; - comments; - - loc; - name: Identifier; members: LibraryMembers; constructor(ast: ast.LibraryDefinition, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.name = new Identifier(ast.name); this.members = new LibraryMembers(ast.members, options); - metadata = updateMetadata(metadata, [this.members]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.members); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/LibraryMembers.ts b/src/slang-nodes/LibraryMembers.ts index c17ca6f02..92ccfd0ed 100644 --- a/src/slang-nodes/LibraryMembers.ts +++ b/src/slang-nodes/LibraryMembers.ts @@ -2,34 +2,27 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedItem } from '../slang-printers/print-separated-item.js'; import { printPreservingEmptyLines } from '../slang-printers/print-preserving-empty-lines.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ContractMember } from './ContractMember.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { hardline } = doc.builders; -export class LibraryMembers implements SlangNode { +export class LibraryMembers extends SlangNode { readonly kind = NonterminalKind.LibraryMembers; - comments; - - loc; - items: ContractMember[]; constructor(ast: ast.LibraryMembers, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new ContractMember(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print( diff --git a/src/slang-nodes/MappingKey.ts b/src/slang-nodes/MappingKey.ts index a41e724fe..6b35477d2 100644 --- a/src/slang-nodes/MappingKey.ts +++ b/src/slang-nodes/MappingKey.ts @@ -1,36 +1,29 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { joinExisting } from '../slang-utils/join-existing.js'; +import { SlangNode } from './SlangNode.js'; import { MappingKeyType } from './MappingKeyType.js'; import { Identifier } from './Identifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class MappingKey implements SlangNode { +export class MappingKey extends SlangNode { readonly kind = NonterminalKind.MappingKey; - comments; - - loc; - keyType: MappingKeyType; name?: Identifier; constructor(ast: ast.MappingKey) { - let metadata = getNodeMetadata(ast); + super(ast); this.keyType = new MappingKeyType(ast.keyType); if (ast.name) { this.name = new Identifier(ast.name); } - metadata = updateMetadata(metadata, [this.keyType]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.keyType); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/MappingKeyType.ts b/src/slang-nodes/MappingKeyType.ts index 16a670bc4..c2b25067e 100644 --- a/src/slang-nodes/MappingKeyType.ts +++ b/src/slang-nodes/MappingKeyType.ts @@ -1,23 +1,19 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ElementaryType } from './ElementaryType.js'; import { IdentifierPath } from './IdentifierPath.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class MappingKeyType implements SlangNode { +export class MappingKeyType extends SlangNode { readonly kind = NonterminalKind.MappingKeyType; - comments; - - loc; - variant: ElementaryType | IdentifierPath; constructor(ast: ast.MappingKeyType) { - let metadata = getNodeMetadata(ast); + super(ast); switch (ast.variant.cst.kind) { case NonterminalKind.ElementaryType: @@ -30,10 +26,7 @@ export class MappingKeyType implements SlangNode { throw new Error(`Unexpected variant: ${ast.variant.cst.kind}`); } - metadata = updateMetadata(metadata, [this.variant]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/MappingType.ts b/src/slang-nodes/MappingType.ts index 02cd805e2..3a95e54f0 100644 --- a/src/slang-nodes/MappingType.ts +++ b/src/slang-nodes/MappingType.ts @@ -1,34 +1,27 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { MappingKey } from './MappingKey.js'; import { MappingValue } from './MappingValue.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class MappingType implements SlangNode { +export class MappingType extends SlangNode { readonly kind = NonterminalKind.MappingType; - comments; - - loc; - keyType: MappingKey; valueType: MappingValue; constructor(ast: ast.MappingType, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.keyType = new MappingKey(ast.keyType); this.valueType = new MappingValue(ast.valueType, options); - metadata = updateMetadata(metadata, [this.keyType, this.valueType]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.keyType, this.valueType); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/MappingValue.ts b/src/slang-nodes/MappingValue.ts index 7cdad05bd..5b266d5d5 100644 --- a/src/slang-nodes/MappingValue.ts +++ b/src/slang-nodes/MappingValue.ts @@ -1,37 +1,30 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { joinExisting } from '../slang-utils/join-existing.js'; +import { SlangNode } from './SlangNode.js'; import { TypeName } from './TypeName.js'; import { Identifier } from './Identifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class MappingValue implements SlangNode { +export class MappingValue extends SlangNode { readonly kind = NonterminalKind.MappingValue; - comments; - - loc; - typeName: TypeName; name?: Identifier; constructor(ast: ast.MappingValue, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.typeName = new TypeName(ast.typeName, options); if (ast.name) { this.name = new Identifier(ast.name); } - metadata = updateMetadata(metadata, [this.typeName]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.typeName); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/MemberAccessExpression.ts b/src/slang-nodes/MemberAccessExpression.ts index b55919b6c..f71e1782c 100644 --- a/src/slang-nodes/MemberAccessExpression.ts +++ b/src/slang-nodes/MemberAccessExpression.ts @@ -2,14 +2,14 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { isLabel } from '../slang-utils/is-label.js'; import { createKindCheckFunction } from '../slang-utils/create-kind-check-function.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import { Identifier } from './Identifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode, StrictAstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, indent, label, softline } = doc.builders; @@ -111,13 +111,9 @@ function processChain(chain: Doc[]): Doc { ]); } -export class MemberAccessExpression implements SlangNode { +export class MemberAccessExpression extends SlangNode { readonly kind = NonterminalKind.MemberAccessExpression; - comments; - - loc; - operand: Expression; member: Identifier; @@ -126,15 +122,12 @@ export class MemberAccessExpression implements SlangNode { ast: ast.MemberAccessExpression, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.operand = new Expression(ast.operand, options); this.member = new Identifier(ast.member); - metadata = updateMetadata(metadata, [this.operand]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.operand); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ModifierAttribute.ts b/src/slang-nodes/ModifierAttribute.ts index 4801a4e90..e49c3e2e4 100644 --- a/src/slang-nodes/ModifierAttribute.ts +++ b/src/slang-nodes/ModifierAttribute.ts @@ -1,35 +1,25 @@ import { NonterminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { OverrideSpecifier } from './OverrideSpecifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ModifierAttribute implements SlangNode { +export class ModifierAttribute extends SlangNode { readonly kind = NonterminalKind.ModifierAttribute; - comments; - - loc; - variant: OverrideSpecifier | string; constructor(ast: ast.ModifierAttribute) { - let metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant instanceof TerminalNode ? ast.variant.unparse() : new OverrideSpecifier(ast.variant); - metadata = updateMetadata( - metadata, - typeof this.variant === 'string' ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (typeof this.variant !== 'string') this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ModifierAttributes.ts b/src/slang-nodes/ModifierAttributes.ts index f30b9d739..6340fdb4d 100644 --- a/src/slang-nodes/ModifierAttributes.ts +++ b/src/slang-nodes/ModifierAttributes.ts @@ -1,33 +1,26 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { sortFunctionAttributes } from '../slang-utils/sort-function-attributes.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ModifierAttribute } from './ModifierAttribute.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line } = doc.builders; -export class ModifierAttributes implements SlangNode { +export class ModifierAttributes extends SlangNode { readonly kind = NonterminalKind.ModifierAttributes; - comments; - - loc; - items: ModifierAttribute[]; constructor(ast: ast.ModifierAttributes) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new ModifierAttribute(item)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); this.items = this.items.sort(sortFunctionAttributes); } diff --git a/src/slang-nodes/ModifierDefinition.ts b/src/slang-nodes/ModifierDefinition.ts index fbbde68d1..dc290a8eb 100644 --- a/src/slang-nodes/ModifierDefinition.ts +++ b/src/slang-nodes/ModifierDefinition.ts @@ -1,6 +1,6 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printFunction } from '../slang-printers/print-function.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Identifier } from './Identifier.js'; import { ParametersDeclaration } from './ParametersDeclaration.js'; import { Parameters } from './Parameters.js'; @@ -10,15 +10,11 @@ import { FunctionBody } from './FunctionBody.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ModifierDefinition implements SlangNode { +export class ModifierDefinition extends SlangNode { readonly kind = NonterminalKind.ModifierDefinition; - comments; - - loc; - name: Identifier; parameters?: ParametersDeclaration; @@ -28,7 +24,7 @@ export class ModifierDefinition implements SlangNode { body: FunctionBody; constructor(ast: ast.ModifierDefinition, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.name = new Identifier(ast.name); if (ast.parameters) { @@ -37,14 +33,7 @@ export class ModifierDefinition implements SlangNode { this.attributes = new ModifierAttributes(ast.attributes); this.body = new FunctionBody(ast.body, options); - metadata = updateMetadata(metadata, [ - this.parameters, - this.attributes, - this.body - ]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.parameters, this.attributes, this.body); if (!this.parameters) { const parametersOffset = diff --git a/src/slang-nodes/ModifierInvocation.ts b/src/slang-nodes/ModifierInvocation.ts index 6e5546041..b5404623b 100644 --- a/src/slang-nodes/ModifierInvocation.ts +++ b/src/slang-nodes/ModifierInvocation.ts @@ -1,36 +1,29 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { IdentifierPath } from './IdentifierPath.js'; import { ArgumentsDeclaration } from './ArgumentsDeclaration.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ModifierInvocation implements SlangNode { +export class ModifierInvocation extends SlangNode { readonly kind = NonterminalKind.ModifierInvocation; - comments; - - loc; - name: IdentifierPath; arguments?: ArgumentsDeclaration; constructor(ast: ast.ModifierInvocation, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.name = new IdentifierPath(ast.name); if (ast.arguments) { this.arguments = new ArgumentsDeclaration(ast.arguments, options); } - metadata = updateMetadata(metadata, [this.name, this.arguments]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.name, this.arguments); } cleanModifierInvocationArguments(): void { diff --git a/src/slang-nodes/MultiLineComment.ts b/src/slang-nodes/MultiLineComment.ts index 40ec753f9..307d89f7f 100644 --- a/src/slang-nodes/MultiLineComment.ts +++ b/src/slang-nodes/MultiLineComment.ts @@ -1,42 +1,22 @@ import { TerminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; import { doc } from 'prettier'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { CommentNode } from './CommentNode.js'; import { isIndentableBlockComment } from '../slang-utils/is-indentable-block-comment.js'; import { printIndentableBlockComment } from '../slang-printers/print-indentable-block-comment.js'; import type { Doc } from 'prettier'; -import type { BaseComment, Location, SlangNode } from '../types.d.ts'; -import type { StrictAstNode } from './types.d.ts'; const { join, literalline } = doc.builders; -export class MultiLineComment implements SlangNode, BaseComment { +export class MultiLineComment extends CommentNode { readonly kind = TerminalKind.MultiLineComment; - loc: Location; - value: string; - leading?: boolean; - - trailing?: boolean; - - printed?: boolean; - - placement?: 'endOfLine' | 'ownLine' | 'remaining'; - - precedingNode?: StrictAstNode; - - enclosingNode?: StrictAstNode; - - followingNode?: StrictAstNode; - - constructor(ast: TerminalNode) { - const metadata = getNodeMetadata(ast); + constructor(ast: TerminalNode, offset: number) { + super(ast, offset); this.value = ast.unparse(); - - this.loc = metadata.loc; } print(): Doc { diff --git a/src/slang-nodes/MultiLineNatSpecComment.ts b/src/slang-nodes/MultiLineNatSpecComment.ts index 589fd0f5b..0881c823f 100644 --- a/src/slang-nodes/MultiLineNatSpecComment.ts +++ b/src/slang-nodes/MultiLineNatSpecComment.ts @@ -1,42 +1,22 @@ import { TerminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; import { doc } from 'prettier'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { CommentNode } from './CommentNode.js'; import { isIndentableBlockComment } from '../slang-utils/is-indentable-block-comment.js'; import { printIndentableBlockComment } from '../slang-printers/print-indentable-block-comment.js'; import type { Doc } from 'prettier'; -import type { BaseComment, Location, SlangNode } from '../types.d.ts'; -import type { StrictAstNode } from './types.d.ts'; const { join, literalline } = doc.builders; -export class MultiLineNatSpecComment implements SlangNode, BaseComment { +export class MultiLineNatSpecComment extends CommentNode { readonly kind = TerminalKind.MultiLineNatSpecComment; - loc: Location; - value: string; - leading?: boolean; - - trailing?: boolean; - - printed?: boolean; - - placement?: 'endOfLine' | 'ownLine' | 'remaining'; - - precedingNode?: StrictAstNode; - - enclosingNode?: StrictAstNode; - - followingNode?: StrictAstNode; - - constructor(ast: TerminalNode) { - const metadata = getNodeMetadata(ast); + constructor(ast: TerminalNode, offset: number) { + super(ast, offset); this.value = ast.unparse(); - - this.loc = metadata.loc; } print(): Doc { diff --git a/src/slang-nodes/MultiplicativeExpression.ts b/src/slang-nodes/MultiplicativeExpression.ts index 87a2e76a5..6c31ccfa8 100644 --- a/src/slang-nodes/MultiplicativeExpression.ts +++ b/src/slang-nodes/MultiplicativeExpression.ts @@ -2,13 +2,13 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printBinaryOperation } from '../slang-printers/print-binary-operation.js'; import { createHugFunction } from '../slang-utils/create-hug-function.js'; import { createKindCheckFunction } from '../slang-utils/create-kind-check-function.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const multiplicationTryToHug = createHugFunction(['/', '%']); const divisionTryToHug = createHugFunction(['*', '%']); @@ -28,13 +28,9 @@ const printMultiplicativeExpression = printBinaryOperation( ]) ); -export class MultiplicativeExpression implements SlangNode { +export class MultiplicativeExpression extends SlangNode { readonly kind = NonterminalKind.MultiplicativeExpression; - comments; - - loc; - leftOperand: Expression; operator: string; @@ -45,16 +41,13 @@ export class MultiplicativeExpression implements SlangNode { ast: ast.MultiplicativeExpression, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.leftOperand = new Expression(ast.leftOperand, options); this.operator = ast.operator.unparse(); this.rightOperand = new Expression(ast.rightOperand, options); - metadata = updateMetadata(metadata, [this.leftOperand, this.rightOperand]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.leftOperand, this.rightOperand); switch (this.operator) { case '*': diff --git a/src/slang-nodes/NamedArgument.ts b/src/slang-nodes/NamedArgument.ts index 2c0b8be87..3d00709f8 100644 --- a/src/slang-nodes/NamedArgument.ts +++ b/src/slang-nodes/NamedArgument.ts @@ -1,34 +1,27 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Identifier } from './Identifier.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class NamedArgument implements SlangNode { +export class NamedArgument extends SlangNode { readonly kind = NonterminalKind.NamedArgument; - comments; - - loc; - name: Identifier; value: Expression; constructor(ast: ast.NamedArgument, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.name = new Identifier(ast.name); this.value = new Expression(ast.value, options); - metadata = updateMetadata(metadata, [this.value]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.value); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/NamedArgumentGroup.ts b/src/slang-nodes/NamedArgumentGroup.ts index 9427bf1b0..a2631867e 100644 --- a/src/slang-nodes/NamedArgumentGroup.ts +++ b/src/slang-nodes/NamedArgumentGroup.ts @@ -1,30 +1,23 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { NamedArguments } from './NamedArguments.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class NamedArgumentGroup implements SlangNode { +export class NamedArgumentGroup extends SlangNode { readonly kind = NonterminalKind.NamedArgumentGroup; - comments; - - loc; - arguments: NamedArguments; constructor(ast: ast.NamedArgumentGroup, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.arguments = new NamedArguments(ast.arguments, options); - metadata = updateMetadata(metadata, [this.arguments]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.arguments); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/NamedArguments.ts b/src/slang-nodes/NamedArguments.ts index 085ad79db..521f40ece 100644 --- a/src/slang-nodes/NamedArguments.ts +++ b/src/slang-nodes/NamedArguments.ts @@ -1,34 +1,27 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { NamedArgument } from './NamedArgument.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line, softline } = doc.builders; -export class NamedArguments implements SlangNode { +export class NamedArguments extends SlangNode { readonly kind = NonterminalKind.NamedArguments; - comments; - - loc; - items: NamedArgument[]; constructor(ast: ast.NamedArguments, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new NamedArgument(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print( diff --git a/src/slang-nodes/NamedArgumentsDeclaration.ts b/src/slang-nodes/NamedArgumentsDeclaration.ts index 52d166959..ca321b7b3 100644 --- a/src/slang-nodes/NamedArgumentsDeclaration.ts +++ b/src/slang-nodes/NamedArgumentsDeclaration.ts @@ -1,35 +1,28 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { NamedArgumentGroup } from './NamedArgumentGroup.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class NamedArgumentsDeclaration implements SlangNode { +export class NamedArgumentsDeclaration extends SlangNode { readonly kind = NonterminalKind.NamedArgumentsDeclaration; - comments; - - loc; - arguments?: NamedArgumentGroup; constructor( ast: ast.NamedArgumentsDeclaration, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); if (ast.arguments) { this.arguments = new NamedArgumentGroup(ast.arguments, options); } - metadata = updateMetadata(metadata, [this.arguments]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.arguments); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/NamedImport.ts b/src/slang-nodes/NamedImport.ts index ddd5a82fa..9c91b1d9b 100644 --- a/src/slang-nodes/NamedImport.ts +++ b/src/slang-nodes/NamedImport.ts @@ -1,34 +1,27 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ImportAlias } from './ImportAlias.js'; import { StringLiteral } from './StringLiteral.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class NamedImport implements SlangNode { +export class NamedImport extends SlangNode { readonly kind = NonterminalKind.NamedImport; - comments; - - loc; - alias: ImportAlias; path: StringLiteral; constructor(ast: ast.NamedImport, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.alias = new ImportAlias(ast.alias); this.path = new StringLiteral(ast.path, options); - metadata = updateMetadata(metadata, [this.alias, this.path]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.alias, this.path); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/NewExpression.ts b/src/slang-nodes/NewExpression.ts index cea08562d..0c40af11d 100644 --- a/src/slang-nodes/NewExpression.ts +++ b/src/slang-nodes/NewExpression.ts @@ -1,30 +1,23 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { TypeName } from './TypeName.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class NewExpression implements SlangNode { +export class NewExpression extends SlangNode { readonly kind = NonterminalKind.NewExpression; - comments; - - loc; - typeName: TypeName; constructor(ast: ast.NewExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.typeName = new TypeName(ast.typeName, options); - metadata = updateMetadata(metadata, [this.typeName]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.typeName); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/NumberUnit.ts b/src/slang-nodes/NumberUnit.ts index b35d41d2a..6bfb73f81 100644 --- a/src/slang-nodes/NumberUnit.ts +++ b/src/slang-nodes/NumberUnit.ts @@ -1,26 +1,18 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { Doc } from 'prettier'; -import type { SlangNode } from '../types.d.ts'; -export class NumberUnit implements SlangNode { +export class NumberUnit extends SlangNode { readonly kind = NonterminalKind.NumberUnit; - comments; - - loc; - variant: string; constructor(ast: ast.NumberUnit) { - const metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant.unparse(); - - this.comments = metadata.comments; - this.loc = metadata.loc; } print(): Doc { diff --git a/src/slang-nodes/OrExpression.ts b/src/slang-nodes/OrExpression.ts index 39c269d41..432e876c0 100644 --- a/src/slang-nodes/OrExpression.ts +++ b/src/slang-nodes/OrExpression.ts @@ -1,23 +1,19 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printLogicalOperation } from '../slang-printers/print-logical-operation.js'; import { createHugFunction } from '../slang-utils/create-hug-function.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const tryToHug = createHugFunction(['&&']); -export class OrExpression implements SlangNode { +export class OrExpression extends SlangNode { readonly kind = NonterminalKind.OrExpression; - comments; - - loc; - leftOperand: Expression; operator: string; @@ -25,16 +21,13 @@ export class OrExpression implements SlangNode { rightOperand: Expression; constructor(ast: ast.OrExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.leftOperand = new Expression(ast.leftOperand, options); this.operator = ast.operator.unparse(); this.rightOperand = new Expression(ast.rightOperand, options); - metadata = updateMetadata(metadata, [this.leftOperand, this.rightOperand]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.leftOperand, this.rightOperand); this.leftOperand = tryToHug(this.leftOperand); this.rightOperand = tryToHug(this.rightOperand); diff --git a/src/slang-nodes/OverridePaths.ts b/src/slang-nodes/OverridePaths.ts index 17cf2b55c..3feb11dd1 100644 --- a/src/slang-nodes/OverridePaths.ts +++ b/src/slang-nodes/OverridePaths.ts @@ -1,30 +1,23 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; +import { SlangNode } from './SlangNode.js'; import { IdentifierPath } from './IdentifierPath.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class OverridePaths implements SlangNode { +export class OverridePaths extends SlangNode { readonly kind = NonterminalKind.OverridePaths; - comments; - - loc; - items: IdentifierPath[]; constructor(ast: ast.OverridePaths) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new IdentifierPath(item)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/OverridePathsDeclaration.ts b/src/slang-nodes/OverridePathsDeclaration.ts index accf68693..8335f117f 100644 --- a/src/slang-nodes/OverridePathsDeclaration.ts +++ b/src/slang-nodes/OverridePathsDeclaration.ts @@ -1,29 +1,22 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { OverridePaths } from './OverridePaths.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class OverridePathsDeclaration implements SlangNode { +export class OverridePathsDeclaration extends SlangNode { readonly kind = NonterminalKind.OverridePathsDeclaration; - comments; - - loc; - paths: OverridePaths; constructor(ast: ast.OverridePathsDeclaration) { - let metadata = getNodeMetadata(ast); + super(ast); this.paths = new OverridePaths(ast.paths); - metadata = updateMetadata(metadata, [this.paths]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.paths); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/OverrideSpecifier.ts b/src/slang-nodes/OverrideSpecifier.ts index 8122eab0f..fe6971762 100644 --- a/src/slang-nodes/OverrideSpecifier.ts +++ b/src/slang-nodes/OverrideSpecifier.ts @@ -1,31 +1,24 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { OverridePathsDeclaration } from './OverridePathsDeclaration.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class OverrideSpecifier implements SlangNode { +export class OverrideSpecifier extends SlangNode { readonly kind = NonterminalKind.OverrideSpecifier; - comments; - - loc; - overridden?: OverridePathsDeclaration; constructor(ast: ast.OverrideSpecifier) { - let metadata = getNodeMetadata(ast); + super(ast); if (ast.overridden) { this.overridden = new OverridePathsDeclaration(ast.overridden); } - metadata = updateMetadata(metadata, [this.overridden]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.overridden); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/Parameter.ts b/src/slang-nodes/Parameter.ts index bf92ad293..45b693048 100644 --- a/src/slang-nodes/Parameter.ts +++ b/src/slang-nodes/Parameter.ts @@ -1,7 +1,7 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { doc } from 'prettier'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { joinExisting } from '../slang-utils/join-existing.js'; +import { SlangNode } from './SlangNode.js'; import { TypeName } from './TypeName.js'; import { StorageLocation } from './StorageLocation.js'; import { Identifier } from './Identifier.js'; @@ -9,17 +9,13 @@ import { Identifier } from './Identifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group } = doc.builders; -export class Parameter implements SlangNode { +export class Parameter extends SlangNode { readonly kind = NonterminalKind.Parameter; - comments; - - loc; - typeName: TypeName; storageLocation?: StorageLocation; @@ -27,7 +23,7 @@ export class Parameter implements SlangNode { name?: Identifier; constructor(ast: ast.Parameter, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.typeName = new TypeName(ast.typeName, options); if (ast.storageLocation) { @@ -37,10 +33,7 @@ export class Parameter implements SlangNode { this.name = new Identifier(ast.name); } - metadata = updateMetadata(metadata, [this.typeName, this.storageLocation]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.typeName, this.storageLocation); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/Parameters.ts b/src/slang-nodes/Parameters.ts index 743e747db..9d95fabd7 100644 --- a/src/slang-nodes/Parameters.ts +++ b/src/slang-nodes/Parameters.ts @@ -2,32 +2,25 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; import { printSeparatedItem } from '../slang-printers/print-separated-item.js'; import { printComments } from '../slang-printers/print-comments.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Parameter } from './Parameter.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class Parameters implements SlangNode { +export class Parameters extends SlangNode { readonly kind = NonterminalKind.Parameters; - comments; - - loc; - items: Parameter[]; constructor(ast: ast.Parameters, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new Parameter(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ParametersDeclaration.ts b/src/slang-nodes/ParametersDeclaration.ts index 80bf19cda..433289d5b 100644 --- a/src/slang-nodes/ParametersDeclaration.ts +++ b/src/slang-nodes/ParametersDeclaration.ts @@ -1,30 +1,23 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Parameters } from './Parameters.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ParametersDeclaration implements SlangNode { +export class ParametersDeclaration extends SlangNode { readonly kind = NonterminalKind.ParametersDeclaration; - comments; - - loc; - parameters: Parameters; constructor(ast: ast.ParametersDeclaration, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.parameters = new Parameters(ast.parameters, options); - metadata = updateMetadata(metadata, [this.parameters]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.parameters); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/PathImport.ts b/src/slang-nodes/PathImport.ts index 493469f38..bd4442dbe 100644 --- a/src/slang-nodes/PathImport.ts +++ b/src/slang-nodes/PathImport.ts @@ -1,36 +1,29 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { StringLiteral } from './StringLiteral.js'; import { ImportAlias } from './ImportAlias.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class PathImport implements SlangNode { +export class PathImport extends SlangNode { readonly kind = NonterminalKind.PathImport; - comments; - - loc; - path: StringLiteral; alias?: ImportAlias; constructor(ast: ast.PathImport, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.path = new StringLiteral(ast.path, options); if (ast.alias) { this.alias = new ImportAlias(ast.alias); } - metadata = updateMetadata(metadata, [this.path, this.alias]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.path, this.alias); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/PositionalArguments.ts b/src/slang-nodes/PositionalArguments.ts index 2fde87591..51a198e73 100644 --- a/src/slang-nodes/PositionalArguments.ts +++ b/src/slang-nodes/PositionalArguments.ts @@ -2,32 +2,25 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printComments } from '../slang-printers/print-comments.js'; import { printSeparatedItem } from '../slang-printers/print-separated-item.js'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class PositionalArguments implements SlangNode { +export class PositionalArguments extends SlangNode { readonly kind = NonterminalKind.PositionalArguments; - comments; - - loc; - items: Expression[]; constructor(ast: ast.PositionalArguments, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new Expression(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/PositionalArgumentsDeclaration.ts b/src/slang-nodes/PositionalArgumentsDeclaration.ts index 497b6be8f..01f7871b3 100644 --- a/src/slang-nodes/PositionalArgumentsDeclaration.ts +++ b/src/slang-nodes/PositionalArgumentsDeclaration.ts @@ -1,20 +1,16 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { isBlockComment } from '../slang-utils/is-comment.js'; +import { SlangNode } from './SlangNode.js'; import { PositionalArguments } from './PositionalArguments.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class PositionalArgumentsDeclaration implements SlangNode { +export class PositionalArgumentsDeclaration extends SlangNode { readonly kind = NonterminalKind.PositionalArgumentsDeclaration; - comments; - - loc; - isEmpty; arguments: PositionalArguments; @@ -23,14 +19,11 @@ export class PositionalArgumentsDeclaration implements SlangNode { ast: ast.PositionalArgumentsDeclaration, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.arguments = new PositionalArguments(ast.arguments, options); - metadata = updateMetadata(metadata, [this.arguments]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.arguments); // We need to check the comments at this point because they will be removed // from this node into the root node. diff --git a/src/slang-nodes/PostfixExpression.ts b/src/slang-nodes/PostfixExpression.ts index ac3c2e5b3..a6dfcad49 100644 --- a/src/slang-nodes/PostfixExpression.ts +++ b/src/slang-nodes/PostfixExpression.ts @@ -1,33 +1,26 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class PostfixExpression implements SlangNode { +export class PostfixExpression extends SlangNode { readonly kind = NonterminalKind.PostfixExpression; - comments; - - loc; - operand: Expression; operator: string; constructor(ast: ast.PostfixExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.operand = new Expression(ast.operand, options); this.operator = ast.operator.unparse(); - metadata = updateMetadata(metadata, [this.operand]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.operand); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/Pragma.ts b/src/slang-nodes/Pragma.ts index 8c0e3ab15..00f8ed5b4 100644 --- a/src/slang-nodes/Pragma.ts +++ b/src/slang-nodes/Pragma.ts @@ -1,5 +1,5 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { AbicoderPragma } from './AbicoderPragma.js'; import { ExperimentalPragma } from './ExperimentalPragma.js'; import { VersionPragma } from './VersionPragma.js'; @@ -7,19 +7,15 @@ import { VersionPragma } from './VersionPragma.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class Pragma implements SlangNode { +export class Pragma extends SlangNode { readonly kind = NonterminalKind.Pragma; - comments; - - loc; - variant: AbicoderPragma | ExperimentalPragma | VersionPragma; constructor(ast: ast.Pragma, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); switch (ast.variant.cst.kind) { case NonterminalKind.AbicoderPragma: @@ -38,10 +34,7 @@ export class Pragma implements SlangNode { throw new Error(`Unexpected variant: ${ast.variant.cst.kind}`); } - metadata = updateMetadata(metadata, [this.variant]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/PragmaDirective.ts b/src/slang-nodes/PragmaDirective.ts index 72a9dc751..071411bb8 100644 --- a/src/slang-nodes/PragmaDirective.ts +++ b/src/slang-nodes/PragmaDirective.ts @@ -1,30 +1,23 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Pragma } from './Pragma.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class PragmaDirective implements SlangNode { +export class PragmaDirective extends SlangNode { readonly kind = NonterminalKind.PragmaDirective; - comments; - - loc; - pragma: Pragma; constructor(ast: ast.PragmaDirective, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.pragma = new Pragma(ast.pragma, options); - metadata = updateMetadata(metadata, [this.pragma]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.pragma); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/PrefixExpression.ts b/src/slang-nodes/PrefixExpression.ts index dadf182f0..6e278f3ae 100644 --- a/src/slang-nodes/PrefixExpression.ts +++ b/src/slang-nodes/PrefixExpression.ts @@ -1,33 +1,26 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class PrefixExpression implements SlangNode { +export class PrefixExpression extends SlangNode { readonly kind = NonterminalKind.PrefixExpression; - comments; - - loc; - operator: string; operand: Expression; constructor(ast: ast.PrefixExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.operator = ast.operator.unparse(); this.operand = new Expression(ast.operand, options); - metadata = updateMetadata(metadata, [this.operand]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.operand); if (this.operator === 'delete') { this.operator = `${this.operator} `; diff --git a/src/slang-nodes/ReceiveFunctionAttribute.ts b/src/slang-nodes/ReceiveFunctionAttribute.ts index 869d575a2..5c6138663 100644 --- a/src/slang-nodes/ReceiveFunctionAttribute.ts +++ b/src/slang-nodes/ReceiveFunctionAttribute.ts @@ -1,27 +1,23 @@ import { NonterminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ModifierInvocation } from './ModifierInvocation.js'; import { OverrideSpecifier } from './OverrideSpecifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ReceiveFunctionAttribute implements SlangNode { +export class ReceiveFunctionAttribute extends SlangNode { readonly kind = NonterminalKind.ReceiveFunctionAttribute; - comments; - - loc; - variant: ModifierInvocation | OverrideSpecifier | string; constructor( ast: ast.ReceiveFunctionAttribute, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); if (ast.variant instanceof TerminalNode) { this.variant = ast.variant.unparse(); @@ -43,13 +39,7 @@ export class ReceiveFunctionAttribute implements SlangNode { } } - metadata = updateMetadata( - metadata, - typeof this.variant === 'string' ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (typeof this.variant !== 'string') this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ReceiveFunctionAttributes.ts b/src/slang-nodes/ReceiveFunctionAttributes.ts index b2a6839ab..7ec5c13a4 100644 --- a/src/slang-nodes/ReceiveFunctionAttributes.ts +++ b/src/slang-nodes/ReceiveFunctionAttributes.ts @@ -1,39 +1,32 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { sortFunctionAttributes } from '../slang-utils/sort-function-attributes.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ReceiveFunctionAttribute } from './ReceiveFunctionAttribute.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line } = doc.builders; -export class ReceiveFunctionAttributes implements SlangNode { +export class ReceiveFunctionAttributes extends SlangNode { readonly kind = NonterminalKind.ReceiveFunctionAttributes; - comments; - - loc; - items: ReceiveFunctionAttribute[]; constructor( ast: ast.ReceiveFunctionAttributes, options: ParserOptions ) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map( (item) => new ReceiveFunctionAttribute(item, options) ); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); this.items = this.items.sort(sortFunctionAttributes); } diff --git a/src/slang-nodes/ReceiveFunctionDefinition.ts b/src/slang-nodes/ReceiveFunctionDefinition.ts index bcd158749..b3637aaf4 100644 --- a/src/slang-nodes/ReceiveFunctionDefinition.ts +++ b/src/slang-nodes/ReceiveFunctionDefinition.ts @@ -1,6 +1,6 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printFunction } from '../slang-printers/print-function.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ParametersDeclaration } from './ParametersDeclaration.js'; import { ReceiveFunctionAttributes } from './ReceiveFunctionAttributes.js'; import { FunctionBody } from './FunctionBody.js'; @@ -8,15 +8,11 @@ import { FunctionBody } from './FunctionBody.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class ReceiveFunctionDefinition implements SlangNode { +export class ReceiveFunctionDefinition extends SlangNode { readonly kind = NonterminalKind.ReceiveFunctionDefinition; - comments; - - loc; - parameters: ParametersDeclaration; attributes: ReceiveFunctionAttributes; @@ -27,20 +23,13 @@ export class ReceiveFunctionDefinition implements SlangNode { ast: ast.ReceiveFunctionDefinition, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.parameters = new ParametersDeclaration(ast.parameters, options); this.attributes = new ReceiveFunctionAttributes(ast.attributes, options); this.body = new FunctionBody(ast.body, options); - metadata = updateMetadata(metadata, [ - this.parameters, - this.attributes, - this.body - ]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.parameters, this.attributes, this.body); this.cleanModifierInvocationArguments(); } diff --git a/src/slang-nodes/ReturnStatement.ts b/src/slang-nodes/ReturnStatement.ts index 4e9a0433a..8523d0f4f 100644 --- a/src/slang-nodes/ReturnStatement.ts +++ b/src/slang-nodes/ReturnStatement.ts @@ -1,12 +1,12 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, indent, line } = doc.builders; @@ -27,26 +27,19 @@ function printExpression( return ''; } -export class ReturnStatement implements SlangNode { +export class ReturnStatement extends SlangNode { readonly kind = NonterminalKind.ReturnStatement; - comments; - - loc; - expression?: Expression; constructor(ast: ast.ReturnStatement, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); if (ast.expression) { this.expression = new Expression(ast.expression, options); } - metadata = updateMetadata(metadata, [this.expression]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.expression); } print( diff --git a/src/slang-nodes/ReturnsDeclaration.ts b/src/slang-nodes/ReturnsDeclaration.ts index 44ed378b9..939609dc9 100644 --- a/src/slang-nodes/ReturnsDeclaration.ts +++ b/src/slang-nodes/ReturnsDeclaration.ts @@ -1,33 +1,26 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ParametersDeclaration } from './ParametersDeclaration.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group } = doc.builders; -export class ReturnsDeclaration implements SlangNode { +export class ReturnsDeclaration extends SlangNode { readonly kind = NonterminalKind.ReturnsDeclaration; - comments; - - loc; - variables: ParametersDeclaration; constructor(ast: ast.ReturnsDeclaration, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.variables = new ParametersDeclaration(ast.variables, options); - metadata = updateMetadata(metadata, [this.variables]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variables); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/RevertStatement.ts b/src/slang-nodes/RevertStatement.ts index 99d76b38b..3beadb315 100644 --- a/src/slang-nodes/RevertStatement.ts +++ b/src/slang-nodes/RevertStatement.ts @@ -1,37 +1,30 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { joinExisting } from '../slang-utils/join-existing.js'; +import { SlangNode } from './SlangNode.js'; import { IdentifierPath } from './IdentifierPath.js'; import { ArgumentsDeclaration } from './ArgumentsDeclaration.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class RevertStatement implements SlangNode { +export class RevertStatement extends SlangNode { readonly kind = NonterminalKind.RevertStatement; - comments; - - loc; - error?: IdentifierPath; arguments: ArgumentsDeclaration; constructor(ast: ast.RevertStatement, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); if (ast.error) { this.error = new IdentifierPath(ast.error); } this.arguments = new ArgumentsDeclaration(ast.arguments, options); - metadata = updateMetadata(metadata, [this.error, this.arguments]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.error, this.arguments); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ShiftExpression.ts b/src/slang-nodes/ShiftExpression.ts index 8f33c9d8d..4292fd367 100644 --- a/src/slang-nodes/ShiftExpression.ts +++ b/src/slang-nodes/ShiftExpression.ts @@ -2,13 +2,13 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printBinaryOperation } from '../slang-printers/print-binary-operation.js'; import { createHugFunction } from '../slang-utils/create-hug-function.js'; import { createKindCheckFunction } from '../slang-utils/create-kind-check-function.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const tryToHugLeftOperand = createHugFunction([ '+', @@ -33,13 +33,9 @@ const printShiftExpression = printBinaryOperation( ]) ); -export class ShiftExpression implements SlangNode { +export class ShiftExpression extends SlangNode { readonly kind = NonterminalKind.ShiftExpression; - comments; - - loc; - leftOperand: Expression; operator: string; @@ -47,16 +43,13 @@ export class ShiftExpression implements SlangNode { rightOperand: Expression; constructor(ast: ast.ShiftExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.leftOperand = new Expression(ast.leftOperand, options); this.operator = ast.operator.unparse(); this.rightOperand = new Expression(ast.rightOperand, options); - metadata = updateMetadata(metadata, [this.leftOperand, this.rightOperand]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.leftOperand, this.rightOperand); this.leftOperand = tryToHugLeftOperand(this.leftOperand); this.rightOperand = tryToHugRightOperand(this.rightOperand); diff --git a/src/slang-nodes/SimpleVersionLiteral.ts b/src/slang-nodes/SimpleVersionLiteral.ts index cff068b35..4e65775d0 100644 --- a/src/slang-nodes/SimpleVersionLiteral.ts +++ b/src/slang-nodes/SimpleVersionLiteral.ts @@ -1,26 +1,18 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { Doc } from 'prettier'; -import type { SlangNode } from '../types.d.ts'; -export class SimpleVersionLiteral implements SlangNode { +export class SimpleVersionLiteral extends SlangNode { readonly kind = NonterminalKind.SimpleVersionLiteral; - comments; - - loc; - items: string[]; constructor(ast: ast.SimpleVersionLiteral) { - const metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => item.unparse()); - - this.comments = metadata.comments; - this.loc = metadata.loc; } print(): Doc { diff --git a/src/slang-nodes/SingleLineComment.ts b/src/slang-nodes/SingleLineComment.ts index 01d0ba536..68958761e 100644 --- a/src/slang-nodes/SingleLineComment.ts +++ b/src/slang-nodes/SingleLineComment.ts @@ -1,37 +1,17 @@ import { TerminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { CommentNode } from './CommentNode.js'; import type { Doc } from 'prettier'; -import type { BaseComment, Location, SlangNode } from '../types.d.ts'; -import type { StrictAstNode } from './types.d.ts'; -export class SingleLineComment implements SlangNode, BaseComment { +export class SingleLineComment extends CommentNode { readonly kind = TerminalKind.SingleLineComment; - loc: Location; - value: string; - leading?: boolean; - - trailing?: boolean; - - printed?: boolean; - - placement?: 'endOfLine' | 'ownLine' | 'remaining'; - - precedingNode?: StrictAstNode; - - enclosingNode?: StrictAstNode; - - followingNode?: StrictAstNode; - - constructor(ast: TerminalNode) { - const metadata = getNodeMetadata(ast); + constructor(ast: TerminalNode, offset: number) { + super(ast, offset); this.value = ast.unparse(); - - this.loc = metadata.loc; } print(): Doc { diff --git a/src/slang-nodes/SingleLineNatSpecComment.ts b/src/slang-nodes/SingleLineNatSpecComment.ts index 154bdaadf..ccafa2443 100644 --- a/src/slang-nodes/SingleLineNatSpecComment.ts +++ b/src/slang-nodes/SingleLineNatSpecComment.ts @@ -1,37 +1,17 @@ import { TerminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { CommentNode } from './CommentNode.js'; import type { Doc } from 'prettier'; -import type { BaseComment, Location, SlangNode } from '../types.d.ts'; -import type { StrictAstNode } from './types.d.ts'; -export class SingleLineNatSpecComment implements SlangNode, BaseComment { +export class SingleLineNatSpecComment extends CommentNode { readonly kind = TerminalKind.SingleLineNatSpecComment; - loc: Location; - value: string; - leading?: boolean; - - trailing?: boolean; - - printed?: boolean; - - placement?: 'endOfLine' | 'ownLine' | 'remaining'; - - precedingNode?: StrictAstNode; - - enclosingNode?: StrictAstNode; - - followingNode?: StrictAstNode; - - constructor(ast: TerminalNode) { - const metadata = getNodeMetadata(ast); + constructor(ast: TerminalNode, offset: number) { + super(ast, offset); this.value = ast.unparse(); - - this.loc = metadata.loc; } print(): Doc { diff --git a/src/slang-nodes/SlangNode.ts b/src/slang-nodes/SlangNode.ts new file mode 100644 index 000000000..4a9d936cf --- /dev/null +++ b/src/slang-nodes/SlangNode.ts @@ -0,0 +1,178 @@ +import { TerminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; +import { createKindCheckFunction } from '../slang-utils/create-kind-check-function.js'; +import { MultiLineComment } from '../slang-nodes/MultiLineComment.js'; +import { MultiLineNatSpecComment } from '../slang-nodes/MultiLineNatSpecComment.js'; +import { SingleLineComment } from '../slang-nodes/SingleLineComment.js'; +import { SingleLineNatSpecComment } from '../slang-nodes/SingleLineNatSpecComment.js'; + +import type { Edge } from '@nomicfoundation/slang/cst'; +import type { Comment, StrictAstNode } from '../slang-nodes/types.d.ts'; +import type { AstLocation, SlangAstNode } from '../types.d.ts'; + +const isCommentOrWhiteSpace = createKindCheckFunction([ + TerminalKind.MultiLineComment, + TerminalKind.MultiLineNatSpecComment, + TerminalKind.SingleLineComment, + TerminalKind.SingleLineNatSpecComment, + TerminalKind.EndOfLine, + TerminalKind.Whitespace +]); + +const offsets = new Map(); +export function clearOffsets(): void { + offsets.clear(); +} + +function reversedIterator(children: T[]): Iterable { + return { + [Symbol.iterator](): Iterator { + let index = children.length; + return { + next: function (): IteratorResult { + index--; + return { done: index < 0, value: children[index] }; + } + }; + } + }; +} + +function getOffset(children: Edge[] | Iterable): number { + let offset = 0; + for (const { node } of children) { + if (node.isNonterminalNode() || !isCommentOrWhiteSpace(node)) { + // The node's content starts when we find the first non-terminal token, + // or if we find a non-comment, non-whitespace token. + return offset; + } + offset += node.textLength.utf16; + } + return offset; +} + +function collectComments( + comments: Comment[], + node: StrictAstNode | StrictAstNode[] | undefined +): Comment[] { + if (node) { + if (Array.isArray(node)) { + return node.reduce(collectComments, comments); + } + if (node.comments.length > 0) { + comments.push(...node.comments.splice(0)); + } + } + return comments; +} + +export class SlangNode { + comments: Comment[] = []; + + loc: AstLocation; + + constructor( + ast: SlangAstNode | TerminalNode, + enclosePeripheralComments = false + ) { + if (ast instanceof TerminalNode) { + const offset = offsets.get(ast.id) || 0; + this.loc = { + start: offset, + end: offset + ast.textLength.utf16, + leadingOffset: 0, + trailingOffset: 0 + }; + return; + } + const parent = ast.cst; + const children = parent.children(); + + const initialOffset = offsets.get(parent.id) || 0; + let offset = initialOffset; + + for (const { node } of children) { + const { id, kind, textLength } = node; + if (node.isNonterminalNode()) { + offsets.set(id, offset); + } else { + switch (kind) { + // Since the fetching the comments and calculating offsets are both done + // as we iterate over the children and the comment also depends on the + // offset, it's hard to separate these responsibilities into different + // functions without doing the iteration twice. + case TerminalKind.MultiLineComment: + this.comments.push(new MultiLineComment(node, offset)); + break; + case TerminalKind.MultiLineNatSpecComment: + this.comments.push(new MultiLineNatSpecComment(node, offset)); + break; + case TerminalKind.SingleLineComment: + this.comments.push(new SingleLineComment(node, offset)); + break; + case TerminalKind.SingleLineNatSpecComment: + this.comments.push(new SingleLineNatSpecComment(node, offset)); + break; + case TerminalKind.Identifier: + case TerminalKind.YulIdentifier: + // Identifiers usually are user provided names for variables, + // functions, etc... + // Since a user can add comments to this section of the code as well, + // we need to track the offsets. + offsets.set(id, offset); + break; + } + } + + offset += textLength.utf16; + } + + const [leadingOffset, trailingOffset] = enclosePeripheralComments + ? [0, 0] + : [getOffset(children), getOffset(reversedIterator(children))]; + + this.loc = { + start: initialOffset + leadingOffset, + end: offset - trailingOffset, + leadingOffset, + trailingOffset + }; + } + + updateMetadata( + ...childNodes: (StrictAstNode | StrictAstNode[] | undefined)[] + ): void { + const { comments, loc } = this; + // Collect comments + this.comments = childNodes.reduce(collectComments, comments); + + // calculate correct loc object + if (loc.leadingOffset === 0) { + for (const childNode of childNodes) { + if (typeof childNode === 'undefined' || Array.isArray(childNode)) + continue; + const { leadingOffset, start } = childNode.loc; + + if (start - leadingOffset === loc.start) { + loc.leadingOffset = leadingOffset; + loc.start += leadingOffset; + break; + } + } + } + + if (loc.trailingOffset === 0) { + for (const childNode of reversedIterator(childNodes)) { + if (typeof childNode === 'undefined' || Array.isArray(childNode)) + continue; + const { trailingOffset, end } = childNode.loc; + + if (end + trailingOffset === loc.end) { + loc.trailingOffset = trailingOffset; + loc.end -= trailingOffset; + break; + } + } + } + this.loc = loc; + } +} diff --git a/src/slang-nodes/SourceUnit.ts b/src/slang-nodes/SourceUnit.ts index 70bfc900b..56a3e5f55 100644 --- a/src/slang-nodes/SourceUnit.ts +++ b/src/slang-nodes/SourceUnit.ts @@ -1,35 +1,30 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { SourceUnitMembers } from './SourceUnitMembers.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line } = doc.builders; -export class SourceUnit implements SlangNode { +export class SourceUnit extends SlangNode { readonly kind = NonterminalKind.SourceUnit; - comments; - - loc; - members: SourceUnitMembers; constructor(ast: ast.SourceUnit, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.members = new SourceUnitMembers(ast.members, options); - metadata = updateMetadata(metadata, [this.members]); + this.updateMetadata(this.members); // Because of comments being extracted like a russian doll, the order needs // to be fixed at the end. - this.comments = metadata.comments.sort((a, b) => a.loc.start - b.loc.start); - this.loc = metadata.loc; + this.comments = this.comments.sort((a, b) => a.loc.start - b.loc.start); } print( diff --git a/src/slang-nodes/SourceUnitMember.ts b/src/slang-nodes/SourceUnitMember.ts index 928c6b356..9a61b639e 100644 --- a/src/slang-nodes/SourceUnitMember.ts +++ b/src/slang-nodes/SourceUnitMember.ts @@ -1,5 +1,5 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { PragmaDirective } from './PragmaDirective.js'; import { ImportDirective } from './ImportDirective.js'; import { ContractDefinition } from './ContractDefinition.js'; @@ -17,15 +17,11 @@ import { EventDefinition } from './EventDefinition.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class SourceUnitMember implements SlangNode { +export class SourceUnitMember extends SlangNode { readonly kind = NonterminalKind.SourceUnitMember; - comments; - - loc; - variant: | PragmaDirective | ImportDirective @@ -42,7 +38,7 @@ export class SourceUnitMember implements SlangNode { | EventDefinition; constructor(ast: ast.SourceUnitMember, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); switch (ast.variant.cst.kind) { case NonterminalKind.PragmaDirective: @@ -123,10 +119,7 @@ export class SourceUnitMember implements SlangNode { throw new Error(`Unexpected variant: ${ast.variant.cst.kind}`); } - metadata = updateMetadata(metadata, [this.variant]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/SourceUnitMembers.ts b/src/slang-nodes/SourceUnitMembers.ts index 687cdaef3..6f60c9e42 100644 --- a/src/slang-nodes/SourceUnitMembers.ts +++ b/src/slang-nodes/SourceUnitMembers.ts @@ -1,31 +1,24 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printPreservingEmptyLines } from '../slang-printers/print-preserving-empty-lines.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { SourceUnitMember } from './SourceUnitMember.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class SourceUnitMembers implements SlangNode { +export class SourceUnitMembers extends SlangNode { readonly kind = NonterminalKind.SourceUnitMembers; - comments; - - loc; - items: SourceUnitMember[]; constructor(ast: ast.SourceUnitMembers, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new SourceUnitMember(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print( diff --git a/src/slang-nodes/StateVariableAttribute.ts b/src/slang-nodes/StateVariableAttribute.ts index 7eef02626..b25a90968 100644 --- a/src/slang-nodes/StateVariableAttribute.ts +++ b/src/slang-nodes/StateVariableAttribute.ts @@ -1,35 +1,25 @@ import { NonterminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { OverrideSpecifier } from './OverrideSpecifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class StateVariableAttribute implements SlangNode { +export class StateVariableAttribute extends SlangNode { readonly kind = NonterminalKind.StateVariableAttribute; - comments; - - loc; - variant: OverrideSpecifier | string; constructor(ast: ast.StateVariableAttribute) { - let metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant instanceof TerminalNode ? ast.variant.unparse() : new OverrideSpecifier(ast.variant); - metadata = updateMetadata( - metadata, - typeof this.variant === 'string' ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (typeof this.variant !== 'string') this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/StateVariableAttributes.ts b/src/slang-nodes/StateVariableAttributes.ts index 0b46a6f57..f59439def 100644 --- a/src/slang-nodes/StateVariableAttributes.ts +++ b/src/slang-nodes/StateVariableAttributes.ts @@ -1,33 +1,26 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { doc } from 'prettier'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { sortFunctionAttributes } from '../slang-utils/sort-function-attributes.js'; +import { SlangNode } from './SlangNode.js'; import { StateVariableAttribute } from './StateVariableAttribute.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line } = doc.builders; -export class StateVariableAttributes implements SlangNode { +export class StateVariableAttributes extends SlangNode { readonly kind = NonterminalKind.StateVariableAttributes; - comments; - - loc; - items: StateVariableAttribute[]; constructor(ast: ast.StateVariableAttributes) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new StateVariableAttribute(item)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); this.items = this.items.sort(sortFunctionAttributes); } diff --git a/src/slang-nodes/StateVariableDefinition.ts b/src/slang-nodes/StateVariableDefinition.ts index 7db4c2c3c..a8b406716 100644 --- a/src/slang-nodes/StateVariableDefinition.ts +++ b/src/slang-nodes/StateVariableDefinition.ts @@ -1,6 +1,6 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { doc } from 'prettier'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { TypeName } from './TypeName.js'; import { StateVariableAttributes } from './StateVariableAttributes.js'; import { Identifier } from './Identifier.js'; @@ -9,17 +9,13 @@ import { StateVariableDefinitionValue } from './StateVariableDefinitionValue.js' import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, indent, indentIfBreak } = doc.builders; -export class StateVariableDefinition implements SlangNode { +export class StateVariableDefinition extends SlangNode { readonly kind = NonterminalKind.StateVariableDefinition; - comments; - - loc; - typeName: TypeName; attributes: StateVariableAttributes; @@ -32,7 +28,7 @@ export class StateVariableDefinition implements SlangNode { ast: ast.StateVariableDefinition, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.typeName = new TypeName(ast.typeName, options); this.attributes = new StateVariableAttributes(ast.attributes); @@ -41,14 +37,7 @@ export class StateVariableDefinition implements SlangNode { this.value = new StateVariableDefinitionValue(ast.value, options); } - metadata = updateMetadata(metadata, [ - this.typeName, - this.attributes, - this.value - ]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.typeName, this.attributes, this.value); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/StateVariableDefinitionValue.ts b/src/slang-nodes/StateVariableDefinitionValue.ts index 3d161d140..77ef4c41f 100644 --- a/src/slang-nodes/StateVariableDefinitionValue.ts +++ b/src/slang-nodes/StateVariableDefinitionValue.ts @@ -1,36 +1,29 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, indent, line } = doc.builders; -export class StateVariableDefinitionValue implements SlangNode { +export class StateVariableDefinitionValue extends SlangNode { readonly kind = NonterminalKind.StateVariableDefinitionValue; - comments; - - loc; - value: Expression; constructor( ast: ast.StateVariableDefinitionValue, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.value = new Expression(ast.value, options); - metadata = updateMetadata(metadata, [this.value]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.value); } print( diff --git a/src/slang-nodes/Statement.ts b/src/slang-nodes/Statement.ts index b49f762cd..293dbdc00 100644 --- a/src/slang-nodes/Statement.ts +++ b/src/slang-nodes/Statement.ts @@ -1,5 +1,5 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ExpressionStatement } from './ExpressionStatement.js'; import { VariableDeclarationStatement } from './VariableDeclarationStatement.js'; import { TupleDeconstructionStatement } from './TupleDeconstructionStatement.js'; @@ -21,15 +21,11 @@ import { UncheckedBlock } from './UncheckedBlock.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class Statement implements SlangNode { +export class Statement extends SlangNode { readonly kind = NonterminalKind.Statement; - comments; - - loc; - variant: | ExpressionStatement | VariableDeclarationStatement @@ -50,7 +46,7 @@ export class Statement implements SlangNode { | UncheckedBlock; constructor(ast: ast.Statement, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); switch (ast.variant.cst.kind) { case NonterminalKind.ExpressionStatement: @@ -146,10 +142,7 @@ export class Statement implements SlangNode { throw new Error(`Unexpected variant: ${ast.variant.cst.kind}`); } - metadata = updateMetadata(metadata, [this.variant]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/Statements.ts b/src/slang-nodes/Statements.ts index c4d4cfea8..0c32e3c18 100644 --- a/src/slang-nodes/Statements.ts +++ b/src/slang-nodes/Statements.ts @@ -3,34 +3,27 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedItem } from '../slang-printers/print-separated-item.js'; import { printComments } from '../slang-printers/print-comments.js'; import { printPreservingEmptyLines } from '../slang-printers/print-preserving-empty-lines.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Statement } from './Statement.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { hardline } = doc.builders; -export class Statements implements SlangNode { +export class Statements extends SlangNode { readonly kind = NonterminalKind.Statements; - comments; - - loc; - items: Statement[]; constructor(ast: ast.Statements, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new Statement(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print( diff --git a/src/slang-nodes/StorageLayoutSpecifier.ts b/src/slang-nodes/StorageLayoutSpecifier.ts index de287758f..5dda52a3f 100644 --- a/src/slang-nodes/StorageLayoutSpecifier.ts +++ b/src/slang-nodes/StorageLayoutSpecifier.ts @@ -1,37 +1,30 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedItem } from '../slang-printers/print-separated-item.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line } = doc.builders; -export class StorageLayoutSpecifier implements SlangNode { +export class StorageLayoutSpecifier extends SlangNode { readonly kind = NonterminalKind.StorageLayoutSpecifier; - comments; - - loc; - expression: Expression; constructor( ast: ast.StorageLayoutSpecifier, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.expression = new Expression(ast.expression, options); - metadata = updateMetadata(metadata, [this.expression]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.expression); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/StorageLocation.ts b/src/slang-nodes/StorageLocation.ts index 89b97f2a3..64d048a03 100644 --- a/src/slang-nodes/StorageLocation.ts +++ b/src/slang-nodes/StorageLocation.ts @@ -1,26 +1,18 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { Doc } from 'prettier'; -import type { SlangNode } from '../types.d.ts'; -export class StorageLocation implements SlangNode { +export class StorageLocation extends SlangNode { readonly kind = NonterminalKind.StorageLocation; - comments; - - loc; - variant: string; constructor(ast: ast.StorageLocation) { - const metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant.unparse(); - - this.comments = metadata.comments; - this.loc = metadata.loc; } print(): Doc { diff --git a/src/slang-nodes/StringExpression.ts b/src/slang-nodes/StringExpression.ts index 7b283498a..fb4563d0c 100644 --- a/src/slang-nodes/StringExpression.ts +++ b/src/slang-nodes/StringExpression.ts @@ -1,5 +1,5 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { StringLiteral } from './StringLiteral.js'; import { StringLiterals } from './StringLiterals.js'; import { HexStringLiteral } from './HexStringLiteral.js'; @@ -9,15 +9,11 @@ import { UnicodeStringLiterals } from './UnicodeStringLiterals.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class StringExpression implements SlangNode { +export class StringExpression extends SlangNode { readonly kind = NonterminalKind.StringExpression; - comments; - - loc; - variant: | StringLiteral | StringLiterals @@ -26,7 +22,7 @@ export class StringExpression implements SlangNode { | UnicodeStringLiterals; constructor(ast: ast.StringExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); switch (ast.variant.cst.kind) { case NonterminalKind.StringLiteral: @@ -63,10 +59,7 @@ export class StringExpression implements SlangNode { throw new Error(`Unexpected variant: ${ast.variant.cst.kind}`); } - metadata = updateMetadata(metadata, [this.variant]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/StringLiteral.ts b/src/slang-nodes/StringLiteral.ts index c7bf84476..aee53e230 100644 --- a/src/slang-nodes/StringLiteral.ts +++ b/src/slang-nodes/StringLiteral.ts @@ -1,29 +1,21 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printString } from '../slang-printers/print-string.js'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { SlangNode } from '../types.d.ts'; -export class StringLiteral implements SlangNode { +export class StringLiteral extends SlangNode { readonly kind = NonterminalKind.StringLiteral; - comments; - - loc; - variant: string; constructor(ast: ast.StringLiteral, options: ParserOptions) { - const metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant.unparse(); - this.comments = metadata.comments; - this.loc = metadata.loc; - this.variant = printString(this.variant.slice(1, -1), options); } diff --git a/src/slang-nodes/StringLiterals.ts b/src/slang-nodes/StringLiterals.ts index afca5d826..a99d3ca48 100644 --- a/src/slang-nodes/StringLiterals.ts +++ b/src/slang-nodes/StringLiterals.ts @@ -1,33 +1,26 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { StringLiteral } from './StringLiteral.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { join, hardline } = doc.builders; -export class StringLiterals implements SlangNode { +export class StringLiterals extends SlangNode { readonly kind = NonterminalKind.StringLiterals; - comments; - - loc; - items: StringLiteral[]; constructor(ast: ast.StringLiterals, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new StringLiteral(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/StructDefinition.ts b/src/slang-nodes/StructDefinition.ts index 341393faf..3ad3a4c00 100644 --- a/src/slang-nodes/StructDefinition.ts +++ b/src/slang-nodes/StructDefinition.ts @@ -1,34 +1,27 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Identifier } from './Identifier.js'; import { StructMembers } from './StructMembers.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class StructDefinition implements SlangNode { +export class StructDefinition extends SlangNode { readonly kind = NonterminalKind.StructDefinition; - comments; - - loc; - name: Identifier; members: StructMembers; constructor(ast: ast.StructDefinition, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.name = new Identifier(ast.name); this.members = new StructMembers(ast.members, options); - metadata = updateMetadata(metadata, [this.members]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.members); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/StructMember.ts b/src/slang-nodes/StructMember.ts index 470fa0ae8..a6e5e5f91 100644 --- a/src/slang-nodes/StructMember.ts +++ b/src/slang-nodes/StructMember.ts @@ -1,34 +1,27 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { TypeName } from './TypeName.js'; import { Identifier } from './Identifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class StructMember implements SlangNode { +export class StructMember extends SlangNode { readonly kind = NonterminalKind.StructMember; - comments; - - loc; - typeName: TypeName; name: Identifier; constructor(ast: ast.StructMember, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.typeName = new TypeName(ast.typeName, options); this.name = new Identifier(ast.name); - metadata = updateMetadata(metadata, [this.typeName]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.typeName); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/StructMembers.ts b/src/slang-nodes/StructMembers.ts index 7fd975619..2d8a8060c 100644 --- a/src/slang-nodes/StructMembers.ts +++ b/src/slang-nodes/StructMembers.ts @@ -1,34 +1,27 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { StructMember } from './StructMember.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { hardline } = doc.builders; -export class StructMembers implements SlangNode { +export class StructMembers extends SlangNode { readonly kind = NonterminalKind.StructMembers; - comments; - - loc; - items: StructMember[]; constructor(ast: ast.StructMembers, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new StructMember(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/ThrowStatement.ts b/src/slang-nodes/ThrowStatement.ts index 155f87b6d..c59252f59 100644 --- a/src/slang-nodes/ThrowStatement.ts +++ b/src/slang-nodes/ThrowStatement.ts @@ -1,22 +1,14 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { Doc } from 'prettier'; -import type { SlangNode } from '../types.d.ts'; -export class ThrowStatement implements SlangNode { +export class ThrowStatement extends SlangNode { readonly kind = NonterminalKind.ThrowStatement; - comments; - - loc; - constructor(ast: ast.ThrowStatement) { - const metadata = getNodeMetadata(ast); - - this.comments = metadata.comments; - this.loc = metadata.loc; + super(ast); } print(): Doc { diff --git a/src/slang-nodes/TryStatement.ts b/src/slang-nodes/TryStatement.ts index c714e6915..cbc00714f 100644 --- a/src/slang-nodes/TryStatement.ts +++ b/src/slang-nodes/TryStatement.ts @@ -1,8 +1,8 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedItem } from '../slang-printers/print-separated-item.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { joinExisting } from '../slang-utils/join-existing.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import { ReturnsDeclaration } from './ReturnsDeclaration.js'; import { Block } from './Block.js'; @@ -11,17 +11,13 @@ import { CatchClauses } from './CatchClauses.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line } = doc.builders; -export class TryStatement implements SlangNode { +export class TryStatement extends SlangNode { readonly kind = NonterminalKind.TryStatement; - comments; - - loc; - expression: Expression; returns?: ReturnsDeclaration; @@ -31,7 +27,7 @@ export class TryStatement implements SlangNode { catchClauses: CatchClauses; constructor(ast: ast.TryStatement, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.expression = new Expression(ast.expression, options); if (ast.returns) { @@ -40,15 +36,12 @@ export class TryStatement implements SlangNode { this.body = new Block(ast.body, options); this.catchClauses = new CatchClauses(ast.catchClauses, options); - metadata = updateMetadata(metadata, [ + this.updateMetadata( this.expression, this.returns, this.body, this.catchClauses - ]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + ); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/TupleDeconstructionElement.ts b/src/slang-nodes/TupleDeconstructionElement.ts index d294ef837..615baca72 100644 --- a/src/slang-nodes/TupleDeconstructionElement.ts +++ b/src/slang-nodes/TupleDeconstructionElement.ts @@ -1,35 +1,28 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { TupleMember } from './TupleMember.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class TupleDeconstructionElement implements SlangNode { +export class TupleDeconstructionElement extends SlangNode { readonly kind = NonterminalKind.TupleDeconstructionElement; - comments; - - loc; - member?: TupleMember; constructor( ast: ast.TupleDeconstructionElement, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); if (ast.member) { this.member = new TupleMember(ast.member, options); } - metadata = updateMetadata(metadata, [this.member]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.member); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/TupleDeconstructionElements.ts b/src/slang-nodes/TupleDeconstructionElements.ts index 113a6908a..674f62a4f 100644 --- a/src/slang-nodes/TupleDeconstructionElements.ts +++ b/src/slang-nodes/TupleDeconstructionElements.ts @@ -1,36 +1,29 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { TupleDeconstructionElement } from './TupleDeconstructionElement.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class TupleDeconstructionElements implements SlangNode { +export class TupleDeconstructionElements extends SlangNode { readonly kind = NonterminalKind.TupleDeconstructionElements; - comments; - - loc; - items: TupleDeconstructionElement[]; constructor( ast: ast.TupleDeconstructionElements, options: ParserOptions ) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map( (item) => new TupleDeconstructionElement(item, options) ); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/TupleDeconstructionStatement.ts b/src/slang-nodes/TupleDeconstructionStatement.ts index 5c15ef3f4..74e167602 100644 --- a/src/slang-nodes/TupleDeconstructionStatement.ts +++ b/src/slang-nodes/TupleDeconstructionStatement.ts @@ -1,23 +1,19 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { doc } from 'prettier'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { TupleDeconstructionElements } from './TupleDeconstructionElements.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, indentIfBreak } = doc.builders; -export class TupleDeconstructionStatement implements SlangNode { +export class TupleDeconstructionStatement extends SlangNode { readonly kind = NonterminalKind.TupleDeconstructionStatement; - comments; - - loc; - varKeyword?: string; elements: TupleDeconstructionElements; @@ -28,16 +24,13 @@ export class TupleDeconstructionStatement implements SlangNode { ast: ast.TupleDeconstructionStatement, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.varKeyword = ast.varKeyword?.unparse(); this.elements = new TupleDeconstructionElements(ast.elements, options); this.expression = new Expression(ast.expression, options); - metadata = updateMetadata(metadata, [this.elements, this.expression]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.elements, this.expression); } print( diff --git a/src/slang-nodes/TupleExpression.ts b/src/slang-nodes/TupleExpression.ts index 89bd6a396..d3c75a086 100644 --- a/src/slang-nodes/TupleExpression.ts +++ b/src/slang-nodes/TupleExpression.ts @@ -1,30 +1,23 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { TupleValues } from './TupleValues.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class TupleExpression implements SlangNode { +export class TupleExpression extends SlangNode { readonly kind = NonterminalKind.TupleExpression; - comments; - - loc; - items: TupleValues; constructor(ast: ast.TupleExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.items = new TupleValues(ast.items, options); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/TupleMember.ts b/src/slang-nodes/TupleMember.ts index 8a761d01d..31f84a284 100644 --- a/src/slang-nodes/TupleMember.ts +++ b/src/slang-nodes/TupleMember.ts @@ -1,24 +1,20 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { TypedTupleMember } from './TypedTupleMember.js'; import { UntypedTupleMember } from './UntypedTupleMember.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class TupleMember implements SlangNode { +export class TupleMember extends SlangNode { readonly kind = NonterminalKind.TupleMember; - comments; - - loc; - variant: TypedTupleMember | UntypedTupleMember; constructor(ast: ast.TupleMember, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); switch (ast.variant.cst.kind) { case NonterminalKind.TypedTupleMember: @@ -36,10 +32,7 @@ export class TupleMember implements SlangNode { throw new Error(`Unexpected variant: ${ast.variant.cst.kind}`); } - metadata = updateMetadata(metadata, [this.variant]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/TupleValue.ts b/src/slang-nodes/TupleValue.ts index 70a5482fc..bb4acbd2a 100644 --- a/src/slang-nodes/TupleValue.ts +++ b/src/slang-nodes/TupleValue.ts @@ -1,32 +1,25 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class TupleValue implements SlangNode { +export class TupleValue extends SlangNode { readonly kind = NonterminalKind.TupleValue; - comments; - - loc; - expression?: Expression; constructor(ast: ast.TupleValue, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); if (ast.expression) { this.expression = new Expression(ast.expression, options); } - metadata = updateMetadata(metadata, [this.expression]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.expression); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/TupleValues.ts b/src/slang-nodes/TupleValues.ts index ba0e73db6..686dca1b0 100644 --- a/src/slang-nodes/TupleValues.ts +++ b/src/slang-nodes/TupleValues.ts @@ -1,33 +1,26 @@ import { NonterminalKind, TerminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; import { isBinaryOperation } from '../slang-utils/is-binary-operation.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { TupleValue } from './TupleValue.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; import type { Expression } from './Expression.js'; -export class TupleValues implements SlangNode { +export class TupleValues extends SlangNode { readonly kind = NonterminalKind.TupleValues; - comments; - - loc; - items: TupleValue[]; constructor(ast: ast.TupleValues, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new TupleValue(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } getSingleExpression(): Expression | undefined { diff --git a/src/slang-nodes/TypeExpression.ts b/src/slang-nodes/TypeExpression.ts index dc180f338..80b76dcbc 100644 --- a/src/slang-nodes/TypeExpression.ts +++ b/src/slang-nodes/TypeExpression.ts @@ -1,30 +1,23 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { TypeName } from './TypeName.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class TypeExpression implements SlangNode { +export class TypeExpression extends SlangNode { readonly kind = NonterminalKind.TypeExpression; - comments; - - loc; - typeName: TypeName; constructor(ast: ast.TypeExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.typeName = new TypeName(ast.typeName, options); - metadata = updateMetadata(metadata, [this.typeName]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.typeName); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/TypeName.ts b/src/slang-nodes/TypeName.ts index 13f1363b1..75aa619f4 100644 --- a/src/slang-nodes/TypeName.ts +++ b/src/slang-nodes/TypeName.ts @@ -1,5 +1,5 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ArrayTypeName } from './ArrayTypeName.js'; import { FunctionType } from './FunctionType.js'; import { MappingType } from './MappingType.js'; @@ -9,15 +9,11 @@ import { IdentifierPath } from './IdentifierPath.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class TypeName implements SlangNode { +export class TypeName extends SlangNode { readonly kind = NonterminalKind.TypeName; - comments; - - loc; - variant: | ArrayTypeName | FunctionType @@ -26,7 +22,7 @@ export class TypeName implements SlangNode { | IdentifierPath; constructor(ast: ast.TypeName, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); switch (ast.variant.cst.kind) { case NonterminalKind.ArrayTypeName: @@ -54,10 +50,7 @@ export class TypeName implements SlangNode { throw new Error(`Unexpected variant: ${ast.variant.cst.kind}`); } - metadata = updateMetadata(metadata, [this.variant]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/TypedTupleMember.ts b/src/slang-nodes/TypedTupleMember.ts index bc075a541..691f05445 100644 --- a/src/slang-nodes/TypedTupleMember.ts +++ b/src/slang-nodes/TypedTupleMember.ts @@ -1,6 +1,6 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { joinExisting } from '../slang-utils/join-existing.js'; +import { SlangNode } from './SlangNode.js'; import { TypeName } from './TypeName.js'; import { StorageLocation } from './StorageLocation.js'; import { Identifier } from './Identifier.js'; @@ -8,15 +8,11 @@ import { Identifier } from './Identifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class TypedTupleMember implements SlangNode { +export class TypedTupleMember extends SlangNode { readonly kind = NonterminalKind.TypedTupleMember; - comments; - - loc; - typeName: TypeName; storageLocation?: StorageLocation; @@ -24,7 +20,7 @@ export class TypedTupleMember implements SlangNode { name: Identifier; constructor(ast: ast.TypedTupleMember, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.typeName = new TypeName(ast.typeName, options); if (ast.storageLocation) { @@ -32,10 +28,7 @@ export class TypedTupleMember implements SlangNode { } this.name = new Identifier(ast.name); - metadata = updateMetadata(metadata, [this.typeName, this.storageLocation]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.typeName, this.storageLocation); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/UncheckedBlock.ts b/src/slang-nodes/UncheckedBlock.ts index e1340278e..3f8fee8e0 100644 --- a/src/slang-nodes/UncheckedBlock.ts +++ b/src/slang-nodes/UncheckedBlock.ts @@ -1,30 +1,23 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Block } from './Block.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class UncheckedBlock implements SlangNode { +export class UncheckedBlock extends SlangNode { readonly kind = NonterminalKind.UncheckedBlock; - comments; - - loc; - block: Block; constructor(ast: ast.UncheckedBlock, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.block = new Block(ast.block, options); - metadata = updateMetadata(metadata, [this.block]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.block); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/UnicodeStringLiteral.ts b/src/slang-nodes/UnicodeStringLiteral.ts index d10bafb5e..68144b674 100644 --- a/src/slang-nodes/UnicodeStringLiteral.ts +++ b/src/slang-nodes/UnicodeStringLiteral.ts @@ -1,29 +1,21 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printString } from '../slang-printers/print-string.js'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { SlangNode } from '../types.d.ts'; -export class UnicodeStringLiteral implements SlangNode { +export class UnicodeStringLiteral extends SlangNode { readonly kind = NonterminalKind.UnicodeStringLiteral; - comments; - - loc; - variant: string; constructor(ast: ast.UnicodeStringLiteral, options: ParserOptions) { - const metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant.unparse(); - this.comments = metadata.comments; - this.loc = metadata.loc; - this.variant = `unicode${printString(this.variant.slice(8, -1), options)}`; } diff --git a/src/slang-nodes/UnicodeStringLiterals.ts b/src/slang-nodes/UnicodeStringLiterals.ts index 5436b6cf8..025957424 100644 --- a/src/slang-nodes/UnicodeStringLiterals.ts +++ b/src/slang-nodes/UnicodeStringLiterals.ts @@ -1,35 +1,28 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { UnicodeStringLiteral } from './UnicodeStringLiteral.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { join, hardline } = doc.builders; -export class UnicodeStringLiterals implements SlangNode { +export class UnicodeStringLiterals extends SlangNode { readonly kind = NonterminalKind.UnicodeStringLiterals; - comments; - - loc; - items: UnicodeStringLiteral[]; constructor(ast: ast.UnicodeStringLiterals, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map( (item) => new UnicodeStringLiteral(item, options) ); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/UnnamedFunctionAttribute.ts b/src/slang-nodes/UnnamedFunctionAttribute.ts index 5f2b57b12..d25bbc7de 100644 --- a/src/slang-nodes/UnnamedFunctionAttribute.ts +++ b/src/slang-nodes/UnnamedFunctionAttribute.ts @@ -1,39 +1,29 @@ import { NonterminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ModifierInvocation } from './ModifierInvocation.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class UnnamedFunctionAttribute implements SlangNode { +export class UnnamedFunctionAttribute extends SlangNode { readonly kind = NonterminalKind.UnnamedFunctionAttribute; - comments; - - loc; - variant: ModifierInvocation | string; constructor( ast: ast.UnnamedFunctionAttribute, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant instanceof TerminalNode ? ast.variant.unparse() : new ModifierInvocation(ast.variant, options); - metadata = updateMetadata( - metadata, - typeof this.variant === 'string' ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (typeof this.variant !== 'string') this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/UnnamedFunctionAttributes.ts b/src/slang-nodes/UnnamedFunctionAttributes.ts index 2d4f8b79e..82f45d924 100644 --- a/src/slang-nodes/UnnamedFunctionAttributes.ts +++ b/src/slang-nodes/UnnamedFunctionAttributes.ts @@ -1,39 +1,32 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { sortFunctionAttributes } from '../slang-utils/sort-function-attributes.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { UnnamedFunctionAttribute } from './UnnamedFunctionAttribute.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line } = doc.builders; -export class UnnamedFunctionAttributes implements SlangNode { +export class UnnamedFunctionAttributes extends SlangNode { readonly kind = NonterminalKind.UnnamedFunctionAttributes; - comments; - - loc; - items: UnnamedFunctionAttribute[]; constructor( ast: ast.UnnamedFunctionAttributes, options: ParserOptions ) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map( (item) => new UnnamedFunctionAttribute(item, options) ); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); this.items = this.items.sort(sortFunctionAttributes); } diff --git a/src/slang-nodes/UnnamedFunctionDefinition.ts b/src/slang-nodes/UnnamedFunctionDefinition.ts index 89caaadfb..ca235104f 100644 --- a/src/slang-nodes/UnnamedFunctionDefinition.ts +++ b/src/slang-nodes/UnnamedFunctionDefinition.ts @@ -1,6 +1,6 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printFunction } from '../slang-printers/print-function.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { ParametersDeclaration } from './ParametersDeclaration.js'; import { UnnamedFunctionAttributes } from './UnnamedFunctionAttributes.js'; import { FunctionBody } from './FunctionBody.js'; @@ -8,15 +8,11 @@ import { FunctionBody } from './FunctionBody.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class UnnamedFunctionDefinition implements SlangNode { +export class UnnamedFunctionDefinition extends SlangNode { readonly kind = NonterminalKind.UnnamedFunctionDefinition; - comments; - - loc; - parameters: ParametersDeclaration; attributes: UnnamedFunctionAttributes; @@ -27,20 +23,13 @@ export class UnnamedFunctionDefinition implements SlangNode { ast: ast.UnnamedFunctionDefinition, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.parameters = new ParametersDeclaration(ast.parameters, options); this.attributes = new UnnamedFunctionAttributes(ast.attributes, options); this.body = new FunctionBody(ast.body, options); - metadata = updateMetadata(metadata, [ - this.parameters, - this.attributes, - this.body - ]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.parameters, this.attributes, this.body); this.cleanModifierInvocationArguments(); } diff --git a/src/slang-nodes/UntypedTupleMember.ts b/src/slang-nodes/UntypedTupleMember.ts index 9dcf661ed..bdd157831 100644 --- a/src/slang-nodes/UntypedTupleMember.ts +++ b/src/slang-nodes/UntypedTupleMember.ts @@ -1,36 +1,29 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { joinExisting } from '../slang-utils/join-existing.js'; +import { SlangNode } from './SlangNode.js'; import { StorageLocation } from './StorageLocation.js'; import { Identifier } from './Identifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class UntypedTupleMember implements SlangNode { +export class UntypedTupleMember extends SlangNode { readonly kind = NonterminalKind.UntypedTupleMember; - comments; - - loc; - storageLocation?: StorageLocation; name: Identifier; constructor(ast: ast.UntypedTupleMember) { - let metadata = getNodeMetadata(ast); + super(ast); if (ast.storageLocation) { this.storageLocation = new StorageLocation(ast.storageLocation); } this.name = new Identifier(ast.name); - metadata = updateMetadata(metadata, [this.storageLocation]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.storageLocation); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/UserDefinedValueTypeDefinition.ts b/src/slang-nodes/UserDefinedValueTypeDefinition.ts index 9561d87ff..3bdd73c08 100644 --- a/src/slang-nodes/UserDefinedValueTypeDefinition.ts +++ b/src/slang-nodes/UserDefinedValueTypeDefinition.ts @@ -1,33 +1,26 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Identifier } from './Identifier.js'; import { ElementaryType } from './ElementaryType.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class UserDefinedValueTypeDefinition implements SlangNode { +export class UserDefinedValueTypeDefinition extends SlangNode { readonly kind = NonterminalKind.UserDefinedValueTypeDefinition; - comments; - - loc; - name: Identifier; valueType: ElementaryType; constructor(ast: ast.UserDefinedValueTypeDefinition) { - let metadata = getNodeMetadata(ast); + super(ast); this.name = new Identifier(ast.name); this.valueType = new ElementaryType(ast.valueType); - metadata = updateMetadata(metadata, [this.valueType]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.valueType); } print( diff --git a/src/slang-nodes/UsingAlias.ts b/src/slang-nodes/UsingAlias.ts index d8c4d14b6..f1823b6c4 100644 --- a/src/slang-nodes/UsingAlias.ts +++ b/src/slang-nodes/UsingAlias.ts @@ -1,29 +1,22 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { UsingOperator } from './UsingOperator.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class UsingAlias implements SlangNode { +export class UsingAlias extends SlangNode { readonly kind = NonterminalKind.UsingAlias; - comments; - - loc; - operator: UsingOperator; constructor(ast: ast.UsingAlias) { - let metadata = getNodeMetadata(ast); + super(ast); this.operator = new UsingOperator(ast.operator); - metadata = updateMetadata(metadata, [this.operator]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.operator); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/UsingClause.ts b/src/slang-nodes/UsingClause.ts index 6e8ea43ed..17ffc5c75 100644 --- a/src/slang-nodes/UsingClause.ts +++ b/src/slang-nodes/UsingClause.ts @@ -1,23 +1,19 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { IdentifierPath } from './IdentifierPath.js'; import { UsingDeconstruction } from './UsingDeconstruction.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class UsingClause implements SlangNode { +export class UsingClause extends SlangNode { readonly kind = NonterminalKind.UsingClause; - comments; - - loc; - variant: IdentifierPath | UsingDeconstruction; constructor(ast: ast.UsingClause) { - let metadata = getNodeMetadata(ast); + super(ast); switch (ast.variant.cst.kind) { case NonterminalKind.IdentifierPath: @@ -32,10 +28,7 @@ export class UsingClause implements SlangNode { throw new Error(`Unexpected variant: ${ast.variant.cst.kind}`); } - metadata = updateMetadata(metadata, [this.variant]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/UsingDeconstruction.ts b/src/slang-nodes/UsingDeconstruction.ts index 250bcc443..940290fc1 100644 --- a/src/slang-nodes/UsingDeconstruction.ts +++ b/src/slang-nodes/UsingDeconstruction.ts @@ -1,29 +1,22 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { UsingDeconstructionSymbols } from './UsingDeconstructionSymbols.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class UsingDeconstruction implements SlangNode { +export class UsingDeconstruction extends SlangNode { readonly kind = NonterminalKind.UsingDeconstruction; - comments; - - loc; - symbols: UsingDeconstructionSymbols; constructor(ast: ast.UsingDeconstruction) { - let metadata = getNodeMetadata(ast); + super(ast); this.symbols = new UsingDeconstructionSymbols(ast.symbols); - metadata = updateMetadata(metadata, [this.symbols]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.symbols); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/UsingDeconstructionSymbol.ts b/src/slang-nodes/UsingDeconstructionSymbol.ts index e14d1d9e6..6158ee528 100644 --- a/src/slang-nodes/UsingDeconstructionSymbol.ts +++ b/src/slang-nodes/UsingDeconstructionSymbol.ts @@ -1,35 +1,28 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { IdentifierPath } from './IdentifierPath.js'; import { UsingAlias } from './UsingAlias.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class UsingDeconstructionSymbol implements SlangNode { +export class UsingDeconstructionSymbol extends SlangNode { readonly kind = NonterminalKind.UsingDeconstructionSymbol; - comments; - - loc; - name: IdentifierPath; alias?: UsingAlias; constructor(ast: ast.UsingDeconstructionSymbol) { - let metadata = getNodeMetadata(ast); + super(ast); this.name = new IdentifierPath(ast.name); if (ast.alias) { this.alias = new UsingAlias(ast.alias); } - metadata = updateMetadata(metadata, [this.name, this.alias]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.name, this.alias); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/UsingDeconstructionSymbols.ts b/src/slang-nodes/UsingDeconstructionSymbols.ts index a89f7fe8c..b73d9d3f5 100644 --- a/src/slang-nodes/UsingDeconstructionSymbols.ts +++ b/src/slang-nodes/UsingDeconstructionSymbols.ts @@ -1,34 +1,27 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { UsingDeconstructionSymbol } from './UsingDeconstructionSymbol.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line, softline } = doc.builders; -export class UsingDeconstructionSymbols implements SlangNode { +export class UsingDeconstructionSymbols extends SlangNode { readonly kind = NonterminalKind.UsingDeconstructionSymbols; - comments; - - loc; - items: UsingDeconstructionSymbol[]; constructor(ast: ast.UsingDeconstructionSymbols) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new UsingDeconstructionSymbol(item)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print( diff --git a/src/slang-nodes/UsingDirective.ts b/src/slang-nodes/UsingDirective.ts index 45481f747..6201516d0 100644 --- a/src/slang-nodes/UsingDirective.ts +++ b/src/slang-nodes/UsingDirective.ts @@ -1,21 +1,17 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { joinExisting } from '../slang-utils/join-existing.js'; +import { SlangNode } from './SlangNode.js'; import { UsingClause } from './UsingClause.js'; import { UsingTarget } from './UsingTarget.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class UsingDirective implements SlangNode { +export class UsingDirective extends SlangNode { readonly kind = NonterminalKind.UsingDirective; - comments; - - loc; - clause: UsingClause; target: UsingTarget; @@ -23,16 +19,13 @@ export class UsingDirective implements SlangNode { globalKeyword?: string; constructor(ast: ast.UsingDirective, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.clause = new UsingClause(ast.clause); this.target = new UsingTarget(ast.target, options); this.globalKeyword = ast.globalKeyword?.unparse(); - metadata = updateMetadata(metadata, [this.clause, this.target]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.clause, this.target); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/UsingOperator.ts b/src/slang-nodes/UsingOperator.ts index 3fe61a41b..48cbbe861 100644 --- a/src/slang-nodes/UsingOperator.ts +++ b/src/slang-nodes/UsingOperator.ts @@ -1,26 +1,18 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { Doc } from 'prettier'; -import type { SlangNode } from '../types.d.ts'; -export class UsingOperator implements SlangNode { +export class UsingOperator extends SlangNode { readonly kind = NonterminalKind.UsingOperator; - comments; - - loc; - variant: string; constructor(ast: ast.UsingOperator) { - const metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant.unparse(); - - this.comments = metadata.comments; - this.loc = metadata.loc; } print(): Doc { diff --git a/src/slang-nodes/UsingTarget.ts b/src/slang-nodes/UsingTarget.ts index 5629960a7..77acd9c0a 100644 --- a/src/slang-nodes/UsingTarget.ts +++ b/src/slang-nodes/UsingTarget.ts @@ -1,36 +1,26 @@ import { NonterminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { TypeName } from './TypeName.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class UsingTarget implements SlangNode { +export class UsingTarget extends SlangNode { readonly kind = NonterminalKind.UsingTarget; - comments; - - loc; - variant: TypeName | string; constructor(ast: ast.UsingTarget, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant instanceof TerminalNode ? ast.variant.unparse() : new TypeName(ast.variant, options); - metadata = updateMetadata( - metadata, - typeof this.variant === 'string' ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (typeof this.variant !== 'string') this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/VariableDeclarationStatement.ts b/src/slang-nodes/VariableDeclarationStatement.ts index 842932609..4312cc45f 100644 --- a/src/slang-nodes/VariableDeclarationStatement.ts +++ b/src/slang-nodes/VariableDeclarationStatement.ts @@ -1,6 +1,6 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { doc } from 'prettier'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { VariableDeclarationType } from './VariableDeclarationType.js'; import { StorageLocation } from './StorageLocation.js'; import { Identifier } from './Identifier.js'; @@ -9,17 +9,13 @@ import { VariableDeclarationValue } from './VariableDeclarationValue.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, indent, indentIfBreak, line } = doc.builders; -export class VariableDeclarationStatement implements SlangNode { +export class VariableDeclarationStatement extends SlangNode { readonly kind = NonterminalKind.VariableDeclarationStatement; - comments; - - loc; - variableType: VariableDeclarationType; storageLocation?: StorageLocation; @@ -32,7 +28,7 @@ export class VariableDeclarationStatement implements SlangNode { ast: ast.VariableDeclarationStatement, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.variableType = new VariableDeclarationType(ast.variableType, options); if (ast.storageLocation) { @@ -43,14 +39,7 @@ export class VariableDeclarationStatement implements SlangNode { this.value = new VariableDeclarationValue(ast.value, options); } - metadata = updateMetadata(metadata, [ - this.variableType, - this.storageLocation, - this.value - ]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variableType, this.storageLocation, this.value); } print( diff --git a/src/slang-nodes/VariableDeclarationType.ts b/src/slang-nodes/VariableDeclarationType.ts index 5475295d1..7e1f04bb0 100644 --- a/src/slang-nodes/VariableDeclarationType.ts +++ b/src/slang-nodes/VariableDeclarationType.ts @@ -1,39 +1,29 @@ import { NonterminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { TypeName } from './TypeName.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class VariableDeclarationType implements SlangNode { +export class VariableDeclarationType extends SlangNode { readonly kind = NonterminalKind.VariableDeclarationType; - comments; - - loc; - variant: TypeName | string; constructor( ast: ast.VariableDeclarationType, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant instanceof TerminalNode ? ast.variant.unparse() : new TypeName(ast.variant, options); - metadata = updateMetadata( - metadata, - typeof this.variant === 'string' ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (typeof this.variant !== 'string') this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/VariableDeclarationValue.ts b/src/slang-nodes/VariableDeclarationValue.ts index 4df39346c..860a529dd 100644 --- a/src/slang-nodes/VariableDeclarationValue.ts +++ b/src/slang-nodes/VariableDeclarationValue.ts @@ -1,33 +1,26 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class VariableDeclarationValue implements SlangNode { +export class VariableDeclarationValue extends SlangNode { readonly kind = NonterminalKind.VariableDeclarationValue; - comments; - - loc; - expression: Expression; constructor( ast: ast.VariableDeclarationValue, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.expression = new Expression(ast.expression, options); - metadata = updateMetadata(metadata, [this.expression]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.expression); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/VersionExpression.ts b/src/slang-nodes/VersionExpression.ts index 57c622096..3c87be7ae 100644 --- a/src/slang-nodes/VersionExpression.ts +++ b/src/slang-nodes/VersionExpression.ts @@ -1,23 +1,19 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { VersionRange } from './VersionRange.js'; import { VersionTerm } from './VersionTerm.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class VersionExpression implements SlangNode { +export class VersionExpression extends SlangNode { readonly kind = NonterminalKind.VersionExpression; - comments; - - loc; - variant: VersionRange | VersionTerm; constructor(ast: ast.VersionExpression) { - let metadata = getNodeMetadata(ast); + super(ast); switch (ast.variant.cst.kind) { case NonterminalKind.VersionRange: @@ -30,10 +26,7 @@ export class VersionExpression implements SlangNode { throw new Error(`Unexpected variant: ${ast.variant.cst.kind}`); } - metadata = updateMetadata(metadata, [this.variant]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/VersionExpressionSet.ts b/src/slang-nodes/VersionExpressionSet.ts index 8f9e71572..b8a6dc275 100644 --- a/src/slang-nodes/VersionExpressionSet.ts +++ b/src/slang-nodes/VersionExpressionSet.ts @@ -1,32 +1,25 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { VersionExpression } from './VersionExpression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { join } = doc.builders; -export class VersionExpressionSet implements SlangNode { +export class VersionExpressionSet extends SlangNode { readonly kind = NonterminalKind.VersionExpressionSet; - comments; - - loc; - items: VersionExpression[]; constructor(ast: ast.VersionExpressionSet) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new VersionExpression(item)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/VersionExpressionSets.ts b/src/slang-nodes/VersionExpressionSets.ts index fb16282d0..1b880571b 100644 --- a/src/slang-nodes/VersionExpressionSets.ts +++ b/src/slang-nodes/VersionExpressionSets.ts @@ -1,32 +1,25 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { doc } from 'prettier'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { VersionExpressionSet } from './VersionExpressionSet.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { join } = doc.builders; -export class VersionExpressionSets implements SlangNode { +export class VersionExpressionSets extends SlangNode { readonly kind = NonterminalKind.VersionExpressionSets; - comments; - - loc; - items: VersionExpressionSet[]; constructor(ast: ast.VersionExpressionSets) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new VersionExpressionSet(item)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/VersionLiteral.ts b/src/slang-nodes/VersionLiteral.ts index 2b56a0e71..2a47b818c 100644 --- a/src/slang-nodes/VersionLiteral.ts +++ b/src/slang-nodes/VersionLiteral.ts @@ -1,35 +1,25 @@ import { NonterminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { SimpleVersionLiteral } from './SimpleVersionLiteral.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class VersionLiteral implements SlangNode { +export class VersionLiteral extends SlangNode { readonly kind = NonterminalKind.VersionLiteral; - comments; - - loc; - variant: SimpleVersionLiteral | string; constructor(ast: ast.VersionLiteral) { - let metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant instanceof TerminalNode ? ast.variant.unparse() : new SimpleVersionLiteral(ast.variant); - metadata = updateMetadata( - metadata, - typeof this.variant === 'string' ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (typeof this.variant !== 'string') this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/VersionOperator.ts b/src/slang-nodes/VersionOperator.ts index 166a84fd3..a94a213f0 100644 --- a/src/slang-nodes/VersionOperator.ts +++ b/src/slang-nodes/VersionOperator.ts @@ -1,26 +1,18 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { Doc } from 'prettier'; -import type { SlangNode } from '../types.d.ts'; -export class VersionOperator implements SlangNode { +export class VersionOperator extends SlangNode { readonly kind = NonterminalKind.VersionOperator; - comments; - - loc; - variant: string; constructor(ast: ast.VersionOperator) { - const metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant.unparse(); - - this.comments = metadata.comments; - this.loc = metadata.loc; } print(): Doc { diff --git a/src/slang-nodes/VersionPragma.ts b/src/slang-nodes/VersionPragma.ts index d84a1aa5b..3f7fecf86 100644 --- a/src/slang-nodes/VersionPragma.ts +++ b/src/slang-nodes/VersionPragma.ts @@ -1,29 +1,22 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { VersionExpressionSets } from './VersionExpressionSets.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class VersionPragma implements SlangNode { +export class VersionPragma extends SlangNode { readonly kind = NonterminalKind.VersionPragma; - comments; - - loc; - sets: VersionExpressionSets; constructor(ast: ast.VersionPragma) { - let metadata = getNodeMetadata(ast); + super(ast); this.sets = new VersionExpressionSets(ast.sets); - metadata = updateMetadata(metadata, [this.sets]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.sets); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/VersionRange.ts b/src/slang-nodes/VersionRange.ts index 5920b123a..968a69007 100644 --- a/src/slang-nodes/VersionRange.ts +++ b/src/slang-nodes/VersionRange.ts @@ -1,32 +1,25 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { VersionLiteral } from './VersionLiteral.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class VersionRange implements SlangNode { +export class VersionRange extends SlangNode { readonly kind = NonterminalKind.VersionRange; - comments; - - loc; - start: VersionLiteral; end: VersionLiteral; constructor(ast: ast.VersionRange) { - let metadata = getNodeMetadata(ast); + super(ast); this.start = new VersionLiteral(ast.start); this.end = new VersionLiteral(ast.end); - metadata = updateMetadata(metadata, [this.start, this.end]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.start, this.end); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/VersionTerm.ts b/src/slang-nodes/VersionTerm.ts index 3208cb400..bdba3ee88 100644 --- a/src/slang-nodes/VersionTerm.ts +++ b/src/slang-nodes/VersionTerm.ts @@ -1,35 +1,28 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { VersionOperator } from './VersionOperator.js'; import { VersionLiteral } from './VersionLiteral.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class VersionTerm implements SlangNode { +export class VersionTerm extends SlangNode { readonly kind = NonterminalKind.VersionTerm; - comments; - - loc; - operator?: VersionOperator; literal: VersionLiteral; constructor(ast: ast.VersionTerm) { - let metadata = getNodeMetadata(ast); + super(ast); if (ast.operator) { this.operator = new VersionOperator(ast.operator); } this.literal = new VersionLiteral(ast.literal); - metadata = updateMetadata(metadata, [this.operator, this.literal]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.operator, this.literal); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/WhileStatement.ts b/src/slang-nodes/WhileStatement.ts index 28c061389..f303b5ce1 100644 --- a/src/slang-nodes/WhileStatement.ts +++ b/src/slang-nodes/WhileStatement.ts @@ -1,38 +1,31 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedItem } from '../slang-printers/print-separated-item.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { Expression } from './Expression.js'; import { Statement } from './Statement.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { group, indent, line } = doc.builders; -export class WhileStatement implements SlangNode { +export class WhileStatement extends SlangNode { readonly kind = NonterminalKind.WhileStatement; - comments; - - loc; - condition: Expression; body: Statement; constructor(ast: ast.WhileStatement, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.condition = new Expression(ast.condition, options); this.body = new Statement(ast.body, options); - metadata = updateMetadata(metadata, [this.condition, this.body]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.condition, this.body); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulArguments.ts b/src/slang-nodes/YulArguments.ts index 82a61a94c..69a6539d5 100644 --- a/src/slang-nodes/YulArguments.ts +++ b/src/slang-nodes/YulArguments.ts @@ -1,31 +1,24 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulExpression } from './YulExpression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class YulArguments implements SlangNode { +export class YulArguments extends SlangNode { readonly kind = NonterminalKind.YulArguments; - comments; - - loc; - items: YulExpression[]; constructor(ast: ast.YulArguments, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new YulExpression(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulAssignmentOperator.ts b/src/slang-nodes/YulAssignmentOperator.ts index adbe53147..ac6be165a 100644 --- a/src/slang-nodes/YulAssignmentOperator.ts +++ b/src/slang-nodes/YulAssignmentOperator.ts @@ -1,35 +1,25 @@ import { NonterminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulColonAndEqual } from './YulColonAndEqual.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class YulAssignmentOperator implements SlangNode { +export class YulAssignmentOperator extends SlangNode { readonly kind = NonterminalKind.YulAssignmentOperator; - comments; - - loc; - variant: YulColonAndEqual | string; constructor(ast: ast.YulAssignmentOperator) { - let metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant instanceof TerminalNode ? ast.variant.unparse() : new YulColonAndEqual(ast.variant); - metadata = updateMetadata( - metadata, - typeof this.variant === 'string' ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (typeof this.variant !== 'string') this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulBlock.ts b/src/slang-nodes/YulBlock.ts index 89947e7a4..c8dfdf147 100644 --- a/src/slang-nodes/YulBlock.ts +++ b/src/slang-nodes/YulBlock.ts @@ -1,30 +1,23 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulStatements } from './YulStatements.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class YulBlock implements SlangNode { +export class YulBlock extends SlangNode { readonly kind = NonterminalKind.YulBlock; - comments; - - loc; - statements: YulStatements; constructor(ast: ast.YulBlock, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.statements = new YulStatements(ast.statements, options); - metadata = updateMetadata(metadata, [this.statements]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.statements); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulBreakStatement.ts b/src/slang-nodes/YulBreakStatement.ts index 36b393efd..96a48843c 100644 --- a/src/slang-nodes/YulBreakStatement.ts +++ b/src/slang-nodes/YulBreakStatement.ts @@ -1,22 +1,14 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { Doc } from 'prettier'; -import type { SlangNode } from '../types.d.ts'; -export class YulBreakStatement implements SlangNode { +export class YulBreakStatement extends SlangNode { readonly kind = NonterminalKind.YulBreakStatement; - comments; - - loc; - constructor(ast: ast.YulBreakStatement) { - const metadata = getNodeMetadata(ast); - - this.comments = metadata.comments; - this.loc = metadata.loc; + super(ast); } print(): Doc { diff --git a/src/slang-nodes/YulColonAndEqual.ts b/src/slang-nodes/YulColonAndEqual.ts index df6109356..3e9f49d2f 100644 --- a/src/slang-nodes/YulColonAndEqual.ts +++ b/src/slang-nodes/YulColonAndEqual.ts @@ -1,22 +1,14 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { Doc } from 'prettier'; -import type { SlangNode } from '../types.d.ts'; -export class YulColonAndEqual implements SlangNode { +export class YulColonAndEqual extends SlangNode { readonly kind = NonterminalKind.YulColonAndEqual; - comments; - - loc; - constructor(ast: ast.YulColonAndEqual) { - const metadata = getNodeMetadata(ast); - - this.comments = metadata.comments; - this.loc = metadata.loc; + super(ast); } print(): Doc { diff --git a/src/slang-nodes/YulContinueStatement.ts b/src/slang-nodes/YulContinueStatement.ts index 3ff4bae62..93bbd3eb2 100644 --- a/src/slang-nodes/YulContinueStatement.ts +++ b/src/slang-nodes/YulContinueStatement.ts @@ -1,22 +1,14 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { Doc } from 'prettier'; -import type { SlangNode } from '../types.d.ts'; -export class YulContinueStatement implements SlangNode { +export class YulContinueStatement extends SlangNode { readonly kind = NonterminalKind.YulContinueStatement; - comments; - - loc; - constructor(ast: ast.YulContinueStatement) { - const metadata = getNodeMetadata(ast); - - this.comments = metadata.comments; - this.loc = metadata.loc; + super(ast); } print(): Doc { diff --git a/src/slang-nodes/YulDefaultCase.ts b/src/slang-nodes/YulDefaultCase.ts index 06e7280f8..0ba6a9389 100644 --- a/src/slang-nodes/YulDefaultCase.ts +++ b/src/slang-nodes/YulDefaultCase.ts @@ -1,30 +1,23 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulBlock } from './YulBlock.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class YulDefaultCase implements SlangNode { +export class YulDefaultCase extends SlangNode { readonly kind = NonterminalKind.YulDefaultCase; - comments; - - loc; - body: YulBlock; constructor(ast: ast.YulDefaultCase, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.body = new YulBlock(ast.body, options); - metadata = updateMetadata(metadata, [this.body]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.body); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulEqualAndColon.ts b/src/slang-nodes/YulEqualAndColon.ts index a1a1ed2de..eac4d384d 100644 --- a/src/slang-nodes/YulEqualAndColon.ts +++ b/src/slang-nodes/YulEqualAndColon.ts @@ -1,22 +1,14 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { Doc } from 'prettier'; -import type { SlangNode } from '../types.d.ts'; -export class YulEqualAndColon implements SlangNode { +export class YulEqualAndColon extends SlangNode { readonly kind = NonterminalKind.YulEqualAndColon; - comments; - - loc; - constructor(ast: ast.YulEqualAndColon) { - const metadata = getNodeMetadata(ast); - - this.comments = metadata.comments; - this.loc = metadata.loc; + super(ast); } print(): Doc { diff --git a/src/slang-nodes/YulExpression.ts b/src/slang-nodes/YulExpression.ts index 4b812654d..55dceb456 100644 --- a/src/slang-nodes/YulExpression.ts +++ b/src/slang-nodes/YulExpression.ts @@ -1,5 +1,5 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulFunctionCallExpression } from './YulFunctionCallExpression.js'; import { YulLiteral } from './YulLiteral.js'; import { YulPath } from './YulPath.js'; @@ -7,19 +7,15 @@ import { YulPath } from './YulPath.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class YulExpression implements SlangNode { +export class YulExpression extends SlangNode { readonly kind = NonterminalKind.YulExpression; - comments; - - loc; - variant: YulFunctionCallExpression | YulLiteral | YulPath; constructor(ast: ast.YulExpression, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); switch (ast.variant.cst.kind) { case NonterminalKind.YulFunctionCallExpression: @@ -38,10 +34,7 @@ export class YulExpression implements SlangNode { throw new Error(`Unexpected variant: ${ast.variant.cst.kind}`); } - metadata = updateMetadata(metadata, [this.variant]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulForStatement.ts b/src/slang-nodes/YulForStatement.ts index eb4da4547..1bd85479a 100644 --- a/src/slang-nodes/YulForStatement.ts +++ b/src/slang-nodes/YulForStatement.ts @@ -1,23 +1,19 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { doc } from 'prettier'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulBlock } from './YulBlock.js'; import { YulExpression } from './YulExpression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { join } = doc.builders; -export class YulForStatement implements SlangNode { +export class YulForStatement extends SlangNode { readonly kind = NonterminalKind.YulForStatement; - comments; - - loc; - initialization: YulBlock; condition: YulExpression; @@ -27,22 +23,19 @@ export class YulForStatement implements SlangNode { body: YulBlock; constructor(ast: ast.YulForStatement, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.initialization = new YulBlock(ast.initialization, options); this.condition = new YulExpression(ast.condition, options); this.iterator = new YulBlock(ast.iterator, options); this.body = new YulBlock(ast.body, options); - metadata = updateMetadata(metadata, [ + this.updateMetadata( this.initialization, this.condition, this.iterator, this.body - ]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + ); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulFunctionCallExpression.ts b/src/slang-nodes/YulFunctionCallExpression.ts index 14db27a8c..43dc99a8d 100644 --- a/src/slang-nodes/YulFunctionCallExpression.ts +++ b/src/slang-nodes/YulFunctionCallExpression.ts @@ -1,20 +1,16 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulExpression } from './YulExpression.js'; import { YulArguments } from './YulArguments.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class YulFunctionCallExpression implements SlangNode { +export class YulFunctionCallExpression extends SlangNode { readonly kind = NonterminalKind.YulFunctionCallExpression; - comments; - - loc; - operand: YulExpression; arguments: YulArguments; @@ -23,15 +19,12 @@ export class YulFunctionCallExpression implements SlangNode { ast: ast.YulFunctionCallExpression, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.operand = new YulExpression(ast.operand, options); this.arguments = new YulArguments(ast.arguments, options); - metadata = updateMetadata(metadata, [this.operand, this.arguments]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.operand, this.arguments); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulFunctionDefinition.ts b/src/slang-nodes/YulFunctionDefinition.ts index f01e5f7f7..dbc381e94 100644 --- a/src/slang-nodes/YulFunctionDefinition.ts +++ b/src/slang-nodes/YulFunctionDefinition.ts @@ -1,5 +1,5 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulIdentifier } from './YulIdentifier.js'; import { YulParametersDeclaration } from './YulParametersDeclaration.js'; import { YulReturnsDeclaration } from './YulReturnsDeclaration.js'; @@ -8,15 +8,11 @@ import { YulBlock } from './YulBlock.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class YulFunctionDefinition implements SlangNode { +export class YulFunctionDefinition extends SlangNode { readonly kind = NonterminalKind.YulFunctionDefinition; - comments; - - loc; - name: YulIdentifier; parameters: YulParametersDeclaration; @@ -26,7 +22,7 @@ export class YulFunctionDefinition implements SlangNode { body: YulBlock; constructor(ast: ast.YulFunctionDefinition, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.name = new YulIdentifier(ast.name); this.parameters = new YulParametersDeclaration(ast.parameters); @@ -35,14 +31,7 @@ export class YulFunctionDefinition implements SlangNode { } this.body = new YulBlock(ast.body, options); - metadata = updateMetadata(metadata, [ - this.parameters, - this.returns, - this.body - ]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.parameters, this.returns, this.body); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulIdentifier.ts b/src/slang-nodes/YulIdentifier.ts index 0011831a3..fac6a0d1a 100644 --- a/src/slang-nodes/YulIdentifier.ts +++ b/src/slang-nodes/YulIdentifier.ts @@ -1,26 +1,17 @@ import { TerminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type { Doc } from 'prettier'; -import type { Location, SlangNode } from '../types.d.ts'; -import type { Comment } from './types.d.ts'; -export class YulIdentifier implements SlangNode { +export class YulIdentifier extends SlangNode { readonly kind = TerminalKind.YulIdentifier; - comments: Comment[]; - - loc: Location; - value: string; constructor(ast: TerminalNode) { - const metadata = getNodeMetadata(ast); + super(ast); this.value = ast.unparse(); - - this.comments = metadata.comments; - this.loc = metadata.loc; } print(): Doc { diff --git a/src/slang-nodes/YulIfStatement.ts b/src/slang-nodes/YulIfStatement.ts index 791281f5a..3b73da5b9 100644 --- a/src/slang-nodes/YulIfStatement.ts +++ b/src/slang-nodes/YulIfStatement.ts @@ -1,34 +1,27 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulExpression } from './YulExpression.js'; import { YulBlock } from './YulBlock.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class YulIfStatement implements SlangNode { +export class YulIfStatement extends SlangNode { readonly kind = NonterminalKind.YulIfStatement; - comments; - - loc; - condition: YulExpression; body: YulBlock; constructor(ast: ast.YulIfStatement, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.condition = new YulExpression(ast.condition, options); this.body = new YulBlock(ast.body, options); - metadata = updateMetadata(metadata, [this.condition, this.body]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.condition, this.body); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulLabel.ts b/src/slang-nodes/YulLabel.ts index 3abd04a17..12e12b1df 100644 --- a/src/slang-nodes/YulLabel.ts +++ b/src/slang-nodes/YulLabel.ts @@ -1,30 +1,23 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulIdentifier } from './YulIdentifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { dedent, line } = doc.builders; -export class YulLabel implements SlangNode { +export class YulLabel extends SlangNode { readonly kind = NonterminalKind.YulLabel; - comments; - - loc; - label: YulIdentifier; constructor(ast: ast.YulLabel) { - const metadata = getNodeMetadata(ast); + super(ast); this.label = new YulIdentifier(ast.label); - - this.comments = metadata.comments; - this.loc = metadata.loc; } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulLeaveStatement.ts b/src/slang-nodes/YulLeaveStatement.ts index 9d0c70b03..eccf192b8 100644 --- a/src/slang-nodes/YulLeaveStatement.ts +++ b/src/slang-nodes/YulLeaveStatement.ts @@ -1,22 +1,14 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { Doc } from 'prettier'; -import type { SlangNode } from '../types.d.ts'; -export class YulLeaveStatement implements SlangNode { +export class YulLeaveStatement extends SlangNode { readonly kind = NonterminalKind.YulLeaveStatement; - comments; - - loc; - constructor(ast: ast.YulLeaveStatement) { - const metadata = getNodeMetadata(ast); - - this.comments = metadata.comments; - this.loc = metadata.loc; + super(ast); } print(): Doc { diff --git a/src/slang-nodes/YulLiteral.ts b/src/slang-nodes/YulLiteral.ts index 15afb5af4..eeb03505d 100644 --- a/src/slang-nodes/YulLiteral.ts +++ b/src/slang-nodes/YulLiteral.ts @@ -1,24 +1,20 @@ import { NonterminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { HexStringLiteral } from './HexStringLiteral.js'; import { StringLiteral } from './StringLiteral.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class YulLiteral implements SlangNode { +export class YulLiteral extends SlangNode { readonly kind = NonterminalKind.YulLiteral; - comments; - - loc; - variant: HexStringLiteral | StringLiteral | string; constructor(ast: ast.YulLiteral, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); if (ast.variant instanceof TerminalNode) { this.variant = ast.variant.unparse(); @@ -41,13 +37,7 @@ export class YulLiteral implements SlangNode { } } - metadata = updateMetadata( - metadata, - typeof this.variant === 'string' ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (typeof this.variant !== 'string') this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulParameters.ts b/src/slang-nodes/YulParameters.ts index 703950f32..8492a6352 100644 --- a/src/slang-nodes/YulParameters.ts +++ b/src/slang-nodes/YulParameters.ts @@ -1,28 +1,21 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulIdentifier } from './YulIdentifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class YulParameters implements SlangNode { +export class YulParameters extends SlangNode { readonly kind = NonterminalKind.YulParameters; - comments; - - loc; - items: YulIdentifier[]; constructor(ast: ast.YulParameters) { - const metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new YulIdentifier(item)); - - this.comments = metadata.comments; - this.loc = metadata.loc; } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulParametersDeclaration.ts b/src/slang-nodes/YulParametersDeclaration.ts index d52920a03..1f283930f 100644 --- a/src/slang-nodes/YulParametersDeclaration.ts +++ b/src/slang-nodes/YulParametersDeclaration.ts @@ -1,29 +1,22 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulParameters } from './YulParameters.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class YulParametersDeclaration implements SlangNode { +export class YulParametersDeclaration extends SlangNode { readonly kind = NonterminalKind.YulParametersDeclaration; - comments; - - loc; - parameters: YulParameters; constructor(ast: ast.YulParametersDeclaration) { - let metadata = getNodeMetadata(ast); + super(ast); this.parameters = new YulParameters(ast.parameters); - metadata = updateMetadata(metadata, [this.parameters]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.parameters); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulPath.ts b/src/slang-nodes/YulPath.ts index a24cb49fb..6719693f8 100644 --- a/src/slang-nodes/YulPath.ts +++ b/src/slang-nodes/YulPath.ts @@ -1,30 +1,23 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { doc } from 'prettier'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulIdentifier } from './YulIdentifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { join } = doc.builders; -export class YulPath implements SlangNode { +export class YulPath extends SlangNode { readonly kind = NonterminalKind.YulPath; - comments; - - loc; - items: YulIdentifier[]; constructor(ast: ast.YulPath) { - const metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new YulIdentifier(item)); - - this.comments = metadata.comments; - this.loc = metadata.loc; } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulPaths.ts b/src/slang-nodes/YulPaths.ts index 50d463039..22161d5a7 100644 --- a/src/slang-nodes/YulPaths.ts +++ b/src/slang-nodes/YulPaths.ts @@ -1,32 +1,25 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { doc } from 'prettier'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulPath } from './YulPath.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { join } = doc.builders; -export class YulPaths implements SlangNode { +export class YulPaths extends SlangNode { readonly kind = NonterminalKind.YulPaths; - comments; - - loc; - items: YulPath[]; constructor(ast: ast.YulPaths) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new YulPath(item)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulReturnsDeclaration.ts b/src/slang-nodes/YulReturnsDeclaration.ts index 1815c3895..69351ef2e 100644 --- a/src/slang-nodes/YulReturnsDeclaration.ts +++ b/src/slang-nodes/YulReturnsDeclaration.ts @@ -1,33 +1,26 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedItem } from '../slang-printers/print-separated-item.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulVariableNames } from './YulVariableNames.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line } = doc.builders; -export class YulReturnsDeclaration implements SlangNode { +export class YulReturnsDeclaration extends SlangNode { readonly kind = NonterminalKind.YulReturnsDeclaration; - comments; - - loc; - variables: YulVariableNames; constructor(ast: ast.YulReturnsDeclaration) { - let metadata = getNodeMetadata(ast); + super(ast); this.variables = new YulVariableNames(ast.variables); - metadata = updateMetadata(metadata, [this.variables]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variables); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulStackAssignmentOperator.ts b/src/slang-nodes/YulStackAssignmentOperator.ts index 68fedcca1..b14b28065 100644 --- a/src/slang-nodes/YulStackAssignmentOperator.ts +++ b/src/slang-nodes/YulStackAssignmentOperator.ts @@ -1,35 +1,25 @@ import { NonterminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulEqualAndColon } from './YulEqualAndColon.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class YulStackAssignmentOperator implements SlangNode { +export class YulStackAssignmentOperator extends SlangNode { readonly kind = NonterminalKind.YulStackAssignmentOperator; - comments; - - loc; - variant: YulEqualAndColon | string; constructor(ast: ast.YulStackAssignmentOperator) { - let metadata = getNodeMetadata(ast); + super(ast); this.variant = ast.variant instanceof TerminalNode ? ast.variant.unparse() : new YulEqualAndColon(ast.variant); - metadata = updateMetadata( - metadata, - typeof this.variant === 'string' ? [] : [this.variant] - ); - - this.comments = metadata.comments; - this.loc = metadata.loc; + if (typeof this.variant !== 'string') this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulStackAssignmentStatement.ts b/src/slang-nodes/YulStackAssignmentStatement.ts index c1da83c53..1b0cd4cc1 100644 --- a/src/slang-nodes/YulStackAssignmentStatement.ts +++ b/src/slang-nodes/YulStackAssignmentStatement.ts @@ -1,37 +1,30 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { doc } from 'prettier'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { printSeparatedItem } from '../slang-printers/print-separated-item.js'; +import { SlangNode } from './SlangNode.js'; import { YulStackAssignmentOperator } from './YulStackAssignmentOperator.js'; import { YulIdentifier } from './YulIdentifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line } = doc.builders; -export class YulStackAssignmentStatement implements SlangNode { +export class YulStackAssignmentStatement extends SlangNode { readonly kind = NonterminalKind.YulStackAssignmentStatement; - comments; - - loc; - assignment: YulStackAssignmentOperator; variable: YulIdentifier; constructor(ast: ast.YulStackAssignmentStatement) { - let metadata = getNodeMetadata(ast); + super(ast); this.assignment = new YulStackAssignmentOperator(ast.assignment); this.variable = new YulIdentifier(ast.variable); - metadata = updateMetadata(metadata, [this.assignment]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.assignment); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulStatement.ts b/src/slang-nodes/YulStatement.ts index 054a71046..100a406b1 100644 --- a/src/slang-nodes/YulStatement.ts +++ b/src/slang-nodes/YulStatement.ts @@ -1,5 +1,5 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulBlock } from './YulBlock.js'; import { YulFunctionDefinition } from './YulFunctionDefinition.js'; import { YulVariableDeclarationStatement } from './YulVariableDeclarationStatement.js'; @@ -17,15 +17,11 @@ import { YulExpression } from './YulExpression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class YulStatement implements SlangNode { +export class YulStatement extends SlangNode { readonly kind = NonterminalKind.YulStatement; - comments; - - loc; - variant: | YulBlock | YulFunctionDefinition @@ -42,7 +38,7 @@ export class YulStatement implements SlangNode { | YulExpression; constructor(ast: ast.YulStatement, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); switch (ast.variant.cst.kind) { case NonterminalKind.YulBlock: @@ -117,10 +113,7 @@ export class YulStatement implements SlangNode { throw new Error(`Unexpected variant: ${ast.variant.cst.kind}`); } - metadata = updateMetadata(metadata, [this.variant]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulStatements.ts b/src/slang-nodes/YulStatements.ts index 082a36008..516a0485e 100644 --- a/src/slang-nodes/YulStatements.ts +++ b/src/slang-nodes/YulStatements.ts @@ -3,34 +3,27 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { printSeparatedItem } from '../slang-printers/print-separated-item.js'; import { printComments } from '../slang-printers/print-comments.js'; import { printPreservingEmptyLines } from '../slang-printers/print-preserving-empty-lines.js'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulStatement } from './YulStatement.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { hardline } = doc.builders; -export class YulStatements implements SlangNode { +export class YulStatements extends SlangNode { readonly kind = NonterminalKind.YulStatements; - comments; - - loc; - items: YulStatement[]; constructor(ast: ast.YulStatements, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new YulStatement(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print( diff --git a/src/slang-nodes/YulSwitchCase.ts b/src/slang-nodes/YulSwitchCase.ts index 30096cb70..f881c7093 100644 --- a/src/slang-nodes/YulSwitchCase.ts +++ b/src/slang-nodes/YulSwitchCase.ts @@ -1,24 +1,20 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulDefaultCase } from './YulDefaultCase.js'; import { YulValueCase } from './YulValueCase.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class YulSwitchCase implements SlangNode { +export class YulSwitchCase extends SlangNode { readonly kind = NonterminalKind.YulSwitchCase; - comments; - - loc; - variant: YulDefaultCase | YulValueCase; constructor(ast: ast.YulSwitchCase, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); switch (ast.variant.cst.kind) { case NonterminalKind.YulDefaultCase: @@ -37,10 +33,7 @@ export class YulSwitchCase implements SlangNode { throw new Error(`Unexpected variant: ${ast.variant.cst.kind}`); } - metadata = updateMetadata(metadata, [this.variant]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variant); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulSwitchCases.ts b/src/slang-nodes/YulSwitchCases.ts index 44dffb224..b5510c929 100644 --- a/src/slang-nodes/YulSwitchCases.ts +++ b/src/slang-nodes/YulSwitchCases.ts @@ -1,33 +1,26 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulSwitchCase } from './YulSwitchCase.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { hardline, join } = doc.builders; -export class YulSwitchCases implements SlangNode { +export class YulSwitchCases extends SlangNode { readonly kind = NonterminalKind.YulSwitchCases; - comments; - - loc; - items: YulSwitchCase[]; constructor(ast: ast.YulSwitchCases, options: ParserOptions) { - let metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new YulSwitchCase(item, options)); - metadata = updateMetadata(metadata, [this.items]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.items); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulSwitchStatement.ts b/src/slang-nodes/YulSwitchStatement.ts index 20efea326..0cb4686e3 100644 --- a/src/slang-nodes/YulSwitchStatement.ts +++ b/src/slang-nodes/YulSwitchStatement.ts @@ -1,37 +1,30 @@ import { doc } from 'prettier'; import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulExpression } from './YulExpression.js'; import { YulSwitchCases } from './YulSwitchCases.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { hardline } = doc.builders; -export class YulSwitchStatement implements SlangNode { +export class YulSwitchStatement extends SlangNode { readonly kind = NonterminalKind.YulSwitchStatement; - comments; - - loc; - expression: YulExpression; cases: YulSwitchCases; constructor(ast: ast.YulSwitchStatement, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.expression = new YulExpression(ast.expression, options); this.cases = new YulSwitchCases(ast.cases, options); - metadata = updateMetadata(metadata, [this.expression, this.cases]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.expression, this.cases); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulValueCase.ts b/src/slang-nodes/YulValueCase.ts index 34a299662..536832178 100644 --- a/src/slang-nodes/YulValueCase.ts +++ b/src/slang-nodes/YulValueCase.ts @@ -1,34 +1,27 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulLiteral } from './YulLiteral.js'; import { YulBlock } from './YulBlock.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class YulValueCase implements SlangNode { +export class YulValueCase extends SlangNode { readonly kind = NonterminalKind.YulValueCase; - comments; - - loc; - value: YulLiteral; body: YulBlock; constructor(ast: ast.YulValueCase, options: ParserOptions) { - let metadata = getNodeMetadata(ast); + super(ast); this.value = new YulLiteral(ast.value, options); this.body = new YulBlock(ast.body, options); - metadata = updateMetadata(metadata, [this.value, this.body]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.value, this.body); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulVariableAssignmentStatement.ts b/src/slang-nodes/YulVariableAssignmentStatement.ts index f71d878df..1ca5c0771 100644 --- a/src/slang-nodes/YulVariableAssignmentStatement.ts +++ b/src/slang-nodes/YulVariableAssignmentStatement.ts @@ -1,6 +1,6 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { doc } from 'prettier'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulPaths } from './YulPaths.js'; import { YulAssignmentOperator } from './YulAssignmentOperator.js'; import { YulExpression } from './YulExpression.js'; @@ -8,17 +8,13 @@ import { YulExpression } from './YulExpression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { join } = doc.builders; -export class YulVariableAssignmentStatement implements SlangNode { +export class YulVariableAssignmentStatement extends SlangNode { readonly kind = NonterminalKind.YulVariableAssignmentStatement; - comments; - - loc; - variables: YulPaths; assignment: YulAssignmentOperator; @@ -29,20 +25,13 @@ export class YulVariableAssignmentStatement implements SlangNode { ast: ast.YulVariableAssignmentStatement, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.variables = new YulPaths(ast.variables); this.assignment = new YulAssignmentOperator(ast.assignment); this.expression = new YulExpression(ast.expression, options); - metadata = updateMetadata(metadata, [ - this.variables, - this.assignment, - this.expression - ]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.variables, this.assignment, this.expression); } print( diff --git a/src/slang-nodes/YulVariableDeclarationStatement.ts b/src/slang-nodes/YulVariableDeclarationStatement.ts index a2bf6dedd..ab449abb2 100644 --- a/src/slang-nodes/YulVariableDeclarationStatement.ts +++ b/src/slang-nodes/YulVariableDeclarationStatement.ts @@ -1,21 +1,17 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; import { joinExisting } from '../slang-utils/join-existing.js'; +import { SlangNode } from './SlangNode.js'; import { YulVariableDeclarationValue } from './YulVariableDeclarationValue.js'; import { YulVariableNames } from './YulVariableNames.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class YulVariableDeclarationStatement implements SlangNode { +export class YulVariableDeclarationStatement extends SlangNode { readonly kind = NonterminalKind.YulVariableDeclarationStatement; - comments; - - loc; - variables: YulVariableNames; value?: YulVariableDeclarationValue; @@ -24,17 +20,14 @@ export class YulVariableDeclarationStatement implements SlangNode { ast: ast.YulVariableDeclarationStatement, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.variables = new YulVariableNames(ast.variables); if (ast.value) { this.value = new YulVariableDeclarationValue(ast.value, options); } - metadata = updateMetadata(metadata, [this.value]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.value); } print( diff --git a/src/slang-nodes/YulVariableDeclarationValue.ts b/src/slang-nodes/YulVariableDeclarationValue.ts index 01f7c416c..008005481 100644 --- a/src/slang-nodes/YulVariableDeclarationValue.ts +++ b/src/slang-nodes/YulVariableDeclarationValue.ts @@ -1,20 +1,16 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulAssignmentOperator } from './YulAssignmentOperator.js'; import { YulExpression } from './YulExpression.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc, ParserOptions } from 'prettier'; import type { AstNode } from './types.d.ts'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; -export class YulVariableDeclarationValue implements SlangNode { +export class YulVariableDeclarationValue extends SlangNode { readonly kind = NonterminalKind.YulVariableDeclarationValue; - comments; - - loc; - assignment: YulAssignmentOperator; expression: YulExpression; @@ -23,15 +19,12 @@ export class YulVariableDeclarationValue implements SlangNode { ast: ast.YulVariableDeclarationValue, options: ParserOptions ) { - let metadata = getNodeMetadata(ast); + super(ast); this.assignment = new YulAssignmentOperator(ast.assignment); this.expression = new YulExpression(ast.expression, options); - metadata = updateMetadata(metadata, [this.assignment, this.expression]); - - this.comments = metadata.comments; - this.loc = metadata.loc; + this.updateMetadata(this.assignment, this.expression); } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-nodes/YulVariableNames.ts b/src/slang-nodes/YulVariableNames.ts index 9e7ac521b..6b2ae7626 100644 --- a/src/slang-nodes/YulVariableNames.ts +++ b/src/slang-nodes/YulVariableNames.ts @@ -1,31 +1,24 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { doc } from 'prettier'; import { printSeparatedList } from '../slang-printers/print-separated-list.js'; -import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { SlangNode } from './SlangNode.js'; import { YulIdentifier } from './YulIdentifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; -import type { PrintFunction, SlangNode } from '../types.d.ts'; +import type { PrintFunction } from '../types.d.ts'; const { line } = doc.builders; -export class YulVariableNames implements SlangNode { +export class YulVariableNames extends SlangNode { readonly kind = NonterminalKind.YulVariableNames; - comments; - - loc; - items: YulIdentifier[]; constructor(ast: ast.YulVariableNames) { - const metadata = getNodeMetadata(ast, true); + super(ast, true); this.items = ast.items.map((item) => new YulIdentifier(item)); - - this.comments = metadata.comments; - this.loc = metadata.loc; } print(path: AstPath, print: PrintFunction): Doc { diff --git a/src/slang-utils/metadata.ts b/src/slang-utils/metadata.ts deleted file mode 100644 index f99d64f89..000000000 --- a/src/slang-utils/metadata.ts +++ /dev/null @@ -1,168 +0,0 @@ -import { TerminalKind, TerminalNode } from '@nomicfoundation/slang/cst'; -import { createKindCheckFunction } from './create-kind-check-function.js'; -import { isComment } from './is-comment.js'; -import { MultiLineComment } from '../slang-nodes/MultiLineComment.js'; -import { MultiLineNatSpecComment } from '../slang-nodes/MultiLineNatSpecComment.js'; -import { SingleLineComment } from '../slang-nodes/SingleLineComment.js'; -import { SingleLineNatSpecComment } from '../slang-nodes/SingleLineNatSpecComment.js'; - -import type { Node } from '@nomicfoundation/slang/cst'; -import type { Comment, StrictAstNode } from '../slang-nodes/types.d.ts'; -import type { Metadata, SlangAstNode } from '../types.d.ts'; - -const isCommentOrWhiteSpace = createKindCheckFunction([ - TerminalKind.MultiLineComment, - TerminalKind.MultiLineNatSpecComment, - TerminalKind.SingleLineComment, - TerminalKind.SingleLineNatSpecComment, - TerminalKind.EndOfLine, - TerminalKind.Whitespace -]); - -const offsets = new Map(); -export function clearOffsets(): void { - offsets.clear(); -} - -function getLeadingOffset(children: Node[]): number { - let offset = 0; - for (const child of children) { - if (child.isNonterminalNode() || !isCommentOrWhiteSpace(child)) { - // The node's content starts when we find the first non-terminal token, - // or if we find a non-comment, non-whitespace token. - return offset; - } - offset += child.textLength.utf16; - } - return offset; -} - -export function getNodeMetadata( - ast: SlangAstNode | TerminalNode, - enclosePeripheralComments = false -): Metadata { - if (ast instanceof TerminalNode) { - const offset = offsets.get(ast.id) || 0; - return { - comments: [], - loc: { - start: offset, - end: offset + ast.textLength.utf16, - leadingOffset: 0, - trailingOffset: 0 - } - }; - } - const { cst: parent } = ast; - const children = parent.children().map(({ node }) => node); - - const initialOffset = offsets.get(parent.id) || 0; - let offset = initialOffset; - const comments: Comment[] = []; - - for (const child of children) { - const { id, kind, textLength } = child; - if (child.isNonterminalNode()) { - offsets.set(id, offset); - } else { - if (isComment(child)) { - offsets.set(id, offset); - } - switch (kind) { - // Since the fetching the comments and calculating offsets are both done - // as we iterate over the children and the comment also depends on the - // offset, it's hard to separate these responsibilities into different - // functions without doing the iteration twice. - case TerminalKind.MultiLineComment: - comments.push(new MultiLineComment(child)); - break; - case TerminalKind.MultiLineNatSpecComment: - comments.push(new MultiLineNatSpecComment(child)); - break; - case TerminalKind.SingleLineComment: - comments.push(new SingleLineComment(child)); - break; - case TerminalKind.SingleLineNatSpecComment: - comments.push(new SingleLineNatSpecComment(child)); - break; - case TerminalKind.Identifier: - case TerminalKind.YulIdentifier: - // Identifiers usually are user provided names for variables, - // functions, etc... - // Since a user can add comments to this section of the code as well, - // we need to track the offsets. - offsets.set(id, offset); - break; - } - } - - offset += textLength.utf16; - } - - const [leadingOffset, trailingOffset] = enclosePeripheralComments - ? [0, 0] - : [getLeadingOffset(children), getLeadingOffset(children.reverse())]; - - const loc = { - start: initialOffset + leadingOffset, - end: offset - trailingOffset, - leadingOffset, - trailingOffset - }; - - return { comments, loc }; -} - -function collectComments( - comments: Comment[], - node: StrictAstNode | StrictAstNode[] | undefined -): Comment[] { - if (node) { - if (Array.isArray(node)) { - return node.reduce(collectComments, comments); - } - if (node.comments.length > 0) { - comments.push(...node.comments.splice(0)); - } - } - return comments; -} - -export function updateMetadata( - { comments, loc }: Metadata, - childNodes: (StrictAstNode | StrictAstNode[] | undefined)[] -): Metadata { - // Collect comments - comments = childNodes.reduce(collectComments, comments); - - // calculate correct loc object - if (loc.leadingOffset === 0) { - for (const childNode of childNodes) { - if (typeof childNode === 'undefined' || Array.isArray(childNode)) - continue; - const { leadingOffset, start } = childNode.loc; - - if (start - leadingOffset === loc.start) { - loc.leadingOffset = leadingOffset; - loc.start += leadingOffset; - break; - } - } - } - - if (loc.trailingOffset === 0) { - for (const childNode of childNodes.reverse()) { - if (typeof childNode === 'undefined' || Array.isArray(childNode)) - continue; - const { trailingOffset, end } = childNode.loc; - - if (end + trailingOffset === loc.end) { - loc.trailingOffset = trailingOffset; - loc.end -= trailingOffset; - break; - } - } - } - - return { comments, loc }; -} diff --git a/src/slangPrinter.ts b/src/slangPrinter.ts index 524f20c5e..11de3e62a 100644 --- a/src/slangPrinter.ts +++ b/src/slangPrinter.ts @@ -24,13 +24,14 @@ function ignoreComments(path: AstPath): void { let key: keyof StrictAstNode; for (key in node) { switch (key) { - // We ignore `kind`, `loc`, and comments since these are added by the - // parser + // We ignore `kind`, `loc`, and `comments` since these are added by the + // parser. `updateMetadata` is an internal function. case 'kind': case 'loc': case 'print': + case 'updateMetadata': break; - // The key `comments` will contain every comment for this node + // The key `comments` will contain every comment for this node. case 'comments': path.each((commentPath) => (commentPath.node.printed = true), key); break; diff --git a/src/slangSolidityParser.ts b/src/slangSolidityParser.ts index cb40ce145..e52da506f 100644 --- a/src/slangSolidityParser.ts +++ b/src/slangSolidityParser.ts @@ -1,6 +1,6 @@ // https://prettier.io/docs/en/plugins.html#parsers import { SourceUnit as SlangSourceUnit } from '@nomicfoundation/slang/ast'; -import { clearOffsets } from './slang-utils/metadata.js'; +import { clearOffsets } from './slang-nodes/SlangNode.js'; import { createParser } from './slang-utils/create-parser.js'; import { SourceUnit } from './slang-nodes/SourceUnit.js'; diff --git a/src/types.d.ts b/src/types.d.ts index daf0f2d4b..5193b7b15 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -1,7 +1,6 @@ -import type { NonterminalKind, TerminalKind } from '@nomicfoundation/slang/cst'; import type * as ast from '@nomicfoundation/slang/ast'; -import type { AstPath, Doc, ParserOptions } from 'prettier'; -import type { AstNode, Comment, StrictAstNode } from './slang-nodes/types.d.ts'; +import type { AstPath, Doc } from 'prettier'; +import type { AstNode } from './slang-nodes/types.d.ts'; // Adding our own options to prettier's `ParserOptions` interface. declare module 'prettier' { @@ -20,41 +19,6 @@ interface AstLocation extends Location { trailingOffset: number; } -interface BaseComment { - value: string; - loc: Location; - leading?: boolean; - trailing?: boolean; - printed?: boolean; - placement?: 'endOfLine' | 'ownLine' | 'remaining'; - precedingNode?: StrictAstNode; - enclosingNode?: StrictAstNode; - followingNode?: StrictAstNode; -} - -interface Metadata { - comments: Comment[]; - loc: AstLocation; -} - -interface SlangNode { - kind: - | NonterminalKind - | typeof TerminalKind.Identifier - | typeof TerminalKind.YulIdentifier - | typeof TerminalKind.MultiLineComment - | typeof TerminalKind.MultiLineNatSpecComment - | typeof TerminalKind.SingleLineComment - | typeof TerminalKind.SingleLineNatSpecComment; - comments?: Comment[]; - loc: AstLocation | Location; - print( - path: AstPath, - print: (path: AstPath) => Doc, - options: ParserOptions - ): Doc; -} - type PrintFunction = (path: AstPath) => Doc; // This the union of all the types in the namespace `ast`.