Skip to content

Commit 90c4f2d

Browse files
committed
Move isFallback to FileBuildSettings
Remove isFallback from func buildSettings for FallbackBuildSystem Finetune a comment Finetune the code
1 parent e141933 commit 90c4f2d

File tree

7 files changed

+66
-53
lines changed

7 files changed

+66
-53
lines changed

Sources/SKCore/BuildSystemManager.swift

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -115,27 +115,32 @@ extension BuildSystemManager {
115115
private func buildSettings(
116116
for document: DocumentURI,
117117
language: Language
118-
) async -> (buildSettings: FileBuildSettings, isFallback: Bool)? {
118+
) async -> FileBuildSettings? {
119119
do {
120120
// FIXME: (async) We should only wait `fallbackSettingsTimeout` for build
121121
// settings and return fallback afterwards. I am not sure yet, how best to
122122
// implement that with Swift concurrency.
123123
// For now, this should be fine because all build systems return
124124
// very quickly from `settings(for:language:)`.
125125
if let settings = try await buildSystem?.buildSettings(for: document, language: language) {
126-
return (buildSettings: settings, isFallback: false)
126+
return settings
127127
}
128128
} catch {
129129
logger.error("Getting build settings failed: \(error.forLogging)")
130130
}
131-
if let settings = fallbackBuildSystem?.buildSettings(for: document, language: language) {
131+
// If there is no build system and we only have the fallback build system,
132+
// we will never get real build settings. Consider the build settings
133+
// non-fallback.
134+
guard var settings = fallbackBuildSystem?.buildSettings(for: document, language: language) else {
135+
return nil
136+
}
137+
if buildSystem == nil {
132138
// If there is no build system and we only have the fallback build system,
133139
// we will never get real build settings. Consider the build settings
134140
// non-fallback.
135-
return (buildSettings: settings, isFallback: buildSystem != nil)
136-
} else {
137-
return nil
141+
settings.isFallback = false
138142
}
143+
return settings
139144
}
140145

141146
/// Returns the build settings for the given document.
@@ -148,34 +153,34 @@ extension BuildSystemManager {
148153
public func buildSettingsInferredFromMainFile(
149154
for document: DocumentURI,
150155
language: Language
151-
) async -> (buildSettings: FileBuildSettings, isFallback: Bool)? {
156+
) async -> FileBuildSettings? {
152157
let mainFile = mainFile(for: document)
153-
var buildSettings = await buildSettings(for: mainFile, language: language)
154-
if mainFile != document, let settings = buildSettings?.buildSettings {
158+
guard var settings = await buildSettings(for: mainFile, language: language) else {
159+
return nil
160+
}
161+
if mainFile != document {
155162
// If the main file isn't the file itself, we need to patch the build settings
156163
// to reference `document` instead of `mainFile`.
157-
buildSettings?.buildSettings = settings.patching(newFile: document.pseudoPath, originalFile: mainFile.pseudoPath)
164+
settings = settings.patching(newFile: document.pseudoPath, originalFile: mainFile.pseudoPath)
158165
}
159-
if let buildSettings {
160-
let log = """
161-
Compiler Arguments:
162-
\(buildSettings.buildSettings.compilerArguments.joined(separator: "\n"))
166+
let log = """
167+
Compiler Arguments:
168+
\(settings.compilerArguments.joined(separator: "\n"))
163169
164-
Working directory:
165-
\(buildSettings.buildSettings.workingDirectory ?? "<nil>")
166-
"""
170+
Working directory:
171+
\(settings.workingDirectory ?? "<nil>")
172+
"""
167173

168-
let chunks = splitLongMultilineMessage(message: log, maxChunkSize: 800)
169-
for (index, chunk) in chunks.enumerated() {
170-
logger.log(
171-
"""
172-
Build settings for \(document.forLogging) (\(index + 1)/\(chunks.count))
173-
\(chunk)
174-
"""
175-
)
176-
}
174+
let chunks = splitLongMultilineMessage(message: log, maxChunkSize: 800)
175+
for (index, chunk) in chunks.enumerated() {
176+
logger.log(
177+
"""
178+
Build settings for \(document.forLogging) (\(index + 1)/\(chunks.count))
179+
\(chunk)
180+
"""
181+
)
177182
}
178-
return buildSettings
183+
return settings
179184
}
180185

181186
public func registerForChangeNotifications(for uri: DocumentURI, language: Language) async {

Sources/SKCore/FallbackBuildSystem.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,17 @@ public final class FallbackBuildSystem {
5252
public var indexPrefixMappings: [PathPrefixMapping] { return [] }
5353

5454
public func buildSettings(for uri: DocumentURI, language: Language) -> FileBuildSettings? {
55+
var fileBuildSettings: FileBuildSettings?
5556
switch language {
5657
case .swift:
57-
return settingsSwift(uri.pseudoPath)
58+
fileBuildSettings = settingsSwift(uri.pseudoPath)
5859
case .c, .cpp, .objective_c, .objective_cpp:
59-
return settingsClang(uri.pseudoPath, language)
60+
fileBuildSettings = settingsClang(uri.pseudoPath, language)
6061
default:
61-
return nil
62+
fileBuildSettings = nil
6263
}
64+
fileBuildSettings?.isFallback = true
65+
return fileBuildSettings
6366
}
6467

6568
func settingsSwift(_ file: String) -> FileBuildSettings {

Sources/SKCore/FileBuildSettings.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,13 @@ public struct FileBuildSettings: Equatable {
2525
/// The working directory to resolve any relative paths in `compilerArguments`.
2626
public var workingDirectory: String? = nil
2727

28-
public init(compilerArguments: [String], workingDirectory: String? = nil) {
28+
/// Whether the build settings were computed from a real build system or whether they are synthesized fallback arguments while the build system is still busy computing build settings.
29+
public var isFallback: Bool
30+
31+
public init(compilerArguments: [String], workingDirectory: String? = nil, isFallback: Bool = false) {
2932
self.compilerArguments = compilerArguments
3033
self.workingDirectory = workingDirectory
34+
self.isFallback = isFallback
3135
}
3236
}
3337

@@ -74,6 +78,6 @@ public extension FileBuildSettings {
7478
arguments.insert("-xobjective-c++", at: 0)
7579
}
7680
}
77-
return FileBuildSettings(compilerArguments: arguments, workingDirectory: self.workingDirectory)
81+
return FileBuildSettings(compilerArguments: arguments, workingDirectory: self.workingDirectory, isFallback: self.isFallback)
7882
}
7983
}

Sources/SourceKitLSP/Clang/ClangLanguageServer.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ actor ClangLanguageServerShim: ToolchainLanguageServer, MessageHandler {
142142
else {
143143
return nil
144144
}
145-
return ClangBuildSettings(settings.buildSettings, clangPath: clangdPath, isFallback: settings.isFallback)
145+
return ClangBuildSettings(settings, clangPath: clangdPath)
146146
}
147147

148148
nonisolated func canHandle(workspace: Workspace) -> Bool {
@@ -600,7 +600,7 @@ private struct ClangBuildSettings: Equatable {
600600
/// fallback arguments and represent the file state differently.
601601
public let isFallback: Bool
602602

603-
public init(_ settings: FileBuildSettings, clangPath: AbsolutePath?, isFallback: Bool = false) {
603+
public init(_ settings: FileBuildSettings, clangPath: AbsolutePath?) {
604604
var arguments = [clangPath?.pathString ?? "clang"] + settings.compilerArguments
605605
if arguments.contains("-fmodules") {
606606
// Clangd is not built with support for the 'obj' format.
@@ -619,7 +619,7 @@ private struct ClangBuildSettings: Equatable {
619619

620620
self.compilerArgs = arguments
621621
self.workingDirectory = settings.workingDirectory ?? ""
622-
self.isFallback = isFallback
622+
self.isFallback = settings.isFallback
623623
}
624624

625625
public var compileCommand: ClangCompileCommand {

Sources/SourceKitLSP/Swift/SwiftLanguageServer.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,15 @@ public struct SwiftCompileCommand: Equatable {
7575
/// fallback arguments and represent the file state differently.
7676
public let isFallback: Bool
7777

78-
public init(_ settings: FileBuildSettings, isFallback: Bool = false) {
78+
public init(_ settings: FileBuildSettings) {
7979
let baseArgs = settings.compilerArguments
8080
// Add working directory arguments if needed.
8181
if let workingDirectory = settings.workingDirectory, !baseArgs.contains("-working-directory") {
8282
self.compilerArgs = baseArgs + ["-working-directory", workingDirectory]
8383
} else {
8484
self.compilerArgs = baseArgs
8585
}
86-
self.isFallback = isFallback
86+
self.isFallback = settings.isFallback
8787
}
8888
}
8989

@@ -177,7 +177,7 @@ public actor SwiftLanguageServer: ToolchainLanguageServer {
177177
for: document,
178178
language: .swift
179179
) {
180-
return SwiftCompileCommand(settings.buildSettings, isFallback: settings.isFallback)
180+
return SwiftCompileCommand(settings)
181181
} else {
182182
return nil
183183
}

Tests/SKCoreTests/BuildSystemManagerTests.swift

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ final class BuildSystemManagerTests: XCTestCase {
105105

106106
bs.map[a] = FileBuildSettings(compilerArguments: ["x"])
107107
await bsm.registerForChangeNotifications(for: a, language: .swift)
108-
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: a, language: .swift)?.buildSettings, bs.map[a]!)
108+
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: a, language: .swift), bs.map[a]!)
109109

110110
bs.map[a] = nil
111111
let changed = expectation(description: "changed settings")
@@ -127,7 +127,7 @@ final class BuildSystemManagerTests: XCTestCase {
127127
defer { withExtendedLifetime(bsm) {} } // Keep BSM alive for callbacks.
128128
let del = await BSMDelegate(bsm)
129129
await bsm.registerForChangeNotifications(for: a, language: .swift)
130-
assertNil(await bsm.buildSettingsInferredFromMainFile(for: a, language: .swift)?.buildSettings)
130+
assertNil(await bsm.buildSettingsInferredFromMainFile(for: a, language: .swift))
131131

132132
bs.map[a] = FileBuildSettings(compilerArguments: ["x"])
133133
let changed = expectation(description: "changed settings")
@@ -151,7 +151,7 @@ final class BuildSystemManagerTests: XCTestCase {
151151
let del = await BSMDelegate(bsm)
152152
let fallbackSettings = fallback.buildSettings(for: a, language: .swift)
153153
await bsm.registerForChangeNotifications(for: a, language: .swift)
154-
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: a, language: .swift)?.buildSettings, fallbackSettings)
154+
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: a, language: .swift), fallbackSettings)
155155

156156
bs.map[a] = FileBuildSettings(compilerArguments: ["non-fallback", "args"])
157157
let changed = expectation(description: "changed settings")
@@ -183,9 +183,9 @@ final class BuildSystemManagerTests: XCTestCase {
183183
bs.map[a] = FileBuildSettings(compilerArguments: ["x"])
184184
bs.map[b] = FileBuildSettings(compilerArguments: ["y"])
185185
await bsm.registerForChangeNotifications(for: a, language: .swift)
186-
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: a, language: .swift)?.buildSettings, bs.map[a]!)
186+
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: a, language: .swift), bs.map[a]!)
187187
await bsm.registerForChangeNotifications(for: b, language: .swift)
188-
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: b, language: .swift)?.buildSettings, bs.map[b]!)
188+
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: b, language: .swift), bs.map[b]!)
189189

190190
bs.map[a] = FileBuildSettings(compilerArguments: ["xx"])
191191
bs.map[b] = FileBuildSettings(compilerArguments: ["yy"])
@@ -225,10 +225,10 @@ final class BuildSystemManagerTests: XCTestCase {
225225
bs.map[b] = FileBuildSettings(compilerArguments: ["b"])
226226

227227
await bsm.registerForChangeNotifications(for: a, language: .swift)
228-
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: a, language: .swift)?.buildSettings, bs.map[a]!)
228+
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: a, language: .swift), bs.map[a]!)
229229

