Skip to content

Commit d0939f0

Browse files
committed
BridgeJS: Fix name collision for same-named nested structs
1 parent 5e96639 commit d0939f0

7 files changed

Lines changed: 237 additions & 19 deletions

File tree

Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -492,15 +492,15 @@ public struct BridgeJSLink {
492492
printer.write("bjs[\"swift_js_struct_lower_\(structDef.abiName)\"] = function(objectId) {")
493493
printer.indent {
494494
printer.write(
495-
"\(JSGlueVariableScope.reservedStructHelpers).\(structDef.name).lower(\(JSGlueVariableScope.reservedSwift).memory.getObject(objectId));"
495+
"\(JSGlueVariableScope.reservedStructHelpers).\(structDef.abiName).lower(\(JSGlueVariableScope.reservedSwift).memory.getObject(objectId));"
496496
)
497497
}
498498
printer.write("}")
499499

500500
printer.write("bjs[\"swift_js_struct_lift_\(structDef.abiName)\"] = function() {")
501501
printer.indent {
502502
printer.write(
503-
"const value = \(JSGlueVariableScope.reservedStructHelpers).\(structDef.name).lift();"
503+
"const value = \(JSGlueVariableScope.reservedStructHelpers).\(structDef.abiName).lift();"
504504
)
505505
printer.write("return \(JSGlueVariableScope.reservedSwift).memory.retain(value);")
506506
}
@@ -1005,7 +1005,7 @@ public struct BridgeJSLink {
10051005
let structScope = JSGlueVariableScope(intrinsicRegistry: intrinsicRegistry)
10061006
let fragment = IntrinsicJSFragment.structHelper(structDefinition: structDef, allStructs: allStructs)
10071007
_ = try fragment.printCode(
1008-
[structDef.name],
1008+
[structDef.abiName],
10091009
IntrinsicJSFragment.PrintCodeContext(
10101010
scope: structScope,
10111011
printer: structPrinter,
@@ -1159,10 +1159,10 @@ public struct BridgeJSLink {
11591159
for skeleton in skeletons.compactMap(\.exported) {
11601160
for structDef in skeleton.structs {
11611161
printer.write(
1162-
"const \(structDef.name)Helpers = __bjs_create\(structDef.name)Helpers();"
1162+
"const \(structDef.abiName)Helpers = __bjs_create\(structDef.abiName)Helpers();"
11631163
)
11641164
printer.write(
1165-
"\(JSGlueVariableScope.reservedStructHelpers).\(structDef.name) = \(structDef.name)Helpers;"
1165+
"\(JSGlueVariableScope.reservedStructHelpers).\(structDef.abiName) = \(structDef.abiName)Helpers;"
11661166
)
11671167
printer.nextLine()
11681168
}
@@ -1497,7 +1497,7 @@ public struct BridgeJSLink {
14971497
func renderExportedStruct(
14981498
_ structDefinition: ExportedStruct
14991499
) throws -> (js: [String], dtsType: [String], dtsExportEntry: [String]) {
1500-
let structName = structDefinition.name
1500+
let structName = structDefinition.abiName
15011501
let hasConstructor = structDefinition.constructor != nil
15021502
let staticMethods = structDefinition.methods.filter { $0.effects.isStatic }
15031503
let staticProperties = structDefinition.properties.filter { $0.isStatic }
@@ -3610,7 +3610,7 @@ extension BridgeType {
36103610
case .associatedValueEnum(let name):
36113611
return "\(name)Tag"
36123612
case .swiftStruct(let name):
3613-
return name.components(separatedBy: ".").last ?? name
3613+
return name.replacingOccurrences(of: ".", with: "_")
36143614
case .namespaceEnum(let name):
36153615
return name
36163616
case .swiftProtocol(let name):

Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1805,7 +1805,7 @@ struct IntrinsicJSFragment: Sendable {
18051805
}
18061806

18071807
static func swiftStructLowerReturn(fullName: String) -> IntrinsicJSFragment {
1808-
swiftStructLower(structBase: fullName.components(separatedBy: ".").last ?? fullName)
1808+
swiftStructLower(structBase: fullName.replacingOccurrences(of: ".", with: "_"))
18091809
}
18101810

18111811
static func swiftStructLowerParameter(structBase: String) -> IntrinsicJSFragment {
@@ -2008,7 +2008,7 @@ struct IntrinsicJSFragment: Sendable {
20082008
}
20092009
)
20102010
case .swiftStruct(let fullName):
2011-
let structBase = fullName.components(separatedBy: ".").last ?? fullName
2011+
let structBase = fullName.replacingOccurrences(of: ".", with: "_")
20122012
return IntrinsicJSFragment(
20132013
parameters: [],
20142014
printCode: { arguments, context in
@@ -2130,7 +2130,7 @@ struct IntrinsicJSFragment: Sendable {
21302130
}
21312131
)
21322132
case .swiftStruct(let fullName):
2133-
let structBase = fullName.components(separatedBy: ".").last ?? fullName
2133+
let structBase = fullName.replacingOccurrences(of: ".", with: "_")
21342134
return IntrinsicJSFragment(
21352135
parameters: ["value"],
21362136
printCode: { arguments, context in
@@ -2426,7 +2426,7 @@ struct IntrinsicJSFragment: Sendable {
24262426
)
24272427
try printer.indent {
24282428
printer.write(
2429-
"\(JSGlueVariableScope.reservedStructHelpers).\(structDef.name).lower(this);"
2429+
"\(JSGlueVariableScope.reservedStructHelpers).\(structDef.abiName).lower(this);"
24302430
)
24312431

24322432
var paramForwardings: [String] = []
@@ -2502,7 +2502,7 @@ struct IntrinsicJSFragment: Sendable {
25022502
let printer = context.printer
25032503
let value = arguments[0]
25042504
printer.write(
2505-
"\(JSGlueVariableScope.reservedStructHelpers).\(nestedName).lower(\(value));"
2505+
"\(JSGlueVariableScope.reservedStructHelpers).\(nestedName.replacingOccurrences(of: ".", with: "_")).lower(\(value));"
25062506
)
25072507
return []
25082508
}
@@ -2540,7 +2540,7 @@ struct IntrinsicJSFragment: Sendable {
25402540
let (scope, printer) = (context.scope, context.printer)
25412541
let structVar = scope.variable("struct")
25422542
printer.write(
2543-
"const \(structVar) = \(JSGlueVariableScope.reservedStructHelpers).\(nestedName).lift();"
2543+
"const \(structVar) = \(JSGlueVariableScope.reservedStructHelpers).\(nestedName.replacingOccurrences(of: ".", with: "_")).lift();"
25442544
)
25452545
return [structVar]
25462546
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,14 @@
88
var score: Double
99
}
1010
}
11+
12+
@JS class Player {
13+
@JS func getTag() -> String {
14+
return "player"
15+
}
16+
17+
@JS struct Stats {
18+
var level: Int
19+
var rating: String
20+
}
21+
}

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

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,32 @@
2626

2727
],
2828
"swiftCallName" : "User"
29+
},
30+
{
31+
"methods" : [
32+
{
33+
"abiName" : "bjs_Player_getTag",
34+
"effects" : {
35+
"isAsync" : false,
36+
"isStatic" : false,
37+
"isThrows" : false
38+
},
39+
"name" : "getTag",
40+
"parameters" : [
41+
42+
],
43+
"returnType" : {
44+
"string" : {
45+
46+
}
47+
}
48+
}
49+
],
50+
"name" : "Player",
51+
"properties" : [
52+
53+
],
54+
"swiftCallName" : "Player"
2955
}
3056
],
3157
"enums" : [
@@ -79,6 +105,47 @@
79105
}
80106
],
81107
"swiftCallName" : "User.Stats"
108+
},
109+
{
110+
"methods" : [
111+
112+
],
113+
"name" : "Stats",
114+
"namespace" : [
115+
"Player"
116+
],
117+
"properties" : [
118+
{
119+
"isReadonly" : true,
120+
"isStatic" : false,
121+
"name" : "level",
122+
"namespace" : [
123+
"Player"
124+
],
125+
"type" : {
126+
"integer" : {
127+
"_0" : {
128+
"isSigned" : true,
129+
"width" : "word"
130+
}
131+
}
132+
}
133+
},
134+
{
135+
"isReadonly" : true,
136+
"isStatic" : false,
137+
"name" : "rating",
138+
"namespace" : [
139+
"Player"
140+
],
141+
"type" : {
142+
"string" : {
143+
144+
}
145+
}
146+
}
147+
],
148+
"swiftCallName" : "Player.Stats"
82149
}
83150
]
84151
},

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NestedType.swift

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,54 @@ fileprivate func _bjs_struct_lift_User_Stats_extern() -> Int32 {
4646
return _bjs_struct_lift_User_Stats_extern()
4747
}
4848

49+
extension Player.Stats: _BridgedSwiftStruct {
50+
@_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> Player.Stats {
51+
let rating = String.bridgeJSStackPop()
52+
let level = Int.bridgeJSStackPop()
53+
return Player.Stats(level: level, rating: rating)
54+
}
55+
56+
@_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() {
57+
self.level.bridgeJSStackPush()
58+
self.rating.bridgeJSStackPush()
59+
}
60+
61+
init(unsafelyCopying jsObject: JSObject) {
62+
_bjs_struct_lower_Player_Stats(jsObject.bridgeJSLowerParameter())
63+
self = Self.bridgeJSStackPop()
64+
}
65+
66+
func toJSObject() -> JSObject {
67+
let __bjs_self = self
68+
__bjs_self.bridgeJSStackPush()
69+
return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_Player_Stats()))
70+
}
71+
}
72+
73+
#if arch(wasm32)
74+
@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_Player_Stats")
75+
fileprivate func _bjs_struct_lower_Player_Stats_extern(_ objectId: Int32) -> Void
76+
#else
77+
fileprivate func _bjs_struct_lower_Player_Stats_extern(_ objectId: Int32) -> Void {
78+
fatalError("Only available on WebAssembly")
79+
}
80+
#endif
81+
@inline(never) fileprivate func _bjs_struct_lower_Player_Stats(_ objectId: Int32) -> Void {
82+
return _bjs_struct_lower_Player_Stats_extern(objectId)
83+
}
84+
85+
#if arch(wasm32)
86+
@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_Player_Stats")
87+
fileprivate func _bjs_struct_lift_Player_Stats_extern() -> Int32
88+
#else
89+
fileprivate func _bjs_struct_lift_Player_Stats_extern() -> Int32 {
90+
fatalError("Only available on WebAssembly")
91+
}
92+
#endif
93+
@inline(never) fileprivate func _bjs_struct_lift_Player_Stats() -> Int32 {
94+
return _bjs_struct_lift_Player_Stats_extern()
95+
}
96+
4997
@_expose(wasm, "bjs_User_getName")
5098
@_cdecl("bjs_User_getName")
5199
public func _bjs_User_getName(_ _self: UnsafeMutableRawPointer) -> Void {
@@ -86,4 +134,46 @@ fileprivate func _bjs_User_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> In
86134
#endif
87135
@inline(never) fileprivate func _bjs_User_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 {
88136
return _bjs_User_wrap_extern(pointer)
137+
}
138+
139+
@_expose(wasm, "bjs_Player_getTag")
140+
@_cdecl("bjs_Player_getTag")
141+
public func _bjs_Player_getTag(_ _self: UnsafeMutableRawPointer) -> Void {
142+
#if arch(wasm32)
143+
let ret = Player.bridgeJSLiftParameter(_self).getTag()
144+
return ret.bridgeJSLowerReturn()
145+
#else
146+
fatalError("Only available on WebAssembly")
147+
#endif
148+
}
149+
150+
@_expose(wasm, "bjs_Player_deinit")
151+
@_cdecl("bjs_Player_deinit")
152+
public func _bjs_Player_deinit(_ pointer: UnsafeMutableRawPointer) -> Void {
153+
#if arch(wasm32)
154+
Unmanaged<Player>.fromOpaque(pointer).release()
155+
#else
156+
fatalError("Only available on WebAssembly")
157+
#endif
158+
}
159+
160+
extension Player: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable {
161+
var jsValue: JSValue {
162+
return .object(JSObject(id: UInt32(bitPattern: _bjs_Player_wrap(Unmanaged.passRetained(self).toOpaque()))))
163+
}
164+
consuming func bridgeJSLowerAsProtocolReturn() -> Int32 {
165+
_bjs_Player_wrap(Unmanaged.passRetained(self).toOpaque())
166+
}
167+
}
168+
169+
#if arch(wasm32)
170+
@_extern(wasm, module: "TestModule", name: "bjs_Player_wrap")
171+
fileprivate func _bjs_Player_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32
172+
#else
173+
fileprivate func _bjs_Player_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 {
174+
fatalError("Only available on WebAssembly")
175+
}
176+
#endif
177+
@inline(never) fileprivate func _bjs_Player_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 {
178+
return _bjs_Player_wrap_extern(pointer)
89179
}

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NestedType.d.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@
44
// To update this file, just rebuild your project or run
55
// `swift package bridge-js`.
66

7-
export interface Stats {
7+
export interface User_Stats {
88
health: number;
99
score: number;
1010
}
11+
export interface Player_Stats {
12+
level: number;
13+
rating: string;
14+
}
1115
/// Represents a Swift heap object like a class instance or an actor instance.
1216
export interface SwiftHeapObject {
1317
/// Release the heap object.
@@ -18,9 +22,14 @@ export interface SwiftHeapObject {
1822
export interface User extends SwiftHeapObject {
1923
getName(): string;
2024
}
25+
export interface Player extends SwiftHeapObject {
26+
getTag(): string;
27+
}
2128
export type Exports = {
2229
User: {
2330
}
31+
Player: {
32+
}
2433
}
2534
export type Imports = {
2635
}

0 commit comments

Comments
 (0)