Skip to content

Commit 3f9ff29

Browse files
authored
Merge pull request #1309 from ahoppen/review-comments-1306
Address review comments to #1306
2 parents af6cdeb + 6695859 commit 3f9ff29

File tree

6 files changed

+173
-82
lines changed

6 files changed

+173
-82
lines changed

Documentation/Files_To_Reindex.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ Alternatives would be:
1818

1919
## `.h`
2020

21-
Affects all files that include the header (including via other headers). For existing headers, we know which files import a header from the existing index. For new header files, we assume that it hasn’t been included in any file yet and so we don’t re-index any file. If it is, it’s likely that the user will modify the file that includes the new header file shortly after, which will re-index it.
21+
All files that include the header (including via other headers) might be affected by the change, similar to how all `.swift` files that import a module might be affected. Similar to modules, we choose to not re-index all files that include the header because of the same considerations mentioned above.
22+
23+
To re-index the header, we pick one main file that includes the header and re-index that, which will effectively update the index for the header. For existing headers, we know which files import a header from the existing index. For new header files, we assume that it hasn’t been included in any file yet and thus don't index it. If the user wrote an include to the new header before creating the header itself, we don't know about that include from the existing index. But it’s likely that the user will modify the file that includes the new header file shortly after, which will index the header and establish the header to main file connection.
2224

2325
## `.c` / `.cpp` / `.m`
2426

Sources/LSPLogging/NonDarwinLogging.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,17 @@ public struct NonDarwinLogInterpolation: StringInterpolationProtocol, Sendable {
195195
append(description: message.description, redactedDescription: message.redactedDescription, privacy: privacy)
196196
}
197197

198+
public mutating func appendInterpolation(
199+
_ message: (some CustomLogStringConvertibleWrapper & Sendable)?,
200+
privacy: NonDarwinLogPrivacy = .private
201+
) {
202+
if let message {
203+
self.appendInterpolation(message, privacy: privacy)
204+
} else {
205+
self.appendLiteral("<nil>")
206+
}
207+
}
208+
198209
public mutating func appendInterpolation(_ type: Any.Type, privacy: NonDarwinLogPrivacy = .public) {
199210
append(description: String(reflecting: type), redactedDescription: "<private>", privacy: privacy)
200211
}

