Skip to content

Commit bcd6552

Browse files
committed
Merge branch 'kr/protocol-in-closure'
2 parents 604c6ad + 3398ff7 commit bcd6552

File tree

13 files changed

+1841
-32
lines changed

13 files changed

+1841
-32
lines changed

Plugins/BridgeJS/Sources/BridgeJSCore/ClosureCodegen.swift

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ public struct ClosureCodegen {
1212
public init() {}
1313

1414
private func swiftClosureType(for signature: ClosureSignature) -> String {
15-
let closureParams = signature.parameters.map { "\($0.swiftType)" }.joined(separator: ", ")
15+
let closureParams = signature.parameters.map { "\($0.closureSwiftType)" }.joined(separator: ", ")
1616
let swiftEffects = (signature.isAsync ? " async" : "") + (signature.isThrows ? " throws" : "")
17-
let swiftReturnType = signature.returnType.swiftType
17+
let swiftReturnType = signature.returnType.closureSwiftType
1818
return "(\(closureParams))\(swiftEffects) -> \(swiftReturnType)"
1919
}
2020

@@ -158,7 +158,26 @@ public struct ClosureCodegen {
158158
printer.write(closureCallExpr.description)
159159
} else {
160160
printer.write("let result = \(closureCallExpr)")
161-
printer.write("return result.bridgeJSLowerReturn()")
161+
switch signature.returnType {
162+
case .swiftProtocol:
163+
printer.write(
164+
"return (result as! _BridgedSwiftProtocolExportable).bridgeJSLowerAsProtocolReturn()"
165+
)
166+
case .nullable(.swiftProtocol, _):
167+
printer.write("if let result {")
168+
printer.indent {
169+
printer.write(
170+
"_swift_js_return_optional_object(1, (result as! _BridgedSwiftProtocolExportable).bridgeJSLowerAsProtocolReturn())"
171+
)
172+
}
173+
printer.write("} else {")
174+
printer.indent {
175+
printer.write("_swift_js_return_optional_object(0, 0)")
176+
}
177+
printer.write("}")
178+
default:
179+
printer.write("return result.bridgeJSLowerReturn()")
180+
}
162181
}
163182
}
164183

Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,6 +1454,16 @@ extension BridgeType {
14541454
}
14551455
}
14561456

1457+
var closureSwiftType: String {
1458+
switch self {
1459+
case .swiftProtocol(let name): return "any \(name)"
1460+
case .nullable(let wrappedType, let kind):
1461+
let wrappedClosureType = wrappedType.closureSwiftType
1462+
return kind == .null ? "Optional<\(wrappedClosureType)>" : "JSUndefinedOr<\(wrappedClosureType)>"
1463+
default: return swiftType
1464+
}
1465+
}
1466+
14571467
var isClosureType: Bool {
14581468
if case .closure = self { return true }
14591469
return false

Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,28 @@ public struct ImportTS {
163163
}
164164
)
165165
)
166+
} else if case .nullable(.swiftProtocol, _) = param.type, context == .exportSwift {
167+
body.write("let \(pattern): (Int32, Int32)")
168+
body.write("if let \(param.name) {")
169+
body.indent {
170+
body.write(
171+
"\(pattern) = (1, (\(param.name) as! _BridgedSwiftProtocolExportable).bridgeJSLowerAsProtocolReturn())"
172+
)
173+
}
174+
body.write("} else {")
175+
body.indent {
176+
body.write("\(pattern) = (0, 0)")
177+
}
178+
body.write("}")
166179
} else {
167-
let initializerExpr = ExprSyntax("\(raw: param.name).bridgeJSLowerParameter()")
180+
let initializerExpr: ExprSyntax
181+
if case .swiftProtocol = param.type, context == .exportSwift {
182+
initializerExpr = ExprSyntax(
183+
"(\(raw: param.name) as! _BridgedSwiftProtocolExportable).bridgeJSLowerAsProtocolReturn()"
184+
)
185+
} else {
186+
initializerExpr = ExprSyntax("\(raw: param.name).bridgeJSLowerParameter()")
187+
}
168188

169189
if loweringInfo.loweredParameters.isEmpty {
170190
stackLoweringStmts.insert("let _ = \(initializerExpr)", at: 0)
@@ -817,7 +837,12 @@ extension BridgeType {
817837
case .swiftHeapObject:
818838
return LoweringParameterInfo(loweredParameters: [("pointer", .pointer)])
819839
case .swiftProtocol:
820-
throw BridgeJSCoreError("swiftProtocol is not supported in imported signatures")
840+
switch context {
841+
case .importTS:
842+
throw BridgeJSCoreError("swiftProtocol is not supported in imported signatures")
843+
case .exportSwift:
844+
return LoweringParameterInfo(loweredParameters: [("objectId", .i32)])
845+
}
821846
case .caseEnum:
822847
switch context {
823848
case .importTS:
@@ -891,7 +916,12 @@ extension BridgeType {
891916
case .swiftHeapObject:
892917
return LiftingReturnInfo(valueToLift: .pointer)
893918
case .swiftProtocol:
894-
throw BridgeJSCoreError("swiftProtocol is not supported in imported signatures")
919+
switch context {
920+
case .importTS:
921+
throw BridgeJSCoreError("swiftProtocol is not supported in imported signatures")
922+
case .exportSwift:
923+
return LiftingReturnInfo(valueToLift: .i32)
924+
}
895925
case .caseEnum:
896926
switch context {
897927
case .importTS:
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import JavaScriptKit
2+
3+
@JS protocol Renderable {
4+
func render() -> String
5+
}
6+
7+
@JS class Widget {
8+
@JS var name: String
9+
10+
@JS init(name: String) {
11+
self.name = name
12+
}
13+
}
14+
15+
@JS func processRenderable(_ item: Renderable, transform: (Renderable) -> String) -> String
16+
@JS func makeRenderableFactory(defaultName: String) -> () -> Renderable
17+
@JS func roundtripRenderable(_ callback: (Renderable) -> Renderable) -> (Renderable) -> Renderable
18+
@JS func processOptionalRenderable(_ callback: (Renderable?) -> String) -> String

0 commit comments

Comments
 (0)