Skip to content

Commit 06c4517

Browse files
committed
Preserve relative ordering in ParsedOptions.arguments(for options:)
This is significant in at least one case (-F/-Fsystem ordering needs to be preserved), and isn't that expensive, so always preserve the ordering to ensure more predictable behavior
1 parent 3ea9371 commit 06c4517

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

Sources/SwiftOptions/ParsedOptions.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,23 +191,25 @@ extension ParsedOptions {
191191
}
192192

193193
public mutating func arguments(for options: Option...) -> [ParsedOption] {
194-
return options.flatMap { lookup($0) }
194+
return arguments(for: options)
195195
}
196196

197197
public mutating func arguments(for options: [Option]) -> [ParsedOption] {
198-
return options.flatMap { lookup($0) }
198+
// The relative ordering of different options is sometimes significant, so
199+
// sort the results by their position in the command line.
200+
return options.flatMap { lookup($0) }.sorted { $0.index < $1.index }
199201
}
200202

201203
public mutating func arguments(in group: Option.Group) -> [ParsedOption] {
202204
return groupIndex[group, default: []]
203205
}
204206

205207
public mutating func last(for options: Option...) -> ParsedOption? {
206-
return arguments(for: options).max { $0.index < $1.index }
208+
return last(for: options)
207209
}
208210

209211
public mutating func last(for options: [Option]) -> ParsedOption? {
210-
return arguments(for: options).max { $0.index < $1.index }
212+
return arguments(for: options).last
211213
}
212214

213215
/// Return the last parsed options that matches the given predicate.

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,19 @@ final class SwiftDriverTests: XCTestCase {
124124
XCTAssertTrue(jobs[0].commandLine.contains(.joinedOptionAndPath("-F=", .relative(.init("other/relative/dir")))))
125125
}
126126

127+
func testRelativeOptionOrdering() throws {
128+
var driver = try Driver(args: ["swiftc", "foo.swift",
129+
"-F", "/path/to/frameworks",
130+
"-Fsystem", "/path/to/systemframeworks",
131+
"-F", "/path/to/more/frameworks"])
132+
let jobs = try driver.planBuild()
133+
XCTAssertEqual(jobs[0].kind, .compile)
134+
// The relative ordering of -F and -Fsystem options should be preserved.
135+
XCTAssertTrue(jobs[0].commandLine.contains(subsequence: [.flag("-F"), .path(.absolute(.init("/path/to/frameworks"))),
136+
.flag("-Fsystem"), .path(.absolute(.init("/path/to/systemframeworks"))),
137+
.flag("-F"), .path(.absolute(.init("/path/to/more/frameworks")))]))
138+
}
139+
127140
func testBatchModeDiagnostics() throws {
128141
try assertNoDriverDiagnostics(args: "swiftc", "-enable-batch-mode") { driver in
129142
switch driver.compilerMode {

0 commit comments

Comments
 (0)