Sources/SKCore/BuildSystemManager.swift

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -146,32 +146,36 @@ extension BuildSystemManager {
146146
/// Implementation detail of `buildSettings(for:language:)`.
147147
private func buildSettingsFromPrimaryBuildSystem(
148148
for document: DocumentURI,
149+
in target: ConfiguredTarget?,
149150
language: Language
150151
) async throws -> FileBuildSettings? {
151-
guard let buildSystem else {
152-
return nil
153-
}
154-
guard let target = await canonicalConfiguredTarget(for: document) else {
155-
logger.error("Failed to get target for \(document.forLogging)")
152+
guard let buildSystem, let target else {
156153
return nil
157154
}
158155
// FIXME: (async) We should only wait `fallbackSettingsTimeout` for build
159156
// settings and return fallback afterwards. I am not sure yet, how best to
160157
// implement that with Swift concurrency.
161158
// For now, this should be fine because all build systems return
162159
// very quickly from `settings(for:language:)`.
163-
guard let settings = try await buildSystem.buildSettings(for: document, in: target, language: language) else {
164-
return nil
165-
}
166-
return settings
160+
return try await buildSystem.buildSettings(for: document, in: target, language: language)
167161
}
168162

169-
private func buildSettings(
163+
/// Returns the build settings for the given file in the given target.
164+
///
165+
/// Only call this method if it is known that `document` is a main file. Prefer `buildSettingsInferredFromMainFile`
166+
/// otherwise. If `document` is a header file, this will most likely return fallback settings because header files
167+
/// don't have build settings by themselves.
168+
public func buildSettings(
170169
for document: DocumentURI,
170+
in target: ConfiguredTarget?,
171171
language: Language
172172
) async -> FileBuildSettings? {
173173
do {
174-
if let buildSettings = try await buildSettingsFromPrimaryBuildSystem(for: document, language: language) {
174+
if let buildSettings = try await buildSettingsFromPrimaryBuildSystem(
175+
for: document,
176+
in: target,
177+
language: language
178+
) {
175179
return buildSettings
176180
}
177181
} catch {
@@ -199,21 +203,19 @@ extension BuildSystemManager {
199203
/// references to that C file in the build settings by the header file.
200204
public func buildSettingsInferredFromMainFile(
201205
for document: DocumentURI,
202-
language: Language,
203-
logBuildSettings: Bool = true
206+
language: Language
204207
) async -> FileBuildSettings? {
205208
let mainFile = await mainFile(for: document, language: language)
206-
guard var settings = await buildSettings(for: mainFile, language: language) else {
209+
let target = await canonicalConfiguredTarget(for: mainFile)
210+
guard var settings = await buildSettings(for: mainFile, in: target, language: language) else {
207211
return nil
208212
}
209213
if mainFile != document {
210214
// If the main file isn't the file itself, we need to patch the build settings
211215
// to reference `document` instead of `mainFile`.
212216
settings = settings.patching(newFile: document.pseudoPath, originalFile: mainFile.pseudoPath)
213217
}
214-
if logBuildSettings {
215-
await BuildSettingsLogger.shared.log(settings: settings, for: document)
216-
}
218+
await BuildSettingsLogger.shared.log(settings: settings, for: document)
217219
return settings
218220
}
219221

Sources/SemanticIndex/SemanticIndexManager.swift

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -229,12 +229,14 @@ public final actor SemanticIndexManager {
229229
///
230230
/// If `files` contains a header file, this will return a `FileToIndex` that re-indexes a main file which includes the
231231
/// header file to update the header file's index.
232-
private func filesToIndex(toCover files: some Collection<DocumentURI>) async -> [FileToIndex] {
232+
private func filesToIndex(
233+
toCover files: some Collection<DocumentURI>
234+
) async -> [FileToIndex] {
233235
let sourceFiles = Set(await buildSystemManager.sourceFiles().map(\.uri))
234236
let filesToReIndex = await files.asyncCompactMap { (uri) -> FileToIndex? in
235237
if sourceFiles.contains(uri) {
236238
// If this is a source file, just index it.
237-
return FileToIndex(uri: uri, mainFile: nil)
239+
return .indexableFile(uri)
238240
}
239241
// Otherwise, see if it is a header file. If so, index a main file that that imports it to update header file's
240242
// index.
@@ -247,7 +249,7 @@ public final actor SemanticIndexManager {
247249
guard let mainFile else {
248250
return nil
249251
}
250-
return FileToIndex(uri: uri, mainFile: mainFile)
252+
return .headerFile(header: uri, mainFile: mainFile)
251253
}
252254
return filesToReIndex
253255
}
@@ -347,33 +349,33 @@ public final actor SemanticIndexManager {
347349
}
348350

349351
/// Update the index store for the given files, assuming that their targets have already been prepared.
350-
private func updateIndexStore(for files: [FileToIndex], taskID: UUID, priority: TaskPriority?) async {
352+
private func updateIndexStore(for filesAndTargets: [FileAndTarget], taskID: UUID, priority: TaskPriority?) async {
351353
let taskDescription = AnyIndexTaskDescription(
352354
UpdateIndexStoreTaskDescription(
353-
filesToIndex: Set(files),
355+
filesToIndex: filesAndTargets,
354356
buildSystemManager: self.buildSystemManager,
355357
index: index
356358
)
357359
)
358360
let updateIndexStoreTask = await self.indexTaskScheduler.schedule(priority: priority, taskDescription) { newState in
359361
switch newState {
360362
case .executing:
361-
for file in files {
362-
if case .scheduled((taskID, let task)) = self.indexStatus[file.uri] {
363-
self.indexStatus[file.uri] = .executing((taskID, task))
363+
for fileAndTarget in filesAndTargets {
364+
if case .scheduled((taskID, let task)) = self.indexStatus[fileAndTarget.file.sourceFile] {
365+
self.indexStatus[fileAndTarget.file.sourceFile] = .executing((taskID, task))
364366
}
365367
}
366368
case .cancelledToBeRescheduled:
367-
for file in files {
368-
if case .executing((taskID, let task)) = self.indexStatus[file.uri] {
369-
self.indexStatus[file.uri] = .scheduled((taskID, task))
369+
for fileAndTarget in filesAndTargets {
370+
if case .executing((taskID, let task)) = self.indexStatus[fileAndTarget.file.sourceFile] {
371+
self.indexStatus[fileAndTarget.file.sourceFile] = .scheduled((taskID, task))
370372
}
371373
}
372374
case .finished:
373-
for file in files {
374-
switch self.indexStatus[file.uri] {
375+
for fileAndTarget in filesAndTargets {
376+
switch self.indexStatus[fileAndTarget.file.sourceFile] {
375377
case .executing((taskID, _)):
376-
self.indexStatus[file.uri] = .upToDate
378+
self.indexStatus[fileAndTarget.file.sourceFile] = .upToDate
377379
default:
378380
break
379381
}
@@ -392,22 +394,25 @@ public final actor SemanticIndexManager {
392394
priority: TaskPriority?
393395
) async -> Task<Void, Never> {
394396
let outOfDateFiles = await filesToIndex(toCover: files).filter {
395-
if case .upToDate = indexStatus[$0.uri] {
397+
if case .upToDate = indexStatus[$0.sourceFile] {
396398
return false
397399
}
398400
return true
399401
}
400-
.sorted(by: { $0.uri.stringValue < $1.uri.stringValue }) // sort files to get deterministic indexing order
402+
// sort files to get deterministic indexing order
403+
.sorted(by: { $0.sourceFile.stringValue < $1.sourceFile.stringValue })
401404

402405
// Sort the targets in topological order so that low-level targets get built before high-level targets, allowing us
403406
// to index the low-level targets ASAP.
404407
var filesByTarget: [ConfiguredTarget: [FileToIndex]] = [:]
405-
for file in outOfDateFiles {
406-
guard let target = await buildSystemManager.canonicalConfiguredTarget(for: file.uri) else {
407-
logger.error("Not indexing \(file.uri.forLogging) because the target could not be determined")
408+
for fileToIndex in outOfDateFiles {
409+
guard let target = await buildSystemManager.canonicalConfiguredTarget(for: fileToIndex.mainFile) else {
410+
logger.error(
411+
"Not indexing \(fileToIndex.forLogging) because the target could not be determined"
412+
)
408413
continue
409414
}
410-
filesByTarget[target, default: []].append(file)
415+
filesByTarget[target, default: []].append(fileToIndex)
411416
}
412417

413418
var sortedTargets: [ConfiguredTarget] =
@@ -447,7 +452,11 @@ public final actor SemanticIndexManager {
447452
// https://github.com/apple/sourcekit-lsp/issues/1268
448453
for fileBatch in filesByTarget[target]!.partition(intoBatchesOfSize: 1) {
449454
taskGroup.addTask {
450-
await self.updateIndexStore(for: fileBatch, taskID: taskID, priority: priority)
455+
await self.updateIndexStore(
456+
for: fileBatch.map { FileAndTarget(file: $0, target: target) },
457+
taskID: taskID,
458+
priority: priority
459+
)
451460
}
452461
}
453462
}
@@ -462,7 +471,7 @@ public final actor SemanticIndexManager {
462471
// setting it to `.scheduled` because we don't have an `await` call between the creation of `indexTask` and
463472
// this loop, so we still have exclusive access to the `SemanticIndexManager` actor and hence `updateIndexStore`
464473
// can't execute until we have set all index statuses to `.scheduled`.
465-
indexStatus[file.uri] = .scheduled((taskID, indexTask))
474+
indexStatus[file.sourceFile] = .scheduled((taskID, indexTask))
466475
}
467476
indexTasksWereScheduled(filesToIndex.count)
468477
}

0 commit comments

Comments
 (0)