@@ -54,14 +54,21 @@ package struct SourceFileInfo: Sendable {
54
54
/// from non-test targets or files that don't actually contain any tests.
55
55
package var mayContainTests : Bool
56
56
57
+ /// Source files returned here fall into two categories:
58
+ /// - Buildable source files are files that can be built by the build system and that make sense to background index
59
+ /// - Non-buildable source files include eg. the SwiftPM package manifest or header files. We have sufficient
60
+ /// compiler arguments for these files to provide semantic editor functionality but we can't build them.
61
+ package var isBuildable : Bool
62
+
57
63
fileprivate func merging( _ other: SourceFileInfo ? ) -> SourceFileInfo {
58
64
guard let other else {
59
65
return self
60
66
}
61
67
return SourceFileInfo (
62
68
targets: targets. union ( other. targets) ,
63
69
isPartOfRootProject: other. isPartOfRootProject || isPartOfRootProject,
64
- mayContainTests: other. mayContainTests || mayContainTests
70
+ mayContainTests: other. mayContainTests || mayContainTests,
71
+ isBuildable: other. isBuildable || isBuildable
65
72
)
66
73
}
67
74
}
@@ -327,11 +334,9 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
327
334
328
335
private var cachedTargetSources = RequestCache < BuildTargetSourcesRequest > ( )
329
336
330
- /// The parameters with which `SourceFilesAndDirectories` can be cached in `cachedSourceFilesAndDirectories`.
331
- private struct SourceFilesAndDirectoriesKey : Hashable {
332
- let includeNonBuildableFiles : Bool
333
- let sourcesItems : [ SourcesItem ]
334
- }
337
+ /// `SourceFilesAndDirectories` is a global property that only gets reset when the build targets change and thus
338
+ /// has no real key.
339
+ private struct SourceFilesAndDirectoriesKey : Hashable { }
335
340
336
341
private struct SourceFilesAndDirectories {
337
342
/// The source files in the workspace, ie. all `SourceItem`s that have `kind == .file`.
@@ -675,7 +680,7 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
675
680
package func targets( for document: DocumentURI ) async -> Set < BuildTargetIdentifier > {
676
681
return await orLog ( " Getting targets for source file " ) {
677
682
var result : Set < BuildTargetIdentifier > = [ ]
678
- let filesAndDirectories = try await sourceFilesAndDirectories ( includeNonBuildableFiles : true )
683
+ let filesAndDirectories = try await sourceFilesAndDirectories ( )
679
684
if let targets = filesAndDirectories. files [ document] ? . targets {
680
685
result. formUnion ( targets)
681
686
}
@@ -1032,46 +1037,35 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
1032
1037
///
1033
1038
/// - SeeAlso: Comment in `sourceFilesAndDirectories` for a definition of what `buildable` means.
1034
1039
package func buildableSourceFiles( ) async throws -> [ DocumentURI : SourceFileInfo ] {
1035
- return try await sourceFilesAndDirectories ( includeNonBuildableFiles : false ) . files
1040
+ return try await sourceFilesAndDirectories ( ) . files. filter ( \ . value . isBuildable )
1036
1041
}
1037
1042
1038
1043
/// Get all files and directories that are known to the build system, ie. that are returned by a `buildTarget/sources`
1039
1044
/// request for any target in the project.
1040
1045
///
1041
- /// Source files returned here fall into two categories:
1042
- /// - Buildable source files are files that can be built by the build system and that make sense to background index
1043
- /// - Non-buildable source files include eg. the SwiftPM package manifest or header files. We have sufficient
1044
- /// compiler arguments for these files to provide semantic editor functionality but we can't build them.
1045
- ///
1046
- /// `includeNonBuildableFiles` determines whether non-buildable files should be included.
1047
- private func sourceFilesAndDirectories( includeNonBuildableFiles: Bool ) async throws -> SourceFilesAndDirectories {
1048
- let targets = try await self . buildTargets ( )
1049
- let sourcesItems = try await self . sourceFiles ( in: Set ( targets. keys) )
1050
-
1051
- let key = SourceFilesAndDirectoriesKey (
1052
- includeNonBuildableFiles: includeNonBuildableFiles,
1053
- sourcesItems: sourcesItems
1054
- )
1046
+ /// - Important: This method returns both buildable and non-buildable source files. Callers need to check
1047
+ /// `SourceFileInfo.isBuildable` if they are only interested in buildable source files.
1048
+ private func sourceFilesAndDirectories( ) async throws -> SourceFilesAndDirectories {
1049
+ return try await cachedSourceFilesAndDirectories. get (
1050
+ SourceFilesAndDirectoriesKey ( ) ,
1051
+ isolation: self
1052
+ ) { key in
1053
+ let targets = try await self . buildTargets ( )
1054
+ let sourcesItems = try await self . sourceFiles ( in: Set ( targets. keys) )
1055
1055
1056
- return try await cachedSourceFilesAndDirectories. get ( key, isolation: self ) { key in
1057
1056
var files : [ DocumentURI : SourceFileInfo ] = [ : ]
1058
1057
var directories : [ DocumentURI : SourceFileInfo ] = [ : ]
1059
- for sourcesItem in key . sourcesItems {
1058
+ for sourcesItem in sourcesItems {
1060
1059
let target = targets [ sourcesItem. target] ? . target
1061
1060
let isPartOfRootProject = !( target? . tags. contains ( . dependency) ?? false )
1062
1061
let mayContainTests = target? . tags. contains ( . test) ?? true
1063
- if !key. includeNonBuildableFiles && ( target? . tags. contains ( . notBuildable) ?? false ) {
1064
- continue
1065
- }
1066
-
1067
1062
for sourceItem in sourcesItem. sources {
1068
- if !key. includeNonBuildableFiles && sourceItem. sourceKitData? . isHeader ?? false {
1069
- continue
1070
- }
1071
1063
let info = SourceFileInfo (
1072
1064
targets: [ sourcesItem. target] ,
1073
1065
isPartOfRootProject: isPartOfRootProject,
1074
- mayContainTests: mayContainTests
1066
+ mayContainTests: mayContainTests,
1067
+ isBuildable: !( target? . tags. contains ( . notBuildable) ?? false )
1068
+ && !( sourceItem. sourceKitData? . isHeader ?? false )
1075
1069
)
1076
1070
switch sourceItem. kind {
1077
1071
case . file:
0 commit comments