diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift index a5f2e108..7634dd9d 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift @@ -351,7 +351,12 @@ public class ExportSwift { return .skipChildren } - let effectiveNamespace = computedNamespace ?? attributeNamespace + let effectiveNamespace: [String]? + if computedNamespace != nil && attributeNamespace != nil { + effectiveNamespace = computedNamespace + } else { + effectiveNamespace = computedNamespace ?? attributeNamespace + } let swiftCallName = ExportSwift.computeSwiftCallName(for: node, itemName: name) let exportedClass = ExportedClass( @@ -446,6 +451,24 @@ public class ExportSwift { ) } + if currentEnum.cases.contains(where: { !$0.associatedValues.isEmpty }) { + for c in currentEnum.cases { + for associatedValue in c.associatedValues { + switch associatedValue.type { + case .string, .int, .float, .double, .bool: + break + default: + diagnose( + node: node, + message: "Unsupported associated value type: \(associatedValue.type.swiftType)", + hint: + "Only primitive types (String, Int, Float, Double, Bool) are supported in associated-value enums" + ) + } + } + } + } + let swiftCallName = ExportSwift.computeSwiftCallName(for: node, itemName: enumName) let exportedEnum = ExportedEnum( name: enumName, @@ -587,47 +610,50 @@ public class ExportSwift { if let primitive = BridgeType(swiftType: type.trimmedDescription) { return primitive } - guard let identifier = type.as(IdentifierTypeSyntax.self) else { - return nil - } - guard let typeDecl = typeDeclResolver.lookupType(for: identifier) else { + guard let typeDecl = typeDeclResolver.resolve(type) else { return nil } + if let enumDecl = typeDecl.as(EnumDeclSyntax.self) { - let enumName = enumDecl.name.text - if let existingEnum = exportedEnums.first(where: { $0.name == enumName }) { - switch existingEnum.enumType { - case .simple: - return .caseEnum(existingEnum.swiftCallName) - case .rawValue: - let rawType = SwiftEnumRawType.from(existingEnum.rawType!)! - return .rawValueEnum(existingEnum.swiftCallName, rawType) - case .associatedValue: - return .associatedValueEnum(existingEnum.swiftCallName) - case .namespace: - return .namespaceEnum(existingEnum.swiftCallName) - } - } let swiftCallName = ExportSwift.computeSwiftCallName(for: enumDecl, itemName: enumDecl.name.text) let rawTypeString = enumDecl.inheritanceClause?.inheritedTypes.first { inheritedType in let typeName = inheritedType.type.trimmedDescription return Constants.supportedRawTypes.contains(typeName) }?.type.trimmedDescription - if let rawTypeString = rawTypeString, - let rawType = SwiftEnumRawType.from(rawTypeString) - { + if let rawTypeString, let rawType = SwiftEnumRawType.from(rawTypeString) { return .rawValueEnum(swiftCallName, rawType) } else { - return .caseEnum(swiftCallName) + let hasAnyCases = enumDecl.memberBlock.members.contains { member in + member.decl.is(EnumCaseDeclSyntax.self) + } + if !hasAnyCases { + return .namespaceEnum(swiftCallName) + } + let hasAssociatedValues = + enumDecl.memberBlock.members.contains { member in + guard let caseDecl = member.decl.as(EnumCaseDeclSyntax.self) else { return false } + return caseDecl.elements.contains { element in + if let params = element.parameterClause?.parameters { + return !params.isEmpty + } + return false + } + } + if hasAssociatedValues { + return .associatedValueEnum(swiftCallName) + } else { + return .caseEnum(swiftCallName) + } } } guard typeDecl.is(ClassDeclSyntax.self) || typeDecl.is(ActorDeclSyntax.self) else { return nil } - return .swiftHeapObject(typeDecl.name.text) + let swiftCallName = ExportSwift.computeSwiftCallName(for: typeDecl, itemName: typeDecl.name.text) + return .swiftHeapObject(swiftCallName) } static let prelude: DeclSyntax = """ @@ -647,10 +673,18 @@ public class ExportSwift { } decls.append(Self.prelude) + if exportedEnums.contains(where: { $0.enumType == .associatedValue }) { + decls.append(renderAssociatedValueBinaryHelpers()) + } + for enumDef in exportedEnums where enumDef.enumType == .simple { decls.append(renderCaseEnumHelpers(enumDef)) } + for enumDef in exportedEnums where enumDef.enumType == .associatedValue { + decls.append(renderAssociatedValueEnumHelpers(enumDef)) + } + for function in exportedFunctions { decls.append(renderSingleExportedFunction(function: function)) } @@ -661,29 +695,108 @@ public class ExportSwift { return decls.map { $0.formatted(using: format).description }.joined(separator: "\n\n") } - func renderCaseEnumHelpers(_ enumDef: ExportedEnum) -> DeclSyntax { - let typeName = enumDef.swiftCallName - var initCases: [String] = [] - var valueCases: [String] = [] - for (index, c) in enumDef.cases.enumerated() { - initCases.append("case \(index): self = .\(c.name)") - valueCases.append("case .\(c.name): return \(index)") - } - let initSwitch = (["switch bridgeJSRawValue {"] + initCases + ["default: return nil", "}"]).joined( - separator: "\n" - ) - let valueSwitch = (["switch self {"] + valueCases + ["}"]).joined(separator: "\n") - + func renderAssociatedValueBinaryHelpers() -> DeclSyntax { return """ - extension \(raw: typeName) { - init?(bridgeJSRawValue: Int32) { - \(raw: initSwitch) + fileprivate enum _BJSParamType: UInt8 { + case string = 1 + case int32 = 2 + case bool = 3 + case float32 = 4 + case float64 = 5 + } + + fileprivate struct _BJSBinaryReader { + let raw: UnsafeRawBufferPointer + var offset: Int = 0 + + @inline(__always) + mutating func readUInt8() -> UInt8 { + let b = raw[offset] + offset += 1 + return b } - var bridgeJSRawValue: Int32 { - \(raw: valueSwitch) + @inline(__always) + mutating func readUInt32() -> UInt32 { + var v = UInt32(0) + withUnsafeMutableBytes(of: &v) { dst in + dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 4)])) + } + offset += 4 + return UInt32(littleEndian: v) + } + + @inline(__always) + mutating func readInt32() -> Int32 { + var v = Int32(0) + withUnsafeMutableBytes(of: &v) { dst in + dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 4)])) + } + offset += 4 + return Int32(littleEndian: v) + } + + @inline(__always) + mutating func readFloat32() -> Float32 { + var bits = UInt32(0) + withUnsafeMutableBytes(of: &bits) { dst in + dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 4)])) + } + offset += 4 + return Float32(bitPattern: UInt32(littleEndian: bits)) + } + + @inline(__always) + mutating func readFloat64() -> Float64 { + var bits = UInt64(0) + withUnsafeMutableBytes(of: &bits) { dst in + dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 8)])) + } + offset += 8 + return Float64(bitPattern: UInt64(littleEndian: bits)) + } + + @inline(__always) + mutating func readString() -> String { + let len = Int(readUInt32()) + let s = String(decoding: UnsafeBufferPointer( + start: raw.baseAddress!.advanced(by: offset).assumingMemoryBound(to: UInt8.self), + count: len + ), as: UTF8.self) + offset += len + return s + } + + @inline(__always) + mutating func expectTag(_ expected: _BJSParamType) { + let rawTag = readUInt8() + guard let got = _BJSParamType(rawValue: rawTag), got == expected else { + preconditionFailure("BridgeJS: mismatched enum param tag. Expected \\(expected) got \\(String(describing: _BJSParamType(rawValue: rawTag)))") + } + } + + @inline(__always) + mutating func readParamCount(expected: Int) { + let count = Int(readUInt32()) + precondition(count == expected, "BridgeJS: mismatched enum param count. Expected \\(expected) got \\(count)") } } + + @_extern(wasm, module: "bjs", name: "swift_js_init_memory") + func _swift_js_init_memory(_: Int32, _: UnsafeMutablePointer) + + @_extern(wasm, module: "bjs", name: "swift_js_return_tag") + func _swift_js_return_tag(_: Int32) + @_extern(wasm, module: "bjs", name: "swift_js_return_string") + func _swift_js_return_string(_: UnsafePointer?, _: Int32) + @_extern(wasm, module: "bjs", name: "swift_js_return_int") + func _swift_js_return_int(_: Int32) + @_extern(wasm, module: "bjs", name: "swift_js_return_f32") + func _swift_js_return_f32(_: Float32) + @_extern(wasm, module: "bjs", name: "swift_js_return_f64") + func _swift_js_return_f64(_: Float64) + @_extern(wasm, module: "bjs", name: "swift_js_return_bool") + func _swift_js_return_bool(_: Int32) """ } @@ -812,8 +925,18 @@ public class ExportSwift { abiParameterSignatures.append((param.name, wasmType)) } } - case .associatedValueEnum(_): - break + case .associatedValueEnum(let enumName): + abiParameterForwardings.append( + LabeledExprSyntax( + label: param.label, + expression: ExprSyntax( + "\(raw: enumName).bridgeJSLiftParameter(\(raw: param.name)CaseId, \(raw: param.name)ParamsId, \(raw: param.name)ParamsLen)" + ) + ) + ) + abiParameterSignatures.append(("\(param.name)CaseId", .i32)) + abiParameterSignatures.append(("\(param.name)ParamsId", .i32)) + abiParameterSignatures.append(("\(param.name)ParamsLen", .i32)) case .namespaceEnum: break case .jsObject(nil): @@ -833,10 +956,14 @@ public class ExportSwift { ) abiParameterSignatures.append((param.name, .i32)) case .swiftHeapObject: - let objectExpr: ExprSyntax = - "Unmanaged<\(raw: param.type.swiftType)>.fromOpaque(\(raw: param.name)).takeUnretainedValue()" + // UnsafeMutableRawPointer is returned as an i32 pointer abiParameterForwardings.append( - LabeledExprSyntax(label: param.label, expression: objectExpr) + LabeledExprSyntax( + label: param.label, + expression: ExprSyntax( + "Unmanaged<\(raw: param.type.swiftType)>.fromOpaque(\(raw: param.name)).takeUnretainedValue()" + ) + ) ) abiParameterSignatures.append((param.name, .pointer)) case .void: @@ -925,6 +1052,7 @@ public class ExportSwift { case .rawValueEnum(_, let rawType): abiReturnType = rawType == .string ? nil : rawType.wasmCoreType case .associatedValueEnum: + append("ret.bridgeJSLowerReturn()") abiReturnType = nil case .namespaceEnum: abiReturnType = nil @@ -979,8 +1107,8 @@ public class ExportSwift { append("return Int32(ret.rawValue)") } } - case .associatedValueEnum: break; - case .namespaceEnum: break; + case .associatedValueEnum: break + case .namespaceEnum: break case .jsObject(nil): append( """ @@ -1204,6 +1332,147 @@ public class ExportSwift { } """ } + + func renderAssociatedValueEnumHelpers(_ enumDef: ExportedEnum) -> DeclSyntax { + let typeName = enumDef.swiftCallName + return """ + private extension \(raw: typeName) { + static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> \(raw: typeName) { + let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in + _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) + initializedCount = Int(paramsLen) + } + return params.withUnsafeBytes { raw in + var reader = _BJSBinaryReader(raw: raw) + switch caseId { + \(raw: generateBinaryLiftSwitchCases(enumDef: enumDef).joined(separator: "\n ")) + default: fatalError("Unknown \(raw: typeName) case ID: \\(caseId)") + } + } + } + + func bridgeJSLowerReturn() { + switch self { + \(raw: generateReturnSwitchCases(enumDef: enumDef).joined(separator: "\n ")) + } + } + } + """ + } + + func generateBinaryLiftSwitchCases(enumDef: ExportedEnum) -> [String] { + var cases: [String] = [] + for (caseIndex, enumCase) in enumDef.cases.enumerated() { + if enumCase.associatedValues.isEmpty { + cases.append("case \(caseIndex): return .\(enumCase.name)") + } else { + var lines: [String] = [] + lines.append("case \(caseIndex):") + lines.append("reader.readParamCount(expected: \(enumCase.associatedValues.count))") + var argList: [String] = [] + + for (paramIndex, associatedValue) in enumCase.associatedValues.enumerated() { + let paramName = associatedValue.label ?? "param\(paramIndex)" + argList.append(paramName) + + switch associatedValue.type { + case .string: + lines.append("reader.expectTag(.string)") + lines.append("let \(paramName) = reader.readString()") + case .int: + lines.append("reader.expectTag(.int32)") + lines.append("let \(paramName) = Int(reader.readInt32())") + case .bool: + lines.append("reader.expectTag(.bool)") + lines.append("let \(paramName) = Int32(reader.readUInt8()) != 0") + case .float: + lines.append("reader.expectTag(.float32)") + lines.append("let \(paramName) = reader.readFloat32()") + case .double: + lines.append("reader.expectTag(.float64)") + lines.append("let \(paramName) = reader.readFloat64()") + default: + lines.append("reader.expectTag(.int32)") + lines.append("let \(paramName) = reader.readInt32()") + } + } + + lines.append("return .\(enumCase.name)(\(argList.joined(separator: ", ")))") + cases.append(lines.joined(separator: "\n ")) + } + } + return cases + } + + func generateReturnSwitchCases(enumDef: ExportedEnum) -> [String] { + var cases: [String] = [] + for (caseIndex, enumCase) in enumDef.cases.enumerated() { + if enumCase.associatedValues.isEmpty { + cases.append(""" + case .\(enumCase.name): + _swift_js_return_tag(Int32(\(caseIndex))) + """) + } else { + var bodyLines: [String] = [] + bodyLines.append("_swift_js_return_tag(Int32(\(caseIndex)))") + for (i, av) in enumCase.associatedValues.enumerated() { + let paramName = av.label ?? "param\(i)" + switch av.type { + case .string: + bodyLines.append(""" + var __bjs_\(paramName) = \(paramName) + __bjs_\(paramName).withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + """) + case .int: + bodyLines.append("_swift_js_return_int(Int32(\(paramName)))") + case .bool: + bodyLines.append("_swift_js_return_bool(\(paramName) ? 1 : 0)") + case .float: + bodyLines.append("_swift_js_return_f32(\(paramName))") + case .double: + bodyLines.append("_swift_js_return_f64(\(paramName))") + default: + bodyLines.append("preconditionFailure(\"BridgeJS: unsupported associated value type in generated code\")") + } + } + let pattern = enumCase.associatedValues.enumerated().map { i, av in "let \(av.label ?? "param\(i)")" }.joined(separator: ", ") + cases.append(""" + case .\(enumCase.name)(\(pattern)): + \(bodyLines.joined(separator: "\n ")) + """) + } + } + return cases + } + + func renderCaseEnumHelpers(_ enumDef: ExportedEnum) -> DeclSyntax { + let typeName = enumDef.swiftCallName + var initCases: [String] = [] + var valueCases: [String] = [] + for (index, c) in enumDef.cases.enumerated() { + initCases.append("case \(index): self = .\(c.name)") + valueCases.append("case .\(c.name): return \(index)") + } + let initSwitch = (["switch bridgeJSRawValue {"] + initCases + ["default: return nil", "}"]).joined( + separator: "\n" + ) + let valueSwitch = (["switch self {"] + valueCases + ["}"]).joined(separator: "\n") + + return """ + extension \(raw: typeName) { + init?(bridgeJSRawValue: Int32) { + \(raw: initSwitch) + } + + var bridgeJSRawValue: Int32 { + \(raw: valueSwitch) + } + } + """ + } + } fileprivate enum Constants { diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/TypeDeclResolver.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/TypeDeclResolver.swift index a7b183af..d353a536 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/TypeDeclResolver.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/TypeDeclResolver.swift @@ -109,4 +109,26 @@ class TypeDeclResolver { func lookupType(fullyQualified: QualifiedName) -> TypeDecl? { return typeDeclByQualifiedName[fullyQualified] } + + /// Resolves a type usage (identifier or member type) to its declaration node + func resolve(_ type: TypeSyntax) -> TypeDecl? { + if let id = type.as(IdentifierTypeSyntax.self) { + return lookupType(for: id) + } + if let components = qualifiedComponents(from: type) { + return lookupType(fullyQualified: components) + } + return nil + } + + private func qualifiedComponents(from type: TypeSyntax) -> QualifiedName? { + if let m = type.as(MemberTypeSyntax.self) { + guard let base = qualifiedComponents(from: TypeSyntax(m.baseType)) else { return nil } + return base + [m.name.text] + } else if let id = type.as(IdentifierTypeSyntax.self) { + return [id.name.text] + } else { + return nil + } + } } diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift index 046cb92d..594c6042 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift @@ -70,8 +70,6 @@ struct BridgeJSLink { var namespacedFunctions: [ExportedFunction] = [] var namespacedClasses: [ExportedClass] = [] var namespacedEnums: [ExportedEnum] = [] - var enumConstantLines: [String] = [] - var dtsEnumLines: [String] = [] var topLevelEnumLines: [String] = [] var topLevelDtsEnumLines: [String] = [] @@ -88,6 +86,10 @@ struct BridgeJSLink { ) } + let hasAssociatedValueEnums = exportedSkeletons.contains { skeleton in + skeleton.enums.contains { $0.enumType == .associatedValue } + } + for skeleton in exportedSkeletons { for klass in skeleton.classes { let (jsType, dtsType, dtsExportEntry) = renderExportedClass(klass) @@ -120,12 +122,15 @@ struct BridgeJSLink { namespacedEnums.append(enumDefinition) } case .associatedValue: - enumConstantLines.append(contentsOf: jsEnum) - exportsLines.append("\(enumDefinition.name),") + var exportedJsEnum = jsEnum + if !exportedJsEnum.isEmpty && exportedJsEnum[0].hasPrefix("const ") { + exportedJsEnum[0] = "export " + exportedJsEnum[0] + } + topLevelEnumLines.append(contentsOf: exportedJsEnum) + topLevelDtsEnumLines.append(contentsOf: dtsEnum) if enumDefinition.namespace != nil { namespacedEnums.append(enumDefinition) } - dtsEnumLines.append(contentsOf: dtsEnum) } } } @@ -158,7 +163,7 @@ struct BridgeJSLink { importObjectBuilders.append(importObjectBuilder) } - let hasNamespacedItems = !namespacedFunctions.isEmpty || !namespacedClasses.isEmpty || !namespacedEnums.isEmpty + let hasNamespacedItems = !namespacedFunctions.isEmpty || !namespacedClasses.isEmpty let namespaceBuilder = NamespaceBuilder() let namespaceDeclarationsLines = namespaceBuilder.namespaceDeclarations( @@ -170,21 +175,15 @@ struct BridgeJSLink { let exportsSection: String if hasNamespacedItems { - let namespacedEnumsForExports = namespacedEnums.filter { $0.enumType == .associatedValue } let namespaceSetupCode = namespaceBuilder.renderGlobalNamespace( namespacedFunctions: namespacedFunctions, - namespacedClasses: namespacedClasses, - namespacedEnums: namespacedEnumsForExports + namespacedClasses: namespacedClasses ) .map { $0.indent(count: 12) }.joined(separator: "\n") - let enumSection = - enumConstantLines.isEmpty - ? "" : enumConstantLines.map { $0.indent(count: 12) }.joined(separator: "\n") + "\n" - exportsSection = """ \(classLines.map { $0.indent(count: 12) }.joined(separator: "\n")) - \(enumSection)\("const exports = {".indent(count: 12)) + \("const exports = {".indent(count: 12)) \(exportsLines.map { $0.indent(count: 16) }.joined(separator: "\n")) \("};".indent(count: 12)) @@ -194,13 +193,9 @@ struct BridgeJSLink { }, """ } else { - let enumSection = - enumConstantLines.isEmpty - ? "" : enumConstantLines.map { $0.indent(count: 12) }.joined(separator: "\n") + "\n" - exportsSection = """ \(classLines.map { $0.indent(count: 12) }.joined(separator: "\n")) - \(enumSection)\("return {".indent(count: 12)) + \("return {".indent(count: 12)) \(exportsLines.map { $0.indent(count: 16) }.joined(separator: "\n")) \("};".indent(count: 12)) }, @@ -208,12 +203,68 @@ struct BridgeJSLink { } let topLevelEnumsSection = topLevelEnumLines.isEmpty ? "" : topLevelEnumLines.joined(separator: "\n") + "\n\n" + let sharedEnumHelpersSection: String = { + guard hasAssociatedValueEnums else { return "" } + let lines: [String] = [ + "const __bjs_ParamType = { STRING: 1, INT32: 2, BOOL: 3, FLOAT32: 4, FLOAT64: 5 };", + "function __bjs_encodeEnumParams(textEncoder, swift, parts) {", + " const SIZE_U8 = 1, SIZE_U32 = 4, SIZE_F32 = 4, SIZE_F64 = 8;", + " let totalLen = SIZE_U32;", + " for (const p of parts) {", + " switch (p.t) {", + " case __bjs_ParamType.STRING: {", + " const bytes = textEncoder.encode(p.v);", + " p._bytes = bytes;", + " totalLen += SIZE_U8 + SIZE_U32 + bytes.length;", + " break;", + " }", + " case __bjs_ParamType.INT32: totalLen += SIZE_U8 + SIZE_U32; break;", + " case __bjs_ParamType.BOOL: totalLen += SIZE_U8 + SIZE_U8; break;", + " case __bjs_ParamType.FLOAT32: totalLen += SIZE_U8 + SIZE_F32; break;", + " case __bjs_ParamType.FLOAT64: totalLen += SIZE_U8 + SIZE_F64; break;", + " default: throw new Error(\"Unsupported param type tag: \" + p.t);", + " }", + " }", + " const buf = new Uint8Array(totalLen);", + " const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);", + " let off = 0;", + " view.setUint32(off, parts.length, true); off += SIZE_U32;", + " for (const p of parts) {", + " view.setUint8(off, p.t); off += SIZE_U8;", + " switch (p.t) {", + " case __bjs_ParamType.STRING: {", + " const b = p._bytes;", + " view.setUint32(off, b.length, true); off += SIZE_U32;", + " buf.set(b, off); off += b.length;", + " break;", + " }", + " case __bjs_ParamType.INT32:", + " view.setInt32(off, (p.v | 0), true); off += SIZE_U32; break;", + " case __bjs_ParamType.BOOL:", + " view.setUint8(off, p.v ? 1 : 0); off += SIZE_U8; break;", + " case __bjs_ParamType.FLOAT32:", + " view.setFloat32(off, Math.fround(p.v), true); off += SIZE_F32; break;", + " case __bjs_ParamType.FLOAT64:", + " view.setFloat64(off, p.v, true); off += SIZE_F64; break;", + " default: throw new Error(\"Unsupported param type tag: \" + p.t);", + " }", + " }", + " const paramsId = swift.memory.retain(buf);", + " return { paramsId, paramsLen: buf.length, cleanup: () => { swift.memory.release(paramsId); } };", + "}", + "", + ] + return lines.joined(separator: "\n") + }() let topLevelNamespaceCode = namespaceBuilder.renderTopLevelEnumNamespaceAssignments( namespacedEnums: namespacedEnums ) let namespaceAssignmentsSection = topLevelNamespaceCode.isEmpty ? "" : topLevelNamespaceCode.joined(separator: "\n") + "\n\n" + let enumHelpers = renderEnumHelperAssignments() + let enumHelpersSection = + enumHelpers.isEmpty ? "" : "\n\n" + enumHelpers.map { $0.indent(count: 12) }.joined(separator: "\n") let outputJs = """ // NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, @@ -222,7 +273,7 @@ struct BridgeJSLink { // To update this file, just rebuild your project or run // `swift package bridge-js`. - \(topLevelEnumsSection)\(namespaceAssignmentsSection)export async function createInstantiator(options, swift) { + \(sharedEnumHelpersSection)\(topLevelEnumsSection)\(namespaceAssignmentsSection)export async function createInstantiator(options, swift) { let instance; let memory; let setException; @@ -232,6 +283,14 @@ struct BridgeJSLink { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -242,7 +301,9 @@ struct BridgeJSLink { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len)\(sharedMemory ? ".slice()" : ""); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -267,12 +328,36 @@ struct BridgeJSLink { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } \(renderSwiftClassWrappers().map { $0.indent(count: 12) }.joined(separator: "\n")) \(importObjectBuilders.flatMap { $0.importedLines }.map { $0.indent(count: 12) }.joined(separator: "\n")) }, setInstance: (i) => { instance = i; - memory = instance.exports.memory; + memory = instance.exports.memory;\(enumHelpersSection) setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } @@ -288,7 +373,6 @@ struct BridgeJSLink { var dtsLines: [String] = [] dtsLines.append(contentsOf: namespaceDeclarationsLines) dtsLines.append(contentsOf: dtsClassLines) - dtsLines.append(contentsOf: dtsEnumLines) dtsLines.append(contentsOf: generateImportedTypeDefinitions()) dtsLines.append("export type Exports = {") dtsLines.append(contentsOf: dtsExportLines.map { $0.indent(count: 4) }) @@ -318,6 +402,24 @@ struct BridgeJSLink { return (outputJs, outputDts) } + private func renderEnumHelperAssignments() -> [String] { + var lines: [String] = [] + + for skeleton in exportedSkeletons { + for enumDef in skeleton.enums where enumDef.enumType == .associatedValue { + let base = enumDef.name + lines.append("const \(base)Helpers = __bjs_create\(base)Helpers()(textEncoder, swift);") + lines.append("globalThis.__bjs_lower_\(base) = (value) => \(base)Helpers.lower(value);") + lines.append( + "globalThis.__bjs_raise_\(base) = () => \(base)Helpers.raise(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools);" + ) + lines.append("") + } + } + + return lines + } + private func renderSwiftClassWrappers() -> [String] { var wrapperLines: [String] = [] var modulesByName: [String: [ExportedClass]] = [:] @@ -342,8 +444,8 @@ struct BridgeJSLink { for klass in classes { let wrapperFunctionName = "bjs_\(klass.name)_wrap" wrapperLines.append("importObject[\"\(moduleName)\"][\"\(wrapperFunctionName)\"] = function(pointer) {") - wrapperLines.append(" const obj = \(klass.name).__construct(pointer);") - wrapperLines.append(" return swift.memory.retain(obj);") + wrapperLines.append("const obj = \(klass.name).__construct(pointer);".indent(count: 4)) + wrapperLines.append("return swift.memory.retain(obj);".indent(count: 4)) wrapperLines.append("};") } } @@ -407,7 +509,7 @@ struct BridgeJSLink { parameterForwardings.append(bytesIdLabel) parameterForwardings.append("\(bytesLabel).length") case .caseEnum(_): - parameterForwardings.append("\(param.name) | 0") + parameterForwardings.append(param.name) case .rawValueEnum(_, let rawType): switch rawType { case .string: @@ -423,9 +525,19 @@ struct BridgeJSLink { default: parameterForwardings.append("\(param.name)") } - case .associatedValueEnum: - parameterForwardings.append("0") - parameterForwardings.append("0") + case .associatedValueEnum(let enumName): + let helperBase = enumName.components(separatedBy: ".").last ?? enumName + let caseIdName = "\(param.name)CaseId" + let paramsIdName = "\(param.name)ParamsId" + let paramsLenName = "\(param.name)ParamsLen" + let cleanupName = "\(param.name)Cleanup" + bodyLines.append( + "const { caseId: \(caseIdName), paramsId: \(paramsIdName), paramsLen: \(paramsLenName), cleanup: \(cleanupName) } = globalThis.__bjs_lower_\(helperBase)(\(param.name));" + ) + cleanupLines.append("if (\(cleanupName)) { \(cleanupName)(); }") + parameterForwardings.append(caseIdName) + parameterForwardings.append(paramsIdName) + parameterForwardings.append(paramsLenName) case .namespaceEnum: break case .jsObject: @@ -476,9 +588,11 @@ struct BridgeJSLink { bodyLines.append("const ret = \(call);") returnExpr = "ret" } - case .associatedValueEnum: + case .associatedValueEnum(let enumName): bodyLines.append("\(call);") - returnExpr = "\"\"" + let helperBase = enumName.components(separatedBy: ".").last ?? enumName + bodyLines.append("const ret = globalThis.__bjs_raise_\(helperBase)();") + returnExpr = "ret" case .namespaceEnum: break case .int, .float, .double: @@ -668,10 +782,184 @@ struct BridgeJSLink { dtsLines.append("") } } - case .associatedValue: - jsLines.append("// TODO: Implement \(enumDefinition.enumType) enum: \(enumDefinition.name)") - dtsLines.append("// TODO: Implement \(enumDefinition.enumType) enum: \(enumDefinition.name)") + do { + jsLines.append("const \(enumDefinition.name) = {") + jsLines.append("Tag: {".indent(count: 4)) + for (caseIndex, enumCase) in enumDefinition.cases.enumerated() { + let caseName = enumCase.name.capitalizedFirstLetter + jsLines.append("\(caseName): \(caseIndex),".indent(count: 8)) + } + jsLines.append("}".indent(count: 4)) + jsLines.append("};") + jsLines.append("") + jsLines.append("") + jsLines.append("const __bjs_create\(enumDefinition.name)Helpers = () => {") + jsLines.append("return (textEncoder, swift) => ({".indent(count: 4)) + + jsLines.append("lower: (value) => {".indent(count: 8)) + jsLines.append("const enumTag = value.tag;".indent(count: 12)) + jsLines.append("switch (enumTag) {".indent(count: 12)) + for (_, enumCase) in enumDefinition.cases.enumerated() { + let caseName = enumCase.name.capitalizedFirstLetter + if enumCase.associatedValues.isEmpty { + jsLines.append("case \(enumDefinition.name).Tag.\(caseName): {".indent(count: 16)) + jsLines.append("const parts = [];".indent(count: 20)) + jsLines.append( + "const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts);" + .indent(count: 20) + ) + jsLines.append( + "return { caseId: \(enumDefinition.name).Tag.\(caseName), paramsId, paramsLen, cleanup };" + .indent(count: 20) + ) + jsLines.append("}".indent(count: 16)) + } else { + jsLines.append("case \(enumDefinition.name).Tag.\(caseName): {".indent(count: 16)) + var partLines: [String] = [] + for (associatedValueIndex, associatedValue) in enumCase.associatedValues.enumerated() { + let prop = associatedValue.label ?? "param\(associatedValueIndex)" + switch associatedValue.type { + case .string: + partLines.append("{ t: __bjs_ParamType.STRING, v: value.\(prop) }") + case .int: + partLines.append("{ t: __bjs_ParamType.INT32, v: (value.\(prop) | 0) }") + case .bool: + partLines.append("{ t: __bjs_ParamType.BOOL, v: value.\(prop) }") + case .float: + partLines.append("{ t: __bjs_ParamType.FLOAT32, v: value.\(prop) }") + case .double: + partLines.append("{ t: __bjs_ParamType.FLOAT64, v: value.\(prop) }") + default: + partLines.append("{ t: __bjs_ParamType.INT32, v: 0 }") + } + } + jsLines.append("const parts = [".indent(count: 20)) + if !partLines.isEmpty { + for (i, pl) in partLines.enumerated() { + let suffix = i == partLines.count - 1 ? "" : "," + jsLines.append("\(pl)\(suffix)".indent(count: 24)) + } + } + jsLines.append("];".indent(count: 20)) + jsLines.append( + "const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts);" + .indent(count: 20) + ) + jsLines.append( + "return { caseId: \(enumDefinition.name).Tag.\(caseName), paramsId, paramsLen, cleanup };" + .indent(count: 20) + ) + jsLines.append("}".indent(count: 16)) + } + } + jsLines.append( + "default: throw new Error(\"Unknown \(enumDefinition.name) tag: \" + String(enumTag));".indent( + count: 16 + ) + ) + jsLines.append("}".indent(count: 12)) + jsLines.append("},".indent(count: 8)) + + jsLines.append( + "raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools) => {".indent( + count: 8 + ) + ) + jsLines.append("const tag = tmpRetTag | 0;".indent(count: 12)) + jsLines.append("switch (tag) {".indent(count: 12)) + for (_, enumCase) in enumDefinition.cases.enumerated() { + let caseName = enumCase.name.capitalizedFirstLetter + if enumCase.associatedValues.isEmpty { + jsLines.append( + "case \(enumDefinition.name).Tag.\(caseName): return { tag: \(enumDefinition.name).Tag.\(caseName) };" + .indent(count: 16) + ) + } else { + var fields: [String] = ["tag: \(enumDefinition.name).Tag.\(caseName)"] + var stringIndex = 0 + var intIndex = 0 + var f32Index = 0 + var f64Index = 0 + var boolIndex = 0 + for (associatedValueIndex, associatedValue) in enumCase.associatedValues.enumerated() { + let prop = associatedValue.label ?? "param\(associatedValueIndex)" + switch associatedValue.type { + case .string: + fields.append("\(prop): tmpRetStrings[\(stringIndex)]") + stringIndex += 1 + case .bool: + fields.append("\(prop): tmpRetBools[\(boolIndex)]") + boolIndex += 1 + case .int: + fields.append("\(prop): tmpRetInts[\(intIndex)]") + intIndex += 1 + case .float: + fields.append("\(prop): tmpRetF32s[\(f32Index)]") + f32Index += 1 + case .double: + fields.append("\(prop): tmpRetF64s[\(f64Index)]") + f64Index += 1 + default: + fields.append("\(prop): undefined") + } + } + jsLines.append( + "case \(enumDefinition.name).Tag.\(caseName): return { \(fields.joined(separator: ", ")) };" + .indent(count: 16) + ) + } + } + jsLines.append( + "default: throw new Error(\"Unknown \(enumDefinition.name) tag returned from Swift: \" + String(tag));" + .indent( + count: 16 + ) + ) + jsLines.append("}".indent(count: 12)) + jsLines.append("}".indent(count: 8)) + jsLines.append("});".indent(count: 4)) + jsLines.append("};") + + if enumDefinition.namespace == nil { + dtsLines.append("export const \(enumDefinition.name): {") + dtsLines.append("readonly Tag: {".indent(count: 4)) + for (caseIndex, enumCase) in enumDefinition.cases.enumerated() { + let caseName = enumCase.name.capitalizedFirstLetter + dtsLines.append("readonly \(caseName): \(caseIndex);".indent(count: 8)) + } + dtsLines.append("};".indent(count: 4)) + dtsLines.append("};") + dtsLines.append("") + var unionParts: [String] = [] + for enumCase in enumDefinition.cases { + if enumCase.associatedValues.isEmpty { + unionParts.append( + "{ tag: typeof \(enumDefinition.name).Tag.\(enumCase.name.capitalizedFirstLetter) }" + ) + } else { + var fields: [String] = [ + "tag: typeof \(enumDefinition.name).Tag.\(enumCase.name.capitalizedFirstLetter)" + ] + for (associatedValueIndex, associatedValue) in enumCase.associatedValues.enumerated() { + let prop = associatedValue.label ?? "param\(associatedValueIndex)" + let ts: String + switch associatedValue.type { + case .string: ts = "string" + case .bool: ts = "boolean" + case .int, .float, .double: ts = "number" + default: ts = "never" + } + fields.append("\(prop): \(ts)") + } + unionParts.append("{ \(fields.joined(separator: "; ")) }") + } + } + dtsLines.append("export type \(enumDefinition.name) =") + dtsLines.append(" " + unionParts.joined(separator: " | ")) + dtsLines.append("") + } + } case .namespace: break } @@ -1010,8 +1298,7 @@ struct BridgeJSLink { /// - Returns: Array of JavaScript code lines that set up the global namespace structure func renderGlobalNamespace( namespacedFunctions: [ExportedFunction], - namespacedClasses: [ExportedClass], - namespacedEnums: [ExportedEnum] + namespacedClasses: [ExportedClass] ) -> [String] { var lines: [String] = [] var uniqueNamespaces: [String] = [] @@ -1025,15 +1312,10 @@ struct BridgeJSLink { namespacedClasses .compactMap { $0.namespace } ) - let enumNamespacePaths: Set<[String]> = Set( - namespacedEnums - .compactMap { $0.namespace } - ) let allNamespacePaths = functionNamespacePaths .union(classNamespacePaths) - .union(enumNamespacePaths) allNamespacePaths.forEach { namespacePath in namespacePath.makeIterator().enumerated().forEach { (index, _) in @@ -1055,11 +1337,6 @@ struct BridgeJSLink { lines.append("globalThis.\(namespacePath).\(klass.name) = exports.\(klass.name);") } - namespacedEnums.forEach { enumDefinition in - let namespacePath: String = enumDefinition.namespace?.joined(separator: ".") ?? "" - lines.append("globalThis.\(namespacePath).\(enumDefinition.name) = exports.\(enumDefinition.name);") - } - namespacedFunctions.forEach { function in let namespacePath: String = function.namespace?.joined(separator: ".") ?? "" lines.append("globalThis.\(namespacePath).\(function.name) = exports.\(function.name);") @@ -1069,15 +1346,13 @@ struct BridgeJSLink { } func renderTopLevelEnumNamespaceAssignments(namespacedEnums: [ExportedEnum]) -> [String] { - let topLevelNamespacedEnums = namespacedEnums.filter { $0.enumType == .simple || $0.enumType == .rawValue } - - guard !topLevelNamespacedEnums.isEmpty else { return [] } + guard !namespacedEnums.isEmpty else { return [] } var lines: [String] = [] var uniqueNamespaces: [String] = [] var seen = Set() - for enumDef in topLevelNamespacedEnums { + for enumDef in namespacedEnums { guard let namespacePath = enumDef.namespace else { continue } namespacePath.enumerated().forEach { (index, _) in let path = namespacePath[0...index].joined(separator: ".") @@ -1098,7 +1373,7 @@ struct BridgeJSLink { lines.append("") } - for enumDef in topLevelNamespacedEnums { + for enumDef in namespacedEnums { let namespacePath = enumDef.namespace?.joined(separator: ".") ?? "" lines.append("globalThis.\(namespacePath).\(enumDef.name) = \(enumDef.name);") } @@ -1237,7 +1512,9 @@ struct BridgeJSLink { for (index, enumCase) in enumDefinition.cases.enumerated() { let caseName = enumCase.name.capitalizedFirstLetter dtsLines.append( - "\(caseName) = \(index),".indent(count: identBaseSize * (contentDepth + 1)) + "readonly \(caseName): \(index);".indent( + count: identBaseSize * (contentDepth + 1) + ) ) } dtsLines.append("}".indent(count: identBaseSize * contentDepth)) @@ -1309,7 +1586,53 @@ struct BridgeJSLink { .indent(count: identBaseSize * contentDepth) ) } - case .associatedValue, .namespace: + case .associatedValue: + dtsLines.append( + "const \(enumDefinition.name): {".indent(count: identBaseSize * contentDepth) + ) + dtsLines.append("readonly Tag: {".indent(count: identBaseSize * (contentDepth + 1))) + for (caseIndex, enumCase) in enumDefinition.cases.enumerated() { + let caseName = enumCase.name.capitalizedFirstLetter + dtsLines.append( + "readonly \(caseName): \(caseIndex);".indent( + count: identBaseSize * (contentDepth + 2) + ) + ) + } + dtsLines.append("};".indent(count: identBaseSize * (contentDepth + 1))) + dtsLines.append("};".indent(count: identBaseSize * contentDepth)) + + var unionParts: [String] = [] + for enumCase in enumDefinition.cases { + if enumCase.associatedValues.isEmpty { + unionParts.append( + "{ tag: typeof \(enumDefinition.name).Tag.\(enumCase.name.capitalizedFirstLetter) }" + ) + } else { + var fields: [String] = [ + "tag: typeof \(enumDefinition.name).Tag.\(enumCase.name.capitalizedFirstLetter)" + ] + for (associatedValueIndex, associatedValue) in enumCase.associatedValues + .enumerated() + { + let prop = associatedValue.label ?? "param\(associatedValueIndex)" + let ts: String + switch associatedValue.type { + case .string: ts = "string" + case .bool: ts = "boolean" + case .int, .float, .double: ts = "number" + default: ts = "never" + } + fields.append("\(prop): \(ts)") + } + unionParts.append("{ \(fields.joined(separator: "; ")) }") + } + } + dtsLines.append("type \(enumDefinition.name) =".indent(count: identBaseSize * contentDepth)) + dtsLines.append( + " " + unionParts.joined(separator: " | ").indent(count: identBaseSize * contentDepth) + ) + case .namespace: continue } } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/EnumAssociatedValue.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/EnumAssociatedValue.swift new file mode 100644 index 00000000..08d03a2b --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/EnumAssociatedValue.swift @@ -0,0 +1,40 @@ +@JS +enum APIResult { + case success(String) + case failure(Int) + case flag(Bool) + case rate(Float) + case precise(Double) + case info +} + +@JS func handle(result: APIResult) +@JS func getResult() -> APIResult + +@JS +enum ComplexResult { + case success(String) + case error(String, Int) + case status(Bool, Int, String) + case coordinates(Double, Double, Double) + case comprehensive(Bool, Bool, Int, Int, Double, Double, String, String, String) + case info +} + +@JS func handleComplex(result: ComplexResult) +@JS func getComplexResult() -> ComplexResult + +@JS +enum Utilities { + @JS enum Result { + case success(String) + case failure(String, Int) + case status(Bool, Int, String) + } +} + +@JS(namespace: "API") +@JS enum NetworkingResult { + case success(String) + case failure(String, Int) +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayParameter.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayParameter.Import.js index c122f179..53bd2084 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayParameter.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayParameter.Import.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_checkArray"] = function bjs_checkArray(a) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Export.js index 1da2f58e..1f2b957d 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Export.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Import.js index 21d11fa4..4d1a2e2e 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Import.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_asyncReturnVoid"] = function bjs_asyncReturnVoid() { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts new file mode 100644 index 00000000..4d7394b4 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts @@ -0,0 +1,75 @@ +// 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 const APIResult: { + readonly Tag: { + readonly Success: 0; + readonly Failure: 1; + readonly Flag: 2; + readonly Rate: 3; + readonly Precise: 4; + readonly Info: 5; + }; +}; + +export type APIResult = + { tag: typeof APIResult.Tag.Success; param0: string } | { tag: typeof APIResult.Tag.Failure; param0: number } | { tag: typeof APIResult.Tag.Flag; param0: boolean } | { tag: typeof APIResult.Tag.Rate; param0: number } | { tag: typeof APIResult.Tag.Precise; param0: number } | { tag: typeof APIResult.Tag.Info } + +export const ComplexResult: { + readonly Tag: { + readonly Success: 0; + readonly Error: 1; + readonly Status: 2; + readonly Coordinates: 3; + readonly Comprehensive: 4; + readonly Info: 5; + }; +}; + +export type ComplexResult = + { tag: typeof ComplexResult.Tag.Success; param0: string } | { tag: typeof ComplexResult.Tag.Error; param0: string; param1: number } | { tag: typeof ComplexResult.Tag.Status; param0: boolean; param1: number; param2: string } | { tag: typeof ComplexResult.Tag.Coordinates; param0: number; param1: number; param2: number } | { tag: typeof ComplexResult.Tag.Comprehensive; param0: boolean; param1: boolean; param2: number; param3: number; param4: number; param5: number; param6: string; param7: string; param8: string } | { tag: typeof ComplexResult.Tag.Info } + +export {}; + +declare global { + namespace API { + const NetworkingResult: { + readonly Tag: { + readonly Success: 0; + readonly Failure: 1; + }; + }; + type NetworkingResult = + { tag: typeof NetworkingResult.Tag.Success; param0: string } | { tag: typeof NetworkingResult.Tag.Failure; param0: string; param1: number } + } + namespace Utilities { + const Result: { + readonly Tag: { + readonly Success: 0; + readonly Failure: 1; + readonly Status: 2; + }; + }; + type Result = + { tag: typeof Result.Tag.Success; param0: string } | { tag: typeof Result.Tag.Failure; param0: string; param1: number } | { tag: typeof Result.Tag.Status; param0: boolean; param1: number; param2: string } + } +} + +export type Exports = { + handle(result: APIResult): void; + getResult(): APIResult; + handleComplex(result: ComplexResult): void; + getComplexResult(): ComplexResult; +} +export type Imports = { +} +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/EnumAssociatedValue.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.js new file mode 100644 index 00000000..ae114f63 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.js @@ -0,0 +1,452 @@ +// 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`. + +const __bjs_ParamType = { STRING: 1, INT32: 2, BOOL: 3, FLOAT32: 4, FLOAT64: 5 }; +function __bjs_encodeEnumParams(textEncoder, swift, parts) { + const SIZE_U8 = 1, SIZE_U32 = 4, SIZE_F32 = 4, SIZE_F64 = 8; + let totalLen = SIZE_U32; + for (const p of parts) { + switch (p.t) { + case __bjs_ParamType.STRING: { + const bytes = textEncoder.encode(p.v); + p._bytes = bytes; + totalLen += SIZE_U8 + SIZE_U32 + bytes.length; + break; + } + case __bjs_ParamType.INT32: totalLen += SIZE_U8 + SIZE_U32; break; + case __bjs_ParamType.BOOL: totalLen += SIZE_U8 + SIZE_U8; break; + case __bjs_ParamType.FLOAT32: totalLen += SIZE_U8 + SIZE_F32; break; + case __bjs_ParamType.FLOAT64: totalLen += SIZE_U8 + SIZE_F64; break; + default: throw new Error("Unsupported param type tag: " + p.t); + } + } + const buf = new Uint8Array(totalLen); + const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength); + let off = 0; + view.setUint32(off, parts.length, true); off += SIZE_U32; + for (const p of parts) { + view.setUint8(off, p.t); off += SIZE_U8; + switch (p.t) { + case __bjs_ParamType.STRING: { + const b = p._bytes; + view.setUint32(off, b.length, true); off += SIZE_U32; + buf.set(b, off); off += b.length; + break; + } + case __bjs_ParamType.INT32: + view.setInt32(off, (p.v | 0), true); off += SIZE_U32; break; + case __bjs_ParamType.BOOL: + view.setUint8(off, p.v ? 1 : 0); off += SIZE_U8; break; + case __bjs_ParamType.FLOAT32: + view.setFloat32(off, Math.fround(p.v), true); off += SIZE_F32; break; + case __bjs_ParamType.FLOAT64: + view.setFloat64(off, p.v, true); off += SIZE_F64; break; + default: throw new Error("Unsupported param type tag: " + p.t); + } + } + const paramsId = swift.memory.retain(buf); + return { paramsId, paramsLen: buf.length, cleanup: () => { swift.memory.release(paramsId); } }; +} +export const APIResult = { + Tag: { + Success: 0, + Failure: 1, + Flag: 2, + Rate: 3, + Precise: 4, + Info: 5, + } +}; + + +const __bjs_createAPIResultHelpers = () => { + return (textEncoder, swift) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case APIResult.Tag.Success: { + const parts = [ + { t: __bjs_ParamType.STRING, v: value.param0 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: APIResult.Tag.Success, paramsId, paramsLen, cleanup }; + } + case APIResult.Tag.Failure: { + const parts = [ + { t: __bjs_ParamType.INT32, v: (value.param0 | 0) } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: APIResult.Tag.Failure, paramsId, paramsLen, cleanup }; + } + case APIResult.Tag.Flag: { + const parts = [ + { t: __bjs_ParamType.BOOL, v: value.param0 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: APIResult.Tag.Flag, paramsId, paramsLen, cleanup }; + } + case APIResult.Tag.Rate: { + const parts = [ + { t: __bjs_ParamType.FLOAT32, v: value.param0 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: APIResult.Tag.Rate, paramsId, paramsLen, cleanup }; + } + case APIResult.Tag.Precise: { + const parts = [ + { t: __bjs_ParamType.FLOAT64, v: value.param0 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: APIResult.Tag.Precise, paramsId, paramsLen, cleanup }; + } + case APIResult.Tag.Info: { + const parts = []; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: APIResult.Tag.Info, paramsId, paramsLen, cleanup }; + } + default: throw new Error("Unknown APIResult tag: " + String(enumTag)); + } + }, + raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools) => { + const tag = tmpRetTag | 0; + switch (tag) { + case APIResult.Tag.Success: return { tag: APIResult.Tag.Success, param0: tmpRetStrings[0] }; + case APIResult.Tag.Failure: return { tag: APIResult.Tag.Failure, param0: tmpRetInts[0] }; + case APIResult.Tag.Flag: return { tag: APIResult.Tag.Flag, param0: tmpRetBools[0] }; + case APIResult.Tag.Rate: return { tag: APIResult.Tag.Rate, param0: tmpRetF32s[0] }; + case APIResult.Tag.Precise: return { tag: APIResult.Tag.Precise, param0: tmpRetF64s[0] }; + case APIResult.Tag.Info: return { tag: APIResult.Tag.Info }; + default: throw new Error("Unknown APIResult tag returned from Swift: " + String(tag)); + } + } + }); +}; +export const ComplexResult = { + Tag: { + Success: 0, + Error: 1, + Status: 2, + Coordinates: 3, + Comprehensive: 4, + Info: 5, + } +}; + + +const __bjs_createComplexResultHelpers = () => { + return (textEncoder, swift) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case ComplexResult.Tag.Success: { + const parts = [ + { t: __bjs_ParamType.STRING, v: value.param0 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: ComplexResult.Tag.Success, paramsId, paramsLen, cleanup }; + } + case ComplexResult.Tag.Error: { + const parts = [ + { t: __bjs_ParamType.STRING, v: value.param0 }, + { t: __bjs_ParamType.INT32, v: (value.param1 | 0) } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: ComplexResult.Tag.Error, paramsId, paramsLen, cleanup }; + } + case ComplexResult.Tag.Status: { + const parts = [ + { t: __bjs_ParamType.BOOL, v: value.param0 }, + { t: __bjs_ParamType.INT32, v: (value.param1 | 0) }, + { t: __bjs_ParamType.STRING, v: value.param2 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: ComplexResult.Tag.Status, paramsId, paramsLen, cleanup }; + } + case ComplexResult.Tag.Coordinates: { + const parts = [ + { t: __bjs_ParamType.FLOAT64, v: value.param0 }, + { t: __bjs_ParamType.FLOAT64, v: value.param1 }, + { t: __bjs_ParamType.FLOAT64, v: value.param2 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: ComplexResult.Tag.Coordinates, paramsId, paramsLen, cleanup }; + } + case ComplexResult.Tag.Comprehensive: { + const parts = [ + { t: __bjs_ParamType.BOOL, v: value.param0 }, + { t: __bjs_ParamType.BOOL, v: value.param1 }, + { t: __bjs_ParamType.INT32, v: (value.param2 | 0) }, + { t: __bjs_ParamType.INT32, v: (value.param3 | 0) }, + { t: __bjs_ParamType.FLOAT64, v: value.param4 }, + { t: __bjs_ParamType.FLOAT64, v: value.param5 }, + { t: __bjs_ParamType.STRING, v: value.param6 }, + { t: __bjs_ParamType.STRING, v: value.param7 }, + { t: __bjs_ParamType.STRING, v: value.param8 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: ComplexResult.Tag.Comprehensive, paramsId, paramsLen, cleanup }; + } + case ComplexResult.Tag.Info: { + const parts = []; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: ComplexResult.Tag.Info, paramsId, paramsLen, cleanup }; + } + default: throw new Error("Unknown ComplexResult tag: " + String(enumTag)); + } + }, + raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools) => { + const tag = tmpRetTag | 0; + switch (tag) { + case ComplexResult.Tag.Success: return { tag: ComplexResult.Tag.Success, param0: tmpRetStrings[0] }; + case ComplexResult.Tag.Error: return { tag: ComplexResult.Tag.Error, param0: tmpRetStrings[0], param1: tmpRetInts[0] }; + case ComplexResult.Tag.Status: return { tag: ComplexResult.Tag.Status, param0: tmpRetBools[0], param1: tmpRetInts[0], param2: tmpRetStrings[0] }; + case ComplexResult.Tag.Coordinates: return { tag: ComplexResult.Tag.Coordinates, param0: tmpRetF64s[0], param1: tmpRetF64s[1], param2: tmpRetF64s[2] }; + case ComplexResult.Tag.Comprehensive: return { tag: ComplexResult.Tag.Comprehensive, param0: tmpRetBools[0], param1: tmpRetBools[1], param2: tmpRetInts[0], param3: tmpRetInts[1], param4: tmpRetF64s[0], param5: tmpRetF64s[1], param6: tmpRetStrings[0], param7: tmpRetStrings[1], param8: tmpRetStrings[2] }; + case ComplexResult.Tag.Info: return { tag: ComplexResult.Tag.Info }; + default: throw new Error("Unknown ComplexResult tag returned from Swift: " + String(tag)); + } + } + }); +}; +export const Result = { + Tag: { + Success: 0, + Failure: 1, + Status: 2, + } +}; + + +const __bjs_createResultHelpers = () => { + return (textEncoder, swift) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case Result.Tag.Success: { + const parts = [ + { t: __bjs_ParamType.STRING, v: value.param0 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: Result.Tag.Success, paramsId, paramsLen, cleanup }; + } + case Result.Tag.Failure: { + const parts = [ + { t: __bjs_ParamType.STRING, v: value.param0 }, + { t: __bjs_ParamType.INT32, v: (value.param1 | 0) } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: Result.Tag.Failure, paramsId, paramsLen, cleanup }; + } + case Result.Tag.Status: { + const parts = [ + { t: __bjs_ParamType.BOOL, v: value.param0 }, + { t: __bjs_ParamType.INT32, v: (value.param1 | 0) }, + { t: __bjs_ParamType.STRING, v: value.param2 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: Result.Tag.Status, paramsId, paramsLen, cleanup }; + } + default: throw new Error("Unknown Result tag: " + String(enumTag)); + } + }, + raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools) => { + const tag = tmpRetTag | 0; + switch (tag) { + case Result.Tag.Success: return { tag: Result.Tag.Success, param0: tmpRetStrings[0] }; + case Result.Tag.Failure: return { tag: Result.Tag.Failure, param0: tmpRetStrings[0], param1: tmpRetInts[0] }; + case Result.Tag.Status: return { tag: Result.Tag.Status, param0: tmpRetBools[0], param1: tmpRetInts[0], param2: tmpRetStrings[0] }; + default: throw new Error("Unknown Result tag returned from Swift: " + String(tag)); + } + } + }); +}; +export const NetworkingResult = { + Tag: { + Success: 0, + Failure: 1, + } +}; + + +const __bjs_createNetworkingResultHelpers = () => { + return (textEncoder, swift) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case NetworkingResult.Tag.Success: { + const parts = [ + { t: __bjs_ParamType.STRING, v: value.param0 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: NetworkingResult.Tag.Success, paramsId, paramsLen, cleanup }; + } + case NetworkingResult.Tag.Failure: { + const parts = [ + { t: __bjs_ParamType.STRING, v: value.param0 }, + { t: __bjs_ParamType.INT32, v: (value.param1 | 0) } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: NetworkingResult.Tag.Failure, paramsId, paramsLen, cleanup }; + } + default: throw new Error("Unknown NetworkingResult tag: " + String(enumTag)); + } + }, + raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools) => { + const tag = tmpRetTag | 0; + switch (tag) { + case NetworkingResult.Tag.Success: return { tag: NetworkingResult.Tag.Success, param0: tmpRetStrings[0] }; + case NetworkingResult.Tag.Failure: return { tag: NetworkingResult.Tag.Failure, param0: tmpRetStrings[0], param1: tmpRetInts[0] }; + default: throw new Error("Unknown NetworkingResult tag returned from Swift: " + String(tag)); + } + } + }); +}; + +if (typeof globalThis.Utilities === 'undefined') { + globalThis.Utilities = {}; +} +if (typeof globalThis.API === 'undefined') { + globalThis.API = {}; +} + +globalThis.Utilities.Result = Result; +globalThis.API.NetworkingResult = NetworkingResult; + +export async function createInstantiator(options, swift) { + let instance; + let memory; + let setException; + const textDecoder = new TextDecoder("utf-8"); + const textEncoder = new TextEncoder("utf-8"); + + let tmpRetString; + let tmpRetBytes; + let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { + /** + * @param {WebAssembly.Imports} importObject + */ + addImports: (importObject, importsContext) => { + const bjs = {}; + importObject["bjs"] = bjs; + const imports = options.getImports(importsContext); + bjs["swift_js_return_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + return swift.memory.retain(textDecoder.decode(bytes)); + } + 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_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } + + + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + const APIResultHelpers = __bjs_createAPIResultHelpers()(textEncoder, swift); + globalThis.__bjs_lower_APIResult = (value) => APIResultHelpers.lower(value); + globalThis.__bjs_raise_APIResult = () => APIResultHelpers.raise(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools); + + const ComplexResultHelpers = __bjs_createComplexResultHelpers()(textEncoder, swift); + globalThis.__bjs_lower_ComplexResult = (value) => ComplexResultHelpers.lower(value); + globalThis.__bjs_raise_ComplexResult = () => ComplexResultHelpers.raise(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools); + + const ResultHelpers = __bjs_createResultHelpers()(textEncoder, swift); + globalThis.__bjs_lower_Result = (value) => ResultHelpers.lower(value); + globalThis.__bjs_raise_Result = () => ResultHelpers.raise(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools); + + const NetworkingResultHelpers = __bjs_createNetworkingResultHelpers()(textEncoder, swift); + globalThis.__bjs_lower_NetworkingResult = (value) => NetworkingResultHelpers.lower(value); + globalThis.__bjs_raise_NetworkingResult = () => NetworkingResultHelpers.raise(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools); + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + + return { + handle: function bjs_handle(result) { + const { caseId: resultCaseId, paramsId: resultParamsId, paramsLen: resultParamsLen, cleanup: resultCleanup } = globalThis.__bjs_lower_APIResult(result); + instance.exports.bjs_handle(resultCaseId, resultParamsId, resultParamsLen); + if (resultCleanup) { resultCleanup(); } + }, + getResult: function bjs_getResult() { + instance.exports.bjs_getResult(); + const ret = globalThis.__bjs_raise_APIResult(); + return ret; + }, + handleComplex: function bjs_handleComplex(result) { + const { caseId: resultCaseId, paramsId: resultParamsId, paramsLen: resultParamsLen, cleanup: resultCleanup } = globalThis.__bjs_lower_ComplexResult(result); + instance.exports.bjs_handleComplex(resultCaseId, resultParamsId, resultParamsLen); + if (resultCleanup) { resultCleanup(); } + }, + getComplexResult: function bjs_getComplexResult() { + instance.exports.bjs_getComplexResult(); + const ret = globalThis.__bjs_raise_ComplexResult(); + return ret; + }, + }; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.Export.js index 3e080948..cc204376 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.Export.js @@ -35,6 +35,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -45,7 +53,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -70,6 +80,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } }, @@ -86,18 +120,18 @@ export async function createInstantiator(options, swift) { return { setDirection: function bjs_setDirection(direction) { - instance.exports.bjs_setDirection(direction | 0); + instance.exports.bjs_setDirection(direction); }, getDirection: function bjs_getDirection() { const ret = instance.exports.bjs_getDirection(); return ret; }, processDirection: function bjs_processDirection(input) { - const ret = instance.exports.bjs_processDirection(input | 0); + const ret = instance.exports.bjs_processDirection(input); return ret; }, setTSDirection: function bjs_setTSDirection(direction) { - instance.exports.bjs_setTSDirection(direction | 0); + instance.exports.bjs_setTSDirection(direction); }, getTSDirection: function bjs_getTSDirection() { const ret = instance.exports.bjs_getTSDirection(); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js index 12613dd8..7819d612 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js @@ -61,6 +61,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -71,7 +79,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -96,6 +106,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } // Wrapper functions for module: TestModule if (!importObject["TestModule"]) { importObject["TestModule"] = {}; @@ -171,7 +205,7 @@ export async function createInstantiator(options, swift) { return HTTPServer.__construct(ret); } call(method) { - instance.exports.bjs_HTTPServer_call(this.pointer, method | 0); + instance.exports.bjs_HTTPServer_call(this.pointer, method); } } class TestServer extends SwiftHeapObject { @@ -185,7 +219,7 @@ export async function createInstantiator(options, swift) { return TestServer.__construct(ret); } call(method) { - instance.exports.bjs_TestServer_call(this.pointer, method | 0); + instance.exports.bjs_TestServer_call(this.pointer, method); } } const exports = { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.Export.js index 68a2b19f..f44c7c8a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.Export.js @@ -90,6 +90,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -100,7 +108,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -125,6 +135,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Interface.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Interface.Import.js index f81c7e47..4bca5872 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Interface.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Interface.Import.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_returnAnimatable"] = function bjs_returnAnimatable() { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MultipleImportedTypes.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MultipleImportedTypes.Import.js index 394d996b..8335235a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MultipleImportedTypes.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MultipleImportedTypes.Import.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_createDatabaseConnection"] = function bjs_createDatabaseConnection(config) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js index 6915a61a..1682c4d2 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } // Wrapper functions for module: TestModule if (!importObject["TestModule"]) { importObject["TestModule"] = {}; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js index 4873fc33..6dd6b163 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js index 3b93b2dd..4c66f1dc 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_check"] = function bjs_check(a, b) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js index 53332b97..88c55eac 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js index 1892eb46..e7ea8533 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_checkNumber"] = function bjs_checkNumber() { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Export.js index ea47fb55..21a0a88b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Export.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Import.js index 16ed1081..f656f84e 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Import.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_checkString"] = function bjs_checkString(a) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Export.js index f98cea55..0b3ac72f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Export.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Import.js index 3220ae7b..cf9e864c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Import.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_checkString"] = function bjs_checkString() { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js index ab4caba3..589d6544 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } // Wrapper functions for module: TestModule if (!importObject["TestModule"]) { importObject["TestModule"] = {}; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TS2SkeletonLike.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TS2SkeletonLike.Import.js index 705c6a37..498c9844 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TS2SkeletonLike.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TS2SkeletonLike.Import.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_createTS2Skeleton"] = function bjs_createTS2Skeleton() { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.Export.js index b2089962..6d755a7b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.Export.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeAlias.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeAlias.Import.js index 2eb9dee5..04226bd9 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeAlias.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeAlias.Import.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_checkSimple"] = function bjs_checkSimple(a) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js index c7d622ea..8e0f0ac7 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_Greeter_init"] = function bjs_Greeter_init(name) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Export.js index c200c077..514a9910 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Export.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Import.js index ca497688..e92d3f09 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Import.js @@ -14,6 +14,14 @@ export async function createInstantiator(options, swift) { let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +32,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +59,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_check"] = function bjs_check() { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json new file mode 100644 index 00000000..1eeca1b8 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json @@ -0,0 +1,435 @@ +{ + "classes" : [ + + ], + "enums" : [ + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "failure" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + + } + } + } + ], + "name" : "flag" + }, + { + "associatedValues" : [ + { + "type" : { + "float" : { + + } + } + } + ], + "name" : "rate" + }, + { + "associatedValues" : [ + { + "type" : { + "double" : { + + } + } + } + ], + "name" : "precise" + }, + { + "associatedValues" : [ + + ], + "name" : "info" + } + ], + "emitStyle" : "const", + "name" : "APIResult", + "swiftCallName" : "APIResult" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "error" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "status" + }, + { + "associatedValues" : [ + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + } + ], + "name" : "coordinates" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + + } + } + }, + { + "type" : { + "bool" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "comprehensive" + }, + { + "associatedValues" : [ + + ], + "name" : "info" + } + ], + "emitStyle" : "const", + "name" : "ComplexResult", + "swiftCallName" : "ComplexResult" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "failure" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "status" + } + ], + "emitStyle" : "const", + "name" : "Result", + "namespace" : [ + "Utilities" + ], + "swiftCallName" : "Utilities.Result" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "failure" + } + ], + "emitStyle" : "const", + "name" : "NetworkingResult", + "namespace" : [ + "API" + ], + "swiftCallName" : "NetworkingResult" + } + ], + "functions" : [ + { + "abiName" : "bjs_handle", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "handle", + "parameters" : [ + { + "label" : "result", + "name" : "result", + "type" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + } + ], + "returnType" : { + "void" : { + + } + } + }, + { + "abiName" : "bjs_getResult", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "getResult", + "parameters" : [ + + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + }, + { + "abiName" : "bjs_handleComplex", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "handleComplex", + "parameters" : [ + { + "label" : "result", + "name" : "result", + "type" : { + "associatedValueEnum" : { + "_0" : "ComplexResult" + } + } + } + ], + "returnType" : { + "void" : { + + } + } + }, + { + "abiName" : "bjs_getComplexResult", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "getComplexResult", + "parameters" : [ + + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "ComplexResult" + } + } + } + ], + "moduleName" : "TestModule" +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.swift new file mode 100644 index 00000000..27d52b01 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.swift @@ -0,0 +1,449 @@ +// 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`. + +@_spi(BridgeJS) import JavaScriptKit + +fileprivate enum _BJSParamType: UInt8 { + case string = 1 + case int32 = 2 + case bool = 3 + case float32 = 4 + case float64 = 5 +} + +fileprivate struct _BJSBinaryReader { + let raw: UnsafeRawBufferPointer + var offset: Int = 0 + + @inline(__always) + mutating func readUInt8() -> UInt8 { + let b = raw[offset] + offset += 1 + return b + } + + @inline(__always) + mutating func readUInt32() -> UInt32 { + var v = UInt32(0) + withUnsafeMutableBytes(of: &v) { dst in + dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 4)])) + } + offset += 4 + return UInt32(littleEndian: v) + } + + @inline(__always) + mutating func readInt32() -> Int32 { + var v = Int32(0) + withUnsafeMutableBytes(of: &v) { dst in + dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 4)])) + } + offset += 4 + return Int32(littleEndian: v) + } + + @inline(__always) + mutating func readFloat32() -> Float32 { + var bits = UInt32(0) + withUnsafeMutableBytes(of: &bits) { dst in + dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 4)])) + } + offset += 4 + return Float32(bitPattern: UInt32(littleEndian: bits)) + } + + @inline(__always) + mutating func readFloat64() -> Float64 { + var bits = UInt64(0) + withUnsafeMutableBytes(of: &bits) { dst in + dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 8)])) + } + offset += 8 + return Float64(bitPattern: UInt64(littleEndian: bits)) + } + + @inline(__always) + mutating func readString() -> String { + let len = Int(readUInt32()) + let s = String(decoding: UnsafeBufferPointer( + start: raw.baseAddress!.advanced(by: offset).assumingMemoryBound(to: UInt8.self), + count: len + ), as: UTF8.self) + offset += len + return s + } + + @inline(__always) + mutating func expectTag(_ expected: _BJSParamType) { + let rawTag = readUInt8() + guard let got = _BJSParamType(rawValue: rawTag), got == expected else { + preconditionFailure("BridgeJS: mismatched enum param tag. Expected \(expected) got \(String(describing: _BJSParamType(rawValue: rawTag)))") + } + } + + @inline(__always) + mutating func readParamCount(expected: Int) { + let count = Int(readUInt32()) + precondition(count == expected, "BridgeJS: mismatched enum param count. Expected \(expected) got \(count)") + } +} + +@_extern(wasm, module: "bjs", name: "swift_js_init_memory") +func _swift_js_init_memory(_: Int32, _: UnsafeMutablePointer) + +@_extern(wasm, module: "bjs", name: "swift_js_return_tag") +func _swift_js_return_tag(_: Int32) +@_extern(wasm, module: "bjs", name: "swift_js_return_string") +func _swift_js_return_string(_: UnsafePointer?, _: Int32) +@_extern(wasm, module: "bjs", name: "swift_js_return_int") +func _swift_js_return_int(_: Int32) +@_extern(wasm, module: "bjs", name: "swift_js_return_f32") +func _swift_js_return_f32(_: Float32) +@_extern(wasm, module: "bjs", name: "swift_js_return_f64") +func _swift_js_return_f64(_: Float64) +@_extern(wasm, module: "bjs", name: "swift_js_return_bool") +func _swift_js_return_bool(_: Int32) + +private extension APIResult { + static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> APIResult { + let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in + _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) + initializedCount = Int(paramsLen) + } + return params.withUnsafeBytes { raw in + var reader = _BJSBinaryReader(raw: raw) + switch caseId { + case 0: + reader.readParamCount(expected: 1) + reader.expectTag(.string) + let param0 = reader.readString() + return .success(param0) + case 1: + reader.readParamCount(expected: 1) + reader.expectTag(.int32) + let param0 = Int(reader.readInt32()) + return .failure(param0) + case 2: + reader.readParamCount(expected: 1) + reader.expectTag(.bool) + let param0 = Int32(reader.readUInt8()) != 0 + return .flag(param0) + case 3: + reader.readParamCount(expected: 1) + reader.expectTag(.float32) + let param0 = reader.readFloat32() + return .rate(param0) + case 4: + reader.readParamCount(expected: 1) + reader.expectTag(.float64) + let param0 = reader.readFloat64() + return .precise(param0) + case 5: + return .info + default: + fatalError("Unknown APIResult case ID: \(caseId)") + } + } + } + + func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_return_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .failure(let param0): + _swift_js_return_tag(Int32(1)) + _swift_js_return_int(Int32(param0)) + case .flag(let param0): + _swift_js_return_tag(Int32(2)) + _swift_js_return_bool(param0 ? 1 : 0) + case .rate(let param0): + _swift_js_return_tag(Int32(3)) + _swift_js_return_f32(param0) + case .precise(let param0): + _swift_js_return_tag(Int32(4)) + _swift_js_return_f64(param0) + case .info: + _swift_js_return_tag(Int32(5)) + } + } +} + +private extension ComplexResult { + static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> ComplexResult { + let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in + _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) + initializedCount = Int(paramsLen) + } + return params.withUnsafeBytes { raw in + var reader = _BJSBinaryReader(raw: raw) + switch caseId { + case 0: + reader.readParamCount(expected: 1) + reader.expectTag(.string) + let param0 = reader.readString() + return .success(param0) + case 1: + reader.readParamCount(expected: 2) + reader.expectTag(.string) + let param0 = reader.readString() + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + return .error(param0, param1) + case 2: + reader.readParamCount(expected: 3) + reader.expectTag(.bool) + let param0 = Int32(reader.readUInt8()) != 0 + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + reader.expectTag(.string) + let param2 = reader.readString() + return .status(param0, param1, param2) + case 3: + reader.readParamCount(expected: 3) + reader.expectTag(.float64) + let param0 = reader.readFloat64() + reader.expectTag(.float64) + let param1 = reader.readFloat64() + reader.expectTag(.float64) + let param2 = reader.readFloat64() + return .coordinates(param0, param1, param2) + case 4: + reader.readParamCount(expected: 9) + reader.expectTag(.bool) + let param0 = Int32(reader.readUInt8()) != 0 + reader.expectTag(.bool) + let param1 = Int32(reader.readUInt8()) != 0 + reader.expectTag(.int32) + let param2 = Int(reader.readInt32()) + reader.expectTag(.int32) + let param3 = Int(reader.readInt32()) + reader.expectTag(.float64) + let param4 = reader.readFloat64() + reader.expectTag(.float64) + let param5 = reader.readFloat64() + reader.expectTag(.string) + let param6 = reader.readString() + reader.expectTag(.string) + let param7 = reader.readString() + reader.expectTag(.string) + let param8 = reader.readString() + return .comprehensive(param0, param1, param2, param3, param4, param5, param6, param7, param8) + case 5: + return .info + default: + fatalError("Unknown ComplexResult case ID: \(caseId)") + } + } + } + + func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_return_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .error(let param0, let param1): + _swift_js_return_tag(Int32(1)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + _swift_js_return_int(Int32(param1)) + case .status(let param0, let param1, let param2): + _swift_js_return_tag(Int32(2)) + _swift_js_return_bool(param0 ? 1 : 0) + _swift_js_return_int(Int32(param1)) + var __bjs_param2 = param2 + __bjs_param2.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .coordinates(let param0, let param1, let param2): + _swift_js_return_tag(Int32(3)) + _swift_js_return_f64(param0) + _swift_js_return_f64(param1) + _swift_js_return_f64(param2) + case .comprehensive(let param0, let param1, let param2, let param3, let param4, let param5, let param6, let param7, let param8): + _swift_js_return_tag(Int32(4)) + _swift_js_return_bool(param0 ? 1 : 0) + _swift_js_return_bool(param1 ? 1 : 0) + _swift_js_return_int(Int32(param2)) + _swift_js_return_int(Int32(param3)) + _swift_js_return_f64(param4) + _swift_js_return_f64(param5) + var __bjs_param6 = param6 + __bjs_param6.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + var __bjs_param7 = param7 + __bjs_param7.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + var __bjs_param8 = param8 + __bjs_param8.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .info: + _swift_js_return_tag(Int32(5)) + } + } +} + +private extension Utilities.Result { + static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> Utilities.Result { + let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in + _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) + initializedCount = Int(paramsLen) + } + return params.withUnsafeBytes { raw in + var reader = _BJSBinaryReader(raw: raw) + switch caseId { + case 0: + reader.readParamCount(expected: 1) + reader.expectTag(.string) + let param0 = reader.readString() + return .success(param0) + case 1: + reader.readParamCount(expected: 2) + reader.expectTag(.string) + let param0 = reader.readString() + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + return .failure(param0, param1) + case 2: + reader.readParamCount(expected: 3) + reader.expectTag(.bool) + let param0 = Int32(reader.readUInt8()) != 0 + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + reader.expectTag(.string) + let param2 = reader.readString() + return .status(param0, param1, param2) + default: + fatalError("Unknown Utilities.Result case ID: \(caseId)") + } + } + } + + func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_return_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .failure(let param0, let param1): + _swift_js_return_tag(Int32(1)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + _swift_js_return_int(Int32(param1)) + case .status(let param0, let param1, let param2): + _swift_js_return_tag(Int32(2)) + _swift_js_return_bool(param0 ? 1 : 0) + _swift_js_return_int(Int32(param1)) + var __bjs_param2 = param2 + __bjs_param2.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + } + } +} + +private extension NetworkingResult { + static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> NetworkingResult { + let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in + _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) + initializedCount = Int(paramsLen) + } + return params.withUnsafeBytes { raw in + var reader = _BJSBinaryReader(raw: raw) + switch caseId { + case 0: + reader.readParamCount(expected: 1) + reader.expectTag(.string) + let param0 = reader.readString() + return .success(param0) + case 1: + reader.readParamCount(expected: 2) + reader.expectTag(.string) + let param0 = reader.readString() + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + return .failure(param0, param1) + default: + fatalError("Unknown NetworkingResult case ID: \(caseId)") + } + } + } + + func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_return_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .failure(let param0, let param1): + _swift_js_return_tag(Int32(1)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + _swift_js_return_int(Int32(param1)) + } + } +} + +@_expose(wasm, "bjs_handle") +@_cdecl("bjs_handle") +public func _bjs_handle(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { + #if arch(wasm32) + handle(result: APIResult.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_getResult") +@_cdecl("bjs_getResult") +public func _bjs_getResult() -> Void { + #if arch(wasm32) + let ret = getResult() + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_handleComplex") +@_cdecl("bjs_handleComplex") +public func _bjs_handleComplex(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { + #if arch(wasm32) + handleComplex(result: ComplexResult.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_getComplexResult") +@_cdecl("bjs_getComplexResult") +public func _bjs_getComplexResult() -> Void { + #if arch(wasm32) + let ret = getComplexResult() + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} \ No newline at end of file diff --git a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift index bd080623..e01b6665 100644 --- a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift +++ b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift @@ -270,6 +270,143 @@ enum Internal { } } +@JS enum APIResult { + case success(String) + case failure(Int) + case flag(Bool) + case rate(Float) + case precise(Double) + case info +} + +@JS func echoAPIResult(result: APIResult) -> APIResult { + return result +} + +@JS func makeAPIResultSuccess(_ value: String) -> APIResult { + return .success(value) +} + +@JS func makeAPIResultFailure(_ value: Int) -> APIResult { + return .failure(value) +} + +@JS func makeAPIResultInfo() -> APIResult { + return .info +} + +@JS func makeAPIResultFlag(_ value: Bool) -> APIResult { + return .flag(value) +} + +@JS func makeAPIResultRate(_ value: Float) -> APIResult { + return .rate(value) +} + +@JS func makeAPIResultPrecise(_ value: Double) -> APIResult { + return .precise(value) +} + +@JS +enum ComplexResult { + case success(String) + case error(String, Int) + case location(Double, Double, String) + case status(Bool, Int, String) + case coordinates(Double, Double, Double) + case comprehensive(Bool, Bool, Int, Int, Double, Double, String, String, String) + case info +} + +@JS func echoComplexResult(result: ComplexResult) -> ComplexResult { + return result +} + +@JS func makeComplexResultSuccess(_ value: String) -> ComplexResult { + return .success(value) +} + +@JS func makeComplexResultError(_ message: String, _ code: Int) -> ComplexResult { + return .error(message, code) +} + +@JS func makeComplexResultLocation(_ lat: Double, _ lng: Double, _ name: String) -> ComplexResult { + return .location(lat, lng, name) +} + +@JS func makeComplexResultStatus(_ active: Bool, _ code: Int, _ message: String) -> ComplexResult { + return .status(active, code, message) +} + +@JS func makeComplexResultCoordinates(_ x: Double, _ y: Double, _ z: Double) -> ComplexResult { + return .coordinates(x, y, z) +} + +@JS func makeComplexResultComprehensive( + _ flag1: Bool, + _ flag2: Bool, + _ count1: Int, + _ count2: Int, + _ value1: Double, + _ value2: Double, + _ text1: String, + _ text2: String, + _ text3: String +) -> ComplexResult { + return .comprehensive(flag1, flag2, count1, count2, value1, value2, text1, text2, text3) +} + +@JS func makeComplexResultInfo() -> ComplexResult { + return .info +} + +@JS func roundtripComplexResult(_ result: ComplexResult) -> ComplexResult { + return result +} + +@JS enum Utilities { + @JS enum Result { + case success(String) + case failure(String, Int) + case status(Bool, Int, String) + } +} + +@JS enum API { + @JS enum NetworkingResult { + case success(String) + case failure(String, Int) + } +} + +@JS func makeUtilitiesResultSuccess(_ message: String) -> Utilities.Result { + return .success(message) +} + +@JS func makeUtilitiesResultFailure(_ error: String, _ code: Int) -> Utilities.Result { + return .failure(error, code) +} + +@JS func makeUtilitiesResultStatus(_ active: Bool, _ code: Int, _ message: String) -> Utilities.Result { + return .status(active, code, message) +} + +@JS func makeAPINetworkingResultSuccess(_ message: String) -> API.NetworkingResult { + return .success(message) +} + +@JS func makeAPINetworkingResultFailure(_ error: String, _ code: Int) -> API.NetworkingResult { + return .failure(error, code) +} + +@JS func roundtripUtilitiesResult(_ result: Utilities.Result) -> Utilities.Result { + return result +} + +@JS func roundtripAPINetworkingResult(_ result: API.NetworkingResult) -> API.NetworkingResult { + return result +} + class ExportAPITests: XCTestCase { func testAll() { var hasDeinitGreeter = false diff --git a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift index 15e1cfc5..f016aa9d 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift @@ -6,6 +6,107 @@ @_spi(BridgeJS) import JavaScriptKit +fileprivate enum _BJSParamType: UInt8 { + case string = 1 + case int32 = 2 + case bool = 3 + case float32 = 4 + case float64 = 5 +} + +fileprivate struct _BJSBinaryReader { + let raw: UnsafeRawBufferPointer + var offset: Int = 0 + + @inline(__always) + mutating func readUInt8() -> UInt8 { + let b = raw[offset] + offset += 1 + return b + } + + @inline(__always) + mutating func readUInt32() -> UInt32 { + var v = UInt32(0) + withUnsafeMutableBytes(of: &v) { dst in + dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 4)])) + } + offset += 4 + return UInt32(littleEndian: v) + } + + @inline(__always) + mutating func readInt32() -> Int32 { + var v = Int32(0) + withUnsafeMutableBytes(of: &v) { dst in + dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 4)])) + } + offset += 4 + return Int32(littleEndian: v) + } + + @inline(__always) + mutating func readFloat32() -> Float32 { + var bits = UInt32(0) + withUnsafeMutableBytes(of: &bits) { dst in + dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 4)])) + } + offset += 4 + return Float32(bitPattern: UInt32(littleEndian: bits)) + } + + @inline(__always) + mutating func readFloat64() -> Float64 { + var bits = UInt64(0) + withUnsafeMutableBytes(of: &bits) { dst in + dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 8)])) + } + offset += 8 + return Float64(bitPattern: UInt64(littleEndian: bits)) + } + + @inline(__always) + mutating func readString() -> String { + let len = Int(readUInt32()) + let s = String(decoding: UnsafeBufferPointer( + start: raw.baseAddress!.advanced(by: offset).assumingMemoryBound(to: UInt8.self), + count: len + ), as: UTF8.self) + offset += len + return s + } + + @inline(__always) + mutating func expectTag(_ expected: _BJSParamType) { + let rawTag = readUInt8() + guard let got = _BJSParamType(rawValue: rawTag), got == expected else { + preconditionFailure("BridgeJS: mismatched enum param tag. Expected \(expected) got \(String(describing: _BJSParamType(rawValue: rawTag)))") + } + } + + @inline(__always) + mutating func readParamCount(expected: Int) { + let count = Int(readUInt32()) + precondition(count == expected, "BridgeJS: mismatched enum param count. Expected \(expected) got \(count)") + } +} + +@_extern(wasm, module: "bjs", name: "swift_js_init_memory") +func _swift_js_init_memory(_: Int32, _: UnsafeMutablePointer) + +@_extern(wasm, module: "bjs", name: "swift_js_return_tag") +func _swift_js_return_tag(_: Int32) +@_extern(wasm, module: "bjs", name: "swift_js_return_string") +func _swift_js_return_string(_: UnsafePointer?, _: Int32) +@_extern(wasm, module: "bjs", name: "swift_js_return_int") +func _swift_js_return_int(_: Int32) +@_extern(wasm, module: "bjs", name: "swift_js_return_f32") +func _swift_js_return_f32(_: Float32) +@_extern(wasm, module: "bjs", name: "swift_js_return_f64") +func _swift_js_return_f64(_: Float64) +@_extern(wasm, module: "bjs", name: "swift_js_return_bool") +func _swift_js_return_bool(_: Int32) + extension Direction { init?(bridgeJSRawValue: Int32) { switch bridgeJSRawValue { @@ -144,6 +245,322 @@ extension Internal.SupportedMethod { } } +private extension APIResult { + static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> APIResult { + let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in + _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) + initializedCount = Int(paramsLen) + } + return params.withUnsafeBytes { raw in + var reader = _BJSBinaryReader(raw: raw) + switch caseId { + case 0: + reader.readParamCount(expected: 1) + reader.expectTag(.string) + let param0 = reader.readString() + return .success(param0) + case 1: + reader.readParamCount(expected: 1) + reader.expectTag(.int32) + let param0 = Int(reader.readInt32()) + return .failure(param0) + case 2: + reader.readParamCount(expected: 1) + reader.expectTag(.bool) + let param0 = Int32(reader.readUInt8()) != 0 + return .flag(param0) + case 3: + reader.readParamCount(expected: 1) + reader.expectTag(.float32) + let param0 = reader.readFloat32() + return .rate(param0) + case 4: + reader.readParamCount(expected: 1) + reader.expectTag(.float64) + let param0 = reader.readFloat64() + return .precise(param0) + case 5: + return .info + default: + fatalError("Unknown APIResult case ID: \(caseId)") + } + } + } + + func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_return_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .failure(let param0): + _swift_js_return_tag(Int32(1)) + _swift_js_return_int(Int32(param0)) + case .flag(let param0): + _swift_js_return_tag(Int32(2)) + _swift_js_return_bool(param0 ? 1 : 0) + case .rate(let param0): + _swift_js_return_tag(Int32(3)) + _swift_js_return_f32(param0) + case .precise(let param0): + _swift_js_return_tag(Int32(4)) + _swift_js_return_f64(param0) + case .info: + _swift_js_return_tag(Int32(5)) + } + } +} + +private extension ComplexResult { + static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> ComplexResult { + let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in + _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) + initializedCount = Int(paramsLen) + } + return params.withUnsafeBytes { raw in + var reader = _BJSBinaryReader(raw: raw) + switch caseId { + case 0: + reader.readParamCount(expected: 1) + reader.expectTag(.string) + let param0 = reader.readString() + return .success(param0) + case 1: + reader.readParamCount(expected: 2) + reader.expectTag(.string) + let param0 = reader.readString() + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + return .error(param0, param1) + case 2: + reader.readParamCount(expected: 3) + reader.expectTag(.float64) + let param0 = reader.readFloat64() + reader.expectTag(.float64) + let param1 = reader.readFloat64() + reader.expectTag(.string) + let param2 = reader.readString() + return .location(param0, param1, param2) + case 3: + reader.readParamCount(expected: 3) + reader.expectTag(.bool) + let param0 = Int32(reader.readUInt8()) != 0 + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + reader.expectTag(.string) + let param2 = reader.readString() + return .status(param0, param1, param2) + case 4: + reader.readParamCount(expected: 3) + reader.expectTag(.float64) + let param0 = reader.readFloat64() + reader.expectTag(.float64) + let param1 = reader.readFloat64() + reader.expectTag(.float64) + let param2 = reader.readFloat64() + return .coordinates(param0, param1, param2) + case 5: + reader.readParamCount(expected: 9) + reader.expectTag(.bool) + let param0 = Int32(reader.readUInt8()) != 0 + reader.expectTag(.bool) + let param1 = Int32(reader.readUInt8()) != 0 + reader.expectTag(.int32) + let param2 = Int(reader.readInt32()) + reader.expectTag(.int32) + let param3 = Int(reader.readInt32()) + reader.expectTag(.float64) + let param4 = reader.readFloat64() + reader.expectTag(.float64) + let param5 = reader.readFloat64() + reader.expectTag(.string) + let param6 = reader.readString() + reader.expectTag(.string) + let param7 = reader.readString() + reader.expectTag(.string) + let param8 = reader.readString() + return .comprehensive(param0, param1, param2, param3, param4, param5, param6, param7, param8) + case 6: + return .info + default: + fatalError("Unknown ComplexResult case ID: \(caseId)") + } + } + } + + func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_return_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .error(let param0, let param1): + _swift_js_return_tag(Int32(1)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + _swift_js_return_int(Int32(param1)) + case .location(let param0, let param1, let param2): + _swift_js_return_tag(Int32(2)) + _swift_js_return_f64(param0) + _swift_js_return_f64(param1) + var __bjs_param2 = param2 + __bjs_param2.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .status(let param0, let param1, let param2): + _swift_js_return_tag(Int32(3)) + _swift_js_return_bool(param0 ? 1 : 0) + _swift_js_return_int(Int32(param1)) + var __bjs_param2 = param2 + __bjs_param2.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .coordinates(let param0, let param1, let param2): + _swift_js_return_tag(Int32(4)) + _swift_js_return_f64(param0) + _swift_js_return_f64(param1) + _swift_js_return_f64(param2) + case .comprehensive(let param0, let param1, let param2, let param3, let param4, let param5, let param6, let param7, let param8): + _swift_js_return_tag(Int32(5)) + _swift_js_return_bool(param0 ? 1 : 0) + _swift_js_return_bool(param1 ? 1 : 0) + _swift_js_return_int(Int32(param2)) + _swift_js_return_int(Int32(param3)) + _swift_js_return_f64(param4) + _swift_js_return_f64(param5) + var __bjs_param6 = param6 + __bjs_param6.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + var __bjs_param7 = param7 + __bjs_param7.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + var __bjs_param8 = param8 + __bjs_param8.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .info: + _swift_js_return_tag(Int32(6)) + } + } +} + +private extension Utilities.Result { + static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> Utilities.Result { + let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in + _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) + initializedCount = Int(paramsLen) + } + return params.withUnsafeBytes { raw in + var reader = _BJSBinaryReader(raw: raw) + switch caseId { + case 0: + reader.readParamCount(expected: 1) + reader.expectTag(.string) + let param0 = reader.readString() + return .success(param0) + case 1: + reader.readParamCount(expected: 2) + reader.expectTag(.string) + let param0 = reader.readString() + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + return .failure(param0, param1) + case 2: + reader.readParamCount(expected: 3) + reader.expectTag(.bool) + let param0 = Int32(reader.readUInt8()) != 0 + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + reader.expectTag(.string) + let param2 = reader.readString() + return .status(param0, param1, param2) + default: + fatalError("Unknown Utilities.Result case ID: \(caseId)") + } + } + } + + func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_return_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .failure(let param0, let param1): + _swift_js_return_tag(Int32(1)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + _swift_js_return_int(Int32(param1)) + case .status(let param0, let param1, let param2): + _swift_js_return_tag(Int32(2)) + _swift_js_return_bool(param0 ? 1 : 0) + _swift_js_return_int(Int32(param1)) + var __bjs_param2 = param2 + __bjs_param2.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + } + } +} + +private extension API.NetworkingResult { + static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> API.NetworkingResult { + let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in + _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) + initializedCount = Int(paramsLen) + } + return params.withUnsafeBytes { raw in + var reader = _BJSBinaryReader(raw: raw) + switch caseId { + case 0: + reader.readParamCount(expected: 1) + reader.expectTag(.string) + let param0 = reader.readString() + return .success(param0) + case 1: + reader.readParamCount(expected: 2) + reader.expectTag(.string) + let param0 = reader.readString() + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + return .failure(param0, param1) + default: + fatalError("Unknown API.NetworkingResult case ID: \(caseId)") + } + } + } + + func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_return_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .failure(let param0, let param1): + _swift_js_return_tag(Int32(1)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + _swift_js_return_int(Int32(param1)) + } + } +} + @_expose(wasm, "bjs_roundTripVoid") @_cdecl("bjs_roundTripVoid") public func _bjs_roundTripVoid() -> Void { @@ -771,6 +1188,311 @@ public func _bjs_getTSTheme() -> Void { #endif } +@_expose(wasm, "bjs_echoAPIResult") +@_cdecl("bjs_echoAPIResult") +public func _bjs_echoAPIResult(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { + #if arch(wasm32) + let ret = echoAPIResult(result: APIResult.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeAPIResultSuccess") +@_cdecl("bjs_makeAPIResultSuccess") +public func _bjs_makeAPIResultSuccess(valueBytes: Int32, valueLen: Int32) -> Void { + #if arch(wasm32) + let value = String(unsafeUninitializedCapacity: Int(valueLen)) { b in + _swift_js_init_memory(valueBytes, b.baseAddress.unsafelyUnwrapped) + return Int(valueLen) + } + let ret = makeAPIResultSuccess(_: value) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeAPIResultFailure") +@_cdecl("bjs_makeAPIResultFailure") +public func _bjs_makeAPIResultFailure(value: Int32) -> Void { + #if arch(wasm32) + let ret = makeAPIResultFailure(_: Int(value)) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeAPIResultInfo") +@_cdecl("bjs_makeAPIResultInfo") +public func _bjs_makeAPIResultInfo() -> Void { + #if arch(wasm32) + let ret = makeAPIResultInfo() + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeAPIResultFlag") +@_cdecl("bjs_makeAPIResultFlag") +public func _bjs_makeAPIResultFlag(value: Int32) -> Void { + #if arch(wasm32) + let ret = makeAPIResultFlag(_: value == 1) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeAPIResultRate") +@_cdecl("bjs_makeAPIResultRate") +public func _bjs_makeAPIResultRate(value: Float32) -> Void { + #if arch(wasm32) + let ret = makeAPIResultRate(_: value) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeAPIResultPrecise") +@_cdecl("bjs_makeAPIResultPrecise") +public func _bjs_makeAPIResultPrecise(value: Float64) -> Void { + #if arch(wasm32) + let ret = makeAPIResultPrecise(_: value) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_echoComplexResult") +@_cdecl("bjs_echoComplexResult") +public func _bjs_echoComplexResult(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { + #if arch(wasm32) + let ret = echoComplexResult(result: ComplexResult.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeComplexResultSuccess") +@_cdecl("bjs_makeComplexResultSuccess") +public func _bjs_makeComplexResultSuccess(valueBytes: Int32, valueLen: Int32) -> Void { + #if arch(wasm32) + let value = String(unsafeUninitializedCapacity: Int(valueLen)) { b in + _swift_js_init_memory(valueBytes, b.baseAddress.unsafelyUnwrapped) + return Int(valueLen) + } + let ret = makeComplexResultSuccess(_: value) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeComplexResultError") +@_cdecl("bjs_makeComplexResultError") +public func _bjs_makeComplexResultError(messageBytes: Int32, messageLen: Int32, code: Int32) -> Void { + #if arch(wasm32) + let message = String(unsafeUninitializedCapacity: Int(messageLen)) { b in + _swift_js_init_memory(messageBytes, b.baseAddress.unsafelyUnwrapped) + return Int(messageLen) + } + let ret = makeComplexResultError(_: message, _: Int(code)) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeComplexResultLocation") +@_cdecl("bjs_makeComplexResultLocation") +public func _bjs_makeComplexResultLocation(lat: Float64, lng: Float64, nameBytes: Int32, nameLen: Int32) -> Void { + #if arch(wasm32) + let name = String(unsafeUninitializedCapacity: Int(nameLen)) { b in + _swift_js_init_memory(nameBytes, b.baseAddress.unsafelyUnwrapped) + return Int(nameLen) + } + let ret = makeComplexResultLocation(_: lat, _: lng, _: name) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeComplexResultStatus") +@_cdecl("bjs_makeComplexResultStatus") +public func _bjs_makeComplexResultStatus(active: Int32, code: Int32, messageBytes: Int32, messageLen: Int32) -> Void { + #if arch(wasm32) + let message = String(unsafeUninitializedCapacity: Int(messageLen)) { b in + _swift_js_init_memory(messageBytes, b.baseAddress.unsafelyUnwrapped) + return Int(messageLen) + } + let ret = makeComplexResultStatus(_: active == 1, _: Int(code), _: message) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeComplexResultCoordinates") +@_cdecl("bjs_makeComplexResultCoordinates") +public func _bjs_makeComplexResultCoordinates(x: Float64, y: Float64, z: Float64) -> Void { + #if arch(wasm32) + let ret = makeComplexResultCoordinates(_: x, _: y, _: z) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeComplexResultComprehensive") +@_cdecl("bjs_makeComplexResultComprehensive") +public func _bjs_makeComplexResultComprehensive(flag1: Int32, flag2: Int32, count1: Int32, count2: Int32, value1: Float64, value2: Float64, text1Bytes: Int32, text1Len: Int32, text2Bytes: Int32, text2Len: Int32, text3Bytes: Int32, text3Len: Int32) -> Void { + #if arch(wasm32) + let text1 = String(unsafeUninitializedCapacity: Int(text1Len)) { b in + _swift_js_init_memory(text1Bytes, b.baseAddress.unsafelyUnwrapped) + return Int(text1Len) + } + let text2 = String(unsafeUninitializedCapacity: Int(text2Len)) { b in + _swift_js_init_memory(text2Bytes, b.baseAddress.unsafelyUnwrapped) + return Int(text2Len) + } + let text3 = String(unsafeUninitializedCapacity: Int(text3Len)) { b in + _swift_js_init_memory(text3Bytes, b.baseAddress.unsafelyUnwrapped) + return Int(text3Len) + } + let ret = makeComplexResultComprehensive(_: flag1 == 1, _: flag2 == 1, _: Int(count1), _: Int(count2), _: value1, _: value2, _: text1, _: text2, _: text3) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeComplexResultInfo") +@_cdecl("bjs_makeComplexResultInfo") +public func _bjs_makeComplexResultInfo() -> Void { + #if arch(wasm32) + let ret = makeComplexResultInfo() + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_roundtripComplexResult") +@_cdecl("bjs_roundtripComplexResult") +public func _bjs_roundtripComplexResult(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { + #if arch(wasm32) + let ret = roundtripComplexResult(_: ComplexResult.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeUtilitiesResultSuccess") +@_cdecl("bjs_makeUtilitiesResultSuccess") +public func _bjs_makeUtilitiesResultSuccess(messageBytes: Int32, messageLen: Int32) -> Void { + #if arch(wasm32) + let message = String(unsafeUninitializedCapacity: Int(messageLen)) { b in + _swift_js_init_memory(messageBytes, b.baseAddress.unsafelyUnwrapped) + return Int(messageLen) + } + let ret = makeUtilitiesResultSuccess(_: message) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeUtilitiesResultFailure") +@_cdecl("bjs_makeUtilitiesResultFailure") +public func _bjs_makeUtilitiesResultFailure(errorBytes: Int32, errorLen: Int32, code: Int32) -> Void { + #if arch(wasm32) + let error = String(unsafeUninitializedCapacity: Int(errorLen)) { b in + _swift_js_init_memory(errorBytes, b.baseAddress.unsafelyUnwrapped) + return Int(errorLen) + } + let ret = makeUtilitiesResultFailure(_: error, _: Int(code)) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeUtilitiesResultStatus") +@_cdecl("bjs_makeUtilitiesResultStatus") +public func _bjs_makeUtilitiesResultStatus(active: Int32, code: Int32, messageBytes: Int32, messageLen: Int32) -> Void { + #if arch(wasm32) + let message = String(unsafeUninitializedCapacity: Int(messageLen)) { b in + _swift_js_init_memory(messageBytes, b.baseAddress.unsafelyUnwrapped) + return Int(messageLen) + } + let ret = makeUtilitiesResultStatus(_: active == 1, _: Int(code), _: message) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeAPINetworkingResultSuccess") +@_cdecl("bjs_makeAPINetworkingResultSuccess") +public func _bjs_makeAPINetworkingResultSuccess(messageBytes: Int32, messageLen: Int32) -> Void { + #if arch(wasm32) + let message = String(unsafeUninitializedCapacity: Int(messageLen)) { b in + _swift_js_init_memory(messageBytes, b.baseAddress.unsafelyUnwrapped) + return Int(messageLen) + } + let ret = makeAPINetworkingResultSuccess(_: message) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeAPINetworkingResultFailure") +@_cdecl("bjs_makeAPINetworkingResultFailure") +public func _bjs_makeAPINetworkingResultFailure(errorBytes: Int32, errorLen: Int32, code: Int32) -> Void { + #if arch(wasm32) + let error = String(unsafeUninitializedCapacity: Int(errorLen)) { b in + _swift_js_init_memory(errorBytes, b.baseAddress.unsafelyUnwrapped) + return Int(errorLen) + } + let ret = makeAPINetworkingResultFailure(_: error, _: Int(code)) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_roundtripUtilitiesResult") +@_cdecl("bjs_roundtripUtilitiesResult") +public func _bjs_roundtripUtilitiesResult(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { + #if arch(wasm32) + let ret = roundtripUtilitiesResult(_: Utilities.Result.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_roundtripAPINetworkingResult") +@_cdecl("bjs_roundtripAPINetworkingResult") +public func _bjs_roundtripAPINetworkingResult(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { + #if arch(wasm32) + let ret = roundtripAPINetworkingResult(_: API.NetworkingResult.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + @_expose(wasm, "bjs_Greeter_init") @_cdecl("bjs_Greeter_init") public func _bjs_Greeter_init(nameBytes: Int32, nameLen: Int32) -> UnsafeMutableRawPointer { diff --git a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json index b4642d8a..6d53232f 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json +++ b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json @@ -572,356 +572,1349 @@ "Internal" ], "swiftCallName" : "Internal.SupportedMethod" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "failure" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + + } + } + } + ], + "name" : "flag" + }, + { + "associatedValues" : [ + { + "type" : { + "float" : { + + } + } + } + ], + "name" : "rate" + }, + { + "associatedValues" : [ + { + "type" : { + "double" : { + + } + } + } + ], + "name" : "precise" + }, + { + "associatedValues" : [ + + ], + "name" : "info" + } + ], + "emitStyle" : "const", + "name" : "APIResult", + "swiftCallName" : "APIResult" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "error" + }, + { + "associatedValues" : [ + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "location" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "status" + }, + { + "associatedValues" : [ + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + } + ], + "name" : "coordinates" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + + } + } + }, + { + "type" : { + "bool" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "comprehensive" + }, + { + "associatedValues" : [ + + ], + "name" : "info" + } + ], + "emitStyle" : "const", + "name" : "ComplexResult", + "swiftCallName" : "ComplexResult" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "failure" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "status" + } + ], + "emitStyle" : "const", + "name" : "Result", + "namespace" : [ + "Utilities" + ], + "swiftCallName" : "Utilities.Result" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "failure" + } + ], + "emitStyle" : "const", + "name" : "NetworkingResult", + "namespace" : [ + "API" + ], + "swiftCallName" : "API.NetworkingResult" } ], "functions" : [ { - "abiName" : "bjs_roundTripVoid", + "abiName" : "bjs_roundTripVoid", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundTripVoid", + "parameters" : [ + + ], + "returnType" : { + "void" : { + + } + } + }, + { + "abiName" : "bjs_roundTripInt", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundTripInt", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "int" : { + + } + } + }, + { + "abiName" : "bjs_roundTripFloat", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundTripFloat", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "float" : { + + } + } + } + ], + "returnType" : { + "float" : { + + } + } + }, + { + "abiName" : "bjs_roundTripDouble", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundTripDouble", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "double" : { + + } + } + } + ], + "returnType" : { + "double" : { + + } + } + }, + { + "abiName" : "bjs_roundTripBool", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundTripBool", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "bool" : { + + } + } + } + ], + "returnType" : { + "bool" : { + + } + } + }, + { + "abiName" : "bjs_roundTripString", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundTripString", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_roundTripSwiftHeapObject", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundTripSwiftHeapObject", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "swiftHeapObject" : { + "_0" : "Greeter" + } + } + } + ], + "returnType" : { + "swiftHeapObject" : { + "_0" : "Greeter" + } + } + }, + { + "abiName" : "bjs_roundTripJSObject", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundTripJSObject", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "jsObject" : { + + } + } + } + ], + "returnType" : { + "jsObject" : { + + } + } + }, + { + "abiName" : "bjs_throwsSwiftError", + "effects" : { + "isAsync" : false, + "isThrows" : true + }, + "name" : "throwsSwiftError", + "parameters" : [ + { + "label" : "shouldThrow", + "name" : "shouldThrow", + "type" : { + "bool" : { + + } + } + } + ], + "returnType" : { + "void" : { + + } + } + }, + { + "abiName" : "bjs_throwsWithIntResult", + "effects" : { + "isAsync" : false, + "isThrows" : true + }, + "name" : "throwsWithIntResult", + "parameters" : [ + + ], + "returnType" : { + "int" : { + + } + } + }, + { + "abiName" : "bjs_throwsWithStringResult", + "effects" : { + "isAsync" : false, + "isThrows" : true + }, + "name" : "throwsWithStringResult", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_throwsWithBoolResult", + "effects" : { + "isAsync" : false, + "isThrows" : true + }, + "name" : "throwsWithBoolResult", + "parameters" : [ + + ], + "returnType" : { + "bool" : { + + } + } + }, + { + "abiName" : "bjs_throwsWithFloatResult", + "effects" : { + "isAsync" : false, + "isThrows" : true + }, + "name" : "throwsWithFloatResult", + "parameters" : [ + + ], + "returnType" : { + "float" : { + + } + } + }, + { + "abiName" : "bjs_throwsWithDoubleResult", + "effects" : { + "isAsync" : false, + "isThrows" : true + }, + "name" : "throwsWithDoubleResult", + "parameters" : [ + + ], + "returnType" : { + "double" : { + + } + } + }, + { + "abiName" : "bjs_throwsWithSwiftHeapObjectResult", + "effects" : { + "isAsync" : false, + "isThrows" : true + }, + "name" : "throwsWithSwiftHeapObjectResult", + "parameters" : [ + + ], + "returnType" : { + "swiftHeapObject" : { + "_0" : "Greeter" + } + } + }, + { + "abiName" : "bjs_throwsWithJSObjectResult", + "effects" : { + "isAsync" : false, + "isThrows" : true + }, + "name" : "throwsWithJSObjectResult", + "parameters" : [ + + ], + "returnType" : { + "jsObject" : { + + } + } + }, + { + "abiName" : "bjs_asyncRoundTripVoid", + "effects" : { + "isAsync" : true, + "isThrows" : false + }, + "name" : "asyncRoundTripVoid", + "parameters" : [ + + ], + "returnType" : { + "void" : { + + } + } + }, + { + "abiName" : "bjs_asyncRoundTripInt", + "effects" : { + "isAsync" : true, + "isThrows" : false + }, + "name" : "asyncRoundTripInt", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "int" : { + + } + } + }, + { + "abiName" : "bjs_asyncRoundTripFloat", + "effects" : { + "isAsync" : true, + "isThrows" : false + }, + "name" : "asyncRoundTripFloat", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "float" : { + + } + } + } + ], + "returnType" : { + "float" : { + + } + } + }, + { + "abiName" : "bjs_asyncRoundTripDouble", + "effects" : { + "isAsync" : true, + "isThrows" : false + }, + "name" : "asyncRoundTripDouble", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "double" : { + + } + } + } + ], + "returnType" : { + "double" : { + + } + } + }, + { + "abiName" : "bjs_asyncRoundTripBool", + "effects" : { + "isAsync" : true, + "isThrows" : false + }, + "name" : "asyncRoundTripBool", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "bool" : { + + } + } + } + ], + "returnType" : { + "bool" : { + + } + } + }, + { + "abiName" : "bjs_asyncRoundTripString", + "effects" : { + "isAsync" : true, + "isThrows" : false + }, + "name" : "asyncRoundTripString", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_asyncRoundTripSwiftHeapObject", + "effects" : { + "isAsync" : true, + "isThrows" : false + }, + "name" : "asyncRoundTripSwiftHeapObject", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "swiftHeapObject" : { + "_0" : "Greeter" + } + } + } + ], + "returnType" : { + "swiftHeapObject" : { + "_0" : "Greeter" + } + } + }, + { + "abiName" : "bjs_asyncRoundTripJSObject", "effects" : { - "isAsync" : false, + "isAsync" : true, "isThrows" : false }, - "name" : "roundTripVoid", + "name" : "asyncRoundTripJSObject", "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "jsObject" : { + } + } + } ], "returnType" : { - "void" : { + "jsObject" : { } } }, { - "abiName" : "bjs_roundTripInt", + "abiName" : "bjs_takeGreeter", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "roundTripInt", + "name" : "takeGreeter", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "g", + "name" : "g", "type" : { - "int" : { + "swiftHeapObject" : { + "_0" : "Greeter" + } + } + }, + { + "label" : "name", + "name" : "name", + "type" : { + "string" : { } } } ], "returnType" : { - "int" : { + "void" : { } } }, { - "abiName" : "bjs_roundTripFloat", + "abiName" : "bjs_createCalculator", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "roundTripFloat", + "name" : "createCalculator", + "parameters" : [ + + ], + "returnType" : { + "swiftHeapObject" : { + "_0" : "Calculator" + } + } + }, + { + "abiName" : "bjs_useCalculator", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "useCalculator", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "calc", + "name" : "calc", "type" : { - "float" : { + "swiftHeapObject" : { + "_0" : "Calculator" + } + } + }, + { + "label" : "x", + "name" : "x", + "type" : { + "int" : { + + } + } + }, + { + "label" : "y", + "name" : "y", + "type" : { + "int" : { } } } ], "returnType" : { - "float" : { + "int" : { } } }, { - "abiName" : "bjs_roundTripDouble", + "abiName" : "bjs_testGreeterToJSValue", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "roundTripDouble", + "name" : "testGreeterToJSValue", "parameters" : [ - { - "label" : "v", - "name" : "v", - "type" : { - "double" : { - } - } + ], + "returnType" : { + "jsObject" : { + } + } + }, + { + "abiName" : "bjs_testCalculatorToJSValue", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "testCalculatorToJSValue", + "parameters" : [ + ], "returnType" : { - "double" : { + "jsObject" : { } } }, { - "abiName" : "bjs_roundTripBool", + "abiName" : "bjs_testSwiftClassAsJSValue", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "roundTripBool", + "name" : "testSwiftClassAsJSValue", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "greeter", + "name" : "greeter", "type" : { - "bool" : { - + "swiftHeapObject" : { + "_0" : "Greeter" } } } ], "returnType" : { - "bool" : { + "jsObject" : { } } }, { - "abiName" : "bjs_roundTripString", + "abiName" : "bjs_setDirection", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "roundTripString", + "name" : "setDirection", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "_", + "name" : "direction", "type" : { - "string" : { - + "caseEnum" : { + "_0" : "Direction" } } } ], "returnType" : { - "string" : { + "caseEnum" : { + "_0" : "Direction" + } + } + }, + { + "abiName" : "bjs_getDirection", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "getDirection", + "parameters" : [ + ], + "returnType" : { + "caseEnum" : { + "_0" : "Direction" } } }, { - "abiName" : "bjs_roundTripSwiftHeapObject", + "abiName" : "bjs_processDirection", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "roundTripSwiftHeapObject", + "name" : "processDirection", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "_", + "name" : "input", "type" : { - "swiftHeapObject" : { - "_0" : "Greeter" + "caseEnum" : { + "_0" : "Direction" } } } ], "returnType" : { - "swiftHeapObject" : { - "_0" : "Greeter" + "caseEnum" : { + "_0" : "Status" } } }, { - "abiName" : "bjs_roundTripJSObject", + "abiName" : "bjs_setTheme", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "roundTripJSObject", + "name" : "setTheme", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "_", + "name" : "theme", "type" : { - "jsObject" : { - + "rawValueEnum" : { + "_0" : "Theme", + "_1" : "String" } } } ], "returnType" : { - "jsObject" : { + "rawValueEnum" : { + "_0" : "Theme", + "_1" : "String" + } + } + }, + { + "abiName" : "bjs_getTheme", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "getTheme", + "parameters" : [ + ], + "returnType" : { + "rawValueEnum" : { + "_0" : "Theme", + "_1" : "String" } } }, { - "abiName" : "bjs_throwsSwiftError", + "abiName" : "bjs_setHttpStatus", "effects" : { "isAsync" : false, - "isThrows" : true + "isThrows" : false }, - "name" : "throwsSwiftError", + "name" : "setHttpStatus", "parameters" : [ { - "label" : "shouldThrow", - "name" : "shouldThrow", + "label" : "_", + "name" : "status", "type" : { - "bool" : { - + "rawValueEnum" : { + "_0" : "HttpStatus", + "_1" : "Int" } } } ], "returnType" : { - "void" : { - + "rawValueEnum" : { + "_0" : "HttpStatus", + "_1" : "Int" } } }, { - "abiName" : "bjs_throwsWithIntResult", + "abiName" : "bjs_getHttpStatus", "effects" : { "isAsync" : false, - "isThrows" : true + "isThrows" : false }, - "name" : "throwsWithIntResult", + "name" : "getHttpStatus", "parameters" : [ ], "returnType" : { - "int" : { - + "rawValueEnum" : { + "_0" : "HttpStatus", + "_1" : "Int" } } }, { - "abiName" : "bjs_throwsWithStringResult", + "abiName" : "bjs_processTheme", "effects" : { "isAsync" : false, - "isThrows" : true + "isThrows" : false }, - "name" : "throwsWithStringResult", + "name" : "processTheme", "parameters" : [ - + { + "label" : "_", + "name" : "theme", + "type" : { + "rawValueEnum" : { + "_0" : "Theme", + "_1" : "String" + } + } + } ], "returnType" : { - "string" : { - + "rawValueEnum" : { + "_0" : "HttpStatus", + "_1" : "Int" } } }, { - "abiName" : "bjs_throwsWithBoolResult", + "abiName" : "bjs_setTSDirection", "effects" : { "isAsync" : false, - "isThrows" : true + "isThrows" : false }, - "name" : "throwsWithBoolResult", + "name" : "setTSDirection", "parameters" : [ - + { + "label" : "_", + "name" : "direction", + "type" : { + "caseEnum" : { + "_0" : "TSDirection" + } + } + } ], "returnType" : { - "bool" : { - + "caseEnum" : { + "_0" : "TSDirection" } } }, { - "abiName" : "bjs_throwsWithFloatResult", + "abiName" : "bjs_getTSDirection", "effects" : { "isAsync" : false, - "isThrows" : true + "isThrows" : false }, - "name" : "throwsWithFloatResult", + "name" : "getTSDirection", "parameters" : [ ], "returnType" : { - "float" : { - + "caseEnum" : { + "_0" : "TSDirection" } } }, { - "abiName" : "bjs_throwsWithDoubleResult", + "abiName" : "bjs_setTSTheme", "effects" : { "isAsync" : false, - "isThrows" : true + "isThrows" : false }, - "name" : "throwsWithDoubleResult", + "name" : "setTSTheme", "parameters" : [ - + { + "label" : "_", + "name" : "theme", + "type" : { + "rawValueEnum" : { + "_0" : "TSTheme", + "_1" : "String" + } + } + } ], "returnType" : { - "double" : { - + "rawValueEnum" : { + "_0" : "TSTheme", + "_1" : "String" } } }, { - "abiName" : "bjs_throwsWithSwiftHeapObjectResult", + "abiName" : "bjs_getTSTheme", "effects" : { "isAsync" : false, - "isThrows" : true + "isThrows" : false }, - "name" : "throwsWithSwiftHeapObjectResult", + "name" : "getTSTheme", "parameters" : [ ], "returnType" : { - "swiftHeapObject" : { - "_0" : "Greeter" + "rawValueEnum" : { + "_0" : "TSTheme", + "_1" : "String" } } }, { - "abiName" : "bjs_throwsWithJSObjectResult", + "abiName" : "bjs_echoAPIResult", "effects" : { "isAsync" : false, - "isThrows" : true + "isThrows" : false }, - "name" : "throwsWithJSObjectResult", + "name" : "echoAPIResult", "parameters" : [ - + { + "label" : "result", + "name" : "result", + "type" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + } ], "returnType" : { - "jsObject" : { - + "associatedValueEnum" : { + "_0" : "APIResult" } } }, { - "abiName" : "bjs_asyncRoundTripVoid", + "abiName" : "bjs_makeAPIResultSuccess", "effects" : { - "isAsync" : true, + "isAsync" : false, "isThrows" : false }, - "name" : "asyncRoundTripVoid", + "name" : "makeAPIResultSuccess", "parameters" : [ + { + "label" : "_", + "name" : "value", + "type" : { + "string" : { + } + } + } ], "returnType" : { - "void" : { - + "associatedValueEnum" : { + "_0" : "APIResult" } } }, { - "abiName" : "bjs_asyncRoundTripInt", + "abiName" : "bjs_makeAPIResultFailure", "effects" : { - "isAsync" : true, + "isAsync" : false, "isThrows" : false }, - "name" : "asyncRoundTripInt", + "name" : "makeAPIResultFailure", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "_", + "name" : "value", "type" : { "int" : { @@ -930,558 +1923,643 @@ } ], "returnType" : { - "int" : { - + "associatedValueEnum" : { + "_0" : "APIResult" } } }, { - "abiName" : "bjs_asyncRoundTripFloat", + "abiName" : "bjs_makeAPIResultInfo", "effects" : { - "isAsync" : true, + "isAsync" : false, "isThrows" : false }, - "name" : "asyncRoundTripFloat", + "name" : "makeAPIResultInfo", "parameters" : [ - { - "label" : "v", - "name" : "v", - "type" : { - "float" : { - } - } - } ], "returnType" : { - "float" : { - + "associatedValueEnum" : { + "_0" : "APIResult" } } }, { - "abiName" : "bjs_asyncRoundTripDouble", + "abiName" : "bjs_makeAPIResultFlag", "effects" : { - "isAsync" : true, + "isAsync" : false, "isThrows" : false }, - "name" : "asyncRoundTripDouble", + "name" : "makeAPIResultFlag", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "_", + "name" : "value", "type" : { - "double" : { + "bool" : { } } } ], "returnType" : { - "double" : { - + "associatedValueEnum" : { + "_0" : "APIResult" } } }, { - "abiName" : "bjs_asyncRoundTripBool", + "abiName" : "bjs_makeAPIResultRate", "effects" : { - "isAsync" : true, + "isAsync" : false, "isThrows" : false }, - "name" : "asyncRoundTripBool", + "name" : "makeAPIResultRate", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "_", + "name" : "value", "type" : { - "bool" : { + "float" : { } } } ], "returnType" : { - "bool" : { - + "associatedValueEnum" : { + "_0" : "APIResult" } } }, { - "abiName" : "bjs_asyncRoundTripString", + "abiName" : "bjs_makeAPIResultPrecise", "effects" : { - "isAsync" : true, + "isAsync" : false, "isThrows" : false }, - "name" : "asyncRoundTripString", + "name" : "makeAPIResultPrecise", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "_", + "name" : "value", "type" : { - "string" : { + "double" : { } } } ], "returnType" : { - "string" : { - + "associatedValueEnum" : { + "_0" : "APIResult" } } }, { - "abiName" : "bjs_asyncRoundTripSwiftHeapObject", + "abiName" : "bjs_echoComplexResult", "effects" : { - "isAsync" : true, + "isAsync" : false, "isThrows" : false }, - "name" : "asyncRoundTripSwiftHeapObject", + "name" : "echoComplexResult", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "result", + "name" : "result", "type" : { - "swiftHeapObject" : { - "_0" : "Greeter" + "associatedValueEnum" : { + "_0" : "ComplexResult" } } } ], "returnType" : { - "swiftHeapObject" : { - "_0" : "Greeter" + "associatedValueEnum" : { + "_0" : "ComplexResult" } } }, { - "abiName" : "bjs_asyncRoundTripJSObject", + "abiName" : "bjs_makeComplexResultSuccess", "effects" : { - "isAsync" : true, + "isAsync" : false, "isThrows" : false }, - "name" : "asyncRoundTripJSObject", + "name" : "makeComplexResultSuccess", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "_", + "name" : "value", "type" : { - "jsObject" : { + "string" : { } } } ], "returnType" : { - "jsObject" : { - + "associatedValueEnum" : { + "_0" : "ComplexResult" } } }, { - "abiName" : "bjs_takeGreeter", + "abiName" : "bjs_makeComplexResultError", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "takeGreeter", + "name" : "makeComplexResultError", "parameters" : [ { - "label" : "g", - "name" : "g", + "label" : "_", + "name" : "message", "type" : { - "swiftHeapObject" : { - "_0" : "Greeter" + "string" : { + } } }, { - "label" : "name", - "name" : "name", + "label" : "_", + "name" : "code", "type" : { - "string" : { + "int" : { } } } ], "returnType" : { - "void" : { - - } - } - }, - { - "abiName" : "bjs_createCalculator", - "effects" : { - "isAsync" : false, - "isThrows" : false - }, - "name" : "createCalculator", - "parameters" : [ - - ], - "returnType" : { - "swiftHeapObject" : { - "_0" : "Calculator" + "associatedValueEnum" : { + "_0" : "ComplexResult" } } }, { - "abiName" : "bjs_useCalculator", + "abiName" : "bjs_makeComplexResultLocation", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "useCalculator", + "name" : "makeComplexResultLocation", "parameters" : [ { - "label" : "calc", - "name" : "calc", + "label" : "_", + "name" : "lat", "type" : { - "swiftHeapObject" : { - "_0" : "Calculator" + "double" : { + } } }, { - "label" : "x", - "name" : "x", + "label" : "_", + "name" : "lng", "type" : { - "int" : { + "double" : { } } }, { - "label" : "y", - "name" : "y", + "label" : "_", + "name" : "name", "type" : { - "int" : { + "string" : { } } } ], "returnType" : { - "int" : { - + "associatedValueEnum" : { + "_0" : "ComplexResult" } } }, { - "abiName" : "bjs_testGreeterToJSValue", + "abiName" : "bjs_makeComplexResultStatus", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "testGreeterToJSValue", + "name" : "makeComplexResultStatus", "parameters" : [ + { + "label" : "_", + "name" : "active", + "type" : { + "bool" : { - ], - "returnType" : { - "jsObject" : { + } + } + }, + { + "label" : "_", + "name" : "code", + "type" : { + "int" : { - } - } - }, - { - "abiName" : "bjs_testCalculatorToJSValue", - "effects" : { - "isAsync" : false, - "isThrows" : false - }, - "name" : "testCalculatorToJSValue", - "parameters" : [ + } + } + }, + { + "label" : "_", + "name" : "message", + "type" : { + "string" : { + } + } + } ], "returnType" : { - "jsObject" : { - + "associatedValueEnum" : { + "_0" : "ComplexResult" } } }, { - "abiName" : "bjs_testSwiftClassAsJSValue", + "abiName" : "bjs_makeComplexResultCoordinates", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "testSwiftClassAsJSValue", + "name" : "makeComplexResultCoordinates", "parameters" : [ { - "label" : "greeter", - "name" : "greeter", + "label" : "_", + "name" : "x", "type" : { - "swiftHeapObject" : { - "_0" : "Greeter" + "double" : { + + } + } + }, + { + "label" : "_", + "name" : "y", + "type" : { + "double" : { + + } + } + }, + { + "label" : "_", + "name" : "z", + "type" : { + "double" : { + } } } ], "returnType" : { - "jsObject" : { - + "associatedValueEnum" : { + "_0" : "ComplexResult" } } }, { - "abiName" : "bjs_setDirection", + "abiName" : "bjs_makeComplexResultComprehensive", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "setDirection", + "name" : "makeComplexResultComprehensive", "parameters" : [ { "label" : "_", - "name" : "direction", + "name" : "flag1", "type" : { - "caseEnum" : { - "_0" : "Direction" + "bool" : { + + } + } + }, + { + "label" : "_", + "name" : "flag2", + "type" : { + "bool" : { + + } + } + }, + { + "label" : "_", + "name" : "count1", + "type" : { + "int" : { + + } + } + }, + { + "label" : "_", + "name" : "count2", + "type" : { + "int" : { + + } + } + }, + { + "label" : "_", + "name" : "value1", + "type" : { + "double" : { + + } + } + }, + { + "label" : "_", + "name" : "value2", + "type" : { + "double" : { + + } + } + }, + { + "label" : "_", + "name" : "text1", + "type" : { + "string" : { + + } + } + }, + { + "label" : "_", + "name" : "text2", + "type" : { + "string" : { + + } + } + }, + { + "label" : "_", + "name" : "text3", + "type" : { + "string" : { + } } } ], "returnType" : { - "caseEnum" : { - "_0" : "Direction" + "associatedValueEnum" : { + "_0" : "ComplexResult" } } }, { - "abiName" : "bjs_getDirection", + "abiName" : "bjs_makeComplexResultInfo", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "getDirection", + "name" : "makeComplexResultInfo", "parameters" : [ ], "returnType" : { - "caseEnum" : { - "_0" : "Direction" + "associatedValueEnum" : { + "_0" : "ComplexResult" } } }, { - "abiName" : "bjs_processDirection", + "abiName" : "bjs_roundtripComplexResult", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "processDirection", + "name" : "roundtripComplexResult", "parameters" : [ { "label" : "_", - "name" : "input", + "name" : "result", "type" : { - "caseEnum" : { - "_0" : "Direction" + "associatedValueEnum" : { + "_0" : "ComplexResult" } } } ], "returnType" : { - "caseEnum" : { - "_0" : "Status" + "associatedValueEnum" : { + "_0" : "ComplexResult" } } }, { - "abiName" : "bjs_setTheme", + "abiName" : "bjs_makeUtilitiesResultSuccess", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "setTheme", + "name" : "makeUtilitiesResultSuccess", "parameters" : [ { "label" : "_", - "name" : "theme", + "name" : "message", "type" : { - "rawValueEnum" : { - "_0" : "Theme", - "_1" : "String" + "string" : { + } } } ], "returnType" : { - "rawValueEnum" : { - "_0" : "Theme", - "_1" : "String" + "associatedValueEnum" : { + "_0" : "Utilities.Result" } } }, { - "abiName" : "bjs_getTheme", + "abiName" : "bjs_makeUtilitiesResultFailure", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "getTheme", + "name" : "makeUtilitiesResultFailure", "parameters" : [ + { + "label" : "_", + "name" : "error", + "type" : { + "string" : { - ], - "returnType" : { - "rawValueEnum" : { - "_0" : "Theme", - "_1" : "String" - } - } - }, - { - "abiName" : "bjs_setHttpStatus", - "effects" : { - "isAsync" : false, - "isThrows" : false - }, - "name" : "setHttpStatus", - "parameters" : [ + } + } + }, { "label" : "_", - "name" : "status", + "name" : "code", "type" : { - "rawValueEnum" : { - "_0" : "HttpStatus", - "_1" : "Int" + "int" : { + } } } ], "returnType" : { - "rawValueEnum" : { - "_0" : "HttpStatus", - "_1" : "Int" + "associatedValueEnum" : { + "_0" : "Utilities.Result" } } }, { - "abiName" : "bjs_getHttpStatus", + "abiName" : "bjs_makeUtilitiesResultStatus", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "getHttpStatus", + "name" : "makeUtilitiesResultStatus", "parameters" : [ + { + "label" : "_", + "name" : "active", + "type" : { + "bool" : { - ], - "returnType" : { - "rawValueEnum" : { - "_0" : "HttpStatus", - "_1" : "Int" - } - } - }, - { - "abiName" : "bjs_processTheme", - "effects" : { - "isAsync" : false, - "isThrows" : false - }, - "name" : "processTheme", - "parameters" : [ + } + } + }, { "label" : "_", - "name" : "theme", + "name" : "code", "type" : { - "rawValueEnum" : { - "_0" : "Theme", - "_1" : "String" + "int" : { + + } + } + }, + { + "label" : "_", + "name" : "message", + "type" : { + "string" : { + } } } ], "returnType" : { - "rawValueEnum" : { - "_0" : "HttpStatus", - "_1" : "Int" + "associatedValueEnum" : { + "_0" : "Utilities.Result" } } }, { - "abiName" : "bjs_setTSDirection", + "abiName" : "bjs_makeAPINetworkingResultSuccess", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "setTSDirection", + "name" : "makeAPINetworkingResultSuccess", "parameters" : [ { "label" : "_", - "name" : "direction", + "name" : "message", "type" : { - "caseEnum" : { - "_0" : "TSDirection" + "string" : { + } } } ], "returnType" : { - "caseEnum" : { - "_0" : "TSDirection" + "associatedValueEnum" : { + "_0" : "API.NetworkingResult" } } }, { - "abiName" : "bjs_getTSDirection", + "abiName" : "bjs_makeAPINetworkingResultFailure", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "getTSDirection", + "name" : "makeAPINetworkingResultFailure", "parameters" : [ + { + "label" : "_", + "name" : "error", + "type" : { + "string" : { + + } + } + }, + { + "label" : "_", + "name" : "code", + "type" : { + "int" : { + } + } + } ], "returnType" : { - "caseEnum" : { - "_0" : "TSDirection" + "associatedValueEnum" : { + "_0" : "API.NetworkingResult" } } }, { - "abiName" : "bjs_setTSTheme", + "abiName" : "bjs_roundtripUtilitiesResult", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "setTSTheme", + "name" : "roundtripUtilitiesResult", "parameters" : [ { "label" : "_", - "name" : "theme", + "name" : "result", "type" : { - "rawValueEnum" : { - "_0" : "TSTheme", - "_1" : "String" + "associatedValueEnum" : { + "_0" : "Utilities.Result" } } } ], "returnType" : { - "rawValueEnum" : { - "_0" : "TSTheme", - "_1" : "String" + "associatedValueEnum" : { + "_0" : "Utilities.Result" } } }, { - "abiName" : "bjs_getTSTheme", + "abiName" : "bjs_roundtripAPINetworkingResult", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "getTSTheme", + "name" : "roundtripAPINetworkingResult", "parameters" : [ - + { + "label" : "_", + "name" : "result", + "type" : { + "associatedValueEnum" : { + "_0" : "API.NetworkingResult" + } + } + } ], "returnType" : { - "rawValueEnum" : { - "_0" : "TSTheme", - "_1" : "String" + "associatedValueEnum" : { + "_0" : "API.NetworkingResult" } } } diff --git a/Tests/prelude.mjs b/Tests/prelude.mjs index 6954d87c..21fed0eb 100644 --- a/Tests/prelude.mjs +++ b/Tests/prelude.mjs @@ -1,7 +1,7 @@ // @ts-check -import { - Direction, Status, Theme, HttpStatus, TSDirection, TSTheme +import { + Direction, Status, Theme, HttpStatus, TSDirection, TSTheme, APIResult, ComplexResult } from '../.build/plugins/PackageToJS/outputs/PackageTests/bridge-js.js'; /** @type {import('../.build/plugins/PackageToJS/outputs/PackageTests/test.d.ts').SetupOptionsFn} */ @@ -252,6 +252,89 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { const globalTestServer = new globalThis.Networking.APIV2.Internal.TestServer(); globalTestServer.call(globalThis.Networking.APIV2.Internal.SupportedMethod.Post); globalTestServer.release(); + + const s1 = { tag: APIResult.Tag.Success, param0: "Cześć 🙋‍♂️" }; + const f1 = { tag: APIResult.Tag.Failure, param0: 42 }; + const i1 = { tag: APIResult.Tag.Info }; + + assert.deepEqual(exports.echoAPIResult(s1), s1); + assert.deepEqual(exports.echoAPIResult(f1), f1); + assert.deepEqual(exports.echoAPIResult(i1), i1); + + + assert.deepEqual(exports.makeAPIResultSuccess("Test"), { tag: APIResult.Tag.Success, param0: "Test" }); + assert.deepEqual(exports.makeAPIResultSuccess("ok"), { tag: APIResult.Tag.Success, param0: "ok" }); + assert.deepEqual(exports.makeAPIResultFailure(123), { tag: APIResult.Tag.Failure, param0: 123 }); + assert.deepEqual(exports.makeAPIResultInfo(), { tag: APIResult.Tag.Info }); + + const bTrue = { tag: APIResult.Tag.Flag, param0: true }; + const bFalse = { tag: APIResult.Tag.Flag, param0: false }; + assert.deepEqual(exports.makeAPIResultFlag(true), bTrue); + assert.deepEqual(exports.makeAPIResultFlag(false), bFalse); + + const rVal = 3.25; + const r1 = { tag: APIResult.Tag.Rate, param0: rVal }; + assert.deepEqual(exports.echoAPIResult(r1), r1); + assert.deepEqual(exports.makeAPIResultRate(rVal), r1); + + const pVal = 3.141592653589793; + const p1 = { tag: APIResult.Tag.Precise, param0: pVal }; + assert.deepEqual(exports.echoAPIResult(p1), p1); + assert.deepEqual(exports.makeAPIResultPrecise(pVal), p1); + + const cs1 = { tag: ComplexResult.Tag.Success, param0: "All good!" }; + const ce1 = { tag: ComplexResult.Tag.Error, param0: "Network error", param1: 503 }; + const cl1 = { tag: ComplexResult.Tag.Location, param0: 37.7749, param1: -122.4194, param2: "San Francisco" }; + const cst1 = { tag: ComplexResult.Tag.Status, param0: true, param1: 200, param2: "OK" }; + const cc1 = { tag: ComplexResult.Tag.Coordinates, param0: 10.5, param1: 20.3, param2: 30.7 }; + const ccomp1 = { tag: ComplexResult.Tag.Comprehensive, param0: true, param1: false, param2: 42, param3: 100, param4: 3.14, param5: 2.718, param6: "Hello", param7: "World", param8: "Test" }; + const ci1 = { tag: ComplexResult.Tag.Info }; + + assert.deepEqual(exports.echoComplexResult(cs1), cs1); + assert.deepEqual(exports.echoComplexResult(ce1), ce1); + assert.deepEqual(exports.echoComplexResult(cl1), cl1); + assert.deepEqual(exports.echoComplexResult(cst1), cst1); + assert.deepEqual(exports.echoComplexResult(cc1), cc1); + assert.deepEqual(exports.echoComplexResult(ccomp1), ccomp1); + assert.deepEqual(exports.echoComplexResult(ci1), ci1); + + assert.deepEqual(exports.roundtripComplexResult(cs1), cs1); + assert.deepEqual(exports.roundtripComplexResult(ce1), ce1); + assert.deepEqual(exports.roundtripComplexResult(cl1), cl1); + assert.deepEqual(exports.roundtripComplexResult(cst1), cst1); + assert.deepEqual(exports.roundtripComplexResult(cc1), cc1); + assert.deepEqual(exports.roundtripComplexResult(ccomp1), ccomp1); + assert.deepEqual(exports.roundtripComplexResult(ci1), ci1); + + assert.deepEqual(exports.makeComplexResultSuccess("Great!"), { tag: ComplexResult.Tag.Success, param0: "Great!" }); + assert.deepEqual(exports.makeComplexResultError("Timeout", 408), { tag: ComplexResult.Tag.Error, param0: "Timeout", param1: 408 }); + assert.deepEqual(exports.makeComplexResultLocation(40.7128, -74.0060, "New York"), { tag: ComplexResult.Tag.Location, param0: 40.7128, param1: -74.0060, param2: "New York" }); + assert.deepEqual(exports.makeComplexResultStatus(false, 500, "Internal Server Error"), { tag: ComplexResult.Tag.Status, param0: false, param1: 500, param2: "Internal Server Error" }); + assert.deepEqual(exports.makeComplexResultCoordinates(1.1, 2.2, 3.3), { tag: ComplexResult.Tag.Coordinates, param0: 1.1, param1: 2.2, param2: 3.3 }); + assert.deepEqual(exports.makeComplexResultComprehensive(true, false, 10, 20, 1.5, 2.5, "First", "Second", "Third"), { tag: ComplexResult.Tag.Comprehensive, param0: true, param1: false, param2: 10, param3: 20, param4: 1.5, param5: 2.5, param6: "First", param7: "Second", param8: "Third" }); + assert.deepEqual(exports.makeComplexResultInfo(), { tag: ComplexResult.Tag.Info }); + + const urSuccess = { tag: globalThis.Utilities.Result.Tag.Success, param0: "Utility operation completed" }; + const urFailure = { tag: globalThis.Utilities.Result.Tag.Failure, param0: "Utility error occurred", param1: 500 }; + const urStatus = { tag: globalThis.Utilities.Result.Tag.Status, param0: true, param1: 200, param2: "Utility status OK" }; + + assert.deepEqual(exports.roundtripUtilitiesResult(urSuccess), urSuccess); + assert.deepEqual(exports.roundtripUtilitiesResult(urFailure), urFailure); + assert.deepEqual(exports.roundtripUtilitiesResult(urStatus), urStatus); + + assert.deepEqual(exports.makeUtilitiesResultSuccess("Test"), { tag: globalThis.Utilities.Result.Tag.Success, param0: "Test" }); + assert.deepEqual(exports.makeUtilitiesResultSuccess("ok"), { tag: globalThis.Utilities.Result.Tag.Success, param0: "ok" }); + assert.deepEqual(exports.makeUtilitiesResultFailure("Error", 123), { tag: globalThis.Utilities.Result.Tag.Failure, param0: "Error", param1: 123 }); + assert.deepEqual(exports.makeUtilitiesResultStatus(true, 200, "OK"), { tag: globalThis.Utilities.Result.Tag.Status, param0: true, param1: 200, param2: "OK" }); + + const nrSuccess = { tag: globalThis.API.NetworkingResult.Tag.Success, param0: "Network request successful" }; + const nrFailure = { tag: globalThis.API.NetworkingResult.Tag.Failure, param0: "Network timeout", param1: 408 }; + + assert.deepEqual(exports.roundtripAPINetworkingResult(nrSuccess), nrSuccess); + assert.deepEqual(exports.roundtripAPINetworkingResult(nrFailure), nrFailure); + + assert.deepEqual(exports.makeAPINetworkingResultSuccess("Connected"), { tag: globalThis.API.NetworkingResult.Tag.Success, param0: "Connected" }); + assert.deepEqual(exports.makeAPINetworkingResultFailure("Timeout", 408), { tag: globalThis.API.NetworkingResult.Tag.Failure, param0: "Timeout", param1: 408 }); } /** @param {import('./../.build/plugins/PackageToJS/outputs/PackageTests/bridge-js.d.ts').Exports} exports */ @@ -350,4 +433,4 @@ function setupTestGlobals(global) { sym: Symbol("s"), bi: BigInt(3) }; -} +} \ No newline at end of file