Skip to content

Commit 9b9d57d

Browse files
committed
feat: Use the latest version support by Slang even if not resolved
This is arguably more useful approach - we designed our parser to be error-tolerant and it makes more sense to offer slightly incomplete experience rather than just suddenly turning off all features just because the user is using a slightly newer version that may not get full coverage.
1 parent 8fdc5a7 commit 9b9d57d

File tree

3 files changed

+29
-17
lines changed

3 files changed

+29
-17
lines changed

server/src/parser/slangHelpers.ts

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { TextDocument } from "vscode-languageserver-textdocument";
66
import { Range } from "vscode-languageserver-types";
77
import { Language } from "@nomicfoundation/slang/language";
88
import semver from "semver";
9+
import { Logger } from "../utils/Logger";
910
import { getPlatform } from "../utils/operatingSystem";
1011

1112
export type SlangNode = RuleNode | TokenNode;
@@ -46,21 +47,27 @@ export function isSlangSupported() {
4647
return SUPPORTED_PLATFORMS.includes(currentPlatform);
4748
}
4849

49-
export function getLanguage(versionPragmas: string[]): Language {
50-
const supportedVersions = Language.supportedVersions();
50+
export function resolveVersion(
51+
logger: Logger,
52+
versionPragmas: string[]
53+
): string {
54+
const versions = Language.supportedVersions();
5155

52-
const slangVersion = semver.maxSatisfying(
53-
supportedVersions,
54-
versionPragmas.join(" ")
55-
);
56+
const slangVersion = semver.maxSatisfying(versions, versionPragmas.join(" "));
5657

57-
if (slangVersion === null) {
58-
const latest = supportedVersions[supportedVersions.length - 1];
59-
throw new Error(
60-
`No Slang-supported version (latest: ${latest}) for Solidity found that satisfies the pragma directives: '${versionPragmas.join(
61-
" "
62-
)}'.`
58+
if (slangVersion !== null) {
59+
return slangVersion;
60+
} else {
61+
const latest = versions[versions.length - 1];
62+
63+
logger.error(
64+
new Error(
65+
`No Slang-supported version (latest: ${latest}) for Solidity found that satisfies the pragma directives: '${versionPragmas.join(
66+
" "
67+
)}'.`
68+
)
6369
);
70+
71+
return latest;
6472
}
65-
return new Language(slangVersion);
6673
}

server/src/services/documentSymbol/onDocumentSymbol.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@ import { DocumentSymbolParams } from "vscode-languageserver/node";
55
import { DocumentSymbol, SymbolInformation } from "vscode-languageserver-types";
66
import { analyze } from "@nomicfoundation/solidity-analyzer";
77
import _ from "lodash";
8+
import { Language } from "@nomicfoundation/slang/language";
89
import { RuleKind } from "@nomicfoundation/slang/kinds";
910
import { RuleNode } from "@nomicfoundation/slang/cst";
1011
import { ServerState } from "../../types";
11-
import { getLanguage } from "../../parser/slangHelpers";
12+
import { resolveVersion } from "../../parser/slangHelpers";
1213
import { SymbolTreeBuilder } from "./SymbolTreeBuilder";
1314
import { StructDefinition } from "./visitors/StructDefinition";
1415
import { StructMember } from "./visitors/StructMember";
@@ -53,8 +54,10 @@ export function onDocumentSymbol(serverState: ServerState) {
5354
const { versionPragmas } = analyze(text);
5455
span.finish();
5556

57+
const resolvedVersion = resolveVersion(logger, versionPragmas);
58+
5659
try {
57-
const language = getLanguage(versionPragmas);
60+
const language = new Language(resolvedVersion);
5861

5962
// Parse using slang
6063
span = transaction.startChild({ op: "slang-parsing" });

server/src/services/semanticHighlight/onSemanticTokensFull.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ import {
77
} from "vscode-languageserver-protocol";
88
import _, { Dictionary } from "lodash";
99
import { analyze } from "@nomicfoundation/solidity-analyzer";
10+
import { Language } from "@nomicfoundation/slang/language";
1011
import { RuleKind, TokenKind } from "@nomicfoundation/slang/kinds";
1112
import { TokenNode } from "@nomicfoundation/slang/cst";
1213
import { ServerState } from "../../types";
13-
import { getLanguage } from "../../parser/slangHelpers";
14+
import { resolveVersion } from "../../parser/slangHelpers";
1415
import { CustomTypeHighlighter } from "./highlighters/CustomTypeHighlighter";
1516
import { SemanticTokensBuilder } from "./SemanticTokensBuilder";
1617
import { FunctionDefinitionHighlighter } from "./highlighters/FunctionDefinitionHighlighter";
@@ -54,9 +55,10 @@ export function onSemanticTokensFull(serverState: ServerState) {
5455
const { versionPragmas } = analyze(text);
5556
span.finish();
5657

57-
const language = getLanguage(versionPragmas);
58+
const resolvedVersion = resolveVersion(logger, versionPragmas);
5859

5960
try {
61+
const language = new Language(resolvedVersion);
6062
// Parse using slang
6163
span = transaction.startChild({ op: "slang-parsing" });
6264

0 commit comments

Comments
 (0)