Skip to content

Commit 569b684

Browse files
authored
Merge pull request #1777 from owenv/ovoorhees/ofm-json
Consistently use JSON when encoding output file maps
2 parents 2edd936 + c89a585 commit 569b684

File tree

3 files changed

+54
-33
lines changed

3 files changed

+54
-33
lines changed

Sources/SwiftDriver/Driver/OutputFileMap.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,15 @@ public struct OutputFileMap: Hashable, Codable {
140140
/// Store the output file map at the given path.
141141
public func store(
142142
fileSystem: FileSystem,
143-
file: AbsolutePath,
144-
diagnosticEngine: DiagnosticsEngine
143+
file: AbsolutePath
145144
) throws {
146145
let encoder = JSONEncoder()
147146

148147
#if os(Linux) || os(Android)
149-
encoder.outputFormatting = [.prettyPrinted]
148+
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
150149
#else
151150
if #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) {
152-
encoder.outputFormatting = [.prettyPrinted, .withoutEscapingSlashes]
151+
encoder.outputFormatting = [.prettyPrinted, .sortedKeys, .withoutEscapingSlashes]
153152
}
154153
#endif
155154

Sources/SwiftDriver/Execution/ArgsResolver.swift

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ import protocol TSCBasic.FileSystem
1717
import struct TSCBasic.AbsolutePath
1818
import struct TSCBasic.SHA256
1919

20-
@_implementationOnly import Yams
21-
2220
/// How the resolver is to handle usage of response files
2321
public enum ResponseFileHandling {
2422
case forced
@@ -166,35 +164,10 @@ public final class ArgsResolver {
166164
throws {
167165
// FIXME: Need a way to support this for distributed build systems...
168166
if let absPath = path.absolutePath {
169-
// This uses Yams to escape and quote strings, but not to output the whole yaml file because
170-
// it sometimes outputs mappings in explicit block format (https://yaml.org/spec/1.2/spec.html#id2798057)
171-
// and the frontend (llvm) only seems to support implicit block format.
172-
try fileSystem.writeFileContents(absPath) { out in
173-
for (input, map) in outputFileMap.entries {
174-
out.send("\(quoteAndEscape(path: VirtualPath.lookup(input))):")
175-
if map.isEmpty {
176-
out.send(" {}\n")
177-
} else {
178-
out.send("\n")
179-
for (type, output) in map {
180-
out.send(" \(type.name): \(quoteAndEscape(path: VirtualPath.lookup(output)))\n")
181-
}
182-
}
183-
}
184-
}
167+
try outputFileMap.store(fileSystem: fileSystem, file: absPath)
185168
}
186169
}
187170

188-
private func quoteAndEscape(path: VirtualPath) -> String {
189-
let inputNode = Node.scalar(Node.Scalar(try! unsafeResolve(path: path),
190-
Tag(.str), .doubleQuoted))
191-
// Width parameter of -1 sets preferred line-width to unlimited so that no extraneous
192-
// line-breaks will be inserted during serialization.
193-
let string = try! Yams.serialize(node: inputNode, width: -1)
194-
// Remove the newline from the end
195-
return string.trimmingCharacters(in: .whitespacesAndNewlines)
196-
}
197-
198171
private func createResponseFileIfNeeded(for job: Job, resolvedArguments: inout [String], useResponseFiles: ResponseFileHandling) throws -> Bool {
199172
guard useResponseFiles != .disabled else {
200173
return false

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1473,7 +1473,7 @@ final class SwiftDriverTests: XCTestCase {
14731473
let sampleOutputFileMap = OutputFileMap(entries: pathyEntries)
14741474

14751475
try withTemporaryFile { file in
1476-
try sampleOutputFileMap.store(fileSystem: localFileSystem, file: file.path, diagnosticEngine: DiagnosticsEngine())
1476+
try sampleOutputFileMap.store(fileSystem: localFileSystem, file: file.path)
14771477
let contentsForDebugging = try localFileSystem.readFileContents(file.path).cString
14781478
_ = contentsForDebugging
14791479
let recoveredOutputFileMap = try OutputFileMap.load(fileSystem: localFileSystem, file: .absolute(file.path), diagnosticEngine: DiagnosticsEngine())
@@ -8290,6 +8290,55 @@ final class SwiftDriverTests: XCTestCase {
82908290
XCTAssertTrue(plannedJobs[0].commandLine.contains(.flag("-load-pass-plugin=/path/to/plugin")))
82918291
#endif
82928292
}
8293+
8294+
func testSupplementaryOutputFileMapUsage() throws {
8295+
// Ensure filenames are escaped properly when using a supplementary output file map
8296+
try withTemporaryDirectory { path in
8297+
try localFileSystem.changeCurrentWorkingDirectory(to: path)
8298+
let moduleCachePath = path.appending(component: "ModuleCache")
8299+
try localFileSystem.createDirectory(moduleCachePath)
8300+
let one = path.appending(component: "one.swift")
8301+
let two = path.appending(component: "needs to escape spaces.swift")
8302+
let three = path.appending(component: #"another"one.swift"#)
8303+
let four = path.appending(component: "4.swift")
8304+
try localFileSystem.writeFileContents(one, bytes:
8305+
"""
8306+
public struct A {}
8307+
"""
8308+
)
8309+
try localFileSystem.writeFileContents(two, bytes:
8310+
"""
8311+
struct B {}
8312+
"""
8313+
)
8314+
try localFileSystem.writeFileContents(three, bytes:
8315+
"""
8316+
struct C {}
8317+
"""
8318+
)
8319+
try localFileSystem.writeFileContents(four, bytes:
8320+
"""
8321+
struct D {}
8322+
"""
8323+
)
8324+
8325+
let sdkArgumentsForTesting = (try? Driver.sdkArgumentsForTesting()) ?? []
8326+
let invocationArguments = ["swiftc",
8327+
"-parse-as-library",
8328+
"-emit-library",
8329+
"-driver-filelist-threshold", "0",
8330+
"-module-cache-path", moduleCachePath.nativePathString(escaped: true),
8331+
"-working-directory", path.nativePathString(escaped: true),
8332+
one.nativePathString(escaped: true),
8333+
two.nativePathString(escaped: true),
8334+
three.nativePathString(escaped: true),
8335+
four.nativePathString(escaped: true)] + sdkArgumentsForTesting
8336+
var driver = try Driver(args: invocationArguments)
8337+
let jobs = try driver.planBuild()
8338+
try driver.run(jobs: jobs)
8339+
XCTAssertFalse(driver.diagnosticEngine.hasErrors)
8340+
}
8341+
}
82938342
}
82948343

82958344
func assertString(

0 commit comments

Comments
 (0)