diff --git a/package-lock.json b/package-lock.json index 56b90e05..4b6ad1bb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "devDependencies": { "@types/glob": "^7.1.4", "@types/mocha": "^9.1.0", - "@types/node": "^12.12.70", + "@types/node": "^16.11.43", "@types/promise.any": "^2.0.0", "@types/proxyquire": "^1.3.28", "@types/vscode": "^1.68.0", @@ -31,10 +31,11 @@ "eslint": "^7.32.0", "glob": "^7.1.7", "mocha": "^9.2.0", + "node-fetch": "^3.2.6", "ts-loader": "^9.2.5", "typescript": "^4.4.3", "webpack": "^5.52.1", - "webpack-cli": "^4.5.0" + "webpack-cli": "^4.10.0" }, "engines": { "vscode": "^1.68.0" @@ -409,9 +410,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" + "version": "16.11.43", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.43.tgz", + "integrity": "sha512-GqWykok+3uocgfAJM8imbozrqLnPyTrpFlrryURQlw1EesPUCx5XxTiucWDSFF9/NUEXDuD4bnvHm8xfVGWTpQ==" }, "node_modules/@types/promise.any": { "version": "2.0.0", @@ -1342,6 +1343,15 @@ "node": ">= 8" } }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", + "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -1956,6 +1966,29 @@ "pend": "~1.2.0" } }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -2036,6 +2069,18 @@ "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==", "dev": true }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3266,6 +3311,43 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.6.tgz", + "integrity": "sha512-LAy/HZnLADOVkVPubaxHDft29booGglPFDr2Hw0J1AercRh01UiVFm++KMDnJeH9sHgNB4hsXPii7Sgym/sTbw==", + "dev": true, + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, "node_modules/node-releases": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz", @@ -4466,6 +4548,15 @@ "node": ">=10.13.0" } }, + "node_modules/web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/webpack": { "version": "5.73.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.73.0.tgz", @@ -5073,9 +5164,9 @@ "dev": true }, "@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==" + "version": "16.11.43", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.43.tgz", + "integrity": "sha512-GqWykok+3uocgfAJM8imbozrqLnPyTrpFlrryURQlw1EesPUCx5XxTiucWDSFF9/NUEXDuD4bnvHm8xfVGWTpQ==" }, "@types/promise.any": { "version": "2.0.0", @@ -5772,6 +5863,12 @@ "which": "^2.0.1" } }, + "data-uri-to-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", + "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==", + "dev": true + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -6231,6 +6328,16 @@ "pend": "~1.2.0" } }, + "fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "dev": true, + "requires": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + } + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -6290,6 +6397,15 @@ "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==", "dev": true }, + "formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, + "requires": { + "fetch-blob": "^3.1.2" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -7178,6 +7294,23 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "dev": true + }, + "node-fetch": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.2.6.tgz", + "integrity": "sha512-LAy/HZnLADOVkVPubaxHDft29booGglPFDr2Hw0J1AercRh01UiVFm++KMDnJeH9sHgNB4hsXPii7Sgym/sTbw==", + "dev": true, + "requires": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + } + }, "node-releases": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz", @@ -8027,6 +8160,12 @@ "graceful-fs": "^4.1.2" } }, + "web-streams-polyfill": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", + "dev": true + }, "webpack": { "version": "5.73.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.73.0.tgz", diff --git a/package.json b/package.json index e4c29a4c..c31caac0 100644 --- a/package.json +++ b/package.json @@ -207,7 +207,8 @@ "3.5.0", "3.4.2", "3.3.0", - "3.2.0" + "3.2.0", + "latest nightly" ], "default": "latest", "description": "The preferred Dafny version to use (overriden by custom compiler and language server paths, requires restart)." @@ -275,7 +276,7 @@ "devDependencies": { "@types/glob": "^7.1.4", "@types/mocha": "^9.1.0", - "@types/node": "^12.12.70", + "@types/node": "^16.11.43", "@types/promise.any": "^2.0.0", "@types/proxyquire": "^1.3.28", "@types/vscode": "^1.68.0", @@ -286,10 +287,11 @@ "eslint": "^7.32.0", "glob": "^7.1.7", "mocha": "^9.2.0", + "node-fetch": "^3.2.6", "ts-loader": "^9.2.5", "typescript": "^4.4.3", "webpack": "^5.52.1", - "webpack-cli": "^4.5.0" + "webpack-cli": "^4.10.0" }, "dependencies": { "extract-zip": "^2.0.1", diff --git a/src/constants.ts b/src/constants.ts index 76810ad0..0a794c37 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -45,7 +45,8 @@ export namespace DotnetConstants { } export namespace LanguageServerConstants { - export const Latest = 'latest'; + export const LatestStable = 'latest'; + export const LatestNightly = 'latest nightly'; export const LatestVersion = '3.7.0'; export const UnknownVersion = 'unknown'; export const DafnyGitUrl = 'https://github.com/dafny-lang/dafny.git'; diff --git a/src/extension.ts b/src/extension.ts index 6098df76..021b5e77 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -32,7 +32,6 @@ export async function deactivate(): Promise { export async function restartServer(): Promise { await extensionRuntime?.restart(); } - class ExtensionRuntime { private readonly installer: DafnyInstaller; private client?: DafnyLanguageClient; @@ -58,7 +57,7 @@ class ExtensionRuntime { return; } await createAndRegisterDafnyIntegration(this.context, this.client!, this.languageServerVersion!); - commands.registerCommand(DafnyCommands.RestartServer, restartServer), + commands.registerCommand(DafnyCommands.RestartServer, restartServer); this.statusOutput.appendLine('Dafny is ready'); } diff --git a/src/language/dafnyInstallation.ts b/src/language/dafnyInstallation.ts index ae19e7da..71274379 100644 --- a/src/language/dafnyInstallation.ts +++ b/src/language/dafnyInstallation.ts @@ -13,6 +13,10 @@ import { ConfigurationConstants, LanguageServerConstants } from '../constants'; import Configuration from '../configuration'; import { exec } from 'child_process'; import { chdir as processChdir, cwd as processCwd } from 'process'; +import { RequestInfo, RequestInit } from 'node-fetch'; + +const fetch = (url: RequestInfo, init?: RequestInit) => + import('node-fetch').then(({ default: fetch }) => fetch(url, init)); const execAsync = promisify(exec); @@ -24,21 +28,54 @@ function ifNullOrEmpty(a: string | null, b: string): string { return a === null || a === '' ? b : a; } -function getConfiguredVersion(): string { - const version = Configuration.get(ConfigurationConstants.PreferredVersion); - return version === LanguageServerConstants.Latest - ? LanguageServerConstants.LatestVersion - : version; +async function getConfiguredVersion(): Promise { + const [ _, version ] = await getConfiguredTagAndVersion(); + return version; +} + +let getConfiguredTagAndVersionCache: [string, string]; +async function getConfiguredTagAndVersion(): Promise<[string, string]> { + if(getConfiguredTagAndVersionCache === undefined) { + const result = await getConfiguredGitTagAndVersionUncached(); + if(getConfiguredTagAndVersionCache === undefined) { + getConfiguredTagAndVersionCache = result; + } + } + return getConfiguredTagAndVersionCache; +} + +async function getConfiguredGitTagAndVersionUncached(): Promise<[string, string]> { + let version = Configuration.get(ConfigurationConstants.PreferredVersion); + switch(version) { + case LanguageServerConstants.LatestStable: + version = LanguageServerConstants.LatestVersion; + break; + case LanguageServerConstants.LatestNightly: { + const result: any = await (await fetch('https://api.github.com/repos/dafny-lang/dafny/releases/tags/nightly')).json(); + if(result.name !== undefined) { + const name: string = result.name; + const versionPrefix = 'Dafny '; + if(name.startsWith(versionPrefix)) { + const version = name.substring(versionPrefix.length); + return [ 'nightly', version ]; + } + } + window.showWarningMessage('Failed to install latest nightly version of Dafny. Using latest stable version instead.\n' + + `The name of the nightly release we found was: ${result.name}`); + version = LanguageServerConstants.LatestVersion; + } + } + return [ `v${version}`, version ]; } export function isConfiguredToInstallLatestDafny(): boolean { - return Configuration.get(ConfigurationConstants.PreferredVersion) === LanguageServerConstants.Latest; + return Configuration.get(ConfigurationConstants.PreferredVersion) === LanguageServerConstants.LatestStable; } -export function getCompilerRuntimePath(context: ExtensionContext): string { +export async function getCompilerRuntimePath(context: ExtensionContext): Promise { const configuredPath = ifNullOrEmpty( Configuration.get(ConfigurationConstants.Compiler.RuntimePath), - LanguageServerConstants.GetDefaultCompilerPath(getConfiguredVersion()) + LanguageServerConstants.GetDefaultCompilerPath(await getConfiguredVersion()) ); if(!path.isAbsolute(configuredPath)) { return path.join(context.extensionPath, configuredPath); @@ -46,10 +83,10 @@ export function getCompilerRuntimePath(context: ExtensionContext): string { return configuredPath; } -export function getLanguageServerRuntimePath(context: ExtensionContext): string { +export async function getLanguageServerRuntimePath(context: ExtensionContext): Promise { const configuredPath = ifNullOrEmpty( getConfiguredLanguageServerRuntimePath(), - LanguageServerConstants.GetDefaultPath(getConfiguredVersion()) + LanguageServerConstants.GetDefaultPath(await getConfiguredVersion()) ); if(path.isAbsolute(configuredPath)) { return configuredPath; @@ -77,11 +114,11 @@ function getDafnyPlatformSuffix(): string { } } -function getDafnyDownloadAddress(): string { +async function getDafnyDownloadAddress(): Promise { const baseUri = LanguageServerConstants.DownloadBaseUri; - const version = getConfiguredVersion(); + const [ tag, version ] = await getConfiguredTagAndVersion(); const suffix = getDafnyPlatformSuffix(); - return `${baseUri}/v${version}/dafny-${version}-x64-${suffix}.zip`; + return `${baseUri}/${tag}/dafny-${version}-x64-${suffix}.zip`; } export class DafnyInstaller { @@ -124,7 +161,7 @@ export class DafnyInstaller { this.writeStatus(`Found a non-supported architecture OSX:${os.arch()}. Going to install from source.`); return await this.installFromSource(); } else { - const archive = await this.downloadArchive(getDafnyDownloadAddress()); + const archive = await this.downloadArchive(await getDafnyDownloadAddress()); await this.extractArchive(archive); await workspace.fs.delete(archive, { useTrash: false }); this.writeStatus('Dafny installation completed'); @@ -153,7 +190,7 @@ export class DafnyInstaller { } private async installFromSource() { - const installationPath = this.getCustomInstallationPath(os.arch()); + const installationPath = await this.getCustomInstallationPath(os.arch()); await mkdirAsync(installationPath.fsPath, { recursive: true }); this.writeStatus(`Installing Dafny from source in ${installationPath.fsPath}.\n`); const previousDirectory = processCwd(); @@ -189,7 +226,7 @@ export class DafnyInstaller { await this.execLog(`git clone --recurse-submodules ${LanguageServerConstants.DafnyGitUrl}`); processChdir(Utils.joinPath(installationPath, 'dafny').fsPath); await this.execLog('git fetch --all --tags'); - await this.execLog(`git checkout v${getConfiguredVersion()}`); + await this.execLog(`git checkout v${await getConfiguredVersion()}`); await this.execLog('make exe'); const binaries = Utils.joinPath(installationPath, 'dafny', 'Binaries').fsPath; processChdir(binaries); @@ -199,7 +236,7 @@ export class DafnyInstaller { await this.execLog(`wget ${z3urlOsx}`); await this.execLog(`unzip ${z3filenameOsx}.zip`); await this.execLog(`mv ${z3filenameOsx} z3`); - processChdir(this.getInstallationPath().fsPath); + processChdir((await this.getInstallationPath()).fsPath); await this.execLog('mkdir -p ./dafny/'); await this.execLog(`cp -R ${binaries}/* ./dafny/`); processChdir(previousDirectory); @@ -211,7 +248,7 @@ export class DafnyInstaller { } public async isLanguageServerRuntimeAccessible(): Promise { - const languageServerDll = getLanguageServerRuntimePath(this.context); + const languageServerDll = await getLanguageServerRuntimePath(this.context); try { await fs.promises.access(languageServerDll, fs.constants.R_OK); return true; @@ -221,7 +258,7 @@ export class DafnyInstaller { } private async cleanInstallDir(): Promise { - const installPath = this.getInstallationPath(); + const installPath = await this.getInstallationPath(); this.writeStatus(`deleting previous Dafny installation at ${installPath.fsPath}`); try { await workspace.fs.delete( @@ -239,9 +276,9 @@ export class DafnyInstaller { } private async downloadArchive(downloadUri: string): Promise { - await mkdirAsync(this.getInstallationPath().fsPath, { recursive: true }); + await mkdirAsync((await this.getInstallationPath()).fsPath, { recursive: true }); + const archivePath = await this.getZipPath(); return await new Promise((resolve, reject) => { - const archivePath = this.getZipPath(); const archiveHandle = fs.createWriteStream(archivePath.fsPath); this.writeStatus(`downloading Dafny from ${downloadUri}`); const progressReporter = new ProgressReporter(this.statusOutput); @@ -256,7 +293,7 @@ export class DafnyInstaller { } private async extractArchive(archivePath: Uri): Promise { - const dirPath = this.getInstallationPath(); + const dirPath = await this.getInstallationPath(); this.writeStatus(`extracting Dafny to ${dirPath.fsPath}`); const progressReporter = new ProgressReporter(this.statusOutput); await extract( @@ -268,20 +305,20 @@ export class DafnyInstaller { ); } - private getZipPath(): Uri { - return Utils.joinPath(this.getInstallationPath(), ArchiveFileName); + private async getZipPath(): Promise { + return Utils.joinPath(await this.getInstallationPath(), ArchiveFileName); } - private getInstallationPath(): Uri { + private async getInstallationPath(): Promise { return Utils.joinPath( this.context.extensionUri, - ...LanguageServerConstants.GetResourceFolder(getConfiguredVersion()) + ...LanguageServerConstants.GetResourceFolder(await getConfiguredVersion()) ); } - private getCustomInstallationPath(typeArch: string): Uri { + private async getCustomInstallationPath(typeArch: string): Promise { return Utils.joinPath( - this.getInstallationPath(), 'custom', typeArch + await this.getInstallationPath(), 'custom', typeArch ); } diff --git a/src/language/dafnyLanguageClient.ts b/src/language/dafnyLanguageClient.ts index 376afc1f..7a7c88bb 100644 --- a/src/language/dafnyLanguageClient.ts +++ b/src/language/dafnyLanguageClient.ts @@ -95,7 +95,7 @@ export class DafnyLanguageClient extends LanguageClient { public static async create(context: ExtensionContext, statusOutput: OutputChannel): Promise { const { path: dotnetExecutable } = await getDotnetExecutablePath(); - const launchArguments = [ getLanguageServerRuntimePath(context), ...getLanguageServerLaunchArgs() ]; + const launchArguments = [ await getLanguageServerRuntimePath(context), ...getLanguageServerLaunchArgs() ]; statusOutput.appendLine(`Language server arguments: ${DafnyLanguageClient.argumentsToCommandLine(launchArguments)}`); const serverOptions: ServerOptions = { run: { command: dotnetExecutable, args: launchArguments }, diff --git a/src/test/suite/MockingUtils.ts b/src/test/suite/MockingUtils.ts index 4a4c00f0..fbf16451 100644 --- a/src/test/suite/MockingUtils.ts +++ b/src/test/suite/MockingUtils.ts @@ -50,7 +50,7 @@ export class MockingUtils { public static mockedWorkspace(): MockedWorkspace { return new MockedWorkspace({ [ConfigurationConstants.SectionName]: new Map([ - [ ConfigurationConstants.PreferredVersion, LanguageServerConstants.Latest ] + [ ConfigurationConstants.PreferredVersion, LanguageServerConstants.LatestStable ] ]) }); } diff --git a/src/ui/dafnyVersionView.ts b/src/ui/dafnyVersionView.ts index f4a41e5c..72221405 100644 --- a/src/ui/dafnyVersionView.ts +++ b/src/ui/dafnyVersionView.ts @@ -21,7 +21,7 @@ async function getTooltipText(context: ExtensionContext, languageServerVersion: async function getCompilerVersion(context: ExtensionContext): Promise { const { path: dotnetPath } = await getDotnetExecutablePath(); - const compilerPath = getCompilerRuntimePath(context); + const compilerPath = await getCompilerRuntimePath(context); try { const { stdout } = await execFileAsync(dotnetPath, [ compilerPath, CompilerVersionArg ]); const version = /\d+\.\d+\.\d+\.\d+/.exec(stdout); diff --git a/tsconfig.json b/tsconfig.json index f8368c86..789929d2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,7 @@ "lib": [ "es2019" ], + "outDir": "out", "sourceMap": true, "strict": true, "alwaysStrict": true,