diff --git a/Sources/CSwiftScan/include/swiftscan_header.h b/Sources/CSwiftScan/include/swiftscan_header.h index b751978ff..f6e8e00cd 100644 --- a/Sources/CSwiftScan/include/swiftscan_header.h +++ b/Sources/CSwiftScan/include/swiftscan_header.h @@ -141,6 +141,8 @@ typedef struct { (*swiftscan_swift_textual_detail_get_is_framework)(swiftscan_module_details_t); swiftscan_string_set_t * (*swiftscan_swift_textual_detail_get_swift_overlay_dependencies)(swiftscan_module_details_t); + swiftscan_string_set_t * + (*swiftscan_swift_textual_detail_get_swift_source_import_module_dependencies)(swiftscan_module_details_t); swiftscan_string_ref_t (*swiftscan_swift_textual_detail_get_module_cache_key)(swiftscan_module_details_t); swiftscan_string_ref_t diff --git a/Sources/SwiftDriver/ExplicitModuleBuilds/InterModuleDependencies/InterModuleDependencyGraph.swift b/Sources/SwiftDriver/ExplicitModuleBuilds/InterModuleDependencies/InterModuleDependencyGraph.swift index 85b9b04c2..a7272b790 100644 --- a/Sources/SwiftDriver/ExplicitModuleBuilds/InterModuleDependencies/InterModuleDependencyGraph.swift +++ b/Sources/SwiftDriver/ExplicitModuleBuilds/InterModuleDependencies/InterModuleDependencyGraph.swift @@ -136,7 +136,10 @@ public struct SwiftModuleDetails: Codable, Hashable { public var isFramework: Bool? /// A set of Swift Overlays of Clang Module Dependencies - var swiftOverlayDependencies: [ModuleDependencyId]? + public var swiftOverlayDependencies: [ModuleDependencyId]? + + /// A set of directly-imported in source module dependencies + public var sourceImportDependencies: [ModuleDependencyId]? /// The module cache key of the output module. public var moduleCacheKey: String? diff --git a/Sources/SwiftDriver/ExplicitModuleBuilds/InterModuleDependencies/InterModuleDependencyOracle.swift b/Sources/SwiftDriver/ExplicitModuleBuilds/InterModuleDependencies/InterModuleDependencyOracle.swift index c5463de10..06e42cabf 100644 --- a/Sources/SwiftDriver/ExplicitModuleBuilds/InterModuleDependencies/InterModuleDependencyOracle.swift +++ b/Sources/SwiftDriver/ExplicitModuleBuilds/InterModuleDependencies/InterModuleDependencyOracle.swift @@ -147,6 +147,13 @@ public class InterModuleDependencyOracle { return swiftScan.supportsLinkLibraries } + @_spi(Testing) public func supportsSeparateImportOnlyDependencise() throws -> Bool { + guard let swiftScan = swiftScanLibInstance else { + fatalError("Attempting to query supported scanner API with no scanner instance.") + } + return swiftScan.supportsSeparateImportOnlyDependencise + } + @_spi(Testing) public func getScannerDiagnostics() throws -> [ScannerDiagnosticPayload]? { guard let swiftScan = swiftScanLibInstance else { fatalError("Attempting to reset scanner cache with no scanner instance.") diff --git a/Sources/SwiftDriver/SwiftScan/DependencyGraphBuilder.swift b/Sources/SwiftDriver/SwiftScan/DependencyGraphBuilder.swift index 4e2cb06c2..f55fef5be 100644 --- a/Sources/SwiftDriver/SwiftScan/DependencyGraphBuilder.swift +++ b/Sources/SwiftDriver/SwiftScan/DependencyGraphBuilder.swift @@ -200,6 +200,16 @@ private extension SwiftScan { swiftOverlayDependencies = nil } + let sourceImportedDependencies: [ModuleDependencyId]? + if supportsSeparateImportOnlyDependencise, + let encodedImportedDepsRef = api.swiftscan_swift_textual_detail_get_swift_source_import_module_dependencies(moduleDetailsRef) { + let encodedImportedDepsendencies = try toSwiftStringArray(encodedImportedDepsRef.pointee) + sourceImportedDependencies = + try encodedImportedDepsendencies.map { try decodeModuleNameAndKind(from: $0, moduleAliases: moduleAliases) } + } else { + sourceImportedDependencies = nil + } + return SwiftModuleDetails(moduleInterfacePath: moduleInterfacePath, compiledModuleCandidates: compiledModuleCandidates, bridgingHeader: bridgingHeader, @@ -208,6 +218,7 @@ private extension SwiftScan { contextHash: contextHash, isFramework: isFramework, swiftOverlayDependencies: swiftOverlayDependencies, + sourceImportDependencies: sourceImportedDependencies, moduleCacheKey: moduleCacheKey, chainedBridgingHeaderPath: chainedBridgingHeaderPath, chainedBridgingHeaderContent: chainedBridgingHeaderContent) diff --git a/Sources/SwiftDriver/SwiftScan/SwiftScan.swift b/Sources/SwiftDriver/SwiftScan/SwiftScan.swift index ed878f944..804a1e8d6 100644 --- a/Sources/SwiftDriver/SwiftScan/SwiftScan.swift +++ b/Sources/SwiftDriver/SwiftScan/SwiftScan.swift @@ -246,6 +246,10 @@ private extension String { return api.swiftscan_swift_textual_detail_get_swift_overlay_dependencies != nil } + @_spi(Testing) public var supportsSeparateImportOnlyDependencise: Bool { + return api.swiftscan_swift_textual_detail_get_swift_source_import_module_dependencies != nil + } + @_spi(Testing) public var supportsScannerDiagnostics : Bool { return api.swiftscan_scanner_diagnostics_query != nil && api.swiftscan_scanner_diagnostics_reset != nil && @@ -573,6 +577,10 @@ private extension swiftscan_functions_t { self.swiftscan_swift_textual_detail_get_swift_overlay_dependencies = loadOptional("swiftscan_swift_textual_detail_get_swift_overlay_dependencies") + // Directly-imported source dependencies + self.swiftscan_swift_textual_detail_get_swift_source_import_module_dependencies = + loadOptional("swiftscan_swift_textual_detail_get_swift_source_import_module_dependencies") + // Header dependencies of binary modules self.swiftscan_swift_binary_detail_get_header_dependencies = loadOptional("swiftscan_swift_binary_detail_get_header_dependencies") diff --git a/Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift b/Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift index 4d420fc59..7ccec69de 100644 --- a/Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift +++ b/Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift @@ -619,6 +619,8 @@ final class ExplicitModuleBuildTests: XCTestCase { "-I", stdlibPath.nativePathString(escaped: true), "-I", shimsPath.nativePathString(escaped: true), "-explicit-module-build", + "-disable-implicit-concurrency-module-import", + "-disable-implicit-string-processing-module-import", "-import-objc-header", bridgingHeaderpath.nativePathString(escaped: true), main.nativePathString(escaped: true)] + sdkArgumentsForTesting) @@ -626,11 +628,21 @@ final class ExplicitModuleBuildTests: XCTestCase { // Figure out which Triples to use. let dependencyGraph = try driver.gatherModuleDependencies() let mainModuleInfo = try dependencyGraph.moduleInfo(of: .swift("testExplicitModuleBuildJobs")) - guard case .swift(_) = mainModuleInfo.details else { + + guard case .swift(let mainModuleDetails) = mainModuleInfo.details else { XCTFail("Main module does not have Swift details field") return } + if try driver.interModuleDependencyOracle.supportsSeparateImportOnlyDependencise() { + let directImportedDependencies = try XCTUnwrap(mainModuleDetails.sourceImportDependencies) + XCTAssertEqual(mainModuleDetails.sourceImportDependencies, [.swift("Swift"), + .swift("SwiftOnoneSupport"), + .swift("E"), + .swift("G"), + .clang("C")]) + } + for job in jobs { XCTAssertEqual(job.outputs.count, 1) let outputFilePath = job.outputs[0].file @@ -650,12 +662,6 @@ final class ExplicitModuleBuildTests: XCTestCase { } else if pathMatchesSwiftModule(path: outputFilePath, "Swift") { try checkExplicitModuleBuildJob(job: job, moduleId: .swift("Swift"), dependencyGraph: dependencyGraph) - } else if pathMatchesSwiftModule(path: outputFilePath, "_Concurrency") { - try checkExplicitModuleBuildJob(job: job, moduleId: .swift("_Concurrency"), - dependencyGraph: dependencyGraph) - } else if pathMatchesSwiftModule(path: outputFilePath, "_StringProcessing") { - try checkExplicitModuleBuildJob(job: job, moduleId: .swift("_StringProcessing"), - dependencyGraph: dependencyGraph) } else if pathMatchesSwiftModule(path: outputFilePath, "SwiftOnoneSupport") { try checkExplicitModuleBuildJob(job: job, moduleId: .swift("SwiftOnoneSupport"), dependencyGraph: dependencyGraph)