Skip to content

Commit

Permalink
caching the parser for multiple calls to the parser
Browse files Browse the repository at this point in the history
  • Loading branch information
Janther committed Dec 10, 2024
1 parent aacb9da commit cc49d87
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 15 deletions.
15 changes: 11 additions & 4 deletions src/slang-utils/create-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,33 @@ const query = Query.parse(
'[VersionPragma @versionRanges [VersionExpressionSets]]'
);

let parser: Parser;

export function createParser(
text: string,
options: ParserOptions<AstNode>
): [Parser, ParseOutput] {
const compiler = maxSatisfying(supportedVersions, options.compiler);
let parser: Parser;
if (compiler) {
parser = Parser.create(compiler);
if (parser?.version !== compiler) {
parser = Parser.create(compiler);
}
return [parser, parser.parse(NonterminalKind.SourceUnit, text)];
}

parser = Parser.create(milestoneVersions[0]);
parser = parser ?? Parser.create(milestoneVersions[0]);
let parseOutput;
let inferredRanges: string[] = [];

try {
parseOutput = parser.parse(NonterminalKind.SourceUnit, text);
inferredRanges = tryToCollectPragmas(parseOutput, parser);
} catch {
for (let i = 1; i <= milestoneVersions.length; i += 1) {
for (
let i = parser.version === milestoneVersions[0] ? 1 : 0;
i <= milestoneVersions.length;
i += 1
) {
try {
const version = milestoneVersions[i];
parser = Parser.create(version);
Expand Down
39 changes: 28 additions & 11 deletions tests/unit/slang-utils/create-parser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,6 @@ describe('inferLanguage', function () {
0.8.2;`,
version: '0.8.2'
},
{
description: 'should use the latest version if the source has no pragmas',
source: `contract Foo {}`,
version: latestSupportedVersion
},
{
description:
'should use the latest valid version if the source has no pragmas and the syntax is old',
source: `contract Foo {byte bar;}`,
version: '0.7.6'
},
{
description:
'should use the latest version if the range is outside the supported versions',
Expand All @@ -96,6 +85,34 @@ describe('inferLanguage', function () {
});
}

test('should use the cached or 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');

createParser(`pragma solidity 0.8.2;`, options);
[parser] = createParser(`contract Foo {}`, options);
expect(parser.version).toEqual('0.8.2');

[parser] = createParser(`contract Foo {byte bar;}`, options);
expect(parser.version).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');

[parser] = createParser(`pragma solidity ^0.8.0;`, {
compiler: '0.8.2'
});
expect(parser.version).toEqual('0.8.2');

[parser] = createParser(`pragma solidity ^0.8.0;`, {});
expect(parser.version).toEqual(latestSupportedVersion);
});

test('should throw when a pragma is broken by new lines, whitespace and comments', function () {
expect(() =>
createParser(
Expand Down

0 comments on commit cc49d87

Please sign in to comment.