From d5f2da12a8846ede46c4612d290189f2e0b62394 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Sat, 2 Nov 2024 01:21:45 -0400 Subject: [PATCH 1/5] Support Swift SDKs --- package.json | 9 ++++- src/commands/switchPlatform.ts | 44 +++++++++------------- src/configuration.ts | 9 ++++- src/extension.ts | 5 ++- src/sourcekit-lsp/LanguageClientManager.ts | 8 ++++ src/toolchain/BuildFlags.ts | 8 +++- 6 files changed, 52 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index daa7f45c1..0fcd7034e 100644 --- a/package.json +++ b/package.json @@ -165,7 +165,7 @@ }, { "command": "swift.switchPlatform", - "title": "Select Target Platform...", + "title": "Select Swift SDK...", "category": "Swift" }, { @@ -593,8 +593,15 @@ "type": "string", "default": "", "markdownDescription": "The path of the SDK to compile against (`--sdk` parameter). This is of use when supporting non-standard SDK layouts on Windows and using custom SDKs. The default SDK is determined by the environment on macOS and Windows.", + "deprecationMessage": "Please use `swift.swiftSDK` with a triple (such as `arm64-apple-ios`) or Swift SDK name instead.", "order": 3 }, + "swift.swiftSDK": { + "type": "string", + "default": "", + "markdownDescription": "The [Swift SDK](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0387-cross-compilation-destinations.md) to compile against (`--swift-sdk` parameter).", + "order": 4 + }, "swift.diagnostics": { "type": "boolean", "default": false, diff --git a/src/commands/switchPlatform.ts b/src/commands/switchPlatform.ts index 821a8ccfb..f9347acdf 100644 --- a/src/commands/switchPlatform.ts +++ b/src/commands/switchPlatform.ts @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// import * as vscode from "vscode"; -import { DarwinCompatibleTarget, SwiftToolchain } from "../toolchain/toolchain"; +import { DarwinCompatibleTarget, getDarwinTargetTriple } from "../toolchain/toolchain"; import configuration from "../configuration"; /** @@ -22,35 +22,27 @@ import configuration from "../configuration"; export async function switchPlatform() { const picked = await vscode.window.showQuickPick( [ - { value: undefined, label: "macOS" }, - { value: DarwinCompatibleTarget.iOS, label: "iOS" }, - { value: DarwinCompatibleTarget.tvOS, label: "tvOS" }, - { value: DarwinCompatibleTarget.watchOS, label: "watchOS" }, - { value: DarwinCompatibleTarget.visionOS, label: "visionOS" }, + { + value: undefined, + label: "macOS", + description: "default", + }, + ...[ + { value: DarwinCompatibleTarget.iOS, label: "iOS" }, + { value: DarwinCompatibleTarget.tvOS, label: "tvOS" }, + { value: DarwinCompatibleTarget.watchOS, label: "watchOS" }, + { value: DarwinCompatibleTarget.visionOS, label: "visionOS" }, + ].map(item => ({ + value: getDarwinTargetTriple(item.value), + description: getDarwinTargetTriple(item.value), + label: item.label, + })), ], { - placeHolder: "Select a new target", + placeHolder: "Select a Swift SDK platform", } ); if (picked) { - try { - const sdkForTarget = picked.value - ? await SwiftToolchain.getSDKForTarget(picked.value) - : ""; - if (sdkForTarget !== undefined) { - if (sdkForTarget !== "") { - configuration.sdk = sdkForTarget; - vscode.window.showWarningMessage( - `Selecting the ${picked.label} SDK will provide code editing support, but compiling with this SDK will have undefined results.` - ); - } else { - configuration.sdk = undefined; - } - } else { - vscode.window.showErrorMessage("Unable to obtain requested SDK path"); - } - } catch { - vscode.window.showErrorMessage("Unable to obtain requested SDK path"); - } + configuration.swiftSDK = picked.value; } } diff --git a/src/configuration.ts b/src/configuration.ts index f44051492..5a6cc3795 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -190,13 +190,20 @@ const configuration = { get runtimePath(): string { return vscode.workspace.getConfiguration("swift").get("runtimePath", ""); }, - /** Path to custom swift sdk */ + /** Path to custom --sdk */ get sdk(): string { return vscode.workspace.getConfiguration("swift").get("SDK", ""); }, set sdk(value: string | undefined) { vscode.workspace.getConfiguration("swift").update("SDK", value); }, + /** Path to custom --swift-sdk */ + get swiftSDK(): string { + return vscode.workspace.getConfiguration("swift").get("swiftSDK", ""); + }, + set swiftSDK(value: string | undefined) { + vscode.workspace.getConfiguration("swift").update("swiftSDK", value); + }, /** swift build arguments */ get buildArguments(): string[] { return vscode.workspace.getConfiguration("swift").get("buildArguments", []); diff --git a/src/extension.ts b/src/extension.ts index ee9367c60..ae994daf7 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -94,7 +94,10 @@ export async function activate(context: vscode.ExtensionContext): Promise Date: Sat, 2 Nov 2024 01:41:46 -0400 Subject: [PATCH 2/5] Fix tests --- src/toolchain/BuildFlags.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/toolchain/BuildFlags.ts b/src/toolchain/BuildFlags.ts index 4168d7080..182d72a98 100644 --- a/src/toolchain/BuildFlags.ts +++ b/src/toolchain/BuildFlags.ts @@ -75,7 +75,7 @@ export class BuildFlags { swiftpmSDKFlags(): string[] { const flags: string[] = []; if (configuration.sdk !== "") { - flags.push("--sdk", configuration.sdk); + flags.push("--sdk", configuration.sdk, ...this.swiftDriverTargetFlags(true)); } if (configuration.swiftSDK !== "") { flags.push("--swift-sdk", configuration.swiftSDK); From d9a6fe9ffc5175c8019465cea7e5f9eb06fdd20e Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Sat, 2 Nov 2024 19:23:37 -0400 Subject: [PATCH 3/5] Add more tests --- .../LanguageClientManager.test.ts | 19 +++++++++++++++++++ test/unit-tests/toolchain/BuildFlags.test.ts | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/test/unit-tests/sourcekit-lsp/LanguageClientManager.test.ts b/test/unit-tests/sourcekit-lsp/LanguageClientManager.test.ts index a1e563862..5eb1993cf 100644 --- a/test/unit-tests/sourcekit-lsp/LanguageClientManager.test.ts +++ b/test/unit-tests/sourcekit-lsp/LanguageClientManager.test.ts @@ -177,6 +177,25 @@ suite("LanguageClientManager Suite", () => { expect(languageClientMock.start).to.have.been.calledOnce; }); + test("launches SourceKit-LSP on startup with swiftSDK", async () => { + mockedConfig.swiftSDK = "arm64-apple-ios"; + + const sut = new LanguageClientManager(instance(mockedWorkspace)); + await waitForReturnedPromises(languageClientMock.start); + + expect(sut.state).to.equal(State.Running); + expect(mockedLangClientModule.LanguageClient).to.have.been.calledOnceWith( + /* id */ match.string, + /* name */ match.string, + /* serverOptions */ match.has("command", "/path/to/toolchain/bin/sourcekit-lsp"), + /* clientOptions */ match.hasNested( + "initializationOptions.swiftPM.swiftSDK", + "arm64-apple-ios" + ) + ); + expect(languageClientMock.start).to.have.been.calledOnce; + }); + test("notifies SourceKit-LSP of WorkspaceFolder changes", async () => { const folder1 = mockObject({ isRootFolder: false, diff --git a/test/unit-tests/toolchain/BuildFlags.test.ts b/test/unit-tests/toolchain/BuildFlags.test.ts index 0c1979546..aba7b7f40 100644 --- a/test/unit-tests/toolchain/BuildFlags.test.ts +++ b/test/unit-tests/toolchain/BuildFlags.test.ts @@ -78,9 +78,11 @@ suite("BuildFlags Test Suite", () => { suite("swiftpmSDKFlags", () => { const sdkConfig = mockGlobalValue(configuration, "sdk"); + const swiftSDKConfig = mockGlobalValue(configuration, "swiftSDK"); test("no configuration provided", async () => { sdkConfig.setValue(""); + swiftSDKConfig.setValue(""); expect(buildFlags.swiftpmSDKFlags()).to.be.an("array").that.is.empty; }); @@ -92,6 +94,22 @@ suite("BuildFlags Test Suite", () => { ]); }); + test("configuration provided for swiftSDK", () => { + swiftSDKConfig.setValue("arm64-apple-ios"); + expect(buildFlags.swiftpmSDKFlags()).to.deep.equal(["--swift-sdk", "arm64-apple-ios"]); + }); + + test("configuration provided for swiftSDK and sdk", () => { + sdkConfig.setValue("/some/other/full/test/path"); + swiftSDKConfig.setValue("arm64-apple-ios"); + expect(buildFlags.swiftpmSDKFlags()).to.deep.equal([ + "--sdk", + "/some/other/full/test/path", + "--swift-sdk", + "arm64-apple-ios", + ]); + }); + test("include target", () => { sdkConfig.setValue("/some/other/full/test/path/WatchOS.sdk"); expect(buildFlags.swiftpmSDKFlags()).to.deep.equal([ From 7a970e291131a1cf29551e9c33caa1ca26c14057 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Sat, 16 Nov 2024 00:20:11 -0500 Subject: [PATCH 4/5] Un-deprecate swift.SDK --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 61e5303b5..982431fa3 100644 --- a/package.json +++ b/package.json @@ -592,8 +592,7 @@ "swift.SDK": { "type": "string", "default": "", - "markdownDescription": "The path of the SDK to compile against (`--sdk` parameter). This is of use when supporting non-standard SDK layouts on Windows and using custom SDKs. The default SDK is determined by the environment on macOS and Windows.", - "deprecationMessage": "Please use `swift.swiftSDK` with a triple (such as `arm64-apple-ios`) or Swift SDK name instead.", + "markdownDescription": "The path of the SDK to compile against (`--sdk` parameter). This is of use when supporting non-standard SDK layouts on Windows and using custom SDKs. The default SDK is determined by the environment on macOS and Windows.\n\nFor SwiftPM projects, prefer using `swift.swiftSDK` with a triple (such as `arm64-apple-ios`) or Swift SDK name instead.", "order": 3 }, "swift.swiftSDK": { From a769ec235f887cef48ad78cb7100a0777c879637 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Sat, 16 Nov 2024 00:34:05 -0500 Subject: [PATCH 5/5] Revert switchPlatform changes --- package.json | 2 +- src/commands/switchPlatform.ts | 44 ++++++++++++++++++++-------------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/package.json b/package.json index 982431fa3..b1f5ccd64 100644 --- a/package.json +++ b/package.json @@ -165,7 +165,7 @@ }, { "command": "swift.switchPlatform", - "title": "Select Swift SDK...", + "title": "Select Target Platform...", "category": "Swift" }, { diff --git a/src/commands/switchPlatform.ts b/src/commands/switchPlatform.ts index f9347acdf..821a8ccfb 100644 --- a/src/commands/switchPlatform.ts +++ b/src/commands/switchPlatform.ts @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// import * as vscode from "vscode"; -import { DarwinCompatibleTarget, getDarwinTargetTriple } from "../toolchain/toolchain"; +import { DarwinCompatibleTarget, SwiftToolchain } from "../toolchain/toolchain"; import configuration from "../configuration"; /** @@ -22,27 +22,35 @@ import configuration from "../configuration"; export async function switchPlatform() { const picked = await vscode.window.showQuickPick( [ - { - value: undefined, - label: "macOS", - description: "default", - }, - ...[ - { value: DarwinCompatibleTarget.iOS, label: "iOS" }, - { value: DarwinCompatibleTarget.tvOS, label: "tvOS" }, - { value: DarwinCompatibleTarget.watchOS, label: "watchOS" }, - { value: DarwinCompatibleTarget.visionOS, label: "visionOS" }, - ].map(item => ({ - value: getDarwinTargetTriple(item.value), - description: getDarwinTargetTriple(item.value), - label: item.label, - })), + { value: undefined, label: "macOS" }, + { value: DarwinCompatibleTarget.iOS, label: "iOS" }, + { value: DarwinCompatibleTarget.tvOS, label: "tvOS" }, + { value: DarwinCompatibleTarget.watchOS, label: "watchOS" }, + { value: DarwinCompatibleTarget.visionOS, label: "visionOS" }, ], { - placeHolder: "Select a Swift SDK platform", + placeHolder: "Select a new target", } ); if (picked) { - configuration.swiftSDK = picked.value; + try { + const sdkForTarget = picked.value + ? await SwiftToolchain.getSDKForTarget(picked.value) + : ""; + if (sdkForTarget !== undefined) { + if (sdkForTarget !== "") { + configuration.sdk = sdkForTarget; + vscode.window.showWarningMessage( + `Selecting the ${picked.label} SDK will provide code editing support, but compiling with this SDK will have undefined results.` + ); + } else { + configuration.sdk = undefined; + } + } else { + vscode.window.showErrorMessage("Unable to obtain requested SDK path"); + } + } catch { + vscode.window.showErrorMessage("Unable to obtain requested SDK path"); + } } }