Skip to content

Commit 40ee43e

Browse files
authored
Merge pull request #1042 from nkcsgexi/ismixed
AdopterAnalysis: record whether a framework has compatibility header and whether it's a mixed-source project
2 parents 424a001 + 03bef0b commit 40ee43e

File tree

10 files changed

+64
-2
lines changed

10 files changed

+64
-2
lines changed

Sources/SwiftDriver/Jobs/PrebuiltModulesJob.swift

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,15 +250,32 @@ public class SwiftAdopter: Codable {
250250
public let hasModule: Bool
251251
public let isFramework: Bool
252252
public let isPrivate: Bool
253-
init(_ name: String, _ moduleDir: AbsolutePath, _ hasInterface: [AbsolutePath], _ hasModule: [AbsolutePath]) {
253+
public let hasCompatibilityHeader: Bool
254+
public let isMixed: Bool
255+
init(_ name: String, _ moduleDir: AbsolutePath, _ hasInterface: [AbsolutePath], _ hasModule: [AbsolutePath]) throws {
254256
self.name = name
255257
self.moduleDir = SwiftAdopter.relativeToSDK(moduleDir)
256258
self.hasInterface = !hasInterface.isEmpty
257259
self.hasPrivateInterface = hasInterface.contains { $0.basename.hasSuffix(".private.swiftinterface") }
258260
self.hasModule = !hasModule.isEmpty
259261
self.isFramework = self.moduleDir.contains("\(name).framework")
260262
self.isPrivate = self.moduleDir.contains("PrivateFrameworks")
263+
let headers = try SwiftAdopter.collectHeaderNames(moduleDir.parentDirectory.parentDirectory)
264+
self.hasCompatibilityHeader = headers.contains { $0 == "\(name)-Swift.h" }
265+
self.isMixed = headers.contains { $0 != "\(name)-Swift.h" }
261266
}
267+
268+
static func collectHeaderNames(_ headersIn: AbsolutePath) throws -> [String] {
269+
var results: [String] = []
270+
let collector = { (dir: AbsolutePath) in
271+
guard localFileSystem.exists(dir) else { return }
272+
try localFileSystem.getDirectoryContents(dir).forEach { results.append($0) }
273+
}
274+
try collector(headersIn.appending(component: "Headers"))
275+
try collector(headersIn.appending(component: "PrivateHeaders"))
276+
return results
277+
}
278+
262279
static func relativeToSDK(_ fullPath: AbsolutePath) -> String {
263280
var SDKDir: AbsolutePath = fullPath
264281
while(SDKDir.extension != "sdk") {
@@ -372,7 +389,7 @@ public struct SDKPrebuiltModuleInputsCollector {
372389
hasModule.append(currentFile)
373390
}
374391
}
375-
allSwiftAdopters.append(SwiftAdopter(moduleName, dir, hasInterface, hasModule))
392+
allSwiftAdopters.append(try! SwiftAdopter(moduleName, dir, hasInterface, hasModule))
376393
}
377394
// Search inside framework dirs in an SDK to find .swiftmodule directories.
378395
for dir in frameworkDirs {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
framework module B [extern_c] {
2+
umbrella header "B.h"
3+
export *
4+
module * { export * }
5+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// Nothing interesting
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// nothing interesting
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// swift-interface-format-version: 1.0
2+
// swift-module-flags: -module-name C
3+
import Swift
4+
public func FuncE() { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// swift-interface-format-version: 1.0
2+
// swift-module-flags: -module-name C
3+
import Swift
4+
public func FuncE() { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// swift-interface-format-version: 1.0
2+
// swift-module-flags: -module-name C
3+
import Swift
4+
public func FuncE() { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// swift-interface-format-version: 1.0
2+
// swift-module-flags: -module-name C
3+
import Swift
4+
public func FuncE() { }
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
framework module C [extern_c] {
2+
umbrella header "C.h"
3+
export *
4+
module * { export * }
5+
}

Tests/SwiftDriverTests/ExplicitModuleBuildTests.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1555,5 +1555,22 @@ final class ExplicitModuleBuildTests: XCTestCase {
15551555
XCTAssertFalse(B.hasModule)
15561556
XCTAssertTrue(B.hasPrivateInterface)
15571557
}
1558+
1559+
func testCollectSwiftAdoptersWhetherMixed() throws {
1560+
let mockSDKPath = testInputsPath.appending(component: "mock-sdk.Internal.sdk")
1561+
let mockSDKPathStr: String = mockSDKPath.pathString
1562+
let collector = try SDKPrebuiltModuleInputsCollector(VirtualPath(path: mockSDKPathStr).absolutePath!, DiagnosticsEngine())
1563+
let adopters = try collector.collectSwiftInterfaceMap().adopters
1564+
XCTAssertTrue(!adopters.isEmpty)
1565+
let B = adopters.first {$0.name == "B"}!
1566+
XCTAssertTrue(B.isFramework)
1567+
XCTAssertTrue(B.hasCompatibilityHeader)
1568+
XCTAssertFalse(B.isMixed)
1569+
1570+
let C = adopters.first {$0.name == "C"}!
1571+
XCTAssertTrue(C.isFramework)
1572+
XCTAssertFalse(C.hasCompatibilityHeader)
1573+
XCTAssertTrue(C.isMixed)
1574+
}
15581575
#endif
15591576
}

0 commit comments

Comments
 (0)