diff --git a/Sources/SwiftDriver/IncrementalCompilation/DependencyKey.swift b/Sources/SwiftDriver/IncrementalCompilation/DependencyKey.swift index 77e531515..fc5478a30 100644 --- a/Sources/SwiftDriver/IncrementalCompilation/DependencyKey.swift +++ b/Sources/SwiftDriver/IncrementalCompilation/DependencyKey.swift @@ -19,6 +19,10 @@ import TSCBasic try? fileSystem.getFileInfo(file).modTime } + var swiftModuleFile: TypedVirtualPath? { + isSwiftModule ? TypedVirtualPath(file: file, type: .swiftModule) : nil + } + public var description: String { file.name } @@ -39,8 +43,13 @@ public struct FingerprintedExternalDependency: Hashable, Equatable, ExternalDepe assert(verifyExternalDependencyAndFingerprint()) } var externalDependencyToCheck: ExternalDependency? { externalDependency } - var isIncremental: Bool { - fingerprint != nil && externalDependency.isSwiftModule + var incrementalDependencySource: DependencySource? { + guard let _ = fingerprint, + let swiftModuleFile = externalDependency.swiftModuleFile + else { + return nil + } + return DependencySource(swiftModuleFile) } } diff --git a/Sources/SwiftDriver/IncrementalCompilation/ModuleDependencyGraph.swift b/Sources/SwiftDriver/IncrementalCompilation/ModuleDependencyGraph.swift index f1a6bfb8d..8708b9c59 100644 --- a/Sources/SwiftDriver/IncrementalCompilation/ModuleDependencyGraph.swift +++ b/Sources/SwiftDriver/IncrementalCompilation/ModuleDependencyGraph.swift @@ -209,12 +209,9 @@ extension ModuleDependencyGraph { externalDependency: FingerprintedExternalDependency, fileSystem: FileSystem ) -> Integrator.Results? { - // Save time; don't even try - guard externalDependency.isIncremental else { + guard let dependencySource = externalDependency.incrementalDependencySource else { return Integrator.Results() } - let file = externalDependency.externalDependency.file - let dependencySource = DependencySource(file) reporter?.report("integrating incremental external dependency", dependencySource.typedFile) guard let sourceGraph = dependencySource.read( @@ -445,6 +442,7 @@ extension ModuleDependencyGraph { case unexpectedSubblock case bogusNameOrContext case unknownKind + case unknownDependencySourceExtension } /// Attempts to read a serialized dependency graph from the given path. @@ -559,9 +557,12 @@ extension ModuleDependencyGraph { let swiftDepsStr = hasSwiftDeps ? identifiers[Int(record.fields[5])] : nil let hasFingerprint = Int(record.fields[6]) != 0 let fingerprint = hasFingerprint ? fingerprintStr : nil - let dependencySource = try swiftDepsStr - .map({ try VirtualPath(path: $0) }) - .map(DependencySource.init) + guard let dependencySource = try swiftDepsStr + .map({ try VirtualPath(path: $0) }) + .map(DependencySource.init) + else { + throw ReadError.unknownDependencySourceExtension + } self.finalize(node: Node(key: key, fingerprint: fingerprint, dependencySource: dependencySource)) diff --git a/Sources/SwiftDriver/IncrementalCompilation/ModuleDependencyGraphParts/DependencySource.swift b/Sources/SwiftDriver/IncrementalCompilation/ModuleDependencyGraphParts/DependencySource.swift index 98c24c6e2..5bd5275ca 100644 --- a/Sources/SwiftDriver/IncrementalCompilation/ModuleDependencyGraphParts/DependencySource.swift +++ b/Sources/SwiftDriver/IncrementalCompilation/ModuleDependencyGraphParts/DependencySource.swift @@ -26,14 +26,15 @@ public struct DependencySource: Hashable, CustomStringConvertible { } /*@_spi(Testing)*/ - public init(_ file: VirtualPath) { + /// Returns nil if cannot be a source + public init?(_ file: VirtualPath) { let ext = file.extension - let typeIfExpected = + guard let type = ext == FileType.swiftDeps .rawValue ? FileType.swiftDeps : ext == FileType.swiftModule.rawValue ? FileType.swiftModule : nil - guard let type = typeIfExpected else { - fatalError("unexpected dependencySource extension: \(String(describing: ext))") + else { + return nil } self.init(TypedVirtualPath(file: file, type: type)) } @@ -48,7 +49,7 @@ public struct DependencySource: Hashable, CustomStringConvertible { // MARK: - mocking extension DependencySource { /*@_spi(Testing)*/ public init(mock i: Int) { - self.init(try! VirtualPath(path: String(i) + "." + FileType.swiftDeps.rawValue)) + self.init(try! VirtualPath(path: String(i) + "." + FileType.swiftDeps.rawValue))! } /*@_spi(Testing)*/ public var mockID: Int { diff --git a/Tests/SwiftDriverTests/IncrementalCompilationTests.swift b/Tests/SwiftDriverTests/IncrementalCompilationTests.swift index 7b8b00ac5..f4065a173 100644 --- a/Tests/SwiftDriverTests/IncrementalCompilationTests.swift +++ b/Tests/SwiftDriverTests/IncrementalCompilationTests.swift @@ -68,7 +68,7 @@ final class NonincrementalCompilationTests: XCTestCase { func testReadBinarySourceFileDependencyGraph() throws { let absolutePath = try XCTUnwrap(Fixture.fixturePath(at: RelativePath("Incremental"), for: "main.swiftdeps")) - let dependencySource = DependencySource(VirtualPath.absolute(absolutePath)) + let dependencySource = DependencySource(VirtualPath.absolute(absolutePath))! let graph = try XCTUnwrap( try SourceFileDependencyGraph( contentsOf: dependencySource, @@ -117,7 +117,7 @@ final class NonincrementalCompilationTests: XCTestCase { for: "hello.swiftdeps")) let graph = try XCTUnwrap( try SourceFileDependencyGraph( - contentsOf: DependencySource(VirtualPath.absolute(absolutePath)), + contentsOf: DependencySource(VirtualPath.absolute(absolutePath))!, on: localFileSystem)) XCTAssertEqual(graph.majorVersion, 1) XCTAssertEqual(graph.minorVersion, 0) @@ -171,7 +171,7 @@ final class NonincrementalCompilationTests: XCTestCase { let data = try localFileSystem.readFileContents(absolutePath) let graph = try XCTUnwrap( try SourceFileDependencyGraph(data: data, - from: DependencySource(.absolute(absolutePath)), + from: DependencySource(.absolute(absolutePath))!, fromSwiftModule: true)) XCTAssertEqual(graph.majorVersion, 1) XCTAssertEqual(graph.minorVersion, 0) @@ -822,7 +822,8 @@ class CrossModuleIncrementalBuildTests: XCTestCase { let sourcePath = path.appending(component: "main.swiftdeps") let data = try localFileSystem.readFileContents(sourcePath) - let graph = try XCTUnwrap(SourceFileDependencyGraph(data: data, from: DependencySource(.absolute(sourcePath)), fromSwiftModule: false)) + let graph = try XCTUnwrap(SourceFileDependencyGraph(data: data, from: DependencySource(.absolute(sourcePath))!, + fromSwiftModule: false)) XCTAssertEqual(graph.majorVersion, 1) XCTAssertEqual(graph.minorVersion, 0) graph.verify()