diff --git a/Benchmarks/Sources/Generated/JavaScript/BridgeJS.json b/Benchmarks/Sources/Generated/JavaScript/BridgeJS.json index 95c4ac18e..b2c33ac01 100644 --- a/Benchmarks/Sources/Generated/JavaScript/BridgeJS.json +++ b/Benchmarks/Sources/Generated/JavaScript/BridgeJS.json @@ -2839,6 +2839,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "benchmarkHelperNoop", "parameters" : [ @@ -2850,6 +2855,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "benchmarkHelperNoopWithNumber", "parameters" : [ { @@ -2868,6 +2878,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "benchmarkRunner", "parameters" : [ { diff --git a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/JavaScript/BridgeJS.json b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/JavaScript/BridgeJS.json index 60eb694ff..1a21916ee 100644 --- a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/JavaScript/BridgeJS.json +++ b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/JavaScript/BridgeJS.json @@ -242,6 +242,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "createTS2Swift", "parameters" : [ @@ -260,6 +265,11 @@ ], "methods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "convert", "parameters" : [ { diff --git a/Plugins/BridgeJS/Sources/BridgeJSBuildPlugin/BridgeJSBuildPlugin.swift b/Plugins/BridgeJS/Sources/BridgeJSBuildPlugin/BridgeJSBuildPlugin.swift index 3cb6dc860..0236039d3 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSBuildPlugin/BridgeJSBuildPlugin.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSBuildPlugin/BridgeJSBuildPlugin.swift @@ -20,9 +20,11 @@ struct BridgeJSBuildPlugin: BuildToolPlugin { private func createGenerateCommand(context: PluginContext, target: SwiftSourceModuleTarget) throws -> Command { let outputSwiftPath = context.pluginWorkDirectoryURL.appending(path: "BridgeJS.swift") + let outputMacrosSwiftPath = context.pluginWorkDirectoryURL.appending(path: "BridgeJS.Macros.swift") let inputSwiftFiles = target.sourceFiles.filter { - !$0.url.path.hasPrefix(context.pluginWorkDirectoryURL.path + "/") + $0.url.pathExtension == "swift" + && !$0.url.path.hasPrefix(context.pluginWorkDirectoryURL.path + "/") } .map(\.url) @@ -42,6 +44,7 @@ struct BridgeJSBuildPlugin: BuildToolPlugin { inputFiles.append(contentsOf: pluginGeneratedSwiftFiles) let inputTSFile = target.directoryURL.appending(path: "bridge-js.d.ts") + let inputGlobalTSFile = target.directoryURL.appending(path: "bridge-js.global.d.ts") let tsconfigPath = context.package.directoryURL.appending(path: "tsconfig.json") var arguments: [String] = [ @@ -55,8 +58,16 @@ struct BridgeJSBuildPlugin: BuildToolPlugin { "--always-write", "true", ] - if FileManager.default.fileExists(atPath: inputTSFile.path) { - inputFiles.append(contentsOf: [inputTSFile, tsconfigPath]) + let hasDts = FileManager.default.fileExists(atPath: inputTSFile.path) + let hasGlobalDts = FileManager.default.fileExists(atPath: inputGlobalTSFile.path) + if hasDts || hasGlobalDts { + if hasDts { + inputFiles.append(inputTSFile) + } + if hasGlobalDts { + inputFiles.append(inputGlobalTSFile) + } + inputFiles.append(tsconfigPath) arguments.append(contentsOf: [ "--project", tsconfigPath.path, @@ -71,7 +82,7 @@ struct BridgeJSBuildPlugin: BuildToolPlugin { executable: try context.tool(named: "BridgeJSTool").url, arguments: arguments, inputFiles: inputFiles, - outputFiles: [outputSwiftPath] + outputFiles: [outputSwiftPath, outputMacrosSwiftPath] ) } } diff --git a/Plugins/BridgeJS/Sources/BridgeJSCommandPlugin/BridgeJSCommandPlugin.swift b/Plugins/BridgeJS/Sources/BridgeJSCommandPlugin/BridgeJSCommandPlugin.swift index 23fbae567..634720b89 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCommandPlugin/BridgeJSCommandPlugin.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCommandPlugin/BridgeJSCommandPlugin.swift @@ -103,6 +103,7 @@ extension BridgeJSCommandPlugin.Context { let generatedDirectory = target.directoryURL.appending(path: "Generated") let bridgeDtsPath = target.directoryURL.appending(path: "bridge-js.d.ts") + let bridgeGlobalDtsPath = target.directoryURL.appending(path: "bridge-js.global.d.ts") let tsconfigPath = context.package.directoryURL.appending(path: "tsconfig.json") // Unified generate command @@ -118,12 +119,16 @@ extension BridgeJSCommandPlugin.Context { options.verbose ? "true" : "false", ] - if FileManager.default.fileExists(atPath: bridgeDtsPath.path) { + let hasDts = FileManager.default.fileExists(atPath: bridgeDtsPath.path) + let hasGlobalDts = FileManager.default.fileExists(atPath: bridgeGlobalDtsPath.path) + if hasDts || hasGlobalDts { generateArguments.append(contentsOf: [ "--project", tsconfigPath.path, - bridgeDtsPath.path, ]) + if hasDts { + generateArguments.append(bridgeDtsPath.path) + } } generateArguments.append( diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ClosureCodegen.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ClosureCodegen.swift index 142050f56..fcf71611b 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ClosureCodegen.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ClosureCodegen.swift @@ -12,7 +12,10 @@ public struct ClosureCodegen { public init() {} private func swiftClosureType(for signature: ClosureSignature) -> String { - let closureParams = signature.parameters.map { "\($0.closureSwiftType)" }.joined(separator: ", ") + let sendingPrefix = signature.sendingParameters ? "sending " : "" + let closureParams = signature.parameters.map { "\(sendingPrefix)\($0.closureSwiftType)" }.joined( + separator: ", " + ) let swiftEffects = (signature.isAsync ? " async" : "") + (signature.isThrows ? " throws" : "") let swiftReturnType = signature.returnType.closureSwiftType return "(\(closureParams))\(swiftEffects) -> \(swiftReturnType)" @@ -188,7 +191,78 @@ public struct ClosureCodegen { let collector = ClosureSignatureCollectorVisitor() var walker = BridgeTypeWalker(visitor: collector) walker.walk(skeleton) - let closureSignatures = walker.visitor.signatures + var closureSignatures = walker.visitor.signatures + + // When async imports exist, inject closure signatures for the typed resolve + // and reject callbacks used by _bjs_awaitPromise. + // - Reject always uses (sending JSValue) -> Void + // - Resolve uses a typed closure matching the return type (or () -> Void for void) + // All async callback closures use `sending` parameters so values can be + // transferred through the checked continuation without Sendable constraints. + if let imported = skeleton.imported { + for file in imported.children { + for function in file.functions where function.effects.isAsync { + // Reject callback + closureSignatures.insert( + ClosureSignature( + parameters: [.jsValue], + returnType: .void, + moduleName: skeleton.moduleName, + sendingParameters: true + ) + ) + // Resolve callback (typed per return type) + if function.returnType == .void { + closureSignatures.insert( + ClosureSignature( + parameters: [], + returnType: .void, + moduleName: skeleton.moduleName + ) + ) + } else { + closureSignatures.insert( + ClosureSignature( + parameters: [function.returnType], + returnType: .void, + moduleName: skeleton.moduleName, + sendingParameters: true + ) + ) + } + } + for type in file.types { + for method in type.methods where method.effects.isAsync { + closureSignatures.insert( + ClosureSignature( + parameters: [.jsValue], + returnType: .void, + moduleName: skeleton.moduleName, + sendingParameters: true + ) + ) + if method.returnType == .void { + closureSignatures.insert( + ClosureSignature( + parameters: [], + returnType: .void, + moduleName: skeleton.moduleName + ) + ) + } else { + closureSignatures.insert( + ClosureSignature( + parameters: [method.returnType], + returnType: .void, + moduleName: skeleton.moduleName, + sendingParameters: true + ) + ) + } + } + } + } + } guard !closureSignatures.isEmpty else { return nil } diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift index 1d1fe3aa9..d709dd190 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift @@ -212,7 +212,16 @@ public struct ImportTS { } } - func call() throws { + /// Prepends `resolveRef: Int32, rejectRef: Int32` parameters to the ABI parameter list. + /// + /// Used for async imports where the JS side receives closure-backed + /// resolve/reject callbacks as object references. + func prependClosureCallbackParams() { + abiParameterSignatures.insert(contentsOf: [("resolveRef", .i32), ("rejectRef", .i32)], at: 0) + abiParameterForwardings.insert(contentsOf: ["resolveRef", "rejectRef"], at: 0) + } + + func call(skipExceptionCheck: Bool = false) throws { for stmt in stackLoweringStmts { body.write(stmt.description) } @@ -243,8 +252,9 @@ public struct ImportTS { } } - // Add exception check for ImportTS context - if context == .importTS { + // Add exception check for ImportTS context (skipped for async, where + // errors are funneled through the JS-side reject path) + if !skipExceptionCheck && context == .importTS { body.write("if let error = _swift_js_take_exception() { throw error }") } } @@ -278,6 +288,41 @@ public struct ImportTS { } } + func liftAsyncReturnValue(originalReturnType: BridgeType) { + // For async imports, the extern function takes leading `resolveRef: Int32, rejectRef: Int32` + // and returns void. The JS side calls the resolve/reject closures when the Promise settles. + // The resolve closure is typed to match the return type, so the ABI conversion is handled + // by the existing closure codegen infrastructure — no manual JSValue-to-type switch needed. + abiReturnType = nil + + // Wrap the existing body (parameter lowering + extern call) in _bjs_awaitPromise + let innerBody = body + body = CodeFragmentPrinter() + + let rejectFactory = "makeRejectClosure: { JSTypedClosure<(sending JSValue) -> Void>($0) }" + if originalReturnType == .void { + let resolveFactory = "makeResolveClosure: { JSTypedClosure<() -> Void>($0) }" + body.write( + "try await _bjs_awaitPromise(\(resolveFactory), \(rejectFactory)) { resolveRef, rejectRef in" + ) + } else { + let resolveSwiftType = originalReturnType.closureSwiftType + let resolveFactory = + "makeResolveClosure: { JSTypedClosure<(sending \(resolveSwiftType)) -> Void>($0) }" + body.write( + "let resolved = try await _bjs_awaitPromise(\(resolveFactory), \(rejectFactory)) { resolveRef, rejectRef in" + ) + } + body.indent { + body.write(lines: innerBody.lines) + } + body.write("}") + + if originalReturnType != .void { + body.write("return resolved") + } + } + func assignThis(returnType: BridgeType) { guard case .jsObject = returnType else { preconditionFailure("assignThis can only be called with a jsObject return type") @@ -299,9 +344,13 @@ public struct ImportTS { return "\(raw: printer.lines.joined(separator: "\n"))" } - func renderThunkDecl(name: String, parameters: [Parameter], returnType: BridgeType) -> DeclSyntax { + func renderThunkDecl( + name: String, + parameters: [Parameter], + returnType: BridgeType, + effects: Effects = Effects(isAsync: false, isThrows: true) + ) -> DeclSyntax { let printer = CodeFragmentPrinter() - let effects = Effects(isAsync: false, isThrows: true) let signature = SwiftSignatureBuilder.buildFunctionSignature( parameters: parameters, returnType: returnType, @@ -359,22 +408,33 @@ public struct ImportTS { _ function: ImportedFunctionSkeleton, topLevelDecls: inout [DeclSyntax] ) throws -> [DeclSyntax] { + // For async functions, the extern returns void (the JS side resolves/rejects + // via continuation callbacks). For sync functions, use the actual return type. + let abiReturnType: BridgeType = function.effects.isAsync ? .void : function.returnType let builder = try CallJSEmission( moduleName: moduleName, abiName: function.abiName(context: nil), - returnType: function.returnType + returnType: abiReturnType ) + if function.effects.isAsync { + builder.prependClosureCallbackParams() + } for param in function.parameters { try builder.lowerParameter(param: param) } - try builder.call() - try builder.liftReturnValue() + try builder.call(skipExceptionCheck: function.effects.isAsync) + if function.effects.isAsync { + builder.liftAsyncReturnValue(originalReturnType: function.returnType) + } else { + try builder.liftReturnValue() + } topLevelDecls.append(builder.renderImportDecl()) return [ builder.renderThunkDecl( name: Self.thunkName(function: function), parameters: function.parameters, - returnType: function.returnType + returnType: function.returnType, + effects: function.effects ) .with(\.leadingTrivia, Self.renderDocumentation(documentation: function.documentation)) ] @@ -385,41 +445,56 @@ public struct ImportTS { var decls: [DeclSyntax] = [] func renderMethod(method: ImportedFunctionSkeleton) throws -> [DeclSyntax] { + let abiReturnType: BridgeType = method.effects.isAsync ? .void : method.returnType let builder = try CallJSEmission( moduleName: moduleName, abiName: method.abiName(context: type), - returnType: method.returnType + returnType: abiReturnType ) + if method.effects.isAsync { + builder.prependClosureCallbackParams() + } try builder.lowerParameter(param: selfParameter) for param in method.parameters { try builder.lowerParameter(param: param) } - try builder.call() - try builder.liftReturnValue() + try builder.call(skipExceptionCheck: method.effects.isAsync) + if method.effects.isAsync { + builder.liftAsyncReturnValue(originalReturnType: method.returnType) + } else { + try builder.liftReturnValue() + } topLevelDecls.append(builder.renderImportDecl()) return [ builder.renderThunkDecl( name: Self.thunkName(type: type, method: method), parameters: [selfParameter] + method.parameters, - returnType: method.returnType + returnType: method.returnType, + effects: method.effects ) ] } func renderStaticMethod(method: ImportedFunctionSkeleton) throws -> [DeclSyntax] { let abiName = method.abiName(context: type, operation: "static") - let builder = try CallJSEmission(moduleName: moduleName, abiName: abiName, returnType: method.returnType) + let abiReturnType: BridgeType = method.effects.isAsync ? .jsObject(nil) : method.returnType + let builder = try CallJSEmission(moduleName: moduleName, abiName: abiName, returnType: abiReturnType) for param in method.parameters { try builder.lowerParameter(param: param) } try builder.call() - try builder.liftReturnValue() + if method.effects.isAsync { + builder.liftAsyncReturnValue(originalReturnType: method.returnType) + } else { + try builder.liftReturnValue() + } topLevelDecls.append(builder.renderImportDecl()) return [ builder.renderThunkDecl( name: Self.thunkName(type: type, method: method), parameters: method.parameters, - returnType: method.returnType + returnType: method.returnType, + effects: method.effects ) ] } diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift index 482b1fff5..7b7c6ca30 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift @@ -2137,7 +2137,7 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor { let valueType: BridgeType } - /// Validates effects (throws required, async not supported) + /// Validates effects (throws required, async only supported for @JSFunction) private func validateEffects( _ effects: FunctionEffectSpecifiersSyntax?, node: some SyntaxProtocol, @@ -2153,7 +2153,7 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor { ) return nil } - if effects.isAsync { + if effects.isAsync && attributeName != "JSFunction" { errors.append( DiagnosticError( node: node, @@ -2490,7 +2490,12 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor { _ jsFunction: AttributeSyntax, _ node: FunctionDeclSyntax, ) -> ImportedFunctionSkeleton? { - guard validateEffects(node.signature.effectSpecifiers, node: node, attributeName: "JSFunction") != nil + guard + let effects = validateEffects( + node.signature.effectSpecifiers, + node: node, + attributeName: "JSFunction" + ) else { return nil } @@ -2516,6 +2521,7 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor { from: from, parameters: parameters, returnType: returnType, + effects: effects, documentation: nil ) } diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift index f69a4b266..573693e4f 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift @@ -639,7 +639,75 @@ public struct BridgeJSLink { let collector = ClosureSignatureCollectorVisitor() var walker = BridgeTypeWalker(visitor: collector) walker.walk(unified) - let closureSignatures = walker.visitor.signatures + var closureSignatures = walker.visitor.signatures + + // Inject closure signatures for async import resolve/reject callbacks. + // All use sendingParameters: true so values can be transferred + // through checked continuations without Sendable constraints. + if let imported = unified.imported { + for file in imported.children { + for function in file.functions where function.effects.isAsync { + // Reject callback + closureSignatures.insert( + ClosureSignature( + parameters: [.jsValue], + returnType: .void, + moduleName: moduleName, + sendingParameters: true + ) + ) + // Resolve callback (typed per return type) + if function.returnType == .void { + closureSignatures.insert( + ClosureSignature( + parameters: [], + returnType: .void, + moduleName: moduleName + ) + ) + } else { + closureSignatures.insert( + ClosureSignature( + parameters: [function.returnType], + returnType: .void, + moduleName: moduleName, + sendingParameters: true + ) + ) + } + } + for type in file.types { + for method in type.methods where method.effects.isAsync { + closureSignatures.insert( + ClosureSignature( + parameters: [.jsValue], + returnType: .void, + moduleName: moduleName, + sendingParameters: true + ) + ) + if method.returnType == .void { + closureSignatures.insert( + ClosureSignature( + parameters: [], + returnType: .void, + moduleName: moduleName + ) + ) + } else { + closureSignatures.insert( + ClosureSignature( + parameters: [method.returnType], + returnType: .void, + moduleName: moduleName, + sendingParameters: true + ) + ) + } + } + } + } + } guard !closureSignatures.isEmpty else { continue } @@ -1233,7 +1301,7 @@ public struct BridgeJSLink { for method in type.methods { let methodName = method.jsName ?? method.name let methodSignature = - "\(renderTSPropertyName(methodName))\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: Effects(isAsync: false, isThrows: false)));" + "\(renderTSPropertyName(methodName))\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" printer.write(methodSignature) } @@ -2232,6 +2300,34 @@ extension BridgeJSLink { return printer.lines } + /// Generates the call expression for an async import. + /// + /// Chains `.then(resolve, reject)` directly on the returned Promise. + func callAsync(name: String, fromObjectExpr: String) { + let calleeExpr = Self.propertyAccessExpr(objectExpr: fromObjectExpr, propertyName: name) + let callExpr = "\(calleeExpr)(\(parameterForwardings.joined(separator: ", ")))" + body.write("\(callExpr).then(resolve, reject);") + } + + /// 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. + func renderAsyncFunction(name: String?) -> [String] { + let printer = CodeFragmentPrinter() + let allParams = ["resolveRef", "rejectRef"] + parameterNames + printer.write("function\(name.map { " \($0)" } ?? "")(\(allParams.joined(separator: ", "))) {") + printer.indent { + 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("}") + return printer.lines + } + func call(name: String, fromObjectExpr: String, returnType: BridgeType) throws -> String? { let calleeExpr = Self.propertyAccessExpr(objectExpr: fromObjectExpr, propertyName: name) return try self.call(calleeExpr: calleeExpr, returnType: returnType) @@ -2285,6 +2381,14 @@ extension BridgeJSLink { ) } + /// 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, returnType: BridgeType) throws -> String? { let calleeExpr = Self.propertyAccessExpr(objectExpr: objectExpr, propertyName: name) return try call( @@ -3124,21 +3228,31 @@ extension BridgeJSLink { } let jsName = function.jsName ?? function.name let importRootExpr = function.from == .global ? "globalThis" : "imports" - let returnExpr = try thunkBuilder.call( - name: jsName, - fromObjectExpr: importRootExpr, - returnType: function.returnType - ) - let funcLines = thunkBuilder.renderFunction( - name: function.abiName(context: nil), - returnExpr: returnExpr, - returnType: function.returnType - ) - let effects = Effects(isAsync: false, isThrows: false) + + let funcLines: [String] + if function.effects.isAsync { + // For async functions, use the continuation-pointer pattern. + // The generated function takes continuationPtr as first param, + // calls the import, attaches .then/.catch on the returned Promise, + // and calls resolve/reject continuations. + thunkBuilder.callAsync(name: jsName, fromObjectExpr: importRootExpr) + funcLines = thunkBuilder.renderAsyncFunction(name: function.abiName(context: nil)) + } else { + let returnExpr = try thunkBuilder.call( + name: jsName, + fromObjectExpr: importRootExpr, + returnType: function.returnType + ) + funcLines = thunkBuilder.renderFunction( + name: function.abiName(context: nil), + returnExpr: returnExpr, + returnType: function.returnType + ) + } if function.from == nil { importObjectBuilder.appendDts( [ - "\(renderTSPropertyName(jsName))\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: effects));" + "\(renderTSPropertyName(jsName))\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" ] ) } @@ -3337,12 +3451,22 @@ extension BridgeJSLink { for param in method.parameters { try thunkBuilder.liftParameter(param: param) } - let returnExpr = try thunkBuilder.callMethod(name: method.jsName ?? method.name, returnType: method.returnType) - let funcLines = thunkBuilder.renderFunction( - name: method.abiName(context: context), - returnExpr: returnExpr, - returnType: method.returnType - ) + + let funcLines: [String] + if method.effects.isAsync { + thunkBuilder.callAsyncMethod(name: method.jsName ?? method.name) + funcLines = thunkBuilder.renderAsyncFunction(name: method.abiName(context: context)) + } else { + let returnExpr = try thunkBuilder.callMethod( + name: method.jsName ?? method.name, + returnType: method.returnType + ) + funcLines = thunkBuilder.renderFunction( + name: method.abiName(context: context), + returnExpr: returnExpr, + returnType: method.returnType + ) + } return (funcLines, []) } diff --git a/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift b/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift index 1f03e09ba..f61f7e2cf 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift @@ -101,24 +101,31 @@ public struct ClosureSignature: Codable, Equatable, Hashable, Sendable { public let isAsync: Bool public let isThrows: Bool public let moduleName: String + /// When true, closure parameters are annotated with `sending` in Swift. + /// Used for async Promise resolve/reject callbacks where values are + /// transferred through a continuation. + public let sendingParameters: Bool public init( parameters: [BridgeType], returnType: BridgeType, moduleName: String, isAsync: Bool = false, - isThrows: Bool = false + isThrows: Bool = false, + sendingParameters: Bool = false ) { self.parameters = parameters self.returnType = returnType self.moduleName = moduleName self.isAsync = isAsync self.isThrows = isThrows + self.sendingParameters = sendingParameters let paramPart = parameters.isEmpty ? "y" : parameters.map { $0.mangleTypeName }.joined() - let signaturePart = "\(paramPart)_\(returnType.mangleTypeName)" + let sendingPart = sendingParameters ? "s" : "" + let signaturePart = "\(sendingPart)\(paramPart)_\(returnType.mangleTypeName)" self.mangleName = "\(moduleName.count)\(moduleName)\(signaturePart)" } } @@ -923,6 +930,7 @@ public struct ImportedFunctionSkeleton: Codable { public let from: JSImportFrom? public let parameters: [Parameter] public let returnType: BridgeType + public let effects: Effects public let documentation: String? public init( @@ -931,6 +939,7 @@ public struct ImportedFunctionSkeleton: Codable { from: JSImportFrom? = nil, parameters: [Parameter], returnType: BridgeType, + effects: Effects = Effects(isAsync: false, isThrows: true), documentation: String? = nil ) { self.name = name @@ -938,6 +947,7 @@ public struct ImportedFunctionSkeleton: Codable { self.from = from self.parameters = parameters self.returnType = returnType + self.effects = effects self.documentation = documentation } diff --git a/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/src/processor.js b/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/src/processor.js index 9617a5261..91a42a9ef 100644 --- a/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/src/processor.js +++ b/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/src/processor.js @@ -313,8 +313,8 @@ export class TypeProcessor { const parameters = signature.getParameters(); const parameterNameMap = this.buildParameterNameMap(parameters); const params = this.renderParameters(parameters, decl); - const returnType = this.visitType(signature.getReturnType(), decl); - const effects = this.renderEffects({ isAsync: false }); + const { returnType, isAsync } = this.unwrapPromiseReturnType(signature.getReturnType(), decl); + const effects = this.renderEffects({ isAsync }); const annotation = this.renderMacroAnnotation("JSFunction", args); this.emitDocComment(decl, { indent: "", parameterNameMap }); @@ -581,8 +581,8 @@ export class TypeProcessor { const parameters = signature.getParameters(); const parameterNameMap = this.buildParameterNameMap(parameters); const params = this.renderParameters(parameters, node); - const returnType = this.visitType(signature.getReturnType(), node); - const effects = this.renderEffects({ isAsync: false }); + const { returnType, isAsync } = this.unwrapPromiseReturnType(signature.getReturnType(), node); + const effects = this.renderEffects({ isAsync }); const swiftFuncName = this.renderIdentifier(swiftName); this.emitDocComment(node, { parameterNameMap }); @@ -1210,8 +1210,8 @@ export class TypeProcessor { const parameters = signature.getParameters(); const parameterNameMap = this.buildParameterNameMap(parameters); const params = this.renderParameters(parameters, node); - const returnType = this.visitType(signature.getReturnType(), node); - const effects = this.renderEffects({ isAsync: false }); + const { returnType, isAsync } = this.unwrapPromiseReturnType(signature.getReturnType(), node); + const effects = this.renderEffects({ isAsync }); const swiftMethodName = this.renderIdentifier(swiftName); const isStatic = node.modifiers?.some( (modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword @@ -1281,6 +1281,27 @@ export class TypeProcessor { return parts.join(" "); } + /** + * Check if a type is Promise and extract the return type and async flag. + * @param {ts.Type} type - The return type to check + * @param {ts.Node} node - The node for type visiting context + * @returns {{ returnType: string, isAsync: boolean }} + * @private + */ + unwrapPromiseReturnType(type, node) { + if (isTypeReference(type)) { + const symbol = type.target?.getSymbol(); + if (symbol?.name === "Promise") { + const typeArgs = this.checker.getTypeArguments(/** @type {ts.TypeReference} */ (type)); + const innerType = typeArgs && typeArgs.length > 0 + ? this.visitType(typeArgs[0], node) + : "Void"; + return { returnType: innerType, isAsync: true }; + } + } + return { returnType: this.visitType(type, node), isAsync: false }; + } + /** * @param {ts.Node} node * @returns {boolean} diff --git a/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/test/__snapshots__/ts2swift.test.js.snap b/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/test/__snapshots__/ts2swift.test.js.snap index 4122f4148..643ac8441 100644 --- a/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/test/__snapshots__/ts2swift.test.js.snap +++ b/Plugins/BridgeJS/Sources/TS2Swift/JavaScript/test/__snapshots__/ts2swift.test.js.snap @@ -32,19 +32,19 @@ exports[`ts2swift > snapshots Swift output for Async.d.ts > Async 1`] = ` @_spi(BridgeJS) import JavaScriptKit -@JSFunction func asyncReturnVoid() throws(JSException) -> JSPromise +@JSFunction func asyncReturnVoid() async throws(JSException) -> Void -@JSFunction func asyncRoundTripInt(_ v: Double) throws(JSException) -> JSPromise +@JSFunction func asyncRoundTripInt(_ v: Double) async throws(JSException) -> Double -@JSFunction func asyncRoundTripString(_ v: String) throws(JSException) -> JSPromise +@JSFunction func asyncRoundTripString(_ v: String) async throws(JSException) -> String -@JSFunction func asyncRoundTripBool(_ v: Bool) throws(JSException) -> JSPromise +@JSFunction func asyncRoundTripBool(_ v: Bool) async throws(JSException) -> Bool -@JSFunction func asyncRoundTripFloat(_ v: Double) throws(JSException) -> JSPromise +@JSFunction func asyncRoundTripFloat(_ v: Double) async throws(JSException) -> Double -@JSFunction func asyncRoundTripDouble(_ v: Double) throws(JSException) -> JSPromise +@JSFunction func asyncRoundTripDouble(_ v: Double) async throws(JSException) -> Double -@JSFunction func asyncRoundTripJSObject(_ v: JSValue) throws(JSException) -> JSPromise +@JSFunction func asyncRoundTripJSObject(_ v: JSValue) async throws(JSException) -> JSValue " `; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/AsyncImport.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/AsyncImport.swift new file mode 100644 index 000000000..02563cbdf --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/AsyncImport.swift @@ -0,0 +1,6 @@ +@JSFunction func asyncReturnVoid() async throws(JSException) +@JSFunction func asyncRoundTripInt(_ v: Int) async throws(JSException) -> Int +@JSFunction func asyncRoundTripString(_ v: String) async throws(JSException) -> String +@JSFunction func asyncRoundTripBool(_ v: Bool) async throws(JSException) -> Bool +@JSFunction func asyncRoundTripDouble(_ v: Double) async throws(JSException) -> Double +@JSFunction func asyncRoundTripJSObject(_ v: JSObject) async throws(JSException) -> JSObject diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ArrayTypes.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ArrayTypes.json index 3664fa339..d071d8c52 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ArrayTypes.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ArrayTypes.json @@ -1331,6 +1331,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "checkArray", "parameters" : [ { @@ -1349,6 +1354,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "checkArrayWithLength", "parameters" : [ { @@ -1375,6 +1385,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "importProcessNumbers", "parameters" : [ { @@ -1397,6 +1412,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "importGetNumbers", "parameters" : [ @@ -1412,6 +1432,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "importTransformNumbers", "parameters" : [ { @@ -1438,6 +1463,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "importProcessStrings", "parameters" : [ { @@ -1464,6 +1494,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "importProcessBooleans", "parameters" : [ { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AsyncImport.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AsyncImport.json new file mode 100644 index 000000000..263578d20 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AsyncImport.json @@ -0,0 +1,151 @@ +{ + "imported" : { + "children" : [ + { + "functions" : [ + { + "effects" : { + "isAsync" : true, + "isStatic" : false, + "isThrows" : true + }, + "name" : "asyncReturnVoid", + "parameters" : [ + + ], + "returnType" : { + "void" : { + + } + } + }, + { + "effects" : { + "isAsync" : true, + "isStatic" : false, + "isThrows" : true + }, + "name" : "asyncRoundTripInt", + "parameters" : [ + { + "name" : "v", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "returnType" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + }, + { + "effects" : { + "isAsync" : true, + "isStatic" : false, + "isThrows" : true + }, + "name" : "asyncRoundTripString", + "parameters" : [ + { + "name" : "v", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "effects" : { + "isAsync" : true, + "isStatic" : false, + "isThrows" : true + }, + "name" : "asyncRoundTripBool", + "parameters" : [ + { + "name" : "v", + "type" : { + "bool" : { + + } + } + } + ], + "returnType" : { + "bool" : { + + } + } + }, + { + "effects" : { + "isAsync" : true, + "isStatic" : false, + "isThrows" : true + }, + "name" : "asyncRoundTripDouble", + "parameters" : [ + { + "name" : "v", + "type" : { + "double" : { + + } + } + } + ], + "returnType" : { + "double" : { + + } + } + }, + { + "effects" : { + "isAsync" : true, + "isStatic" : false, + "isThrows" : true + }, + "name" : "asyncRoundTripJSObject", + "parameters" : [ + { + "name" : "v", + "type" : { + "jsObject" : { + + } + } + } + ], + "returnType" : { + "jsObject" : { + + } + } + } + ], + "types" : [ + + ] + } + ] + }, + "moduleName" : "TestModule" +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AsyncImport.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AsyncImport.swift new file mode 100644 index 000000000..7a60bc6b7 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AsyncImport.swift @@ -0,0 +1,569 @@ +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "invoke_js_callback_TestModule_10TestModules7JSValueV_y") +fileprivate func invoke_js_callback_TestModule_10TestModules7JSValueV_y_extern(_ callback: Int32, _ param0Kind: Int32, _ param0Payload1: Int32, _ param0Payload2: Float64) -> Void +#else +fileprivate func invoke_js_callback_TestModule_10TestModules7JSValueV_y_extern(_ callback: Int32, _ param0Kind: Int32, _ param0Payload1: Int32, _ param0Payload2: Float64) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func invoke_js_callback_TestModule_10TestModules7JSValueV_y(_ callback: Int32, _ param0Kind: Int32, _ param0Payload1: Int32, _ param0Payload2: Float64) -> Void { + return invoke_js_callback_TestModule_10TestModules7JSValueV_y_extern(callback, param0Kind, param0Payload1, param0Payload2) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "make_swift_closure_TestModule_10TestModules7JSValueV_y") +fileprivate func make_swift_closure_TestModule_10TestModules7JSValueV_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 +#else +fileprivate func make_swift_closure_TestModule_10TestModules7JSValueV_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func make_swift_closure_TestModule_10TestModules7JSValueV_y(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + return make_swift_closure_TestModule_10TestModules7JSValueV_y_extern(boxPtr, file, line) +} + +private enum _BJS_Closure_10TestModules7JSValueV_y { + static func bridgeJSLift(_ callbackId: Int32) -> (sending JSValue) -> Void { + let callback = JSObject.bridgeJSLiftParameter(callbackId) + return { [callback] param0 in + #if arch(wasm32) + let callbackValue = callback.bridgeJSLowerParameter() + let (param0Kind, param0Payload1, param0Payload2) = param0.bridgeJSLowerParameter() + invoke_js_callback_TestModule_10TestModules7JSValueV_y(callbackValue, param0Kind, param0Payload1, param0Payload2) + #else + fatalError("Only available on WebAssembly") + #endif + } + } +} + +extension JSTypedClosure where Signature == (sending JSValue) -> Void { + init(fileID: StaticString = #fileID, line: UInt32 = #line, _ body: @escaping (sending JSValue) -> Void) { + self.init( + makeClosure: make_swift_closure_TestModule_10TestModules7JSValueV_y, + body: body, + fileID: fileID, + line: line + ) + } +} + +@_expose(wasm, "invoke_swift_closure_TestModule_10TestModules7JSValueV_y") +@_cdecl("invoke_swift_closure_TestModule_10TestModules7JSValueV_y") +public func _invoke_swift_closure_TestModule_10TestModules7JSValueV_y(_ boxPtr: UnsafeMutableRawPointer, _ param0Kind: Int32, _ param0Payload1: Int32, _ param0Payload2: Float64) -> Void { + #if arch(wasm32) + let closure = Unmanaged<_BridgeJSTypedClosureBox<(sending JSValue) -> Void>>.fromOpaque(boxPtr).takeUnretainedValue().closure + closure(JSValue.bridgeJSLiftParameter(param0Kind, param0Payload1, param0Payload2)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "invoke_js_callback_TestModule_10TestModules8JSObjectC_y") +fileprivate func invoke_js_callback_TestModule_10TestModules8JSObjectC_y_extern(_ callback: Int32, _ param0: Int32) -> Void +#else +fileprivate func invoke_js_callback_TestModule_10TestModules8JSObjectC_y_extern(_ callback: Int32, _ param0: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func invoke_js_callback_TestModule_10TestModules8JSObjectC_y(_ callback: Int32, _ param0: Int32) -> Void { + return invoke_js_callback_TestModule_10TestModules8JSObjectC_y_extern(callback, param0) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "make_swift_closure_TestModule_10TestModules8JSObjectC_y") +fileprivate func make_swift_closure_TestModule_10TestModules8JSObjectC_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 +#else +fileprivate func make_swift_closure_TestModule_10TestModules8JSObjectC_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func make_swift_closure_TestModule_10TestModules8JSObjectC_y(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + return make_swift_closure_TestModule_10TestModules8JSObjectC_y_extern(boxPtr, file, line) +} + +private enum _BJS_Closure_10TestModules8JSObjectC_y { + static func bridgeJSLift(_ callbackId: Int32) -> (sending JSObject) -> Void { + let callback = JSObject.bridgeJSLiftParameter(callbackId) + return { [callback] param0 in + #if arch(wasm32) + let callbackValue = callback.bridgeJSLowerParameter() + let param0Value = param0.bridgeJSLowerParameter() + invoke_js_callback_TestModule_10TestModules8JSObjectC_y(callbackValue, param0Value) + #else + fatalError("Only available on WebAssembly") + #endif + } + } +} + +extension JSTypedClosure where Signature == (sending JSObject) -> Void { + init(fileID: StaticString = #fileID, line: UInt32 = #line, _ body: @escaping (sending JSObject) -> Void) { + self.init( + makeClosure: make_swift_closure_TestModule_10TestModules8JSObjectC_y, + body: body, + fileID: fileID, + line: line + ) + } +} + +@_expose(wasm, "invoke_swift_closure_TestModule_10TestModules8JSObjectC_y") +@_cdecl("invoke_swift_closure_TestModule_10TestModules8JSObjectC_y") +public func _invoke_swift_closure_TestModule_10TestModules8JSObjectC_y(_ boxPtr: UnsafeMutableRawPointer, _ param0: Int32) -> Void { + #if arch(wasm32) + let closure = Unmanaged<_BridgeJSTypedClosureBox<(sending JSObject) -> Void>>.fromOpaque(boxPtr).takeUnretainedValue().closure + closure(JSObject.bridgeJSLiftParameter(param0)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "invoke_js_callback_TestModule_10TestModulesSS_y") +fileprivate func invoke_js_callback_TestModule_10TestModulesSS_y_extern(_ callback: Int32, _ param0Bytes: Int32, _ param0Length: Int32) -> Void +#else +fileprivate func invoke_js_callback_TestModule_10TestModulesSS_y_extern(_ callback: Int32, _ param0Bytes: Int32, _ param0Length: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func invoke_js_callback_TestModule_10TestModulesSS_y(_ callback: Int32, _ param0Bytes: Int32, _ param0Length: Int32) -> Void { + return invoke_js_callback_TestModule_10TestModulesSS_y_extern(callback, param0Bytes, param0Length) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "make_swift_closure_TestModule_10TestModulesSS_y") +fileprivate func make_swift_closure_TestModule_10TestModulesSS_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 +#else +fileprivate func make_swift_closure_TestModule_10TestModulesSS_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func make_swift_closure_TestModule_10TestModulesSS_y(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + return make_swift_closure_TestModule_10TestModulesSS_y_extern(boxPtr, file, line) +} + +private enum _BJS_Closure_10TestModulesSS_y { + static func bridgeJSLift(_ callbackId: Int32) -> (sending String) -> Void { + let callback = JSObject.bridgeJSLiftParameter(callbackId) + return { [callback] param0 in + #if arch(wasm32) + let callbackValue = callback.bridgeJSLowerParameter() + param0.bridgeJSWithLoweredParameter { (param0Bytes, param0Length) in + invoke_js_callback_TestModule_10TestModulesSS_y(callbackValue, param0Bytes, param0Length) + } + #else + fatalError("Only available on WebAssembly") + #endif + } + } +} + +extension JSTypedClosure where Signature == (sending String) -> Void { + init(fileID: StaticString = #fileID, line: UInt32 = #line, _ body: @escaping (sending String) -> Void) { + self.init( + makeClosure: make_swift_closure_TestModule_10TestModulesSS_y, + body: body, + fileID: fileID, + line: line + ) + } +} + +@_expose(wasm, "invoke_swift_closure_TestModule_10TestModulesSS_y") +@_cdecl("invoke_swift_closure_TestModule_10TestModulesSS_y") +public func _invoke_swift_closure_TestModule_10TestModulesSS_y(_ boxPtr: UnsafeMutableRawPointer, _ param0Bytes: Int32, _ param0Length: Int32) -> Void { + #if arch(wasm32) + let closure = Unmanaged<_BridgeJSTypedClosureBox<(sending String) -> Void>>.fromOpaque(boxPtr).takeUnretainedValue().closure + closure(String.bridgeJSLiftParameter(param0Bytes, param0Length)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "invoke_js_callback_TestModule_10TestModulesSb_y") +fileprivate func invoke_js_callback_TestModule_10TestModulesSb_y_extern(_ callback: Int32, _ param0: Int32) -> Void +#else +fileprivate func invoke_js_callback_TestModule_10TestModulesSb_y_extern(_ callback: Int32, _ param0: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func invoke_js_callback_TestModule_10TestModulesSb_y(_ callback: Int32, _ param0: Int32) -> Void { + return invoke_js_callback_TestModule_10TestModulesSb_y_extern(callback, param0) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "make_swift_closure_TestModule_10TestModulesSb_y") +fileprivate func make_swift_closure_TestModule_10TestModulesSb_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 +#else +fileprivate func make_swift_closure_TestModule_10TestModulesSb_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func make_swift_closure_TestModule_10TestModulesSb_y(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + return make_swift_closure_TestModule_10TestModulesSb_y_extern(boxPtr, file, line) +} + +private enum _BJS_Closure_10TestModulesSb_y { + static func bridgeJSLift(_ callbackId: Int32) -> (sending Bool) -> Void { + let callback = JSObject.bridgeJSLiftParameter(callbackId) + return { [callback] param0 in + #if arch(wasm32) + let callbackValue = callback.bridgeJSLowerParameter() + let param0Value = param0.bridgeJSLowerParameter() + invoke_js_callback_TestModule_10TestModulesSb_y(callbackValue, param0Value) + #else + fatalError("Only available on WebAssembly") + #endif + } + } +} + +extension JSTypedClosure where Signature == (sending Bool) -> Void { + init(fileID: StaticString = #fileID, line: UInt32 = #line, _ body: @escaping (sending Bool) -> Void) { + self.init( + makeClosure: make_swift_closure_TestModule_10TestModulesSb_y, + body: body, + fileID: fileID, + line: line + ) + } +} + +@_expose(wasm, "invoke_swift_closure_TestModule_10TestModulesSb_y") +@_cdecl("invoke_swift_closure_TestModule_10TestModulesSb_y") +public func _invoke_swift_closure_TestModule_10TestModulesSb_y(_ boxPtr: UnsafeMutableRawPointer, _ param0: Int32) -> Void { + #if arch(wasm32) + let closure = Unmanaged<_BridgeJSTypedClosureBox<(sending Bool) -> Void>>.fromOpaque(boxPtr).takeUnretainedValue().closure + closure(Bool.bridgeJSLiftParameter(param0)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "invoke_js_callback_TestModule_10TestModulesSd_y") +fileprivate func invoke_js_callback_TestModule_10TestModulesSd_y_extern(_ callback: Int32, _ param0: Float64) -> Void +#else +fileprivate func invoke_js_callback_TestModule_10TestModulesSd_y_extern(_ callback: Int32, _ param0: Float64) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func invoke_js_callback_TestModule_10TestModulesSd_y(_ callback: Int32, _ param0: Float64) -> Void { + return invoke_js_callback_TestModule_10TestModulesSd_y_extern(callback, param0) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "make_swift_closure_TestModule_10TestModulesSd_y") +fileprivate func make_swift_closure_TestModule_10TestModulesSd_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 +#else +fileprivate func make_swift_closure_TestModule_10TestModulesSd_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func make_swift_closure_TestModule_10TestModulesSd_y(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + return make_swift_closure_TestModule_10TestModulesSd_y_extern(boxPtr, file, line) +} + +private enum _BJS_Closure_10TestModulesSd_y { + static func bridgeJSLift(_ callbackId: Int32) -> (sending Double) -> Void { + let callback = JSObject.bridgeJSLiftParameter(callbackId) + return { [callback] param0 in + #if arch(wasm32) + let callbackValue = callback.bridgeJSLowerParameter() + let param0Value = param0.bridgeJSLowerParameter() + invoke_js_callback_TestModule_10TestModulesSd_y(callbackValue, param0Value) + #else + fatalError("Only available on WebAssembly") + #endif + } + } +} + +extension JSTypedClosure where Signature == (sending Double) -> Void { + init(fileID: StaticString = #fileID, line: UInt32 = #line, _ body: @escaping (sending Double) -> Void) { + self.init( + makeClosure: make_swift_closure_TestModule_10TestModulesSd_y, + body: body, + fileID: fileID, + line: line + ) + } +} + +@_expose(wasm, "invoke_swift_closure_TestModule_10TestModulesSd_y") +@_cdecl("invoke_swift_closure_TestModule_10TestModulesSd_y") +public func _invoke_swift_closure_TestModule_10TestModulesSd_y(_ boxPtr: UnsafeMutableRawPointer, _ param0: Float64) -> Void { + #if arch(wasm32) + let closure = Unmanaged<_BridgeJSTypedClosureBox<(sending Double) -> Void>>.fromOpaque(boxPtr).takeUnretainedValue().closure + closure(Double.bridgeJSLiftParameter(param0)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "invoke_js_callback_TestModule_10TestModulesSi_y") +fileprivate func invoke_js_callback_TestModule_10TestModulesSi_y_extern(_ callback: Int32, _ param0: Int32) -> Void +#else +fileprivate func invoke_js_callback_TestModule_10TestModulesSi_y_extern(_ callback: Int32, _ param0: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func invoke_js_callback_TestModule_10TestModulesSi_y(_ callback: Int32, _ param0: Int32) -> Void { + return invoke_js_callback_TestModule_10TestModulesSi_y_extern(callback, param0) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "make_swift_closure_TestModule_10TestModulesSi_y") +fileprivate func make_swift_closure_TestModule_10TestModulesSi_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 +#else +fileprivate func make_swift_closure_TestModule_10TestModulesSi_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func make_swift_closure_TestModule_10TestModulesSi_y(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + return make_swift_closure_TestModule_10TestModulesSi_y_extern(boxPtr, file, line) +} + +private enum _BJS_Closure_10TestModulesSi_y { + static func bridgeJSLift(_ callbackId: Int32) -> (sending Int) -> Void { + let callback = JSObject.bridgeJSLiftParameter(callbackId) + return { [callback] param0 in + #if arch(wasm32) + let callbackValue = callback.bridgeJSLowerParameter() + let param0Value = param0.bridgeJSLowerParameter() + invoke_js_callback_TestModule_10TestModulesSi_y(callbackValue, param0Value) + #else + fatalError("Only available on WebAssembly") + #endif + } + } +} + +extension JSTypedClosure where Signature == (sending Int) -> Void { + init(fileID: StaticString = #fileID, line: UInt32 = #line, _ body: @escaping (sending Int) -> Void) { + self.init( + makeClosure: make_swift_closure_TestModule_10TestModulesSi_y, + body: body, + fileID: fileID, + line: line + ) + } +} + +@_expose(wasm, "invoke_swift_closure_TestModule_10TestModulesSi_y") +@_cdecl("invoke_swift_closure_TestModule_10TestModulesSi_y") +public func _invoke_swift_closure_TestModule_10TestModulesSi_y(_ boxPtr: UnsafeMutableRawPointer, _ param0: Int32) -> Void { + #if arch(wasm32) + let closure = Unmanaged<_BridgeJSTypedClosureBox<(sending Int) -> Void>>.fromOpaque(boxPtr).takeUnretainedValue().closure + closure(Int.bridgeJSLiftParameter(param0)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "invoke_js_callback_TestModule_10TestModuley_y") +fileprivate func invoke_js_callback_TestModule_10TestModuley_y_extern(_ callback: Int32) -> Void +#else +fileprivate func invoke_js_callback_TestModule_10TestModuley_y_extern(_ callback: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func invoke_js_callback_TestModule_10TestModuley_y(_ callback: Int32) -> Void { + return invoke_js_callback_TestModule_10TestModuley_y_extern(callback) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "make_swift_closure_TestModule_10TestModuley_y") +fileprivate func make_swift_closure_TestModule_10TestModuley_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 +#else +fileprivate func make_swift_closure_TestModule_10TestModuley_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func make_swift_closure_TestModule_10TestModuley_y(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + return make_swift_closure_TestModule_10TestModuley_y_extern(boxPtr, file, line) +} + +private enum _BJS_Closure_10TestModuley_y { + static func bridgeJSLift(_ callbackId: Int32) -> () -> Void { + let callback = JSObject.bridgeJSLiftParameter(callbackId) + return { [callback] in + #if arch(wasm32) + let callbackValue = callback.bridgeJSLowerParameter() + invoke_js_callback_TestModule_10TestModuley_y(callbackValue) + #else + fatalError("Only available on WebAssembly") + #endif + } + } +} + +extension JSTypedClosure where Signature == () -> Void { + init(fileID: StaticString = #fileID, line: UInt32 = #line, _ body: @escaping () -> Void) { + self.init( + makeClosure: make_swift_closure_TestModule_10TestModuley_y, + body: body, + fileID: fileID, + line: line + ) + } +} + +@_expose(wasm, "invoke_swift_closure_TestModule_10TestModuley_y") +@_cdecl("invoke_swift_closure_TestModule_10TestModuley_y") +public func _invoke_swift_closure_TestModule_10TestModuley_y(_ boxPtr: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let closure = Unmanaged<_BridgeJSTypedClosureBox<() -> Void>>.fromOpaque(boxPtr).takeUnretainedValue().closure + closure() + #else + fatalError("Only available on WebAssembly") + #endif +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_asyncReturnVoid") +fileprivate func bjs_asyncReturnVoid_extern(_ resolveRef: Int32, _ rejectRef: Int32) -> Void +#else +fileprivate func bjs_asyncReturnVoid_extern(_ resolveRef: Int32, _ rejectRef: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_asyncReturnVoid(_ resolveRef: Int32, _ rejectRef: Int32) -> Void { + return bjs_asyncReturnVoid_extern(resolveRef, rejectRef) +} + +func _$asyncReturnVoid() async throws(JSException) -> Void { + try await _bjs_awaitPromise(makeResolveClosure: { + JSTypedClosure<() -> Void>($0) + }, makeRejectClosure: { + JSTypedClosure<(sending JSValue) -> Void>($0) + }) { resolveRef, rejectRef in + bjs_asyncReturnVoid(resolveRef, rejectRef) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_asyncRoundTripInt") +fileprivate func bjs_asyncRoundTripInt_extern(_ resolveRef: Int32, _ rejectRef: Int32, _ v: Int32) -> Void +#else +fileprivate func bjs_asyncRoundTripInt_extern(_ resolveRef: Int32, _ rejectRef: Int32, _ v: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_asyncRoundTripInt(_ resolveRef: Int32, _ rejectRef: Int32, _ v: Int32) -> Void { + return bjs_asyncRoundTripInt_extern(resolveRef, rejectRef, v) +} + +func _$asyncRoundTripInt(_ v: Int) async throws(JSException) -> Int { + let resolved = try await _bjs_awaitPromise(makeResolveClosure: { + JSTypedClosure<(sending Int) -> Void>($0) + }, makeRejectClosure: { + JSTypedClosure<(sending JSValue) -> Void>($0) + }) { resolveRef, rejectRef in + let vValue = v.bridgeJSLowerParameter() + bjs_asyncRoundTripInt(resolveRef, rejectRef, vValue) + } + return resolved +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_asyncRoundTripString") +fileprivate func bjs_asyncRoundTripString_extern(_ resolveRef: Int32, _ rejectRef: Int32, _ vBytes: Int32, _ vLength: Int32) -> Void +#else +fileprivate func bjs_asyncRoundTripString_extern(_ resolveRef: Int32, _ rejectRef: Int32, _ vBytes: Int32, _ vLength: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_asyncRoundTripString(_ resolveRef: Int32, _ rejectRef: Int32, _ vBytes: Int32, _ vLength: Int32) -> Void { + return bjs_asyncRoundTripString_extern(resolveRef, rejectRef, vBytes, vLength) +} + +func _$asyncRoundTripString(_ v: String) async throws(JSException) -> String { + let resolved = try await _bjs_awaitPromise(makeResolveClosure: { + JSTypedClosure<(sending String) -> Void>($0) + }, makeRejectClosure: { + JSTypedClosure<(sending JSValue) -> Void>($0) + }) { resolveRef, rejectRef in + v.bridgeJSWithLoweredParameter { (vBytes, vLength) in + bjs_asyncRoundTripString(resolveRef, rejectRef, vBytes, vLength) + } + } + return resolved +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_asyncRoundTripBool") +fileprivate func bjs_asyncRoundTripBool_extern(_ resolveRef: Int32, _ rejectRef: Int32, _ v: Int32) -> Void +#else +fileprivate func bjs_asyncRoundTripBool_extern(_ resolveRef: Int32, _ rejectRef: Int32, _ v: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_asyncRoundTripBool(_ resolveRef: Int32, _ rejectRef: Int32, _ v: Int32) -> Void { + return bjs_asyncRoundTripBool_extern(resolveRef, rejectRef, v) +} + +func _$asyncRoundTripBool(_ v: Bool) async throws(JSException) -> Bool { + let resolved = try await _bjs_awaitPromise(makeResolveClosure: { + JSTypedClosure<(sending Bool) -> Void>($0) + }, makeRejectClosure: { + JSTypedClosure<(sending JSValue) -> Void>($0) + }) { resolveRef, rejectRef in + let vValue = v.bridgeJSLowerParameter() + bjs_asyncRoundTripBool(resolveRef, rejectRef, vValue) + } + return resolved +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_asyncRoundTripDouble") +fileprivate func bjs_asyncRoundTripDouble_extern(_ resolveRef: Int32, _ rejectRef: Int32, _ v: Float64) -> Void +#else +fileprivate func bjs_asyncRoundTripDouble_extern(_ resolveRef: Int32, _ rejectRef: Int32, _ v: Float64) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_asyncRoundTripDouble(_ resolveRef: Int32, _ rejectRef: Int32, _ v: Float64) -> Void { + return bjs_asyncRoundTripDouble_extern(resolveRef, rejectRef, v) +} + +func _$asyncRoundTripDouble(_ v: Double) async throws(JSException) -> Double { + let resolved = try await _bjs_awaitPromise(makeResolveClosure: { + JSTypedClosure<(sending Double) -> Void>($0) + }, makeRejectClosure: { + JSTypedClosure<(sending JSValue) -> Void>($0) + }) { resolveRef, rejectRef in + let vValue = v.bridgeJSLowerParameter() + bjs_asyncRoundTripDouble(resolveRef, rejectRef, vValue) + } + return resolved +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_asyncRoundTripJSObject") +fileprivate func bjs_asyncRoundTripJSObject_extern(_ resolveRef: Int32, _ rejectRef: Int32, _ v: Int32) -> Void +#else +fileprivate func bjs_asyncRoundTripJSObject_extern(_ resolveRef: Int32, _ rejectRef: Int32, _ v: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_asyncRoundTripJSObject(_ resolveRef: Int32, _ rejectRef: Int32, _ v: Int32) -> Void { + return bjs_asyncRoundTripJSObject_extern(resolveRef, rejectRef, v) +} + +func _$asyncRoundTripJSObject(_ v: JSObject) async throws(JSException) -> JSObject { + let resolved = try await _bjs_awaitPromise(makeResolveClosure: { + JSTypedClosure<(sending JSObject) -> Void>($0) + }, makeRejectClosure: { + JSTypedClosure<(sending JSValue) -> Void>($0) + }) { resolveRef, rejectRef in + let vValue = v.bridgeJSLowerParameter() + bjs_asyncRoundTripJSObject(resolveRef, rejectRef, vValue) + } + return resolved +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/CrossFileSkipsEmptySkeletons.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/CrossFileSkipsEmptySkeletons.json index 4d7495a7c..a0c2c80c6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/CrossFileSkipsEmptySkeletons.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/CrossFileSkipsEmptySkeletons.json @@ -4,6 +4,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "fetchNumber", "parameters" : [ diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DictionaryTypes.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DictionaryTypes.json index c740dc46f..ea707098d 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DictionaryTypes.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DictionaryTypes.json @@ -235,6 +235,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "importMirrorDictionary", "parameters" : [ { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumRawType.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumRawType.json index ba36405ba..fc4a7ae52 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumRawType.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumRawType.json @@ -1526,6 +1526,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "takesFeatureFlag", "parameters" : [ { @@ -1545,6 +1550,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "returnsFeatureFlag", "parameters" : [ diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/FixedWidthIntegers.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/FixedWidthIntegers.json index bef9cbc88..15a20f72e 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/FixedWidthIntegers.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/FixedWidthIntegers.json @@ -269,6 +269,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "roundTripInt8", "parameters" : [ { @@ -293,6 +298,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "roundTripUInt8", "parameters" : [ { @@ -317,6 +327,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "roundTripInt16", "parameters" : [ { @@ -341,6 +356,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "roundTripUInt16", "parameters" : [ { @@ -365,6 +385,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "roundTripInt32", "parameters" : [ { @@ -389,6 +414,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "roundTripUInt32", "parameters" : [ { @@ -413,6 +443,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "roundTripInt64", "parameters" : [ { @@ -437,6 +472,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "roundTripUInt64", "parameters" : [ { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GlobalGetter.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GlobalGetter.json index 55ac7dd70..f750fc6a5 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GlobalGetter.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GlobalGetter.json @@ -22,6 +22,11 @@ ], "methods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "log", "parameters" : [ { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GlobalThisImports.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GlobalThisImports.json index 5e002e34f..809a9ad99 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GlobalThisImports.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GlobalThisImports.json @@ -4,6 +4,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "from" : "global", "jsName" : "parseInt", "name" : "parseInt", @@ -42,6 +47,11 @@ ], "methods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "log", "parameters" : [ { @@ -87,6 +97,11 @@ ], "methods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "close", "parameters" : [ diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportArray.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportArray.json index 7f79a8146..3f9cb8e32 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportArray.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportArray.json @@ -4,6 +4,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "roundtrip", "parameters" : [ { @@ -36,6 +41,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "logStrings", "parameters" : [ { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/InvalidPropertyNames.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/InvalidPropertyNames.json index 935f7a7f2..1ad99f397 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/InvalidPropertyNames.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/InvalidPropertyNames.json @@ -4,6 +4,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "createWeirdObject", "parameters" : [ @@ -15,6 +20,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "createWeirdClass", "parameters" : [ @@ -100,6 +110,11 @@ ], "methods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "as", "parameters" : [ @@ -111,6 +126,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "try", "parameters" : [ @@ -218,6 +238,11 @@ "jsName" : "$Weird", "methods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "jsName" : "method-with-dashes", "name" : "method_with_dashes", "parameters" : [ diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSClass.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSClass.json index 689e86150..ef8eba9ba 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSClass.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSClass.json @@ -4,6 +4,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "returnAnimatable", "parameters" : [ @@ -49,6 +54,11 @@ ], "methods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "greet", "parameters" : [ @@ -60,6 +70,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "changeName", "parameters" : [ { @@ -100,6 +115,11 @@ ], "methods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "animate", "parameters" : [ { @@ -126,6 +146,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "getAnimations", "parameters" : [ { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSClassStaticFunctions.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSClassStaticFunctions.json index a8b64558f..18f7cfaac 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSClassStaticFunctions.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSClassStaticFunctions.json @@ -12,6 +12,11 @@ ], "methods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "value", "parameters" : [ @@ -29,6 +34,11 @@ ], "staticMethods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "create", "parameters" : [ { @@ -47,6 +57,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "value", "parameters" : [ @@ -58,6 +73,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "makeDefault", "parameters" : [ @@ -69,6 +89,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "jsName" : "with-dashes", "name" : "dashed", "parameters" : [ @@ -107,6 +132,11 @@ ], "staticMethods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "create", "parameters" : [ { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSValue.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSValue.json index 5bd83be27..fb8601ae7 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSValue.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSValue.json @@ -321,6 +321,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsEchoJSValue", "parameters" : [ { @@ -339,6 +344,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsEchoJSValueArray", "parameters" : [ { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Optionals.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Optionals.json index 67d97821c..3e6d6c60c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Optionals.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Optionals.json @@ -1152,6 +1152,11 @@ ], "methods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "roundTripStringOrNull", "parameters" : [ { @@ -1180,6 +1185,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "roundTripStringOrUndefined", "parameters" : [ { @@ -1208,6 +1218,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "roundTripDoubleOrNull", "parameters" : [ { @@ -1236,6 +1251,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "roundTripDoubleOrUndefined", "parameters" : [ { @@ -1264,6 +1284,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "roundTripBoolOrNull", "parameters" : [ { @@ -1292,6 +1317,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "roundTripBoolOrUndefined", "parameters" : [ { @@ -1320,6 +1350,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "roundTripIntOrNull", "parameters" : [ { @@ -1354,6 +1389,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "roundTripIntOrUndefined", "parameters" : [ { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/PrimitiveParameters.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/PrimitiveParameters.json index f75bf7610..cf76f3878 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/PrimitiveParameters.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/PrimitiveParameters.json @@ -88,6 +88,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "check", "parameters" : [ { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/PrimitiveReturn.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/PrimitiveReturn.json index cded9a973..b0398c161 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/PrimitiveReturn.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/PrimitiveReturn.json @@ -112,6 +112,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "checkNumber", "parameters" : [ @@ -123,6 +128,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "checkBoolean", "parameters" : [ diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ProtocolInClosure.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ProtocolInClosure.json index 4ba7ba9a5..36d6941d3 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ProtocolInClosure.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ProtocolInClosure.json @@ -84,7 +84,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -130,7 +131,8 @@ "swiftProtocol" : { "_0" : "Renderable" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -166,7 +168,8 @@ "swiftProtocol" : { "_0" : "Renderable" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -191,7 +194,8 @@ "swiftProtocol" : { "_0" : "Renderable" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -232,7 +236,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StringParameter.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StringParameter.json index b0aa8c35b..75462af81 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StringParameter.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StringParameter.json @@ -71,6 +71,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "checkString", "parameters" : [ { @@ -89,6 +94,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "checkStringWithLength", "parameters" : [ { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StringReturn.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StringReturn.json index 3f9271592..1088a5cab 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StringReturn.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StringReturn.json @@ -38,6 +38,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "checkString", "parameters" : [ diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClass.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClass.json index 6ab78c82c..ceda64904 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClass.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClass.json @@ -213,6 +213,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripGreeter", "parameters" : [ { @@ -231,6 +236,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripOptionalGreeter", "parameters" : [ { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosure.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosure.json index f610d4bde..41662e48b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosure.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosure.json @@ -61,7 +61,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -313,7 +314,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -338,7 +340,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -380,7 +383,8 @@ "width" : "word" } } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -411,7 +415,8 @@ "width" : "word" } } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -447,7 +452,8 @@ "bool" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -472,7 +478,8 @@ "bool" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -508,7 +515,8 @@ "float" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -533,7 +541,8 @@ "float" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -569,7 +578,8 @@ "double" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -594,7 +604,8 @@ "double" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -640,7 +651,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -675,7 +687,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -727,7 +740,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -768,7 +782,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -814,7 +829,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -849,7 +865,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -895,7 +912,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -930,7 +948,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -976,7 +995,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1011,7 +1031,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1047,7 +1068,8 @@ "swiftHeapObject" : { "_0" : "Person" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1072,7 +1094,8 @@ "swiftHeapObject" : { "_0" : "Person" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1118,7 +1141,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1153,7 +1177,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1189,7 +1214,8 @@ "caseEnum" : { "_0" : "Direction" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1214,7 +1240,8 @@ "caseEnum" : { "_0" : "Direction" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1252,7 +1279,8 @@ "_0" : "Theme", "_1" : "String" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1279,7 +1307,8 @@ "_0" : "Theme", "_1" : "String" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1317,7 +1346,8 @@ "_0" : "HttpStatus", "_1" : "Int" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1344,7 +1374,8 @@ "_0" : "HttpStatus", "_1" : "Int" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1380,7 +1411,8 @@ "associatedValueEnum" : { "_0" : "APIResult" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1405,7 +1437,8 @@ "associatedValueEnum" : { "_0" : "APIResult" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1451,7 +1484,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1486,7 +1520,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1534,7 +1569,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1571,7 +1607,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1619,7 +1656,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1656,7 +1694,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1702,7 +1741,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1737,7 +1777,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1783,7 +1824,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -1818,7 +1860,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosureImports.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosureImports.json index 4359b50ec..a78b1bf5d 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosureImports.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosureImports.json @@ -4,6 +4,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "applyInt", "parameters" : [ { @@ -43,7 +48,8 @@ "width" : "word" } } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -60,6 +66,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "makeAdder", "parameters" : [ { @@ -98,7 +109,8 @@ "width" : "word" } } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStructImports.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStructImports.json index c1329cd79..ccd3043ac 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStructImports.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStructImports.json @@ -56,6 +56,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "translate", "parameters" : [ { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/VoidParameterVoidReturn.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/VoidParameterVoidReturn.json index 14da32841..7f19c18bf 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/VoidParameterVoidReturn.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/VoidParameterVoidReturn.json @@ -38,6 +38,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "check", "parameters" : [ diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncImport.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncImport.d.ts new file mode 100644 index 000000000..e612ae1e1 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncImport.d.ts @@ -0,0 +1,23 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +export type Exports = { +} +export type Imports = { + asyncReturnVoid(): Promise; + asyncRoundTripInt(v: number): Promise; + asyncRoundTripString(v: string): Promise; + asyncRoundTripBool(v: boolean): Promise; + asyncRoundTripDouble(v: number): Promise; + asyncRoundTripJSObject(v: any): Promise; +} +export function createInstantiator(options: { + imports: Imports; +}, swift: any): Promise<{ + addImports: (importObject: WebAssembly.Imports) => void; + setInstance: (instance: WebAssembly.Instance) => void; + createExports: (instance: WebAssembly.Instance) => Exports; +}>; \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncImport.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncImport.js new file mode 100644 index 000000000..89ab29827 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncImport.js @@ -0,0 +1,507 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +export async function createInstantiator(options, swift) { + let instance; + let memory; + let setException; + let decodeString; + const textDecoder = new TextDecoder("utf-8"); + const textEncoder = new TextEncoder("utf-8"); + let tmpRetString; + let tmpRetBytes; + let tmpRetException; + let tmpRetOptionalBool; + let tmpRetOptionalInt; + let tmpRetOptionalFloat; + let tmpRetOptionalDouble; + let tmpRetOptionalHeapObject; + let strStack = []; + let i32Stack = []; + let i64Stack = []; + let f32Stack = []; + let f64Stack = []; + let ptrStack = []; + const enumHelpers = {}; + const structHelpers = {}; + + let _exports = null; + let bjs = null; + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const swiftClosureRegistry = (typeof FinalizationRegistry === "undefined") ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => { + if (state.unregistered) { return; } + instance?.exports?.bjs_release_swift_closure(state.pointer); + }); + const makeClosure = (pointer, file, line, func) => { + const state = { pointer, file, line, unregistered: false }; + const real = (...args) => { + if (state.unregistered) { + const bytes = new Uint8Array(memory.buffer, state.file); + let length = 0; + while (bytes[length] !== 0) { length += 1; } + const fileID = decodeString(state.file, length); + throw new Error(`Attempted to call a released JSTypedClosure created at ${fileID}:${state.line}`); + } + return func(...args); + }; + real.__unregister = () => { + if (state.unregistered) { return; } + state.unregistered = true; + swiftClosureRegistry.unregister(state); + }; + swiftClosureRegistry.register(real, state, state); + return swift.memory.retain(real); + }; + + + return { + /** + * @param {WebAssembly.Imports} importObject + */ + addImports: (importObject, importsContext) => { + bjs = {}; + importObject["bjs"] = bjs; + const imports = options.getImports(importsContext); + bjs["swift_js_return_string"] = function(ptr, len) { + tmpRetString = decodeString(ptr, len); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + return swift.memory.retain(decodeString(ptr, len)); + } + bjs["swift_js_init_memory_with_result"] = function(ptr, len) { + const target = new Uint8Array(memory.buffer, ptr, len); + target.set(tmpRetBytes); + tmpRetBytes = undefined; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_push_i32"] = function(v) { + i32Stack.push(v | 0); + } + bjs["swift_js_push_f32"] = function(v) { + f32Stack.push(Math.fround(v)); + } + bjs["swift_js_push_f64"] = function(v) { + f64Stack.push(v); + } + bjs["swift_js_push_string"] = function(ptr, len) { + const value = decodeString(ptr, len); + strStack.push(value); + } + bjs["swift_js_pop_i32"] = function() { + return i32Stack.pop(); + } + bjs["swift_js_pop_f32"] = function() { + return f32Stack.pop(); + } + bjs["swift_js_pop_f64"] = function() { + return f64Stack.pop(); + } + bjs["swift_js_push_pointer"] = function(pointer) { + ptrStack.push(pointer); + } + bjs["swift_js_pop_pointer"] = function() { + return ptrStack.pop(); + } + bjs["swift_js_push_i64"] = function(v) { + i64Stack.push(v); + } + bjs["swift_js_pop_i64"] = function() { + return i64Stack.pop(); + } + bjs["swift_js_return_optional_bool"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalBool = null; + } else { + tmpRetOptionalBool = value !== 0; + } + } + bjs["swift_js_return_optional_int"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalInt = null; + } else { + tmpRetOptionalInt = value | 0; + } + } + bjs["swift_js_return_optional_float"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalFloat = null; + } else { + tmpRetOptionalFloat = Math.fround(value); + } + } + bjs["swift_js_return_optional_double"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalDouble = null; + } else { + tmpRetOptionalDouble = value; + } + } + bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = decodeString(ptr, len); + } + } + bjs["swift_js_return_optional_object"] = function(isSome, objectId) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = swift.memory.getObject(objectId); + } + } + bjs["swift_js_return_optional_heap_object"] = function(isSome, pointer) { + if (isSome === 0) { + tmpRetOptionalHeapObject = null; + } else { + tmpRetOptionalHeapObject = pointer; + } + } + bjs["swift_js_get_optional_int_presence"] = function() { + return tmpRetOptionalInt != null ? 1 : 0; + } + bjs["swift_js_get_optional_int_value"] = function() { + const value = tmpRetOptionalInt; + tmpRetOptionalInt = undefined; + return value; + } + bjs["swift_js_get_optional_string"] = function() { + const str = tmpRetString; + tmpRetString = undefined; + if (str == null) { + return -1; + } else { + const bytes = textEncoder.encode(str); + tmpRetBytes = bytes; + return bytes.length; + } + } + bjs["swift_js_get_optional_float_presence"] = function() { + return tmpRetOptionalFloat != null ? 1 : 0; + } + bjs["swift_js_get_optional_float_value"] = function() { + const value = tmpRetOptionalFloat; + tmpRetOptionalFloat = undefined; + return value; + } + bjs["swift_js_get_optional_double_presence"] = function() { + return tmpRetOptionalDouble != null ? 1 : 0; + } + bjs["swift_js_get_optional_double_value"] = function() { + const value = tmpRetOptionalDouble; + tmpRetOptionalDouble = undefined; + return value; + } + bjs["swift_js_get_optional_heap_object_pointer"] = function() { + const pointer = tmpRetOptionalHeapObject; + tmpRetOptionalHeapObject = undefined; + return pointer || 0; + } + bjs["swift_js_closure_unregister"] = function(funcRef) {} + bjs["swift_js_closure_unregister"] = function(funcRef) { + const func = swift.memory.getObject(funcRef); + func.__unregister(); + } + bjs["invoke_js_callback_TestModule_10TestModules7JSValueV_y"] = function(callbackId, param0Kind, param0Payload1, param0Payload2) { + try { + const callback = swift.memory.getObject(callbackId); + const jsValue = __bjs_jsValueLift(param0Kind, param0Payload1, param0Payload2); + callback(jsValue); + } catch (error) { + setException(error); + } + } + bjs["make_swift_closure_TestModule_10TestModules7JSValueV_y"] = function(boxPtr, file, line) { + const lower_closure_TestModule_10TestModules7JSValueV_y = function(param0) { + const [param0Kind, param0Payload1, param0Payload2] = __bjs_jsValueLower(param0); + instance.exports.invoke_swift_closure_TestModule_10TestModules7JSValueV_y(boxPtr, param0Kind, param0Payload1, param0Payload2); + if (tmpRetException) { + const error = swift.memory.getObject(tmpRetException); + swift.memory.release(tmpRetException); + tmpRetException = undefined; + throw error; + } + }; + return makeClosure(boxPtr, file, line, lower_closure_TestModule_10TestModules7JSValueV_y); + } + bjs["invoke_js_callback_TestModule_10TestModules8JSObjectC_y"] = function(callbackId, param0) { + try { + const callback = swift.memory.getObject(callbackId); + callback(swift.memory.getObject(param0)); + } catch (error) { + setException(error); + } + } + bjs["make_swift_closure_TestModule_10TestModules8JSObjectC_y"] = function(boxPtr, file, line) { + const lower_closure_TestModule_10TestModules8JSObjectC_y = function(param0) { + instance.exports.invoke_swift_closure_TestModule_10TestModules8JSObjectC_y(boxPtr, swift.memory.retain(param0)); + if (tmpRetException) { + const error = swift.memory.getObject(tmpRetException); + swift.memory.release(tmpRetException); + tmpRetException = undefined; + throw error; + } + }; + return makeClosure(boxPtr, file, line, lower_closure_TestModule_10TestModules8JSObjectC_y); + } + bjs["invoke_js_callback_TestModule_10TestModulesSS_y"] = function(callbackId, param0Bytes, param0Count) { + try { + const callback = swift.memory.getObject(callbackId); + const string = decodeString(param0Bytes, param0Count); + callback(string); + } catch (error) { + setException(error); + } + } + bjs["make_swift_closure_TestModule_10TestModulesSS_y"] = function(boxPtr, file, line) { + const lower_closure_TestModule_10TestModulesSS_y = function(param0) { + const param0Bytes = textEncoder.encode(param0); + const param0Id = swift.memory.retain(param0Bytes); + instance.exports.invoke_swift_closure_TestModule_10TestModulesSS_y(boxPtr, param0Id, param0Bytes.length); + if (tmpRetException) { + const error = swift.memory.getObject(tmpRetException); + swift.memory.release(tmpRetException); + tmpRetException = undefined; + throw error; + } + }; + return makeClosure(boxPtr, file, line, lower_closure_TestModule_10TestModulesSS_y); + } + bjs["invoke_js_callback_TestModule_10TestModulesSb_y"] = function(callbackId, param0) { + try { + const callback = swift.memory.getObject(callbackId); + callback(param0 !== 0); + } catch (error) { + setException(error); + } + } + bjs["make_swift_closure_TestModule_10TestModulesSb_y"] = function(boxPtr, file, line) { + const lower_closure_TestModule_10TestModulesSb_y = function(param0) { + instance.exports.invoke_swift_closure_TestModule_10TestModulesSb_y(boxPtr, param0); + if (tmpRetException) { + const error = swift.memory.getObject(tmpRetException); + swift.memory.release(tmpRetException); + tmpRetException = undefined; + throw error; + } + }; + return makeClosure(boxPtr, file, line, lower_closure_TestModule_10TestModulesSb_y); + } + bjs["invoke_js_callback_TestModule_10TestModulesSd_y"] = function(callbackId, param0) { + try { + const callback = swift.memory.getObject(callbackId); + callback(param0); + } catch (error) { + setException(error); + } + } + bjs["make_swift_closure_TestModule_10TestModulesSd_y"] = function(boxPtr, file, line) { + const lower_closure_TestModule_10TestModulesSd_y = function(param0) { + instance.exports.invoke_swift_closure_TestModule_10TestModulesSd_y(boxPtr, param0); + if (tmpRetException) { + const error = swift.memory.getObject(tmpRetException); + swift.memory.release(tmpRetException); + tmpRetException = undefined; + throw error; + } + }; + return makeClosure(boxPtr, file, line, lower_closure_TestModule_10TestModulesSd_y); + } + bjs["invoke_js_callback_TestModule_10TestModulesSi_y"] = function(callbackId, param0) { + try { + const callback = swift.memory.getObject(callbackId); + callback(param0); + } catch (error) { + setException(error); + } + } + bjs["make_swift_closure_TestModule_10TestModulesSi_y"] = function(boxPtr, file, line) { + const lower_closure_TestModule_10TestModulesSi_y = function(param0) { + instance.exports.invoke_swift_closure_TestModule_10TestModulesSi_y(boxPtr, param0); + if (tmpRetException) { + const error = swift.memory.getObject(tmpRetException); + swift.memory.release(tmpRetException); + tmpRetException = undefined; + throw error; + } + }; + return makeClosure(boxPtr, file, line, lower_closure_TestModule_10TestModulesSi_y); + } + bjs["invoke_js_callback_TestModule_10TestModuley_y"] = function(callbackId) { + try { + const callback = swift.memory.getObject(callbackId); + callback(); + } catch (error) { + setException(error); + } + } + bjs["make_swift_closure_TestModule_10TestModuley_y"] = function(boxPtr, file, line) { + const lower_closure_TestModule_10TestModuley_y = function() { + instance.exports.invoke_swift_closure_TestModule_10TestModuley_y(boxPtr); + if (tmpRetException) { + const error = swift.memory.getObject(tmpRetException); + swift.memory.release(tmpRetException); + tmpRetException = undefined; + throw error; + } + }; + return makeClosure(boxPtr, file, line, lower_closure_TestModule_10TestModuley_y); + } + const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; + TestModule["bjs_asyncReturnVoid"] = function bjs_asyncReturnVoid(resolveRef, rejectRef) { + const resolve = swift.memory.getObject(resolveRef); + const reject = swift.memory.getObject(rejectRef); + imports.asyncReturnVoid().then(resolve, reject); + } + TestModule["bjs_asyncRoundTripInt"] = function bjs_asyncRoundTripInt(resolveRef, rejectRef, v) { + const resolve = swift.memory.getObject(resolveRef); + const reject = swift.memory.getObject(rejectRef); + imports.asyncRoundTripInt(v).then(resolve, reject); + } + TestModule["bjs_asyncRoundTripString"] = function bjs_asyncRoundTripString(resolveRef, rejectRef, vBytes, vCount) { + const resolve = swift.memory.getObject(resolveRef); + const reject = swift.memory.getObject(rejectRef); + const string = decodeString(vBytes, vCount); + imports.asyncRoundTripString(string).then(resolve, reject); + } + TestModule["bjs_asyncRoundTripBool"] = function bjs_asyncRoundTripBool(resolveRef, rejectRef, v) { + const resolve = swift.memory.getObject(resolveRef); + const reject = swift.memory.getObject(rejectRef); + imports.asyncRoundTripBool(v !== 0).then(resolve, reject); + } + TestModule["bjs_asyncRoundTripDouble"] = function bjs_asyncRoundTripDouble(resolveRef, rejectRef, v) { + const resolve = swift.memory.getObject(resolveRef); + const reject = swift.memory.getObject(rejectRef); + imports.asyncRoundTripDouble(v).then(resolve, reject); + } + TestModule["bjs_asyncRoundTripJSObject"] = function bjs_asyncRoundTripJSObject(resolveRef, rejectRef, v) { + const resolve = swift.memory.getObject(resolveRef); + const reject = swift.memory.getObject(rejectRef); + imports.asyncRoundTripJSObject(swift.memory.getObject(v)).then(resolve, reject); + } + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + decodeString = (ptr, len) => { const bytes = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); return textDecoder.decode(bytes); } + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + const exports = { + }; + _exports = exports; + return exports; + }, + } +} \ No newline at end of file diff --git a/Sources/JavaScriptKit/BridgeJSIntrinsics.swift b/Sources/JavaScriptKit/BridgeJSIntrinsics.swift index 180567ed1..867d0e835 100644 --- a/Sources/JavaScriptKit/BridgeJSIntrinsics.swift +++ b/Sources/JavaScriptKit/BridgeJSIntrinsics.swift @@ -4,6 +4,7 @@ /// by the BridgeJS system. import _CJavaScriptKit +import _Concurrency #if !arch(wasm32) @usableFromInline func _onlyAvailableOnWasm() -> Never { @@ -2083,3 +2084,91 @@ extension _BridgedAsOptional { Wrapped.bridgeJSStackPushAsOptional(asOptional) } } + +// MARK: Async Promise Awaiting + +/// Protocol for type-erasing `JSTypedClosure` in `_bjs_awaitPromise`. +/// +/// The library cannot name concrete `JSTypedClosure<(Int) -> Void>` etc. because +/// those require per-module generated convenience inits. This protocol provides +/// access to the underlying JS object ref and cleanup. +@_spi(BridgeJS) public protocol _BridgeJSReleasableClosure { + var jsObject: JSObject { get } + func release() +} + +@_spi(BridgeJS) extension JSTypedClosure: _BridgeJSReleasableClosure {} + +/// Awaits a JavaScript Promise using typed resolve/reject `JSTypedClosure` callbacks. +/// +/// The closure factories are dependency-injected because this library cannot +/// reference per-module generated `make_swift_closure_*` externs. The generated +/// code passes `{ JSTypedClosure<(T) -> Void>($0) }` which uses the per-module +/// convenience init. +/// +/// - Parameters: +/// - makeResolveClosure: A factory that wraps a `(T) -> Void` Swift closure +/// into a typed `JSTypedClosure`, creating the corresponding JS function. +/// - makeRejectClosure: A factory that wraps a `(JSValue) -> Void` Swift closure +/// into a `JSTypedClosure`, for the rejection path. +/// - body: A closure that receives the resolve and reject JS object refs +/// (as `Int32`) and should pass them to the appropriate JS extern function. +/// - Returns: The resolved value of type `T` from the Promise. +/// - Throws: `JSException` if the Promise rejects. +@_spi(BridgeJS) public func _bjs_awaitPromise( + makeResolveClosure: (@escaping (sending T) -> Void) -> R, + makeRejectClosure: (@escaping (sending JSValue) -> Void) -> E, + _ body: (_ resolveRef: Int32, _ rejectRef: Int32) -> Void +) async throws(JSException) -> T { + var resolveClosure: R? + var rejectClosure: E? + let result: Result = await withCheckedContinuation { continuation in + let resolve = makeResolveClosure { value in + continuation.resume(returning: .success(value)) + } + let reject = makeRejectClosure { value in + continuation.resume(returning: .failure(JSException(value))) + } + resolveClosure = resolve + rejectClosure = reject + body( + Int32(bitPattern: resolve.jsObject.id), + Int32(bitPattern: reject.jsObject.id) + ) + } + resolveClosure?.release() + rejectClosure?.release() + return try result.get() +} + +/// Void-returning overload of `_bjs_awaitPromise`. +/// +/// Needed because `(Void) -> Void` is not the same as `() -> Void` in Swift (SE-0110), +/// so the generic overload cannot handle void returns. +@_spi(BridgeJS) public func _bjs_awaitPromise( + makeResolveClosure: (@escaping () -> Void) -> R, + makeRejectClosure: (@escaping (sending JSValue) -> Void) -> E, + _ body: (_ resolveRef: Int32, _ rejectRef: Int32) -> Void +) async throws(JSException) { + var resolveClosure: R? + var rejectClosure: E? + let error: JSException? = await withCheckedContinuation { continuation in + let resolve = makeResolveClosure { + continuation.resume(returning: nil) + } + let reject = makeRejectClosure { value in + continuation.resume(returning: JSException(value)) + } + resolveClosure = resolve + rejectClosure = reject + body( + Int32(bitPattern: resolve.jsObject.id), + Int32(bitPattern: reject.jsObject.id) + ) + } + resolveClosure?.release() + rejectClosure?.release() + if let error { + throw error + } +} diff --git a/Tests/BridgeJSRuntimeTests/AsyncImportTests.swift b/Tests/BridgeJSRuntimeTests/AsyncImportTests.swift new file mode 100644 index 000000000..9b6cc0688 --- /dev/null +++ b/Tests/BridgeJSRuntimeTests/AsyncImportTests.swift @@ -0,0 +1,35 @@ +import Testing +import JavaScriptKit + +@Suite struct AsyncImportTests { + @Test func asyncRoundTripVoid() async throws { + try await jsAsyncRoundTripVoid() + } + + @Test(arguments: [0.0, 1.0, -1.0, Double.pi, Double.infinity]) + func asyncRoundTripNumber(v: Double) async throws { + try #expect(await jsAsyncRoundTripNumber(v) == v) + } + + @Test(arguments: [true, false]) + func asyncRoundTripBool(v: Bool) async throws { + try #expect(await jsAsyncRoundTripBool(v) == v) + } + + @Test(arguments: ["", "Hello, world!", "🧑‍🧑‍🧒"]) + func asyncRoundTripString(v: String) async throws { + try #expect(await jsAsyncRoundTripString(v) == v) + } + + @Test func fetchWeatherData() async throws { + let weather = try await BridgeJSRuntimeTests.fetchWeatherData("London") + #expect(try weather.temperature == 15.5) + #expect(try weather.description == "Cloudy") + #expect(try weather.humidity == 80) + + let weather2 = try await BridgeJSRuntimeTests.fetchWeatherData("Tokyo") + #expect(try weather2.temperature == 25.0) + #expect(try weather2.description == "Sunny") + #expect(try weather2.humidity == 40) + } +} diff --git a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift index 171d0dd3a..3db9497fc 100644 --- a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift +++ b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift @@ -1301,6 +1301,6 @@ class ExportAPITests: XCTestCase { } func testAllAsync() async throws { - _ = try await runAsyncWorks().value() + try await runAsyncWorks() } } diff --git a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.Macros.swift b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.Macros.swift index ac9ad0bc6..b4e780bee 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.Macros.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.Macros.swift @@ -41,7 +41,26 @@ extension FeatureFlag: _BridgedSwiftEnumNoPayload, _BridgedSwiftRawValueEnum {} @JSFunction func changeName(_ name: String) throws(JSException) -> Void } -@JSFunction func runAsyncWorks() throws(JSException) -> JSPromise +@JSFunction func runAsyncWorks() async throws(JSException) -> Void + +@JSFunction func jsAsyncRoundTripVoid() async throws(JSException) -> Void + +@JSFunction func jsAsyncRoundTripNumber(_ v: Double) async throws(JSException) -> Double + +@JSFunction func jsAsyncRoundTripBool(_ v: Bool) async throws(JSException) -> Bool + +@JSFunction func jsAsyncRoundTripString(_ v: String) async throws(JSException) -> String + +@JSFunction func fetchWeatherData(_ city: String) async throws(JSException) -> WeatherData + +@JSClass struct WeatherData { + @JSGetter var temperature: Double + @JSSetter func setTemperature(_ value: Double) throws(JSException) + @JSGetter var description: String + @JSSetter func setDescription(_ value: String) throws(JSException) + @JSGetter var humidity: Double + @JSSetter func setHumidity(_ value: Double) throws(JSException) +} @JSFunction(jsName: "$jsWeirdFunction") func _jsWeirdFunction() throws(JSException) -> Double diff --git a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift index b54106be9..b7d6b55c3 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift @@ -1674,6 +1674,312 @@ public func _invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestsSqS #endif } +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss11WeatherDataC_y") +fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss11WeatherDataC_y_extern(_ callback: Int32, _ param0: Int32) -> Void +#else +fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss11WeatherDataC_y_extern(_ callback: Int32, _ param0: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss11WeatherDataC_y(_ callback: Int32, _ param0: Int32) -> Void { + return invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss11WeatherDataC_y_extern(callback, param0) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss11WeatherDataC_y") +fileprivate func make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss11WeatherDataC_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 +#else +fileprivate func make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss11WeatherDataC_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss11WeatherDataC_y(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + return make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss11WeatherDataC_y_extern(boxPtr, file, line) +} + +private enum _BJS_Closure_20BridgeJSRuntimeTestss11WeatherDataC_y { + static func bridgeJSLift(_ callbackId: Int32) -> (sending WeatherData) -> Void { + let callback = JSObject.bridgeJSLiftParameter(callbackId) + return { [callback] param0 in + #if arch(wasm32) + let callbackValue = callback.bridgeJSLowerParameter() + let param0Value = param0.bridgeJSLowerParameter() + invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss11WeatherDataC_y(callbackValue, param0Value) + #else + fatalError("Only available on WebAssembly") + #endif + } + } +} + +extension JSTypedClosure where Signature == (sending WeatherData) -> Void { + init(fileID: StaticString = #fileID, line: UInt32 = #line, _ body: @escaping (sending WeatherData) -> Void) { + self.init( + makeClosure: make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss11WeatherDataC_y, + body: body, + fileID: fileID, + line: line + ) + } +} + +@_expose(wasm, "invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss11WeatherDataC_y") +@_cdecl("invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss11WeatherDataC_y") +public func _invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss11WeatherDataC_y(_ boxPtr: UnsafeMutableRawPointer, _ param0: Int32) -> Void { + #if arch(wasm32) + let closure = Unmanaged<_BridgeJSTypedClosureBox<(sending WeatherData) -> Void>>.fromOpaque(boxPtr).takeUnretainedValue().closure + closure(WeatherData.bridgeJSLiftParameter(param0)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss7JSValueV_y") +fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss7JSValueV_y_extern(_ callback: Int32, _ param0Kind: Int32, _ param0Payload1: Int32, _ param0Payload2: Float64) -> Void +#else +fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss7JSValueV_y_extern(_ callback: Int32, _ param0Kind: Int32, _ param0Payload1: Int32, _ param0Payload2: Float64) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss7JSValueV_y(_ callback: Int32, _ param0Kind: Int32, _ param0Payload1: Int32, _ param0Payload2: Float64) -> Void { + return invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss7JSValueV_y_extern(callback, param0Kind, param0Payload1, param0Payload2) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss7JSValueV_y") +fileprivate func make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss7JSValueV_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 +#else +fileprivate func make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss7JSValueV_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss7JSValueV_y(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + return make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss7JSValueV_y_extern(boxPtr, file, line) +} + +private enum _BJS_Closure_20BridgeJSRuntimeTestss7JSValueV_y { + static func bridgeJSLift(_ callbackId: Int32) -> (sending JSValue) -> Void { + let callback = JSObject.bridgeJSLiftParameter(callbackId) + return { [callback] param0 in + #if arch(wasm32) + let callbackValue = callback.bridgeJSLowerParameter() + let (param0Kind, param0Payload1, param0Payload2) = param0.bridgeJSLowerParameter() + invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss7JSValueV_y(callbackValue, param0Kind, param0Payload1, param0Payload2) + #else + fatalError("Only available on WebAssembly") + #endif + } + } +} + +extension JSTypedClosure where Signature == (sending JSValue) -> Void { + init(fileID: StaticString = #fileID, line: UInt32 = #line, _ body: @escaping (sending JSValue) -> Void) { + self.init( + makeClosure: make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss7JSValueV_y, + body: body, + fileID: fileID, + line: line + ) + } +} + +@_expose(wasm, "invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss7JSValueV_y") +@_cdecl("invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss7JSValueV_y") +public func _invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestss7JSValueV_y(_ boxPtr: UnsafeMutableRawPointer, _ param0Kind: Int32, _ param0Payload1: Int32, _ param0Payload2: Float64) -> Void { + #if arch(wasm32) + let closure = Unmanaged<_BridgeJSTypedClosureBox<(sending JSValue) -> Void>>.fromOpaque(boxPtr).takeUnretainedValue().closure + closure(JSValue.bridgeJSLiftParameter(param0Kind, param0Payload1, param0Payload2)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSS_y") +fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSS_y_extern(_ callback: Int32, _ param0Bytes: Int32, _ param0Length: Int32) -> Void +#else +fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSS_y_extern(_ callback: Int32, _ param0Bytes: Int32, _ param0Length: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSS_y(_ callback: Int32, _ param0Bytes: Int32, _ param0Length: Int32) -> Void { + return invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSS_y_extern(callback, param0Bytes, param0Length) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSS_y") +fileprivate func make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSS_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 +#else +fileprivate func make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSS_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSS_y(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + return make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSS_y_extern(boxPtr, file, line) +} + +private enum _BJS_Closure_20BridgeJSRuntimeTestssSS_y { + static func bridgeJSLift(_ callbackId: Int32) -> (sending String) -> Void { + let callback = JSObject.bridgeJSLiftParameter(callbackId) + return { [callback] param0 in + #if arch(wasm32) + let callbackValue = callback.bridgeJSLowerParameter() + param0.bridgeJSWithLoweredParameter { (param0Bytes, param0Length) in + invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSS_y(callbackValue, param0Bytes, param0Length) + } + #else + fatalError("Only available on WebAssembly") + #endif + } + } +} + +extension JSTypedClosure where Signature == (sending String) -> Void { + init(fileID: StaticString = #fileID, line: UInt32 = #line, _ body: @escaping (sending String) -> Void) { + self.init( + makeClosure: make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSS_y, + body: body, + fileID: fileID, + line: line + ) + } +} + +@_expose(wasm, "invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSS_y") +@_cdecl("invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSS_y") +public func _invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSS_y(_ boxPtr: UnsafeMutableRawPointer, _ param0Bytes: Int32, _ param0Length: Int32) -> Void { + #if arch(wasm32) + let closure = Unmanaged<_BridgeJSTypedClosureBox<(sending String) -> Void>>.fromOpaque(boxPtr).takeUnretainedValue().closure + closure(String.bridgeJSLiftParameter(param0Bytes, param0Length)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSb_y") +fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSb_y_extern(_ callback: Int32, _ param0: Int32) -> Void +#else +fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSb_y_extern(_ callback: Int32, _ param0: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSb_y(_ callback: Int32, _ param0: Int32) -> Void { + return invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSb_y_extern(callback, param0) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSb_y") +fileprivate func make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSb_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 +#else +fileprivate func make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSb_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSb_y(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + return make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSb_y_extern(boxPtr, file, line) +} + +private enum _BJS_Closure_20BridgeJSRuntimeTestssSb_y { + static func bridgeJSLift(_ callbackId: Int32) -> (sending Bool) -> Void { + let callback = JSObject.bridgeJSLiftParameter(callbackId) + return { [callback] param0 in + #if arch(wasm32) + let callbackValue = callback.bridgeJSLowerParameter() + let param0Value = param0.bridgeJSLowerParameter() + invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSb_y(callbackValue, param0Value) + #else + fatalError("Only available on WebAssembly") + #endif + } + } +} + +extension JSTypedClosure where Signature == (sending Bool) -> Void { + init(fileID: StaticString = #fileID, line: UInt32 = #line, _ body: @escaping (sending Bool) -> Void) { + self.init( + makeClosure: make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSb_y, + body: body, + fileID: fileID, + line: line + ) + } +} + +@_expose(wasm, "invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSb_y") +@_cdecl("invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSb_y") +public func _invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSb_y(_ boxPtr: UnsafeMutableRawPointer, _ param0: Int32) -> Void { + #if arch(wasm32) + let closure = Unmanaged<_BridgeJSTypedClosureBox<(sending Bool) -> Void>>.fromOpaque(boxPtr).takeUnretainedValue().closure + closure(Bool.bridgeJSLiftParameter(param0)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSd_y") +fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSd_y_extern(_ callback: Int32, _ param0: Float64) -> Void +#else +fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSd_y_extern(_ callback: Int32, _ param0: Float64) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSd_y(_ callback: Int32, _ param0: Float64) -> Void { + return invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSd_y_extern(callback, param0) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSd_y") +fileprivate func make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSd_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 +#else +fileprivate func make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSd_y_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSd_y(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + return make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSd_y_extern(boxPtr, file, line) +} + +private enum _BJS_Closure_20BridgeJSRuntimeTestssSd_y { + static func bridgeJSLift(_ callbackId: Int32) -> (sending Double) -> Void { + let callback = JSObject.bridgeJSLiftParameter(callbackId) + return { [callback] param0 in + #if arch(wasm32) + let callbackValue = callback.bridgeJSLowerParameter() + let param0Value = param0.bridgeJSLowerParameter() + invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSd_y(callbackValue, param0Value) + #else + fatalError("Only available on WebAssembly") + #endif + } + } +} + +extension JSTypedClosure where Signature == (sending Double) -> Void { + init(fileID: StaticString = #fileID, line: UInt32 = #line, _ body: @escaping (sending Double) -> Void) { + self.init( + makeClosure: make_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSd_y, + body: body, + fileID: fileID, + line: line + ) + } +} + +@_expose(wasm, "invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSd_y") +@_cdecl("invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSd_y") +public func _invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSd_y(_ boxPtr: UnsafeMutableRawPointer, _ param0: Float64) -> Void { + #if arch(wasm32) + let closure = Unmanaged<_BridgeJSTypedClosureBox<(sending Double) -> Void>>.fromOpaque(boxPtr).takeUnretainedValue().closure + closure(Double.bridgeJSLiftParameter(param0)) + #else + fatalError("Only available on WebAssembly") + #endif +} + #if arch(wasm32) @_extern(wasm, module: "bjs", name: "invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestsy_13DataProcessorP") fileprivate func invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestsy_13DataProcessorP_extern(_ callback: Int32) -> Int32 @@ -11296,22 +11602,144 @@ func _$jsRoundTripFeatureFlag(_ flag: FeatureFlag) throws(JSException) -> Featur #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_runAsyncWorks") -fileprivate func bjs_runAsyncWorks_extern() -> Int32 +fileprivate func bjs_runAsyncWorks_extern(_ resolveRef: Int32, _ rejectRef: Int32) -> Void #else -fileprivate func bjs_runAsyncWorks_extern() -> Int32 { +fileprivate func bjs_runAsyncWorks_extern(_ resolveRef: Int32, _ rejectRef: Int32) -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_runAsyncWorks() -> Int32 { - return bjs_runAsyncWorks_extern() +@inline(never) fileprivate func bjs_runAsyncWorks(_ resolveRef: Int32, _ rejectRef: Int32) -> Void { + return bjs_runAsyncWorks_extern(resolveRef, rejectRef) } -func _$runAsyncWorks() throws(JSException) -> JSPromise { - let ret = bjs_runAsyncWorks() - if let error = _swift_js_take_exception() { - throw error +func _$runAsyncWorks() async throws(JSException) -> Void { + try await _bjs_awaitPromise(makeResolveClosure: { + JSTypedClosure<() -> Void>($0) + }, makeRejectClosure: { + JSTypedClosure<(sending JSValue) -> Void>($0) + }) { resolveRef, rejectRef in + bjs_runAsyncWorks(resolveRef, rejectRef) } - return JSPromise.bridgeJSLiftReturn(ret) +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsAsyncRoundTripVoid") +fileprivate func bjs_jsAsyncRoundTripVoid_extern(_ resolveRef: Int32, _ rejectRef: Int32) -> Void +#else +fileprivate func bjs_jsAsyncRoundTripVoid_extern(_ resolveRef: Int32, _ rejectRef: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsAsyncRoundTripVoid(_ resolveRef: Int32, _ rejectRef: Int32) -> Void { + return bjs_jsAsyncRoundTripVoid_extern(resolveRef, rejectRef) +} + +func _$jsAsyncRoundTripVoid() async throws(JSException) -> Void { + try await _bjs_awaitPromise(makeResolveClosure: { + JSTypedClosure<() -> Void>($0) + }, makeRejectClosure: { + JSTypedClosure<(sending JSValue) -> Void>($0) + }) { resolveRef, rejectRef in + bjs_jsAsyncRoundTripVoid(resolveRef, rejectRef) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsAsyncRoundTripNumber") +fileprivate func bjs_jsAsyncRoundTripNumber_extern(_ resolveRef: Int32, _ rejectRef: Int32, _ v: Float64) -> Void +#else +fileprivate func bjs_jsAsyncRoundTripNumber_extern(_ resolveRef: Int32, _ rejectRef: Int32, _ v: Float64) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsAsyncRoundTripNumber(_ resolveRef: Int32, _ rejectRef: Int32, _ v: Float64) -> Void { + return bjs_jsAsyncRoundTripNumber_extern(resolveRef, rejectRef, v) +} + +func _$jsAsyncRoundTripNumber(_ v: Double) async throws(JSException) -> Double { + let resolved = try await _bjs_awaitPromise(makeResolveClosure: { + JSTypedClosure<(sending Double) -> Void>($0) + }, makeRejectClosure: { + JSTypedClosure<(sending JSValue) -> Void>($0) + }) { resolveRef, rejectRef in + let vValue = v.bridgeJSLowerParameter() + bjs_jsAsyncRoundTripNumber(resolveRef, rejectRef, vValue) + } + return resolved +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsAsyncRoundTripBool") +fileprivate func bjs_jsAsyncRoundTripBool_extern(_ resolveRef: Int32, _ rejectRef: Int32, _ v: Int32) -> Void +#else +fileprivate func bjs_jsAsyncRoundTripBool_extern(_ resolveRef: Int32, _ rejectRef: Int32, _ v: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsAsyncRoundTripBool(_ resolveRef: Int32, _ rejectRef: Int32, _ v: Int32) -> Void { + return bjs_jsAsyncRoundTripBool_extern(resolveRef, rejectRef, v) +} + +func _$jsAsyncRoundTripBool(_ v: Bool) async throws(JSException) -> Bool { + let resolved = try await _bjs_awaitPromise(makeResolveClosure: { + JSTypedClosure<(sending Bool) -> Void>($0) + }, makeRejectClosure: { + JSTypedClosure<(sending JSValue) -> Void>($0) + }) { resolveRef, rejectRef in + let vValue = v.bridgeJSLowerParameter() + bjs_jsAsyncRoundTripBool(resolveRef, rejectRef, vValue) + } + return resolved +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsAsyncRoundTripString") +fileprivate func bjs_jsAsyncRoundTripString_extern(_ resolveRef: Int32, _ rejectRef: Int32, _ vBytes: Int32, _ vLength: Int32) -> Void +#else +fileprivate func bjs_jsAsyncRoundTripString_extern(_ resolveRef: Int32, _ rejectRef: Int32, _ vBytes: Int32, _ vLength: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsAsyncRoundTripString(_ resolveRef: Int32, _ rejectRef: Int32, _ vBytes: Int32, _ vLength: Int32) -> Void { + return bjs_jsAsyncRoundTripString_extern(resolveRef, rejectRef, vBytes, vLength) +} + +func _$jsAsyncRoundTripString(_ v: String) async throws(JSException) -> String { + let resolved = try await _bjs_awaitPromise(makeResolveClosure: { + JSTypedClosure<(sending String) -> Void>($0) + }, makeRejectClosure: { + JSTypedClosure<(sending JSValue) -> Void>($0) + }) { resolveRef, rejectRef in + v.bridgeJSWithLoweredParameter { (vBytes, vLength) in + bjs_jsAsyncRoundTripString(resolveRef, rejectRef, vBytes, vLength) + } + } + return resolved +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_fetchWeatherData") +fileprivate func bjs_fetchWeatherData_extern(_ resolveRef: Int32, _ rejectRef: Int32, _ cityBytes: Int32, _ cityLength: Int32) -> Void +#else +fileprivate func bjs_fetchWeatherData_extern(_ resolveRef: Int32, _ rejectRef: Int32, _ cityBytes: Int32, _ cityLength: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_fetchWeatherData(_ resolveRef: Int32, _ rejectRef: Int32, _ cityBytes: Int32, _ cityLength: Int32) -> Void { + return bjs_fetchWeatherData_extern(resolveRef, rejectRef, cityBytes, cityLength) +} + +func _$fetchWeatherData(_ city: String) async throws(JSException) -> WeatherData { + let resolved = try await _bjs_awaitPromise(makeResolveClosure: { + JSTypedClosure<(sending WeatherData) -> Void>($0) + }, makeRejectClosure: { + JSTypedClosure<(sending JSValue) -> Void>($0) + }) { resolveRef, rejectRef in + city.bridgeJSWithLoweredParameter { (cityBytes, cityLength) in + bjs_fetchWeatherData(resolveRef, rejectRef, cityBytes, cityLength) + } + } + return resolved } #if arch(wasm32) @@ -11492,6 +11920,133 @@ func _$JsGreeter_changeName(_ self: JSObject, _ name: String) throws(JSException } } +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_WeatherData_temperature_get") +fileprivate func bjs_WeatherData_temperature_get_extern(_ self: Int32) -> Float64 +#else +fileprivate func bjs_WeatherData_temperature_get_extern(_ self: Int32) -> Float64 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_WeatherData_temperature_get(_ self: Int32) -> Float64 { + return bjs_WeatherData_temperature_get_extern(self) +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_WeatherData_description_get") +fileprivate func bjs_WeatherData_description_get_extern(_ self: Int32) -> Int32 +#else +fileprivate func bjs_WeatherData_description_get_extern(_ self: Int32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_WeatherData_description_get(_ self: Int32) -> Int32 { + return bjs_WeatherData_description_get_extern(self) +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_WeatherData_humidity_get") +fileprivate func bjs_WeatherData_humidity_get_extern(_ self: Int32) -> Float64 +#else +fileprivate func bjs_WeatherData_humidity_get_extern(_ self: Int32) -> Float64 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_WeatherData_humidity_get(_ self: Int32) -> Float64 { + return bjs_WeatherData_humidity_get_extern(self) +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_WeatherData_temperature_set") +fileprivate func bjs_WeatherData_temperature_set_extern(_ self: Int32, _ newValue: Float64) -> Void +#else +fileprivate func bjs_WeatherData_temperature_set_extern(_ self: Int32, _ newValue: Float64) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_WeatherData_temperature_set(_ self: Int32, _ newValue: Float64) -> Void { + return bjs_WeatherData_temperature_set_extern(self, newValue) +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_WeatherData_description_set") +fileprivate func bjs_WeatherData_description_set_extern(_ self: Int32, _ newValueBytes: Int32, _ newValueLength: Int32) -> Void +#else +fileprivate func bjs_WeatherData_description_set_extern(_ self: Int32, _ newValueBytes: Int32, _ newValueLength: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_WeatherData_description_set(_ self: Int32, _ newValueBytes: Int32, _ newValueLength: Int32) -> Void { + return bjs_WeatherData_description_set_extern(self, newValueBytes, newValueLength) +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_WeatherData_humidity_set") +fileprivate func bjs_WeatherData_humidity_set_extern(_ self: Int32, _ newValue: Float64) -> Void +#else +fileprivate func bjs_WeatherData_humidity_set_extern(_ self: Int32, _ newValue: Float64) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_WeatherData_humidity_set(_ self: Int32, _ newValue: Float64) -> Void { + return bjs_WeatherData_humidity_set_extern(self, newValue) +} + +func _$WeatherData_temperature_get(_ self: JSObject) throws(JSException) -> Double { + let selfValue = self.bridgeJSLowerParameter() + let ret = bjs_WeatherData_temperature_get(selfValue) + if let error = _swift_js_take_exception() { + throw error + } + return Double.bridgeJSLiftReturn(ret) +} + +func _$WeatherData_description_get(_ self: JSObject) throws(JSException) -> String { + let selfValue = self.bridgeJSLowerParameter() + let ret = bjs_WeatherData_description_get(selfValue) + if let error = _swift_js_take_exception() { + throw error + } + return String.bridgeJSLiftReturn(ret) +} + +func _$WeatherData_humidity_get(_ self: JSObject) throws(JSException) -> Double { + let selfValue = self.bridgeJSLowerParameter() + let ret = bjs_WeatherData_humidity_get(selfValue) + if let error = _swift_js_take_exception() { + throw error + } + return Double.bridgeJSLiftReturn(ret) +} + +func _$WeatherData_temperature_set(_ self: JSObject, _ newValue: Double) throws(JSException) -> Void { + let selfValue = self.bridgeJSLowerParameter() + let newValueValue = newValue.bridgeJSLowerParameter() + bjs_WeatherData_temperature_set(selfValue, newValueValue) + if let error = _swift_js_take_exception() { + throw error + } +} + +func _$WeatherData_description_set(_ self: JSObject, _ newValue: String) throws(JSException) -> Void { + let selfValue = self.bridgeJSLowerParameter() + newValue.bridgeJSWithLoweredParameter { (newValueBytes, newValueLength) in + bjs_WeatherData_description_set(selfValue, newValueBytes, newValueLength) + } + if let error = _swift_js_take_exception() { + throw error + } +} + +func _$WeatherData_humidity_set(_ self: JSObject, _ newValue: Double) throws(JSException) -> Void { + let selfValue = self.bridgeJSLowerParameter() + let newValueValue = newValue.bridgeJSLowerParameter() + bjs_WeatherData_humidity_set(selfValue, newValueValue) + if let error = _swift_js_take_exception() { + throw error + } +} + #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs__WeirdClass_init") fileprivate func bjs__WeirdClass_init_extern() -> Int32 diff --git a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json index 842bcff24..c8c25c492 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json +++ b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json @@ -49,7 +49,8 @@ "width" : "word" } } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -97,7 +98,8 @@ "double" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -145,7 +147,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -202,7 +205,8 @@ "width" : "word" } } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : true } @@ -250,7 +254,8 @@ "double" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : true } @@ -298,7 +303,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : true } @@ -591,7 +597,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -641,7 +648,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -684,7 +692,8 @@ "swiftHeapObject" : { "_0" : "Greeter" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -724,7 +733,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -2931,7 +2941,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3017,7 +3028,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3059,7 +3071,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3100,7 +3113,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3151,7 +3165,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3199,7 +3214,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3246,7 +3262,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3282,7 +3299,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3318,7 +3336,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3362,7 +3381,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3409,7 +3429,8 @@ "width" : "word" } } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3455,7 +3476,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3497,7 +3519,8 @@ "bool" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3533,7 +3556,8 @@ "bool" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3572,7 +3596,8 @@ "width" : "word" } } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3607,7 +3632,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3648,7 +3674,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3697,7 +3724,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3745,7 +3773,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3792,7 +3821,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3828,7 +3858,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3866,7 +3897,8 @@ "swiftProtocol" : { "_0" : "DataProcessor" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3902,7 +3934,8 @@ "swiftProtocol" : { "_0" : "DataProcessor" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3927,7 +3960,8 @@ "swiftProtocol" : { "_0" : "DataProcessor" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -3968,7 +4002,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -10604,7 +10639,8 @@ }, "_1" : "null" } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -13606,7 +13642,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -13656,7 +13693,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -13708,7 +13746,8 @@ "width" : "word" } } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } @@ -16372,6 +16411,11 @@ ], "staticMethods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsIntArrayLength", "parameters" : [ { @@ -16400,6 +16444,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripIntArray", "parameters" : [ { @@ -16432,6 +16481,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripNumberArray", "parameters" : [ { @@ -16458,6 +16512,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripStringArray", "parameters" : [ { @@ -16484,6 +16543,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripBoolArray", "parameters" : [ { @@ -16510,6 +16574,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripJSValueArray", "parameters" : [ { @@ -16536,6 +16605,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripJSObjectArray", "parameters" : [ { @@ -16562,6 +16636,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripJSClassArray", "parameters" : [ { @@ -16588,6 +16667,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripOptionalIntArray", "parameters" : [ { @@ -16630,6 +16714,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripOptionalStringArray", "parameters" : [ { @@ -16666,6 +16755,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripOptionalBoolArray", "parameters" : [ { @@ -16702,6 +16796,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripOptionalJSValueArray", "parameters" : [ { @@ -16738,6 +16837,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripOptionalJSObjectArray", "parameters" : [ { @@ -16774,6 +16878,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripOptionalJSClassArray", "parameters" : [ { @@ -16810,6 +16919,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsSumNumberArray", "parameters" : [ { @@ -16832,6 +16946,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsCreateNumberArray", "parameters" : [ @@ -16847,6 +16966,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "runJsArraySupportTests", "parameters" : [ @@ -16879,6 +17003,11 @@ ], "staticMethods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsApplyVoid", "parameters" : [ { @@ -16897,7 +17026,8 @@ "void" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : true } @@ -16911,6 +17041,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsApplyBool", "parameters" : [ { @@ -16929,7 +17064,8 @@ "bool" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : true } @@ -16943,6 +17079,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsApplyInt", "parameters" : [ { @@ -16982,7 +17123,8 @@ "width" : "word" } } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : true } @@ -16999,6 +17141,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsApplyDouble", "parameters" : [ { @@ -17029,7 +17176,8 @@ "double" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : true } @@ -17043,6 +17191,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsApplyString", "parameters" : [ { @@ -17073,7 +17226,8 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : true } @@ -17087,6 +17241,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsApplyJSObject", "parameters" : [ { @@ -17117,7 +17276,8 @@ "jsObject" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : true } @@ -17131,6 +17291,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsMakeIntToInt", "parameters" : [ { @@ -17169,13 +17334,19 @@ "width" : "word" } } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsMakeDoubleToDouble", "parameters" : [ { @@ -17205,13 +17376,19 @@ "double" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsMakeStringToString", "parameters" : [ { @@ -17241,13 +17418,19 @@ "string" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : false } } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsCallTwice", "parameters" : [ { @@ -17284,7 +17467,8 @@ "void" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : true } @@ -17301,6 +17485,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsCallBinary", "parameters" : [ { @@ -17337,7 +17526,8 @@ "width" : "word" } } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : true } @@ -17354,6 +17544,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsCallTriple", "parameters" : [ { @@ -17398,7 +17593,8 @@ "width" : "word" } } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : true } @@ -17415,6 +17611,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsCallAfterRelease", "parameters" : [ { @@ -17433,7 +17634,8 @@ "void" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : true } @@ -17447,6 +17649,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsOptionalInvoke", "parameters" : [ { @@ -17467,7 +17674,8 @@ "bool" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : true } @@ -17484,6 +17692,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsStoreClosure", "parameters" : [ { @@ -17502,7 +17715,8 @@ "void" : { } - } + }, + "sendingParameters" : false }, "useJSTypedClosure" : true } @@ -17516,6 +17730,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsCallStoredClosure", "parameters" : [ @@ -17527,6 +17746,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsHeapCount", "parameters" : [ @@ -17541,6 +17765,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "runJsClosureSupportTests", "parameters" : [ @@ -17573,6 +17802,11 @@ ], "staticMethods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "runJsDefaultArgumentTests", "parameters" : [ @@ -17605,6 +17839,11 @@ ], "staticMethods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripDictionaryInt", "parameters" : [ { @@ -17637,6 +17876,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripDictionaryBool", "parameters" : [ { @@ -17663,6 +17907,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripDictionaryDouble", "parameters" : [ { @@ -17689,6 +17938,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripDictionaryJSObject", "parameters" : [ { @@ -17715,6 +17969,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripDictionaryJSValue", "parameters" : [ { @@ -17741,6 +18000,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripDictionaryDoubleArray", "parameters" : [ { @@ -17822,6 +18086,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripVoid", "parameters" : [ @@ -17833,6 +18102,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripNumber", "parameters" : [ { @@ -17851,6 +18125,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripBool", "parameters" : [ { @@ -17869,6 +18148,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripString", "parameters" : [ { @@ -17887,6 +18171,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripJSValue", "parameters" : [ { @@ -17905,6 +18194,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsThrowOrVoid", "parameters" : [ { @@ -17923,6 +18217,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsThrowOrNumber", "parameters" : [ { @@ -17941,6 +18240,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsThrowOrBool", "parameters" : [ { @@ -17959,6 +18263,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsThrowOrString", "parameters" : [ { @@ -17977,6 +18286,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripFeatureFlag", "parameters" : [ { @@ -17997,17 +18311,135 @@ } }, { + "effects" : { + "isAsync" : true, + "isStatic" : false, + "isThrows" : true + }, "name" : "runAsyncWorks", "parameters" : [ + ], + "returnType" : { + "void" : { + + } + } + }, + { + "effects" : { + "isAsync" : true, + "isStatic" : false, + "isThrows" : true + }, + "name" : "jsAsyncRoundTripVoid", + "parameters" : [ + + ], + "returnType" : { + "void" : { + + } + } + }, + { + "effects" : { + "isAsync" : true, + "isStatic" : false, + "isThrows" : true + }, + "name" : "jsAsyncRoundTripNumber", + "parameters" : [ + { + "name" : "v", + "type" : { + "double" : { + + } + } + } + ], + "returnType" : { + "double" : { + + } + } + }, + { + "effects" : { + "isAsync" : true, + "isStatic" : false, + "isThrows" : true + }, + "name" : "jsAsyncRoundTripBool", + "parameters" : [ + { + "name" : "v", + "type" : { + "bool" : { + + } + } + } + ], + "returnType" : { + "bool" : { + + } + } + }, + { + "effects" : { + "isAsync" : true, + "isStatic" : false, + "isThrows" : true + }, + "name" : "jsAsyncRoundTripString", + "parameters" : [ + { + "name" : "v", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "effects" : { + "isAsync" : true, + "isStatic" : false, + "isThrows" : true + }, + "name" : "fetchWeatherData", + "parameters" : [ + { + "name" : "city", + "type" : { + "string" : { + + } + } + } ], "returnType" : { "jsObject" : { - "_0" : "JSPromise" + "_0" : "WeatherData" } } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "jsName" : "$jsWeirdFunction", "name" : "_jsWeirdFunction", "parameters" : [ @@ -18020,6 +18452,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "from" : "global", "name" : "parseInt", "parameters" : [ @@ -18092,6 +18529,11 @@ ], "methods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "greet", "parameters" : [ @@ -18103,6 +18545,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "changeName", "parameters" : [ { @@ -18137,6 +18584,70 @@ ] }, + { + "getters" : [ + { + "name" : "temperature", + "type" : { + "double" : { + + } + } + }, + { + "name" : "description", + "type" : { + "string" : { + + } + } + }, + { + "name" : "humidity", + "type" : { + "double" : { + + } + } + } + ], + "methods" : [ + + ], + "name" : "WeatherData", + "setters" : [ + { + "functionName" : "temperature_set", + "name" : "temperature", + "type" : { + "double" : { + + } + } + }, + { + "functionName" : "description_set", + "name" : "description", + "type" : { + "string" : { + + } + } + }, + { + "functionName" : "humidity_set", + "name" : "humidity", + "type" : { + "double" : { + + } + } + } + ], + "staticMethods" : [ + + ] + }, { "constructor" : { "parameters" : [ @@ -18149,6 +18660,11 @@ "jsName" : "$WeirdClass", "methods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "jsName" : "method-with-dashes", "name" : "method_with_dashes", "parameters" : [ @@ -18187,6 +18703,11 @@ ], "methods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "value", "parameters" : [ @@ -18204,6 +18725,11 @@ ], "staticMethods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "create", "parameters" : [ { @@ -18222,6 +18748,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "value", "parameters" : [ @@ -18233,6 +18764,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "makeDefault", "parameters" : [ @@ -18244,6 +18780,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "jsName" : "with-dashes", "name" : "with_dashes", "parameters" : [ @@ -18315,6 +18856,11 @@ ], "methods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "bark", "parameters" : [ @@ -18326,6 +18872,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "getIsCat", "parameters" : [ @@ -18376,6 +18927,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsTranslatePoint", "parameters" : [ { @@ -18438,6 +18994,11 @@ ], "staticMethods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripInt", "parameters" : [ { @@ -18462,6 +19023,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripUInt", "parameters" : [ { @@ -18486,6 +19052,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripInt8", "parameters" : [ { @@ -18510,6 +19081,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripUInt8", "parameters" : [ { @@ -18534,6 +19110,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripInt16", "parameters" : [ { @@ -18558,6 +19139,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripUInt16", "parameters" : [ { @@ -18582,6 +19168,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripInt32", "parameters" : [ { @@ -18606,6 +19197,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripUInt32", "parameters" : [ { @@ -18630,6 +19226,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripInt64", "parameters" : [ { @@ -18654,6 +19255,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripUInt64", "parameters" : [ { @@ -18678,6 +19284,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "runJsIntegerTypesSupportTests", "parameters" : [ @@ -18760,6 +19371,11 @@ ], "methods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "concatNumbers", "parameters" : [ { @@ -18792,6 +19408,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "concatLabels", "parameters" : [ { @@ -18818,6 +19439,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "firstLabel", "parameters" : [ { @@ -18889,6 +19515,11 @@ ], "staticMethods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "makeJSClassWithArrayMembers", "parameters" : [ { @@ -19002,6 +19633,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsFunctionWithPackageAccess", "parameters" : [ @@ -19013,6 +19649,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsFunctionWithPublicAccess", "parameters" : [ @@ -19024,6 +19665,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsFunctionWithInternalAccess", "parameters" : [ @@ -19035,6 +19681,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsFunctionWithFilePrivateAccess", "parameters" : [ @@ -19046,6 +19697,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsFunctionWithPrivateAccess", "parameters" : [ @@ -19079,6 +19735,11 @@ ], "staticMethods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripOptionalNumberNull", "parameters" : [ { @@ -19113,6 +19774,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripOptionalNumberUndefined", "parameters" : [ { @@ -19147,6 +19813,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripOptionalStringNull", "parameters" : [ { @@ -19175,6 +19846,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripOptionalStringUndefined", "parameters" : [ { @@ -19203,6 +19879,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripOptionalJSValueArrayNull", "parameters" : [ { @@ -19239,6 +19920,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripOptionalJSValueArrayUndefined", "parameters" : [ { @@ -19275,6 +19961,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripOptionalStringToStringDictionaryNull", "parameters" : [ { @@ -19311,6 +20002,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripOptionalStringToStringDictionaryUndefined", "parameters" : [ { @@ -19347,6 +20043,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "runJsOptionalSupportTests", "parameters" : [ @@ -19364,6 +20065,11 @@ { "functions" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "from" : "global", "name" : "gc", "parameters" : [ @@ -19390,6 +20096,11 @@ ], "staticMethods" : [ { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripGreeter", "parameters" : [ { @@ -19408,6 +20119,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripUUID", "parameters" : [ { @@ -19426,6 +20142,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsRoundTripOptionalGreeter", "parameters" : [ { @@ -19454,6 +20175,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsConsumeLeakCheck", "parameters" : [ { @@ -19472,6 +20198,11 @@ } }, { + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, "name" : "jsConsumeOptionalLeakCheck", "parameters" : [ { diff --git a/Tests/BridgeJSRuntimeTests/bridge-js.d.ts b/Tests/BridgeJSRuntimeTests/bridge-js.d.ts index e8533a3d8..635a783b8 100644 --- a/Tests/BridgeJSRuntimeTests/bridge-js.d.ts +++ b/Tests/BridgeJSRuntimeTests/bridge-js.d.ts @@ -26,6 +26,20 @@ export class JsGreeter { export function runAsyncWorks(): Promise; +// Async round-trip tests +export function jsAsyncRoundTripVoid(): Promise; +export function jsAsyncRoundTripNumber(v: number): Promise; +export function jsAsyncRoundTripBool(v: boolean): Promise; +export function jsAsyncRoundTripString(v: string): Promise; + +// Async fetch-like test with structured return type +export interface WeatherData { + temperature: number; + description: string; + humidity: number; +} +export function fetchWeatherData(city: string): Promise; + // jsName tests export function $jsWeirdFunction(): number; diff --git a/Tests/prelude.mjs b/Tests/prelude.mjs index 8eb9a0270..8c652bc5c 100644 --- a/Tests/prelude.mjs +++ b/Tests/prelude.mjs @@ -119,6 +119,25 @@ export async function setupOptions(options, context) { }, StaticBox, Foo: ImportedFoo, + "fetchWeatherData": (city) => { + return Promise.resolve({ + temperature: city === "London" ? 15.5 : 25.0, + description: city === "London" ? "Cloudy" : "Sunny", + humidity: city === "London" ? 80 : 40, + }); + }, + "jsAsyncRoundTripVoid": () => { + return Promise.resolve(); + }, + "jsAsyncRoundTripNumber": (v) => { + return Promise.resolve(v); + }, + "jsAsyncRoundTripBool": (v) => { + return Promise.resolve(v); + }, + "jsAsyncRoundTripString": (v) => { + return Promise.resolve(v); + }, runAsyncWorks: async () => { const exports = importsContext.getExports(); if (!exports) {