Skip to content

Commit 909c0a9

Browse files
authored
Merge pull request #2073 from ahoppen/index-unit-output-path
If the compiler arguments only contain `-o`, add the output path as `-index-unit-output-path` to the adjusted options
2 parents 6d96ec6 + 71e7404 commit 909c0a9

File tree

3 files changed

+83
-17
lines changed

3 files changed

+83
-17
lines changed

Sources/BuildSystemIntegration/BuildSystemManager.swift

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,6 +1471,15 @@ fileprivate extension TextDocumentSourceKitOptionsResponse {
14711471
/// This removes compiler arguments that produce output files and adds arguments to eg. allow errors and index the
14721472
/// file.
14731473
func adjustArgsForSemanticSwiftFunctionality(fileToIndex: DocumentURI) -> TextDocumentSourceKitOptionsResponse {
1474+
// Technically, `-o` and the output file don't need to be separated by a space. Eg. `swiftc -oa file.swift` is
1475+
// valid and will write to an output file named `a`.
1476+
// We can't support that because the only way to know that `-output-file-map` is a different flag and not an option
1477+
// to write to an output file named `utput-file-map` is to know all compiler arguments of `swiftc`, which we don't.
1478+
let outputPathOption = CompilerCommandLineOption.option("o", [.singleDash], [.separatedBySpace])
1479+
1480+
let indexUnitOutputPathOption =
1481+
CompilerCommandLineOption.option("index-unit-output-path", [.singleDash], [.separatedBySpace])
1482+
14741483
let optionsToRemove: [CompilerCommandLineOption] = [
14751484
.flag("c", [.singleDash]),
14761485
.flag("disable-cmo", [.singleDash]),
@@ -1498,11 +1507,7 @@ fileprivate extension TextDocumentSourceKitOptionsResponse {
14981507
.option("emit-package-module-interface-path", [.singleDash], [.separatedBySpace]),
14991508
.option("emit-private-module-interface-path", [.singleDash], [.separatedBySpace]),
15001509
.option("num-threads", [.singleDash], [.separatedBySpace]),
1501-
// Technically, `-o` and the output file don't need to be separated by a space. Eg. `swiftc -oa file.swift` is
1502-
// valid and will write to an output file named `a`.
1503-
// We can't support that because the only way to know that `-output-file-map` is a different flag and not an option
1504-
// to write to an output file named `utput-file-map` is to know all compiler arguments of `swiftc`, which we don't.
1505-
.option("o", [.singleDash], [.separatedBySpace]),
1510+
outputPathOption,
15061511
.option("output-file-map", [.singleDash], [.separatedBySpace, .separatedByEqualSign]),
15071512
]
15081513

@@ -1534,6 +1539,15 @@ fileprivate extension TextDocumentSourceKitOptionsResponse {
15341539

15351540
result += supplementalClangIndexingArgs.flatMap { ["-Xcc", $0] }
15361541

1542+
if let outputPathIndex = compilerArguments.lastIndex(where: { outputPathOption.matches(argument: $0) != nil }),
1543+
compilerArguments.allSatisfy({ indexUnitOutputPathOption.matches(argument: $0) == nil }),
1544+
outputPathIndex + 1 < compilerArguments.count
1545+
{
1546+
// The original compiler arguments contained `-o` to specify the output file but we have stripped that away.
1547+
// Re-introduce the output path as `-index-unit-output-path` so that we have an output path for the unit file.
1548+
result += ["-index-unit-output-path", compilerArguments[outputPathIndex + 1]]
1549+
}
1550+
15371551
var adjusted = self
15381552
adjusted.compilerArguments = result
15391553
return adjusted

Sources/SKTestSupport/CustomBuildServerTestProject.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ package final class CustomBuildServerTestProject<BuildServer: CustomBuildServer>
277277
options: SourceKitLSPOptions? = nil,
278278
hooks: Hooks = Hooks(),
279279
enableBackgroundIndexing: Bool = false,
280+
pollIndex: Bool = true,
280281
testScratchDir: URL? = nil,
281282
testName: String = #function
282283
) async throws {
@@ -295,6 +296,11 @@ package final class CustomBuildServerTestProject<BuildServer: CustomBuildServer>
295296
testScratchDir: testScratchDir,
296297
testName: testName
297298
)
299+
300+
if pollIndex {
301+
// Wait for the indexstore-db to finish indexing
302+
try await testClient.send(SynchronizeRequest(index: true))
303+
}
298304
}
299305

300306
package func buildServer(file: StaticString = #filePath, line: UInt = #line) throws -> BuildServer {

Tests/SourceKitLSPTests/BackgroundIndexingTests.swift

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1978,7 +1978,8 @@ final class BackgroundIndexingTests: XCTestCase {
19781978
"""
19791979
],
19801980
buildServer: BuildServer.self,
1981-
enableBackgroundIndexing: true
1981+
enableBackgroundIndexing: true,
1982+
pollIndex: false
19821983
)
19831984
let fileUrl = try XCTUnwrap(project.uri(for: "Test.swift").fileURL)
19841985

@@ -2141,7 +2142,6 @@ final class BackgroundIndexingTests: XCTestCase {
21412142
buildServer: BuildServer.self,
21422143
enableBackgroundIndexing: true
21432144
)
2144-
try await project.testClient.send(SynchronizeRequest(index: true))
21452145

21462146
let symbols = try await project.testClient.send(WorkspaceSymbolsRequest(query: "myTestFunc"))
21472147
XCTAssertEqual(
@@ -2220,13 +2220,9 @@ final class BackgroundIndexingTests: XCTestCase {
22202220
}
22212221

22222222
func initializeBuildRequest(_ request: InitializeBuildRequest) async throws -> InitializeBuildResponse {
2223-
return initializationResponse(
2224-
initializeData: SourceKitInitializeBuildResponseData(
2225-
indexDatabasePath: try projectRoot.appendingPathComponent("index-db").filePath,
2226-
indexStorePath: try projectRoot.appendingPathComponent("index-store").filePath,
2227-
prepareProvider: true,
2228-
sourceKitOptionsProvider: true
2229-
)
2223+
return try initializationResponseSupportingBackgroundIndexing(
2224+
projectRoot: projectRoot,
2225+
outputPathsProvider: false
22302226
)
22312227
}
22322228

@@ -2264,7 +2260,6 @@ final class BackgroundIndexingTests: XCTestCase {
22642260
enableBackgroundIndexing: true,
22652261
testScratchDir: scratchDirectory
22662262
)
2267-
try await project.testClient.send(SynchronizeRequest(index: true))
22682263

22692264
// Ensure that changing `/private/tmp/.../test.c` only causes `/tmp/.../test.c` to be indexed, not
22702265
// `/private/tmp/.../test.c`.
@@ -2375,7 +2370,6 @@ final class BackgroundIndexingTests: XCTestCase {
23752370
buildServer: BuildServer.self,
23762371
enableBackgroundIndexing: true
23772372
)
2378-
try await project.testClient.send(SynchronizeRequest(index: true))
23792373

23802374
let (libAUri, libAPositions) = try project.openDocument("LibA.swift")
23812375
let libATypeHierarchyPrepare = try await project.testClient.send(
@@ -2493,7 +2487,6 @@ final class BackgroundIndexingTests: XCTestCase {
24932487
buildServer: BuildServer.self,
24942488
enableBackgroundIndexing: true
24952489
)
2496-
try await project.testClient.send(SynchronizeRequest(index: true))
24972490

24982491
let workspaceSymbolsBeforeUpdate = try await project.testClient.send(WorkspaceSymbolsRequest(query: "myTest"))
24992492
XCTAssertEqual(workspaceSymbolsBeforeUpdate?.compactMap(\.symbolInformation?.name), ["myTestA", "myTestB"])
@@ -2539,6 +2532,59 @@ final class BackgroundIndexingTests: XCTestCase {
25392532
// Check that we don't enter an infinite loop trying to index the circular symlink.
25402533
try await project.testClient.send(SynchronizeRequest(index: true))
25412534
}
2535+
2536+
func testBuildSystemDoesNotReturnIndexUnitOutputPath() async throws {
2537+
final class BuildSystem: CustomBuildServer {
2538+
let inProgressRequestsTracker = CustomBuildServerInProgressRequestTracker()
2539+
private let projectRoot: URL
2540+
2541+
required init(projectRoot: URL, connectionToSourceKitLSP: any LanguageServerProtocol.Connection) {
2542+
self.projectRoot = projectRoot
2543+
}
2544+
2545+
func initializeBuildRequest(_ request: InitializeBuildRequest) async throws -> InitializeBuildResponse {
2546+
return try initializationResponseSupportingBackgroundIndexing(
2547+
projectRoot: projectRoot,
2548+
outputPathsProvider: true
2549+
)
2550+
}
2551+
2552+
func buildTargetSourcesRequest(_ request: BuildTargetSourcesRequest) async throws -> BuildTargetSourcesResponse {
2553+
return BuildTargetSourcesResponse(items: [
2554+
SourcesItem(
2555+
target: .dummy,
2556+
sources: [
2557+
sourceItem(
2558+
for: projectRoot.appendingPathComponent("test.swift"),
2559+
outputPath: fakeOutputPath(for: "test.swift", in: "dummy")
2560+
)
2561+
]
2562+
)
2563+
])
2564+
}
2565+
2566+
func textDocumentSourceKitOptionsRequest(
2567+
_ request: TextDocumentSourceKitOptionsRequest
2568+
) async throws -> TextDocumentSourceKitOptionsResponse? {
2569+
var arguments = [request.textDocument.uri.pseudoPath, "-o", fakeOutputPath(for: "test.swift", in: "dummy")]
2570+
if let defaultSDKPath {
2571+
arguments += ["-sdk", defaultSDKPath]
2572+
}
2573+
return TextDocumentSourceKitOptionsResponse(compilerArguments: arguments)
2574+
}
2575+
}
2576+
2577+
let project = try await CustomBuildServerTestProject(
2578+
files: [
2579+
"test.swift": "func myTestFunc() {}"
2580+
],
2581+
buildServer: BuildSystem.self,
2582+
enableBackgroundIndexing: true
2583+
)
2584+
2585+
let symbols = try await project.testClient.send(WorkspaceSymbolsRequest(query: "myTestFu"))
2586+
XCTAssertEqual(symbols?.compactMap(\.symbolInformation?.name), ["myTestFunc()"])
2587+
}
25422588
}
25432589

25442590
extension HoverResponseContents {

0 commit comments

Comments
 (0)