@@ -642,24 +642,31 @@ final class ExplicitModuleBuildTests: XCTestCase {
642642 }
643643 }
644644
645- /// Test the libSwiftScan dependency scanning.
646- func testDependencyScanning( ) throws {
645+ private func getDriverArtifactsForScanning( ) throws -> ( stdLibPath: AbsolutePath ,
646+ shimsPath: AbsolutePath ,
647+ toolchain: Toolchain ,
648+ hostTriple: Triple ) {
647649 // Just instantiating to get at the toolchain path
648650 let driver = try Driver ( args: [ " swiftc " , " -experimental-explicit-module-build " ,
649651 " -module-name " , " testDependencyScanning " ,
650652 " test.swift " ] )
651653 let ( stdLibPath, shimsPath) = try getStdlibShimsPaths ( driver)
652-
653654 XCTAssertTrue ( localFileSystem. exists ( stdLibPath) ,
654655 " expected Swift StdLib at: \( stdLibPath. description) " )
655656 XCTAssertTrue ( localFileSystem. exists ( shimsPath) ,
656657 " expected Swift Shims at: \( shimsPath. description) " )
658+ return ( stdLibPath, shimsPath, driver. toolchain, driver. hostTriple)
659+ }
660+
661+ /// Test the libSwiftScan dependency scanning.
662+ func testDependencyScanning( ) throws {
663+ let ( stdLibPath, shimsPath, toolchain, hostTriple) = try getDriverArtifactsForScanning ( )
657664
658665 // The dependency oracle wraps an instance of libSwiftScan and ensures thread safety across
659666 // queries.
660667 let dependencyOracle = InterModuleDependencyOracle ( )
661- let scanLibPath = try Driver . getScanLibPath ( of: driver . toolchain,
662- hostTriple: driver . hostTriple,
668+ let scanLibPath = try Driver . getScanLibPath ( of: toolchain,
669+ hostTriple: hostTriple,
663670 env: ProcessEnv . vars)
664671 guard try dependencyOracle
665672 . verifyOrCreateScannerInstance ( fileSystem: localFileSystem,
@@ -694,8 +701,8 @@ final class ExplicitModuleBuildTests: XCTestCase {
694701 // Module `X` is only imported on Darwin when:
695702 // #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 110000
696703 let expectedNumberOfDependencies : Int
697- if driver . targetTriple . isMacOSX,
698- driver . targetTriple . version ( for: . macOS) >= Triple . Version ( 11 , 0 , 0 ) {
704+ if hostTriple . isMacOSX,
705+ hostTriple . version ( for: . macOS) >= Triple . Version ( 11 , 0 , 0 ) {
699706 expectedNumberOfDependencies = 11
700707 } else {
701708 expectedNumberOfDependencies = 12
@@ -733,6 +740,64 @@ final class ExplicitModuleBuildTests: XCTestCase {
733740 }
734741 }
735742
743+
744+ /// Test the libSwiftScan dependency scanning.
745+ func testDependencyScanReuseCache( ) throws {
746+ let ( stdLibPath, shimsPath, toolchain, hostTriple) = try getDriverArtifactsForScanning ( )
747+ try withTemporaryDirectory { path in
748+ let cacheSavePath = path. appending ( component: " saved.moddepcache " )
749+ let main = path. appending ( component: " testDependencyScanning.swift " )
750+ try localFileSystem. writeFileContents ( main) {
751+ $0 <<< " import C; "
752+ $0 <<< " import E; "
753+ $0 <<< " import G; "
754+ }
755+ let packageRootPath = URL ( fileURLWithPath: #file) . pathComponents
756+ . prefix ( while: { $0 != " Tests " } ) . joined ( separator: " / " ) . dropFirst ( )
757+ let testInputsPath = packageRootPath + " /TestInputs "
758+ let cHeadersPath : String = testInputsPath + " /ExplicitModuleBuilds/CHeaders "
759+ let swiftModuleInterfacesPath : String = testInputsPath + " /ExplicitModuleBuilds/Swift "
760+ let scannerCommand = [ " -scan-dependencies " ,
761+ " -I " , cHeadersPath,
762+ " -I " , swiftModuleInterfacesPath,
763+ " -I " , stdLibPath. description,
764+ " -I " , shimsPath. description,
765+ main. pathString]
766+
767+ let scanLibPath = try Driver . getScanLibPath ( of: toolchain,
768+ hostTriple: hostTriple,
769+ env: ProcessEnv . vars)
770+ // Run the first scan and serialize the cache contents.
771+ let firstDependencyOracle = InterModuleDependencyOracle ( )
772+ guard try firstDependencyOracle
773+ . verifyOrCreateScannerInstance ( fileSystem: localFileSystem,
774+ swiftScanLibPath: scanLibPath) else {
775+ XCTFail ( " Dependency scanner library not found " )
776+ return
777+ }
778+
779+ let firstScanGraph =
780+ try ! firstDependencyOracle. getDependencies ( workingDirectory: path,
781+ commandLine: scannerCommand)
782+ firstDependencyOracle. serializeScannerCache ( to: cacheSavePath)
783+
784+ // Run the second scan, re-using the serialized cache contents.
785+ let secondDependencyOracle = InterModuleDependencyOracle ( )
786+ guard try secondDependencyOracle
787+ . verifyOrCreateScannerInstance ( fileSystem: localFileSystem,
788+ swiftScanLibPath: scanLibPath) else {
789+ XCTFail ( " Dependency scanner library not found " )
790+ return
791+ }
792+ XCTAssertFalse ( secondDependencyOracle. loadScannerCache ( from: cacheSavePath) )
793+ let secondScanGraph =
794+ try ! secondDependencyOracle. getDependencies ( workingDirectory: path,
795+ commandLine: scannerCommand)
796+
797+ XCTAssertTrue ( firstScanGraph. modules. count == secondScanGraph. modules. count)
798+ }
799+ }
800+
736801 func testDependencyGraphMerge( ) throws {
737802 let moduleDependencyGraph1 =
738803 try JSONDecoder ( ) . decode (
0 commit comments