@@ -1167,6 +1167,69 @@ final class ExplicitModuleBuildTests: XCTestCase {
11671167 }
11681168 }
11691169
1170+ func testDependencyGraphDotSerialization( ) throws {
1171+ let ( stdlibPath, shimsPath, toolchain, hostTriple) = try getDriverArtifactsForScanning ( )
1172+ let dependencyOracle = InterModuleDependencyOracle ( )
1173+ let scanLibPath = try Driver . getScanLibPath ( of: toolchain,
1174+ hostTriple: hostTriple,
1175+ env: ProcessEnv . vars)
1176+ guard try dependencyOracle
1177+ . verifyOrCreateScannerInstance ( fileSystem: localFileSystem,
1178+ swiftScanLibPath: scanLibPath) else {
1179+ XCTFail ( " Dependency scanner library not found " )
1180+ return
1181+ }
1182+ // Create a simple test case.
1183+ try withTemporaryDirectory { path in
1184+ let main = path. appending ( component: " testDependencyScanning.swift " )
1185+ try localFileSystem. writeFileContents ( main) {
1186+ $0 <<< " import C; "
1187+ $0 <<< " import E; "
1188+ $0 <<< " import G; "
1189+ }
1190+
1191+ let cHeadersPath : AbsolutePath =
1192+ testInputsPath. appending ( component: " ExplicitModuleBuilds " )
1193+ . appending ( component: " CHeaders " )
1194+ let swiftModuleInterfacesPath : AbsolutePath =
1195+ testInputsPath. appending ( component: " ExplicitModuleBuilds " )
1196+ . appending ( component: " Swift " )
1197+ let sdkArgumentsForTesting = ( try ? Driver . sdkArgumentsForTesting ( ) ) ?? [ ]
1198+ var driver = try Driver ( args: [ " swiftc " ,
1199+ " -I " , cHeadersPath. nativePathString ( escaped: true ) ,
1200+ " -I " , swiftModuleInterfacesPath. nativePathString ( escaped: true ) ,
1201+ " -I " , stdlibPath. nativePathString ( escaped: true ) ,
1202+ " -I " , shimsPath. nativePathString ( escaped: true ) ,
1203+ " -import-objc-header " ,
1204+ " -explicit-module-build " ,
1205+ " -working-directory " , path. nativePathString ( escaped: true ) ,
1206+ " -disable-clang-target " ,
1207+ main. nativePathString ( escaped: true ) ] + sdkArgumentsForTesting,
1208+ env: ProcessEnv . vars)
1209+ let resolver = try ArgsResolver ( fileSystem: localFileSystem)
1210+ var scannerCommand = try driver. dependencyScannerInvocationCommand ( ) . 1 . map { try resolver. resolve ( $0) }
1211+ if scannerCommand. first == " -frontend " {
1212+ scannerCommand. removeFirst ( )
1213+ }
1214+ let dependencyGraph =
1215+ try dependencyOracle. getDependencies ( workingDirectory: path,
1216+ commandLine: scannerCommand)
1217+ let serializer = DOTModuleDependencyGraphSerializer ( dependencyGraph)
1218+
1219+ let outputFile = path. appending ( component: " dependency_graph.dot " )
1220+ var outputStream = try ThreadSafeOutputByteStream ( LocalFileOutputByteStream ( outputFile) )
1221+ serializer. writeDOT ( to: & outputStream)
1222+ outputStream. flush ( )
1223+ let contents = try localFileSystem. readFileContents ( outputFile) . description
1224+ XCTAssertTrue ( contents. contains ( " \" testDependencyScanning \" [shape=box, style=bold, color=navy " ) )
1225+ XCTAssertTrue ( contents. contains ( " \" G \" [style=bold, color=orange " ) )
1226+ XCTAssertTrue ( contents. contains ( " \" E \" [style=bold, color=orange, style=filled " ) )
1227+ XCTAssertTrue ( contents. contains ( " \" C (C) \" [style=bold, color=lightskyblue, style=filled " ) )
1228+ XCTAssertTrue ( contents. contains ( " \" Swift \" [style=bold, color=orange, style=filled " ) )
1229+ XCTAssertTrue ( contents. contains ( " \" SwiftShims (C) \" [style=bold, color=lightskyblue, style=filled " ) )
1230+ XCTAssertTrue ( contents. contains ( " \" Swift \" -> \" SwiftShims (C) \" [color=black]; " ) )
1231+ }
1232+ }
11701233
11711234 /// Test the libSwiftScan dependency scanning.
11721235 func testDependencyScanReuseCache( ) throws {
0 commit comments