diff --git a/Sources/SwiftDriver/Driver/Driver.swift b/Sources/SwiftDriver/Driver/Driver.swift index 4e6d90b1a..17554fa5e 100644 --- a/Sources/SwiftDriver/Driver/Driver.swift +++ b/Sources/SwiftDriver/Driver/Driver.swift @@ -296,6 +296,7 @@ public struct Driver { self.numParallelJobs = Self.determineNumParallelJobs(&parsedOptions, diagnosticsEngine: diagnosticEngine, env: env) try Self.validateWarningControlArgs(&parsedOptions) + Self.validateCoverageArgs(&parsedOptions, diagnosticsEngine: diagnosticEngine) // Compute debug information output. self.debugInfo = Self.computeDebugInfo(&parsedOptions, diagnosticsEngine: diagnosticEngine) @@ -1512,6 +1513,16 @@ extension Driver { throw Error.conflictingOptions(.warningsAsErrors, .suppressWarnings) } } + + private static func validateCoverageArgs(_ parsedOptions: inout ParsedOptions, diagnosticsEngine: DiagnosticsEngine) { + for coveragePrefixMap in parsedOptions.arguments(for: .coveragePrefixMap) { + let value = coveragePrefixMap.argument.asSingle + let parts = value.split(separator: "=", maxSplits: 1, omittingEmptySubsequences: false) + if parts.count != 2 { + diagnosticsEngine.emit(.error_opt_invalid_mapping(option: coveragePrefixMap.option, value: value)) + } + } + } } extension Triple { diff --git a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift index 99ed12f57..5fb541dbf 100644 --- a/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift +++ b/Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift @@ -170,6 +170,7 @@ extension Driver { try commandLine.appendAll(.sanitizeEQ, from: &parsedOptions) try commandLine.appendAll(.debugPrefixMap, from: &parsedOptions) try commandLine.appendAllArguments(.Xfrontend, from: &parsedOptions) + try commandLine.appendAll(.coveragePrefixMap, from: &parsedOptions) if let workingDirectory = workingDirectory { // Add -Xcc -working-directory before any other -Xcc options to ensure it is diff --git a/Sources/SwiftOptions/Options.swift b/Sources/SwiftOptions/Options.swift index 0258b68f6..f3be748de 100644 --- a/Sources/SwiftOptions/Options.swift +++ b/Sources/SwiftOptions/Options.swift @@ -31,6 +31,7 @@ extension Option { public static let colorDiagnostics: Option = Option("-color-diagnostics", .flag, attributes: [.frontend, .doesNotAffectIncrementalBuild], helpText: "Print diagnostics in color") public static let compileModuleFromInterface: Option = Option("-compile-module-from-interface", .flag, attributes: [.helpHidden, .frontend, .noDriver], helpText: "Treat the (single) input as a swiftinterface and produce a module", group: .modes) public static let continueBuildingAfterErrors: Option = Option("-continue-building-after-errors", .flag, attributes: [.frontend, .doesNotAffectIncrementalBuild], helpText: "Continue building, even after errors are encountered") + public static let coveragePrefixMap: Option = Option("-coverage-prefix-map", .separate, attributes: [.frontend], helpText: "Remap source paths in coverage info") public static let CrossModuleOptimization: Option = Option("-cross-module-optimization", .flag, attributes: [.helpHidden, .frontend], helpText: "Perform cross-module optimization") public static let crosscheckUnqualifiedLookup: Option = Option("-crosscheck-unqualified-lookup", .flag, attributes: [.frontend, .noDriver], helpText: "Compare legacy DeclContext- to ASTScope-based unqualified name lookup (for debugging)") public static let c: Option = Option("-c", .flag, alias: Option.emitObject, attributes: [.frontend, .noInteractive], group: .modes) @@ -503,6 +504,7 @@ extension Option { Option.colorDiagnostics, Option.compileModuleFromInterface, Option.continueBuildingAfterErrors, + Option.coveragePrefixMap, Option.CrossModuleOptimization, Option.crosscheckUnqualifiedLookup, Option.c, diff --git a/Tests/SwiftDriverTests/SwiftDriverTests.swift b/Tests/SwiftDriverTests/SwiftDriverTests.swift index 700014851..148f8eb7b 100644 --- a/Tests/SwiftDriverTests/SwiftDriverTests.swift +++ b/Tests/SwiftDriverTests/SwiftDriverTests.swift @@ -358,6 +358,21 @@ final class SwiftDriverTests: XCTestCase { } } + func testCoverageSettings() throws { + try assertNoDriverDiagnostics(args: "swiftc", "foo.swift", "-coverage-prefix-map", "foo=bar=baz", "-coverage-prefix-map", "qux=") { driver in + let jobs = try driver.planBuild() + XCTAssertTrue(jobs[0].commandLine.contains(.flag("-coverage-prefix-map"))) + XCTAssertTrue(jobs[0].commandLine.contains(.flag("foo=bar=baz"))) + XCTAssertTrue(jobs[0].commandLine.contains(.flag("-coverage-prefix-map"))) + XCTAssertTrue(jobs[0].commandLine.contains(.flag("qux="))) + } + + try assertDriverDiagnostics(args: "swiftc", "foo.swift", "-coverage-prefix-map", "foo", "-coverage-prefix-map", "bar") { + $1.expect(.error("values for '-coverage-prefix-map' must be in the format original=remapped not 'foo'")) + $1.expect(.error("values for '-coverage-prefix-map' must be in the format original=remapped not 'bar'")) + } + } + func testModuleSettings() throws { try assertNoDriverDiagnostics(args: "swiftc", "foo.swift") { driver in XCTAssertNil(driver.moduleOutputInfo.output)