Skip to content

Commit 335739b

Browse files
Hide underlying debug adapter from the user (swiftlang#1024)
Always generate swift-lldb launch configurations that delegate to the correct debug adapter. Work around the lack of CodeLLDB support on Windows arm64 by forcing the use of lldb-dap in this case.
1 parent 4fd1e41 commit 335739b

File tree

13 files changed

+201
-92
lines changed

13 files changed

+201
-92
lines changed

Diff for: assets/test/.vscode/launch.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"configurations": [
33
{
4-
"type": "lldb",
4+
"type": "swift-lldb",
55
"request": "launch",
66
"sourceLanguages": [
77
"swift"
@@ -13,7 +13,7 @@
1313
"preLaunchTask": "swift: Build Debug PackageExe (defaultPackage)"
1414
},
1515
{
16-
"type": "lldb",
16+
"type": "swift-lldb",
1717
"request": "launch",
1818
"sourceLanguages": [
1919
"swift"

Diff for: assets/test/defaultPackage/.vscode/launch.json

+2-8
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,17 @@
11
{
22
"configurations": [
33
{
4-
"type": "lldb",
4+
"type": "swift-lldb",
55
"request": "launch",
6-
"sourceLanguages": [
7-
"swift"
8-
],
96
"name": "Debug package1",
107
"program": "${workspaceFolder:defaultPackage}/.build/debug/package1",
118
"args": [],
129
"cwd": "${workspaceFolder:defaultPackage}",
1310
"preLaunchTask": "swift: Build Debug package1"
1411
},
1512
{
16-
"type": "lldb",
13+
"type": "swift-lldb",
1714
"request": "launch",
18-
"sourceLanguages": [
19-
"swift"
20-
],
2115
"name": "Release package1",
2216
"program": "${workspaceFolder:defaultPackage}/.build/release/package1",
2317
"args": [],

Diff for: assets/test/diagnostics/.vscode/launch.json

+4-16
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,35 @@
11
{
22
"configurations": [
33
{
4-
"type": "lldb",
4+
"type": "swift-lldb",
55
"request": "launch",
6-
"sourceLanguages": [
7-
"swift"
8-
],
96
"args": [],
107
"cwd": "${workspaceFolder:diagnostics}",
118
"name": "Debug diagnostics",
129
"program": "${workspaceFolder:diagnostics}/.build/debug/diagnostics",
1310
"preLaunchTask": "swift: Build Debug diagnostics"
1411
},
1512
{
16-
"type": "lldb",
13+
"type": "swift-lldb",
1714
"request": "launch",
18-
"sourceLanguages": [
19-
"swift"
20-
],
2115
"args": [],
2216
"cwd": "${workspaceFolder:diagnostics}",
2317
"name": "Release diagnostics",
2418
"program": "${workspaceFolder:diagnostics}/.build/release/diagnostics",
2519
"preLaunchTask": "swift: Build Release diagnostics"
2620
},
2721
{
28-
"type": "lldb",
22+
"type": "swift-lldb",
2923
"request": "launch",
30-
"sourceLanguages": [
31-
"swift"
32-
],
3324
"args": [],
3425
"cwd": "${workspaceFolder:diagnostics}",
3526
"name": "Debug diagnostics",
3627
"program": "${workspaceFolder:diagnostics}/.build/debug/diagnostics",
3728
"preLaunchTask": "swift: Build Debug diagnostics"
3829
},
3930
{
40-
"type": "lldb",
31+
"type": "swift-lldb",
4132
"request": "launch",
42-
"sourceLanguages": [
43-
"swift"
44-
],
4533
"args": [],
4634
"cwd": "${workspaceFolder:diagnostics}",
4735
"name": "Release diagnostics",

Diff for: package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@
558558
"swift.debugger.useDebugAdapterFromToolchain": {
559559
"type": "boolean",
560560
"default": false,
561-
"markdownDescription": "Use lldb debug adapter packaged with Swift toolchain as your debug adapter. This is currently only available on Windows or platforms using Swift 6",
561+
"markdownDescription": "Use the LLDB debug adapter packaged with the Swift toolchain as your debug adapter. Note: this is only available starting with Swift 6. The CodeLLDB extension will be used if your Swift toolchain does not contain lldb-dap.",
562562
"order": 1
563563
},
564564
"swift.debugger.path": {
@@ -1075,12 +1075,12 @@
10751075
"array",
10761076
"string"
10771077
],
1078-
"description": "Program arguments.",
1078+
"description": "Arguments to provide to the program.",
10791079
"default": []
10801080
},
10811081
"cwd": {
10821082
"type": "string",
1083-
"description": "Program working directory.",
1083+
"description": "The working directory that the program will be launched within.",
10841084
"default": "${workspaceRoot}"
10851085
},
10861086
"env": {
@@ -1277,9 +1277,9 @@
12771277
"format": "prettier --check *.json src test",
12781278
"pretest": "npm run compile && find ./assets/test -type d -name '.build' -exec rm -rf {} + && find . -type d -name 'Package.resolved' -exec rm -rf {} + && tsc -p ./",
12791279
"test": "vscode-test",
1280-
"integration-test": "vscode-test --label integrationTests",
1281-
"unit-test": "vscode-test --label unitTests",
1282-
"coverage": "npm run compile-tests && vscode-test --coverage",
1280+
"integration-test": "npm test -- --label integrationTests",
1281+
"unit-test": "npm test -- --label unitTests",
1282+
"coverage": "npm test -- --coverage",
12831283
"compile-tests": "find ./assets/test -type d -name '.build' -exec rm -rf {} + && npm run compile && npm run esbuild",
12841284
"package": "vsce package",
12851285
"dev-package": "vsce package --no-update-package-json 1.11.1-dev",

Diff for: src/WorkspaceContext.ts

+1-19
Original file line numberDiff line numberDiff line change
@@ -104,24 +104,6 @@ export class WorkspaceContext implements vscode.Disposable {
104104
}
105105
});
106106
}
107-
// on change of swift debugger type
108-
if (
109-
event.affectsConfiguration("swift.debugger.useDebugAdapterFromToolchain") ||
110-
event.affectsConfiguration("swift.debugger.path")
111-
) {
112-
if (configuration.debugger.useDebugAdapterFromToolchain) {
113-
if (!(await DebugAdapter.verifyDebugAdapterExists(this))) {
114-
return;
115-
}
116-
}
117-
this.folders.forEach(
118-
async ctx =>
119-
await makeDebugConfigurations(
120-
ctx,
121-
"Launch configurations need to be updated after changing the debug adapter."
122-
)
123-
);
124-
}
125107
});
126108
const backgroundCompilationOnDidSave = BackgroundCompilation.start(this);
127109
const contextKeysUpdate = this.observeFolders((folder, event) => {
@@ -443,7 +425,7 @@ export class WorkspaceContext implements vscode.Disposable {
443425
/** find LLDB version and setup path in CodeLLDB */
444426
async setLLDBVersion() {
445427
// check we are using CodeLLDB
446-
if (DebugAdapter.adapterName !== "lldb") {
428+
if (DebugAdapter.getDebugAdapterType(this.swiftVersion) !== "lldb-vscode") {
447429
return;
448430
}
449431
const libPathResult = await getLLDBLibPath(this.toolchain);

Diff for: src/configuration.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export interface LSPConfiguration {
4747

4848
/** debugger configuration */
4949
export interface DebuggerConfiguration {
50-
/** Are we using debug adapter provided with Toolchain */
50+
/** Whether or not to use CodeLLDB for debugging instead of lldb-dap */
5151
readonly useDebugAdapterFromToolchain: boolean;
5252
/** Return path to debug adapter */
5353
readonly customDebugAdapterPath: string;
@@ -151,8 +151,16 @@ const configuration = {
151151
/** debugger configuration */
152152
get debugger(): DebuggerConfiguration {
153153
return {
154-
/** Should we use the debug adapter included in the Toolchain or CodeLLDB */
155154
get useDebugAdapterFromToolchain(): boolean {
155+
// Enabled by default only when we're on Windows arm64 since CodeLLDB does not support
156+
// this platform and gives an awful error message.
157+
if (process.platform === "win32" && process.arch === "arm64") {
158+
// We need to use inspect to find out if the value is explicitly set.
159+
const inspect = vscode.workspace
160+
.getConfiguration("swift.debugger")
161+
.inspect<boolean>("useDebugAdapterFromToolchain");
162+
return inspect?.workspaceValue ?? inspect?.globalValue ?? true;
163+
}
156164
return vscode.workspace
157165
.getConfiguration("swift.debugger")
158166
.get<boolean>("useDebugAdapterFromToolchain", false);

Diff for: src/debugger/buildConfig.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,6 @@ export class TestingConfigurationFactory {
427427
return {
428428
type: DebugAdapter.adapterName,
429429
request: "custom",
430-
sourceLanguages: ["swift"],
431430
name: `Test ${this.ctx.swiftPackage.name}`,
432431
targetCreateCommands: [`file -a ${arch} ${xctestPath}/xctest`],
433432
processCreateCommands: [
@@ -639,8 +638,10 @@ function getBaseConfig(ctx: FolderContext, expandEnvVariables: boolean) {
639638

640639
export function getFolderAndNameSuffix(
641640
ctx: FolderContext,
642-
expandEnvVariables = false
641+
expandEnvVariables = false,
642+
platform?: "posix" | "win32"
643643
): { folder: string; nameSuffix: string } {
644+
const nodePath = platform === "posix" ? path.posix : platform === "win32" ? path.win32 : path;
644645
const workspaceFolder = expandEnvVariables
645646
? ctx.workspaceFolder.uri.fsPath
646647
: `\${workspaceFolder:${ctx.workspaceFolder.name}}`;
@@ -650,7 +651,7 @@ export function getFolderAndNameSuffix(
650651
folder = workspaceFolder;
651652
nameSuffix = "";
652653
} else {
653-
folder = path.join(workspaceFolder, ctx.relativePath);
654+
folder = nodePath.join(workspaceFolder, ctx.relativePath);
654655
nameSuffix = ` (${ctx.relativePath})`;
655656
}
656657
return { folder: folder, nameSuffix: nameSuffix };

Diff for: src/debugger/debugAdapter.ts

+8-11
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,17 @@ import { SwiftToolchain } from "../toolchain/toolchain";
2424
* Class managing which debug adapter we are using. Will only setup lldb-vscode/lldb-dap if it is available.
2525
*/
2626
export class DebugAdapter {
27-
private static debugAdapaterExists = false;
28-
2927
/** Debug adapter name */
3028
public static get adapterName(): string {
31-
return configuration.debugger.useDebugAdapterFromToolchain && this.debugAdapaterExists
32-
? "swift-lldb"
33-
: "lldb";
29+
return "swift-lldb";
3430
}
3531

3632
/** Return debug adapter for toolchain */
37-
public static getDebugAdapter(swiftVersion: Version): "lldb-vscode" | "lldb-dap" {
38-
return swiftVersion.isLessThan(new Version(6, 0, 0)) ? "lldb-vscode" : "lldb-dap";
33+
public static getDebugAdapterType(swiftVersion: Version): "lldb-vscode" | "lldb-dap" {
34+
return swiftVersion.isGreaterThanOrEqual(new Version(6, 0, 0)) &&
35+
configuration.debugger.useDebugAdapterFromToolchain
36+
? "lldb-dap"
37+
: "lldb-vscode";
3938
}
4039

4140
/** Return the path to the debug adapter */
@@ -45,7 +44,7 @@ export class DebugAdapter {
4544
return customDebugAdapterPath;
4645
}
4746

48-
const debugAdapter = this.getDebugAdapter(toolchain.swiftVersion);
47+
const debugAdapter = this.getDebugAdapterType(toolchain.swiftVersion);
4948
if (process.platform === "darwin" && debugAdapter === "lldb-dap") {
5049
return await toolchain.getLLDBDebugAdapter();
5150
} else {
@@ -67,20 +66,18 @@ export class DebugAdapter {
6766

6867
if (!(await fileExists(lldbDebugAdapterPath))) {
6968
if (!quiet) {
70-
const debugAdapterName = this.getDebugAdapter(workspace.toolchain.swiftVersion);
69+
const debugAdapterName = this.getDebugAdapterType(workspace.toolchain.swiftVersion);
7170
vscode.window.showErrorMessage(
7271
configuration.debugger.customDebugAdapterPath.length > 0
7372
? `Cannot find ${debugAdapterName} debug adapter specified in setting Swift.Debugger.Path.`
7473
: `Cannot find ${debugAdapterName} debug adapter in your Swift toolchain.`
7574
);
7675
}
7776
workspace.outputChannel.log(`Failed to find ${lldbDebugAdapterPath}`);
78-
this.debugAdapaterExists = false;
7977
contextKeys.lldbVSCodeAvailable = false;
8078
return false;
8179
}
8280

83-
this.debugAdapaterExists = true;
8481
contextKeys.lldbVSCodeAvailable = true;
8582
return true;
8683
}

Diff for: src/debugger/debugAdapterFactory.ts

+26-9
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,25 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
import * as vscode from "vscode";
16+
import * as path from "path";
1617
import { WorkspaceContext } from "../WorkspaceContext";
1718
import { DebugAdapter } from "./debugAdapter";
19+
import { Version } from "../utilities/version";
1820

1921
export function registerLLDBDebugAdapter(workspaceContext: WorkspaceContext): vscode.Disposable {
2022
class LLDBDebugAdapterExecutableFactory implements vscode.DebugAdapterDescriptorFactory {
21-
createDebugAdapterDescriptor(
23+
async createDebugAdapterDescriptor(
2224
_session: vscode.DebugSession,
2325
executable: vscode.DebugAdapterExecutable | undefined
24-
): vscode.ProviderResult<vscode.DebugAdapterDescriptor> {
26+
): Promise<vscode.DebugAdapterDescriptor> {
2527
if (executable) {
2628
// make VS Code launch the debug adapter executable
2729
return executable;
2830
}
2931

30-
return DebugAdapter.debugAdapterPath(workspaceContext.toolchain)
31-
.then(path =>
32-
DebugAdapter.verifyDebugAdapterExists(workspaceContext).then(() => path)
33-
)
34-
.then(path => new vscode.DebugAdapterExecutable(path, [], {}));
32+
const adapterPath = await DebugAdapter.debugAdapterPath(workspaceContext.toolchain);
33+
await DebugAdapter.verifyDebugAdapterExists(workspaceContext);
34+
return new vscode.DebugAdapterExecutable(adapterPath, [], {});
3535
}
3636
}
3737

@@ -41,7 +41,10 @@ export function registerLLDBDebugAdapter(workspaceContext: WorkspaceContext): vs
4141
);
4242
const debugConfigProvider = vscode.debug.registerDebugConfigurationProvider(
4343
"swift-lldb",
44-
new LLDBDebugConfigurationProvider()
44+
new LLDBDebugConfigurationProvider(
45+
process.platform,
46+
workspaceContext.toolchain.swiftVersion
47+
)
4548
);
4649
return {
4750
dispose: () => {
@@ -60,14 +63,28 @@ export function registerLLDBDebugAdapter(workspaceContext: WorkspaceContext): vs
6063
* This could also be used to augment the configuration with values from the settings
6164
* althought it isn't at the moment.
6265
*/
63-
class LLDBDebugConfigurationProvider implements vscode.DebugConfigurationProvider {
66+
export class LLDBDebugConfigurationProvider implements vscode.DebugConfigurationProvider {
67+
constructor(
68+
private platform: NodeJS.Platform,
69+
private swiftVersion: Version
70+
) {}
71+
6472
async resolveDebugConfiguration(
6573
folder: vscode.WorkspaceFolder | undefined,
6674
launchConfig: vscode.DebugConfiguration,
6775
// eslint-disable-next-line @typescript-eslint/no-unused-vars
6876
cancellation?: vscode.CancellationToken
6977
): Promise<vscode.DebugConfiguration> {
7078
launchConfig.env = this.convertEnvironmentVariables(launchConfig.env);
79+
// Fix the program path on Windows to include the ".exe" extension
80+
if (this.platform === "win32" && path.extname(launchConfig.program) !== ".exe") {
81+
launchConfig.program += ".exe";
82+
}
83+
// Delegate to CodeLLDB if that's the debug adapter we have selected
84+
if (DebugAdapter.getDebugAdapterType(this.swiftVersion) === "lldb-vscode") {
85+
launchConfig.type = "lldb";
86+
launchConfig.sourceLanguages = ["swift"];
87+
}
7188
return launchConfig;
7289
}
7390

0 commit comments

Comments
 (0)