Skip to content

Commit

Permalink
- remove YulPathComponent and using YulIdentifier
Browse files Browse the repository at this point in the history
- renaming parser.version to parser.languageVersion
- using LanguageFacts for languageVersions
  • Loading branch information
Janther committed Jan 27, 2025
1 parent a489406 commit 8c9e7e1
Show file tree
Hide file tree
Showing 8 changed files with 29 additions and 65 deletions.
12 changes: 5 additions & 7 deletions src/slang-nodes/YulPath.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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;
}
Expand Down
30 changes: 0 additions & 30 deletions src/slang-nodes/YulPathComponent.ts

This file was deleted.

2 changes: 0 additions & 2 deletions src/slang-nodes/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -410,7 +409,6 @@ export type StrictAstNode =
| YulAssignmentOperator
| YulSwitchCase
| YulExpression
| YulPathComponent
| YulBuiltInFunction
| YulLiteral
| SourceUnitMembers
Expand Down
21 changes: 11 additions & 10 deletions src/slang-utils/create-parser.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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) => {
Expand All @@ -31,7 +32,7 @@ const milestoneVersions = Array.from(
}, []);

const queries = [
Query.parse('[VersionPragma @versionRanges [VersionExpressionSets]]')
Query.create('[VersionPragma @versionRanges [VersionExpressionSets]]')
];

let parser: Parser;
Expand All @@ -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;
Expand All @@ -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 (
Expand All @@ -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 {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.`
);
}

Expand Down
2 changes: 1 addition & 1 deletion src/slang-utils/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export function getNodeMetadata(
};
}

const children = ast.cst.children.map((child) => {
const children = ast.cst.children().map((child) => {
return child.node;
});

Expand Down
6 changes: 3 additions & 3 deletions src/slangSolidityParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
1 change: 0 additions & 1 deletion src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,6 @@ export type SlangAstNode =
| ast.YulAssignmentOperator
| ast.YulSwitchCase
| ast.YulExpression
| ast.YulPathComponent
| ast.YulBuiltInFunction
| ast.YulLiteral
| ast.SourceUnitMembers
Expand Down
20 changes: 9 additions & 11 deletions tests/unit/slang-utils/create-parser.test.js
Original file line number Diff line number Diff line change
@@ -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 = [
Expand Down Expand Up @@ -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 () {
Expand Down

0 comments on commit 8c9e7e1

Please sign in to comment.