@@ -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`.
@@ -678,7 +683,7 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
678
683
package func targets( for document: DocumentURI ) async -> Set < BuildTargetIdentifier > {
679
684
return await orLog ( " Getting targets for source file " ) {
680
685
var result : Set < BuildTargetIdentifier > = [ ]
681
- let filesAndDirectories = try await sourceFilesAndDirectories ( includeNonBuildableFiles : true )
686
+ let filesAndDirectories = try await sourceFilesAndDirectories ( )
682
687
if let targets = filesAndDirectories. files [ document] ? . targets {
683
688
result. formUnion ( targets)
684
689
}
@@ -1037,46 +1042,35 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
1037
1042
///
1038
1043
/// - SeeAlso: Comment in `sourceFilesAndDirectories` for a definition of what `buildable` means.
1039
1044
package func buildableSourceFiles( ) async throws -> [ DocumentURI : SourceFileInfo ] {
1040
- return try await sourceFilesAndDirectories ( includeNonBuildableFiles : false ) . files
1045
+ return try await sourceFilesAndDirectories ( ) . files. filter ( \ . value . isBuildable )
1041
1046
}
1042
1047
1043
1048
/// Get all files and directories that are known to the build system, ie. that are returned by a `buildTarget/sources`
1044
1049
/// request for any target in the project.
1045
1050
///
1046
- /// Source files returned here fall into two categories:
1047
- /// - Buildable source files are files that can be built by the build system and that make sense to background index
1048
- /// - Non-buildable source files include eg. the SwiftPM package manifest or header files. We have sufficient
1049
- /// compiler arguments for these files to provide semantic editor functionality but we can't build them.
1050
- ///
1051
- /// `includeNonBuildableFiles` determines whether non-buildable files should be included.
1052
- private func sourceFilesAndDirectories( includeNonBuildableFiles: Bool ) async throws -> SourceFilesAndDirectories {
1053
- let targets = try await self . buildTargets ( )
1054
- let sourcesItems = try await self . sourceFiles ( in: Set ( targets. keys) )
1055
-
1056
- let key = SourceFilesAndDirectoriesKey (
1057
- includeNonBuildableFiles: includeNonBuildableFiles,
1058
- sourcesItems: sourcesItems
1059
- )
1051
+ /// - Important: This method returns both buildable and non-buildable source files. Callers need to check
1052
+ /// `SourceFileInfo.isBuildable` if they are only interested in buildable source files.
1053
+ private func sourceFilesAndDirectories( ) async throws -> SourceFilesAndDirectories {
1054
+ return try await cachedSourceFilesAndDirectories. get (
1055
+ SourceFilesAndDirectoriesKey ( ) ,
1056
+ isolation: self
1057
+ ) { key in
1058
+ let targets = try await self . buildTargets ( )
1059
+ let sourcesItems = try await self . sourceFiles ( in: Set ( targets. keys) )
1060
1060
1061
- return try await cachedSourceFilesAndDirectories. get ( key, isolation: self ) { key in
1062
1061
var files : [ DocumentURI : SourceFileInfo ] = [ : ]
1063
1062
var directories : [ DocumentURI : ( pathComponents: [ String ] ? , info: SourceFileInfo ) ] = [ : ]
1064
- for sourcesItem in key . sourcesItems {
1063
+ for sourcesItem in sourcesItems {
1065
1064
let target = targets [ sourcesItem. target] ? . target
1066
1065
let isPartOfRootProject = !( target? . tags. contains ( . dependency) ?? false )
1067
1066
let mayContainTests = target? . tags. contains ( . test) ?? true
1068
- if !key. includeNonBuildableFiles && ( target? . tags. contains ( . notBuildable) ?? false ) {
1069
- continue
1070
- }
1071
-
1072
1067
for sourceItem in sourcesItem. sources {
1073
- if !key. includeNonBuildableFiles && sourceItem. sourceKitData? . isHeader ?? false {
1074
- continue
1075
- }
1076
1068
let info = SourceFileInfo (
1077
1069
targets: [ sourcesItem. target] ,
1078
1070
isPartOfRootProject: isPartOfRootProject,
1079
- mayContainTests: mayContainTests
1071
+ mayContainTests: mayContainTests,
1072
+ isBuildable: !( target? . tags. contains ( . notBuildable) ?? false )
1073
+ && !( sourceItem. sourceKitData? . isHeader ?? false )
1080
1074
)
1081
1075
switch sourceItem. kind {
1082
1076
case . file:
0 commit comments