From 8c9e7e1c8c4596b260257cda53ff9444eef5998f Mon Sep 17 00:00:00 2001 From: Klaus Date: Tue, 28 Jan 2025 00:36:30 +1300 Subject: [PATCH] - remove YulPathComponent and using YulIdentifier - renaming parser.version to parser.languageVersion - using LanguageFacts for languageVersions --- src/slang-nodes/YulPath.ts | 12 ++++---- src/slang-nodes/YulPathComponent.ts | 30 -------------------- src/slang-nodes/types.d.ts | 2 -- src/slang-utils/create-parser.ts | 21 +++++++------- src/slang-utils/metadata.ts | 2 +- src/slangSolidityParser.ts | 6 ++-- src/types.d.ts | 1 - tests/unit/slang-utils/create-parser.test.js | 20 ++++++------- 8 files changed, 29 insertions(+), 65 deletions(-) delete mode 100644 src/slang-nodes/YulPathComponent.ts diff --git a/src/slang-nodes/YulPath.ts b/src/slang-nodes/YulPath.ts index e9613c5d..badbc830 100644 --- a/src/slang-nodes/YulPath.ts +++ b/src/slang-nodes/YulPath.ts @@ -1,6 +1,6 @@ import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata, updateMetadata } from '../slang-utils/metadata.js'; -import { YulPathComponent } from './YulPathComponent.js'; +import { getNodeMetadata } from '../slang-utils/metadata.js'; +import { YulIdentifier } from './YulIdentifier.js'; import type * as ast from '@nomicfoundation/slang/ast'; import type { AstPath, Doc } from 'prettier'; @@ -13,18 +13,16 @@ export class YulPath implements SlangNode { loc; - items: YulPathComponent[]; + items: YulIdentifier[]; separators: string[]; constructor(ast: ast.YulPath) { - let metadata = getNodeMetadata(ast, true); + const metadata = getNodeMetadata(ast, true); - this.items = ast.items.map((item) => new YulPathComponent(item)); + this.items = ast.items.map((item) => new YulIdentifier(item)); this.separators = ast.separators.map((separator) => separator.unparse()); - metadata = updateMetadata(metadata, [this.items]); - this.comments = metadata.comments; this.loc = metadata.loc; } diff --git a/src/slang-nodes/YulPathComponent.ts b/src/slang-nodes/YulPathComponent.ts deleted file mode 100644 index f4fb9701..00000000 --- a/src/slang-nodes/YulPathComponent.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { NonterminalKind } from '@nomicfoundation/slang/cst'; -import { getNodeMetadata } from '../slang-utils/metadata.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'; - -export class YulPathComponent implements SlangNode { - readonly kind = NonterminalKind.YulPathComponent; - - comments; - - loc; - - variant: YulIdentifier; - - constructor(ast: ast.YulPathComponent) { - const metadata = getNodeMetadata(ast); - - this.variant = new YulIdentifier(ast.variant); - - this.comments = metadata.comments; - this.loc = metadata.loc; - } - - print(path: AstPath, print: PrintFunction): Doc { - return path.call(print, 'variant'); - } -} diff --git a/src/slang-nodes/types.d.ts b/src/slang-nodes/types.d.ts index 0e785273..0a5f75cd 100644 --- a/src/slang-nodes/types.d.ts +++ b/src/slang-nodes/types.d.ts @@ -207,7 +207,6 @@ import type { YulLiteral } from './YulLiteral.ts'; import type { YulParameters } from './YulParameters.ts'; import type { YulParametersDeclaration } from './YulParametersDeclaration.ts'; import type { YulPath } from './YulPath.ts'; -import type { YulPathComponent } from './YulPathComponent.ts'; import type { YulPaths } from './YulPaths.ts'; import type { YulReturnsDeclaration } from './YulReturnsDeclaration.ts'; import type { YulStackAssignmentOperator } from './YulStackAssignmentOperator.ts'; @@ -410,7 +409,6 @@ export type StrictAstNode = | YulAssignmentOperator | YulSwitchCase | YulExpression - | YulPathComponent | YulBuiltInFunction | YulLiteral | SourceUnitMembers diff --git a/src/slang-utils/create-parser.ts b/src/slang-utils/create-parser.ts index 13c27258..60bfb5dd 100644 --- a/src/slang-utils/create-parser.ts +++ b/src/slang-utils/create-parser.ts @@ -1,6 +1,7 @@ import { VersionExpressionSets as SlangVersionExpressionSets } from '@nomicfoundation/slang/ast'; import { NonterminalKind, Query } from '@nomicfoundation/slang/cst'; import { Parser } from '@nomicfoundation/slang/parser'; +import { LanguageFacts } from '@nomicfoundation/slang/utils'; import { maxSatisfying, minSatisfying, @@ -15,7 +16,7 @@ import type { ParseOutput } from '@nomicfoundation/slang/parser'; import type { ParserOptions } from 'prettier'; import type { AstNode } from '../slang-nodes/types.js'; -const supportedVersions = Parser.supportedVersions(); +const supportedVersions = LanguageFacts.allVersions(); const milestoneVersions = Array.from( supportedVersions.reduce((minorRanges, version) => { @@ -31,7 +32,7 @@ const milestoneVersions = Array.from( }, []); const queries = [ - Query.parse('[VersionPragma @versionRanges [VersionExpressionSets]]') + Query.create('[VersionPragma @versionRanges [VersionExpressionSets]]') ]; let parser: Parser; @@ -42,10 +43,10 @@ export function createParser( ): [Parser, ParseOutput] { const compiler = maxSatisfying(supportedVersions, options.compiler); if (compiler) { - if (!parser || parser.version !== compiler) { + if (!parser || parser.languageVersion !== compiler) { parser = Parser.create(compiler); } - return [parser, parser.parse(NonterminalKind.SourceUnit, text)]; + return [parser, parser.parseNonterminal(NonterminalKind.SourceUnit, text)]; } let isCachedParser = false; @@ -59,7 +60,7 @@ export function createParser( let inferredRanges: string[] = []; try { - parseOutput = parser.parse(NonterminalKind.SourceUnit, text); + parseOutput = parser.parseNonterminal(NonterminalKind.SourceUnit, text); inferredRanges = tryToCollectPragmas(parseOutput, parser, isCachedParser); } catch { for ( @@ -70,7 +71,7 @@ export function createParser( try { const version = milestoneVersions[i]; parser = Parser.create(version); - parseOutput = parser.parse(NonterminalKind.SourceUnit, text); + parseOutput = parser.parseNonterminal(NonterminalKind.SourceUnit, text); inferredRanges = tryToCollectPragmas(parseOutput, parser); break; } catch { @@ -98,9 +99,9 @@ export function createParser( ? satisfyingVersions[satisfyingVersions.length - 1] : supportedVersions[supportedVersions.length - 1]; - if (inferredVersion !== parser.version) { + if (inferredVersion !== parser.languageVersion) { parser = Parser.create(inferredVersion); - parseOutput = parser.parse(NonterminalKind.SourceUnit, text); + parseOutput = parser.parseNonterminal(NonterminalKind.SourceUnit, text); } // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion @@ -132,11 +133,11 @@ function tryToCollectPragmas( if (ranges.length === 0) { // If we didn't find pragmas but succeeded parsing the source we keep it. if (!isCachedParser && parseOutput.isValid()) { - return [parser.version]; + return [parser.languageVersion]; } // Otherwise we throw. throw new Error( - `Using version ${parser.version} did not find any pragma statement and does not parse without errors.` + `Using version ${parser.languageVersion} did not find any pragma statement and does not parse without errors.` ); } diff --git a/src/slang-utils/metadata.ts b/src/slang-utils/metadata.ts index b6e4d36b..f5f7fc24 100644 --- a/src/slang-utils/metadata.ts +++ b/src/slang-utils/metadata.ts @@ -54,7 +54,7 @@ export function getNodeMetadata( }; } - const children = ast.cst.children.map((child) => { + const children = ast.cst.children().map((child) => { return child.node; }); diff --git a/src/slangSolidityParser.ts b/src/slangSolidityParser.ts index ea5d7486..766ee6a5 100644 --- a/src/slangSolidityParser.ts +++ b/src/slangSolidityParser.ts @@ -15,13 +15,13 @@ export default function parse( if (parseOutput.isValid()) { // We update the compiler version by the inferred one. - options.compiler = parser.version; + options.compiler = parser.languageVersion; const parsed = new SourceUnit( - new SlangSourceUnit(parseOutput.tree.asNonterminalNode()!), + new SlangSourceUnit(parseOutput.tree.asNonterminalNode()), options ); clearOffsets(); return parsed; } - throw new Error(parseOutput.errors[0].message); + throw new Error(parseOutput.errors()[0].message); } diff --git a/src/types.d.ts b/src/types.d.ts index c7a001ae..0114ba1a 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -230,7 +230,6 @@ export type SlangAstNode = | ast.YulAssignmentOperator | ast.YulSwitchCase | ast.YulExpression - | ast.YulPathComponent | ast.YulBuiltInFunction | ast.YulLiteral | ast.SourceUnitMembers diff --git a/tests/unit/slang-utils/create-parser.test.js b/tests/unit/slang-utils/create-parser.test.js index 5405a39a..c543994f 100644 --- a/tests/unit/slang-utils/create-parser.test.js +++ b/tests/unit/slang-utils/create-parser.test.js @@ -1,10 +1,8 @@ -import { Parser } from '@nomicfoundation/slang/parser'; +import { LanguageFacts } from '@nomicfoundation/slang/utils'; import { createParser } from '../../../src/slang-utils/create-parser.js'; describe('inferLanguage', function () { - const supportedVersions = Parser.supportedVersions(); - const latestSupportedVersion = - supportedVersions[supportedVersions.length - 1]; + const latestSupportedVersion = LanguageFacts.latestVersion(); const options = { filepath: 'test.sol' }; const fixtures = [ @@ -81,36 +79,36 @@ describe('inferLanguage', function () { for (const { description, source, version } of fixtures) { test(description, function () { const [parser] = createParser(source, options); - expect(parser.version).toEqual(version); + expect(parser.languageVersion).toEqual(version); }); } test('should use the latest successful version if the source has no pragmas', function () { createParser(`pragma solidity 0.8.28;`, options); let [parser] = createParser(`contract Foo {}`, options); - expect(parser.version).toEqual('0.8.28'); + expect(parser.languageVersion).toEqual('0.8.28'); createParser(`pragma solidity 0.8.2;`, options); [parser] = createParser(`contract Foo {}`, options); - expect(parser.version).toEqual('0.8.28'); + expect(parser.languageVersion).toEqual('0.8.28'); [parser] = createParser(`contract Foo {byte bar;}`, options); - expect(parser.version).toEqual('0.7.6'); + expect(parser.languageVersion).toEqual('0.7.6'); }); test('should use compiler option if given', function () { let [parser] = createParser(`pragma solidity ^0.8.0;`, { compiler: '0.8.20' }); - expect(parser.version).toEqual('0.8.20'); + expect(parser.languageVersion).toEqual('0.8.20'); [parser] = createParser(`pragma solidity ^0.8.0;`, { compiler: '0.8.2' }); - expect(parser.version).toEqual('0.8.2'); + expect(parser.languageVersion).toEqual('0.8.2'); [parser] = createParser(`pragma solidity ^0.8.0;`, {}); - expect(parser.version).toEqual(latestSupportedVersion); + expect(parser.languageVersion).toEqual(latestSupportedVersion); }); test('should throw when a pragma is broken by new lines, whitespace and comments', function () {