230230
await bsm.registerForChangeNotifications(for: b, language: .swift)
231-
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: b, language: .swift)?.buildSettings, bs.map[b]!)
231+
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: b, language: .swift), bs.map[b]!)
232232

233233
bs.map[a] = nil
234234
bs.map[b] = nil
@@ -262,7 +262,7 @@ final class BuildSystemManagerTests: XCTestCase {
262262
bs.map[cpp2] = FileBuildSettings(compilerArguments: ["C++ 2"])
263263

264264
await bsm.registerForChangeNotifications(for: h, language: .c)
265-
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: h, language: .c)?.buildSettings, bs.map[cpp1]!)
265+
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: h, language: .c), bs.map[cpp1]!)
266266

267267
mainFiles.mainFiles[h] = Set([cpp2])
268268

@@ -320,8 +320,8 @@ final class BuildSystemManagerTests: XCTestCase {
320320

321321
let expectedArgsH1 = FileBuildSettings(compilerArguments: ["-xc++", cppArg, h1.pseudoPath])
322322
let expectedArgsH2 = FileBuildSettings(compilerArguments: ["-xc++", cppArg, h2.pseudoPath])
323-
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: h1, language: .c)?.buildSettings, expectedArgsH1)
324-
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: h2, language: .c)?.buildSettings, expectedArgsH2)
323+
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: h1, language: .c), expectedArgsH1)
324+
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: h2, language: .c), expectedArgsH2)
325325

