From faa0a3a1ceb207b9c1c863b974663824185d6afb Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Tue, 16 Apr 2024 01:34:38 -0400 Subject: [PATCH 01/12] Update Options.swift --- Sources/SwiftOptions/Options.swift | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Sources/SwiftOptions/Options.swift b/Sources/SwiftOptions/Options.swift index cd6e072f6..cd24b73bd 100644 --- a/Sources/SwiftOptions/Options.swift +++ b/Sources/SwiftOptions/Options.swift @@ -211,7 +211,9 @@ extension Option { public static let disableOnlyOneDependencyFile: Option = Option("-disable-only-one-dependency-file", .flag, attributes: [.doesNotAffectIncrementalBuild], helpText: "Disables incremental build optimization that only produces one dependencies file") public static let disableOsChecks: Option = Option("-disable-os-checks", .flag, attributes: [.noDriver], helpText: "Skip OS related diagnostics") public static let disableOsChecks_: Option = Option("--disable-os-checks", .flag, alias: Option.disableOsChecks, attributes: [.noDriver], helpText: "Skip OS related diagnostics") + public static let disableOssaCompleteLifetimes: Option = Option("-disable-ossa-complete-lifetimes", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Do not require linear OSSA lifetimes after SILGen") public static let disableOssaOpts: Option = Option("-disable-ossa-opts", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Don't run SIL OSSA optimization passes.") + public static let disableOssaVerifyComplete: Option = Option("-disable-ossa-verify-complete", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Do not verify linear OSSA lifetimes after SILGen") public static let disablePlaygroundTransform: Option = Option("-disable-playground-transform", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable playground transformation") public static let disablePreallocatedInstantiationCaches: Option = Option("-disable-preallocated-instantiation-caches", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Avoid preallocating metadata instantiation caches in globals") public static let disablePreviousImplementationCallsInDynamicReplacements: Option = Option("-disable-previous-implementation-calls-in-dynamic-replacements", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable calling the previous implementation in dynamic replacements") @@ -219,6 +221,7 @@ extension Option { public static let disableReadonlyStaticObjects: Option = Option("-disable-readonly-static-objects", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Avoid allocating static objects in a read-only data section") public static let disableReflectionMetadata: Option = Option("-disable-reflection-metadata", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable emission of reflection metadata for nominal types") public static let disableReflectionNames: Option = Option("-disable-reflection-names", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable emission of names of stored properties and enum cases inreflection metadata") + public static let disableStrictConcurrencyRegionBasedIsolation: Option = Option("-disable-region-based-isolation-with-strict-concurrency", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable region based isolation when running with strict concurrency enabled. Only enabled with asserts") public static let disableRelativeProtocolWitnessTables: Option = Option("-disable-relative-protocol-witness-tables", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Disable relative protocol witness tables") public static let disableRemoveDeprecatedCheck: Option = Option("-disable-remove-deprecated-check", .flag, attributes: [.noDriver], helpText: "Skip diagnosing removal of deprecated symbols") public static let disableRemoveDeprecatedCheck_: Option = Option("--disable-remove-deprecated-check", .flag, alias: Option.disableRemoveDeprecatedCheck, attributes: [.noDriver], helpText: "Skip diagnosing removal of deprecated symbols") @@ -304,6 +307,7 @@ extension Option { public static let emitDependencies: Option = Option("-emit-dependencies", .flag, attributes: [.frontend, .noInteractive, .supplementaryOutput], helpText: "Emit basic Make-compatible dependencies files") public static let emitDigesterBaselinePath: Option = Option("-emit-digester-baseline-path", .separate, attributes: [.noInteractive, .argumentIsPath, .supplementaryOutput], metaVar: "", helpText: "Emit a baseline file for the module to using the API digester") public static let emitDigesterBaseline: Option = Option("-emit-digester-baseline", .flag, attributes: [.noInteractive, .supplementaryOutput], helpText: "Emit a baseline file for the module using the API digester") + public static let emitEmptyObjectFile: Option = Option("-emit-empty-object-file", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Produce a valid but dummy object file when building a library module") public static let emitExecutable: Option = Option("-emit-executable", .flag, attributes: [.noInteractive, .doesNotAffectIncrementalBuild], helpText: "Emit a linked executable", group: .modes) public static let emitExtensionBlockSymbols: Option = Option("-emit-extension-block-symbols", .flag, attributes: [.helpHidden, .frontend, .noInteractive, .supplementaryOutput], helpText: "Emit 'swift.extension' symbols for extensions to external types instead of directly associating members and conformances with the extended nominal when generating symbol graphs") public static let emitFineGrainedDependencySourcefileDotFiles: Option = Option("-emit-fine-grained-dependency-sourcefile-dot-files", .flag, attributes: [.helpHidden, .frontend], helpText: "Emit dot files for every source file.") @@ -406,7 +410,6 @@ extension Option { public static let enableFragileResilientProtocolWitnesses: Option = Option("-enable-fragile-relative-protocol-tables", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable relative protocol witness tables") public static let enableImplicitBacktracingModuleImport: Option = Option("-enable-implicit-backtracing-module-import", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable the implicit import of the _Backtracing module.") public static let enableImplicitDynamic: Option = Option("-enable-implicit-dynamic", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Add 'dynamic' to all declarations") - public static let enableImportPtrauthFieldFunctionPointers: Option = Option("-enable-import-ptrauth-field-function-pointers", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable import of custom ptrauth qualified field function pointers") public static let enableIncrementalImports: Option = Option("-enable-incremental-imports", .flag, attributes: [.frontend], helpText: "Enable cross-module incremental build metadata and driver scheduling for Swift modules") public static let enableInferPublicConcurrentValue: Option = Option("-enable-infer-public-sendable", .flag, attributes: [.frontend, .noDriver], helpText: "Enable inference of Sendable conformances for public structs and enums") public static let enableInvalidEphemeralnessAsError: Option = Option("-enable-invalid-ephemeralness-as-error", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Diagnose invalid ephemeral to non-ephemeral conversions as errors") @@ -432,6 +435,7 @@ extension Option { public static let enableOperatorDesignatedTypes: Option = Option("-enable-operator-designated-types", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Enable operator designated types") public static let enableOssaCompleteLifetimes: Option = Option("-enable-ossa-complete-lifetimes", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Require linear OSSA lifetimes after SILGen") public static let enableOssaModules: Option = Option("-enable-ossa-modules", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Always serialize SIL in ossa form. If this flag is not passed in, when optimizing ownership will be lowered before serializing SIL") + public static let enableOssaVerifyComplete: Option = Option("-enable-ossa-verify-complete", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Verify linear OSSA lifetimes after SILGen") public static let enablePackMetadataStackPromotion: Option = Option("-enable-pack-metadata-stack-promotion=", .joined, attributes: [.helpHidden, .frontend, .noDriver], metaVar: "true|false", helpText: "Whether to skip heapifying stack metadata packs when possible.") public static let enablePackMetadataStackPromotionNoArg: Option = Option("-enable-pack-metadata-stack-promotion", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Skip heapifying stack metadata packs when possible.") public static let enablePrivateImports: Option = Option("-enable-private-imports", .flag, attributes: [.helpHidden, .frontend, .noInteractive], helpText: "Allows this module's internal and private API to be accessed") @@ -830,7 +834,7 @@ extension Option { public static let vfsoverlayEQ: Option = Option("-vfsoverlay=", .joined, alias: Option.vfsoverlay) public static let vfsoverlay: Option = Option("-vfsoverlay", .joinedOrSeparate, attributes: [.frontend, .argumentIsPath], helpText: "Add directory to VFS overlay file") public static let visualcToolsRoot: Option = Option("-visualc-tools-root", .separate, attributes: [.frontend, .argumentIsPath], metaVar: "", helpText: "VisualC++ Tools Root") - public static let visualcToolsVersion: Option = Option("-visualc-tools-version", .separate, attributes: [.frontend,], metaVar: "", helpText: "VisualC++ ToolSet Version") + public static let visualcToolsVersion: Option = Option("-visualc-tools-version", .separate, attributes: [.frontend], metaVar: "", helpText: "VisualC++ ToolSet Version") public static let v: Option = Option("-v", .flag, attributes: [.doesNotAffectIncrementalBuild], helpText: "Show commands to run and use verbose output") public static let warnConcurrency: Option = Option("-warn-concurrency", .flag, attributes: [.frontend, .doesNotAffectIncrementalBuild], helpText: "Warn about code that is unsafe according to the Swift Concurrency model and will become ill-formed in a future language version") public static let warnImplicitOverrides: Option = Option("-warn-implicit-overrides", .flag, attributes: [.frontend, .doesNotAffectIncrementalBuild], helpText: "Warn about implicit overrides of protocol members") @@ -844,6 +848,7 @@ extension Option { public static let warnSwift3ObjcInferenceMinimal: Option = Option("-warn-swift3-objc-inference-minimal", .flag, attributes: [.helpHidden, .frontend, .doesNotAffectIncrementalBuild], helpText: "Deprecated, has no effect") public static let warnSwift3ObjcInference: Option = Option("-warn-swift3-objc-inference", .flag, alias: Option.warnSwift3ObjcInferenceComplete, attributes: [.helpHidden, .frontend, .doesNotAffectIncrementalBuild]) public static let warningsAsErrors: Option = Option("-warnings-as-errors", .flag, attributes: [.frontend], helpText: "Treat warnings as errors") + public static let wasmPluginServerPath: Option = Option("-wasm-plugin-server-path", .separate, attributes: [.frontend, .noDriver], metaVar: "", helpText: "Path to the swift-wasm-plugin-server executable") public static let weakLinkAtTarget: Option = Option("-weak-link-at-target", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Weakly link symbols for declarations that were introduced at the deployment target. Symbols introduced before the deployment target are still strongly linked.") public static let wholeModuleOptimization: Option = Option("-whole-module-optimization", .flag, attributes: [.frontend, .noInteractive], helpText: "Optimize input files together instead of individually") public static let windowsSdkRoot: Option = Option("-windows-sdk-root", .separate, attributes: [.frontend, .argumentIsPath], metaVar: "", helpText: "Windows SDK Root") @@ -1055,7 +1060,9 @@ extension Option { Option.disableOnlyOneDependencyFile, Option.disableOsChecks, Option.disableOsChecks_, + Option.disableOssaCompleteLifetimes, Option.disableOssaOpts, + Option.disableOssaVerifyComplete, Option.disablePlaygroundTransform, Option.disablePreallocatedInstantiationCaches, Option.disablePreviousImplementationCallsInDynamicReplacements, @@ -1063,6 +1070,7 @@ extension Option { Option.disableReadonlyStaticObjects, Option.disableReflectionMetadata, Option.disableReflectionNames, + Option.disableStrictConcurrencyRegionBasedIsolation, Option.disableRelativeProtocolWitnessTables, Option.disableRemoveDeprecatedCheck, Option.disableRemoveDeprecatedCheck_, @@ -1148,6 +1156,7 @@ extension Option { Option.emitDependencies, Option.emitDigesterBaselinePath, Option.emitDigesterBaseline, + Option.emitEmptyObjectFile, Option.emitExecutable, Option.emitExtensionBlockSymbols, Option.emitFineGrainedDependencySourcefileDotFiles, @@ -1250,7 +1259,6 @@ extension Option { Option.enableFragileResilientProtocolWitnesses, Option.enableImplicitBacktracingModuleImport, Option.enableImplicitDynamic, - Option.enableImportPtrauthFieldFunctionPointers, Option.enableIncrementalImports, Option.enableInferPublicConcurrentValue, Option.enableInvalidEphemeralnessAsError, @@ -1276,6 +1284,7 @@ extension Option { Option.enableOperatorDesignatedTypes, Option.enableOssaCompleteLifetimes, Option.enableOssaModules, + Option.enableOssaVerifyComplete, Option.enablePackMetadataStackPromotion, Option.enablePackMetadataStackPromotionNoArg, Option.enablePrivateImports, @@ -1688,6 +1697,7 @@ extension Option { Option.warnSwift3ObjcInferenceMinimal, Option.warnSwift3ObjcInference, Option.warningsAsErrors, + Option.wasmPluginServerPath, Option.weakLinkAtTarget, Option.wholeModuleOptimization, Option.windowsSdkRoot, From d9e3c31360c3ee315529e5f3c81351326134e252 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Tue, 16 Apr 2024 01:35:08 -0400 Subject: [PATCH 02/12] Pass wasm-plugin-server-path to frontend --- .../SwiftDriver/Jobs/FrontendJobHelpers.swift | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift index 89dedeb32..a21043c1a 100644 --- a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift +++ b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift @@ -488,6 +488,11 @@ extension Driver { commandLine.appendFlag(.pluginPath) commandLine.appendPath(pluginPathRoot.localPluginPath) + + if isFrontendArgSupported(.wasmPluginServerPath) { + commandLine.appendFlag(.wasmPluginServerPath) + commandLine.appendPath(pluginPathRoot.wasmPluginServerPath) + } } } @@ -906,3 +911,15 @@ extension ParsedOptions { } } } + +extension VirtualPath { + // Given a virtual path pointing into a toolchain/SDK/platform, produce the + // path to `swift-wasm-plugin-server`. + fileprivate var wasmPluginServerPath: VirtualPath { +#if os(Windows) + self.appending(components: "bin", "swift-wasm-plugin-server.exe") +#else + self.appending(components: "bin", "swift-wasm-plugin-server") +#endif + } +} From 0081b2be4dbd31d19e721169ec6d41c9df2e73b6 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Tue, 16 Apr 2024 15:38:24 -0400 Subject: [PATCH 03/12] hasWasmPlugins --- .../SwiftDriver/Jobs/FrontendJobHelpers.swift | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift index a21043c1a..7fe669421 100644 --- a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift +++ b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift @@ -489,7 +489,9 @@ extension Driver { commandLine.appendFlag(.pluginPath) commandLine.appendPath(pluginPathRoot.localPluginPath) - if isFrontendArgSupported(.wasmPluginServerPath) { + // Avoid cluttering the invocation with the wasm plugin server path unless + // the user has requested to load a wasm macro. + if isFrontendArgSupported(.wasmPluginServerPath) && parsedOptions.hasWasmPlugins { commandLine.appendFlag(.wasmPluginServerPath) commandLine.appendPath(pluginPathRoot.wasmPluginServerPath) } @@ -910,6 +912,19 @@ extension ParsedOptions { return experimentalFeatures.map(\.argument).map(\.asSingle).contains("Embedded") } } + + /// Checks whether there are any `-load-plugin-executable` arguments for WebAssembly plugins. + var hasWasmPlugins: Bool { + mutating get { + let loadPluginExecutables = self.arguments(for: .loadPluginExecutable) + return loadPluginExecutables.contains { option in + let argument = option.argument.asSingle + // the format is # + guard let separator = argument.lastIndex(of: "#") else { return false } + return argument[.. Date: Tue, 16 Apr 2024 16:24:22 -0400 Subject: [PATCH 04/12] Add test for wasm plugins --- Tests/SwiftDriverTests/SwiftDriverTests.swift | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index fc63d9ca4..6f46af15a 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -7335,7 +7335,7 @@ final class SwiftDriverTests: XCTestCase { func pluginPathTest(platform: String, sdk: String, searchPlatform: String) throws { let sdkRoot = try testInputsPath.appending( components: ["Platform Checks", "\(platform).platform", "Developer", "SDKs", "\(sdk).sdk"]) - var driver = try Driver(args: ["swiftc", "-typecheck", "foo.swift", "-sdk", VirtualPath.absolute(sdkRoot).name, "-plugin-path", "PluginA", "-external-plugin-path", "Plugin~B#Bexe", "-load-plugin-library", "PluginB2", "-plugin-path", "PluginC", "-working-directory", "/tmp"]) + var driver = try Driver(args: ["swiftc", "-typecheck", "foo.swift", "-sdk", VirtualPath.absolute(sdkRoot).name, "-plugin-path", "PluginA", "-external-plugin-path", "Plugin~B#Bexe", "-load-plugin-library", "PluginB2", "-plugin-path", "PluginC", "-load-plugin-executable", "PluginD#PluginD", "-working-directory", "/tmp"]) guard driver.isFrontendArgSupported(.pluginPath) && driver.isFrontendArgSupported(.externalPluginPath) else { return } @@ -7383,6 +7383,7 @@ final class SwiftDriverTests: XCTestCase { #endif XCTAssertTrue(job.commandLine.contains(.flag("-plugin-path"))) + XCTAssertFalse(job.commandLine.contains(.flag("-wasm-plugin-server-path"))) #if os(Windows) XCTAssertTrue(job.commandLine.contains(.path(.absolute(try driver.toolchain.executableDir.parentDirectory.appending(components: "bin"))))) #else @@ -7391,6 +7392,45 @@ final class SwiftDriverTests: XCTestCase { #endif } + func testWasmPlugins() throws { + let sdkRoot = try testInputsPath.appending( + components: ["Platform Checks", "iPhoneOS.platform", "Developer", "SDKs", "iPhoneOS13.0.sdk"]) + let executor = try SwiftDriverExecutor( + diagnosticsEngine: DiagnosticsEngine(handlers: [Driver.stderrDiagnosticsHandler]), + processSet: ProcessSet(), + fileSystem: localFileSystem, + env: [:] + ) + let executableDir = try AbsolutePath(validating: "/tmp/swift/bin") + var driver = try Driver( + args: ["swiftc", "-typecheck", "foo.swift", "-sdk", VirtualPath.absolute(sdkRoot).name, "-load-plugin-executable", "PluginA.wasm#ModuleA", "-working-directory", "/tmp"], + executor: executor, + compilerExecutableDir: executableDir + ) + guard driver.isFrontendArgSupported(.wasmPluginServerPath) else { + return + } + + let jobs = try driver.planBuild().removingAutolinkExtractJobs() + XCTAssertEqual(jobs.count, 1) + let job = jobs.first! + + // Check that the we have the plugin path + let pluginAIndex = job.commandLine.firstIndex(of: .path(VirtualPath.absolute(try .init(validating: "/tmp/PluginA.wasm#ModuleA")))) + print(job.commandLine) + XCTAssertNotNil(pluginAIndex) + + // Check that we also have the wasm plugin server path + let wasmPathOptionIndex = try XCTUnwrap(job.commandLine.firstIndex(of: "-wasm-plugin-server-path")) + let wasmPath = job.commandLine[wasmPathOptionIndex + 1] + #if os(Windows) + let expectedWasmServerPath = executableDir.appending(component: "swift-wasm-plugin-server.exe") + #else + let expectedWasmServerPath = executableDir.appending(component: "swift-wasm-plugin-server") + #endif + XCTAssertEqual(wasmPath, .path(.absolute(expectedWasmServerPath))) + } + func testClangModuleValidateOnce() throws { let flagTest = try Driver(args: ["swiftc", "-typecheck", "foo.swift"]) guard flagTest.isFrontendArgSupported(.clangBuildSessionFile), From fb902b124ee4043ede67016e662c8887e7ed2c22 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Tue, 16 Apr 2024 16:26:20 -0400 Subject: [PATCH 05/12] tweaks --- Tests/SwiftDriverTests/SwiftDriverTests.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index 6f46af15a..03cf06a68 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -7417,11 +7417,10 @@ final class SwiftDriverTests: XCTestCase { // Check that the we have the plugin path let pluginAIndex = job.commandLine.firstIndex(of: .path(VirtualPath.absolute(try .init(validating: "/tmp/PluginA.wasm#ModuleA")))) - print(job.commandLine) XCTAssertNotNil(pluginAIndex) // Check that we also have the wasm plugin server path - let wasmPathOptionIndex = try XCTUnwrap(job.commandLine.firstIndex(of: "-wasm-plugin-server-path")) + let wasmPathOptionIndex = try XCTUnwrap(job.commandLine.firstIndex(of: .flag("-wasm-plugin-server-path"))) let wasmPath = job.commandLine[wasmPathOptionIndex + 1] #if os(Windows) let expectedWasmServerPath = executableDir.appending(component: "swift-wasm-plugin-server.exe") From a6db182953102c28f6989e6bd92dd668935fb500 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Sat, 25 May 2024 19:22:22 -0400 Subject: [PATCH 06/12] swift-wasm-plugin-server => swift-plugin-server --- Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift | 14 +------------- .../SwiftDriver/Toolchains/DarwinToolchain.swift | 2 +- Tests/SwiftDriverTests/SwiftDriverTests.swift | 4 ++-- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift index c6731ddb5..4e5be1a56 100644 --- a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift +++ b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift @@ -795,7 +795,7 @@ extension Driver { // the user has requested to load a wasm macro. if isFrontendArgSupported(.wasmPluginServerPath) && parsedOptions.hasWasmPlugins { commandLine.appendFlag(.wasmPluginServerPath) - commandLine.appendPath(pluginPathRoot.wasmPluginServerPath) + commandLine.appendPath(pluginPathRoot.pluginServerPath) } } @@ -945,15 +945,3 @@ extension ParsedOptions { } } } - -extension VirtualPath { - // Given a virtual path pointing into a toolchain/SDK/platform, produce the - // path to `swift-wasm-plugin-server`. - fileprivate var wasmPluginServerPath: VirtualPath { -#if os(Windows) - self.appending(components: "bin", "swift-wasm-plugin-server.exe") -#else - self.appending(components: "bin", "swift-wasm-plugin-server") -#endif - } -} diff --git a/Sources/SwiftDriver/Toolchains/DarwinToolchain.swift b/Sources/SwiftDriver/Toolchains/DarwinToolchain.swift index 303d68bb6..05cb65038 100644 --- a/Sources/SwiftDriver/Toolchains/DarwinToolchain.swift +++ b/Sources/SwiftDriver/Toolchains/DarwinToolchain.swift @@ -484,7 +484,7 @@ private extension Version { extension VirtualPath { // Given a virtual path pointing into a toolchain/SDK/platform, produce the // path to `swift-plugin-server`. - fileprivate var pluginServerPath: VirtualPath { + var pluginServerPath: VirtualPath { #if os(Windows) self.appending(components: "bin", "swift-plugin-server.exe") #else diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index 7b38a620b..fa3015ef4 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -7494,9 +7494,9 @@ final class SwiftDriverTests: XCTestCase { let wasmPathOptionIndex = try XCTUnwrap(job.commandLine.firstIndex(of: .flag("-wasm-plugin-server-path"))) let wasmPath = job.commandLine[wasmPathOptionIndex + 1] #if os(Windows) - let expectedWasmServerPath = executableDir.appending(component: "swift-wasm-plugin-server.exe") + let expectedWasmServerPath = executableDir.appending(component: "swift-plugin-server.exe") #else - let expectedWasmServerPath = executableDir.appending(component: "swift-wasm-plugin-server") + let expectedWasmServerPath = executableDir.appending(component: "swift-plugin-server") #endif XCTAssertEqual(wasmPath, .path(.absolute(expectedWasmServerPath))) } From 39f0a6e260fdb120e0ba7f00ecbb0b610daad48e Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Sat, 25 May 2024 22:34:00 -0400 Subject: [PATCH 07/12] Use -load-plugin --- .../SwiftDriver/Jobs/FrontendJobHelpers.swift | 52 ++++++++++++------- Sources/SwiftOptions/Options.swift | 12 +++-- Tests/SwiftDriverTests/SwiftDriverTests.swift | 14 ++--- 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift index 4e5be1a56..c6460b4a2 100644 --- a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift +++ b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift @@ -309,7 +309,10 @@ extension Driver { } // Emit user-provided plugin paths, in order. - if isFrontendArgSupported(.externalPluginPath) { + if isFrontendArgSupported(.loadPlugin) { + try commandLine.appendAll(.pluginPath, .externalPluginPath, .loadPluginLibrary, .loadPlugin, from: &parsedOptions) + try addLoadPluginExecutableArguments(commandLine: &commandLine) + } else if isFrontendArgSupported(.externalPluginPath) { try commandLine.appendAll(.pluginPath, .externalPluginPath, .loadPluginLibrary, .loadPluginExecutable, from: &parsedOptions) } else if isFrontendArgSupported(.pluginPath) { try commandLine.appendAll(.pluginPath, .loadPluginLibrary, from: &parsedOptions) @@ -790,12 +793,36 @@ extension Driver { commandLine.appendFlag(.pluginPath) commandLine.appendPath(pluginPathRoot.localPluginPath) + } + + mutating func addLoadPluginExecutableArguments(commandLine: inout [Job.ArgTemplate]) throws { + var cachedPluginServerPath: VirtualPath? + var pluginServerPath: VirtualPath { + get throws { + if let cachedPluginServerPath = cachedPluginServerPath { + return cachedPluginServerPath + } + let pluginPathRoot = VirtualPath.absolute(try toolchain.executableDir.parentDirectory) + let pluginServerPath = pluginPathRoot.pluginServerPath + cachedPluginServerPath = pluginServerPath + return pluginServerPath + } + } + + for loadPluginExecutable in parsedOptions.arguments(for: .loadPluginExecutable) { + let argument = loadPluginExecutable.argument.asSingle + guard let separator = argument.lastIndex(of: "#") else { continue } + + let path = argument[..# - guard let separator = argument.lastIndex(of: "#") else { return false } - return argument[..#", helpText: "Path to a compiler plugin executable and a comma-separated list of module names where the macro types are declared", group: .pluginSearch) public static let loadPluginLibrary: Option = Option("-load-plugin-library", .separate, attributes: [.frontend, .doesNotAffectIncrementalBuild, .argumentIsPath], metaVar: "", helpText: "Path to a dynamic library containing compiler plugins such as macros", group: .pluginSearch) + public static let loadPlugin: Option = Option("-load-plugin", .separate, attributes: [.frontend, .doesNotAffectIncrementalBuild], metaVar: ":#", helpText: "Path to a plugin library, a server to load it in, and a comma-separated list of module names where the macro types are declared", group: .pluginSearch) public static let locale: Option = Option("-locale", .separate, attributes: [.frontend, .doesNotAffectIncrementalBuild], metaVar: "", helpText: "Choose a language for diagnostic messages") public static let localizationPath: Option = Option("-localization-path", .separate, attributes: [.frontend, .doesNotAffectIncrementalBuild, .argumentIsPath], metaVar: "", helpText: "Path to localized diagnostic messages directory") public static let location: Option = Option("-location", .separate, attributes: [.noDriver], metaVar: "", helpText: "Filter nodes with the given location.") @@ -775,6 +777,7 @@ extension Option { public static let suppressStaticExclusivitySwap: Option = Option("-suppress-static-exclusivity-swap", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Suppress static violations of exclusive access with swap()") public static let suppressWarnings: Option = Option("-suppress-warnings", .flag, attributes: [.frontend], helpText: "Suppress all warnings") public static let swiftAsyncFramePointerEQ: Option = Option("-swift-async-frame-pointer=", .joined, attributes: [.helpHidden, .frontend, .noDriver], helpText: "One of 'auto', 'always' or 'never'") + public static let swiftModuleCrossImport: Option = Option("-swift-module-cross-import", .multiArg, attributes: [.frontend, .noDriver], metaVar: " ", helpText: "Specify the cross import module", numArgs: 2) public static let swiftModuleFile: Option = Option("-swift-module-file=", .joined, attributes: [.frontend, .noDriver], metaVar: "=", helpText: "Specify Swift module input explicitly built from textual interface") public static let swiftOnly: Option = Option("-swift-only", .flag, attributes: [.noDriver], helpText: "Only include APIs defined from Swift source") public static let swiftOnly_: Option = Option("--swift-only", .flag, alias: Option.swiftOnly, attributes: [.noDriver], helpText: "Only include APIs defined from Swift source") @@ -856,7 +859,6 @@ extension Option { public static let warnSwift3ObjcInferenceMinimal: Option = Option("-warn-swift3-objc-inference-minimal", .flag, attributes: [.helpHidden, .frontend, .doesNotAffectIncrementalBuild], helpText: "Deprecated, has no effect") public static let warnSwift3ObjcInference: Option = Option("-warn-swift3-objc-inference", .flag, alias: Option.warnSwift3ObjcInferenceComplete, attributes: [.helpHidden, .frontend, .doesNotAffectIncrementalBuild]) public static let warningsAsErrors: Option = Option("-warnings-as-errors", .flag, attributes: [.frontend], helpText: "Treat warnings as errors") - public static let wasmPluginServerPath: Option = Option("-wasm-plugin-server-path", .separate, attributes: [.frontend, .noDriver], metaVar: "", helpText: "Path to the swift-wasm-plugin-server executable") public static let weakLinkAtTarget: Option = Option("-weak-link-at-target", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Weakly link symbols for declarations that were introduced at the deployment target. Symbols introduced before the deployment target are still strongly linked.") public static let wholeModuleOptimization: Option = Option("-whole-module-optimization", .flag, attributes: [.frontend, .noInteractive], helpText: "Optimize input files together instead of individually") public static let windowsSdkRoot: Option = Option("-windows-sdk-root", .separate, attributes: [.frontend, .argumentIsPath], metaVar: "", helpText: "Windows SDK Root") @@ -1021,6 +1023,7 @@ extension Option { Option.disableColocateTypeDescriptors, Option.disableConcreteTypeMetadataMangledNameAccessors, Option.disableConstraintSolverPerformanceHacks, + Option.disableCrossImportOverlaySearch, Option.disableCrossImportOverlays, Option.cxxInteropDisableRequirementAtImport, Option.disableDebuggerShadowCopies, @@ -1040,6 +1043,7 @@ extension Option { Option.disableGenericMetadataPrespecialization, Option.disableImplicitBacktracingModuleImport, Option.disableImplicitConcurrencyModuleImport, + Option.disableImplicitCxxModuleImport, Option.disableImplicitStringProcessingModuleImport, Option.disableImplicitSwiftModules, Option.disableImportPtrauthFieldFunctionPointers, @@ -1343,7 +1347,6 @@ extension Option { Option.experimentalPrintFullConvention, Option.experimentalSkipAllFunctionBodies, Option.experimentalSkipNonExportableDecls, - Option.experimentalSkipNonInlinableFunctionBodiesIsLazy, Option.experimentalSkipNonInlinableFunctionBodiesWithoutTypes, Option.experimentalSkipNonInlinableFunctionBodies, Option.experimentalSpiImports, @@ -1441,6 +1444,7 @@ extension Option { Option.reuseDependencyScanCache, Option.loadPluginExecutable, Option.loadPluginLibrary, + Option.loadPlugin, Option.locale, Option.localizationPath, Option.location, @@ -1632,6 +1636,7 @@ extension Option { Option.suppressStaticExclusivitySwap, Option.suppressWarnings, Option.swiftAsyncFramePointerEQ, + Option.swiftModuleCrossImport, Option.swiftModuleFile, Option.swiftOnly, Option.swiftOnly_, @@ -1713,7 +1718,6 @@ extension Option { Option.warnSwift3ObjcInferenceMinimal, Option.warnSwift3ObjcInference, Option.warningsAsErrors, - Option.wasmPluginServerPath, Option.weakLinkAtTarget, Option.wholeModuleOptimization, Option.windowsSdkRoot, diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index fa3015ef4..e4c2e444e 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -7478,7 +7478,7 @@ final class SwiftDriverTests: XCTestCase { executor: executor, compilerExecutableDir: executableDir ) - guard driver.isFrontendArgSupported(.wasmPluginServerPath) else { + guard driver.isFrontendArgSupported(.loadPlugin) else { return } @@ -7486,19 +7486,15 @@ final class SwiftDriverTests: XCTestCase { XCTAssertEqual(jobs.count, 1) let job = jobs.first! - // Check that the we have the plugin path - let pluginAIndex = job.commandLine.firstIndex(of: .path(VirtualPath.absolute(try .init(validating: "/tmp/PluginA.wasm#ModuleA")))) - XCTAssertNotNil(pluginAIndex) - - // Check that we also have the wasm plugin server path - let wasmPathOptionIndex = try XCTUnwrap(job.commandLine.firstIndex(of: .flag("-wasm-plugin-server-path"))) - let wasmPath = job.commandLine[wasmPathOptionIndex + 1] #if os(Windows) let expectedWasmServerPath = executableDir.appending(component: "swift-plugin-server.exe") #else let expectedWasmServerPath = executableDir.appending(component: "swift-plugin-server") #endif - XCTAssertEqual(wasmPath, .path(.absolute(expectedWasmServerPath))) + + // Check that the we have the plugin path + let pluginAIndex = job.commandLine.firstIndex(of: .flag("/tmp/PluginA.wasm:\(expectedWasmServerPath)#ModuleA")) + XCTAssertNotNil(pluginAIndex) } func testClangModuleValidateOnce() throws { From 1eb80db3d277d370dac5849591a6d7b9ca3a9fe7 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Sat, 25 May 2024 22:36:22 -0400 Subject: [PATCH 08/12] Move pluginServerPath extension --- Sources/SwiftDriver/Toolchains/DarwinToolchain.swift | 10 ---------- Sources/SwiftDriver/Toolchains/Toolchain.swift | 12 ++++++++++++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Sources/SwiftDriver/Toolchains/DarwinToolchain.swift b/Sources/SwiftDriver/Toolchains/DarwinToolchain.swift index 05cb65038..7cf4ca4e8 100644 --- a/Sources/SwiftDriver/Toolchains/DarwinToolchain.swift +++ b/Sources/SwiftDriver/Toolchains/DarwinToolchain.swift @@ -482,16 +482,6 @@ private extension Version { } extension VirtualPath { - // Given a virtual path pointing into a toolchain/SDK/platform, produce the - // path to `swift-plugin-server`. - var pluginServerPath: VirtualPath { -#if os(Windows) - self.appending(components: "bin", "swift-plugin-server.exe") -#else - self.appending(components: "bin", "swift-plugin-server") -#endif - } - // Given a virtual path pointing into a toolchain/SDK/platform, produce the // path to the plugins. var pluginPath: VirtualPath { diff --git a/Sources/SwiftDriver/Toolchains/Toolchain.swift b/Sources/SwiftDriver/Toolchains/Toolchain.swift index 214ff8597..3c3c685de 100644 --- a/Sources/SwiftDriver/Toolchains/Toolchain.swift +++ b/Sources/SwiftDriver/Toolchains/Toolchain.swift @@ -371,3 +371,15 @@ extension Toolchain { @_spi(Testing) public enum ToolchainError: Swift.Error { case unableToFind(tool: String) } + +extension VirtualPath { + // Given a virtual path pointing into a toolchain/SDK/platform, produce the + // path to `swift-plugin-server`. + var pluginServerPath: VirtualPath { +#if os(Windows) + self.appending(components: "bin", "swift-plugin-server.exe") +#else + self.appending(components: "bin", "swift-plugin-server") +#endif + } +} From 3e450cb6395b91c6488d25beb82a3468b0423bfb Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Sat, 25 May 2024 22:40:11 -0400 Subject: [PATCH 09/12] Tweaks --- Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift | 3 +++ Tests/SwiftDriverTests/SwiftDriverTests.swift | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift index c6460b4a2..d238427a1 100644 --- a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift +++ b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift @@ -795,6 +795,9 @@ extension Driver { commandLine.appendPath(pluginPathRoot.localPluginPath) } + /// Forward `-load-plugin-executable` arguments, with special handling for Wasm plugins. + /// + /// Wasm plugins are updated to use `-load-plugin` with the plugin server. mutating func addLoadPluginExecutableArguments(commandLine: inout [Job.ArgTemplate]) throws { var cachedPluginServerPath: VirtualPath? var pluginServerPath: VirtualPath { diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index e4c2e444e..d744e082d 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -7454,7 +7454,7 @@ final class SwiftDriverTests: XCTestCase { #endif XCTAssertTrue(job.commandLine.contains(.flag("-plugin-path"))) - XCTAssertFalse(job.commandLine.contains(.flag("-wasm-plugin-server-path"))) + XCTAssertFalse(job.commandLine.contains(.flag("-load-plugin"))) #if os(Windows) XCTAssertTrue(job.commandLine.contains(.path(.absolute(try driver.toolchain.executableDir.parentDirectory.appending(components: "bin"))))) #else From dc640ff5160e979eacc24b02e04dcf428f946289 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Wed, 12 Jun 2024 15:43:51 +0530 Subject: [PATCH 10/12] Preserve order of options --- .../SwiftDriver/Jobs/FrontendJobHelpers.swift | 67 +++++++++++-------- Tests/SwiftDriverTests/SwiftDriverTests.swift | 14 ++-- 2 files changed, 47 insertions(+), 34 deletions(-) diff --git a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift index 639c47ac2..3104d4a6d 100644 --- a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift +++ b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift @@ -313,8 +313,8 @@ extension Driver { // Emit user-provided plugin paths, in order. if isFrontendArgSupported(.loadPlugin) { - try commandLine.appendAll(.pluginPath, .externalPluginPath, .loadPluginLibrary, .loadPlugin, from: &parsedOptions) - try addLoadPluginExecutableArguments(commandLine: &commandLine) + let options = parsedOptions.arguments(for: .pluginPath, .externalPluginPath, .loadPluginLibrary, .loadPluginExecutable, .loadPlugin) + try commandLine.append(contentsOf: transformPluginOptions(options)) } else if isFrontendArgSupported(.externalPluginPath) { try commandLine.appendAll(.pluginPath, .externalPluginPath, .loadPluginLibrary, .loadPluginExecutable, from: &parsedOptions) } else if isFrontendArgSupported(.pluginPath) { @@ -804,40 +804,51 @@ extension Driver { commandLine.appendPath(pluginPathRoot.localPluginPath) } - /// Forward `-load-plugin-executable` arguments, with special handling for Wasm plugins. + /// Forward all plugin-related arguments, with special handling for Wasm plugins requested via `-load-plugin-executable`. /// /// Wasm plugins are updated to use `-load-plugin` with the plugin server. - mutating func addLoadPluginExecutableArguments(commandLine: inout [Job.ArgTemplate]) throws { - var cachedPluginServerPath: VirtualPath? - var pluginServerPath: VirtualPath { - get throws { - if let cachedPluginServerPath = cachedPluginServerPath { - return cachedPluginServerPath - } - let pluginPathRoot = VirtualPath.absolute(try toolchain.executableDir.parentDirectory) - let pluginServerPath = pluginPathRoot.pluginServerPath - cachedPluginServerPath = pluginServerPath - return pluginServerPath - } + private func transformPluginOptions(_ options: [ParsedOption]) throws -> [ParsedOption] { + lazy var pluginServerPathResult = Result { + VirtualPath.absolute(try toolchain.executableDir.parentDirectory).pluginServerPath + } + return try options.map { pluginOption in + try transformPluginOption( + pluginOption, + // Not the same as `pluginServerPath: pluginServerPathResult.get`. + // We want to ensure that `pluginServerPathResult` is lazily initialized. + pluginServerPath: { try pluginServerPathResult.get() } + ) + } + } + + /// Transforms a single plugin-related option to handle Wasm plugins. + /// + /// If the option is of the form `-load-plugin-executable foo.wasm`, it's updated to use + /// `-load-plugin` with the plugin server. Otherwise, it's returned unmodified. + private func transformPluginOption( + _ pluginOption: ParsedOption, + pluginServerPath: () throws -> VirtualPath + ) throws -> ParsedOption { + guard pluginOption.option == .loadPluginExecutable else { + return pluginOption } - for loadPluginExecutable in parsedOptions.arguments(for: .loadPluginExecutable) { - let argument = loadPluginExecutable.argument.asSingle - guard let separator = argument.lastIndex(of: "#") else { continue } + let argument = pluginOption.argument.asSingle + guard let separator = argument.lastIndex(of: "#") else { return pluginOption } - let path = argument[.. Bool { diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index c7b350a29..c76c2eed5 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -7497,13 +7497,11 @@ final class SwiftDriverTests: XCTestCase { ) let executableDir = try AbsolutePath(validating: "/tmp/swift/bin") var driver = try Driver( - args: ["swiftc", "-typecheck", "foo.swift", "-sdk", VirtualPath.absolute(sdkRoot).name, "-load-plugin-executable", "PluginA.wasm#ModuleA", "-working-directory", "/tmp"], + args: ["swiftc", "-typecheck", "foo.swift", "-sdk", VirtualPath.absolute(sdkRoot).name, "-load-plugin-executable", "PluginA#ModuleA", "-load-plugin-executable", "PluginB.wasm#ModuleB", "-working-directory", "/tmp", "-load-plugin-library", "PluginC.dylib"], executor: executor, compilerExecutableDir: executableDir ) - guard driver.isFrontendArgSupported(.loadPlugin) else { - return - } + try XCTSkipUnless(driver.isFrontendArgSupported(.loadPlugin)) let jobs = try driver.planBuild().removingAutolinkExtractJobs() XCTAssertEqual(jobs.count, 1) @@ -7516,8 +7514,12 @@ final class SwiftDriverTests: XCTestCase { #endif // Check that the we have the plugin path - let pluginAIndex = job.commandLine.firstIndex(of: .flag("/tmp/PluginA.wasm:\(expectedWasmServerPath)#ModuleA")) - XCTAssertNotNil(pluginAIndex) + let pluginAIndex = try XCTUnwrap(job.commandLine.firstIndex(of: .path(.absolute(AbsolutePath(validating: "/tmp/PluginA#ModuleA"))))) + let pluginBIndex = try XCTUnwrap(job.commandLine.firstIndex(of: .flag("/tmp/PluginB.wasm:\(expectedWasmServerPath)#ModuleB"))) + let pluginCIndex = try XCTUnwrap(job.commandLine.firstIndex(of: .path(.absolute(AbsolutePath(validating: "/tmp/PluginC.dylib"))))) + + XCTAssertLessThan(pluginAIndex, pluginBIndex, "Order of options should be preserved") + XCTAssertLessThan(pluginBIndex, pluginCIndex, "Order of options should be preserved") } func testClangModuleValidateOnce() throws { From 74e989c90bb42b4973aa51dc431807df7aefa9f1 Mon Sep 17 00:00:00 2001 From: Kabir Oberai Date: Wed, 12 Jun 2024 15:46:42 +0530 Subject: [PATCH 11/12] formatting --- Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift index 3104d4a6d..fcff5d269 100644 --- a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift +++ b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift @@ -834,13 +834,16 @@ extension Driver { } let argument = pluginOption.argument.asSingle - guard let separator = argument.lastIndex(of: "#") else { return pluginOption } + guard let separator = argument.lastIndex(of: "#") else { + return pluginOption + } let path = argument[.. Date: Wed, 12 Jun 2024 16:00:15 +0530 Subject: [PATCH 12/12] Minor renaming --- .../SwiftDriver/Jobs/FrontendJobHelpers.swift | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift index fcff5d269..dcb6c57d0 100644 --- a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift +++ b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift @@ -314,7 +314,7 @@ extension Driver { // Emit user-provided plugin paths, in order. if isFrontendArgSupported(.loadPlugin) { let options = parsedOptions.arguments(for: .pluginPath, .externalPluginPath, .loadPluginLibrary, .loadPluginExecutable, .loadPlugin) - try commandLine.append(contentsOf: transformPluginOptions(options)) + try commandLine.append(contentsOf: handleWasmPlugins(options)) } else if isFrontendArgSupported(.externalPluginPath) { try commandLine.appendAll(.pluginPath, .externalPluginPath, .loadPluginLibrary, .loadPluginExecutable, from: &parsedOptions) } else if isFrontendArgSupported(.pluginPath) { @@ -807,13 +807,12 @@ extension Driver { /// Forward all plugin-related arguments, with special handling for Wasm plugins requested via `-load-plugin-executable`. /// /// Wasm plugins are updated to use `-load-plugin` with the plugin server. - private func transformPluginOptions(_ options: [ParsedOption]) throws -> [ParsedOption] { + private func handleWasmPlugins(_ options: [ParsedOption]) throws -> [ParsedOption] { lazy var pluginServerPathResult = Result { VirtualPath.absolute(try toolchain.executableDir.parentDirectory).pluginServerPath } - return try options.map { pluginOption in - try transformPluginOption( - pluginOption, + return try options.map { option in + try option.handlingWasmPlugins( // Not the same as `pluginServerPath: pluginServerPathResult.get`. // We want to ensure that `pluginServerPathResult` is lazily initialized. pluginServerPath: { try pluginServerPathResult.get() } @@ -821,38 +820,6 @@ extension Driver { } } - /// Transforms a single plugin-related option to handle Wasm plugins. - /// - /// If the option is of the form `-load-plugin-executable foo.wasm`, it's updated to use - /// `-load-plugin` with the plugin server. Otherwise, it's returned unmodified. - private func transformPluginOption( - _ pluginOption: ParsedOption, - pluginServerPath: () throws -> VirtualPath - ) throws -> ParsedOption { - guard pluginOption.option == .loadPluginExecutable else { - return pluginOption - } - - let argument = pluginOption.argument.asSingle - guard let separator = argument.lastIndex(of: "#") else { - return pluginOption - } - - let path = argument[.. Bool { return try explicitDependencyBuildPlanner?.supportsBridgingHeaderPCHCommand() ?? false @@ -985,3 +952,36 @@ extension ParsedOptions { } } } + +extension ParsedOption { + /// Transforms the receiver to handle Wasm plugins. + /// + /// If the option is of the form `-load-plugin-executable foo.wasm`, it's updated to use + /// `-load-plugin` with the plugin server. Otherwise, it's returned unmodified. + fileprivate func handlingWasmPlugins( + pluginServerPath: () throws -> VirtualPath + ) throws -> ParsedOption { + guard option == .loadPluginExecutable else { + return self + } + + let argument = argument.asSingle + guard let separator = argument.lastIndex(of: "#") else { + return self + } + + let path = argument[..