From b141bd9553830e1680ab12fead858ec34f8b7202 Mon Sep 17 00:00:00 2001 From: Klaus Date: Fri, 20 Jun 2025 22:20:10 +0100 Subject: [PATCH 1/3] I could not parse any nightly builds even when using specific versions of nightly builds of `solc` --- tests/unit/slang-utils/create-parser.test.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/unit/slang-utils/create-parser.test.js b/tests/unit/slang-utils/create-parser.test.js index d8c04cb08..bb667d353 100644 --- a/tests/unit/slang-utils/create-parser.test.js +++ b/tests/unit/slang-utils/create-parser.test.js @@ -16,14 +16,6 @@ describe('inferLanguage', function () { source: `pragma solidity 0.8.1;`, version: '0.8.1' }, - { - description: 'With nightly commit', - source: `pragma solidity 0.8.18-ci.2023.1.17+commit.e7b959af;`, - 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;`, From 308eeb9dd6748ccea3ff2bc4e9e7e5fb389ebc47 Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 23 Jun 2025 09:14:47 +0100 Subject: [PATCH 2/3] with an empty array as a result of inferLanguage, we default on the latest supported version --- src/slang-utils/create-parser.ts | 24 ++++++++++++++------ tests/unit/slang-utils/create-parser.test.js | 6 ++--- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/slang-utils/create-parser.ts b/src/slang-utils/create-parser.ts index 8f511d739..b913ce3e1 100644 --- a/src/slang-utils/create-parser.ts +++ b/src/slang-utils/create-parser.ts @@ -40,18 +40,28 @@ export function createParser( return result; } + const inferredRanges: string[] = LanguageFacts.inferLanguageVersions(text); const inferredLength = inferredRanges.length; - 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.` + if (inferredLength === 0 || inferredLength === supportedLength) { + const result = parserAndOutput( + text, + supportedVersions[supportedLength - 1] ); + + if (!result.parseOutput.isValid()) + throw new Error( + `We encountered the following syntax error:\n\n\t${ + result.parseOutput.errors()[0].message + }\n\nWe couldn't infer a Solidity version base on the pragma statements in your code so we defaulted to ${ + result.parser.languageVersion + }. You might be attempting to use a syntax not yet supported by Slang or you might want to specify a version in your \`.prettierrc\` file.` + ); + return result; } - const result = parserAndOutput( - text, - inferredRanges[inferredLength === supportedLength ? inferredLength - 1 : 0] - ); + + const result = parserAndOutput(text, inferredRanges[0]); if (!result.parseOutput.isValid()) throw new Error( diff --git a/tests/unit/slang-utils/create-parser.test.js b/tests/unit/slang-utils/create-parser.test.js index bb667d353..c02ad15df 100644 --- a/tests/unit/slang-utils/create-parser.test.js +++ b/tests/unit/slang-utils/create-parser.test.js @@ -76,9 +76,7 @@ describe('inferLanguage', function () { description: 'should use the latest version if the range is outside the supported versions', 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 + version: latestSupportedVersion } ]; @@ -112,7 +110,7 @@ describe('inferLanguage', function () { expect(parser.languageVersion).toEqual('0.8.0'); }); - test('should throw an error if there are incompatible ranges', function () { + test.skip('should throw an error if there are incompatible ranges', function () { expect(() => createParser(`pragma solidity ^0.8.0; pragma solidity 0.7.6;`, options) ).toThrow(); From 9af32ce5aba4b4d090414c3e199ee09be880dbee Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 23 Jun 2025 12:59:32 +0100 Subject: [PATCH 3/3] testing the errors --- src/slang-utils/create-parser.ts | 30 ++++++++------ tests/unit/slang-utils/create-parser.test.js | 41 ++++++++++++++++++-- 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/src/slang-utils/create-parser.ts b/src/slang-utils/create-parser.ts index b913ce3e1..8d90b680e 100644 --- a/src/slang-utils/create-parser.ts +++ b/src/slang-utils/create-parser.ts @@ -21,6 +21,15 @@ function parserAndOutput( }; } +function createError( + { parseOutput }: { parseOutput: ParseOutput }, + reason: string +): Error { + return new Error( + `We encountered the following syntax error:\n\n\t${parseOutput.errors()[0].message}\n\n${reason}` + ); +} + export function createParser( text: string, options: ParserOptions @@ -30,10 +39,9 @@ export function createParser( 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 ${ + throw createError( + result, + `Based 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.` ); @@ -51,10 +59,9 @@ export function createParser( ); if (!result.parseOutput.isValid()) - throw new Error( - `We encountered the following syntax error:\n\n\t${ - result.parseOutput.errors()[0].message - }\n\nWe couldn't infer a Solidity version base on the pragma statements in your code so we defaulted to ${ + throw createError( + result, + `We couldn't infer a Solidity version based on the pragma statements in your code so we defaulted to ${ result.parser.languageVersion }. You might be attempting to use a syntax not yet supported by Slang or you might want to specify a version in your \`.prettierrc\` file.` ); @@ -64,10 +71,9 @@ export function createParser( const result = parserAndOutput(text, inferredRanges[0]); 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 pragma statements, we inferred your code to be using Solidity version ${ + throw createError( + result, + `Based 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.` ); diff --git a/tests/unit/slang-utils/create-parser.test.js b/tests/unit/slang-utils/create-parser.test.js index c02ad15df..ed318b31e 100644 --- a/tests/unit/slang-utils/create-parser.test.js +++ b/tests/unit/slang-utils/create-parser.test.js @@ -110,9 +110,44 @@ describe('inferLanguage', function () { expect(parser.languageVersion).toEqual('0.8.0'); }); - test.skip('should throw an error if there are incompatible ranges', function () { + test('should throw if compiler option does not match the syntax', function () { expect(() => - createParser(`pragma solidity ^0.8.0; pragma solidity 0.7.6;`, options) - ).toThrow(); + createParser(`contract Foo {byte bar;}`, { compiler: '0.8.0' }) + ).toThrow( + 'Based on the compiler option provided, we inferred your code to be using Solidity version' + ); + }); + + test('should throw if pragma is outside the supported version and the syntax does not match with the latest supported version', function () { + expect(() => + createParser(`pragma solidity 10.0.0;contract Foo {byte bar;}`, options) + ).toThrow( + "We couldn't infer a Solidity version based on the pragma statements" + ); + }); + + test('should throw if there is no pragma and the syntax does not match with the latest supported version', function () { + expect(() => createParser(`contract Foo {byte bar;}`, options)).toThrow( + "We couldn't infer a Solidity version based on the pragma statements" + ); + }); + + test('should throw an error if there are incompatible ranges and the syntax does not match with the latest supported version', function () { + expect(() => + createParser( + `pragma solidity ^0.8.0; pragma solidity 0.7.6;contract Foo {byte bar;}`, + options + ) + ).toThrow( + "We couldn't infer a Solidity version based on the pragma statements" + ); + }); + + test('should throw an error if the pragma statement is and the syntax do not match', function () { + expect(() => + createParser(`pragma solidity ^0.8.0;contract Foo {byte bar;}`, options) + ).toThrow( + 'Based on the pragma statements, we inferred your code to be using Solidity version' + ); }); });