326326
let newCppArg = "New C++ Main File"
327327
bs.map[cpp] = FileBuildSettings(compilerArguments: [newCppArg, cpp.pseudoPath])
@@ -360,9 +360,9 @@ final class BuildSystemManagerTests: XCTestCase {
360360
await bsm.registerForChangeNotifications(for: a, language: .swift)
361361
await bsm.registerForChangeNotifications(for: b, language: .swift)
362362
await bsm.registerForChangeNotifications(for: c, language: .swift)
363-
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: a, language: .swift)?.buildSettings, bs.map[a]!)
364-
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: b, language: .swift)?.buildSettings, bs.map[b]!)
365-
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: c, language: .swift)?.buildSettings, bs.map[c]!)
363+
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: a, language: .swift), bs.map[a]!)
364+
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: b, language: .swift), bs.map[b]!)
365+
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: c, language: .swift), bs.map[c]!)
366366

367367
bs.map[a] = FileBuildSettings(compilerArguments: ["new-a"])
368368
bs.map[b] = FileBuildSettings(compilerArguments: ["new-b"])
@@ -397,7 +397,7 @@ final class BuildSystemManagerTests: XCTestCase {
397397
let del = await BSMDelegate(bsm)
398398

399399
bs.map[a] = FileBuildSettings(compilerArguments: ["x"])
400-
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: a, language: .swift)?.buildSettings, bs.map[a]!)
400+
assertEqual(await bsm.buildSettingsInferredFromMainFile(for: a, language: .swift), bs.map[a]!)
401401

402402
await bsm.registerForChangeNotifications(for: a, language: .swift)
403403

@@ -507,7 +507,7 @@ private actor BSMDelegate: BuildSystemDelegate {
507507
}
508508

509509
XCTAssertEqual(uri, expected.uri, file: expected.file, line: expected.line)
510-
let settings = await bsm.buildSettingsInferredFromMainFile(for: uri, language: expected.language)?.buildSettings
510+
let settings = await bsm.buildSettingsInferredFromMainFile(for: uri, language: expected.language)
511511
XCTAssertEqual(settings, expected.settings, file: expected.file, line: expected.line)
512512
expected.expectation.fulfill()
513513
}

Tests/SourceKitLSPTests/BuildSystemTests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ final class BuildSystemTests: XCTestCase {
251251

252252
// Primary settings must be different than the fallback settings.
253253
var primarySettings = FallbackBuildSystem(buildSetup: .default).buildSettings(for: doc, language: .swift)!
254+
primarySettings.isFallback = false
254255
primarySettings.compilerArguments.append("-DPRIMARY")
255256

256257
let text = """

0 commit comments

Comments
 (0)