From 128d38648cc262beb877899df6b452b581b871ae Mon Sep 17 00:00:00 2001 From: Adam Fowler <adamfowler71@gmail.com> Date: Thu, 16 Mar 2023 17:23:16 +0000 Subject: [PATCH 1/4] Remove hard dependency with CodeLLDB --- package.json | 5 +---- src/WorkspaceContext.ts | 18 +++++++++++++++- src/debugger/lldb.ts | 48 +++++++++++++++++++++++++++++++++++++++++ src/extension.ts | 2 +- 4 files changed, 67 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 8369697a0..589b8e6bc 100644 --- a/package.json +++ b/package.json @@ -567,9 +567,6 @@ ] } }, - "extensionDependencies": [ - "vadimcn.vscode-lldb" - ], "scripts": { "vscode:prepublish": "npm run esbuild-base -- --minify", "esbuild-base": "esbuild ./src/extension.ts --bundle --outfile=dist/extension.js --external:vscode --format=cjs --platform=node --target=node16", @@ -608,4 +605,4 @@ "@types/lcov-parse": "1.0.0", "lcov-parse": "1.0.0" } -} \ No newline at end of file +} diff --git a/src/WorkspaceContext.ts b/src/WorkspaceContext.ts index 6ab270309..6c5599dc0 100644 --- a/src/WorkspaceContext.ts +++ b/src/WorkspaceContext.ts @@ -23,7 +23,7 @@ import { swiftLibraryPathKey, getErrorDescription, } from "./utilities/utilities"; -import { getLLDBLibPath } from "./debugger/lldb"; +import { checkLLDBInstalled, getLLDBLibPath } from "./debugger/lldb"; import { LanguageClientManager } from "./sourcekit-lsp/LanguageClientManager"; import { TemporaryFolder } from "./utilities/tempFolder"; import { SwiftToolchain } from "./toolchain/toolchain"; @@ -350,6 +350,22 @@ export class WorkspaceContext implements vscode.Disposable { return { dispose: () => this.observers.delete(fn) }; } + async setupLLDB() { + await checkLLDBInstalled().then( + async result => { + if (result) { + this.setLLDBVersion(); + } + }, + error => { + const errorMessage = `Error: ${getErrorDescription(error)}`; + vscode.window.showErrorMessage( + `Failed to setup CodeLLDB for debugging of Swift code. Debugging may produce unexpected results. ${errorMessage}` + ); + } + ); + } + /** find LLDB version and setup path in CodeLLDB */ async setLLDBVersion() { const libPathResult = await getLLDBLibPath(this.toolchain); diff --git a/src/debugger/lldb.ts b/src/debugger/lldb.ts index 78ac826db..29629ad0a 100644 --- a/src/debugger/lldb.ts +++ b/src/debugger/lldb.ts @@ -15,12 +15,60 @@ // Based on code taken from CodeLLDB https://github.com/vadimcn/vscode-lldb/ // LICENSED with MIT License +import * as vscode from "vscode"; import * as path from "path"; import * as fs from "fs/promises"; import { execFile } from "../utilities/utilities"; import { Result } from "../utilities/result"; import { SwiftToolchain } from "../toolchain/toolchain"; +/** + * Check if CodeLLDB extension is installed and offer to install it if it is not. + * @returns Whether extension was installed + */ +export async function checkLLDBInstalled(): Promise<boolean> { + const lldbExtension = vscode.extensions.getExtension("vadimcn.vscode-lldb"); + // if extension is in list return true + if (lldbExtension) { + return true; + } + + // otherwise display menu asking if user wants to install it + return new Promise<boolean>((resolve, reject) => { + vscode.window + .showWarningMessage( + "The Swift extension requires the CodeLLDB extension to enable debugging. Do you want to install it?", + "Yes", + "No" + ) + .then(async result => { + switch (result) { + case "Yes": + try { + await installCodeLLDB(); + return resolve(true); + } catch (error) { + return reject(error); + } + break; + case "No": + break; + } + return resolve(false); + }); + }); +} + +/** + * Install CodeLLDB extension + */ +async function installCodeLLDB() { + await vscode.commands.executeCommand( + "workbench.extensions.installExtension", + "vadimcn.vscode-lldb" + ); +} + /** * Get LLDB library for given LLDB executable * @param executable LLDB executable diff --git a/src/extension.ts b/src/extension.ts index 54832cf45..d7352df9a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -46,7 +46,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<Api> { context.subscriptions.push(workspaceContext); // setup swift version of LLDB. Don't await on this as it can run in the background - workspaceContext.setLLDBVersion(); + workspaceContext.setupLLDB(); // listen for workspace folder changes and active text editor changes workspaceContext.setupEventListeners(); From 1c9297a00242d5a310e0b01b01f35998ade0730e Mon Sep 17 00:00:00 2001 From: Adam Fowler <adamfowler71@gmail.com> Date: Thu, 16 Mar 2023 18:17:18 +0000 Subject: [PATCH 2/4] Add state to never ask about LLDB again --- src/WorkspaceContext.ts | 4 ++-- src/debugger/lldb.ts | 22 +++++++++++++++++----- src/extension.ts | 2 +- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/WorkspaceContext.ts b/src/WorkspaceContext.ts index 6c5599dc0..3ba16a6e9 100644 --- a/src/WorkspaceContext.ts +++ b/src/WorkspaceContext.ts @@ -350,8 +350,8 @@ export class WorkspaceContext implements vscode.Disposable { return { dispose: () => this.observers.delete(fn) }; } - async setupLLDB() { - await checkLLDBInstalled().then( + async setupLLDB(extContext: vscode.ExtensionContext) { + await checkLLDBInstalled(extContext.globalState).then( async result => { if (result) { this.setLLDBVersion(); diff --git a/src/debugger/lldb.ts b/src/debugger/lldb.ts index 29629ad0a..2e14f8b05 100644 --- a/src/debugger/lldb.ts +++ b/src/debugger/lldb.ts @@ -26,20 +26,29 @@ import { SwiftToolchain } from "../toolchain/toolchain"; * Check if CodeLLDB extension is installed and offer to install it if it is not. * @returns Whether extension was installed */ -export async function checkLLDBInstalled(): Promise<boolean> { +export async function checkLLDBInstalled(workspaceState: vscode.Memento): Promise<boolean> { const lldbExtension = vscode.extensions.getExtension("vadimcn.vscode-lldb"); // if extension is in list return true if (lldbExtension) { + // reset skip check flag + workspaceState.update("skip-check-lldb", false); return true; } - + // if workspace is set to ignore LLDB check then return + if (workspaceState.get("skip-check-lldb") === true) { + return false; + } // otherwise display menu asking if user wants to install it return new Promise<boolean>((resolve, reject) => { vscode.window .showWarningMessage( - "The Swift extension requires the CodeLLDB extension to enable debugging. Do you want to install it?", + "Do you want to install the CodeLLDB extension?", + { + modal: true, + detail: "The Swift extension requires it to enable debugging.", + }, "Yes", - "No" + "Never" ) .then(async result => { switch (result) { @@ -51,7 +60,10 @@ export async function checkLLDBInstalled(): Promise<boolean> { return reject(error); } break; - case "No": + case "Never": + workspaceState.update("skip-check-lldb", true); + break; + case undefined: break; } return resolve(false); diff --git a/src/extension.ts b/src/extension.ts index d7352df9a..5ca03dc66 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -46,7 +46,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<Api> { context.subscriptions.push(workspaceContext); // setup swift version of LLDB. Don't await on this as it can run in the background - workspaceContext.setupLLDB(); + workspaceContext.setupLLDB(context); // listen for workspace folder changes and active text editor changes workspaceContext.setupEventListeners(); From ceea97a6745826d3df1b627acdce8bf5e3a7f111 Mon Sep 17 00:00:00 2001 From: Adam Fowler <adamfowler71@gmail.com> Date: Thu, 16 Mar 2023 18:39:00 +0000 Subject: [PATCH 3/4] No need to install CodeLLDB for test anymore --- test/runTest.ts | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/test/runTest.ts b/test/runTest.ts index a4af7b377..7a7351171 100644 --- a/test/runTest.ts +++ b/test/runTest.ts @@ -12,13 +12,8 @@ // //===----------------------------------------------------------------------===// -import * as cp from "child_process"; import * as path from "path"; -import { - runTests, - downloadAndUnzipVSCode, - resolveCliPathFromVSCodeExecutablePath, -} from "@vscode/test-electron"; +import { runTests } from "@vscode/test-electron"; async function main() { try { @@ -30,22 +25,6 @@ async function main() { // Passed to --extensionTestsPath const extensionTestsPath = path.resolve(__dirname, "./suite/index"); - const vscodeExecutablePath = await downloadAndUnzipVSCode(); - const cliPath = resolveCliPathFromVSCodeExecutablePath(vscodeExecutablePath); - - // Use cp.spawn / cp.exec for custom setup - console.log(`${cliPath} --install-extension vadimcn.vscode-lldb`); - const { stdout, stderr } = cp.spawnSync( - cliPath, - ["--install-extension", "vadimcn.vscode-lldb"], - { - encoding: "utf-8", - stdio: "inherit", - } - ); - console.log(stdout); - console.log(stderr); - // Download VS Code, unzip it and run the integration test await runTests({ extensionDevelopmentPath, From 509fd9ea6e85f91ff6612dd8af1c37bcdfb673b4 Mon Sep 17 00:00:00 2001 From: Adam Fowler <adamfowler71@gmail.com> Date: Sat, 8 Apr 2023 19:02:08 +0100 Subject: [PATCH 4/4] Disable CodeLLDB dialog via setting --- package.json | 8 +++++++- src/WorkspaceContext.ts | 4 ++-- src/configuration.ts | 4 ++++ src/debugger/lldb.ts | 16 +++++----------- src/extension.ts | 2 +- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 589b8e6bc..d655b0d6b 100644 --- a/package.json +++ b/package.json @@ -328,6 +328,12 @@ "description": "The path of the SDK to compile against (`--sdk` parameter). The default SDK is determined by the environment on macOS and Windows.", "order": 3 }, + "swift.skipCodeLLDBCheck": { + "type": "boolean", + "default": false, + "description": "Skip check for CodeLLDB being installed.", + "order": 4 + }, "swift.diagnostics": { "type": "boolean", "default": false, @@ -605,4 +611,4 @@ "@types/lcov-parse": "1.0.0", "lcov-parse": "1.0.0" } -} +} \ No newline at end of file diff --git a/src/WorkspaceContext.ts b/src/WorkspaceContext.ts index 3ba16a6e9..6c5599dc0 100644 --- a/src/WorkspaceContext.ts +++ b/src/WorkspaceContext.ts @@ -350,8 +350,8 @@ export class WorkspaceContext implements vscode.Disposable { return { dispose: () => this.observers.delete(fn) }; } - async setupLLDB(extContext: vscode.ExtensionContext) { - await checkLLDBInstalled(extContext.globalState).then( + async setupLLDB() { + await checkLLDBInstalled().then( async result => { if (result) { this.setLLDBVersion(); diff --git a/src/configuration.ts b/src/configuration.ts index 4cddcbab4..d4004d4df 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -141,6 +141,10 @@ const configuration = { .get<boolean>("backgroundCompilation", false); }, /** output additional diagnostics */ + get skipCodeLLDBCheck(): boolean { + return vscode.workspace.getConfiguration("swift").get<boolean>("skipCodeLLDBCheck", false); + }, + /** output additional diagnostics */ get diagnostics(): boolean { return vscode.workspace.getConfiguration("swift").get<boolean>("diagnostics", false); }, diff --git a/src/debugger/lldb.ts b/src/debugger/lldb.ts index 2e14f8b05..92c579836 100644 --- a/src/debugger/lldb.ts +++ b/src/debugger/lldb.ts @@ -21,21 +21,20 @@ import * as fs from "fs/promises"; import { execFile } from "../utilities/utilities"; import { Result } from "../utilities/result"; import { SwiftToolchain } from "../toolchain/toolchain"; +import configuration from "../configuration"; /** * Check if CodeLLDB extension is installed and offer to install it if it is not. * @returns Whether extension was installed */ -export async function checkLLDBInstalled(workspaceState: vscode.Memento): Promise<boolean> { +export async function checkLLDBInstalled(): Promise<boolean> { const lldbExtension = vscode.extensions.getExtension("vadimcn.vscode-lldb"); // if extension is in list return true if (lldbExtension) { - // reset skip check flag - workspaceState.update("skip-check-lldb", false); return true; } // if workspace is set to ignore LLDB check then return - if (workspaceState.get("skip-check-lldb") === true) { + if (configuration.skipCodeLLDBCheck === true) { return false; } // otherwise display menu asking if user wants to install it @@ -47,22 +46,17 @@ export async function checkLLDBInstalled(workspaceState: vscode.Memento): Promis modal: true, detail: "The Swift extension requires it to enable debugging.", }, - "Yes", - "Never" + "Install" ) .then(async result => { switch (result) { - case "Yes": + case "Install": try { await installCodeLLDB(); return resolve(true); } catch (error) { return reject(error); } - break; - case "Never": - workspaceState.update("skip-check-lldb", true); - break; case undefined: break; } diff --git a/src/extension.ts b/src/extension.ts index 5ca03dc66..d7352df9a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -46,7 +46,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<Api> { context.subscriptions.push(workspaceContext); // setup swift version of LLDB. Don't await on this as it can run in the background - workspaceContext.setupLLDB(context); + workspaceContext.setupLLDB(); // listen for workspace folder changes and active text editor changes workspaceContext.setupEventListeners();