Skip to content

Commit c900d61

Browse files
authored
better handling of empty array from inferLanguage (#1175)
1 parent 796f6ca commit c900d61

2 files changed

Lines changed: 70 additions & 29 deletions

File tree

src/slang-utils/create-parser.ts

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ function parserAndOutput(
2121
};
2222
}
2323

24+
function createError(
25+
{ parseOutput }: { parseOutput: ParseOutput },
26+
reason: string
27+
): Error {
28+
return new Error(
29+
`We encountered the following syntax error:\n\n\t${parseOutput.errors()[0].message}\n\n${reason}`
30+
);
31+
}
32+
2433
export function createParser(
2534
text: string,
2635
options: ParserOptions<AstNode>
@@ -30,34 +39,41 @@ export function createParser(
3039
const result = parserAndOutput(text, compiler);
3140

3241
if (!result.parseOutput.isValid())
33-
throw new Error(
34-
`We encountered the following syntax error:\n\n\t${
35-
result.parseOutput.errors()[0].message
36-
}\n\nBased on the compiler option provided, we inferred your code to be using Solidity version ${
42+
throw createError(
43+
result,
44+
`Based on the compiler option provided, we inferred your code to be using Solidity version ${
3745
result.parser.languageVersion
3846
}. If you would like to change that, specify a different version in your \`.prettierrc\` file.`
3947
);
4048

4149
return result;
4250
}
51+
4352
const inferredRanges: string[] = LanguageFacts.inferLanguageVersions(text);
4453
const inferredLength = inferredRanges.length;
4554

46-
if (inferredLength === 0) {
47-
throw new Error(
48-
`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.`
55+
if (inferredLength === 0 || inferredLength === supportedLength) {
56+
const result = parserAndOutput(
57+
text,
58+
supportedVersions[supportedLength - 1]
4959
);
60+
61+
if (!result.parseOutput.isValid())
62+
throw createError(
63+
result,
64+
`We couldn't infer a Solidity version based on the pragma statements in your code so we defaulted to ${
65+
result.parser.languageVersion
66+
}. 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.`
67+
);
68+
return result;
5069
}
51-
const result = parserAndOutput(
52-
text,
53-
inferredRanges[inferredLength === supportedLength ? inferredLength - 1 : 0]
54-
);
70+
71+
const result = parserAndOutput(text, inferredRanges[0]);
5572

5673
if (!result.parseOutput.isValid())
57-
throw new Error(
58-
`We encountered the following syntax error:\n\n\t${
59-
result.parseOutput.errors()[0].message
60-
}\n\nBased on the pragma statements, we inferred your code to be using Solidity version ${
74+
throw createError(
75+
result,
76+
`Based on the pragma statements, we inferred your code to be using Solidity version ${
6177
result.parser.languageVersion
6278
}. If you would like to change that, update the pragmas in your source file, or specify a version in your \`.prettierrc\` file.`
6379
);

tests/unit/slang-utils/create-parser.test.js

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,6 @@ describe('inferLanguage', function () {
1616
source: `pragma solidity 0.8.1;`,
1717
version: '0.8.1'
1818
},
19-
{
20-
description: 'With nightly commit',
21-
source: `pragma solidity 0.8.18-ci.2023.1.17+commit.e7b959af;`,
22-
version: '0.8.18',
23-
// TODO: unskip this test when addresses this issue
24-
// https://github.com/NomicFoundation/slang/issues/1346
25-
skip: true
26-
},
2719
{
2820
description: 'Caret range and pinned version',
2921
source: `pragma solidity ^0.8.0; pragma solidity 0.8.2;`,
@@ -84,9 +76,7 @@ describe('inferLanguage', function () {
8476
description:
8577
'should use the latest version if the range is outside the supported versions',
8678
source: `pragma solidity ^10.0.0;`,
87-
version: latestSupportedVersion,
88-
// TODO: unskip this test when slack fixes the error with ranges outside the supported versions.
89-
skip: true
79+
version: latestSupportedVersion
9080
}
9181
];
9282

@@ -120,9 +110,44 @@ describe('inferLanguage', function () {
120110
expect(parser.languageVersion).toEqual('0.8.0');
121111
});
122112

123-
test('should throw an error if there are incompatible ranges', function () {
113+
test('should throw if compiler option does not match the syntax', function () {
114+
expect(() =>
115+
createParser(`contract Foo {byte bar;}`, { compiler: '0.8.0' })
116+
).toThrow(
117+
'Based on the compiler option provided, we inferred your code to be using Solidity version'
118+
);
119+
});
120+
121+
test('should throw if pragma is outside the supported version and the syntax does not match with the latest supported version', function () {
122+
expect(() =>
123+
createParser(`pragma solidity 10.0.0;contract Foo {byte bar;}`, options)
124+
).toThrow(
125+
"We couldn't infer a Solidity version based on the pragma statements"
126+
);
127+
});
128+
129+
test('should throw if there is no pragma and the syntax does not match with the latest supported version', function () {
130+
expect(() => createParser(`contract Foo {byte bar;}`, options)).toThrow(
131+
"We couldn't infer a Solidity version based on the pragma statements"
132+
);
133+
});
134+
135+
test('should throw an error if there are incompatible ranges and the syntax does not match with the latest supported version', function () {
136+
expect(() =>
137+
createParser(
138+
`pragma solidity ^0.8.0; pragma solidity 0.7.6;contract Foo {byte bar;}`,
139+
options
140+
)
141+
).toThrow(
142+
"We couldn't infer a Solidity version based on the pragma statements"
143+
);
144+
});
145+
146+
test('should throw an error if the pragma statement is and the syntax do not match', function () {
124147
expect(() =>
125-
createParser(`pragma solidity ^0.8.0; pragma solidity 0.7.6;`, options)
126-
).toThrow();
148+
createParser(`pragma solidity ^0.8.0;contract Foo {byte bar;}`, options)
149+
).toThrow(
150+
'Based on the pragma statements, we inferred your code to be using Solidity version'
151+
);
127152
});
128153
});

0 commit comments

Comments
 (0)