Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1439,7 +1439,7 @@ struct ProtocolCodegen {
let signature = SwiftSignatureBuilder.buildFunctionSignature(
parameters: method.parameters,
returnType: method.returnType,
effects: nil
effects: method.effects
)

// Build extern declaration using helper function
Expand Down
27 changes: 13 additions & 14 deletions Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2897,9 +2897,8 @@ extension BridgeJSLink {

/// Renders an async import function with resolve/reject closure refs.
///
/// The generated function takes `resolveRef` and `rejectRef` as the first parameters,
/// looks up the resolve/reject closures from memory, and executes the body which
/// chains `.then(resolve, reject)` on the import's returned Promise.
/// The generated function takes `resolveRef` and `rejectRef` as the first parameters
/// and settles them with the result of the import call.
private func renderAsyncFunction(name: String?) -> [String] {
let printer = CodeFragmentPrinter()
let allParams = ["resolveRef", "rejectRef"] + parameterNames
Expand All @@ -2908,7 +2907,15 @@ extension BridgeJSLink {
let s = JSGlueVariableScope.reservedSwift
printer.write("const resolve = \(s).memory.getObject(resolveRef);")
printer.write("const reject = \(s).memory.getObject(rejectRef);")
printer.write(contentsOf: body)
printer.write("try {")
printer.indent {
Comment thread
krodak marked this conversation as resolved.
printer.write(contentsOf: body)
}
printer.write("} catch (error) {")
printer.indent {
printer.write("reject(error);")
}
printer.write("}")
}
printer.write("}")
return printer.lines
Expand All @@ -2930,7 +2937,7 @@ extension BridgeJSLink {

private func call(callExpr: String) throws {
if effects.isAsync {
body.write("\(callExpr).then(resolve, reject);")
body.write("Promise.resolve(\(callExpr)).then(resolve, reject);")
return
}
if let name = returnType.referencedGenericName {
Expand Down Expand Up @@ -2997,14 +3004,6 @@ extension BridgeJSLink {
return try call(calleeExpr: calleeExpr)
}

/// Generates an async method call with resolve/reject closure refs.
func callAsyncMethod(name: String) {
let objectExpr = "\(JSGlueVariableScope.reservedSwift).memory.getObject(self)"
let calleeExpr = Self.propertyAccessExpr(objectExpr: objectExpr, propertyName: name)
let callExpr = "\(calleeExpr)(\(parameterForwardings.joined(separator: ", ")))"
body.write("\(callExpr).then(resolve, reject);")
}

func callStaticMethod(on objectExpr: String, name: String) throws {
let calleeExpr = Self.propertyAccessExpr(objectExpr: objectExpr, propertyName: name)
return try call(calleeExpr: calleeExpr)
Expand Down Expand Up @@ -4235,7 +4234,7 @@ extension BridgeJSLink {
method: ExportedFunction
) throws {
let thunkBuilder = ImportedThunkBuilder(
effects: Effects(isAsync: false, isThrows: false),
effects: method.effects,
returnType: method.returnType,
context: .exportSwift,
intrinsicRegistry: intrinsicRegistry
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,7 @@ public protocol BridgeSkeletonVisitor {
accessLevel: BridgeJSAccessLevel
)
mutating func visitImportedFunction(_ function: ImportedFunctionSkeleton)
mutating func visitProtocolMethod(_ method: ExportedFunction, accessLevel: BridgeJSAccessLevel)
}

public extension BridgeSkeletonVisitor {
Expand All @@ -616,6 +617,7 @@ public extension BridgeSkeletonVisitor {
accessLevel: BridgeJSAccessLevel
) {}
mutating func visitImportedFunction(_ function: ImportedFunctionSkeleton) {}
mutating func visitProtocolMethod(_ method: ExportedFunction, accessLevel: BridgeJSAccessLevel) {}
}

public struct BridgeSkeletonWalker<Visitor: BridgeSkeletonVisitor> {
Expand Down Expand Up @@ -681,6 +683,7 @@ public struct BridgeSkeletonWalker<Visitor: BridgeSkeletonVisitor> {
}
for proto in skeleton.protocols {
for method in proto.methods {
visitor.visitProtocolMethod(method, accessLevel: currentAccessLevel)
walk(method)
}
for property in proto.properties {
Expand Down Expand Up @@ -1870,6 +1873,12 @@ public struct ClosureSignatureCollectorVisitor: BridgeSkeletonVisitor {
)
}

public mutating func visitProtocolMethod(_ method: ExportedFunction, accessLevel: BridgeJSAccessLevel) {
guard method.effects.isAsync else { return }

recordInjectedSignatures(forReturnType: method.returnType, accessLevel: accessLevel)
}

private mutating func recordInjectedSignatures(
forReturnType returnType: BridgeType,
accessLevel: BridgeJSAccessLevel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ import JavaScriptKit
func createEnum() -> ExampleEnum
func handleResult(_ result: Result)
func getResult() -> Result
func validate(_ value: Int) throws(JSException) -> Int
func loadLabel(_ key: String) async throws(JSException) -> String
func reset() async throws(JSException)
func fetchCount() async -> Int
}

@JS class MyViewController {
Expand Down Expand Up @@ -95,6 +99,14 @@ import JavaScriptKit
@JS func sendHelper(_ helper: Helper) {
delegate.onHelperUpdated(helper)
}

@JS func validateValue(_ value: Int) throws(JSException) -> Int {
return try delegate.validate(value)
}

@JS func loadLabel(_ key: String) async throws(JSException) -> String {
return try await delegate.loadLabel(key)
}
}

// Protocol array support
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,62 @@
"returnType" : {
"void" : {

}
}
},
{
"abiName" : "bjs_MyViewController_validateValue",
"effects" : {
"isAsync" : false,
"isStatic" : false,
"isThrows" : true
},
"name" : "validateValue",
"parameters" : [
{
"label" : "_",
"name" : "value",
"type" : {
"integer" : {
"_0" : {
"isSigned" : true,
"width" : "word"
}
}
}
}
],
"returnType" : {
"integer" : {
"_0" : {
"isSigned" : true,
"width" : "word"
}
}
}
},
{
"abiName" : "bjs_MyViewController_loadLabel",
"effects" : {
"isAsync" : true,
"isStatic" : false,
"isThrows" : true
},
"name" : "loadLabel",
"parameters" : [
{
"label" : "_",
"name" : "key",
"type" : {
"string" : {

}
}
}
],
"returnType" : {
"string" : {

}
}
}
Expand Down Expand Up @@ -831,6 +887,99 @@
"_0" : "Result"
}
}
},
{
"abiName" : "bjs_MyViewControllerDelegate_validate",
"effects" : {
"isAsync" : false,
"isStatic" : false,
"isThrows" : true
},
"name" : "validate",
"parameters" : [
{
"label" : "_",
"name" : "value",
"type" : {
"integer" : {
"_0" : {
"isSigned" : true,
"width" : "word"
}
}
}
}
],
"returnType" : {
"integer" : {
"_0" : {
"isSigned" : true,
"width" : "word"
}
}
}
},
{
"abiName" : "bjs_MyViewControllerDelegate_loadLabel",
"effects" : {
"isAsync" : true,
"isStatic" : false,
"isThrows" : true
},
"name" : "loadLabel",
"parameters" : [
{
"label" : "_",
"name" : "key",
"type" : {
"string" : {

}
}
}
],
"returnType" : {
"string" : {

}
}
},
{
"abiName" : "bjs_MyViewControllerDelegate_reset",
"effects" : {
"isAsync" : true,
"isStatic" : false,
"isThrows" : true
},
"name" : "reset",
"parameters" : [

],
"returnType" : {
"void" : {

}
}
},
{
"abiName" : "bjs_MyViewControllerDelegate_fetchCount",
"effects" : {
"isAsync" : true,
"isStatic" : false,
"isThrows" : false
},
"name" : "fetchCount",
"parameters" : [

],
"returnType" : {
"integer" : {
"_0" : {
"isSigned" : true,
"width" : "word"
}
}
}
}
],
"name" : "MyViewControllerDelegate",
Expand Down
Loading
Loading