@@ -803,6 +803,82 @@ final class ExplicitModuleBuildTests: XCTestCase {
803803 }
804804 }
805805
806+ func testRegisterModuleDependencyFlag( ) throws {
807+ let ( stdlibPath, shimsPath, _, _) = try getDriverArtifactsForScanning ( )
808+ try withTemporaryDirectory { path in
809+ try localFileSystem. changeCurrentWorkingDirectory ( to: path)
810+ let moduleCachePath = path. appending ( component: " ModuleCache " )
811+ try localFileSystem. createDirectory ( moduleCachePath)
812+ let main = path. appending ( component: " testRegisterModuleDependency.swift " )
813+ // Note: We're NOT importing module E in the source code
814+ try localFileSystem. writeFileContents ( main, bytes:
815+ """
816+ import A;
817+ """
818+ )
819+ let cHeadersPath : AbsolutePath =
820+ try testInputsPath. appending ( component: " ExplicitModuleBuilds " )
821+ . appending ( component: " CHeaders " )
822+ let swiftModuleInterfacesPath : AbsolutePath =
823+ try testInputsPath. appending ( component: " ExplicitModuleBuilds " )
824+ . appending ( component: " Swift " )
825+ let sdkArgumentsForTesting = ( try ? Driver . sdkArgumentsForTesting ( ) ) ?? [ ]
826+
827+ var driver = try Driver ( args: [ " swiftc " ,
828+ " -I " , cHeadersPath. nativePathString ( escaped: true ) ,
829+ " -I " , swiftModuleInterfacesPath. nativePathString ( escaped: true ) ,
830+ " -I " , stdlibPath. nativePathString ( escaped: true ) ,
831+ " -I " , shimsPath. nativePathString ( escaped: true ) ,
832+ " -explicit-module-build " ,
833+ " -module-cache-path " , moduleCachePath. nativePathString ( escaped: true ) ,
834+ " -working-directory " , path. nativePathString ( escaped: true ) ,
835+ " -disable-implicit-concurrency-module-import " ,
836+ " -disable-implicit-string-processing-module-import " ,
837+ " -register-module-dependency " , " E " ,
838+ " -register-module-dependency " , " G " ,
839+ " -emit-loaded-module-trace " ,
840+ main. nativePathString ( escaped: true ) ] + sdkArgumentsForTesting)
841+ let dependencyGraph = try driver. scanModuleDependencies ( )
842+ let jobs = try driver. planBuild ( )
843+ // E and G SHOULD be in the dependency graph (registered for scanning)
844+ XCTAssertTrue ( dependencyGraph. modules. keys. contains ( . swift( " E " ) ) ,
845+ " Module E should be in dependency graph when registered via -register-module-dependency " )
846+ XCTAssertTrue ( dependencyGraph. modules. keys. contains ( . swift( " G " ) ) ,
847+ " Module G should be in dependency graph when registered via -register-module-dependency " )
848+ // Checking that registered module compiled
849+ let moduleEJobs = jobs. filter { job in
850+ job. outputs. contains { output in
851+ output. file. basename. contains ( " E " ) && output. file. extension == " swiftmodule "
852+ }
853+ }
854+ XCTAssertFalse ( moduleEJobs. isEmpty,
855+ " Module E should have a build job when registered via -register-module-dependency " )
856+ let moduleGJobs = jobs. filter { job in
857+ job. outputs. contains { output in
858+ output. file. basename. contains ( " G " ) && output. file. extension == " swiftmodule "
859+ }
860+ }
861+ XCTAssertFalse ( moduleGJobs. isEmpty,
862+ " Module G should have a build job when registered via -register-module-dependency " )
863+ // Checking that registered module is not loaded for the main compilation
864+ try driver. run ( jobs: jobs)
865+ XCTAssertFalse ( driver. diagnosticEngine. hasErrors)
866+ // Checking the output given by the -emit-loaded-module-trace flag
867+ let traceFile = path. appending ( component: " testRegisterModuleDependency.trace.json " )
868+ XCTAssertTrue ( localFileSystem. exists ( traceFile) , " Module trace file should exist " )
869+ let traceData = try localFileSystem. readFileContents ( traceFile)
870+ let traceJSON = try traceData. withData { data in
871+ try JSONSerialization . jsonObject ( with: data, options: [ ] ) as? [ String : Any ]
872+ }
873+ let jsonString = String ( decoding: traceData. contents, as: UTF8 . self)
874+ XCTAssertFalse ( jsonString. contains ( " \" name \" : \" E \" " ) ,
875+ " Module E should not be loaded in the final compilation since it's not imported " )
876+ XCTAssertFalse ( jsonString. contains ( " \" name \" : \" G \" " ) ,
877+ " Module G should not be loaded in the final compilation since it's not imported " )
878+
879+ }
880+ }
881+
806882 // Ensure that (even when not in '-incremental' mode) up-to-date module dependencies
807883 // do not get re-built
808884 func testExplicitModuleBuildIncrementalEndToEnd( ) throws {
0 commit comments