diff --git a/package-lock.json b/package-lock.json index 4f05f07c5..7454a338d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,14 +16,14 @@ "devDependencies": { "@babel/code-frame": "^7.27.1", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.28.0", + "@eslint/js": "^9.29.0", "@types/jest": "^29.5.14", "@types/semver": "^7.7.0", - "@typescript-eslint/eslint-plugin": "^8.34.0", - "@typescript-eslint/parser": "^8.34.0", + "@typescript-eslint/eslint-plugin": "^8.34.1", + "@typescript-eslint/parser": "^8.34.1", "c8": "^10.1.3", "cross-env": "^7.0.3", - "eslint": "^9.28.0", + "eslint": "^9.29.0", "eslint-config-prettier": "^10.1.5", "esm-utils": "^4.4.2", "globals": "^16.2.0", diff --git a/package.json b/package.json index f530043a3..0d46d8cd9 100644 --- a/package.json +++ b/package.json @@ -85,14 +85,14 @@ "devDependencies": { "@babel/code-frame": "^7.27.1", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.28.0", + "@eslint/js": "^9.29.0", "@types/jest": "^29.5.14", "@types/semver": "^7.7.0", - "@typescript-eslint/eslint-plugin": "^8.34.0", - "@typescript-eslint/parser": "^8.34.0", + "@typescript-eslint/eslint-plugin": "^8.34.1", + "@typescript-eslint/parser": "^8.34.1", "c8": "^10.1.3", "cross-env": "^7.0.3", - "eslint": "^9.28.0", + "eslint": "^9.29.0", "eslint-config-prettier": "^10.1.5", "esm-utils": "^4.4.2", "globals": "^16.2.0", diff --git a/src/slang-utils/create-parser.ts b/src/slang-utils/create-parser.ts index 60bfb5dd5..8f511d739 100644 --- a/src/slang-utils/create-parser.ts +++ b/src/slang-utils/create-parser.ts @@ -1,145 +1,66 @@ -import { VersionExpressionSets as SlangVersionExpressionSets } from '@nomicfoundation/slang/ast'; -import { NonterminalKind, Query } from '@nomicfoundation/slang/cst'; +import { NonterminalKind } from '@nomicfoundation/slang/cst'; import { Parser } from '@nomicfoundation/slang/parser'; import { LanguageFacts } from '@nomicfoundation/slang/utils'; -import { - maxSatisfying, - minSatisfying, - minor, - major, - satisfies, - validRange -} from 'semver'; -import { VersionExpressionSets } from '../slang-nodes/VersionExpressionSets.js'; +import { minSatisfying } from 'semver'; import type { ParseOutput } from '@nomicfoundation/slang/parser'; import type { ParserOptions } from 'prettier'; import type { AstNode } from '../slang-nodes/types.js'; const supportedVersions = LanguageFacts.allVersions(); +const supportedLength = supportedVersions.length; -const milestoneVersions = Array.from( - supportedVersions.reduce((minorRanges, version) => { - minorRanges.add(`^${major(version)}.${minor(version)}.0`); - return minorRanges; - }, new Set()) -) - .reverse() - .reduce((versions: string[], range) => { - versions.push(maxSatisfying(supportedVersions, range)!); - versions.push(minSatisfying(supportedVersions, range)!); - return versions; - }, []); - -const queries = [ - Query.create('[VersionPragma @versionRanges [VersionExpressionSets]]') -]; - -let parser: Parser; +function parserAndOutput( + text: string, + version: string +): { parser: Parser; parseOutput: ParseOutput } { + const parser = Parser.create(version); + return { + parser, + parseOutput: parser.parseNonterminal(NonterminalKind.SourceUnit, text) + }; +} export function createParser( text: string, options: ParserOptions -): [Parser, ParseOutput] { - const compiler = maxSatisfying(supportedVersions, options.compiler); +): { parser: Parser; parseOutput: ParseOutput } { + const compiler = minSatisfying(supportedVersions, options.compiler); if (compiler) { - if (!parser || parser.languageVersion !== compiler) { - parser = Parser.create(compiler); - } - return [parser, parser.parseNonterminal(NonterminalKind.SourceUnit, text)]; - } - - let isCachedParser = false; - if (parser) { - isCachedParser = true; - } else { - parser = Parser.create(milestoneVersions[0]); - } - - let parseOutput; - let inferredRanges: string[] = []; - - try { - parseOutput = parser.parseNonterminal(NonterminalKind.SourceUnit, text); - inferredRanges = tryToCollectPragmas(parseOutput, parser, isCachedParser); - } catch { - for ( - let i = isCachedParser ? 0 : 1; - i <= milestoneVersions.length; - i += 1 - ) { - try { - const version = milestoneVersions[i]; - parser = Parser.create(version); - parseOutput = parser.parseNonterminal(NonterminalKind.SourceUnit, text); - inferredRanges = tryToCollectPragmas(parseOutput, parser); - break; - } catch { - continue; - } - } - } - - const satisfyingVersions = inferredRanges.reduce( - (versions, inferredRange) => { - if (!validRange(inferredRange)) { - throw new Error( - `Couldn't infer any version from the ranges in the pragmas${options.filepath ? ` for file ${options.filepath}` : ''}` - ); - } - return versions.filter((supportedVersion) => - satisfies(supportedVersion, inferredRange) + const result = parserAndOutput(text, compiler); + + if (!result.parseOutput.isValid()) + throw new Error( + `We encountered the following syntax error:\n\n\t${ + result.parseOutput.errors()[0].message + }\n\nBased on the compiler option provided, we inferred your code to be using Solidity version ${ + result.parser.languageVersion + }. If you would like to change that, specify a different version in your \`.prettierrc\` file.` ); - }, - supportedVersions - ); - - const inferredVersion = - satisfyingVersions.length > 0 - ? satisfyingVersions[satisfyingVersions.length - 1] - : supportedVersions[supportedVersions.length - 1]; - if (inferredVersion !== parser.languageVersion) { - parser = Parser.create(inferredVersion); - parseOutput = parser.parseNonterminal(NonterminalKind.SourceUnit, text); + return result; } + const inferredRanges: string[] = LanguageFacts.inferLanguageVersions(text); + const inferredLength = inferredRanges.length; - // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion - return [parser, parseOutput!]; -} - -function tryToCollectPragmas( - parseOutput: ParseOutput, - parser: Parser, - isCachedParser = false -): string[] { - const matches = parseOutput.createTreeCursor().query(queries); - const ranges: string[] = []; - - let match; - while ((match = matches.next())) { - const versionRange = new SlangVersionExpressionSets( - match.captures.versionRanges[0].node.asNonterminalNode()! - ); - ranges.push( - // Replace all comments that could be in the expression with whitespace - new VersionExpressionSets(versionRange).comments.reduce( - (range, comment) => range.replace(comment.value, ' '), - versionRange.cst.unparse() - ) + if (inferredLength === 0) { + throw new Error( + `We couldn't infer a Solidity version base on the pragma statements in your code. If you would like to change that, update the pragmas in your source file, or specify a version in your \`.prettierrc\` file.` ); } + const result = parserAndOutput( + text, + inferredRanges[inferredLength === supportedLength ? inferredLength - 1 : 0] + ); - if (ranges.length === 0) { - // If we didn't find pragmas but succeeded parsing the source we keep it. - if (!isCachedParser && parseOutput.isValid()) { - return [parser.languageVersion]; - } - // Otherwise we throw. + if (!result.parseOutput.isValid()) throw new Error( - `Using version ${parser.languageVersion} did not find any pragma statement and does not parse without errors.` + `We encountered the following syntax error:\n\n\t${ + result.parseOutput.errors()[0].message + }\n\nBased on the pragma statements, we inferred your code to be using Solidity version ${ + result.parser.languageVersion + }. If you would like to change that, update the pragmas in your source file, or specify a version in your \`.prettierrc\` file.` ); - } - return ranges; + return result; } diff --git a/src/slangSolidityParser.ts b/src/slangSolidityParser.ts index 766ee6a57..cb40ce145 100644 --- a/src/slangSolidityParser.ts +++ b/src/slangSolidityParser.ts @@ -11,17 +11,14 @@ export default function parse( text: string, options: ParserOptions ): AstNode { - const [parser, parseOutput] = createParser(text, options); + const { parser, parseOutput } = createParser(text, options); - if (parseOutput.isValid()) { - // We update the compiler version by the inferred one. - options.compiler = parser.languageVersion; - const parsed = new SourceUnit( - new SlangSourceUnit(parseOutput.tree.asNonterminalNode()), - options - ); - clearOffsets(); - return parsed; - } - throw new Error(parseOutput.errors()[0].message); + // We update the compiler version by the inferred one. + options.compiler = parser.languageVersion; + const parsed = new SourceUnit( + new SlangSourceUnit(parseOutput.tree.asNonterminalNode()), + options + ); + clearOffsets(); + return parsed; } diff --git a/tests/config/run-format-test.js b/tests/config/run-format-test.js index dd1ee45d7..284528efa 100644 --- a/tests/config/run-format-test.js +++ b/tests/config/run-format-test.js @@ -334,7 +334,7 @@ async function runTest({ // same for ANTLR unless it was already given as an option. compiler: formatOptions.compiler || - createParser(code, formatOptions)[0].languageVersion, + createParser(code, formatOptions).parser.languageVersion, parser: "antlr", plugins: await getPlugins(), }); diff --git a/tests/format/AllSolidityFeatures/AllSolidityFeatures.sol b/tests/format/AllSolidityFeatures/AllSolidityFeatures.sol index 487df3a6e..081663de2 100644 --- a/tests/format/AllSolidityFeatures/AllSolidityFeatures.sol +++ b/tests/format/AllSolidityFeatures/AllSolidityFeatures.sol @@ -1,8 +1,4 @@ // Examples taken from the Solidity documentation online. - -// for pragma version numbers, see https://docs.npmjs.com/misc/semver#versions -pragma solidity 0.4.0; -pragma solidity ^0.4.0; pragma experimental ABIEncoderV2; import "SomeFile.sol"; diff --git a/tests/format/AllSolidityFeatures/__snapshots__/format.test.js.snap b/tests/format/AllSolidityFeatures/__snapshots__/format.test.js.snap index c01769dab..8551620d5 100644 --- a/tests/format/AllSolidityFeatures/__snapshots__/format.test.js.snap +++ b/tests/format/AllSolidityFeatures/__snapshots__/format.test.js.snap @@ -7,10 +7,6 @@ printWidth: 80 | printWidth =====================================input====================================== // Examples taken from the Solidity documentation online. - -// for pragma version numbers, see https://docs.npmjs.com/misc/semver#versions -pragma solidity 0.4.0; -pragma solidity ^0.4.0; pragma experimental ABIEncoderV2; import "SomeFile.sol"; @@ -370,10 +366,6 @@ using { add as + , sub } for Fixed18 global ; =====================================output===================================== // Examples taken from the Solidity documentation online. - -// for pragma version numbers, see https://docs.npmjs.com/misc/semver#versions -pragma solidity 0.4.0; -pragma solidity ^0.4.0; pragma experimental ABIEncoderV2; import "SomeFile.sol"; diff --git a/tests/format/AllSolidityFeaturesV0.4.26/__snapshots__/format.test.js.snap b/tests/format/AllSolidityFeaturesV0.4.26/__snapshots__/format.test.js.snap index 4dc632449..ee0607181 100644 --- a/tests/format/AllSolidityFeaturesV0.4.26/__snapshots__/format.test.js.snap +++ b/tests/format/AllSolidityFeaturesV0.4.26/__snapshots__/format.test.js.snap @@ -1,7 +1,8 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing -exports[`AllSolidityFeatures.sol format 1`] = ` +exports[`AllSolidityFeatures.sol - {"compiler":"0.4.26"} format 1`] = ` ====================================options===================================== +compiler: "0.4.26" parsers: ["slang"] printWidth: 80 | printWidth diff --git a/tests/format/AllSolidityFeaturesV0.4.26/format.test.js b/tests/format/AllSolidityFeaturesV0.4.26/format.test.js index 6021bbb0d..85c6f9a33 100644 --- a/tests/format/AllSolidityFeaturesV0.4.26/format.test.js +++ b/tests/format/AllSolidityFeaturesV0.4.26/format.test.js @@ -1 +1 @@ -runFormatTest(import.meta, ['slang']); +runFormatTest(import.meta, ['slang'], { compiler: '0.4.26' }); diff --git a/tests/format/BasicIterator/__snapshots__/format.test.js.snap b/tests/format/BasicIterator/__snapshots__/format.test.js.snap index db55d79c3..1fdd5e387 100644 --- a/tests/format/BasicIterator/__snapshots__/format.test.js.snap +++ b/tests/format/BasicIterator/__snapshots__/format.test.js.snap @@ -1,7 +1,8 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing -exports[`BasicIterator.sol format 1`] = ` +exports[`BasicIterator.sol - {"compiler":"0.4.26"} format 1`] = ` ====================================options===================================== +compiler: "0.4.26" parsers: ["slang"] printWidth: 80 | printWidth diff --git a/tests/format/BasicIterator/format.test.js b/tests/format/BasicIterator/format.test.js index 6021bbb0d..85c6f9a33 100644 --- a/tests/format/BasicIterator/format.test.js +++ b/tests/format/BasicIterator/format.test.js @@ -1 +1 @@ -runFormatTest(import.meta, ['slang']); +runFormatTest(import.meta, ['slang'], { compiler: '0.4.26' }); diff --git a/tests/format/Comments/Comments.sol b/tests/format/Comments/Comments.sol index 4167e90bc..e59f5e034 100644 --- a/tests/format/Comments/Comments.sol +++ b/tests/format/Comments/Comments.sol @@ -1,6 +1,3 @@ -pragma solidity ^0.4.29; - - contract Comments1 { /* solhint-disable var-name-mixedcase */ IEIP712DomainSeparator private EIP712domainSeparator; diff --git a/tests/format/Comments/__snapshots__/format.test.js.snap b/tests/format/Comments/__snapshots__/format.test.js.snap index 06902e3e8..1e9252a79 100644 --- a/tests/format/Comments/__snapshots__/format.test.js.snap +++ b/tests/format/Comments/__snapshots__/format.test.js.snap @@ -6,9 +6,6 @@ parsers: ["slang"] printWidth: 80 | printWidth =====================================input====================================== -pragma solidity ^0.4.29; - - contract Comments1 { /* solhint-disable var-name-mixedcase */ IEIP712DomainSeparator private EIP712domainSeparator; @@ -178,8 +175,6 @@ contract Comments13 { } } =====================================output===================================== -pragma solidity ^0.4.29; - contract Comments1 { /* solhint-disable var-name-mixedcase */ IEIP712DomainSeparator private EIP712domainSeparator; diff --git a/tests/format/FunctionDefinitionsV0.5.0/__snapshots__/format.test.js.snap b/tests/format/FunctionDefinitionsV0.5.0/__snapshots__/format.test.js.snap index 625f22065..e010c16f7 100644 --- a/tests/format/FunctionDefinitionsV0.5.0/__snapshots__/format.test.js.snap +++ b/tests/format/FunctionDefinitionsV0.5.0/__snapshots__/format.test.js.snap @@ -1,7 +1,8 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing -exports[`FunctionDefinitions.sol format 1`] = ` +exports[`FunctionDefinitions.sol - {"compiler":"0.5.17"} format 1`] = ` ====================================options===================================== +compiler: "0.5.17" parsers: ["slang"] printWidth: 80 | printWidth diff --git a/tests/format/FunctionDefinitionsV0.5.0/format.test.js b/tests/format/FunctionDefinitionsV0.5.0/format.test.js index 6021bbb0d..80d418f68 100644 --- a/tests/format/FunctionDefinitionsV0.5.0/format.test.js +++ b/tests/format/FunctionDefinitionsV0.5.0/format.test.js @@ -1 +1 @@ -runFormatTest(import.meta, ['slang']); +runFormatTest(import.meta, ['slang'], { compiler: '0.5.17' }); diff --git a/tests/format/FunctionDefinitionsv0.5.0/__snapshots__/format.test.js.snap b/tests/format/FunctionDefinitionsv0.5.0/__snapshots__/format.test.js.snap index 625f22065..e010c16f7 100644 --- a/tests/format/FunctionDefinitionsv0.5.0/__snapshots__/format.test.js.snap +++ b/tests/format/FunctionDefinitionsv0.5.0/__snapshots__/format.test.js.snap @@ -1,7 +1,8 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing -exports[`FunctionDefinitions.sol format 1`] = ` +exports[`FunctionDefinitions.sol - {"compiler":"0.5.17"} format 1`] = ` ====================================options===================================== +compiler: "0.5.17" parsers: ["slang"] printWidth: 80 | printWidth diff --git a/tests/format/FunctionDefinitionsv0.5.0/format.test.js b/tests/format/FunctionDefinitionsv0.5.0/format.test.js index 6021bbb0d..80d418f68 100644 --- a/tests/format/FunctionDefinitionsv0.5.0/format.test.js +++ b/tests/format/FunctionDefinitionsv0.5.0/format.test.js @@ -1 +1 @@ -runFormatTest(import.meta, ['slang']); +runFormatTest(import.meta, ['slang'], { compiler: '0.5.17' }); diff --git a/tests/format/IndexOf/__snapshots__/format.test.js.snap b/tests/format/IndexOf/__snapshots__/format.test.js.snap index 791069d51..01afcc0b0 100644 --- a/tests/format/IndexOf/__snapshots__/format.test.js.snap +++ b/tests/format/IndexOf/__snapshots__/format.test.js.snap @@ -1,7 +1,8 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing -exports[`IndexOf.sol format 1`] = ` +exports[`IndexOf.sol - {"compiler":"0.4.26"} format 1`] = ` ====================================options===================================== +compiler: "0.4.26" parsers: ["slang"] printWidth: 80 | printWidth diff --git a/tests/format/IndexOf/format.test.js b/tests/format/IndexOf/format.test.js index 6021bbb0d..85c6f9a33 100644 --- a/tests/format/IndexOf/format.test.js +++ b/tests/format/IndexOf/format.test.js @@ -1 +1 @@ -runFormatTest(import.meta, ['slang']); +runFormatTest(import.meta, ['slang'], { compiler: '0.4.26' }); diff --git a/tests/format/MemberAccess/__snapshots__/format.test.js.snap b/tests/format/MemberAccess/__snapshots__/format.test.js.snap index f036c9128..f3d07202b 100644 --- a/tests/format/MemberAccess/__snapshots__/format.test.js.snap +++ b/tests/format/MemberAccess/__snapshots__/format.test.js.snap @@ -1,7 +1,8 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing -exports[`MemberAccess.sol format 1`] = ` +exports[`MemberAccess.sol - {"compiler":"0.6.12"} format 1`] = ` ====================================options===================================== +compiler: "0.6.12" parsers: ["slang"] printWidth: 80 | printWidth diff --git a/tests/format/MemberAccess/format.test.js b/tests/format/MemberAccess/format.test.js index 6021bbb0d..569e4c7b0 100644 --- a/tests/format/MemberAccess/format.test.js +++ b/tests/format/MemberAccess/format.test.js @@ -1 +1 @@ -runFormatTest(import.meta, ['slang']); +runFormatTest(import.meta, ['slang'], { compiler: '0.6.12' }); diff --git a/tests/format/Pragma/__snapshots__/format.test.js.snap b/tests/format/Pragma/__snapshots__/format.test.js.snap index 1c005d1ce..e613b05f8 100644 --- a/tests/format/Pragma/__snapshots__/format.test.js.snap +++ b/tests/format/Pragma/__snapshots__/format.test.js.snap @@ -1,7 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Pragma.sol format 1`] = ` +exports[`Pragma.sol - {"compiler":"0.8.0"} format 1`] = ` ====================================options===================================== +compiler: "0.8.0" parsers: ["slang"] printWidth: 80 | printWidth diff --git a/tests/format/Pragma/format.test.js b/tests/format/Pragma/format.test.js index 6021bbb0d..875eca87d 100644 --- a/tests/format/Pragma/format.test.js +++ b/tests/format/Pragma/format.test.js @@ -1 +1 @@ -runFormatTest(import.meta, ['slang']); +runFormatTest(import.meta, ['slang'], { compiler: '0.8.0' }); diff --git a/tests/format/SimpleStorage/__snapshots__/format.test.js.snap b/tests/format/SimpleStorage/__snapshots__/format.test.js.snap index db687b891..99944356e 100644 --- a/tests/format/SimpleStorage/__snapshots__/format.test.js.snap +++ b/tests/format/SimpleStorage/__snapshots__/format.test.js.snap @@ -1,7 +1,8 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing -exports[`SimpleStorage.sol format 1`] = ` +exports[`SimpleStorage.sol - {"compiler":"0.4.26"} format 1`] = ` ====================================options===================================== +compiler: "0.4.26" parsers: ["slang"] printWidth: 80 | printWidth diff --git a/tests/format/SimpleStorage/format.test.js b/tests/format/SimpleStorage/format.test.js index 6021bbb0d..85c6f9a33 100644 --- a/tests/format/SimpleStorage/format.test.js +++ b/tests/format/SimpleStorage/format.test.js @@ -1 +1 @@ -runFormatTest(import.meta, ['slang']); +runFormatTest(import.meta, ['slang'], { compiler: '0.4.26' }); diff --git a/tests/format/StyleGuide/__snapshots__/format.test.js.snap b/tests/format/StyleGuide/__snapshots__/format.test.js.snap index b8014781f..8ceed378d 100644 --- a/tests/format/StyleGuide/__snapshots__/format.test.js.snap +++ b/tests/format/StyleGuide/__snapshots__/format.test.js.snap @@ -1,7 +1,8 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing -exports[`BlankLines.sol format 1`] = ` +exports[`BlankLines.sol - {"compiler":"0.5.17"} format 1`] = ` ====================================options===================================== +compiler: "0.5.17" parsers: ["slang"] printWidth: 80 | printWidth @@ -46,8 +47,9 @@ contract A { ================================================================================ `; -exports[`ControlStructures.sol format 1`] = ` +exports[`ControlStructures.sol - {"compiler":"0.5.17"} format 1`] = ` ====================================options===================================== +compiler: "0.5.17" parsers: ["slang"] printWidth: 80 | printWidth @@ -167,8 +169,9 @@ contract ControlStructures { ================================================================================ `; -exports[`FunctionDeclaration.sol format 1`] = ` +exports[`FunctionDeclaration.sol - {"compiler":"0.5.17"} format 1`] = ` ====================================options===================================== +compiler: "0.5.17" parsers: ["slang"] printWidth: 80 | printWidth @@ -458,8 +461,9 @@ contract X is B, C, D { ================================================================================ `; -exports[`Mappings.sol format 1`] = ` +exports[`Mappings.sol - {"compiler":"0.5.17"} format 1`] = ` ====================================options===================================== +compiler: "0.5.17" parsers: ["slang"] printWidth: 80 | printWidth @@ -487,8 +491,9 @@ contract Mappings { ================================================================================ `; -exports[`MaximumLineLength.sol format 1`] = ` +exports[`MaximumLineLength.sol - {"compiler":"0.5.17"} format 1`] = ` ====================================options===================================== +compiler: "0.5.17" parsers: ["slang"] printWidth: 80 | printWidth @@ -642,8 +647,9 @@ contract EventDefinitionsAndEventEmitters { ================================================================================ `; -exports[`OtherRecommendations.sol format 1`] = ` +exports[`OtherRecommendations.sol - {"compiler":"0.5.17"} format 1`] = ` ====================================options===================================== +compiler: "0.5.17" parsers: ["slang"] printWidth: 80 | printWidth @@ -709,8 +715,9 @@ contract OtherRecommendations { ================================================================================ `; -exports[`VariableDeclarations.sol format 1`] = ` +exports[`VariableDeclarations.sol - {"compiler":"0.5.17"} format 1`] = ` ====================================options===================================== +compiler: "0.5.17" parsers: ["slang"] printWidth: 80 | printWidth @@ -732,8 +739,9 @@ contract VariableDeclarations { ================================================================================ `; -exports[`WhitespaceInExpressions.sol format 1`] = ` +exports[`WhitespaceInExpressions.sol - {"compiler":"0.5.17"} format 1`] = ` ====================================options===================================== +compiler: "0.5.17" parsers: ["slang"] printWidth: 80 | printWidth diff --git a/tests/format/StyleGuide/format.test.js b/tests/format/StyleGuide/format.test.js index 6021bbb0d..80d418f68 100644 --- a/tests/format/StyleGuide/format.test.js +++ b/tests/format/StyleGuide/format.test.js @@ -1 +1 @@ -runFormatTest(import.meta, ['slang']); +runFormatTest(import.meta, ['slang'], { compiler: '0.5.17' }); diff --git a/tests/format/strings/__snapshots__/format.test.js.snap b/tests/format/strings/__snapshots__/format.test.js.snap index 397392bf3..09408f084 100644 --- a/tests/format/strings/__snapshots__/format.test.js.snap +++ b/tests/format/strings/__snapshots__/format.test.js.snap @@ -1,7 +1,8 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing -exports[`strings.sol format 1`] = ` +exports[`strings.sol - {"compiler":"0.4.26"} format 1`] = ` ====================================options===================================== +compiler: "0.4.26" parsers: ["slang"] printWidth: 80 | printWidth diff --git a/tests/format/strings/format.test.js b/tests/format/strings/format.test.js index 6021bbb0d..85c6f9a33 100644 --- a/tests/format/strings/format.test.js +++ b/tests/format/strings/format.test.js @@ -1 +1 @@ -runFormatTest(import.meta, ['slang']); +runFormatTest(import.meta, ['slang'], { compiler: '0.4.26' }); diff --git a/tests/unit/slang-utils/create-parser.test.js b/tests/unit/slang-utils/create-parser.test.js index 3d926d6e1..d8c04cb08 100644 --- a/tests/unit/slang-utils/create-parser.test.js +++ b/tests/unit/slang-utils/create-parser.test.js @@ -9,7 +9,7 @@ describe('inferLanguage', function () { { description: 'Caret range', source: `pragma solidity ^0.7.0;`, - version: '0.7.6' + version: '0.7.0' }, { description: 'Pinned version', @@ -19,13 +19,25 @@ describe('inferLanguage', function () { { description: 'With nightly commit', source: `pragma solidity 0.8.18-ci.2023.1.17+commit.e7b959af;`, - version: '0.8.18' + version: '0.8.18', + // TODO: unskip this test when addresses this issue + // https://github.com/NomicFoundation/slang/issues/1346 + skip: true }, { description: 'Caret range and pinned version', source: `pragma solidity ^0.8.0; pragma solidity 0.8.2;`, version: '0.8.2' }, + { + description: 'pragma is broken by new lines, whitespace and comments', + source: `pragma solidity 0. + // comment 1 + 7. + /* comment 2*/ + 3;`, + version: '0.7.3' + }, { description: 'With multiline comment before the range', source: `pragma solidity /* comment */ 0.8.2;`, @@ -71,74 +83,44 @@ describe('inferLanguage', function () { { description: 'should use the latest version if the range is outside the supported versions', - source: `pragma solidity ^0.8.27;`, - version: latestSupportedVersion + source: `pragma solidity ^10.0.0;`, + version: latestSupportedVersion, + // TODO: unskip this test when slack fixes the error with ranges outside the supported versions. + skip: true } ]; - for (const { description, source, version } of fixtures) { - test(description, function () { - const [parser] = createParser(source, options); + for (const { description, source, version, skip } of fixtures) { + (skip ? test.skip : test)(description, function () { + const { parser } = createParser(source, options); expect(parser.languageVersion).toEqual(version); }); } test('should use the latest successful version if the source has no pragmas', function () { - // This is to create in memory the latest parser and review the behaviour - createParser(`pragma solidity ${latestSupportedVersion};`, options); - let [parser] = createParser(`contract Foo {}`, options); + let { parser } = createParser(`contract Foo {}`, options); expect(parser.languageVersion).toEqual(latestSupportedVersion); - // This is to create in memory an old parser and review the behaviour - createParser(`pragma solidity 0.8.2;`, options); - [parser] = createParser(`contract Foo {}`, options); - expect(parser.languageVersion).toEqual(latestSupportedVersion); - - [parser] = createParser(`contract Foo {byte bar;}`, options); - expect(parser.languageVersion).toEqual('0.7.6'); + // ({ parser } = createParser(`contract Foo {byte bar;}`, options)); + // expect(parser.languageVersion).toEqual('0.7.6'); }); test('should use compiler option if given', function () { - let [parser] = createParser(`pragma solidity ^0.8.0;`, { + let { parser } = createParser(`pragma solidity ^0.8.0;`, { compiler: '0.8.20' }); expect(parser.languageVersion).toEqual('0.8.20'); - [parser] = createParser(`pragma solidity ^0.8.0;`, { + ({ parser } = createParser(`pragma solidity ^0.8.0;`, { compiler: '0.8.2' - }); + })); expect(parser.languageVersion).toEqual('0.8.2'); - [parser] = createParser(`pragma solidity ^0.8.0;`, {}); - expect(parser.languageVersion).toEqual(latestSupportedVersion); - }); - - test('should throw when a pragma is broken by new lines, whitespace and comments', function () { - expect(() => - createParser( - `pragma solidity 0. - // comment 1 - 7. - /* comment 2*/ - 3;`, - options - ) - ).toThrow( - "Couldn't infer any version from the ranges in the pragmas for file test.sol" - ); - expect(() => - createParser( - `pragma solidity 0. - // comment 1 - 7. - /* comment 2*/ - 3;`, - {} - ) - ).toThrow("Couldn't infer any version from the ranges in the pragmas"); + ({ parser } = createParser(`pragma solidity ^0.8.0;`, {})); + expect(parser.languageVersion).toEqual('0.8.0'); }); - test.skip('should throw an error if there are incompatible ranges', function () { + test('should throw an error if there are incompatible ranges', function () { expect(() => createParser(`pragma solidity ^0.8.0; pragma solidity 0.7.6;`, options) ).toThrow();