Skip to content

Commit 3e75647

Browse files
committed
BridgeJS: Diagnose unsupported protocol conformers before lowering
1 parent cadafdc commit 3e75647

11 files changed

Lines changed: 614 additions & 45 deletions

File tree

Plugins/BridgeJS/Sources/BridgeJSCore/ClosureCodegen.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,15 +182,15 @@ public struct ClosureCodegen {
182182
} else {
183183
printer.write("let result = \(closureCallExpr)")
184184
switch signature.returnType {
185-
case .swiftProtocol:
185+
case .swiftProtocol(let protocolName):
186186
printer.write(
187-
"return (result as! _BridgedSwiftProtocolExportable).bridgeJSLowerAsProtocolReturn()"
187+
"return _bridgeJSUnwrapProtocolExportable(result, \"\(protocolName)\").bridgeJSLowerAsProtocolReturn()"
188188
)
189-
case .nullable(.swiftProtocol, _):
189+
case .nullable(.swiftProtocol(let protocolName), _):
190190
printer.write("if let result {")
191191
printer.indent {
192192
printer.write(
193-
"_swift_js_return_optional_object(1, (result as! _BridgedSwiftProtocolExportable).bridgeJSLowerAsProtocolReturn())"
193+
"_swift_js_return_optional_object(1, _bridgeJSUnwrapProtocolExportable(result, \"\(protocolName)\").bridgeJSLowerAsProtocolReturn())"
194194
)
195195
}
196196
printer.write("} else {")

Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,8 @@ public class ExportSwift {
262262

263263
private func protocolCastSuffix(for returnType: BridgeType) -> (prefix: String, suffix: String) {
264264
switch returnType {
265-
case .swiftProtocol:
266-
return ("", " as! _BridgedSwiftProtocolExportable")
265+
case .swiftProtocol(let name):
266+
return ("_bridgeJSUnwrapProtocolExportable(", ", \"\(name)\")")
267267
default:
268268
return ("", "")
269269
}
@@ -424,11 +424,11 @@ public class ExportSwift {
424424
}
425425
case .swiftProtocol:
426426
append("return ret.bridgeJSLowerAsProtocolReturn()")
427-
case .nullable(.swiftProtocol, _):
427+
case .nullable(.swiftProtocol(let protocolName), _):
428428
append(
429429
"""
430430
if let ret {
431-
_swift_js_return_optional_object(1, (ret as! _BridgedSwiftProtocolExportable).bridgeJSLowerAsProtocolReturn())
431+
_swift_js_return_optional_object(1, _bridgeJSUnwrapProtocolExportable(ret, "\(raw: protocolName)").bridgeJSLowerAsProtocolReturn())
432432
} else {
433433
_swift_js_return_optional_object(0, 0)
434434
}
@@ -993,9 +993,9 @@ struct StackCodegen {
993993
return ["\(raw: accessor).bridgeJSStackPush()"]
994994
case .jsObject(_?):
995995
return ["\(raw: accessor).jsObject.bridgeJSStackPush()"]
996-
case .swiftProtocol:
996+
case .swiftProtocol(let protocolName):
997997
return [
998-
"_swift_js_push_i32((\(raw: accessor) as! _BridgedSwiftProtocolExportable).bridgeJSLowerAsProtocolReturn())"
998+
"_swift_js_push_i32(_bridgeJSUnwrapProtocolExportable(\(raw: accessor), \"\(raw: protocolName)\").bridgeJSLowerAsProtocolReturn())"
999999
]
10001000
case .void, .namespaceEnum:
10011001
return []
@@ -1016,8 +1016,8 @@ struct StackCodegen {
10161016
varPrefix: String
10171017
) -> [CodeBlockItemSyntax] {
10181018
switch elementType {
1019-
case .swiftProtocol:
1020-
return lowerProtocolArrayStatements(accessor: accessor, varPrefix: varPrefix)
1019+
case .swiftProtocol(let protocolName):
1020+
return lowerProtocolArrayStatements(protocolName: protocolName, accessor: accessor, varPrefix: varPrefix)
10211021
case .void, .namespaceEnum:
10221022
fatalError("Invalid array element type: \(elementType)")
10231023
default:
@@ -1026,14 +1026,15 @@ struct StackCodegen {
10261026
}
10271027

10281028
private func lowerProtocolArrayStatements(
1029+
protocolName: String,
10291030
accessor: String,
10301031
varPrefix: String
10311032
) -> [CodeBlockItemSyntax] {
10321033
let elemVar = "__bjs_elem_\(varPrefix)"
10331034
return [
10341035
"""
10351036
for \(raw: elemVar) in \(raw: accessor) {
1036-
_swift_js_push_i32((\(raw: elemVar) as! _BridgedSwiftProtocolExportable).bridgeJSLowerAsProtocolReturn())
1037+
_swift_js_push_i32(_bridgeJSUnwrapProtocolExportable(\(raw: elemVar), "\(raw: protocolName)").bridgeJSLowerAsProtocolReturn())
10371038
}
10381039
""",
10391040
"_swift_js_push_i32(Int32(\(raw: accessor).count))",
@@ -1048,8 +1049,12 @@ struct StackCodegen {
10481049
switch valueType {
10491050
case .jsObject(let className?) where className != "JSObject":
10501051
return ["\(raw: accessor).mapValues { $0.jsObject }.bridgeJSStackPush()"]
1051-
case .swiftProtocol:
1052-
return lowerProtocolDictionaryStatements(accessor: accessor, varPrefix: varPrefix)
1052+
case .swiftProtocol(let protocolName):
1053+
return lowerProtocolDictionaryStatements(
1054+
protocolName: protocolName,
1055+
accessor: accessor,
1056+
varPrefix: varPrefix
1057+
)
10531058
case .nullable, .closure:
10541059
return lowerDictionaryStatementsInline(
10551060
valueType: valueType,
@@ -1107,6 +1112,7 @@ struct StackCodegen {
11071112
}
11081113

11091114
private func lowerProtocolDictionaryStatements(
1115+
protocolName: String,
11101116
accessor: String,
11111117
varPrefix: String
11121118
) -> [CodeBlockItemSyntax] {
@@ -1115,7 +1121,7 @@ struct StackCodegen {
11151121
"""
11161122
for \(raw: pairVar) in \(raw: accessor) {
11171123
\(raw: pairVar).key.bridgeJSStackPush()
1118-
_swift_js_push_i32((\(raw: pairVar).value as! _BridgedSwiftProtocolExportable).bridgeJSLowerAsProtocolReturn())
1124+
_swift_js_push_i32(_bridgeJSUnwrapProtocolExportable(\(raw: pairVar).value, "\(raw: protocolName)").bridgeJSLowerAsProtocolReturn())
11191125
}
11201126
""",
11211127
"_swift_js_push_i32(Int32(\(raw: accessor).count))",

Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,12 @@ public struct ImportTS {
188188
}
189189
)
190190
)
191-
} else if case .nullable(.swiftProtocol, _) = param.type, context == .exportSwift {
191+
} else if case .nullable(.swiftProtocol(let protocolName), _) = param.type, context == .exportSwift {
192192
body.write("let \(pattern): (Int32, Int32)")
193193
body.write("if let \(param.name) {")
194194
body.indent {
195195
body.write(
196-
"\(pattern) = (1, (\(param.name) as! _BridgedSwiftProtocolExportable).bridgeJSLowerAsProtocolReturn())"
196+
"\(pattern) = (1, _bridgeJSUnwrapProtocolExportable(\(param.name), \"\(protocolName)\").bridgeJSLowerAsProtocolReturn())"
197197
)
198198
}
199199
body.write("} else {")
@@ -203,9 +203,9 @@ public struct ImportTS {
203203
body.write("}")
204204
} else {
205205
let initializerExpr: ExprSyntax
206-
if case .swiftProtocol = param.type, context == .exportSwift {
206+
if case .swiftProtocol(let protocolName) = param.type, context == .exportSwift {
207207
initializerExpr = ExprSyntax(
208-
"(\(raw: param.name) as! _BridgedSwiftProtocolExportable).bridgeJSLowerAsProtocolReturn()"
208+
"_bridgeJSUnwrapProtocolExportable(\(raw: param.name), \"\(raw: protocolName)\").bridgeJSLowerAsProtocolReturn()"
209209
)
210210
} else {
211211
initializerExpr = ExprSyntax("\(raw: param.name).bridgeJSLowerParameter()")

0 commit comments

Comments
 (0)