Skip to content

Commit a809b23

Browse files
committed
BridgeJS: Fix generic name collisions and nested enum tokens
1 parent b0d353d commit a809b23

17 files changed

Lines changed: 664 additions & 417 deletions

File tree

Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -857,8 +857,9 @@ public class ExportSwift {
857857
let concreteLiftedExprs = builder.liftedParameterExprs
858858
let concreteABINames = concreteABIParameters.map { $0.name }
859859

860-
func metatypeName(_ genericName: String) -> String { "\(genericName.lowercased())Type" }
861-
func typeIdName(_ genericName: String) -> String { "\(genericName.lowercased())TypeId" }
860+
func genericIndex(_ genericName: String) -> Int { genericNames.firstIndex(of: genericName) ?? 0 }
861+
func metatypeName(_ genericName: String) -> String { "_generic\(genericIndex(genericName))Type" }
862+
func typeIdName(_ genericName: String) -> String { "_generic\(genericIndex(genericName))TypeId" }
862863

863864
func argument(label: String?, expression: String) -> String {
864865
if let label, label != "_" {

Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,8 @@ public struct ImportTS {
246246
abiParameterForwardings.insert(contentsOf: ["resolveRef", "rejectRef"], at: 0)
247247
}
248248

249-
func appendTypeIDParameter(genericParameterName: String) {
250-
let abiParamName = "\(genericParameterName.lowercased())TypeId"
249+
func appendTypeIDParameter(index: Int, genericParameterName: String) {
250+
let abiParamName = "_generic\(index)TypeId"
251251
abiParameterSignatures.append((abiParamName, .i32))
252252
abiParameterForwardings.append("\(genericParameterName).bridgeJSTypeID")
253253
}
@@ -453,8 +453,8 @@ public struct ImportTS {
453453
for param in function.parameters {
454454
try builder.lowerParameter(param: param)
455455
}
456-
for genericParam in function.genericParameters ?? [] {
457-
builder.appendTypeIDParameter(genericParameterName: genericParam)
456+
for (index, genericParam) in (function.genericParameters ?? []).enumerated() {
457+
builder.appendTypeIDParameter(index: index, genericParameterName: genericParam)
458458
}
459459
try builder.call()
460460
try builder.liftReturnValue()

Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -470,12 +470,8 @@ public struct BridgeJSLink {
470470
}
471471
}
472472

473-
private func genericCodecEntries(
474-
allStructs: [ExportedStruct],
475-
allClasses: [ExportedClass],
476-
allEnums: [ExportedEnum]
477-
) -> [(token: String, type: BridgeType)] {
478-
var entries: [(token: String, type: BridgeType)] = [
473+
private var genericPrimitiveEntries: [(token: String, type: BridgeType)] {
474+
[
479475
("Bool", .bool),
480476
("Int", .integer(.int)),
481477
("Int8", .integer(.int8)),
@@ -492,6 +488,14 @@ public struct BridgeJSLink {
492488
("String", .string),
493489
("JSValue", .jsValue),
494490
]
491+
}
492+
493+
private func genericCodecEntries(
494+
allStructs: [ExportedStruct],
495+
allClasses: [ExportedClass],
496+
allEnums: [ExportedEnum]
497+
) -> [(token: String, type: BridgeType)] {
498+
var entries = genericPrimitiveEntries
495499
for structDef in allStructs {
496500
entries.append((structDef.abiName, .swiftStruct(structDef.abiName)))
497501
}
@@ -571,23 +575,9 @@ public struct BridgeJSLink {
571575
}
572576

573577
private func generateBridgeTypeTokens() -> (js: [String], dts: [String]) {
574-
let primitives: [(token: String, tsType: String)] = [
575-
("Bool", BridgeType.bool.tsType),
576-
("Int", BridgeType.integer(.int).tsType),
577-
("Int8", BridgeType.integer(.int8).tsType),
578-
("UInt8", BridgeType.integer(.uint8).tsType),
579-
("Int16", BridgeType.integer(.int16).tsType),
580-
("UInt16", BridgeType.integer(.uint16).tsType),
581-
("Int32", BridgeType.integer(.int32).tsType),
582-
("UInt32", BridgeType.integer(.uint32).tsType),
583-
("UInt", BridgeType.integer(.uint).tsType),
584-
("Int64", BridgeType.integer(.int64).tsType),
585-
("UInt64", BridgeType.integer(.uint64).tsType),
586-
("Float", BridgeType.float.tsType),
587-
("Double", BridgeType.double.tsType),
588-
("String", BridgeType.string.tsType),
589-
("JSValue", BridgeType.jsValue.tsType),
590-
]
578+
let primitives: [(token: String, tsType: String)] = genericPrimitiveEntries.map {
579+
(token: $0.token, tsType: $0.type.tsType)
580+
}
591581
func tsQualifiedName(name: String, namespace: [String]?) -> String {
592582
((namespace ?? []) + [name]).joined(separator: ".")
593583
}
@@ -609,8 +599,9 @@ public struct BridgeJSLink {
609599
)
610600
}
611601
for enumDef in enums {
612-
guard let bridgeType = genericEnumBridgeType(enumDef) else { continue }
613-
tokens.append((token: enumDef.abiName, tsType: bridgeType.tsType))
602+
guard genericEnumBridgeType(enumDef) != nil else { continue }
603+
let enumTypeName = enumDef.emitStyle == .tsEnum ? enumDef.tsFullPath : "\(enumDef.tsFullPath)Tag"
604+
tokens.append((token: enumDef.abiName, tsType: enumTypeName))
614605
}
615606

616607
let jsEntries = tokens.map { "\($0.token): \"\($0.token)\"" }
@@ -2201,9 +2192,20 @@ extension BridgeJSLink {
22012192
}
22022193
let concreteForwardings = thunkBuilder.parameterForwardings
22032194

2204-
func tokenName(_ genericName: String) -> String { "type\(genericName)" }
2205-
func codecVariable(_ genericName: String) -> String { "codec\(genericName)" }
2206-
func typeIdVariable(_ genericName: String) -> String { "\(genericName.lowercased())TypeId" }
2195+
let nameScope = JSGlueVariableScope(intrinsicRegistry: intrinsicRegistry)
2196+
for parameter in function.parameters {
2197+
_ = nameScope.variable(parameter.name)
2198+
}
2199+
let tokenNames = Dictionary(uniqueKeysWithValues: genericNames.map { ($0, nameScope.variable("type\($0)")) })
2200+
let codecNames = Dictionary(uniqueKeysWithValues: genericNames.map { ($0, nameScope.variable("codec\($0)")) })
2201+
let typeIdNames = Dictionary(
2202+
uniqueKeysWithValues: genericNames.map { ($0, nameScope.variable("\($0.lowercased())TypeId")) }
2203+
)
2204+
func tokenName(_ genericName: String) -> String { tokenNames[genericName] ?? "type\(genericName)" }
2205+
func codecVariable(_ genericName: String) -> String { codecNames[genericName] ?? "codec\(genericName)" }
2206+
func typeIdVariable(_ genericName: String) -> String {
2207+
typeIdNames[genericName] ?? "\(genericName.lowercased())TypeId"
2208+
}
22072209

22082210
let returnGenericName = function.returnType.referencedGenericName
22092211

@@ -2665,6 +2667,7 @@ extension BridgeJSLink {
26652667
var parameterForwardings: [String] = []
26662668
var returnExpr: String?
26672669
var genericCodecVariables: [String: String] = [:]
2670+
var genericTypeIdParameters: [String: String] = [:]
26682671
let printContext: IntrinsicJSFragment.PrintCodeContext
26692672

26702673
init(
@@ -2692,10 +2695,11 @@ extension BridgeJSLink {
26922695

26932696
func declareGenericCodecs(genericParameters: [String]) {
26942697
for genericParam in genericParameters {
2695-
let typeIdParam = "\(genericParam.lowercased())TypeId"
2698+
let typeIdParam = scope.variable("\(genericParam.lowercased())TypeId")
26962699
let codecVar = scope.variable("codec\(genericParam)")
26972700
body.write("const \(codecVar) = \(JSGlueVariableScope.reservedCodecsById)[\(typeIdParam)];")
26982701
genericCodecVariables[genericParam] = codecVar
2702+
genericTypeIdParameters[genericParam] = typeIdParam
26992703
}
27002704
}
27012705

@@ -3742,7 +3746,7 @@ extension BridgeJSLink {
37423746
try thunkBuilder.liftParameter(param: param)
37433747
}
37443748
for genericParam in genericParameters {
3745-
thunkBuilder.parameterNames.append("\(genericParam.lowercased())TypeId")
3749+
thunkBuilder.parameterNames.append(thunkBuilder.genericTypeIdParameters[genericParam] ?? genericParam)
37463750
}
37473751
let jsName = function.jsName ?? function.name
37483752
let importRootExpr = function.from == .global ? "globalThis" : "imports"

Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/GenericExports.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
var label: String
99
var count: Int
1010
}
11+
12+
@JS enum Level: Int {
13+
case low = 1
14+
case high = 9
15+
}
1116
}
1217

1318
@JS enum ExportMode: String {
@@ -129,3 +134,11 @@ public func genericExportCombineMix<
129134
>(_ a: T, _ b: T, _ c: U) -> U {
130135
return c
131136
}
137+
138+
@JS
139+
public func genericExportCaseDistinct<
140+
T: _BridgedSwiftGenericBridgeable,
141+
t: _BridgedSwiftGenericBridgeable
142+
>(_ a: T, _ b: t) -> T {
143+
return a
144+
}

Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/GenericImports.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ struct GenericPoint {
4444
_ b: U
4545
) throws(JSException) -> U
4646

47+
@JSFunction func importGenericCaseDistinct<T: _BridgedSwiftGenericBridgeable, t: _BridgedSwiftGenericBridgeable>(
48+
_ a: T,
49+
_ b: t
50+
) throws(JSException) -> T
51+
4752
@JSFunction func importGenericArray<T: _BridgedSwiftGenericBridgeable>(_ values: [T]) throws(JSException) -> [T]
4853

4954
@JSFunction func importGenericOptional<T: _BridgedSwiftGenericBridgeable>(_ value: T?) throws(JSException) -> T?

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GenericExports.json

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,38 @@
8787
{
8888
"associatedValues" : [
8989

90+
],
91+
"name" : "low",
92+
"rawValue" : "1"
93+
},
94+
{
95+
"associatedValues" : [
96+
97+
],
98+
"name" : "high",
99+
"rawValue" : "9"
100+
}
101+
],
102+
"emitStyle" : "const",
103+
"name" : "Level",
104+
"namespace" : [
105+
"ExportNamespace"
106+
],
107+
"rawType" : "Int",
108+
"staticMethods" : [
109+
110+
],
111+
"staticProperties" : [
112+
113+
],
114+
"swiftCallName" : "ExportNamespace.Level",
115+
"tsFullPath" : "ExportNamespace.Level"
116+
},
117+
{
118+
"cases" : [
119+
{
120+
"associatedValues" : [
121+
90122
],
91123
"name" : "on"
92124
},
@@ -917,6 +949,44 @@
917949
"_0" : "U"
918950
}
919951
}
952+
},
953+
{
954+
"abiName" : "bjs_genericExportCaseDistinct",
955+
"effects" : {
956+
"isAsync" : false,
957+
"isStatic" : false,
958+
"isThrows" : false
959+
},
960+
"genericParameters" : [
961+
"T",
962+
"t"
963+
],
964+
"name" : "genericExportCaseDistinct",
965+
"parameters" : [
966+
{
967+
"label" : "_",
968+
"name" : "a",
969+
"type" : {
970+
"generic" : {
971+
"_0" : "T"
972+
}
973+
}
974+
},
975+
{
976+
"label" : "_",
977+
"name" : "b",
978+
"type" : {
979+
"generic" : {
980+
"_0" : "t"
981+
}
982+
}
983+
}
984+
],
985+
"returnType" : {
986+
"generic" : {
987+
"_0" : "T"
988+
}
989+
}
920990
}
921991
],
922992
"protocols" : [

0 commit comments

Comments
 (0)