diff --git a/.github/actions/install-swift/action.yml b/.github/actions/install-swift/action.yml index d6fbcc969..c2803206c 100644 --- a/.github/actions/install-swift/action.yml +++ b/.github/actions/install-swift/action.yml @@ -32,6 +32,12 @@ runs: zlib1g-dev curl + # Keep the toolchain's `/usr/bin` layout intact. Flattening it into + # /usr/local breaks toolchain discovery in the swiftbuild build system, + # which derives the toolchain root by stripping `usr/bin` from `swiftc`. - name: Install Swift shell: bash - run: curl -fL ${{ inputs.download-url }} | sudo tar xfz - --strip-components=2 -C /usr/local + run: | + sudo mkdir -p /opt/swift + curl -fL ${{ inputs.download-url }} | sudo tar xfz - --strip-components=1 -C /opt/swift + echo "/opt/swift/usr/bin" >> "$GITHUB_PATH" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0458dec5d..a9e90c175 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,9 +14,10 @@ jobs: entry: - os: ubuntu-24.04 toolchain: - download-url: https://download.swift.org/development/ubuntu2404/swift-DEVELOPMENT-SNAPSHOT-2026-05-27-a/swift-DEVELOPMENT-SNAPSHOT-2026-05-27-a-ubuntu24.04.tar.gz + download-url: https://download.swift.org/development/ubuntu2404/swift-DEVELOPMENT-SNAPSHOT-2026-08-11-a/swift-DEVELOPMENT-SNAPSHOT-2026-08-11-a-ubuntu24.04.tar.gz wasi-backend: Node target: "wasm32-unknown-wasip1" + build-system: swiftbuild env: | JAVASCRIPTKIT_DISABLE_TRACING_TRAIT=1 - os: ubuntu-24.04 @@ -24,11 +25,13 @@ jobs: download-url: https://download.swift.org/swift-6.3-branch/ubuntu2404/swift-6.3-DEVELOPMENT-SNAPSHOT-2026-03-05-a/swift-6.3-DEVELOPMENT-SNAPSHOT-2026-03-05-a-ubuntu24.04.tar.gz wasi-backend: Node target: "wasm32-unknown-wasip1" + build-system: native - os: ubuntu-22.04 toolchain: - download-url: https://download.swift.org/development/ubuntu2204/swift-DEVELOPMENT-SNAPSHOT-2026-05-27-a/swift-DEVELOPMENT-SNAPSHOT-2026-05-27-a-ubuntu22.04.tar.gz + download-url: https://download.swift.org/development/ubuntu2204/swift-DEVELOPMENT-SNAPSHOT-2026-08-11-a/swift-DEVELOPMENT-SNAPSHOT-2026-08-11-a-ubuntu22.04.tar.gz wasi-backend: Node target: "wasm32-unknown-wasip1-threads" + build-system: swiftbuild runs-on: ${{ matrix.entry.os }} env: @@ -55,7 +58,7 @@ jobs: echo "SWIFT_BIN_PATH=$(dirname $(which swiftc))" >> $GITHUB_ENV - run: make bootstrap - run: npm run test:runtime - - run: make unittest + - run: make unittest BUILD_SYSTEM=${{ matrix.entry.build-system }} # Skip unit tests with uwasi because its proc_exit throws # unhandled promise rejection. if: ${{ matrix.entry.wasi-backend != 'MicroWASI' }} @@ -144,7 +147,7 @@ jobs: - uses: actions/checkout@v7 - uses: ./.github/actions/install-swift with: - download-url: https://download.swift.org/development/ubuntu2204/swift-DEVELOPMENT-SNAPSHOT-2026-05-27-a/swift-DEVELOPMENT-SNAPSHOT-2026-05-27-a-ubuntu22.04.tar.gz + download-url: https://download.swift.org/development/ubuntu2204/swift-DEVELOPMENT-SNAPSHOT-2026-08-11-a/swift-DEVELOPMENT-SNAPSHOT-2026-08-11-a-ubuntu22.04.tar.gz - run: make bootstrap - run: ./Utilities/bridge-js-generate.sh - name: Check if BridgeJS generated files are up-to-date @@ -175,7 +178,7 @@ jobs: - uses: actions/checkout@v7 - uses: ./.github/actions/install-swift with: - download-url: https://download.swift.org/development/ubuntu2204/swift-DEVELOPMENT-SNAPSHOT-2026-05-27-a/swift-DEVELOPMENT-SNAPSHOT-2026-05-27-a-ubuntu22.04.tar.gz + download-url: https://download.swift.org/development/ubuntu2204/swift-DEVELOPMENT-SNAPSHOT-2026-08-11-a/swift-DEVELOPMENT-SNAPSHOT-2026-08-11-a-ubuntu22.04.tar.gz - uses: swiftwasm/setup-swiftwasm@v2 id: setup-wasm32-unknown-wasip1 with: { target: wasm32-unknown-wasip1 } @@ -198,7 +201,7 @@ jobs: - uses: actions/checkout@v7 - uses: ./.github/actions/install-swift with: - download-url: https://download.swift.org/development/ubuntu2204/swift-DEVELOPMENT-SNAPSHOT-2026-05-27-a/swift-DEVELOPMENT-SNAPSHOT-2026-05-27-a-ubuntu22.04.tar.gz + download-url: https://download.swift.org/development/ubuntu2204/swift-DEVELOPMENT-SNAPSHOT-2026-08-11-a/swift-DEVELOPMENT-SNAPSHOT-2026-08-11-a-ubuntu22.04.tar.gz - uses: swiftwasm/setup-swiftwasm@v2 id: setup-wasm32-unknown-wasip1 with: { target: wasm32-unknown-wasip1 } diff --git a/Benchmarks/Sources/Generated/BridgeJS.swift b/Benchmarks/Sources/Generated/BridgeJS.swift index 384ca35a2..5e3e11db8 100644 --- a/Benchmarks/Sources/Generated/BridgeJS.swift +++ b/Benchmarks/Sources/Generated/BridgeJS.swift @@ -2179,6 +2179,34 @@ fileprivate func _bjs_ArrayRoundtrip_wrap_extern(_ pointer: UnsafeMutableRawPoin return _bjs_ArrayRoundtrip_wrap_extern(pointer) } +extension SimpleStruct: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = SimpleStruct.bridgeJSMakeTypeHandle() +} + +extension Address: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Address.bridgeJSMakeTypeHandle() +} + +extension Person: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Person.bridgeJSMakeTypeHandle() +} + +extension ComplexStruct: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ComplexStruct.bridgeJSMakeTypeHandle() +} + +extension Point: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Point.bridgeJSMakeTypeHandle() +} + +extension APIResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = APIResult.bridgeJSMakeTypeHandle() +} + +extension ComplexResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ComplexResult.bridgeJSMakeTypeHandle() +} + #if arch(wasm32) @_extern(wasm, module: "Benchmarks", name: "bjs_benchmarkHelperNoop") fileprivate func bjs_benchmarkHelperNoop_extern() -> Void @@ -2238,4 +2266,25 @@ func _$benchmarkRunner(_ name: String, _ body: JSObject) throws(JSException) -> if let error = _swift_js_take_exception() { throw error } -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_Benchmarks_register_type_handles") +fileprivate func _bjs_Benchmarks_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_Benchmarks_register_type_handles") +public func _bjs_Benchmarks_register_type_handles() { + let typeIds: [Int32] = [ + SimpleStruct.bridgeJSTypeID, + Address.bridgeJSTypeID, + Person.bridgeJSTypeID, + ComplexStruct.bridgeJSTypeID, + Point.bridgeJSTypeID, + APIResult.bridgeJSTypeID, + ComplexResult.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_Benchmarks_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Examples/Embedded/Package.swift b/Examples/Embedded/Package.swift index 42702394a..1f88a8947 100644 --- a/Examples/Embedded/Package.swift +++ b/Examples/Embedded/Package.swift @@ -16,6 +16,9 @@ let package = Package( swiftSettings: [ .enableExperimentalFeature("Extern") ], + plugins: [ + .plugin(name: "BridgeJS", package: "JavaScriptKit") + ] ) ], swiftLanguageModes: [.v5] diff --git a/Examples/Embedded/Sources/EmbeddedApp/main.swift b/Examples/Embedded/Sources/EmbeddedApp/main.swift index 5e7f01a3c..c3e0dd3cd 100644 --- a/Examples/Embedded/Sources/EmbeddedApp/main.swift +++ b/Examples/Embedded/Sources/EmbeddedApp/main.swift @@ -1,5 +1,12 @@ import JavaScriptKit +@JS struct CounterLabel { + var count: Int + var text: String +} + +@JSFunction func echoValue(_ value: T) throws(JSException) -> T + let alert = JSObject.global.alert.object! let document = JSObject.global.document @@ -46,6 +53,17 @@ _ = encoderContainer.appendChild(textInputElement) _ = encoderContainer.appendChild(encodeResultElement) _ = document.body.appendChild(encoderContainer) +let genericResultElement = document.createElement("pre") +do { + let number = try echoValue(42) + let text = try echoValue("hello") + let label = try echoValue(CounterLabel(count: number, text: text)) + genericResultElement.innerText = .string("Generic import round-trip: \(label.text) \(label.count)") +} catch { + genericResultElement.innerText = "Generic import round-trip failed" +} +_ = document.body.appendChild(genericResultElement) + func print(_ message: String) { _ = JSObject.global.console.log(message) } diff --git a/Examples/Embedded/index.html b/Examples/Embedded/index.html index 93868214d..d280d7067 100644 --- a/Examples/Embedded/index.html +++ b/Examples/Embedded/index.html @@ -8,7 +8,13 @@ diff --git a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.swift b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.swift index 10976f793..328ae0610 100644 --- a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.swift +++ b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.swift @@ -231,6 +231,18 @@ fileprivate func _bjs_PlayBridgeJS_wrap_extern(_ pointer: UnsafeMutableRawPointe return _bjs_PlayBridgeJS_wrap_extern(pointer) } +extension PlayBridgeJSOutput: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PlayBridgeJSOutput.bridgeJSMakeTypeHandle() +} + +extension PlayBridgeJSDiagnostic: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PlayBridgeJSDiagnostic.bridgeJSMakeTypeHandle() +} + +extension PlayBridgeJSResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PlayBridgeJSResult.bridgeJSMakeTypeHandle() +} + #if arch(wasm32) @_extern(wasm, module: "PlayBridgeJS", name: "bjs_createTS2Swift") fileprivate func bjs_createTS2Swift_extern() -> Int32 @@ -274,4 +286,21 @@ func _$TS2Swift_convert(_ self: JSObject, _ ts: String) throws(JSException) -> S throw error } return String.bridgeJSLiftReturn(ret) -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_PlayBridgeJS_register_type_handles") +fileprivate func _bjs_PlayBridgeJS_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_PlayBridgeJS_register_type_handles") +public func _bjs_PlayBridgeJS_register_type_handles() { + let typeIds: [Int32] = [ + PlayBridgeJSOutput.bridgeJSTypeID, + PlayBridgeJSDiagnostic.bridgeJSTypeID, + PlayBridgeJSResult.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_PlayBridgeJS_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/main.swift b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/main.swift index a30eb3b06..3a4063945 100644 --- a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/main.swift +++ b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/main.swift @@ -70,7 +70,7 @@ import class Foundation.JSONDecoder let importTS = ImportTS(progress: .silent, moduleName: moduleName, skeleton: $0) return try importTS.finalize() } - let linker = BridgeJSLink(skeletons: [skeleton], sharedMemory: false) + let linker = BridgeJSLink(skeletons: [skeleton]) let linked = try linker.link() return PlayBridgeJSOutput( diff --git a/Makefile b/Makefile index 4b174e347..bbf031a00 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ SWIFT_SDK_ID ?= +BUILD_SYSTEM ?= swiftbuild ifeq ($(JAVASCRIPTKIT_DISABLE_TRACING_TRAIT),1) TRACING_ARGS := else @@ -16,7 +17,7 @@ unittest: echo "SWIFT_SDK_ID is not set. Run 'swift sdk list' and pass a matching SDK, e.g. 'make unittest SWIFT_SDK_ID='."; \ exit 2; \ } - swift package --build-system native --swift-sdk "$(SWIFT_SDK_ID)" \ + swift package --build-system "$(BUILD_SYSTEM)" --swift-sdk "$(SWIFT_SDK_ID)" \ $(TRACING_ARGS) \ --disable-sandbox \ js test --prelude ./Tests/prelude.mjs -Xnode --expose-gc diff --git a/Package.swift b/Package.swift index 63eacf6be..0504d4505 100644 --- a/Package.swift +++ b/Package.swift @@ -82,7 +82,7 @@ let package = Package( .testTarget( name: "JavaScriptKitTests", - dependencies: ["JavaScriptKit"], + dependencies: ["JavaScriptKit", "JavaScriptEventLoopTestSupport"], swiftSettings: [ .enableExperimentalFeature("Extern"), .define("Tracing", .when(traits: ["Tracing"])), @@ -191,7 +191,7 @@ let package = Package( ), .testTarget( name: "BridgeJSRuntimeTests", - dependencies: ["JavaScriptKit", "JavaScriptEventLoop"], + dependencies: ["JavaScriptKit", "JavaScriptEventLoop", "JavaScriptEventLoopTestSupport"], exclude: [ "bridge-js.config.json", "bridge-js.d.ts", @@ -220,7 +220,7 @@ let package = Package( ), .testTarget( name: "BridgeJSIdentityTests", - dependencies: ["JavaScriptKit", "JavaScriptEventLoop"], + dependencies: ["JavaScriptKit", "JavaScriptEventLoop", "JavaScriptEventLoopTestSupport"], exclude: [ "bridge-js.config.json", "Generated/JavaScript", diff --git a/Plugins/BridgeJS/README.md b/Plugins/BridgeJS/README.md index 9e1e0aa08..0905695c5 100644 --- a/Plugins/BridgeJS/README.md +++ b/Plugins/BridgeJS/README.md @@ -98,7 +98,7 @@ graph LR | `Dictionary` | `Record` | - | [#495](https://github.com/swiftwasm/JavaScriptKit/issues/495) | | `Set` | `Set` | - | [#397](https://github.com/swiftwasm/JavaScriptKit/issues/397) | | `Foundation.URL` | `string` | - | [#496](https://github.com/swiftwasm/JavaScriptKit/issues/496) | -| Generics | - | - | [#398](https://github.com/swiftwasm/JavaScriptKit/issues/398) | +| Generic function or method (`T`, `[T]`, `T?`, `[String: T]`) | `(value: T): T` | Depends on `T` | ✅ imports only ([#398](https://github.com/swiftwasm/JavaScriptKit/issues/398) for exports) | ### Import-specific (TypeScript -> Swift) diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift index 2cc551857..55b5889fe 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift @@ -91,6 +91,13 @@ public class ExportSwift { } } + withSpan("Render Generic Bridgeable Conformances") { [self] in + let genericConformanceCodegen = GenericConformanceCodegen() + for entry in skeleton.genericBridgeableTypeEntries { + decls.append(contentsOf: genericConformanceCodegen.renderConformance(typeName: entry.swiftName)) + } + } + try withSpan("Render Async Promise Helpers") { [self] in let asyncResolveTypes = skeleton.asyncPromiseResolveReturnTypes if !asyncResolveTypes.isEmpty { @@ -875,6 +882,57 @@ public class ExportSwift { } } +// MARK: - GenericConformanceCodegen + +struct GenericConformanceCodegen { + func renderConformance(typeName: String) -> [DeclSyntax] { + let printer = CodeFragmentPrinter() + printer.write("extension \(typeName): BridgedSwiftGenericBridgeable {") + printer.indent { + printer.write( + "@_spi(BridgeJS) public static let bridgeJSTypeHandle = \(typeName).bridgeJSMakeTypeHandle()" + ) + } + printer.write("}") + return ["\(raw: printer.lines.joined(separator: "\n"))"] + } +} + +// MARK: - GenericTypeRegistrationCodegen + +public struct GenericTypeRegistrationCodegen { + public init() {} + + public func render(for skeleton: BridgeJSSkeleton) -> String? { + guard let entries = skeleton.typeRegistrationEntries else { return nil } + let abiName = ABINameGenerator.typeRegistrationFunctionName(moduleName: skeleton.moduleName) + let printer = CodeFragmentPrinter() + printer.write("#if arch(wasm32)") + printer.write("@_extern(wasm, module: \"bjs\", name: \"\(abiName)\")") + printer.write("fileprivate func _\(abiName)_extern(_ base: UnsafePointer?, _ count: Int32)") + printer.nextLine() + printer.write("@_expose(wasm, \"\(abiName)\")") + printer.write("public func _\(abiName)() {") + printer.indent { + printer.write("let typeIds: [Int32] = [") + printer.indent { + for entry in entries { + printer.write("\(entry.swiftName).bridgeJSTypeID,") + } + } + printer.write("]") + printer.write("typeIds.withUnsafeBufferPointer { buffer in") + printer.indent { + printer.write("_\(abiName)_extern(buffer.baseAddress, Int32(buffer.count))") + } + printer.write("}") + } + printer.write("}") + printer.write("#endif") + return printer.lines.joined(separator: "\n") + } +} + // MARK: - StackCodegen /// Helper for stack-based lifting and lowering operations. @@ -896,6 +954,10 @@ struct StackCodegen { return "JSObject.bridgeJSStackPop()" case .void, .namespaceEnum: return "()" + case .generic: + fatalError( + "Generic parameters are only supported on imported declarations, not exported concrete-type codegen" + ) } } @@ -908,7 +970,7 @@ struct StackCodegen { return "\(raw: typeName)<\(raw: wrappedType.swiftType)>.bridgeJSStackPop()" case .jsObject(let className?): return "\(raw: typeName).bridgeJSStackPop().map { \(raw: className)(unsafelyWrapping: $0) }" - case .nullable, .void, .namespaceEnum, .closure, .unsafePointer, .swiftProtocol: + case .nullable, .void, .namespaceEnum, .closure, .unsafePointer, .swiftProtocol, .generic: fatalError("Invalid nullable wrapped type: \(wrappedType)") } } @@ -941,6 +1003,10 @@ struct StackCodegen { return lowerArrayStatements(elementType: elementType, accessor: accessor, varPrefix: varPrefix) case .dictionary(let valueType): return lowerDictionaryStatements(valueType: valueType, accessor: accessor, varPrefix: varPrefix) + case .generic: + fatalError( + "Generic parameters are only supported on imported declarations, not exported concrete-type codegen" + ) } } @@ -1596,12 +1662,34 @@ extension BridgeType { case .associatedValueEnum: return ["_BridgedSwiftAssociatedValueEnum"] case .rawValueEnum, .void, .unsafePointer, .namespaceEnum, - .swiftProtocol, .closure, .nullable, .array, .dictionary, .alias: + .swiftProtocol, .closure, .nullable, .array, .dictionary, .alias, .generic: // Not supported yet. return nil } } + /// Stack expressions for bare `T` and `T?`, the only generic shapes that + /// cannot reuse the concrete emission: `bridgeJSLowerParameter()` names + /// per-type members that the generic constraint erases to the stack, so + /// `bridgeJSStackPush()`/`bridgeJSStackPop()` is the shared spelling. + /// `[T]` and `[String: T]` go through the ordinary paths via the `Array` + /// and `Dictionary` stack conformances. + var genericStackPopExpression: String? { + switch self { + case .generic(let name): return "\(name).bridgeJSStackPop()" + case .nullable(.generic(let name), _): return "Optional<\(name)>.bridgeJSStackPop()" + default: return nil + } + } + + func genericStackPushStatement(value: String) -> String? { + switch self { + case .generic, .nullable(.generic, _): + return "\(value).bridgeJSStackPush()" + default: return nil + } + } + var swiftType: String { switch self { case .bool: return "Bool" @@ -1631,6 +1719,7 @@ extension BridgeType { let closureType = "(\(paramTypes))\(effectsStr) -> \(signature.returnType.swiftType)" return useJSTypedClosure ? "JSTypedClosure<\(closureType)>" : closureType case .alias(let name, _): return name + case .generic(let name): return name } } @@ -1717,6 +1806,10 @@ extension BridgeType { return LiftingIntrinsicInfo(parameters: []) case .alias(_, let underlying): return try underlying.liftParameterInfo() + case .generic: + throw BridgeJSCoreError( + "Generic parameters are only supported on imported declarations, not exported concrete-type codegen" + ) } } @@ -1770,6 +1863,10 @@ extension BridgeType { return .array case .alias(_, let underlying): return try underlying.loweringReturnInfo() + case .generic: + throw BridgeJSCoreError( + "Generic parameters are only supported on imported declarations, not exported concrete-type codegen" + ) } } } diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift index 286352915..cff1aa979 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift @@ -143,6 +143,11 @@ public struct ImportTS { } func lowerParameter(param: Parameter) throws { + if let genericPush = param.type.genericStackPushStatement(value: param.name) { + stackLoweringStmts.insert(genericPush, at: 0) + return + } + let loweringInfo = try param.type.loweringParameterInfo(context: context) switch param.type { @@ -237,6 +242,18 @@ public struct ImportTS { abiParameterForwardings.insert(contentsOf: ["resolveRef", "rejectRef"], at: 0) } + private func appendTypeIDParameter(index: Int, genericParameterName: String) { + let abiParamName = ABINameGenerator.genericTypeIdParameterName(index: index) + abiParameterSignatures.append((abiParamName, .i32)) + abiParameterForwardings.append("\(genericParameterName).bridgeJSTypeID") + } + + func appendTypeIDParameters(_ genericParameterNames: [String]) { + for (index, name) in genericParameterNames.enumerated() { + appendTypeIDParameter(index: index, genericParameterName: name) + } + } + func call() throws { for stmt in stackLoweringStmts { body.write(stmt.description) @@ -293,14 +310,18 @@ public struct ImportTS { body.write("return \(returnType.swiftType).bridgeJSLiftReturnFromSideChannel()") } else { let liftExpr: String - switch returnType { - case .closure(let signature, _): - liftExpr = "_BJS_Closure_\(signature.mangleName).bridgeJSLift(ret)" - default: - if liftingInfo.valueToLift != nil { - liftExpr = "\(returnType.swiftType).bridgeJSLiftReturn(ret)" - } else { - liftExpr = "\(returnType.swiftType).bridgeJSLiftReturn()" + if let genericPop = returnType.genericStackPopExpression { + liftExpr = genericPop + } else { + switch returnType { + case .closure(let signature, _): + liftExpr = "_BJS_Closure_\(signature.mangleName).bridgeJSLift(ret)" + default: + if liftingInfo.valueToLift != nil { + liftExpr = "\(returnType.swiftType).bridgeJSLiftReturn(ret)" + } else { + liftExpr = "\(returnType.swiftType).bridgeJSLiftReturn()" + } } } body.write("return \(liftExpr)") @@ -359,7 +380,8 @@ public struct ImportTS { name: String, parameters: [Parameter], returnType: BridgeType, - effects: Effects + effects: Effects, + genericParameters: [String] = [] ) -> DeclSyntax { let printer = CodeFragmentPrinter() let signature = SwiftSignatureBuilder.buildFunctionSignature( @@ -368,7 +390,12 @@ public struct ImportTS { effects: effects, useWildcardLabels: true ) - printer.write("func \(name.backtickIfNeeded())\(signature) {") + let genericClause = + genericParameters.isEmpty + ? "" + : "<" + genericParameters.map { "\($0): BridgedSwiftGenericBridgeable" }.joined(separator: ", ") + + ">" + printer.write("func \(name.backtickIfNeeded())\(genericClause)\(signature) {") printer.indent { printer.write(lines: body.lines) } @@ -428,6 +455,7 @@ public struct ImportTS { for param in function.parameters { try builder.lowerParameter(param: param) } + builder.appendTypeIDParameters(function.genericParameterNames) try builder.call() try builder.liftReturnValue() topLevelDecls.append(builder.renderImportDecl()) @@ -436,7 +464,8 @@ public struct ImportTS { name: Self.thunkName(function: function), parameters: function.parameters, returnType: function.returnType, - effects: function.effects + effects: function.effects, + genericParameters: function.genericParameterNames ) .with(\.leadingTrivia, Self.renderDocumentation(documentation: function.documentation)) ] @@ -457,6 +486,7 @@ public struct ImportTS { for param in method.parameters { try builder.lowerParameter(param: param) } + builder.appendTypeIDParameters(method.genericParameterNames) try builder.call() try builder.liftReturnValue() topLevelDecls.append(builder.renderImportDecl()) @@ -465,7 +495,8 @@ public struct ImportTS { name: Self.thunkName(type: type, method: method), parameters: [selfParameter] + method.parameters, returnType: method.returnType, - effects: method.effects + effects: method.effects, + genericParameters: method.genericParameterNames ) ] } @@ -481,6 +512,7 @@ public struct ImportTS { for param in method.parameters { try builder.lowerParameter(param: param) } + builder.appendTypeIDParameters(method.genericParameterNames) try builder.call() try builder.liftReturnValue() topLevelDecls.append(builder.renderImportDecl()) @@ -489,7 +521,8 @@ public struct ImportTS { name: Self.thunkName(type: type, method: method), parameters: method.parameters, returnType: method.returnType, - effects: method.effects + effects: method.effects, + genericParameters: method.genericParameterNames ) ] } @@ -505,6 +538,7 @@ public struct ImportTS { for param in constructor.parameters { try builder.lowerParameter(param: param) } + builder.appendTypeIDParameters(constructor.genericParameterNames) try builder.call() try builder.liftReturnValue() topLevelDecls.append(builder.renderImportDecl()) @@ -513,7 +547,8 @@ public struct ImportTS { name: Self.thunkName(type: type), parameters: constructor.parameters, returnType: .jsObject(nil), - effects: effects + effects: effects, + genericParameters: constructor.genericParameterNames ) ] } @@ -932,17 +967,20 @@ extension BridgeType { return LoweringParameterInfo(loweredParameters: [("value", wasmType)]) case .associatedValueEnum: return LoweringParameterInfo(loweredParameters: [("caseId", .i32)]) - case .swiftStruct: - // `@JS struct` parameters always use the stack ABI (same as arrays/dictionaries). - return LoweringParameterInfo(loweredParameters: []) case .namespaceEnum: throw BridgeJSCoreError("Namespace enums cannot be used as parameters") case .nullable(let wrappedType, _): let wrappedInfo = try wrappedType.loweringParameterInfo(context: context) + if wrappedInfo.loweredParameters.isEmpty { + return LoweringParameterInfo(loweredParameters: []) + } var params = [("isSome", WasmCoreType.i32)] params.append(contentsOf: wrappedInfo.loweredParameters) return LoweringParameterInfo(loweredParameters: params, useBorrowing: wrappedInfo.useBorrowing) - case .array, .dictionary: + case .swiftStruct: + // `@JS struct` parameters always use the stack ABI (same as arrays/dictionaries). + return LoweringParameterInfo(loweredParameters: []) + case .array, .dictionary, .generic: return LoweringParameterInfo(loweredParameters: []) case .alias: preconditionFailure("`.alias` must be resolved by `.unaliased` before reaching loweringParameterInfo") @@ -995,9 +1033,6 @@ extension BridgeType { return LiftingReturnInfo(valueToLift: wasmType) case .associatedValueEnum: return LiftingReturnInfo(valueToLift: .i32) - case .swiftStruct: - // `@JS struct` returns always use the stack ABI (same as arrays/dictionaries). - return LiftingReturnInfo(valueToLift: nil) case .namespaceEnum: throw BridgeJSCoreError("Namespace enums cannot be used as return values") case .nullable(let wrappedType, _): @@ -1008,7 +1043,10 @@ extension BridgeType { } let wrappedInfo = try wrappedType.liftingReturnInfo(context: context) return LiftingReturnInfo(valueToLift: wrappedInfo.valueToLift) - case .array, .dictionary: + case .swiftStruct: + // `@JS struct` returns always use the stack ABI (same as arrays/dictionaries). + return LiftingReturnInfo(valueToLift: nil) + case .array, .dictionary, .generic: return LiftingReturnInfo(valueToLift: nil) case .alias: preconditionFailure("`.alias` must be resolved by `.unaliased` before reaching liftingReturnInfo") diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift index d327de307..fb81d9089 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift @@ -7,6 +7,79 @@ import BridgeJSUtilities import BridgeJSSkeleton #endif +/// Outcome of attempting to resolve a type as a reference to a generic parameter. +enum GenericParameterResolution { + case resolved(BridgeType) + /// A non-nil message is a hard diagnostic; `nil` means the type isn't generic + /// and the caller should fall back to normal type resolution. + case rejected(String?) +} + +func resolveGenericTypeReference( + for type: TypeSyntax, + genericParameterNames: [String] +) -> GenericParameterResolution { + if let identifier = type.as(IdentifierTypeSyntax.self), + identifier.genericArgumentClause == nil, + genericParameterNames.contains(identifier.name.text) + { + return .resolved(.generic(identifier.name.text)) + } + if let wrapped = wrappedGenericBridgeType(for: type, genericParameterNames: genericParameterNames) { + return .resolved(wrapped) + } + if !genericParameterNames.isEmpty, + let wrapped = wrappedGenericParameter(in: type, genericParameterNames: genericParameterNames) + { + return .rejected( + "Generic parameter '\(wrapped)' may only be used as a bare type; wrapping it beyond 'T?', '[T]' and '[String: T]' is not supported." + ) + } + return .rejected(nil) +} + +private func wrappedGenericParameter( + in type: TypeSyntax, + genericParameterNames: [String] +) -> String? { + for token in type.tokens(viewMode: .sourceAccurate) { + if case .identifier(let text) = token.tokenKind, genericParameterNames.contains(text) { + return text + } + } + return nil +} + +private func wrappedGenericBridgeType( + for type: TypeSyntax, + genericParameterNames: [String] +) -> BridgeType? { + func bareGenericName(_ inner: TypeSyntax) -> String? { + guard let identifier = inner.as(IdentifierTypeSyntax.self), + identifier.genericArgumentClause == nil, + genericParameterNames.contains(identifier.name.text) + else { + return nil + } + return identifier.name.text + } + if let arrayType = type.as(ArrayTypeSyntax.self), let name = bareGenericName(arrayType.element) { + return .array(.generic(name)) + } + if let optionalType = type.as(OptionalTypeSyntax.self), let name = bareGenericName(optionalType.wrappedType) { + return .nullable(.generic(name), .null) + } + if let dictType = type.as(DictionaryTypeSyntax.self), + let keyIdentifier = dictType.key.as(IdentifierTypeSyntax.self), + keyIdentifier.genericArgumentClause == nil, + keyIdentifier.name.text == "String", + let name = bareGenericName(dictType.value) + { + return .dictionary(.generic(name)) + } + return nil +} + /// Builds BridgeJS skeletons from Swift source files using SwiftSyntax walk for API collection. /// /// This is a shared entry point for producing: @@ -66,6 +139,39 @@ public final class SwiftToSkeleton { sourceFiles.append((sourceFile, inputFilePath)) } + private func resolveDeferredExtensions(_ exportCollectors: [ExportSwiftAPICollector]) { + var pendingExtensions = exportCollectors.flatMap { collector in + collector.deferredExtensions.map { (owner: collector, declaration: $0) } + } + var previousCount: Int + // An extended type might be defined in another extension, so keep resolving until no more progress is made. + repeat { + previousCount = pendingExtensions.count + var nextPendingExtensions: [(owner: ExportSwiftAPICollector, declaration: ExtensionDeclSyntax)] = [] + for pending in pendingExtensions { + if !resolveExtension(pending.declaration, in: exportCollectors) { + nextPendingExtensions.append(pending) + } + } + pendingExtensions = nextPendingExtensions + } while pendingExtensions.count < previousCount + for pending in pendingExtensions { + pending.owner.diagnoseUnresolvedExtension(pending.declaration) + } + } + + private func resolveExtension( + _ declaration: ExtensionDeclSyntax, + in exportCollectors: [ExportSwiftAPICollector] + ) -> Bool { + for collector in exportCollectors { + if collector.resolveExtension(declaration) { + return true + } + } + return false + } + public func finalize() throws -> BridgeJSSkeleton { var perSourceErrors: [(inputFilePath: String, errors: [DiagnosticError])] = [] var importedFiles: [ImportedFileSkeleton] = [] @@ -149,15 +255,14 @@ public final class SwiftToSkeleton { validatedJavaScriptModulePaths.insert(path) } - let exportErrors = exportCollector.errors.filter { $0.severity == .error } let importErrorsFatal = importCollector.errors.filter { $0.severity == .error && !$0.message.contains("Unsupported type '") } - let fileWarnings = (exportCollector.errors + importCollector.errors).filter { $0.severity == .warning } + let fileWarnings = importCollector.errors.filter { $0.severity == .warning } warnings.append(contentsOf: fileWarnings.map { (file: inputFilePath, diagnostic: $0) }) - if !exportErrors.isEmpty || !importErrorsFatal.isEmpty { + if !importErrorsFatal.isEmpty { perSourceErrors.append( - (inputFilePath: inputFilePath, errors: exportErrors + importErrorsFatal) + (inputFilePath: inputFilePath, errors: importErrorsFatal) ) } @@ -172,8 +277,18 @@ public final class SwiftToSkeleton { } // Resolve extensions against all collectors. This needs to happen at this point so we can resolve both same file and cross file extensions. - for source in exportCollectors { - source.resolveDeferredExtensions(against: exportCollectors) + resolveDeferredExtensions(exportCollectors) + + // We have to collect diagnostics after all deferred extensions are resolved, since they could generate some. + for ((_, inputFilePath), exportCollector) in zip(sourceFiles, exportCollectors) { + let exportErrors = exportCollector.errors.filter { $0.severity == .error } + let fileWarnings = exportCollector.errors.filter { $0.severity == .warning } + warnings.append(contentsOf: fileWarnings.map { (file: inputFilePath, diagnostic: $0) }) + if !exportErrors.isEmpty { + perSourceErrors.append( + (inputFilePath: inputFilePath, errors: exportErrors) + ) + } } for collector in exportCollectors { @@ -452,12 +567,12 @@ public final class SwiftToSkeleton { if let typeDecl = typeDeclResolver.resolve(type) { if typeDecl.is(ProtocolDeclSyntax.self) { - let swiftCallName = SwiftToSkeleton.computeSwiftCallName(for: typeDecl, itemName: typeDecl.name.text) + let swiftCallName = computeSwiftCallName(for: typeDecl, itemName: typeDecl.name.text) return .swiftProtocol(swiftCallName) } if let enumDecl = typeDecl.as(EnumDeclSyntax.self) { - let swiftCallName = SwiftToSkeleton.computeSwiftCallName(for: enumDecl, itemName: enumDecl.name.text) + let swiftCallName = computeSwiftCallName(for: enumDecl, itemName: enumDecl.name.text) if let jsAttribute = enumDecl.attributes.firstJSAttribute, let aliasTarget = extractAliasTarget(from: jsAttribute) { @@ -496,7 +611,7 @@ public final class SwiftToSkeleton { } if let structDecl = typeDecl.as(StructDeclSyntax.self) { - let swiftCallName = SwiftToSkeleton.computeSwiftCallName( + let swiftCallName = computeSwiftCallName( for: structDecl, itemName: structDecl.name.text ) @@ -514,7 +629,7 @@ public final class SwiftToSkeleton { guard typeDecl.is(ClassDeclSyntax.self) || typeDecl.is(ActorDeclSyntax.self) else { return nil } - let swiftCallName = SwiftToSkeleton.computeSwiftCallName(for: typeDecl, itemName: typeDecl.name.text) + let swiftCallName = computeSwiftCallName(for: typeDecl, itemName: typeDecl.name.text) // A type annotated with @JSClass is a JavaScript object wrapper (imported), // even if it is declared as a Swift class. @@ -554,7 +669,7 @@ public final class SwiftToSkeleton { private func resolveExternal(for type: TypeSyntax, errors: inout [DiagnosticError]) -> BridgeType? { guard !externalModuleIndex.isEmpty, - var components = typeDeclResolver.qualifiedComponents(from: type) + var components = type.qualifiedComponents else { return nil } @@ -693,27 +808,50 @@ public final class SwiftToSkeleton { return nil } - /// Computes the full Swift call name by walking up the AST hierarchy to find all parent enums + /// This currently doesn’t work correctly for extensions on types defined in other modules, + /// which is fine for now since we don’t support extending @JS types from other modules. + /// This will need updating when we do. + fileprivate func enclosingDeclarations(of node: some SyntaxProtocol) -> [Syntax] { + var declarations: [Syntax] = [] + var visitedExtendedTypes: Set = [] + var currentNode: Syntax? = Syntax(node).parent + + while let parent = currentNode { + if let extensionDecl = parent.as(ExtensionDeclSyntax.self) { + if let extendedDecl = typeDeclResolver.resolveExtensionTarget(extensionDecl.extendedType), + visitedExtendedTypes.insert(extendedDecl.id).inserted + { + declarations.append(Syntax(extendedDecl)) + currentNode = Syntax(extendedDecl).parent + } else { + currentNode = parent.parent + } + } else { + declarations.append(parent) + currentNode = parent.parent + } + } + return declarations + } + /// This generates the qualified name needed for Swift code generation (e.g., "Networking.API.HTTPServer") - fileprivate static func computeSwiftCallName(for node: some SyntaxProtocol, itemName: String) -> String { + fileprivate func computeSwiftCallName(for node: some SyntaxProtocol, itemName: String) -> String { var swiftPath: [String] = [] - var currentNode: Syntax? = node.parent - while let parent = currentNode { - if let enumDecl = parent.as(EnumDeclSyntax.self), + for declaration in enclosingDeclarations(of: node) { + if let enumDecl = declaration.as(EnumDeclSyntax.self), enumDecl.attributes.hasJSAttribute() { swiftPath.insert(enumDecl.name.text, at: 0) - } else if let structDecl = parent.as(StructDeclSyntax.self), + } else if let structDecl = declaration.as(StructDeclSyntax.self), structDecl.attributes.hasJSAttribute() { swiftPath.insert(structDecl.name.text, at: 0) - } else if let classDecl = parent.as(ClassDeclSyntax.self), + } else if let classDecl = declaration.as(ClassDeclSyntax.self), classDecl.attributes.hasJSAttribute() { swiftPath.insert(classDecl.name.text, at: 0) } - currentNode = parent.parent } if swiftPath.isEmpty { @@ -731,6 +869,28 @@ public final class SwiftToSkeleton { return String(name.dropFirst().dropLast()) } + fileprivate static func isValidJSIdentifier(_ name: String) -> Bool { + func isIdentifierPart(_ scalar: Unicode.Scalar, isStart: Bool) -> Bool { + switch scalar { + case "a"..."z", "A"..."Z", "_", "$": + return true + case "0"..."9": + return !isStart + default: + return false + } + } + guard let first = name.unicodeScalars.first, isIdentifierPart(first, isStart: true) else { + return false + } + return name.unicodeScalars.dropFirst().allSatisfy { isIdentifierPart($0, isStart: false) } + } + + fileprivate static func isBridgeableGenericConstraint(_ constraint: String?) -> Bool { + constraint == "BridgedSwiftGenericBridgeable" + || constraint == "JavaScriptKit.BridgedSwiftGenericBridgeable" + } + } private enum ExportSwiftConstants { @@ -763,6 +923,17 @@ extension AttributeListSyntax { } } +private final class JSAttributeFinder: SyntaxVisitor { + private(set) var found = false + + override func visit(_ node: AttributeSyntax) -> SyntaxVisitorContinueKind { + if node.attributeNameText == "JS" { + found = true + } + return .skipChildren + } +} + private final class ExportSwiftAPICollector: SyntaxAnyVisitor { var exportedFunctions: [ExportedFunction] = [] /// The names of the exported classes, in the order they were written in the source file @@ -1202,10 +1373,6 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { diagnoseNestedOptional(node: param.type, type: param.type.trimmedDescription) continue } - if case .nullable(let wrappedType, _) = type, wrappedType.isOptional { - diagnoseNestedOptional(node: param.type, type: param.type.trimmedDescription) - continue - } let name = param.secondName?.text ?? param.firstName.text let label = param.firstName.text @@ -1290,7 +1457,17 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { return nil } + if let genericClause = node.genericParameterClause, let firstGenericParam = genericClause.parameters.first { + diagnose( + node: firstGenericParam, + message: + "Generic parameters on exported @JS functions are not supported yet. Generic functions are currently only supported on imported @JSFunction declarations." + ) + return nil + } + let name = node.name.text + let jsName = extractValidatedJSName(from: jsAttribute) let attributeNamespace = extractNamespace(from: jsAttribute) let computedNamespace = computeNamespace(for: node) @@ -1378,7 +1555,7 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { classNameForABI = nil } abiName = ABINameGenerator.generateABIName( - baseName: name, + baseName: jsName ?? name, namespace: finalNamespace, staticContext: isStatic ? staticContext : nil, className: classNameForABI @@ -1390,6 +1567,7 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { return ExportedFunction( name: name, + jsName: jsName, abiName: abiName, parameters: parameters, returnType: returnType, @@ -1469,6 +1647,45 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { return Effects(isAsync: isAsync, isThrows: isThrows, isStatic: isStatic) } + private func extractJSName( + from jsAttribute: AttributeSyntax + ) -> String? { + guard let arguments = jsAttribute.arguments?.as(LabeledExprListSyntax.self), + let nameArg = arguments.first, + nameArg.label == nil, + let stringLiteral = nameArg.expression.as(StringLiteralExprSyntax.self), + stringLiteral.segments.count == 1, + let name = stringLiteral.segments.first?.as(StringSegmentSyntax.self)?.content.text + else { + return nil + } + return name + } + + private func extractValidatedJSName( + from jsAttribute: AttributeSyntax + ) -> String? { + guard let jsName = extractJSName(from: jsAttribute) else { return nil } + guard SwiftToSkeleton.isValidJSIdentifier(jsName) else { + diagnose( + node: jsAttribute, + message: "`\(jsName)` is not a valid JavaScript identifier" + ) + return nil + } + return jsName + } + + private func diagnoseUnsupportedJSName( + from jsAttribute: AttributeSyntax + ) { + guard extractJSName(from: jsAttribute) != nil else { return } + diagnose( + node: jsAttribute, + message: "A separate name for JavaScript is not supported here" + ) + } + private func extractNamespace( from jsAttribute: AttributeSyntax ) -> [String]? { @@ -1515,6 +1732,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { override func visit(_ node: InitializerDeclSyntax) -> SyntaxVisitorContinueKind { guard let jsAttribute = node.attributes.firstJSAttribute else { return .skipChildren } + diagnoseUnsupportedJSName(from: jsAttribute) + switch state { case .classBody(_, let classKey): if extractNamespace(from: jsAttribute) != nil { @@ -1636,6 +1855,15 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { } } + let jsName = extractValidatedJSName(from: jsAttribute) + if jsName != nil, node.bindings.count > 1 { + diagnose( + node: jsAttribute, + message: "Name targets declaration with multiple bindings", + hint: "Declare each property with a different JS name separately" + ) + } + // Process each binding (variable declaration) for binding in node.bindings { guard let pattern = binding.pattern.as(IdentifierPatternSyntax.self) else { @@ -1663,6 +1891,7 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { let exportedProperty = ExportedProperty( name: propertyName, + jsName: jsName, type: propertyType, isReadonly: isReadonly, isStatic: isStatic, @@ -1693,6 +1922,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { return .skipChildren } + diagnoseUnsupportedJSName(from: jsAttribute) + if let aliasTarget = parent.extractAliasTarget(from: jsAttribute) { recordAlias(node: node, jsAttribute: jsAttribute, aliasTarget: aliasTarget) return .skipChildren @@ -1706,12 +1937,13 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { resolvedNamespace: namespaceResult.namespace, parentTypeNamespace: computeParentTypeNamespace(for: node) ) - let swiftCallName = SwiftToSkeleton.computeSwiftCallName(for: node, itemName: name) + let swiftCallName = parent.computeSwiftCallName(for: node, itemName: name) let explicitAccessControl = computeExplicitAtLeastInternalAccessControl( for: node, message: "Class visibility must be at least internal" ) let classIdentityMode = extractIdentityMode(from: jsAttribute) + let isFinal = node.modifiers.contains { $0.name.tokenKind == .keyword(.final) } ? true : nil let exportedClass = ExportedClass( name: name, swiftCallName: swiftCallName, @@ -1721,7 +1953,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { properties: [], namespace: effectiveNamespace, identityMode: classIdentityMode, - documentation: extractDocumentation(from: node) + documentation: extractDocumentation(from: node), + isFinal: isFinal ) let uniqueKey = makeKey(name: name, namespace: effectiveNamespace) @@ -1744,45 +1977,41 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { return .skipChildren } - func resolveDeferredExtensions(against collectors: [ExportSwiftAPICollector]) { - for ext in deferredExtensions { - var resolved = false - for collector in collectors { - if collector.resolveExtension(ext) { - resolved = true - break - } - } - if !resolved { - diagnose( - node: ext.extendedType, - message: "Unsupported type '\(ext.extendedType.trimmedDescription)'.", - hint: "You can only extend `@JS` annotated types defined in the same module" - ) - } + func diagnoseUnresolvedExtension(_ ext: ExtensionDeclSyntax) { + guard containsJSAnnotatedDeclaration(ext.memberBlock.members) else { + return } + diagnose( + node: ext.extendedType, + message: "Unsupported type '\(ext.extendedType.trimmedDescription)'.", + hint: "You can only extend `@JS` annotated types defined in the same module" + ) + } + + private func containsJSAnnotatedDeclaration(_ members: MemberBlockItemListSyntax) -> Bool { + let finder = JSAttributeFinder(viewMode: .sourceAccurate) + finder.walk(members) + return finder.found } /// Walks extension members under the matching type’s state, returning whether the type was found. - /// - /// Note: The lookup scans dictionaries keyed by `makeKey(name:namespace:)`, matching only by - /// plain name. If two types share a name but differ by namespace, `.first(where:)` picks - /// whichever comes first. This is acceptable today since namespace collisions are unlikely, - /// but may need refinement if namespace-qualified extension resolution is added. func resolveExtension(_ ext: ExtensionDeclSyntax) -> Bool { - let name = ext.extendedType.trimmedDescription + guard let extendedDecl = parent.typeDeclResolver.resolveExtensionTarget(ext.extendedType) else { + return false + } + let swiftCallName = parent.computeSwiftCallName(for: extendedDecl, itemName: extendedDecl.name.text) let state: State - if let entry = exportedClassByName.first(where: { $0.value.name == name }) { - state = .classBody(name: name, key: entry.key) - } else if let entry = exportedStructByName.first(where: { $0.value.name == name }) { - state = .structBody(name: name, key: entry.key) - } else if let entry = exportedEnumByName.first(where: { $0.value.name == name }) { - state = .enumBody(name: name, key: entry.key) - } else if exportedProtocolByName.values.contains(where: { $0.name == name }) { + if let entry = exportedClassByName.first(where: { $0.value.swiftCallName == swiftCallName }) { + state = .classBody(name: entry.value.name, key: entry.key) + } else if let entry = exportedStructByName.first(where: { $0.value.swiftCallName == swiftCallName }) { + state = .structBody(name: entry.value.name, key: entry.key) + } else if let entry = exportedEnumByName.first(where: { $0.value.swiftCallName == swiftCallName }) { + state = .enumBody(name: entry.value.name, key: entry.key) + } else if exportedProtocolByName.values.contains(where: { $0.name == swiftCallName }) { diagnose( node: ext.extendedType, message: "Protocol extensions are not supported by BridgeJS.", - hint: "You cannot extend `@JS` protocol '\(name)' with additional members" + hint: "You cannot extend `@JS` protocol '\(swiftCallName)' with additional members" ) return true } else { @@ -1801,7 +2030,7 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { jsAttribute: AttributeSyntax, aliasTarget: TypeSyntax ) { - let swiftCallName = SwiftToSkeleton.computeSwiftCallName(for: node, itemName: node.name.text) + let swiftCallName = parent.computeSwiftCallName(for: node, itemName: node.name.text) if extractNamespace(from: jsAttribute) != nil { errors.append( DiagnosticError( @@ -1843,6 +2072,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { return .skipChildren } + diagnoseUnsupportedJSName(from: jsAttribute) + if let aliasTarget = parent.extractAliasTarget(from: jsAttribute) { recordAlias(node: node, jsAttribute: jsAttribute, aliasTarget: aliasTarget) return .skipChildren @@ -1864,7 +2095,7 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { parentTypeNamespace: computeParentTypeNamespace(for: node) ) let emitStyle = extractEnumStyle(from: jsAttribute) ?? .const - let swiftCallName = SwiftToSkeleton.computeSwiftCallName(for: node, itemName: name) + let swiftCallName = parent.computeSwiftCallName(for: node, itemName: name) let explicitAccessControl = computeExplicitAtLeastInternalAccessControl( for: node, message: "Enum visibility must be at least internal" @@ -1968,6 +2199,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { return .skipChildren } + diagnoseUnsupportedJSName(from: jsAttribute) + let name = node.name.text let namespaceResult = resolveNamespace(from: jsAttribute, for: node, declarationType: "protocol") @@ -2031,6 +2264,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { return .skipChildren } + diagnoseUnsupportedJSName(from: jsAttribute) + if let aliasTarget = parent.extractAliasTarget(from: jsAttribute) { recordAlias(node: node, jsAttribute: jsAttribute, aliasTarget: aliasTarget) return .skipChildren @@ -2046,7 +2281,7 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { resolvedNamespace: namespaceResult.namespace, parentTypeNamespace: computeParentTypeNamespace(for: node) ) - let swiftCallName = SwiftToSkeleton.computeSwiftCallName(for: node, itemName: name) + let swiftCallName = parent.computeSwiftCallName(for: node, itemName: name) let explicitAccessControl = computeExplicitAtLeastInternalAccessControl( for: node, message: "Struct visibility must be at least internal" @@ -2169,6 +2404,10 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { protocolName: String, namespace: [String]? ) -> ExportedFunction? { + if let jsAttribute = node.attributes.firstJSAttribute { + diagnoseUnsupportedJSName(from: jsAttribute) + } + let name = node.name.text let parameters = parseParameters(from: node.signature.parameterClause, allowDefaults: false) @@ -2215,6 +2454,10 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { protocolName: String, protocolKey: String ) -> SyntaxVisitorContinueKind { + if let jsAttribute = node.attributes.firstJSAttribute { + diagnoseUnsupportedJSName(from: jsAttribute) + } + for binding in node.bindings { guard let pattern = binding.pattern.as(IdentifierPatternSyntax.self) else { diagnose(node: binding.pattern, message: "Complex patterns not supported for protocol properties") @@ -2353,10 +2596,9 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { /// Method allows for explicit namespace for top level enum, it will be used as base namespace and will concat enum name private func computeNamespace(for node: some SyntaxProtocol) -> [String]? { var namespace: [String] = [] - var currentNode: Syntax? = node.parent - while let parent = currentNode { - if let enumDecl = parent.as(EnumDeclSyntax.self), + for declaration in parent.enclosingDeclarations(of: node) { + if let enumDecl = declaration.as(EnumDeclSyntax.self), enumDecl.attributes.hasJSAttribute() { let isNamespaceEnum = !enumDecl.memberBlock.members.contains { member in @@ -2373,7 +2615,6 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { } } } - currentNode = parent.parent } return namespace.isEmpty ? nil : namespace @@ -2381,19 +2622,17 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { private func computeParentTypeNamespace(for node: some SyntaxProtocol) -> [String]? { var path: [String] = [] - var currentNode: Syntax? = node.parent - while let parent = currentNode { - if let structDecl = parent.as(StructDeclSyntax.self), + for declaration in parent.enclosingDeclarations(of: node) { + if let structDecl = declaration.as(StructDeclSyntax.self), structDecl.attributes.hasJSAttribute() { path.insert(structDecl.name.text, at: 0) - } else if let classDecl = parent.as(ClassDeclSyntax.self), + } else if let classDecl = declaration.as(ClassDeclSyntax.self), classDecl.attributes.hasJSAttribute() { path.insert(classDecl.name.text, at: 0) } - currentNode = parent.parent } return path.isEmpty ? nil : path @@ -3118,24 +3357,101 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor { // MARK: - Parsing Methods + /// Validates and collects the generic parameter names of an imported + /// `@JSFunction` declaration (function, method or initializer). + /// + /// Returns `nil` when a diagnostic was emitted; an empty array when the + /// declaration is not generic. + private func parseGenericParameterNames( + genericParameterClause: GenericParameterClauseSyntax?, + genericWhereClause: GenericWhereClauseSyntax?, + node: Syntax + ) -> [String]? { + var genericParameterNames: [String] = [] + if let genericParameterClause { + for genericParam in genericParameterClause.parameters { + let paramName = genericParam.name.text + let constraintText = genericParam.inheritedType?.trimmedDescription + guard SwiftToSkeleton.isBridgeableGenericConstraint(constraintText) else { + errors.append( + DiagnosticError( + node: Syntax(genericParam), + message: + "Generic parameter '\(paramName)' must be constrained to 'BridgedSwiftGenericBridgeable' to be used with @JSFunction." + ) + ) + return nil + } + genericParameterNames.append(paramName) + } + } + if genericWhereClause != nil { + errors.append( + DiagnosticError( + node: node, + message: "'where' clauses are not supported on @JSFunction declarations." + ) + ) + return nil + } + return genericParameterNames + } + private func parseConstructor( _ initializer: InitializerDeclSyntax, typeName: String ) -> ImportedConstructorSkeleton? { guard - validateEffects(initializer.signature.effectSpecifiers, node: initializer, attributeName: "JSFunction") - != nil + let effects = validateEffects( + initializer.signature.effectSpecifiers, + node: initializer, + attributeName: "JSFunction" + ) else { return nil } + guard + let genericParameterNames = parseGenericParameterNames( + genericParameterClause: initializer.genericParameterClause, + genericWhereClause: initializer.genericWhereClause, + node: Syntax(initializer) + ) + else { + return nil + } + if !genericParameterNames.isEmpty && effects.isAsync { + errors.append( + DiagnosticError( + node: Syntax(initializer), + message: "Generic @JSFunction declarations cannot be 'async' yet." + ) + ) + return nil + } + let parameters = parseParameters( + from: initializer.signature.parameterClause, + genericParameterNames: genericParameterNames + ) + for genericName in genericParameterNames + where !parameters.contains(where: { $0.type.referencedGenericName == genericName }) { + errors.append( + DiagnosticError( + node: Syntax(initializer), + message: + "The generic parameter '\(genericName)' must be used in a parameter of a generic @JSFunction initializer." + ) + ) + return nil + } // Initializers without an explicit modifier inherit access from the // enclosing `@JSClass` (the user's example pattern: `public init(...)` // inside `public struct JSDocument`). let parentLevel = currentType?.accessLevel ?? .internal let accessLevel = Self.bridgeAccessLevel(from: initializer.modifiers, default: parentLevel) return ImportedConstructorSkeleton( - parameters: parseParameters(from: initializer.signature.parameterClause), - accessLevel: accessLevel + parameters: parameters, + accessLevel: accessLevel, + genericParameters: genericParameterNames.isEmpty ? nil : genericParameterNames ) } @@ -3153,6 +3469,16 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor { return nil } + guard + let genericParameterNames = parseGenericParameterNames( + genericParameterClause: node.genericParameterClause, + genericWhereClause: node.genericWhereClause, + node: Syntax(node) + ) + else { + return nil + } + let baseName = SwiftToSkeleton.normalizeIdentifier(node.name.text) let extractedJSName = extractJSName(from: jsFunction) let from = extractJSImportFrom(from: jsFunction) @@ -3160,16 +3486,51 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor { let jsName = extractedJSName?.memberName let name = baseName - let parameters = parseParameters(from: node.signature.parameterClause) + let parameters = parseParameters( + from: node.signature.parameterClause, + genericParameterNames: genericParameterNames + ) let returnType: BridgeType if let returnTypeSyntax = node.signature.returnClause?.type { - guard let resolved = withLookupErrors({ parent.lookupType(for: returnTypeSyntax, errors: &$0) }) else { + guard + let resolved = lookupTypeWithGenerics( + for: returnTypeSyntax, + genericParameterNames: genericParameterNames + ) + else { return nil } returnType = resolved } else { returnType = .void } + + if !genericParameterNames.isEmpty { + if effects.isAsync { + errors.append( + DiagnosticError( + node: node, + message: "Generic @JSFunction declarations cannot be 'async' yet." + ) + ) + return nil + } + for genericName in genericParameterNames { + let usedInParameter = parameters.contains { $0.type.referencedGenericName == genericName } + let usedInReturn = returnType.referencedGenericName == genericName + if !usedInParameter && !usedInReturn { + errors.append( + DiagnosticError( + node: node, + message: + "The generic parameter '\(genericName)' must be used in a parameter or return type of a generic @JSFunction declaration." + ) + ) + return nil + } + } + } + let accessLevel = Self.bridgeAccessLevel(from: node.modifiers) return ImportedFunctionSkeleton( name: name, @@ -3179,7 +3540,8 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor { returnType: returnType, effects: effects, documentation: nil, - accessLevel: accessLevel + accessLevel: accessLevel, + genericParameters: genericParameterNames.isEmpty ? nil : genericParameterNames ) } @@ -3256,7 +3618,26 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor { // MARK: - Type and Parameter Parsing - private func parseParameters(from clause: FunctionParameterClauseSyntax) -> [Parameter] { + private func lookupTypeWithGenerics( + for type: TypeSyntax, + genericParameterNames: [String] + ) -> BridgeType? { + switch resolveGenericTypeReference(for: type, genericParameterNames: genericParameterNames) { + case .resolved(let bridgeType): + return bridgeType + case .rejected(let message): + if let message { + errors.append(DiagnosticError(node: Syntax(type), message: message)) + return nil + } + return withLookupErrors { parent.lookupType(for: type, errors: &$0) } + } + } + + private func parseParameters( + from clause: FunctionParameterClauseSyntax, + genericParameterNames: [String] = [] + ) -> [Parameter] { clause.parameters.compactMap { param in let type = param.type if type.is(MissingTypeSyntax.self) { @@ -3268,7 +3649,8 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor { ) return nil } - guard let bridgeType = withLookupErrors({ parent.lookupType(for: type, errors: &$0) }) else { + guard let bridgeType = lookupTypeWithGenerics(for: type, genericParameterNames: genericParameterNames) + else { return nil } let nameToken = param.secondName ?? param.firstName diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/TypeDeclResolver.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/TypeDeclResolver.swift index ec04421aa..4df546b8a 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/TypeDeclResolver.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/TypeDeclResolver.swift @@ -16,8 +16,7 @@ class TypeDeclResolver { private class TypeDeclCollector: SyntaxVisitor { let resolver: TypeDeclResolver - var scope: [TypeDecl] = [] - var rootTypeDecls: [TypeDecl] = [] + var scope: [String] = [] init(resolver: TypeDeclResolver) { self.resolver = resolver @@ -26,17 +25,14 @@ class TypeDeclResolver { func visitNominalDecl(_ node: TypeDecl) -> SyntaxVisitorContinueKind { let name = node.name.text - let qualifiedName = scope.map(\.name.text) + [name] + let qualifiedName = scope + [name] resolver.typeDeclByQualifiedName[qualifiedName] = node - scope.append(node) + scope.append(name) return .visitChildren } func visitPostNominalDecl() { - let type = scope.removeLast() - if scope.isEmpty { - rootTypeDecls.append(type) - } + scope.removeLast() } override func visit(_ node: StructDeclSyntax) -> SyntaxVisitorContinueKind { @@ -72,10 +68,21 @@ class TypeDeclResolver { override func visit(_ node: TypeAliasDeclSyntax) -> SyntaxVisitorContinueKind { let name = node.name.text - let qualifiedName = scope.map(\.name.text) + [name] + let qualifiedName = scope + [name] resolver.typeAliasByQualifiedName[qualifiedName] = node return .skipChildren } + + override func visit(_ node: ExtensionDeclSyntax) -> SyntaxVisitorContinueKind { + guard let components = node.memberScopeComponents else { + return .skipChildren + } + scope.append(contentsOf: components) + return .visitChildren + } + override func visitPost(_ node: ExtensionDeclSyntax) { + scope.removeLast(node.memberScopeComponents?.count ?? 0) + } } /// Collects type declarations from a parsed Swift source file @@ -85,37 +92,45 @@ class TypeDeclResolver { } /// Builds the type name scope for a given type usage - private func buildScope(type: IdentifierTypeSyntax) -> QualifiedName { + private func buildScope(type: TypeSyntax) -> QualifiedName { var innerToOuter: [String] = [] var context: SyntaxProtocol = type while let parent = context.parent { if let parent = parent.asProtocol(NamedDeclSyntax.self), parent.isProtocol(DeclGroupSyntax.self) { innerToOuter.append(parent.name.text) + } else if let extensionDecl = parent.as(ExtensionDeclSyntax.self), + let components = extensionDecl.memberScopeComponents + { + innerToOuter.append(contentsOf: components.reversed()) } context = parent } return innerToOuter.reversed() } - /// Looks up a qualified name of a type declaration by its unqualified type usage + /// Looks up a qualified name of a type declaration relative to its lexical scope /// Returns the qualified name hierarchy of the type declaration - /// If the type declaration is not found, returns the unqualified name - private func tryQualify(type: IdentifierTypeSyntax) -> QualifiedName { - let name = type.name.text + /// If the type declaration is not found, returns the original qualified name + private func tryQualify(type: TypeSyntax) -> QualifiedName? { + guard let components = type.qualifiedComponents else { + return nil + } let scope = buildScope(type: type) /// Search for the type declaration from the innermost scope to the outermost scope for i in (0...scope.count).reversed() { - let qualifiedName = Array(scope[0.. TypeDecl? { - let qualifiedName = tryQualify(type: type) + guard let qualifiedName = tryQualify(type: TypeSyntax(type)) else { + return nil + } return typeDeclByQualifiedName[qualifiedName] } @@ -128,47 +143,55 @@ class TypeDeclResolver { /// /// Supported inputs: /// - IdentifierTypeSyntax (e.g. `Method`) — resolved relative to the lexical scope, preferring the innermost enclosing type. - /// - MemberTypeSyntax (e.g. `Networking.API.Method`) — resolved by recursively building the fully qualified name. + /// - MemberTypeSyntax (e.g. `Networking.API.Method`) — resolved relative to the lexical scope before falling back to the fully qualified name. /// /// Resolution strategy: - /// 1. If the node is IdentifierTypeSyntax, call `lookupType(for:)` which attempts scope-aware qualification via `tryQualify`. - /// 2. Otherwise, attempt to build a fully qualified name with `qualifiedComponents(from:)` and look it up with `lookupType(fullyQualified:)`. + /// Build the qualified name with `qualifiedComponents`, then attempt scope-aware qualification via `tryQualify`. /// /// - Parameter type: The SwiftSyntax node representing a type appearance in source code. /// - Returns: The nominal declaration (enum/class/actor/struct) if found, otherwise nil. 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) + if let qualifiedName = tryQualify(type: type) { + return lookupType(fullyQualified: qualifiedName) } return nil } + func resolveExtensionTarget(_ type: TypeSyntax) -> TypeDecl? { + guard let qualifiedName = type.qualifiedComponents else { + return nil + } + return lookupType(fullyQualified: qualifiedName) + } + /// Resolves a type usage node to a type alias declaration /// /// - Parameter type: The SwiftSyntax node representing a type appearance in source code. /// - Returns: The type alias declaration if found, otherwise nil. func resolveTypeAlias(_ type: TypeSyntax) -> TypeAliasDeclSyntax? { - if let id = type.as(IdentifierTypeSyntax.self) { - let qualifiedName = tryQualify(type: id) + if let qualifiedName = tryQualify(type: type) { return typeAliasByQualifiedName[qualifiedName] } - if let components = qualifiedComponents(from: type) { - return typeAliasByQualifiedName[components] - } return nil } - func qualifiedComponents(from type: TypeSyntax) -> QualifiedName? { - if let m = type.as(MemberTypeSyntax.self) { - guard let base = qualifiedComponents(from: TypeSyntax(m.baseType)) else { return nil } +} + +extension TypeSyntax { + var qualifiedComponents: TypeDeclResolver.QualifiedName? { + if let m = self.as(MemberTypeSyntax.self) { + guard let base = TypeSyntax(m.baseType).qualifiedComponents else { return nil } return base + [m.name.text] - } else if let id = type.as(IdentifierTypeSyntax.self) { + } else if let id = self.as(IdentifierTypeSyntax.self) { return [id.name.text] } else { return nil } } } + +extension ExtensionDeclSyntax { + var memberScopeComponents: TypeDeclResolver.QualifiedName? { + extendedType.qualifiedComponents + } +} diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift index 1b6300595..163b7db6b 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift @@ -9,7 +9,6 @@ import BridgeJSUtilities public struct BridgeJSLink { var skeletons: [BridgeJSSkeleton] = [] - let sharedMemory: Bool /// Whether to track the lifetime of Swift objects. /// /// This is useful for debugging memory issues. @@ -19,11 +18,9 @@ public struct BridgeJSLink { private let importedModuleRegistry = ImportedJSModuleRegistry() public init( - skeletons: [BridgeJSSkeleton] = [], - sharedMemory: Bool = false + skeletons: [BridgeJSSkeleton] = [] ) { self.skeletons = skeletons - self.sharedMemory = sharedMemory } /// The identity mode from the config file, resolved from skeletons. @@ -31,6 +28,10 @@ public struct BridgeJSLink { skeletons.compactMap(\.exported).compactMap(\.identityMode).first ?? "none" } + var hasGenerics: Bool { + skeletons.contains { $0.imported?.hasGenericDeclarations ?? false } + } + /// Whether a class should use identity caching based on its annotation and the config default. private func shouldUseIdentityCache(for klass: ExportedClass) -> Bool { // Per-class annotation takes priority @@ -235,7 +236,7 @@ public struct BridgeJSLink { for function in skeleton.functions { if function.namespace == nil { var (js, dts) = try renderExportedFunction(function: function) - js[0] = "\(function.name): " + js[0] + js[0] = "\(function.resolvedJSName): " + js[0] js[js.count - 1] += "," data.exportsLines.append(contentsOf: js) data.dtsExportLines.append(contentsOf: dts) @@ -266,7 +267,9 @@ public struct BridgeJSLink { try renderImportedFunction(importObjectBuilder: importObjectBuilder, function: function) } for type in fileSkeleton.types { - if type.constructor != nil, type.from == nil { + // Matches the condition rendering the type into the `getImports` result + // type: both its constructor and its static methods are looked up there. + if type.from == nil, type.constructor != nil || !type.staticMethods.isEmpty { data.needsImportsObject = true } try renderImportedType(importObjectBuilder: importObjectBuilder, type: type) @@ -311,7 +314,7 @@ public struct BridgeJSLink { } private func generateVariableDeclarations() -> [String] { - return [ + var declarations: [String] = [ "let \(JSGlueVariableScope.reservedInstance);", "let \(JSGlueVariableScope.reservedMemory);", "let \(JSGlueVariableScope.reservedSetException);", @@ -335,10 +338,32 @@ public struct BridgeJSLink { "let \(JSGlueVariableScope.reservedTaStack) = [];", "const \(JSGlueVariableScope.reservedEnumHelpers) = {};", "const \(JSGlueVariableScope.reservedStructHelpers) = {};", + ] + if hasGenerics { + declarations.append("const \(JSGlueVariableScope.reservedCodecByTypeId) = new Map();") + declarations.append("let __bjs_typeHandlesRegistered = false;") + declarations.append("function __bjs_registerTypeHandles() {") + declarations.append(" if (__bjs_typeHandlesRegistered) {") + declarations.append(" return;") + declarations.append(" }") + declarations.append(" __bjs_typeHandlesRegistered = true;") + declarations.append( + " \(JSGlueVariableScope.reservedInstance).exports[\"\(ABINameGenerator.coreTypeRegistrationFunctionName)\"]();" + ) + for skeleton in skeletons { + guard skeleton.typeRegistrationEntries != nil else { continue } + let name = ABINameGenerator.typeRegistrationFunctionName(moduleName: skeleton.moduleName) + declarations.append(" \(JSGlueVariableScope.reservedInstance).exports[\"\(name)\"]();") + } + declarations.append("}") + declarations.append(contentsOf: GenericJSCodegen.runtimeHelperDeclarations()) + } + declarations.append(contentsOf: [ "", "let _exports = null;", "let bjs = null;", - ] + ]) + return declarations } /// JS const (in the import glue scope) holding the `Symbol` under which a promise's @@ -375,9 +400,83 @@ public struct BridgeJSLink { printer.write(lines: lines) } + private func makeCodecPrintContext(printer: CodeFragmentPrinter) -> IntrinsicJSFragment.PrintCodeContext { + IntrinsicJSFragment.PrintCodeContext( + scope: JSGlueVariableScope(intrinsicRegistry: intrinsicRegistry), + printer: printer, + hasDirectAccessToSwiftClass: false, + classNamespaces: intrinsicRegistry.classNamespaces + ) + } + + private func genericCodecReference(type: BridgeType, into printer: CodeFragmentPrinter) throws -> String { + try ContainerCodecJS.codecExpression(for: type, context: makeCodecPrintContext(printer: printer)) + } + + private func writeTypeHandleRegistrationBody(into printer: CodeFragmentPrinter) { + printer.write( + "const typeIds = new Int32Array(\(JSGlueVariableScope.reservedMemory).buffer, base >>> 0, count >>> 0);" + ) + printer.write("for (let i = 0; i < count; i++) {") + printer.indent { + printer.write("\(JSGlueVariableScope.reservedCodecByTypeId).set(typeIds[i], codecs[i]);") + } + printer.write("}") + } + + private func generateCoreTypeRegistrationHook(into printer: CodeFragmentPrinter) throws { + let hookName = ABINameGenerator.coreTypeRegistrationFunctionName + guard hasGenerics else { + printer.write("bjs[\"\(hookName)\"] = function() {};") + return + } + try ContainerCodecJS.registerPrimitiveCodecs(context: makeCodecPrintContext(printer: printer)) + printer.write("bjs[\"\(hookName)\"] = function(base, count) {") + printer.indent { + printer.write("const codecs = [") + printer.indent { + for primitive in BridgeType.genericBridgeablePrimitives { + printer.write("\(JSGlueVariableScope.reservedPrimitiveCodecs).\(primitive.token),") + } + } + printer.write("];") + writeTypeHandleRegistrationBody(into: printer) + } + printer.write("}") + } + + private func generateTypeRegistrationHooks(into printer: CodeFragmentPrinter) throws { + try generateCoreTypeRegistrationHook(into: printer) + for skeleton in skeletons { + guard let moduleEntries = skeleton.typeRegistrationEntries else { continue } + let hookName = ABINameGenerator.typeRegistrationFunctionName(moduleName: skeleton.moduleName) + guard hasGenerics else { + printer.write("bjs[\"\(hookName)\"] = function() {};") + continue + } + printer.write("bjs[\"\(hookName)\"] = function(base, count) {") + try printer.indent { + let codecNames = try moduleEntries.map { + try genericCodecReference(type: $0.bridgeType, into: printer) + } + printer.write("const codecs = [") + printer.indent { + for name in codecNames { + printer.write("\(name),") + } + } + printer.write("];") + writeTypeHandleRegistrationBody(into: printer) + } + printer.write("}") + } + } + private func generateAddImports(needsImportsObject: Bool) throws -> CodeFragmentPrinter { let printer = CodeFragmentPrinter() - let allStructs = skeletons.compactMap { $0.exported?.structs }.flatMap { $0 } + let allStructs = skeletons.flatMap { unified in + (unified.exported?.structs ?? []).map { (moduleName: unified.moduleName, structDef: $0) } + } printer.write("return {") try printer.indent { printer.write(lines: [ @@ -525,11 +624,12 @@ public struct BridgeJSLink { } printer.write("}") if !allStructs.isEmpty { - for structDef in allStructs { + for (moduleName, structDef) in allStructs { + let key = HelperNaming.type(module: moduleName, swiftName: structDef.swiftCallName) printer.write("bjs[\"swift_js_struct_lower_\(structDef.abiName)\"] = function(objectId) {") printer.indent { printer.write( - "\(JSGlueVariableScope.reservedStructHelpers).\(structDef.abiName).lower(\(JSGlueVariableScope.reservedSwift).memory.getObject(objectId));" + "\(JSGlueVariableScope.reservedStructHelpers).\(key).lower(\(JSGlueVariableScope.reservedSwift).memory.getObject(objectId));" ) } printer.write("}") @@ -537,13 +637,14 @@ public struct BridgeJSLink { printer.write("bjs[\"swift_js_struct_lift_\(structDef.abiName)\"] = function() {") printer.indent { printer.write( - "const value = \(JSGlueVariableScope.reservedStructHelpers).\(structDef.abiName).lift();" + "const value = \(JSGlueVariableScope.reservedStructHelpers).\(key).lift();" ) printer.write("return \(JSGlueVariableScope.reservedSwift).memory.retain(value);") } printer.write("}") } } + try generateTypeRegistrationHooks(into: printer) // Always provided: the runtime's `_bjs_makePromise` imports it unconditionally. // The settlers are stored under a Symbol to avoid clashing with promise fields. @@ -973,13 +1074,15 @@ public struct BridgeJSLink { ) ) printer.write( - "\(function.name)\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" + "\(function.resolvedJSName)\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" ) } for property in enumDefinition.staticProperties { let readonly = property.isReadonly ? "readonly " : "" printer.write(lines: renderJSDoc(documentation: property.documentation, parameters: [])) - printer.write("\(readonly)\(property.name): \(resolveTypeScriptType(property.type));") + printer.write( + "\(readonly)\(property.resolvedJSName): \(resolveTypeScriptType(property.type));" + ) } } printer.write("};") @@ -1023,15 +1126,15 @@ public struct BridgeJSLink { self.renderExportedStructExportEntry(structDef) }, renderFunctionEntry: { function in - self.renderJSDoc(documentation: function.documentation, parameters: function.parameters) + return self.renderJSDoc(documentation: function.documentation, parameters: function.parameters) + [ - "\(function.name)\(self.renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" + "\(function.resolvedJSName)\(self.renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" ] }, renderPropertyEntry: { property in let readonly = property.isReadonly ? "readonly " : "" return self.renderJSDoc(documentation: property.documentation, parameters: []) - + ["\(readonly)\(property.name): \(property.type.tsType);"] + + ["\(readonly)\(property.resolvedJSName): \(property.type.tsType);"] } ) printer.write("export type Exports = {") @@ -1069,7 +1172,7 @@ public struct BridgeJSLink { } /// Generates JavaScript output using CodeFragmentPrinter for better maintainability - private func generateJavaScript(data: LinkData) throws -> String { + private func generateJavaScript(data: LinkData, sharedMemory: Bool) throws -> String { let header = """ // NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, // DO NOT EDIT. @@ -1107,12 +1210,18 @@ public struct BridgeJSLink { let bodyPrinter = CodeFragmentPrinter() let allStructs = exportedSkeletons.flatMap { $0.structs } - for structDef in allStructs { + for (moduleName, structDef) in skeletons.flatMap({ unified in + (unified.exported?.structs ?? []).map { (unified.moduleName, $0) } + }) { let structPrinter = CodeFragmentPrinter() let structScope = JSGlueVariableScope(intrinsicRegistry: intrinsicRegistry) - let fragment = IntrinsicJSFragment.structHelper(structDefinition: structDef, allStructs: allStructs) + let fragment = IntrinsicJSFragment.structHelper( + structDefinition: structDef, + allStructs: allStructs, + moduleName: moduleName + ) _ = try fragment.printCode( - [structDef.abiName], + [], IntrinsicJSFragment.PrintCodeContext( scope: structScope, printer: structPrinter, @@ -1123,13 +1232,16 @@ public struct BridgeJSLink { bodyPrinter.write(lines: structPrinter.lines) } - let allAssocEnums = exportedSkeletons.flatMap { - $0.enums.filter { $0.enumType == .associatedValue } - } - for enumDef in allAssocEnums { + for (moduleName, enumDef) in skeletons.flatMap({ unified in + (unified.exported?.enums ?? []).filter { $0.enumType == .associatedValue } + .map { (unified.moduleName, $0) } + }) { let enumPrinter = CodeFragmentPrinter() let enumScope = JSGlueVariableScope(intrinsicRegistry: intrinsicRegistry) - let fragment = IntrinsicJSFragment.associatedValueEnumHelperFactory(enumDefinition: enumDef) + let fragment = IntrinsicJSFragment.associatedValueEnumHelperFactory( + enumDefinition: enumDef, + moduleName: moduleName + ) _ = try fragment.printCode( [enumDef.valuesName], IntrinsicJSFragment.PrintCodeContext( @@ -1149,6 +1261,11 @@ public struct BridgeJSLink { printer.nextLine() } + if intrinsicRegistry.hasNamedCodecs { + printer.write(lines: intrinsicRegistry.emitNamedCodecLines()) + printer.nextLine() + } + printer.write(lines: bodyPrinter.lines) } printer.indent() @@ -1228,7 +1345,7 @@ public struct BridgeJSLink { return printer.lines.joined(separator: "\n") } - public func link() throws -> (outputJs: String, outputDts: String) { + public func link(sharedMemory: Bool = false) throws -> (outputJs: String, outputDts: String) { intrinsicRegistry.reset() importedModuleRegistry.configure(skeletons: skeletons) intrinsicRegistry.classNamespaces = skeletons.reduce(into: [:]) { result, unified in @@ -1239,21 +1356,55 @@ public struct BridgeJSLink { } } } + intrinsicRegistry.typeOwnerModules = collectTypeOwnerModules() let data = try collectLinkData() - let outputJs = try generateJavaScript(data: data) + let outputJs = try generateJavaScript(data: data, sharedMemory: sharedMemory) let outputDts = generateTypeScript(data: data) return (outputJs, outputDts) } + private func collectTypeOwnerModules() -> [String: String] { + var result: [String: String] = [:] + func record(_ name: String, _ moduleName: String) { + if result[name] == nil { + result[name] = moduleName + } + } + for unified in skeletons { + let moduleName = unified.moduleName + if let skeleton = unified.exported { + for structDef in skeleton.structs { + record(structDef.name, moduleName) + record(structDef.abiName, moduleName) + record(structDef.swiftCallName, moduleName) + } + for klass in skeleton.classes { + record(klass.name, moduleName) + record(klass.abiName, moduleName) + } + for enumDef in skeleton.enums { + record(enumDef.name, moduleName) + record(enumDef.abiName, moduleName) + record(enumDef.swiftCallName, moduleName) + } + for protocolDef in skeleton.protocols { + record(protocolDef.name, moduleName) + } + } + } + return result + } + private func enumHelperAssignments() -> CodeFragmentPrinter { let printer = CodeFragmentPrinter() - for skeleton in skeletons.compactMap(\.exported) { + for unified in skeletons { + guard let skeleton = unified.exported else { continue } for enumDef in skeleton.enums where enumDef.enumType == .associatedValue { - printer.write( - "const \(enumDef.name)Helpers = __bjs_create\(enumDef.valuesName)Helpers();" - ) - printer.write("\(JSGlueVariableScope.reservedEnumHelpers).\(enumDef.name) = \(enumDef.name)Helpers;") + let key = HelperNaming.type(module: unified.moduleName, swiftName: enumDef.swiftCallName) + let local = HelperNaming.helperConstant(key) + printer.write("const \(local) = \(HelperNaming.enumHelperFactory(key))();") + printer.write("\(JSGlueVariableScope.reservedEnumHelpers).\(key) = \(local);") printer.nextLine() } } @@ -1264,14 +1415,13 @@ public struct BridgeJSLink { private func structHelperAssignments() -> CodeFragmentPrinter { let printer = CodeFragmentPrinter() - for skeleton in skeletons.compactMap(\.exported) { + for unified in skeletons { + guard let skeleton = unified.exported else { continue } for structDef in skeleton.structs { - printer.write( - "const \(structDef.abiName)Helpers = __bjs_create\(structDef.abiName)Helpers();" - ) - printer.write( - "\(JSGlueVariableScope.reservedStructHelpers).\(structDef.abiName) = \(structDef.abiName)Helpers;" - ) + let key = HelperNaming.type(module: unified.moduleName, swiftName: structDef.swiftCallName) + let local = HelperNaming.helperConstant(key) + printer.write("const \(local) = \(HelperNaming.structHelperFactory(key))();") + printer.write("\(JSGlueVariableScope.reservedStructHelpers).\(key) = \(local);") printer.nextLine() } } @@ -1370,18 +1520,19 @@ public struct BridgeJSLink { // Add methods for method in type.methods { - let methodName = method.jsName ?? method.name + let methodName = method.resolvedJSName + let genericClause = renderGenericClause(method.genericParameterNames) let methodSignature = - "\(renderTSPropertyName(methodName))\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" + "\(renderTSPropertyName(methodName))\(genericClause)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" printer.write(methodSignature) } // Add properties from getters var propertyNames = Set() for getter in type.getters { - let propertyName = getter.jsName ?? getter.name + let propertyName = getter.resolvedJSName propertyNames.insert(propertyName) - let hasSetter = type.setters.contains { ($0.jsName ?? $0.name) == propertyName } + let hasSetter = type.setters.contains { $0.resolvedJSName == propertyName } let propertySignature = hasSetter ? "\(renderTSPropertyName(propertyName)): \(resolveTypeScriptType(getter.type));" @@ -1390,7 +1541,7 @@ public struct BridgeJSLink { } // Add setters that don't have corresponding getters for setter in type.setters { - let propertyName = setter.jsName ?? setter.name + let propertyName = setter.resolvedJSName guard !propertyNames.contains(propertyName) else { continue } printer.write("\(renderTSPropertyName(propertyName)): \(resolveTypeScriptType(setter.type));") } @@ -1537,7 +1688,7 @@ public struct BridgeJSLink { // Look up the enum to get its tsFullPath for skeleton in exportedSkeletons { for enumDef in skeleton.enums { - if enumDef.name == name || enumDef.swiftCallName == name { + if enumDef.swiftCallName == name { // Use the stored tsFullPath which has the full namespace switch type { case .namespaceEnum: @@ -1552,6 +1703,26 @@ public struct BridgeJSLink { } } return type.tsType + case .swiftStruct(let name): + for skeleton in exportedSkeletons { + for structDef in skeleton.structs { + if structDef.swiftCallName == name { + return structDef.tsFullPath + } + } + } + return type.tsType + case .swiftHeapObject(let name): + for skeleton in exportedSkeletons { + for klass in skeleton.classes { + if klass.swiftCallName == name { + return klass.name + } + } + } + return type.tsType + case .closure(let signature, _): + return signature.renderTSFunctionType { resolveTypeScriptType($0, exportedSkeletons: exportedSkeletons) } case .alias(_, let underlying): return resolveTypeScriptType(underlying, exportedSkeletons: exportedSkeletons) case .nullable(let wrapped, let kind): @@ -1587,6 +1758,10 @@ public struct BridgeJSLink { return "(\(parameterSignatures.joined(separator: ", "))): \(returnTypeWithEffect)" } + private func renderGenericClause(_ genericParameterNames: [String]) -> String { + genericParameterNames.isEmpty ? "" : "<\(genericParameterNames.joined(separator: ", "))>" + } + private func renderTSPropertyName(_ name: String) -> String { // TypeScript allows quoted property names for keys that aren't valid identifiers. if name.range(of: #"^[$A-Z_][0-9A-Z_$]*$"#, options: [.regularExpression, .caseInsensitive]) != nil { @@ -1628,7 +1803,7 @@ public struct BridgeJSLink { returnType: method.returnType, effects: method.effects ) - dtsTypePrinter.write("\(method.name)\(signature);") + dtsTypePrinter.write("\(method.resolvedJSName)\(signature);") } } dtsTypePrinter.write("}") @@ -1649,13 +1824,15 @@ public struct BridgeJSLink { for property in structDefinition.properties where property.isStatic { let readonly = property.isReadonly ? "readonly " : "" dtsExportEntryPrinter.write(lines: renderJSDoc(documentation: property.documentation, parameters: [])) - dtsExportEntryPrinter.write("\(readonly)\(property.name): \(resolveTypeScriptType(property.type));") + dtsExportEntryPrinter.write( + "\(readonly)\(property.resolvedJSName): \(resolveTypeScriptType(property.type));" + ) } for method in structDefinition.methods where method.effects.isStatic { let jsDocLines = renderJSDoc(documentation: method.documentation, parameters: method.parameters) dtsExportEntryPrinter.write(lines: jsDocLines) dtsExportEntryPrinter.write( - "\(method.name)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" + "\(method.resolvedJSName)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" ) } @@ -1914,7 +2091,7 @@ extension BridgeJSLink { dtsLines.append(contentsOf: renderJSDoc(documentation: function.documentation, parameters: function.parameters)) dtsLines.append( - "\(function.name)\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" + "\(function.resolvedJSName)\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" ) return (funcLines, dtsLines) @@ -1955,7 +2132,7 @@ extension BridgeJSLink { let returnExpr = try thunkBuilder.call(abiName: function.abiName, returnType: function.returnType) let funcLines = thunkBuilder.renderFunction( - name: function.name, + name: function.resolvedJSName, parameters: function.parameters, returnExpr: returnExpr, declarationPrefixKeyword: "static" @@ -1966,7 +2143,7 @@ extension BridgeJSLink { dtsLines.append(contentsOf: renderJSDoc(documentation: function.documentation, parameters: function.parameters)) dtsLines.append( - "static \(function.name)\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" + "static \(function.resolvedJSName)\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" ) return (funcLines, dtsLines) @@ -1986,7 +2163,7 @@ extension BridgeJSLink { let returnExpr = try thunkBuilder.call(abiName: function.abiName, returnType: function.returnType) let printer = CodeFragmentPrinter() - printer.write("\(function.name)(\(DefaultValueUtils.formatParameterList(function.parameters))) {") + printer.write("\(function.resolvedJSName)(\(DefaultValueUtils.formatParameterList(function.parameters))) {") printer.indent { thunkBuilder.renderFunctionBody(into: printer, returnExpr: returnExpr) } @@ -1997,7 +2174,7 @@ extension BridgeJSLink { dtsLines.append(contentsOf: renderJSDoc(documentation: function.documentation, parameters: function.parameters)) dtsLines.append( - "\(function.name)\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" + "\(function.resolvedJSName)\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" ) return (printer.lines, dtsLines) @@ -2043,7 +2220,7 @@ extension BridgeJSLink { let methodPrinter = CodeFragmentPrinter() methodPrinter.write( - "\(method.name): function(\(DefaultValueUtils.formatParameterList(method.parameters))) {" + "\(method.resolvedJSName): function(\(DefaultValueUtils.formatParameterList(method.parameters))) {" ) methodPrinter.indent { thunkBuilder.renderFunctionBody(into: methodPrinter, returnExpr: returnExpr) @@ -2071,7 +2248,7 @@ extension BridgeJSLink { returnType: property.type ) - propertyPrinter.write("get \(property.name)() {") + propertyPrinter.write("get \(property.resolvedJSName)() {") propertyPrinter.indent { getterThunkBuilder.renderFunctionBody(into: propertyPrinter, returnExpr: getterReturnExpr) } @@ -2093,7 +2270,7 @@ extension BridgeJSLink { returnType: .void ) - propertyPrinter.write("set \(property.name)(value) {") + propertyPrinter.write("set \(property.resolvedJSName)(value) {") propertyPrinter.indent { setterThunkBuilder.renderFunctionBody(into: propertyPrinter, returnExpr: nil) } @@ -2177,7 +2354,7 @@ extension BridgeJSLink { jsPrinter.indent { jsPrinter.write( lines: thunkBuilder.renderFunction( - name: method.name, + name: method.resolvedJSName, parameters: method.parameters, returnExpr: returnExpr, declarationPrefixKeyword: "static" @@ -2198,7 +2375,7 @@ extension BridgeJSLink { jsPrinter.indent { jsPrinter.write( lines: thunkBuilder.renderFunction( - name: method.name, + name: method.resolvedJSName, parameters: method.parameters, returnExpr: returnExpr, declarationPrefixKeyword: nil @@ -2214,7 +2391,7 @@ extension BridgeJSLink { dtsTypePrinter.write(line) } dtsTypePrinter.write( - "\(method.name)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" + "\(method.resolvedJSName)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" ) } } @@ -2252,13 +2429,13 @@ extension BridgeJSLink { for method in klass.methods where method.effects.isStatic { printer.write(lines: renderJSDoc(documentation: method.documentation, parameters: method.parameters)) printer.write( - "\(method.name)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" + "\(method.resolvedJSName)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" ) } for property in klass.properties where property.isStatic { let readonly = property.isReadonly ? "readonly " : "" printer.write(lines: renderJSDoc(documentation: property.documentation, parameters: [])) - printer.write("\(readonly)\(property.name): \(resolveTypeScriptType(property.type));") + printer.write("\(readonly)\(property.resolvedJSName): \(resolveTypeScriptType(property.type));") } return printer.lines } @@ -2280,18 +2457,20 @@ extension BridgeJSLink { ) printer.write("constructor(\(paramSignatures.joined(separator: ", ")));") } - for method in klass.methods.sorted(by: { $0.name < $1.name }) { + for method in klass.methods.sorted(by: { $0.resolvedJSName < $1.resolvedJSName }) { let staticKeyword = method.effects.isStatic ? "static " : "" printer.write(lines: renderJSDoc(documentation: method.documentation, parameters: method.parameters)) printer.write( - "\(staticKeyword)\(method.name)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" + "\(staticKeyword)\(method.resolvedJSName)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" ) } - for property in klass.properties.sorted(by: { $0.name < $1.name }) { + for property in klass.properties.sorted(by: { $0.resolvedJSName < $1.resolvedJSName }) { let staticKeyword = property.isStatic ? "static " : "" let readonly = property.isReadonly ? "readonly " : "" printer.write(lines: renderJSDoc(documentation: property.documentation, parameters: [])) - printer.write("\(staticKeyword)\(readonly)\(property.name): \(resolveTypeScriptType(property.type));") + printer.write( + "\(staticKeyword)\(readonly)\(property.resolvedJSName): \(resolveTypeScriptType(property.type));" + ) } printer.write("release(): void;") } @@ -2321,7 +2500,7 @@ extension BridgeJSLink { jsPrinter.indent { jsPrinter.write( lines: getterThunkBuilder.renderFunction( - name: property.name, + name: property.resolvedJSName, parameters: [], returnExpr: getterReturnExpr, declarationPrefixKeyword: getterKeyword @@ -2349,7 +2528,7 @@ extension BridgeJSLink { jsPrinter.indent { jsPrinter.write( lines: setterThunkBuilder.renderFunction( - name: property.name, + name: property.resolvedJSName, parameters: [.init(label: nil, name: "value", type: property.type)], returnExpr: nil, declarationPrefixKeyword: setterKeyword @@ -2365,7 +2544,7 @@ extension BridgeJSLink { for line in renderJSDoc(documentation: property.documentation, parameters: []) { dtsPrinter.write(line) } - dtsPrinter.write("\(readonly)\(property.name): \(resolveTypeScriptType(property.type));") + dtsPrinter.write("\(readonly)\(property.resolvedJSName): \(resolveTypeScriptType(property.type));") } } } @@ -2379,6 +2558,8 @@ extension BridgeJSLink { var parameterNames: [String] = [] var parameterForwardings: [String] = [] var returnExpr: String? + var genericCodecVariables: [String: String] = [:] + var genericTypeIdParameters: [String: String] = [:] let printContext: IntrinsicJSFragment.PrintCodeContext init( @@ -2404,7 +2585,34 @@ extension BridgeJSLink { parameterNames.append("self") } + func declareGenericCodecs(genericParameters: [String]) { + if !genericParameters.isEmpty { + ContainerCodecJS.registerCombinators(scope: scope) + } + for genericParam in genericParameters { + let typeIdParam = scope.variable("\(genericParam.lowercased())TypeId") + let codecVar = scope.variable("codec\(genericParam)") + body.write("const \(codecVar) = __bjs_codecForTypeId(\(typeIdParam));") + genericCodecVariables[genericParam] = codecVar + genericTypeIdParameters[genericParam] = typeIdParam + } + } + func liftParameter(param: Parameter) throws { + if let name = param.type.referencedGenericName { + guard let codecVar = genericCodecVariables[name] else { + throw BridgeJSLinkError( + message: "Generic codec for '\(name)' was not declared before lifting parameter '\(param.name)'" + ) + } + let valueVar = scope.variable(param.name) + let liftExpr = + GenericJSCodegen.genericCodecLiftExpression(type: param.type, codec: codecVar) + ?? "\(codecVar).lift()" + body.write("const \(valueVar) = \(liftExpr);") + parameterForwardings.append(valueVar) + return + } let liftingFragment = try IntrinsicJSFragment.liftParameter(type: param.type, context: context) let valuesToLift: [String] if liftingFragment.parameters.count == 0 { @@ -2421,6 +2629,16 @@ extension BridgeJSLink { parameterForwardings.append(contentsOf: liftedValues) } + func liftParametersAndGenericTypeIds(_ parameters: [Parameter], genericParameters: [String]) throws { + declareGenericCodecs(genericParameters: genericParameters) + for param in parameters { + try liftParameter(param: param) + } + for genericParam in genericParameters { + parameterNames.append(genericTypeIdParameters[genericParam] ?? genericParam) + } + } + func renderFunction(name: String?) -> [String] { if effects.isAsync { return renderAsyncFunction(name: name) @@ -2497,6 +2715,25 @@ extension BridgeJSLink { body.write("\(callExpr).then(resolve, reject);") return } + if let name = returnType.referencedGenericName { + guard let codecVar = genericCodecVariables[name] else { + throw BridgeJSLinkError( + message: "Generic codec for return type '\(name)' was not declared before the call" + ) + } + let resultVariable = scope.variable("ret") + body.write("let \(resultVariable) = \(callExpr);") + let lowerStmt = + GenericJSCodegen.genericCodecLowerStatement( + type: returnType, + codec: codecVar, + value: resultVariable + ) + ?? "\(codecVar).lower(\(resultVariable));" + body.write(lowerStmt) + self.returnExpr = nil + return + } let loweringFragment = try IntrinsicJSFragment.lowerReturn(type: returnType, context: context) let returnExpr: String? if loweringFragment.parameters.count == 0 { @@ -2685,7 +2922,7 @@ extension BridgeJSLink { let namespaceEnumPaths = skeleton.enums .filter { $0.enumType == .namespace } .filter { !$0.staticProperties.isEmpty || !$0.staticMethods.isEmpty } - .map { ($0.namespace ?? []) + [$0.name] } + .map(\.tsPathComponents) return itemNamespaces + namespaceEnumPaths } @@ -2738,27 +2975,27 @@ extension BridgeJSLink { for function in skeleton.functions where function.namespace != nil { let namespacePath = function.namespace!.joined(separator: ".") printer.write( - "globalThis.\(namespacePath).\(function.name) = exports.\(namespacePath).\(function.name);" + "globalThis.\(namespacePath).\(function.resolvedJSName) = exports.\(namespacePath).\(function.resolvedJSName);" ) } for enumDef in skeleton.enums where enumDef.enumType == .namespace { for function in enumDef.staticMethods { - let fullNamespace = (enumDef.namespace ?? []) + [enumDef.name] - let namespacePath = fullNamespace.joined(separator: ".") + let namespacePath = enumDef.tsFullPath printer.write( - "globalThis.\(namespacePath).\(function.name) = exports.\(namespacePath).\(function.name);" + "globalThis.\(namespacePath).\(function.resolvedJSName) = exports.\(namespacePath).\(function.resolvedJSName);" ) } for property in enumDef.staticProperties { - let fullNamespace = (enumDef.namespace ?? []) + [enumDef.name] - let namespacePath = fullNamespace.joined(separator: ".") + let namespacePath = enumDef.tsFullPath let exportsPath = "exports.\(namespacePath)" - printer.write("Object.defineProperty(globalThis.\(namespacePath), '\(property.name)', {") + printer.write( + "Object.defineProperty(globalThis.\(namespacePath), '\(property.resolvedJSName)', {" + ) printer.indent { - printer.write("get: () => \(exportsPath).\(property.name),") + printer.write("get: () => \(exportsPath).\(property.resolvedJSName),") if !property.isReadonly { - printer.write("set: (value) => { \(exportsPath).\(property.name) = value; }") + printer.write("set: (value) => { \(exportsPath).\(property.resolvedJSName) = value; }") } } printer.write("});") @@ -2862,7 +3099,7 @@ extension BridgeJSLink { for klass in skeleton.classes { var currentNode = rootNode - for part in (klass.namespace ?? []) + [klass.name] { + for part in klass.tsPathComponents { currentNode = currentNode.addChild(part) } currentNode.content.declaration = .classType(klass) @@ -2870,7 +3107,7 @@ extension BridgeJSLink { for structDef in skeleton.structs { var currentNode = rootNode - for part in (structDef.namespace ?? []) + [structDef.name] { + for part in structDef.tsPathComponents { currentNode = currentNode.addChild(part) } currentNode.content.declaration = .structType(structDef) @@ -2886,17 +3123,15 @@ extension BridgeJSLink { for enumDef in skeleton.enums where enumDef.enumType == .namespace { for property in enumDef.staticProperties { - let fullNamespace = (enumDef.namespace ?? []) + [enumDef.name] var currentNode = rootNode - for part in fullNamespace { + for part in enumDef.tsPathComponents { currentNode = currentNode.addChild(part) } currentNode.content.staticProperties.append(property) } for function in enumDef.staticMethods { - let fullNamespace = (enumDef.namespace ?? []) + [enumDef.name] var currentNode = rootNode - for part in fullNamespace { + for part in enumDef.tsPathComponents { currentNode = currentNode.addChild(part) } currentNode.content.functions.append(function) @@ -2940,7 +3175,7 @@ extension BridgeJSLink { renderPropertyEntry: (ExportedProperty) -> [String] ) { for function in node.content.functions { - node.content.functionDtsLines.append((function.name, renderFunctionEntry(function))) + node.content.functionDtsLines.append((function.resolvedJSName, renderFunctionEntry(function))) } switch node.content.declaration { @@ -2953,7 +3188,7 @@ extension BridgeJSLink { } for property in node.content.staticProperties { - node.content.staticPropertyDtsLines.append((property.name, renderPropertyEntry(property))) + node.content.staticPropertyDtsLines.append((property.resolvedJSName, renderPropertyEntry(property))) } for enumDef in node.content.enums { @@ -3005,7 +3240,7 @@ extension BridgeJSLink { ) throws { for function in node.content.functions { let impl = try renderFunctionImpl(function) - node.content.functionJsLines.append((function.name, impl)) + node.content.functionJsLines.append((function.resolvedJSName, impl)) } switch node.content.declaration { @@ -3039,7 +3274,7 @@ extension BridgeJSLink { ) let getterPrinter = CodeFragmentPrinter() - getterPrinter.write("get \(property.name)() {") + getterPrinter.write("get \(property.resolvedJSName)() {") getterPrinter.indent { getterPrinter.write(contentsOf: getterThunkBuilder.body) getterPrinter.write(lines: getterThunkBuilder.checkExceptionLines()) @@ -3066,7 +3301,7 @@ extension BridgeJSLink { ) let setterPrinter = CodeFragmentPrinter() - setterPrinter.write("set \(property.name)(value) {") + setterPrinter.write("set \(property.resolvedJSName)(value) {") setterPrinter.indent { setterPrinter.write(contentsOf: setterThunkBuilder.body) setterPrinter.write(lines: setterThunkBuilder.checkExceptionLines()) @@ -3431,18 +3666,22 @@ extension BridgeJSLink { // Only include functions and properties when exposeToGlobal is true if exposeToGlobal { - let sortedFunctions = childNode.content.functions.sorted { $0.name < $1.name } + let sortedFunctions = childNode.content.functions.sorted { + $0.resolvedJSName < $1.resolvedJSName + } for function in sortedFunctions { let signature = - "function \(function.name)\(renderTSSignatureCallback(function.parameters, function.returnType, function.effects));" + "function \(function.resolvedJSName)\(renderTSSignatureCallback(function.parameters, function.returnType, function.effects));" printer.write(lines: renderDocCallback(function.documentation, function.parameters)) printer.write(signature) } - let sortedProperties = childNode.content.staticProperties.sorted { $0.name < $1.name } + let sortedProperties = childNode.content.staticProperties.sorted { + $0.resolvedJSName < $1.resolvedJSName + } for property in sortedProperties { let readonly = property.isReadonly ? "var " : "let " printer.write(lines: renderDocCallback(property.documentation, [])) - printer.write("\(readonly)\(property.name): \(property.type.tsType);") + printer.write("\(readonly)\(property.resolvedJSName): \(property.type.tsType);") } } @@ -3476,10 +3715,12 @@ extension BridgeJSLink { returnType: function.returnType, intrinsicRegistry: intrinsicRegistry ) - for param in function.parameters { - try thunkBuilder.liftParameter(param: param) - } - let jsName = function.jsName ?? function.name + let genericParameters = function.genericParameterNames + try thunkBuilder.liftParametersAndGenericTypeIds( + function.parameters, + genericParameters: genericParameters + ) + let jsName = function.resolvedJSName let calleeExpr = try importedModuleRegistry.memberExpression( swiftModuleName: importObjectBuilder.moduleName, from: function.from, @@ -3489,9 +3730,10 @@ extension BridgeJSLink { try thunkBuilder.call(calleeExpr: calleeExpr) let funcLines = thunkBuilder.renderFunction(name: function.abiName(context: nil)) if function.from == nil { + let genericClause = renderGenericClause(genericParameters) importObjectBuilder.appendDts( [ - "\(renderTSPropertyName(jsName))\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" + "\(renderTSPropertyName(jsName))\(genericClause)\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" ] ) } @@ -3507,7 +3749,7 @@ extension BridgeJSLink { returnType: getter.type, intrinsicRegistry: intrinsicRegistry ) - let jsName = getter.jsName ?? getter.name + let jsName = getter.resolvedJSName let accessExpr = try importedModuleRegistry.memberExpression( swiftModuleName: importObjectBuilder.moduleName, from: getter.from, @@ -3520,7 +3762,8 @@ extension BridgeJSLink { let abiName = getter.abiName(context: nil) let funcLines = thunkBuilder.renderFunction(name: abiName) if getter.from == nil { - importObjectBuilder.appendDts(["readonly \(renderTSPropertyName(jsName)): \(getter.type.tsType);"]) + importObjectBuilder.appendDts(["readonly \(renderTSPropertyName(jsName)): \(getter.type.tsType);"] + ) } importObjectBuilder.assignToImportObject(name: abiName, function: funcLines) } @@ -3542,7 +3785,7 @@ extension BridgeJSLink { getter: getter, abiName: getterAbiName, emitCall: { thunkBuilder in - return try thunkBuilder.callPropertyGetter(name: getter.jsName ?? getter.name) + return try thunkBuilder.callPropertyGetter(name: getter.resolvedJSName) } ) importObjectBuilder.assignToImportObject(name: getterAbiName, function: js) @@ -3558,7 +3801,7 @@ extension BridgeJSLink { try thunkBuilder.liftParameter( param: Parameter(label: nil, name: "newValue", type: setter.type) ) - thunkBuilder.callPropertySetter(name: setter.jsName ?? setter.name) + thunkBuilder.callPropertySetter(name: setter.resolvedJSName) } ) importObjectBuilder.assignToImportObject(name: setterAbiName, function: js) @@ -3580,14 +3823,16 @@ extension BridgeJSLink { dtsPrinter.indent { if let constructor = type.constructor { let returnType = BridgeType.jsObject(type.name) + let genericClause = renderGenericClause(constructor.genericParameterNames) dtsPrinter.write( - "new\(renderTSSignature(parameters: constructor.parameters, returnType: returnType, effects: Effects(isAsync: false, isThrows: false)));" + "new\(genericClause)\(renderTSSignature(parameters: constructor.parameters, returnType: returnType, effects: Effects(isAsync: false, isThrows: false)));" ) } for method in type.staticMethods { - let methodName = method.jsName ?? method.name + let methodName = method.resolvedJSName + let genericClause = renderGenericClause(method.genericParameterNames) let signature = - "\(renderTSPropertyName(methodName))\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" + "\(renderTSPropertyName(methodName))\(genericClause)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" dtsPrinter.write(signature) } } @@ -3611,13 +3856,14 @@ extension BridgeJSLink { returnType: BridgeType.jsObject(type.name), intrinsicRegistry: intrinsicRegistry ) - for param in constructor.parameters { - try thunkBuilder.liftParameter(param: param) - } + try thunkBuilder.liftParametersAndGenericTypeIds( + constructor.parameters, + genericParameters: constructor.genericParameterNames + ) let ctorExpr = try importedModuleRegistry.memberExpression( swiftModuleName: importObjectBuilder.moduleName, from: type.from, - memberName: type.jsName ?? type.name + memberName: type.resolvedJSName ) try thunkBuilder.callConstructor( ctorExpr: ctorExpr, @@ -3670,16 +3916,17 @@ extension BridgeJSLink { returnType: method.returnType, intrinsicRegistry: intrinsicRegistry ) - for param in method.parameters { - try thunkBuilder.liftParameter(param: param) - } + try thunkBuilder.liftParametersAndGenericTypeIds( + method.parameters, + genericParameters: method.genericParameterNames + ) let constructorExpr = try importedModuleRegistry.memberExpression( swiftModuleName: swiftModuleName, from: context.from, - memberName: context.jsName ?? context.name + memberName: context.resolvedJSName ) - try thunkBuilder.callStaticMethod(on: constructorExpr, name: method.jsName ?? method.name) + try thunkBuilder.callStaticMethod(on: constructorExpr, name: method.resolvedJSName) let funcLines = thunkBuilder.renderFunction(name: method.abiName(context: context, operation: "static")) return (funcLines, []) } @@ -3694,11 +3941,13 @@ extension BridgeJSLink { intrinsicRegistry: intrinsicRegistry ) thunkBuilder.liftSelf() - for param in method.parameters { - try thunkBuilder.liftParameter(param: param) - } + let genericParameters = method.genericParameterNames + try thunkBuilder.liftParametersAndGenericTypeIds( + method.parameters, + genericParameters: genericParameters + ) - try thunkBuilder.callMethod(name: method.jsName ?? method.name) + try thunkBuilder.callMethod(name: method.resolvedJSName) let funcLines = thunkBuilder.renderFunction(name: method.abiName(context: context)) return (funcLines, []) } @@ -3983,6 +4232,17 @@ struct BridgeJSLinkError: Error { let message: String } +extension ClosureSignature { + fileprivate func renderTSFunctionType(renderType: (BridgeType) -> String) -> String { + let renderedParameters = parameters.enumerated().map { index, parameter in + "arg\(index): \(renderType(parameter))" + }.joined(separator: ", ") + let renderedReturnType = renderType(returnType) + let returnTypeWithEffect = isAsync ? "Promise<\(renderedReturnType)>" : renderedReturnType + return "(\(renderedParameters)) => \(returnTypeWithEffect)" + } +} + extension BridgeType { var tsType: String { switch self { @@ -4024,12 +4284,7 @@ extension BridgeType { case .swiftProtocol(let name): return name case .closure(let signature, _): - let paramTypes = signature.parameters.enumerated().map { index, param in - "arg\(index): \(param.tsType)" - }.joined(separator: ", ") - let returnTS = - signature.isAsync ? "Promise<\(signature.returnType.tsType)>" : signature.returnType.tsType - return "(\(paramTypes)) => \(returnTS)" + return signature.renderTSFunctionType { $0.tsType } case .array(let elementType): let inner = elementType.tsType if inner.contains("|") || inner.contains("=>") { @@ -4040,6 +4295,8 @@ extension BridgeType { return "Record" case .alias(_, let underlying): return underlying.tsType + case .generic(let name): + return name } } diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/ImportedJSModuleRegistry.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/ImportedJSModuleRegistry.swift index 96efcd1d4..daf220d7f 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/ImportedJSModuleRegistry.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/ImportedJSModuleRegistry.swift @@ -133,14 +133,14 @@ final class ImportedJSModuleRegistry { } for file in skeleton.imported?.children ?? [] { for function in file.functions { - visit(from: function.from, memberName: function.jsName ?? function.name) + visit(from: function.from, memberName: function.resolvedJSName) } for getter in file.globalGetters { - visit(from: getter.from, memberName: getter.jsName ?? getter.name) + visit(from: getter.from, memberName: getter.resolvedJSName) } for type in file.types { guard type.constructor != nil || !type.staticMethods.isEmpty else { continue } - visit(from: type.from, memberName: type.jsName ?? type.name) + visit(from: type.from, memberName: type.resolvedJSName) } } } diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift index 1cf0fa298..3f8530c55 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift @@ -35,6 +35,11 @@ final class JSGlueVariableScope { static let reservedSwiftClosureRegistry = "swiftClosureRegistry" static let reservedMakeSwiftClosure = "makeClosure" static let reservedTaStack = "taStack" + static let reservedCodecByTypeId = "__bjs_codecByTypeId" + static let reservedPrimitiveCodecs = "__bjs_primitiveCodecs" + static let reservedStringCodec = "__bjs_stringCodec" + static let reservedTypeHandlesRegistered = "__bjs_typeHandlesRegistered" + static let reservedRegisterTypeHandles = "__bjs_registerTypeHandles" private let intrinsicRegistry: JSIntrinsicRegistry @@ -65,6 +70,11 @@ final class JSGlueVariableScope { reservedSwiftClosureRegistry, reservedMakeSwiftClosure, reservedTaStack, + reservedCodecByTypeId, + reservedPrimitiveCodecs, + reservedStringCodec, + reservedTypeHandlesRegistered, + reservedRegisterTypeHandles, ] init(intrinsicRegistry: JSIntrinsicRegistry) { @@ -92,12 +102,62 @@ final class JSGlueVariableScope { try intrinsicRegistry.register(name: name, build: build) } + func registerNamedCodec(_ name: String, build: (CodeFragmentPrinter) throws -> Void) rethrows { + try intrinsicRegistry.registerNamedCodec(name: name, build: build) + } + + func moduleName(declaringType typeName: String) -> String? { + intrinsicRegistry.typeOwnerModules[typeName] + } + func makeChildScope() -> JSGlueVariableScope { JSGlueVariableScope(intrinsicRegistry: intrinsicRegistry) } } +extension JSGlueVariableScope { + func helperKey(forTypeNamed fullName: String) -> String { + HelperNaming.type( + module: moduleName(declaringType: fullName), + swiftName: fullName + ) + } +} + +enum HelperNaming { + static func identifierComponent(_ name: String) -> String { + name.utf8.map { byte in + switch byte { + case 48...57, 65...90, 97...122: + return String(UnicodeScalar(byte)) + default: + return "_\(String(byte, radix: 16))_" + } + }.joined() + } + + static func type(module: String?, swiftName: String) -> String { + let module = module.map { "M\($0.utf8.count)\(identifierComponent($0))" } ?? "" + let type = swiftName.split(separator: ".").map { component in + "T\(component.utf8.count)\(identifierComponent(String(component)))" + }.joined() + return module + type + } + + static func structHelperFactory(_ qualifiedKey: String) -> String { + "__bjs_createStructHelpers_\(qualifiedKey)" + } + + static func enumHelperFactory(_ qualifiedKey: String) -> String { + "__bjs_createEnumHelpers_\(qualifiedKey)" + } + + static func helperConstant(_ qualifiedKey: String) -> String { + "__bjs_helpers_\(qualifiedKey)" + } +} + extension JSGlueVariableScope { // MARK: Parameter @@ -138,6 +198,327 @@ extension JSGlueVariableScope { } } +enum GenericJSCodegen { + static func genericCodecExpression(type: BridgeType, codec: String) -> String? { + switch type { + case .generic: return codec + case .array(.generic): return "\(ContainerCodecJS.arrayCodec)(\(codec))" + case .nullable(.generic, let kind): + return ContainerCodecJS.optionalCodecExpression(elementCodec: codec, kind: kind) + case .dictionary(.generic): return "\(ContainerCodecJS.dictCodec)(\(codec))" + default: return nil + } + } + + static func genericCodecLowerStatement(type: BridgeType, codec: String, value: String) -> String? { + genericCodecExpression(type: type, codec: codec).map { "\($0).lower(\(value));" } + } + + static func genericCodecLiftExpression(type: BridgeType, codec: String) -> String? { + genericCodecExpression(type: type, codec: codec).map { "\($0).lift()" } + } + + static func runtimeHelperDeclarations() -> [String] { + let codecByTypeId = JSGlueVariableScope.reservedCodecByTypeId + return [ + "function __bjs_codecForTypeId(typeId) {", + " __bjs_registerTypeHandles();", + " const codec = \(codecByTypeId).get(typeId);", + " if (!codec) {", + " throw new Error(\"BridgeJS: no codec registered for type ID \" + typeId);", + " }", + " return codec;", + "}", + ] + } +} + +enum ContainerCodecJS { + static let arrayCodec = "__bjs_arrayCodec" + static let optionalCodec = "__bjs_optionalCodec" + static let dictCodec = "__bjs_dictCodec" + + static let namedCodecPrefix = "__bjs_codec_" + + private static let combinatorIntrinsicName = "containerCodecCombinators" + private static let primitiveCodecIntrinsicName = "containerPrimitiveCodecs" + + static func combinatorDeclarations() -> [String] { + let i32 = JSGlueVariableScope.reservedI32Stack + let stringCodec = JSGlueVariableScope.reservedStringCodec + return [ + "const \(arrayCodec)Cache = new WeakMap();", + "function \(arrayCodec)(elementCodec) {", + " let codec = \(arrayCodec)Cache.get(elementCodec);", + " if (codec !== undefined) {", + " return codec;", + " }", + " codec = {", + " lower(value) {", + " for (let i = 0; i < value.length; i++) {", + " elementCodec.lower(value[i]);", + " }", + " \(i32).push(value.length);", + " },", + " lift() {", + " const count = \(i32).pop();", + " if (count === -1) {", + " return \(JSGlueVariableScope.reservedTaStack).pop();", + " }", + " const result = new Array(count);", + " for (let i = count - 1; i >= 0; i--) {", + " result[i] = elementCodec.lift();", + " }", + " return result;", + " },", + " };", + " \(arrayCodec)Cache.set(elementCodec, codec);", + " return codec;", + "}", + "const \(optionalCodec)Cache = new WeakMap();", + "const \(optionalCodec)UndefinedOrCache = new WeakMap();", + "function \(optionalCodec)(elementCodec, isUndefinedOr = false) {", + " const cache = isUndefinedOr ? \(optionalCodec)UndefinedOrCache : \(optionalCodec)Cache;", + " let codec = cache.get(elementCodec);", + " if (codec !== undefined) {", + " return codec;", + " }", + " codec = {", + " lower(value) {", + " const isSome = isUndefinedOr ? value !== undefined : value != null;", + " if (isSome) {", + " elementCodec.lower(value);", + " \(i32).push(1);", + " } else {", + " \(i32).push(0);", + " }", + " },", + " lift() {", + " if (\(i32).pop() === 0) {", + " return isUndefinedOr ? undefined : null;", + " }", + " return elementCodec.lift();", + " },", + " };", + " cache.set(elementCodec, codec);", + " return codec;", + "}", + "const \(dictCodec)Cache = new WeakMap();", + "function \(dictCodec)(valueCodec) {", + " let codec = \(dictCodec)Cache.get(valueCodec);", + " if (codec !== undefined) {", + " return codec;", + " }", + " codec = {", + " lower(value) {", + " const keys = Object.keys(value);", + " for (let i = 0; i < keys.length; i++) {", + " \(stringCodec).lower(keys[i]);", + " valueCodec.lower(value[keys[i]]);", + " }", + " \(i32).push(keys.length);", + " },", + " lift() {", + " const count = \(i32).pop();", + " const result = {};", + " for (let i = 0; i < count; i++) {", + " const value = valueCodec.lift();", + " const key = \(stringCodec).lift();", + " result[key] = value;", + " }", + " return result;", + " },", + " };", + " \(dictCodec)Cache.set(valueCodec, codec);", + " return codec;", + "}", + ] + } + + static func optionalCodecExpression(elementCodec: String, kind: JSOptionalKind) -> String { + switch kind { + case .null: return "\(optionalCodec)(\(elementCodec))" + case .undefined: return "\(optionalCodec)(\(elementCodec), true)" + } + } + + static func registerCombinators(scope: JSGlueVariableScope) { + scope.registerIntrinsic(combinatorIntrinsicName) { printer in + printer.write(lines: combinatorDeclarations()) + } + } + + static func registerPrimitiveCodecs(context: IntrinsicJSFragment.PrintCodeContext) throws { + try context.scope.registerIntrinsic(primitiveCodecIntrinsicName) { printer in + let stringCodec = JSGlueVariableScope.reservedStringCodec + try writeCodecLiteral( + type: .string, + into: printer, + context: context, + prefix: "const \(stringCodec) = ", + suffix: ";" + ) + printer.write("const \(JSGlueVariableScope.reservedPrimitiveCodecs) = {") + try printer.indent { + for primitive in BridgeType.genericBridgeablePrimitives { + if case .string = primitive.type { + printer.write("\(primitive.token): \(stringCodec),") + } else { + try writeCodecLiteral( + type: primitive.type, + into: printer, + context: context, + prefix: "\(primitive.token): ", + suffix: "," + ) + } + } + } + printer.write("};") + } + } + + static func writeCodecLiteral( + type: BridgeType, + into printer: CodeFragmentPrinter, + context: IntrinsicJSFragment.PrintCodeContext, + prefix: String = "", + suffix: String = "," + ) throws { + func literalContext() -> IntrinsicJSFragment.PrintCodeContext { + context.with(\.printer, printer).with(\.scope, context.scope.makeChildScope()) + } + let lowerFragment = try IntrinsicJSFragment.stackLowerFragment(elementType: type) + let liftFragment = try IntrinsicJSFragment.stackLiftFragment(elementType: type) + printer.write("\(prefix){") + try printer.indent { + printer.write("lower: (v) => {") + try printer.indent { + _ = try lowerFragment.printCode(["v"], literalContext()) + } + printer.write("},") + printer.write("lift: () => {") + try printer.indent { + let results = try liftFragment.printCode([], literalContext()) + printer.write("return \(results[0]);") + } + printer.write("},") + } + printer.write("}\(suffix)") + } + + struct NamedCodec { + let expression: String + let token: String + } + + static func codecExpression( + for elementType: BridgeType, + context: IntrinsicJSFragment.PrintCodeContext + ) throws -> String { + try namedCodec(for: elementType, context: context).expression + } + + static func namedCodec( + for elementType: BridgeType, + context: IntrinsicJSFragment.PrintCodeContext + ) throws -> NamedCodec { + registerCombinators(scope: context.scope) + try registerPrimitiveCodecs(context: context) + let type = elementType.unaliased + switch type { + case .array(let element): + let element = try namedCodec(for: element, context: context) + return composedCodec( + token: "Array_\(element.token)", + factory: "\(arrayCodec)(\(element.expression))", + context: context + ) + case .dictionary(let value): + let value = try namedCodec(for: value, context: context) + return composedCodec( + token: "Dict_\(value.token)", + factory: "\(dictCodec)(\(value.expression))", + context: context + ) + case .nullable(let wrapped, let kind): + let wrapped = try namedCodec(for: wrapped, context: context) + let prefix = kind == .null ? "Optional" : "UndefinedOr" + return composedCodec( + token: "\(prefix)_\(wrapped.token)", + factory: optionalCodecExpression(elementCodec: wrapped.expression, kind: kind), + context: context + ) + case .string, .rawValueEnum(_, .string): + return NamedCodec(expression: JSGlueVariableScope.reservedStringCodec, token: "String") + default: + if let token = BridgeType.genericBridgeablePrimitives.first(where: { $0.type == type })?.token { + return NamedCodec( + expression: "\(JSGlueVariableScope.reservedPrimitiveCodecs).\(token)", + token: token + ) + } + return try leafCodec(for: type, context: context) + } + } + + private static func composedCodec( + token: String, + factory: String, + context: IntrinsicJSFragment.PrintCodeContext + ) -> NamedCodec { + let name = "\(namedCodecPrefix)\(token)" + context.scope.registerNamedCodec(name) { printer in + printer.write("const \(name) = \(factory);") + } + return NamedCodec(expression: name, token: token) + } + + private static func leafCodec( + for type: BridgeType, + context: IntrinsicJSFragment.PrintCodeContext + ) throws -> NamedCodec { + let token = leafToken(for: type, scope: context.scope) + let name = "\(namedCodecPrefix)\(token)" + let hoistedContext = context.with(\.hasDirectAccessToSwiftClass, false) + try context.scope.registerNamedCodec(name) { printer in + try writeCodecLiteral( + type: type, + into: printer, + context: hoistedContext, + prefix: "const \(name) = ", + suffix: ";" + ) + } + return NamedCodec(expression: name, token: token) + } + + private static func leafToken(for type: BridgeType, scope: JSGlueVariableScope) -> String { + func identifierComponent(_ name: String) -> String { + HelperNaming.identifierComponent(name) + } + func qualified(_ name: String) -> String { + scope.helperKey(forTypeNamed: name) + } + switch type { + case .jsObject(nil): + return "JSObject" + case .jsObject(let name?): + return identifierComponent(name) + case .swiftStruct(let name), + .swiftHeapObject(let name), + .swiftProtocol(let name), + .caseEnum(let name), + .rawValueEnum(let name, _), + .associatedValueEnum(let name), + .namespaceEnum(let name): + return qualified(name) + default: + return identifierComponent(type.mangleTypeName) + } + } +} + /// A fragment of JS code used to convert a value between Swift and JS. /// /// See `BridgeJSIntrinsics.swift` in the main JavaScriptKit module for Swift side lowering/lifting implementation. @@ -615,12 +996,13 @@ struct IntrinsicJSFragment: Sendable { // MARK: - Associated Enum Fragments - static func associatedEnumLowerParameter(enumBase: String) -> IntrinsicJSFragment { + static func associatedEnumLowerParameter(enumName: String) -> IntrinsicJSFragment { IntrinsicJSFragment( parameters: ["value"], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) let value = arguments[0] + let enumBase = scope.helperKey(forTypeNamed: enumName) let caseIdName = scope.variable("\(value)CaseId") printer.write( "const \(caseIdName) = \(JSGlueVariableScope.reservedEnumHelpers).\(enumBase).lower(\(value));" @@ -630,11 +1012,12 @@ struct IntrinsicJSFragment: Sendable { ) } - static func associatedEnumLiftReturn(enumBase: String) -> IntrinsicJSFragment { + static func associatedEnumLiftReturn(enumName: String) -> IntrinsicJSFragment { IntrinsicJSFragment( parameters: [], printCode: { _, context in let (scope, printer) = (context.scope, context.printer) + let enumBase = scope.helperKey(forTypeNamed: enumName) let retName = scope.variable("ret") printer.write( "const \(retName) = \(JSGlueVariableScope.reservedEnumHelpers).\(enumBase).lift(\(scope.popI32()));" @@ -668,40 +1051,35 @@ struct IntrinsicJSFragment: Sendable { ) } - let innerFragment = - if wrappedType.optionalParameterUsesStackABI { - try stackLiftFragment(elementType: wrappedType) - } else { - try liftParameter(type: wrappedType, context: bridgeContext) - } + if wrappedType.optionalParameterUsesStackABI { + return try optionalElementRaiseFragment(wrappedType: wrappedType, kind: kind) + } return compositeOptionalLiftParameter( wrappedType: wrappedType, kind: kind, - innerFragment: innerFragment + innerFragment: try liftParameter(type: wrappedType, context: bridgeContext) ) } + /// Lift an optional parameter whose presence flag arrives as a wasm + /// parameter (not on the i32 stack), with the payload either in further + /// wasm parameters or on the stacks. The shared optional codec combinator + /// pops its flag from the i32 stack, so this ABI cannot go through it; + /// stack-convention payloads still lift through the shared container + /// codecs via `stackLiftFragment`. private static func compositeOptionalLiftParameter( wrappedType: BridgeType, kind: JSOptionalKind, innerFragment: IntrinsicJSFragment ) -> IntrinsicJSFragment { - let isStackConvention = wrappedType.optionalParameterUsesStackABI let absenceLiteral = kind.absenceLiteral - let outerParams: [String] - if isStackConvention { - outerParams = ["isSome"] - } else { - outerParams = ["isSome"] + innerFragment.parameters - } - return IntrinsicJSFragment( - parameters: outerParams, + parameters: ["isSome"] + innerFragment.parameters, printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) let isSome = arguments[0] - let innerArgs = isStackConvention ? [] : Array(arguments.dropFirst()) + let innerArgs = Array(arguments.dropFirst()) let bufferPrinter = CodeFragmentPrinter() let innerResults = try innerFragment.printCode( @@ -761,26 +1139,26 @@ struct IntrinsicJSFragment: Sendable { ) } - let innerFragment = - if wrappedType.optionalParameterUsesStackABI { - try stackLowerFragment(elementType: wrappedType) - } else { - try lowerParameter(type: wrappedType) - } + if wrappedType.optionalParameterUsesStackABI { + // Stack convention: the conditional flag-plus-payload protocol is + // the shared optional codec's stack ABI. + return try optionalElementLowerFragment(wrappedType: wrappedType, kind: kind) + } return try compositeOptionalLowerParameter( wrappedType: wrappedType, kind: kind, - innerFragment: innerFragment + innerFragment: try lowerParameter(type: wrappedType) ) } + /// Lower an optional parameter using the direct `(isSome, ...payload)` wasm + /// parameter ABI with zero placeholders for nil. This is not the container + /// stack ABI, so it cannot go through the shared optional codec combinator. private static func compositeOptionalLowerParameter( wrappedType: BridgeType, kind: JSOptionalKind, innerFragment: IntrinsicJSFragment ) throws -> IntrinsicJSFragment { - let isStackConvention = wrappedType.optionalParameterUsesStackABI - return IntrinsicJSFragment( parameters: ["value"], printCode: { arguments, context in @@ -797,7 +1175,7 @@ struct IntrinsicJSFragment: Sendable { let resultVars = innerResults.map { _ in scope.variable("result") } assert( - isStackConvention || resultVars.count == wrappedType.wasmParams.count, + resultVars.count == wrappedType.wasmParams.count, "Inner fragment result count (\(resultVars.count)) must match wasmParams count (\(wrappedType.wasmParams.count)) for \(wrappedType)" ) if !resultVars.isEmpty { @@ -814,8 +1192,7 @@ struct IntrinsicJSFragment: Sendable { } } - let hasPlaceholders = !isStackConvention && !wrappedType.wasmParams.isEmpty - if hasPlaceholders { + if !wrappedType.wasmParams.isEmpty { printer.write("} else {") printer.indent { for (resultVar, param) in zip(resultVars, wrappedType.wasmParams) { @@ -825,12 +1202,7 @@ struct IntrinsicJSFragment: Sendable { } printer.write("}") - if isStackConvention { - scope.emitPushI32Parameter("+\(isSomeVar)", printer: printer) - return [] - } else { - return ["+\(isSomeVar)"] + resultVars - } + return ["+\(isSomeVar)"] + resultVars } ) } @@ -848,6 +1220,9 @@ struct IntrinsicJSFragment: Sendable { ) } + /// Lift an optional return whose presence flag travels on the i32 stack but + /// whose payload uses the wrapped type's regular (non-stack) return ABI, so + /// it cannot go through the shared optional codec combinator. private static func optionalLiftReturnWithPresenceFlag( wrappedType: BridgeType, kind: JSOptionalKind @@ -860,12 +1235,7 @@ struct IntrinsicJSFragment: Sendable { let isSomeVar = scope.variable("isSome") printer.write("const \(isSomeVar) = \(scope.popI32());") - let innerFragment = - if wrappedType.optionalConvention == .stackABI { - try stackLiftFragment(elementType: wrappedType) - } else { - try liftReturn(type: wrappedType) - } + let innerFragment = try liftReturn(type: wrappedType) let innerPrinter = CodeFragmentPrinter() let innerResults = try innerFragment.printCode([], context.with(\.printer, innerPrinter)) @@ -898,12 +1268,12 @@ struct IntrinsicJSFragment: Sendable { fullName: String, kind: JSOptionalKind ) -> IntrinsicJSFragment { - let base = fullName.components(separatedBy: ".").last ?? fullName let absenceLiteral = kind.absenceLiteral return IntrinsicJSFragment( parameters: [], printCode: { _, context in let (scope, printer) = (context.scope, context.printer) + let base = scope.helperKey(forTypeNamed: fullName) let resultVar = scope.variable("optResult") let tagVar = scope.variable("tag") printer.write("const \(tagVar) = \(scope.popI32());") @@ -942,31 +1312,13 @@ struct IntrinsicJSFragment: Sendable { ) } - private static func optionalLiftReturnStruct( - fullName: String, - kind: JSOptionalKind - ) -> IntrinsicJSFragment { - let base = fullName.replacingOccurrences(of: ".", with: "_") - let absenceLiteral = kind.absenceLiteral - return IntrinsicJSFragment( - parameters: [], - printCode: { _, context in - let (scope, printer) = (context.scope, context.printer) - let isSomeVar = scope.variable("isSome") - let resultVar = scope.variable("optResult") - printer.write("const \(isSomeVar) = \(scope.popI32());") - printer.write( - "const \(resultVar) = \(isSomeVar) ? \(JSGlueVariableScope.reservedStructHelpers).\(base).lift() : \(absenceLiteral);" - ) - return [resultVar] - } - ) - } - static func optionalLiftReturn( wrappedType: BridgeType, kind: JSOptionalKind - ) -> IntrinsicJSFragment { + ) throws -> IntrinsicJSFragment { + // Side-channel optionals deliver their payload through dedicated + // storage/imports instead of the bridge stacks, so they cannot go + // through the shared optional codec combinator. if let scalarKind = wrappedType.optionalScalarKind { return optionalLiftReturnFromStorage(storage: scalarKind.storageName) } @@ -974,18 +1326,21 @@ struct IntrinsicJSFragment: Sendable { return optionalLiftReturnFromStorage(storage: JSGlueVariableScope.reservedStorageToReturnString) } + // Heap object optionals use the tmpRetOptionalHeapObject side channel. if case .swiftHeapObject(let className) = wrappedType { return optionalLiftReturnHeapObject(className: className, kind: kind) } - if case .swiftStruct(let fullName) = wrappedType { - return optionalLiftReturnStruct(fullName: fullName, kind: kind) - } - + // Sentinel optionals encode nil in-band (tag -1), with no presence flag. if wrappedType.nilSentinel.hasSentinel, case .associatedValueEnum(let fullName) = wrappedType { return optionalLiftReturnAssociatedEnum(fullName: fullName, kind: kind) } + if wrappedType.optionalConvention == .stackABI { + // Stack convention: route through the shared optional codec combinator. + return try optionalElementRaiseFragment(wrappedType: wrappedType, kind: kind) + } + return optionalLiftReturnWithPresenceFlag(wrappedType: wrappedType, kind: kind) } @@ -1111,12 +1466,8 @@ struct IntrinsicJSFragment: Sendable { } if wrappedType.optionalConvention == .stackABI { - let innerFragment = try stackLowerFragment(elementType: wrappedType) - return stackOptionalLower( - wrappedType: wrappedType, - kind: kind, - innerFragment: innerFragment - ) + // Stack convention: route through the shared optional codec combinator. + return try optionalElementLowerFragment(wrappedType: wrappedType, kind: kind) } if wrappedType.nilSentinel.hasSentinel { @@ -1248,39 +1599,6 @@ struct IntrinsicJSFragment: Sendable { } } - /// Lower an optional value to the stack using the **conditional** protocol: - /// push isSome flag, then conditionally push the payload (no placeholders for nil). - private static func stackOptionalLower( - wrappedType: BridgeType, - kind: JSOptionalKind, - innerFragment: IntrinsicJSFragment - ) -> IntrinsicJSFragment { - IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, context in - let (scope, printer) = (context.scope, context.printer) - let value = arguments[0] - let isSomeVar = scope.variable("isSome") - printer.write("const \(isSomeVar) = \(kind.presenceCheck(value: value));") - - let ifBodyPrinter = CodeFragmentPrinter() - try ifBodyPrinter.indent { - let _ = try innerFragment.printCode( - [value], - context.with(\.printer, ifBodyPrinter) - ) - } - printer.write("if (\(isSomeVar)) {") - for line in ifBodyPrinter.lines { - printer.write(line) - } - printer.write("}") - scope.emitPushI32Parameter("\(isSomeVar) ? 1 : 0", printer: printer) - return [] - } - ) - } - // MARK: - ExportSwift /// Returns a fragment that lowers a JS value to Wasm core values for parameters @@ -1300,11 +1618,9 @@ struct IntrinsicJSFragment: Sendable { return try .optionalLowerParameter(wrappedType: wrappedType, kind: kind) case .rawValueEnum(_, .string): return .stringLowerParameter case .associatedValueEnum(let fullName): - let base = fullName.components(separatedBy: ".").last ?? fullName - return .associatedEnumLowerParameter(enumBase: base) + return .associatedEnumLowerParameter(enumName: fullName) case .swiftStruct(let fullName): - let base = fullName.replacingOccurrences(of: ".", with: "_") - return swiftStructLowerParameter(structBase: base) + return swiftStructLowerParameter(structName: fullName) case .closure: return IntrinsicJSFragment( parameters: ["closure"], @@ -1357,14 +1673,12 @@ struct IntrinsicJSFragment: Sendable { case .swiftProtocol: return .jsObjectLiftReturn case .void: return .void case .nullable(let wrappedType, let kind): - return .optionalLiftReturn(wrappedType: wrappedType, kind: kind) + return try .optionalLiftReturn(wrappedType: wrappedType, kind: kind) case .rawValueEnum(_, .string): return .stringLiftReturn case .associatedValueEnum(let fullName): - let base = fullName.components(separatedBy: ".").last ?? fullName - return .associatedEnumLiftReturn(enumBase: base) + return .associatedEnumLiftReturn(enumName: fullName) case .swiftStruct(let fullName): - let base = fullName.replacingOccurrences(of: ".", with: "_") - return swiftStructLiftReturn(structBase: base) + return swiftStructLiftReturn(structName: fullName) case .closure: return IntrinsicJSFragment( parameters: ["funcRef"], @@ -1423,11 +1737,11 @@ struct IntrinsicJSFragment: Sendable { return try .optionalLiftParameter(wrappedType: wrappedType, kind: kind, context: context) case .rawValueEnum(_, .string): return .stringLiftParameter case .associatedValueEnum(let fullName): - let base = fullName.components(separatedBy: ".").last ?? fullName return IntrinsicJSFragment( parameters: ["caseId"], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) + let base = scope.helperKey(forTypeNamed: fullName) let caseId = arguments[0] let resultVar = scope.variable("enumValue") printer.write( @@ -1437,11 +1751,11 @@ struct IntrinsicJSFragment: Sendable { } ) case .swiftStruct(let fullName): - let base = fullName.replacingOccurrences(of: ".", with: "_") return IntrinsicJSFragment( parameters: [], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) + let base = scope.helperKey(forTypeNamed: fullName) let resultVar = scope.variable("structValue") printer.write( "const \(resultVar) = \(JSGlueVariableScope.reservedStructHelpers).\(base).lift();" @@ -1523,11 +1837,11 @@ struct IntrinsicJSFragment: Sendable { // MARK: - Enums Payload Fragments static func associatedValueLowerReturn(fullName: String) -> IntrinsicJSFragment { - let base = fullName.components(separatedBy: ".").last ?? fullName return IntrinsicJSFragment( parameters: ["value"], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) + let base = scope.helperKey(forTypeNamed: fullName) let value = arguments[0] let caseIdVar = scope.variable("caseId") printer.write( @@ -1566,17 +1880,20 @@ struct IntrinsicJSFragment: Sendable { ) } - /// Generates the enum helper factory function (lower/lift closures). - /// This is placed inside `createInstantiator` alongside struct helpers, - /// so it has access to `_exports` for class references. - static func associatedValueEnumHelperFactory(enumDefinition: ExportedEnum) -> IntrinsicJSFragment { + static func associatedValueEnumHelperFactory( + enumDefinition: ExportedEnum, + moduleName: String + ) -> IntrinsicJSFragment { + let factoryName = HelperNaming.enumHelperFactory( + HelperNaming.type(module: moduleName, swiftName: enumDefinition.swiftCallName) + ) return IntrinsicJSFragment( parameters: ["enumName"], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) let enumName = arguments[0] - printer.write("const __bjs_create\(enumName)Helpers = () => ({") + printer.write("const \(factoryName) = () => ({") try printer.indent { printer.write("lower: (value) => {") try printer.indent { @@ -1769,11 +2086,12 @@ struct IntrinsicJSFragment: Sendable { } } - private static func swiftStructLower(structBase: String) -> IntrinsicJSFragment { + private static func swiftStructLower(structName: String) -> IntrinsicJSFragment { IntrinsicJSFragment( parameters: ["value"], printCode: { arguments, context in let printer = context.printer + let structBase = context.scope.helperKey(forTypeNamed: structName) let value = arguments[0] printer.write( "\(JSGlueVariableScope.reservedStructHelpers).\(structBase).lower(\(value));" @@ -1784,18 +2102,19 @@ struct IntrinsicJSFragment: Sendable { } static func swiftStructLowerReturn(fullName: String) -> IntrinsicJSFragment { - swiftStructLower(structBase: fullName.replacingOccurrences(of: ".", with: "_")) + swiftStructLower(structName: fullName) } - static func swiftStructLowerParameter(structBase: String) -> IntrinsicJSFragment { - swiftStructLower(structBase: structBase) + static func swiftStructLowerParameter(structName: String) -> IntrinsicJSFragment { + swiftStructLower(structName: structName) } - static func swiftStructLiftReturn(structBase: String) -> IntrinsicJSFragment { + static func swiftStructLiftReturn(structName: String) -> IntrinsicJSFragment { return IntrinsicJSFragment( parameters: [], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) + let structBase = scope.helperKey(forTypeNamed: structName) let resultVar = scope.variable("structValue") printer.write( "const \(resultVar) = \(JSGlueVariableScope.reservedStructHelpers).\(structBase).lift();" @@ -1807,133 +2126,53 @@ struct IntrinsicJSFragment: Sendable { // MARK: - Array Helpers - /// Lowers an array from JS to Swift by iterating elements and pushing to stacks static func arrayLower(elementType: BridgeType) throws -> IntrinsicJSFragment { return IntrinsicJSFragment( parameters: ["arr"], printCode: { arguments, context in - let (scope, printer) = (context.scope, context.printer) - let arr = arguments[0] - - let elemVar = scope.variable("elem") - printer.write("for (const \(elemVar) of \(arr)) {") - try printer.indent { - let elementFragment = try stackLowerFragment(elementType: elementType) - let _ = try elementFragment.printCode( - [elemVar], - context - ) - } - printer.write("}") - scope.emitPushI32Parameter("\(arr).length", printer: printer) + let codec = try ContainerCodecJS.codecExpression(for: .array(elementType), context: context) + context.printer.write("\(codec).lower(\(arguments[0]));") return [] } ) } - /// Lowers a dictionary from JS to Swift by iterating entries and pushing to stacks static func dictionaryLower(valueType: BridgeType) throws -> IntrinsicJSFragment { return IntrinsicJSFragment( parameters: ["dict"], printCode: { arguments, context in - let (scope, printer) = (context.scope, context.printer) - let dict = arguments[0] - - let entriesVar = scope.variable("entries") - let entryVar = scope.variable("entry") - printer.write("const \(entriesVar) = Object.entries(\(dict));") - printer.write("for (const \(entryVar) of \(entriesVar)) {") - try printer.indent { - let keyVar = scope.variable("key") - let valueVar = scope.variable("value") - printer.write("const [\(keyVar), \(valueVar)] = \(entryVar);") - - let keyFragment = try stackLowerFragment(elementType: .string) - let _ = try keyFragment.printCode( - [keyVar], - context - ) - - let valueFragment = try stackLowerFragment(elementType: valueType) - let _ = try valueFragment.printCode( - [valueVar], - context - ) - } - printer.write("}") - scope.emitPushI32Parameter("\(entriesVar).length", printer: printer) + let codec = try ContainerCodecJS.codecExpression(for: .dictionary(valueType), context: context) + context.printer.write("\(codec).lower(\(arguments[0]));") return [] } ) } - /// Lifts an array from Swift to JS by popping elements from stacks static func arrayLift(elementType: BridgeType) throws -> IntrinsicJSFragment { return IntrinsicJSFragment( parameters: [], - printCode: { arguments, context in - let (scope, printer) = (context.scope, context.printer) - let resultVar = scope.variable("arrayResult") - let lenVar = scope.variable("arrayLen") - - printer.write("const \(lenVar) = \(scope.popI32());") - printer.write("let \(resultVar);") - printer.write("if (\(lenVar) === -1) {") - printer.indent { - // Bulk path: Swift pushed a typed array onto the typed-array stack - printer.write("\(resultVar) = \(JSGlueVariableScope.reservedTaStack).pop();") - } - printer.write("} else {") - try printer.indent { - // Element-by-element path (original behavior) - let iVar = scope.variable("i") - printer.write("\(resultVar) = [];") - printer.write("for (let \(iVar) = 0; \(iVar) < \(lenVar); \(iVar)++) {") - try printer.indent { - let elementFragment = try stackLiftFragment(elementType: elementType) - let elementResults = try elementFragment.printCode([], context) - if let elementExpr = elementResults.first { - printer.write("\(resultVar).push(\(elementExpr));") - } - } - printer.write("}") - printer.write("\(resultVar).reverse();") - } - printer.write("}") + printCode: { _, context in + let codec = try ContainerCodecJS.codecExpression(for: .array(elementType), context: context) + let resultVar = context.scope.variable("arrayResult") + context.printer.write("const \(resultVar) = \(codec).lift();") return [resultVar] } ) } - /// Lifts a dictionary from Swift to JS by popping key/value pairs from stacks static func dictionaryLift(valueType: BridgeType) throws -> IntrinsicJSFragment { return IntrinsicJSFragment( parameters: [], - printCode: { arguments, context in - let (scope, printer) = (context.scope, context.printer) - let resultVar = scope.variable("dictResult") - let lenVar = scope.variable("dictLen") - let iVar = scope.variable("i") - - printer.write("const \(lenVar) = \(scope.popI32());") - printer.write("const \(resultVar) = {};") - printer.write("for (let \(iVar) = 0; \(iVar) < \(lenVar); \(iVar)++) {") - try printer.indent { - let valueFragment = try stackLiftFragment(elementType: valueType) - let valueResults = try valueFragment.printCode([], context) - let keyFragment = try stackLiftFragment(elementType: .string) - let keyResults = try keyFragment.printCode([], context) - if let keyExpr = keyResults.first, let valueExpr = valueResults.first { - printer.write("\(resultVar)[\(keyExpr)] = \(valueExpr);") - } - } - printer.write("}") + printCode: { _, context in + let codec = try ContainerCodecJS.codecExpression(for: .dictionary(valueType), context: context) + let resultVar = context.scope.variable("dictResult") + context.printer.write("const \(resultVar) = \(codec).lift();") return [resultVar] } ) } - private static func stackLiftFragment(elementType: BridgeType) throws -> IntrinsicJSFragment { + static func stackLiftFragment(elementType: BridgeType) throws -> IntrinsicJSFragment { if case .nullable(let wrappedType, let kind) = elementType { return try optionalElementRaiseFragment(wrappedType: wrappedType, kind: kind) } @@ -1998,11 +2237,11 @@ struct IntrinsicJSFragment: Sendable { } ) case .swiftStruct(let fullName): - let structBase = fullName.replacingOccurrences(of: ".", with: "_") return IntrinsicJSFragment( parameters: [], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) + let structBase = scope.helperKey(forTypeNamed: fullName) let resultVar = scope.variable("struct") printer.write( "const \(resultVar) = \(JSGlueVariableScope.reservedStructHelpers).\(structBase).lift();" @@ -2011,11 +2250,11 @@ struct IntrinsicJSFragment: Sendable { } ) case .associatedValueEnum(let fullName): - let base = fullName.components(separatedBy: ".").last ?? fullName return IntrinsicJSFragment( parameters: [], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) + let base = scope.helperKey(forTypeNamed: fullName) let resultVar = scope.variable("enumValue") printer.write( "const \(resultVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(scope.popI32()));" @@ -2060,7 +2299,7 @@ struct IntrinsicJSFragment: Sendable { } } - private static func stackLowerFragment(elementType: BridgeType) throws -> IntrinsicJSFragment { + static func stackLowerFragment(elementType: BridgeType) throws -> IntrinsicJSFragment { if case .nullable(let wrappedType, let kind) = elementType { return try optionalElementLowerFragment(wrappedType: wrappedType, kind: kind) } @@ -2120,11 +2359,11 @@ struct IntrinsicJSFragment: Sendable { } ) case .swiftStruct(let fullName): - let structBase = fullName.replacingOccurrences(of: ".", with: "_") return IntrinsicJSFragment( parameters: ["value"], printCode: { arguments, context in let printer = context.printer + let structBase = context.scope.helperKey(forTypeNamed: fullName) let value = arguments[0] printer.write( "\(JSGlueVariableScope.reservedStructHelpers).\(structBase).lower(\(value));" @@ -2134,11 +2373,11 @@ struct IntrinsicJSFragment: Sendable { ) case .associatedValueEnum(let fullName): - let base = fullName.components(separatedBy: ".").last ?? fullName return IntrinsicJSFragment( parameters: ["value"], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) + let base = scope.helperKey(forTypeNamed: fullName) let value = arguments[0] let caseIdVar = scope.variable("caseId") printer.write( @@ -2185,39 +2424,20 @@ struct IntrinsicJSFragment: Sendable { wrappedType: BridgeType, kind: JSOptionalKind ) throws -> IntrinsicJSFragment { - let absenceLiteral = kind.absenceLiteral return IntrinsicJSFragment( parameters: [], - printCode: { arguments, context in - let (scope, printer) = (context.scope, context.printer) - let isSomeVar = scope.variable("isSome") - let resultVar = scope.variable("optValue") - - printer.write("const \(isSomeVar) = \(scope.popI32());") - printer.write("let \(resultVar);") - printer.write("if (\(isSomeVar) === 0) {") - printer.indent { - printer.write("\(resultVar) = \(absenceLiteral);") - } - printer.write("} else {") - try printer.indent { - let innerFragment = try stackLiftFragment(elementType: wrappedType) - let innerResults = try innerFragment.printCode([], context) - if let innerResult = innerResults.first { - printer.write("\(resultVar) = \(innerResult);") - } else { - printer.write("\(resultVar) = undefined;") - } - } - printer.write("}") - + printCode: { _, context in + let codec = try ContainerCodecJS.codecExpression( + for: .nullable(wrappedType, kind), + context: context + ) + let resultVar = context.scope.variable("optValue") + context.printer.write("const \(resultVar) = \(codec).lift();") return [resultVar] } ) } - /// Lower an optional element to the stack using the **conditional** protocol: - /// push isSome flag, then conditionally push the payload (no placeholders for nil). private static func optionalElementLowerFragment( wrappedType: BridgeType, kind: JSOptionalKind @@ -2225,23 +2445,11 @@ struct IntrinsicJSFragment: Sendable { return IntrinsicJSFragment( parameters: ["value"], printCode: { arguments, context in - let (scope, printer) = (context.scope, context.printer) - let value = arguments[0] - let isSomeVar = scope.variable("isSome") - - let presenceExpr = kind.presenceCheck(value: value) - printer.write("const \(isSomeVar) = \(presenceExpr) ? 1 : 0;") - printer.write("if (\(isSomeVar)) {") - try printer.indent { - let innerFragment = try stackLowerFragment(elementType: wrappedType) - let _ = try innerFragment.printCode( - [value], - context - ) - } - printer.write("}") - scope.emitPushI32Parameter(isSomeVar, printer: printer) - + let codec = try ContainerCodecJS.codecExpression( + for: .nullable(wrappedType, kind), + context: context + ) + context.printer.write("\(codec).lower(\(arguments[0]));") return [] } ) @@ -2249,16 +2457,22 @@ struct IntrinsicJSFragment: Sendable { // MARK: - Struct Helpers - static func structHelper(structDefinition: ExportedStruct, allStructs: [ExportedStruct]) -> IntrinsicJSFragment { + static func structHelper( + structDefinition: ExportedStruct, + allStructs: [ExportedStruct], + moduleName: String + ) -> IntrinsicJSFragment { + let factoryName = HelperNaming.structHelperFactory( + HelperNaming.type(module: moduleName, swiftName: structDefinition.swiftCallName) + ) return IntrinsicJSFragment( - parameters: ["structName"], + parameters: [], printCode: { arguments, context in let printer = context.printer - let structName = arguments[0] let capturedStructDef = structDefinition let capturedAllStructs = allStructs - printer.write("const __bjs_create\(structName)Helpers = () => ({") + printer.write("const \(factoryName) = () => ({") try printer.indent { printer.write("lower: (value) => {") try printer.indent { @@ -2353,11 +2567,11 @@ struct IntrinsicJSFragment: Sendable { for method in structDef.methods where !method.effects.isStatic { let paramList = DefaultValueUtils.formatParameterList(method.parameters) printer.write( - "\(instanceVar).\(method.name) = function(\(paramList)) {" + "\(instanceVar).\(method.resolvedJSName) = function(\(paramList)) {" ) try printer.indent { printer.write( - "\(JSGlueVariableScope.reservedStructHelpers).\(structDef.abiName).lower(this);" + "\(JSGlueVariableScope.reservedStructHelpers).\(context.scope.helperKey(forTypeNamed: structDef.swiftCallName)).lower(this);" ) var paramForwardings: [String] = [] @@ -2428,9 +2642,10 @@ struct IntrinsicJSFragment: Sendable { parameters: ["value"], printCode: { arguments, context in let printer = context.printer + let nestedBase = context.scope.helperKey(forTypeNamed: nestedName) let value = arguments[0] printer.write( - "\(JSGlueVariableScope.reservedStructHelpers).\(nestedName.replacingOccurrences(of: ".", with: "_")).lower(\(value));" + "\(JSGlueVariableScope.reservedStructHelpers).\(nestedBase).lower(\(value));" ) return [] } @@ -2467,9 +2682,10 @@ struct IntrinsicJSFragment: Sendable { parameters: [], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) + let nestedBase = scope.helperKey(forTypeNamed: nestedName) let structVar = scope.variable("struct") printer.write( - "const \(structVar) = \(JSGlueVariableScope.reservedStructHelpers).\(nestedName.replacingOccurrences(of: ".", with: "_")).lift();" + "const \(structVar) = \(JSGlueVariableScope.reservedStructHelpers).\(nestedBase).lift();" ) return [structVar] } @@ -2608,7 +2824,7 @@ private extension BridgeType { return .inlineFlag case .closure: return .inlineFlag - case .swiftStruct, .array, .dictionary, .void, .namespaceEnum: + case .swiftStruct, .array, .dictionary, .void, .namespaceEnum, .generic: return .stackABI case .nullable(let wrapped, _): return wrapped.optionalConvention @@ -2706,7 +2922,7 @@ private extension BridgeType { return [("caseId", .i32)] case .closure: return [("funcRef", .i32)] - case .void, .namespaceEnum, .swiftStruct, .array, .dictionary: + case .void, .namespaceEnum, .swiftStruct, .array, .dictionary, .generic: return [] case .nullable(let wrapped, _): return wrapped.wasmParams diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/JSIntrinsicRegistry.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/JSIntrinsicRegistry.swift index e3654e89f..d0bf2781f 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/JSIntrinsicRegistry.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/JSIntrinsicRegistry.swift @@ -7,6 +7,11 @@ final class JSIntrinsicRegistry { private var entries: [String: [String]] = [:] var classNamespaces: [String: [String]] = [:] + var typeOwnerModules: [String: String] = [:] + + private var codecNameOrder: [String] = [] + private var codecBodies: [String: [String]] = [:] + var isEmpty: Bool { entries.isEmpty } @@ -18,9 +23,29 @@ final class JSIntrinsicRegistry { entries[name] = printer.lines } + func registerNamedCodec(name: String, build: (CodeFragmentPrinter) throws -> Void) rethrows { + guard codecBodies[name] == nil else { return } + let printer = CodeFragmentPrinter() + try build(printer) + guard codecBodies[name] == nil else { return } + codecBodies[name] = printer.lines + codecNameOrder.append(name) + } + + var hasNamedCodecs: Bool { + !codecNameOrder.isEmpty + } + + func emitNamedCodecLines() -> [String] { + codecNameOrder.flatMap { codecBodies[$0] ?? [] } + } + func reset() { entries.removeAll() classNamespaces.removeAll() + typeOwnerModules.removeAll() + codecNameOrder.removeAll() + codecBodies.removeAll() } func emitLines() -> [String] { diff --git a/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift b/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift index 5507f39c2..8aaa6d5cd 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift @@ -14,6 +14,14 @@ extension NamespacedExportedType { } return name } + + public var tsPathComponents: [String] { + (namespace ?? []) + [name] + } + + public var tsFullPath: String { + tsPathComponents.joined(separator: ".") + } } // MARK: - ABI Name Generation @@ -22,6 +30,14 @@ extension NamespacedExportedType { public struct ABINameGenerator { static let prefixComponent = "bjs" + public static func genericTypeIdParameterName(index: Int) -> String { "_generic\(index)TypeId" } + + public static func typeRegistrationFunctionName(moduleName: String) -> String { + "bjs_\(moduleName)_register_type_handles" + } + + public static let coreTypeRegistrationFunctionName = "bjs_core_register_type_handles" + /// Generates ABI name using standardized namespace + context pattern public static func generateABIName( baseName: String, @@ -273,10 +289,104 @@ public enum BridgeType: Codable, Equatable, Hashable, Sendable { case namespaceEnum(String) case swiftProtocol(String) case swiftStruct(String) + case generic(String) indirect case closure(ClosureSignature, useJSTypedClosure: Bool) indirect case alias(name: String, underlying: BridgeType) } +extension BridgeType { + public var referencedGenericName: String? { + switch self { + case .generic(let name): return name + case .array(.generic(let name)): return name + case .nullable(.generic(let name), _): return name + case .dictionary(.generic(let name)): return name + default: return nil + } + } + + public static let genericBridgeablePrimitives: [(token: String, type: BridgeType)] = [ + ("Bool", .bool), + ("Int", .integer(.int)), + ("Int8", .integer(.int8)), + ("UInt8", .integer(.uint8)), + ("Int16", .integer(.int16)), + ("UInt16", .integer(.uint16)), + ("Int32", .integer(.int32)), + ("UInt32", .integer(.uint32)), + ("UInt", .integer(.uint)), + ("Int64", .integer(.int64)), + ("UInt64", .integer(.uint64)), + ("Float", .float), + ("Double", .double), + ("String", .string), + ("JSValue", .jsValue), + ] + +} + +public struct GenericBridgeableTypeEntry: Sendable { + public let swiftName: String + public let bridgeType: BridgeType + + public init(swiftName: String, bridgeType: BridgeType) { + self.swiftName = swiftName + self.bridgeType = bridgeType + } +} + +extension ExportedEnum { + public var genericBridgeType: BridgeType? { + switch enumType { + case .simple: + return .caseEnum(swiftCallName) + case .rawValue: + guard let rawType = rawType else { return nil } + return .rawValueEnum(swiftCallName, rawType) + case .associatedValue: + return .associatedValueEnum(swiftCallName) + case .namespace: + return nil + } + } +} + +extension ExportedSkeleton { + /// Keep this order in sync with the generated registration codec array. + public var genericBridgeableTypeEntries: [GenericBridgeableTypeEntry] { + var entries: [GenericBridgeableTypeEntry] = [] + for structDef in structs { + entries.append( + GenericBridgeableTypeEntry( + swiftName: structDef.swiftCallName, + bridgeType: .swiftStruct(structDef.swiftCallName) + ) + ) + } + for klass in classes where klass.isFinal == true { + entries.append( + GenericBridgeableTypeEntry( + swiftName: klass.swiftCallName, + bridgeType: .swiftHeapObject(klass.swiftCallName) + ) + ) + } + for enumDef in enums { + guard let bridgeType = enumDef.genericBridgeType else { continue } + entries.append(GenericBridgeableTypeEntry(swiftName: enumDef.swiftCallName, bridgeType: bridgeType)) + } + return entries + } +} + +extension BridgeJSSkeleton { + public var typeRegistrationEntries: [GenericBridgeableTypeEntry]? { + let exportedEntries = exported?.genericBridgeableTypeEntries ?? [] + guard !exportedEntries.isEmpty else { return nil } + return exportedEntries + } +} + public enum WasmCoreType: String, Codable, Sendable { case i32, i64, f32, f64, pointer } @@ -861,6 +971,7 @@ public struct ExportedProtocol: Codable, Equatable { public struct ExportedFunction: Codable, Equatable, Sendable { public var name: String + public var jsName: String? public var abiName: String public var parameters: [Parameter] public var returnType: BridgeType @@ -869,8 +980,11 @@ public struct ExportedFunction: Codable, Equatable, Sendable { public var staticContext: StaticContext? public var documentation: String? + public var resolvedJSName: String { jsName ?? name } + public init( name: String, + jsName: String? = nil, abiName: String, parameters: [Parameter], returnType: BridgeType, @@ -880,6 +994,7 @@ public struct ExportedFunction: Codable, Equatable, Sendable { documentation: String? = nil ) { self.name = name + self.jsName = jsName self.abiName = abiName self.parameters = parameters self.returnType = returnType @@ -900,6 +1015,7 @@ public struct ExportedClass: Codable, NamespacedExportedType { public var namespace: [String]? public var identityMode: Bool? // nil = use config default, true/false = override public var documentation: String? + public var isFinal: Bool? public init( name: String, @@ -910,7 +1026,8 @@ public struct ExportedClass: Codable, NamespacedExportedType { properties: [ExportedProperty] = [], namespace: [String]? = nil, identityMode: Bool? = nil, - documentation: String? = nil + documentation: String? = nil, + isFinal: Bool? = nil ) { self.name = name self.swiftCallName = swiftCallName @@ -921,6 +1038,7 @@ public struct ExportedClass: Codable, NamespacedExportedType { self.namespace = namespace self.identityMode = identityMode self.documentation = documentation + self.isFinal = isFinal } } @@ -948,6 +1066,7 @@ public struct ExportedConstructor: Codable, Equatable, Sendable { public struct ExportedProperty: Codable, Equatable, Sendable { public var name: String + public var jsName: String? public var type: BridgeType public var isReadonly: Bool public var isStatic: Bool @@ -955,8 +1074,11 @@ public struct ExportedProperty: Codable, Equatable, Sendable { public var staticContext: StaticContext? public var documentation: String? + public var resolvedJSName: String { jsName ?? name } + public init( name: String, + jsName: String? = nil, type: BridgeType, isReadonly: Bool = false, isStatic: Bool = false, @@ -965,6 +1087,7 @@ public struct ExportedProperty: Codable, Equatable, Sendable { documentation: String? = nil ) { self.name = name + self.jsName = jsName self.type = type self.isReadonly = isReadonly self.isStatic = isStatic @@ -1244,6 +1367,11 @@ public struct ImportedFunctionSkeleton: Codable { /// determine the access level of bridge-generated helpers (e.g. typed /// closure inits) that surface through this function's signature. public let accessLevel: BridgeJSAccessLevel + public let genericParameters: [String]? + public var genericParameterNames: [String] { genericParameters ?? [] } + public var isGeneric: Bool { !genericParameterNames.isEmpty } + + public var resolvedJSName: String { jsName ?? name } public init( name: String, @@ -1253,7 +1381,8 @@ public struct ImportedFunctionSkeleton: Codable { returnType: BridgeType, effects: Effects = Effects(isAsync: false, isThrows: true), documentation: String? = nil, - accessLevel: BridgeJSAccessLevel = .internal + accessLevel: BridgeJSAccessLevel = .internal, + genericParameters: [String]? = nil ) { self.name = name self.jsName = jsName @@ -1263,10 +1392,11 @@ public struct ImportedFunctionSkeleton: Codable { self.effects = effects self.documentation = documentation self.accessLevel = accessLevel + self.genericParameters = genericParameters } private enum CodingKeys: String, CodingKey { - case name, jsName, from, parameters, returnType, effects, documentation, accessLevel + case name, jsName, from, parameters, returnType, effects, documentation, accessLevel, genericParameters } public init(from decoder: any Decoder) throws { @@ -1279,6 +1409,7 @@ public struct ImportedFunctionSkeleton: Codable { self.effects = try container.decode(Effects.self, forKey: .effects) self.documentation = try container.decodeIfPresent(String.self, forKey: .documentation) self.accessLevel = try container.decodeIfPresent(BridgeJSAccessLevel.self, forKey: .accessLevel) ?? .internal + self.genericParameters = try container.decodeIfPresent([String].self, forKey: .genericParameters) } public func abiName(context: ImportedTypeSkeleton?) -> String { @@ -1299,20 +1430,29 @@ public struct ImportedConstructorSkeleton: Codable { /// Source access level of the originating Swift `init`. Inherits from the /// enclosing `@JSClass` type when not annotated explicitly. public let accessLevel: BridgeJSAccessLevel + public let genericParameters: [String]? + public var genericParameterNames: [String] { genericParameters ?? [] } + public var isGeneric: Bool { !genericParameterNames.isEmpty } - public init(parameters: [Parameter], accessLevel: BridgeJSAccessLevel = .internal) { + public init( + parameters: [Parameter], + accessLevel: BridgeJSAccessLevel = .internal, + genericParameters: [String]? = nil + ) { self.parameters = parameters self.accessLevel = accessLevel + self.genericParameters = genericParameters } private enum CodingKeys: String, CodingKey { - case parameters, accessLevel + case parameters, accessLevel, genericParameters } public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.parameters = try container.decode([Parameter].self, forKey: .parameters) self.accessLevel = try container.decodeIfPresent(BridgeJSAccessLevel.self, forKey: .accessLevel) ?? .internal + self.genericParameters = try container.decodeIfPresent([String].self, forKey: .genericParameters) } public func abiName(context: ImportedTypeSkeleton) -> String { @@ -1336,6 +1476,8 @@ public struct ImportedGetterSkeleton: Codable { /// Source access level of the originating Swift declaration. public let accessLevel: BridgeJSAccessLevel + public var resolvedJSName: String { jsName ?? name } + public init( name: String, jsName: String? = nil, @@ -1396,6 +1538,8 @@ public struct ImportedSetterSkeleton: Codable { /// Source access level of the originating Swift declaration. public let accessLevel: BridgeJSAccessLevel + public var resolvedJSName: String { jsName ?? name } + public init( name: String, jsName: String? = nil, @@ -1458,6 +1602,8 @@ public struct ImportedTypeSkeleton: Codable { /// Source access level of the originating Swift `@JSClass` declaration. public let accessLevel: BridgeJSAccessLevel + public var resolvedJSName: String { jsName ?? name } + public init( name: String, jsName: String? = nil, @@ -1553,6 +1699,17 @@ public struct ImportedFileSkeleton: Codable { } } +extension ImportedFileSkeleton { + public var hasGenericDeclarations: Bool { + functions.contains(where: \.isGeneric) + || types.contains { + $0.methods.contains(where: \.isGeneric) + || $0.staticMethods.contains(where: \.isGeneric) + || ($0.constructor?.isGeneric ?? false) + } + } +} + public struct ImportedModuleSkeleton: Codable { public var children: [ImportedFileSkeleton] @@ -1561,6 +1718,12 @@ public struct ImportedModuleSkeleton: Codable { } } +extension ImportedModuleSkeleton { + public var hasGenericDeclarations: Bool { + children.contains { $0.hasGenericDeclarations } + } +} + // MARK: - Closure signature collection visitor public struct ClosureSignatureCollectorVisitor: BridgeSkeletonVisitor { @@ -1735,7 +1898,7 @@ extension BridgeType { case .bool, .integer, .float, .double, .string, .jsValue, .jsObject, .swiftHeapObject, .unsafePointer, .swiftProtocol, .void, .caseEnum, .rawValueEnum, .associatedValueEnum, .swiftStruct, - .namespaceEnum, .closure: + .namespaceEnum, .closure, .generic: return self } } @@ -1782,6 +1945,8 @@ extension BridgeType { return nil case .alias(_, let underlying): return underlying.abiReturnType + case .generic: + return nil } } @@ -1822,11 +1987,11 @@ extension BridgeType { case .void: return "y" case .jsObject(let name): let typeName = name ?? "JSObject" - return "\(typeName.count)\(typeName)C" + return "\(Self.mangleQualifiedName(typeName))C" case .jsValue: return "7JSValueV" case .swiftHeapObject(let name): - return "\(name.count)\(name)C" + return "\(Self.mangleQualifiedName(name))C" case .unsafePointer(let ptr): func sanitize(_ s: String) -> String { s.filter { $0.isNumber || $0.isLetter } @@ -1851,11 +2016,11 @@ extension BridgeType { .rawValueEnum(let name, _), .associatedValueEnum(let name), .namespaceEnum(let name): - return "\(name.count)\(name)O" + return "\(Self.mangleQualifiedName(name))O" case .swiftProtocol(let name): - return "\(name.count)\(name)P" + return "\(Self.mangleQualifiedName(name))P" case .swiftStruct(let name): - return "\(name.count)\(name)V" + return "\(Self.mangleQualifiedName(name))V" case .closure(let signature, let useJSTypedClosure): let params = signature.parameters.isEmpty @@ -1872,10 +2037,18 @@ extension BridgeType { case .alias(let name, _): // `name` is the namespace-qualified swiftCallName (unique), so the underlying // representation isn't mangled in - aliases bridge via their JS type's ABI. - return "Al\(name.count)\(name)" + return "Al\(Self.mangleQualifiedName(name))" + case .generic(let name): + return "\(name.count)\(name)T" } } + /// Transforms a namespace-qualified name into a valid identifier by removing + /// each dot and prefixing each component with length (e.g. `Workshop.Bench` -> `8Workshop5Bench`). + private static func mangleQualifiedName(_ name: String) -> String { + name.split(separator: ".").map { "\($0.count)\($0)" }.joined() + } + /// Determines if an optional type requires side-channel communication for protocol property returns /// /// Side channels are needed when the wrapped type cannot be directly returned via WASM, diff --git a/Plugins/BridgeJS/Sources/BridgeJSTool/BridgeJSTool.swift b/Plugins/BridgeJS/Sources/BridgeJSTool/BridgeJSTool.swift index 140ebda63..d3d9a484e 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSTool/BridgeJSTool.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSTool/BridgeJSTool.swift @@ -2,7 +2,6 @@ @preconcurrency import func Foundation.fputs @preconcurrency import func Foundation.open @preconcurrency import func Foundation.strerror -@preconcurrency import var Foundation.stderr @preconcurrency import var Foundation.errno @preconcurrency import var Foundation.O_WRONLY @preconcurrency import var Foundation.O_CREAT @@ -15,6 +14,17 @@ @preconcurrency import class Foundation.FileManager @preconcurrency import class Foundation.JSONDecoder @preconcurrency import class Foundation.ProcessInfo + +#if canImport(Darwin) +@preconcurrency import var Darwin.stderr +#elseif canImport(Glibc) +@preconcurrency import var Glibc.stderr +#elseif canImport(Musl) +@preconcurrency import var Musl.stderr +#elseif canImport(Android) +@preconcurrency import var Android.stderr +#endif + import SwiftParser import SwiftSyntax @@ -240,9 +250,12 @@ import BridgeJSUtilities return try exporter?.finalize() } + // Type-handle registration is shared by exported types and generic imports. + let typeRegistration = GenericTypeRegistrationCodegen().render(for: skeleton) + // Combine and write unified Swift output let outputSwiftURL = outputDirectory.appending(path: "BridgeJS.swift") - let combinedSwift = [closureSupport, exportResult, importResult].compactMap { $0 } + let combinedSwift = [closureSupport, exportResult, importResult, typeRegistration].compactMap { $0 } let outputSwift = combineGeneratedSwift( combinedSwift, importingExternalModules: skeleton.usedExternalModules diff --git a/Plugins/BridgeJS/Sources/BridgeJSToolInternal/BridgeJSToolInternal.swift b/Plugins/BridgeJS/Sources/BridgeJSToolInternal/BridgeJSToolInternal.swift index cb6a5481c..f57f50756 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSToolInternal/BridgeJSToolInternal.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSToolInternal/BridgeJSToolInternal.swift @@ -98,7 +98,8 @@ import ArgumentParser skeleton: $0 ).finalize() } - let combinedSwift = [exported, imported].compactMap { $0 } + let typeRegistration = GenericTypeRegistrationCodegen().render(for: skeleton) + let combinedSwift = [exported, imported, typeRegistration].compactMap { $0 } print(combinedSwift.joined(separator: "\n\n")) } } @@ -109,7 +110,7 @@ import ArgumentParser let skeletonData = try readData(from: skeletonFile) skeletons.append(try JSONDecoder().decode(BridgeJSSkeleton.self, from: skeletonData)) } - let link = BridgeJSLink(skeletons: skeletons, sharedMemory: false) + let link = BridgeJSLink(skeletons: skeletons) return try link.link() } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSCodegenTests.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSCodegenTests.swift index 60b2fd485..11347dc40 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSCodegenTests.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSCodegenTests.swift @@ -141,6 +141,9 @@ import Testing swiftParts.append(s) } } + if let typeRegistration = GenericTypeRegistrationCodegen().render(for: skeleton) { + swiftParts.append(typeRegistration) + } let combinedSwift = swiftParts .map { $0.trimmingCharacters(in: .newlines) } @@ -333,6 +336,52 @@ import Testing try snapshotCodegen(skeleton: skeleton, name: "CrossFileExtension") } + @Test + func codegenCrossFileNestedTypeExtension() throws { + let swiftAPI = SwiftToSkeleton( + progress: .silent, + moduleName: "TestModule", + exposeToGlobal: false, + externalModuleIndex: .empty + ) + let classURL = Self.multifileInputsDirectory.appendingPathComponent("CrossFileNestedTypeClass.swift") + swiftAPI.addSourceFile( + Parser.parse(source: try String(contentsOf: classURL, encoding: .utf8)), + inputFilePath: "CrossFileNestedTypeClass.swift" + ) + let extensionURL = Self.multifileInputsDirectory.appendingPathComponent("CrossFileNestedTypeExtension.swift") + swiftAPI.addSourceFile( + Parser.parse(source: try String(contentsOf: extensionURL, encoding: .utf8)), + inputFilePath: "CrossFileNestedTypeExtension.swift" + ) + let skeleton = try swiftAPI.finalize() + try snapshotCodegen(skeleton: skeleton, name: "CrossFileNestedTypeExtension") + } + + @Test + func codegenCrossFileExtensionOrderIndependence() throws { + let swiftAPI = SwiftToSkeleton( + progress: .silent, + moduleName: "TestModule", + exposeToGlobal: false, + externalModuleIndex: .empty + ) + let memberURL = Self.multifileInputsDirectory.appendingPathComponent("CrossFileExtensionOrderMember.swift") + swiftAPI.addSourceFile( + Parser.parse(source: try String(contentsOf: memberURL, encoding: .utf8)), + inputFilePath: "CrossFileExtensionOrderMember.swift" + ) + let typeURL = Self.multifileInputsDirectory.appendingPathComponent("CrossFileExtensionOrderType.swift") + swiftAPI.addSourceFile( + Parser.parse(source: try String(contentsOf: typeURL, encoding: .utf8)), + inputFilePath: "CrossFileExtensionOrderType.swift" + ) + let skeleton = try swiftAPI.finalize() + let record = skeleton.exported?.structs.first { $0.swiftCallName == "Archive.Record" } + #expect(record?.methods.map(\.name) == ["describeRecord"]) + try snapshotCodegen(skeleton: skeleton, name: "CrossFileExtensionOrderIndependence") + } + @Test func codegenSkipsEmptySkeletons() throws { let swiftAPI = SwiftToSkeleton( diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift index 642debedc..f96ec2d8d 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift @@ -70,7 +70,7 @@ import Testing ) importSwift.addSourceFile(sourceFile, inputFilePath: "\(name).swift") let importResult = try importSwift.finalize() - var bridgeJSLink = BridgeJSLink(sharedMemory: false) + var bridgeJSLink = BridgeJSLink() let encoder = JSONEncoder() encoder.outputFormatting = [.prettyPrinted, .sortedKeys] let unifiedData = try encoder.encode(importResult) @@ -99,8 +99,7 @@ import Testing let bridgeJSLink: BridgeJSLink = BridgeJSLink( skeletons: [ outputSkeleton - ], - sharedMemory: false + ] ) try snapshot(bridgeJSLink: bridgeJSLink, name: name + ".Global") } @@ -133,12 +132,31 @@ import Testing skeletons: [ globalSkeleton, privateSkeleton, - ], - sharedMemory: false + ] ) try snapshot(bridgeJSLink: bridgeJSLink, name: "MixedModules") } + private func linkedJS(forFixture input: String) throws -> String { + let url = Self.inputsDirectory.appendingPathComponent(input) + let name = url.deletingPathExtension().lastPathComponent + let sourceFile = Parser.parse(source: try String(contentsOf: url, encoding: .utf8)) + let importSwift = SwiftToSkeleton( + progress: .silent, + moduleName: "TestModule", + exposeToGlobal: false, + externalModuleIndex: .empty + ) + importSwift.addSourceFile(sourceFile, inputFilePath: "\(name).swift") + let importResult = try importSwift.finalize() + var bridgeJSLink = BridgeJSLink() + let encoder = JSONEncoder() + encoder.outputFormatting = [.prettyPrinted, .sortedKeys] + let unifiedData = try encoder.encode(importResult) + try bridgeJSLink.addSkeletonFile(data: unifiedData) + return try bridgeJSLink.link().0 + } + @Test func perClassIdentityModeFromAnnotation() throws { let url = Self.inputsDirectory.appendingPathComponent("IdentityModeClass.swift") @@ -162,7 +180,7 @@ import Testing #expect(explicitlyUncachedClass?.identityMode == false) // Verify generated JS via snapshot - let bridgeJSLink = BridgeJSLink(skeletons: [outputSkeleton], sharedMemory: false) + let bridgeJSLink = BridgeJSLink(skeletons: [outputSkeleton]) try snapshot(bridgeJSLink: bridgeJSLink, name: "IdentityModeClass.PerClass") } @@ -186,7 +204,7 @@ import Testing #expect(explicitlyUncachedClass?.identityMode == false) // Verify generated JS via snapshot - let bridgeJSLink = BridgeJSLink(skeletons: [outputSkeleton], sharedMemory: false) + let bridgeJSLink = BridgeJSLink(skeletons: [outputSkeleton]) try snapshot(bridgeJSLink: bridgeJSLink, name: "IdentityModeClass.ConfigPointer") } } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/CodegenTestSupport.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/CodegenTestSupport.swift new file mode 100644 index 000000000..b66a5ba6f --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/CodegenTestSupport.swift @@ -0,0 +1,40 @@ +import Foundation +import SwiftParser +import SwiftSyntax +import Testing + +@testable import BridgeJSLink +@testable import BridgeJSCore +@testable import BridgeJSSkeleton + +func makeSkeleton( + _ source: String, + moduleName: String = "TestModule", + dependencies: [(moduleName: String, skeleton: BridgeJSSkeleton)] = [] +) throws -> BridgeJSSkeleton { + let swiftAPI = SwiftToSkeleton( + progress: .silent, + moduleName: moduleName, + exposeToGlobal: false, + externalModuleIndex: ExternalModuleIndex(dependencies: dependencies) + ) + swiftAPI.addSourceFile(Parser.parse(source: source), inputFilePath: "\(moduleName).swift") + return try swiftAPI.finalize() +} + +func expectDiagnostic( + source: String, + moduleName: String = "App", + contains message: String, + sourceLocation: Testing.SourceLocation = #_sourceLocation +) { + do { + _ = try makeSkeleton(source, moduleName: moduleName) + Issue.record("Expected diagnostic but resolution succeeded", sourceLocation: sourceLocation) + } catch let error as BridgeJSCoreDiagnosticError { + let combined = error.diagnostics.map(\.diagnostic.message).joined(separator: "\n") + #expect(combined.contains(message), sourceLocation: sourceLocation) + } catch { + Issue.record("Unexpected error: \(error)", sourceLocation: sourceLocation) + } +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/DiagnosticsTests.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/DiagnosticsTests.swift index 316d51b41..4f45a9880 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/DiagnosticsTests.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/DiagnosticsTests.swift @@ -26,6 +26,44 @@ import Testing } } + @Test + func extensionOfUnknownTypeWithJSMemberProducesDiagnostic() throws { + let source = """ + extension Unknown { + @JS func bridged() -> Int { 42 } + } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("Unsupported type 'Unknown'")) + } + + @Test + func extensionWithoutJSMembersIsIgnored() throws { + let source = """ + extension String { + func helper() -> Int { 42 } + } + """ + #expect(moduleDiagnostics(source: source) == nil) + } + + @Test + func invalidJSMemberInsideExtensionProducesDiagnostic() throws { + let source = """ + @JS class Host { + @JS init() {} + } + + extension Host { + @JS struct Bad { + var field = 1 + } + } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("Struct field must have explicit type annotation")) + } + @Test func missingJavaScriptModuleProducesDiagnostic() throws { let source = """ @@ -658,6 +696,87 @@ import Testing } } + @Test + func jsNameOnClassDiagnostic() throws { + let source = """ + @JS("Renamed") class Box { @JS init() {} } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("A separate name for JavaScript is not supported here")) + } + + @Test + func jsNameOnStructDiagnostic() throws { + let source = """ + @JS("Renamed") struct Box { var x: Int } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("A separate name for JavaScript is not supported here")) + } + + @Test + func jsNameOnEnumDiagnostic() throws { + let source = """ + @JS("Renamed") enum Box { case a } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("A separate name for JavaScript is not supported here")) + } + + @Test + func jsNameOnProtocolDiagnostic() throws { + let source = """ + @JS("Renamed") protocol Box { func run() } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("A separate name for JavaScript is not supported here")) + } + + @Test + func jsNameOnInitializerDiagnostic() throws { + let source = """ + @JS class Box { @JS("create") init() {} } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("A separate name for JavaScript is not supported here")) + } + + @Test + func jsNameOnProtocolRequirementDiagnostic() throws { + let source = """ + @JS protocol Box { @JS("run") func run() } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("A separate name for JavaScript is not supported here")) + } + + @Test + func invalidJSNameDiagnostic() throws { + let source = """ + @JS("1notAnIdentifier") func a() -> Int { 42 } + @JS("has space") func b() -> Int { 42 } + @JS("has-dash") func c() -> Int { 42 } + @JS("") func d() -> Int { 42 } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("`1notAnIdentifier` is not a valid JavaScript identifier")) + #expect(diagnostics.description.contains("`has space` is not a valid JavaScript identifier")) + #expect(diagnostics.description.contains("`has-dash` is not a valid JavaScript identifier")) + #expect(diagnostics.description.contains("`` is not a valid JavaScript identifier")) + } + + @Test + func jsNameOnMultipleBindingsDiagnostic() throws { + let source = """ + @JS class Box { + @JS init() {} + @JS("renamed") var first: Int = 1, second: Int = 2 + } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("Name targets declaration with multiple bindings")) + } + @Test func omitsNextLineWhenErrorIsOnLastLine() throws { let source = """ diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/GenericExportDiagnosticsTests.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/GenericExportDiagnosticsTests.swift new file mode 100644 index 000000000..37f2a0318 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/GenericExportDiagnosticsTests.swift @@ -0,0 +1,63 @@ +import Testing + +@Suite struct GenericExportDiagnosticsTests { + + @Test + func genericExportedFunctionRejected() { + expectDiagnostic( + source: """ + @JS public func identity(_ value: T) -> T { value } + """, + contains: "Generic parameters on exported @JS functions are not supported yet" + ) + } + + @Test + func genericMethodOnExportedClassRejected() { + expectDiagnostic( + source: """ + @JS final class Box { + @JS init() {} + @JS func wrap(_ value: T) -> T { value } + } + """, + contains: "Generic parameters on exported @JS functions are not supported yet" + ) + } + + @Test + func genericMethodOnExportedStructRejected() { + expectDiagnostic( + source: """ + @JS struct Pair { + @JS init() {} + @JS func first(_ value: T) -> T { value } + } + """, + contains: "Generic parameters on exported @JS functions are not supported yet" + ) + } + + @Test + func genericStaticMethodOnExportedEnumRejected() { + expectDiagnostic( + source: """ + @JS enum Factory { + case primary + @JS static func one(_ value: T) -> T { value } + } + """, + contains: "Generic parameters on exported @JS functions are not supported yet" + ) + } + + @Test + func unconstrainedGenericExportedFunctionRejected() { + expectDiagnostic( + source: """ + @JS public func identity(_ value: T) -> T { value } + """, + contains: "Generic parameters on exported @JS functions are not supported yet" + ) + } +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/GenericImportDiagnosticsTests.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/GenericImportDiagnosticsTests.swift new file mode 100644 index 000000000..4a421b73b --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/GenericImportDiagnosticsTests.swift @@ -0,0 +1,210 @@ +import Testing + +@testable import BridgeJSSkeleton + +@Suite struct GenericImportDiagnosticsTests { + + @Test + func genericParameterRequiresBridgeableConstraint() { + expectDiagnostic( + source: """ + @JSFunction func identity(_ value: T) throws(JSException) -> T + """, + contains: "Generic parameter 'T' must be constrained to 'BridgedSwiftGenericBridgeable'" + ) + } + + @Test + func genericWhereClauseUnsupported() { + expectDiagnostic( + source: """ + @JSFunction func identity(_ value: T) throws(JSException) -> T where T: Sendable + """, + contains: "'where' clauses are not supported on @JSFunction" + ) + } + + @Test + func asyncGenericImportUnsupported() { + expectDiagnostic( + source: """ + @JSFunction func identityAsync(_ value: T) async throws(JSException) -> T + """, + contains: "Generic @JSFunction declarations cannot be 'async' yet." + ) + } + + @Test + func genericImportedMethodIsParsed() throws { + let skeleton = try makeSkeleton( + """ + @JSClass struct Box { + @JSFunction func member(_ value: T) throws(JSException) -> T + } + """, + moduleName: "App" + ) + let imported = try #require(skeleton.imported) + let types = imported.children.flatMap { $0.types } + let box = try #require(types.first { $0.name == "Box" }) + let method = try #require(box.methods.first { $0.name == "member" }) + #expect(method.genericParameters == ["T"]) + } + + @Test + func genericImportedConstructorIsParsed() throws { + let skeleton = try makeSkeleton( + """ + @JSClass struct Box { + @JSFunction init(_ value: T) throws(JSException) + } + """, + moduleName: "App" + ) + let imported = try #require(skeleton.imported) + let types = imported.children.flatMap { $0.types } + let box = try #require(types.first { $0.name == "Box" }) + let constructor = try #require(box.constructor) + #expect(constructor.genericParameters == ["T"]) + #expect(constructor.parameters.map(\.type) == [.generic("T")]) + } + + @Test + func genericImportedConstructorUnconstrainedParamIsRejected() { + expectDiagnostic( + source: """ + @JSClass struct Box { + @JSFunction init(_ value: T) throws(JSException) + } + """, + contains: + "Generic parameter 'T' must be constrained to 'BridgedSwiftGenericBridgeable' to be used with @JSFunction." + ) + } + + @Test + func genericImportedConstructorUnusedTypeParamIsRejected() { + expectDiagnostic( + source: """ + @JSClass struct Box { + @JSFunction init(_ value: Int) throws(JSException) + } + """, + contains: + "The generic parameter 'T' must be used in a parameter of a generic @JSFunction initializer." + ) + } + + @Test + func genericImportedConstructorAsyncIsRejected() { + expectDiagnostic( + source: """ + @JSClass struct Box { + @JSFunction init(_ value: T) async throws(JSException) + } + """, + contains: "Generic @JSFunction declarations cannot be 'async' yet." + ) + } + + @Test + func genericImportedConstructorUnsupportedWrapperFormIsRejected() { + expectDiagnostic( + source: """ + @JSClass struct Box { + @JSFunction init(_ value: [[T]]) throws(JSException) + } + """, + contains: "may only be used as a bare type" + ) + } + + @Test(arguments: [ + ("[[T]]", "@JSFunction func f(_ v: [[T]]) throws(JSException)"), + ("[T?]", "@JSFunction func f(_ v: [T?]) throws(JSException)"), + ("T??", "@JSFunction func f(_ v: T??) throws(JSException)"), + ("[Int: T]", "@JSFunction func f(_ v: [Int: T]) throws(JSException)"), + ]) + func unsupportedGenericWrapperFormsInParameter(label: String, source: String) { + expectDiagnostic( + source: source, + contains: "may only be used as a bare type" + ) + } + + @Test(arguments: [ + ("[[T]]", "@JSFunction func f(_ v: T) throws(JSException) -> [[T]]"), + ("[T?]", "@JSFunction func f(_ v: T) throws(JSException) -> [T?]"), + ("T??", "@JSFunction func f(_ v: T) throws(JSException) -> T??"), + ("[Int: T]", "@JSFunction func f(_ v: T) throws(JSException) -> [Int: T]"), + ]) + func unsupportedGenericWrapperFormsInReturn(label: String, source: String) { + expectDiagnostic( + source: source, + contains: "may only be used as a bare type" + ) + } + + @Test + func genericImportedMethodAsyncIsRejected() { + expectDiagnostic( + source: """ + @JSClass struct Box { + @JSFunction func member(_ value: T) async throws(JSException) -> T + } + """, + contains: "Generic @JSFunction declarations cannot be 'async' yet." + ) + } + + @Test + func genericImportedMethodUnconstrainedParamIsRejected() { + expectDiagnostic( + source: """ + @JSClass struct Box { + @JSFunction func member(_ value: T) throws(JSException) -> T + } + """, + contains: + "Generic parameter 'T' must be constrained to 'BridgedSwiftGenericBridgeable' to be used with @JSFunction." + ) + } + + @Test + func genericImportedFunctionUnusedTypeParamIsRejected() { + expectDiagnostic( + source: """ + @JSFunction func unused() throws(JSException) -> Int + """, + contains: + "The generic parameter 'T' must be used in a parameter or return type of a generic @JSFunction declaration." + ) + } + + @Test + func genericImportedMethodUnusedTypeParamIsRejected() { + expectDiagnostic( + source: """ + @JSClass struct Box { + @JSFunction func member() throws(JSException) -> Int + } + """, + contains: + "The generic parameter 'T' must be used in a parameter or return type of a generic @JSFunction declaration." + ) + } + + @Test + func genericImportedReturnOnlyTypeParamIsAllowed() throws { + let skeleton = try makeSkeleton( + """ + @JSFunction func make() throws(JSException) -> T + """, + moduleName: "App" + ) + let imported = try #require(skeleton.imported) + let functions = imported.children.flatMap { $0.functions } + let function = try #require(functions.first { $0.name == "make" }) + #expect(function.genericParameters == ["T"]) + } +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/ImportedJSModuleRegistryTests.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/ImportedJSModuleRegistryTests.swift index 16c28be95..7c5d168d2 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/ImportedJSModuleRegistryTests.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/ImportedJSModuleRegistryTests.swift @@ -35,7 +35,7 @@ import Testing } private func importLines(_ skeletons: [BridgeJSSkeleton]) throws -> [String] { - var link = BridgeJSLink(sharedMemory: false) + var link = BridgeJSLink() let encoder = JSONEncoder() for skeleton in skeletons { _ = try link.addSkeletonFile(data: try encoder.encode(skeleton)) diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/ExtensionNestedTypes.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/ExtensionNestedTypes.swift new file mode 100644 index 000000000..b3ef8ddaf --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/ExtensionNestedTypes.swift @@ -0,0 +1,68 @@ +@JS class Library { + @JS var name: String + + @JS init(name: String) { + self.name = name + } + + @JS func describe() -> String { + name + } +} + +extension Library { + typealias Title = String + + @JS enum Genre: String { + case fiction + case reference + } + + @JS struct Shelf { + var label: String + + @JS init(label: String) { + self.label = label + } + + @JS static var capacity: Int { 32 } + } + + @JS func rename(_ title: Title) -> Title { + title + } + + @JS func shelf(label: String) -> Shelf { + Shelf(label: label) + } +} + +extension Library.Shelf { + @JS struct Divider { + var slot: Int + + @JS init(slot: Int) { + self.slot = slot + } + } + + @JS func describeShelf() -> String { + "Shelf: " + label + } +} + +@JS enum Message { + case update(Update) + case delete +} + +extension Message { + @JS enum Update { + case flip + case rotate + } +} + +@JS func roundTripMessage(_ message: Message) -> Message { + message +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/ExtensionOrderIndependence.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/ExtensionOrderIndependence.swift new file mode 100644 index 000000000..143a60233 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/ExtensionOrderIndependence.swift @@ -0,0 +1,19 @@ +@JS class Depot { + @JS init() {} +} + +extension Depot.Crate { + @JS func describeCrate() -> String { + "Crate: " + label + } +} + +extension Depot { + @JS struct Crate { + var label: String + + @JS init(label: String) { + self.label = label + } + } +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/ExtensionScopeParity.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/ExtensionScopeParity.swift new file mode 100644 index 000000000..43a71c484 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/ExtensionScopeParity.swift @@ -0,0 +1,25 @@ +@JS(namespace: "app") enum Toolbox { + @JS class Mallet { + @JS init() {} + } +} + +extension Toolbox { + @JS class Hammer { + @JS init() {} + } +} + +@JS enum Signal: String { + case ready +} + +extension Signal { + @JS struct Meta { + var note: String + + @JS init(note: String) { + self.note = note + } + } +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/GenericImports.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/GenericImports.swift new file mode 100644 index 000000000..5fd3d0226 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/GenericImports.swift @@ -0,0 +1,74 @@ +@JS +struct GenericPoint { + var x: Int + var y: Int +} + +@JS enum GenericColor { + case red + case green +} + +@JS enum GenericMode: String { + case light + case dark +} + +@JS enum GenericTagged { + case number(value: Int) + case text(value: String) +} + +@JS final class GenericImportBox { + @JS var value: Int + @JS init(value: Int) { + self.value = value + } + @JS func get() -> Int { + value + } +} + +@JSFunction func genericRoundTrip(_ value: T) throws(JSException) -> T + +@JSFunction func genericParse(_ json: String) throws(JSException) -> T + +@JSFunction func importGenericCombine( + _ a: T, + _ b: U +) throws(JSException) -> U + +@JSFunction func importGenericCaseDistinct( + _ a: T, + _ b: t +) throws(JSException) -> T + +@JSFunction func importGenericArray(_ values: [T]) throws(JSException) -> [T] + +@JSFunction func importGenericOptional(_ value: T?) throws(JSException) -> T? + +@JSFunction func importGenericDictionary( + _ values: [String: T] +) throws(JSException) -> [String: T] + +// A generic parameter alongside another parameter that pushes onto the shared +// stacks: both are lowered in reverse declaration order. +@JSFunction func importGenericAfterOptionalArray( + _ values: [Int]?, + _ value: T +) throws(JSException) -> T + +@JSClass struct GenericPairFactory { + @JSFunction init( + _ tag: String, + _ first: T, + _ second: U + ) throws(JSException) +} + +@JSClass struct GenericConsumer { + @JSFunction init(_ value: T) throws(JSException) + @JSFunction func accept(_ value: T) throws(JSException) + @JSFunction func identity(_ value: T) throws(JSException) -> T + @JSFunction static func box(_ value: T) throws(JSException) -> T +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/JSNameOverride.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/JSNameOverride.swift new file mode 100644 index 000000000..fc5777a15 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/JSNameOverride.swift @@ -0,0 +1,40 @@ +@JS("makeGreeting") func renderGreeting(name: String) -> String + +@JS("greetName") func greet(_ name: String) -> String + +@JS("greetCount") func greet(_ count: Int) -> String + +@JS("namespacedRenamed", namespace: "Utils.Text") func namespacedFunction() -> Int + +@JS class RenamedMembers { + @JS("label") var title: String + @JS("total") let count: Int + @JS("sharedTotal") nonisolated(unsafe) static var sharedCount: Int = 0 + @JS("readOnlyLimit") static let limit: Int = 10 + + @JS init(title: String, count: Int) + @JS("makeGreeting") func greet() -> String + @JS("makeDefault") static func createDefault() -> RenamedMembers +} + +@JS struct RenamedVector { + var dx: Double + var dy: Double + + @JS("originVector") static let origin: RenamedVector = RenamedVector(dx: 0, dy: 0) + @JS("magnitude") func length() -> Double + @JS("fromPolar") static func polar(radius: Double, angle: Double) -> RenamedVector +} + +@JS enum RenamedEnumMembers { + case active + case inactive + + @JS("describeCase") static func describe() -> String + @JS("currentDefault") nonisolated(unsafe) static var defaultValue: String = "active" +} + +@JS enum RenamedNamespaceMembers { + @JS("plus") static func add(_ a: Int, _ b: Int) -> Int + @JS("theAnswer") nonisolated(unsafe) static var answer: Int = 42 +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/Multifile/CrossFileExtensionOrderMember.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/Multifile/CrossFileExtensionOrderMember.swift new file mode 100644 index 000000000..277e9d40f --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/Multifile/CrossFileExtensionOrderMember.swift @@ -0,0 +1,5 @@ +extension Archive.Record { + @JS func describeRecord() -> String { + "Record: " + label + } +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/Multifile/CrossFileExtensionOrderType.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/Multifile/CrossFileExtensionOrderType.swift new file mode 100644 index 000000000..641e25559 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/Multifile/CrossFileExtensionOrderType.swift @@ -0,0 +1,13 @@ +@JS class Archive { + @JS init() {} +} + +extension Archive { + @JS struct Record { + var label: String + + @JS init(label: String) { + self.label = label + } + } +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/Multifile/CrossFileNestedTypeClass.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/Multifile/CrossFileNestedTypeClass.swift new file mode 100644 index 000000000..7fa16b59f --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/Multifile/CrossFileNestedTypeClass.swift @@ -0,0 +1,11 @@ +@JS class Workspace { + let name: String + + @JS init(name: String) { + self.name = name + } + + @JS func describe() -> String { + name + } +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/Multifile/CrossFileNestedTypeExtension.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/Multifile/CrossFileNestedTypeExtension.swift new file mode 100644 index 000000000..1e99eae1e --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/Multifile/CrossFileNestedTypeExtension.swift @@ -0,0 +1,6 @@ +extension Workspace { + @JS enum Kind: String { + case personal + case shared + } +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/NamespacedClassSignature.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/NamespacedClassSignature.swift new file mode 100644 index 000000000..67841f250 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/NamespacedClassSignature.swift @@ -0,0 +1,13 @@ +@JS enum Workshop { + @JS class Bench { + @JS init() {} + } +} + +@JS func makeBench() -> Workshop.Bench { + Workshop.Bench() +} + +@JS func refitBench(_ bench: Workshop.Bench, _ transform: (Workshop.Bench) -> Workshop.Bench) -> Workshop.Bench { + transform(bench) +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/NestedTypeNameCollision.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/NestedTypeNameCollision.swift new file mode 100644 index 000000000..231e8d7b6 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/NestedTypeNameCollision.swift @@ -0,0 +1,25 @@ +@JS enum Catalog { + @JS struct Entry { + var title: String + + @JS init(title: String) { + self.title = title + } + } +} + +@JS struct Entry { + var identifier: Int + + @JS init(identifier: Int) { + self.identifier = identifier + } +} + +@JS func takeEntry(_ entry: Entry) -> Entry { + entry +} + +@JS func takeCatalogEntry(_ entry: Catalog.Entry) -> Catalog.Entry { + entry +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/RelativeQualifiedTypes.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/RelativeQualifiedTypes.swift new file mode 100644 index 000000000..b1eae64dd --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/RelativeQualifiedTypes.swift @@ -0,0 +1,37 @@ +@JS class Library { + @JS struct Shelf { + @JS struct Divider { + var slot: Int + + @JS init(slot: Int) { + self.slot = slot + } + } + } + + @JS init() {} +} + +extension Library { + @JS func divider(_ value: Shelf.Divider) -> Shelf.Divider { + value + } +} + +@JS class Outer { + @JS struct Inner { + @JS struct Outer { + @JS struct Inner { + @JS init() {} + } + } + + @JS init() {} + } + + @JS init() {} +} + +extension Outer.Inner { + @JS func marker() -> Int { 1 } +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Alias.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Alias.json index bcdc43375..b47afb905 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Alias.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Alias.json @@ -79,6 +79,7 @@ } ] }, + "isFinal" : true, "methods" : [ { "abiName" : "bjs_PolygonReference_snapshot", @@ -196,6 +197,7 @@ } ] }, + "isFinal" : true, "methods" : [ ], diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Alias.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Alias.swift index a9252e57f..4483de428 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Alias.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Alias.swift @@ -257,6 +257,18 @@ fileprivate func _bjs_TagReference_wrap_extern(_ pointer: UnsafeMutableRawPointe return _bjs_TagReference_wrap_extern(pointer) } +extension PolygonReference: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PolygonReference.bridgeJSMakeTypeHandle() +} + +extension TagReference: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TagReference.bridgeJSMakeTypeHandle() +} + +extension InnerTag: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = InnerTag.bridgeJSMakeTypeHandle() +} + extension Polygon: _BridgedSwiftAlias, _BridgedSwiftStackType {} extension Tag: _BridgedSwiftAlias, _BridgedSwiftStackType {} @@ -394,4 +406,21 @@ func _$Surface_label_get(_ self: JSObject) throws(JSException) -> String { throw error } return String.bridgeJSLiftReturn(ret) -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + PolygonReference.bridgeJSTypeID, + TagReference.bridgeJSTypeID, + InnerTag.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AliasInClosure.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AliasInClosure.json index d76761e0b..c9107133d 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AliasInClosure.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AliasInClosure.json @@ -34,6 +34,7 @@ } ] }, + "isFinal" : true, "methods" : [ ], diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AliasInClosure.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AliasInClosure.swift index 3c87bcdcc..0a208bf70 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AliasInClosure.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AliasInClosure.swift @@ -187,4 +187,23 @@ fileprivate func _bjs_PolygonReference_wrap_extern(_ pointer: UnsafeMutableRawPo return _bjs_PolygonReference_wrap_extern(pointer) } -extension Polygon: _BridgedSwiftAlias, _BridgedSwiftStackType {} \ No newline at end of file +extension PolygonReference: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PolygonReference.bridgeJSMakeTypeHandle() +} + +extension Polygon: _BridgedSwiftAlias, _BridgedSwiftStackType {} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + PolygonReference.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ArrayTypes.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ArrayTypes.swift index 51c6911bd..94b8eb208 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ArrayTypes.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ArrayTypes.swift @@ -501,6 +501,18 @@ fileprivate func _bjs_MultiArrayContainer_wrap_extern(_ pointer: UnsafeMutableRa return _bjs_MultiArrayContainer_wrap_extern(pointer) } +extension Point: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Point.bridgeJSMakeTypeHandle() +} + +extension Direction: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Direction.bridgeJSMakeTypeHandle() +} + +extension Status: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Status.bridgeJSMakeTypeHandle() +} + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_checkArray") fileprivate func bjs_checkArray_extern(_ a: Int32) -> Void @@ -643,4 +655,21 @@ func _$importProcessBooleans(_ values: [Bool]) throws(JSException) -> [Bool] { throw error } return [Bool].bridgeJSLiftReturn() -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Point.bridgeJSTypeID, + Direction.bridgeJSTypeID, + Status.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Async.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Async.swift index f2223ee7c..35618554c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Async.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Async.swift @@ -335,6 +335,18 @@ public func _bjs_asyncRoundTripEnumDictionary() -> Int32 { #endif } +extension AsyncPoint: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = AsyncPoint.bridgeJSMakeTypeHandle() +} + +extension AsyncDirection: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = AsyncDirection.bridgeJSMakeTypeHandle() +} + +extension AsyncTheme: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = AsyncTheme.bridgeJSMakeTypeHandle() +} + @JSFunction func Promise_reject(_ promise: JSObject, _ value: JSValue) throws(JSException) #if arch(wasm32) @@ -614,20 +626,20 @@ func _$Promise_resolve_Sq10AsyncThemeO(_ promise: JSObject, _ value: Optional Void +fileprivate func promise_resolve_TestModule_Sq10AsyncPointV_extern(_ promise: Int32) -> Void #else -fileprivate func promise_resolve_TestModule_Sq10AsyncPointV_extern(_ promise: Int32, _ value: Int32) -> Void { +fileprivate func promise_resolve_TestModule_Sq10AsyncPointV_extern(_ promise: Int32) -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func promise_resolve_TestModule_Sq10AsyncPointV(_ promise: Int32, _ value: Int32) -> Void { - return promise_resolve_TestModule_Sq10AsyncPointV_extern(promise, value) +@inline(never) fileprivate func promise_resolve_TestModule_Sq10AsyncPointV(_ promise: Int32) -> Void { + return promise_resolve_TestModule_Sq10AsyncPointV_extern(promise) } func _$Promise_resolve_Sq10AsyncPointV(_ promise: JSObject, _ value: Optional) throws(JSException) -> Void { - let valueIsSome = value.bridgeJSLowerParameter() + let _ = value.bridgeJSLowerParameter() let promiseValue = promise.bridgeJSLowerParameter() - promise_resolve_TestModule_Sq10AsyncPointV(promiseValue, valueIsSome) + promise_resolve_TestModule_Sq10AsyncPointV(promiseValue) if let error = _swift_js_take_exception() { throw error } } @@ -713,4 +725,21 @@ func _$Promise_resolve_SD14AsyncDirectionO(_ promise: JSObject, _ value: [String let promiseValue = promise.bridgeJSLowerParameter() promise_resolve_TestModule_SD14AsyncDirectionO(promiseValue) if let error = _swift_js_take_exception() { throw error } -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + AsyncPoint.bridgeJSTypeID, + AsyncDirection.bridgeJSTypeID, + AsyncTheme.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AsyncAssociatedValueEnum.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AsyncAssociatedValueEnum.swift index 3208eda33..6776998bc 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AsyncAssociatedValueEnum.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AsyncAssociatedValueEnum.swift @@ -52,6 +52,10 @@ public func _bjs_asyncRoundTripOptionalAssociatedValueEnum(_ valueIsSome: Int32, #endif } +extension AsyncPayloadResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = AsyncPayloadResult.bridgeJSMakeTypeHandle() +} + @JSFunction func Promise_reject(_ promise: JSObject, _ value: JSValue) throws(JSException) #if arch(wasm32) @@ -113,4 +117,19 @@ func _$Promise_resolve_Sq18AsyncPayloadResultO(_ promise: JSObject, _ value: Opt let promiseValue = promise.bridgeJSLowerParameter() promise_resolve_TestModule_Sq18AsyncPayloadResultO(promiseValue, valueIsSome, valueCaseId) if let error = _swift_js_take_exception() { throw error } -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + AsyncPayloadResult.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ClassWithNestedTypes.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ClassWithNestedTypes.swift index 52c633045..c9c291317 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ClassWithNestedTypes.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ClassWithNestedTypes.swift @@ -174,4 +174,28 @@ fileprivate func _bjs_Account_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> #endif @inline(never) fileprivate func _bjs_Account_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_Account_wrap_extern(pointer) -} \ No newline at end of file +} + +extension Account.Credentials: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Account.Credentials.bridgeJSMakeTypeHandle() +} + +extension Account.Role: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Account.Role.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Account.Credentials.bridgeJSTypeID, + Account.Role.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/CrossFileExtensionOrderIndependence.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/CrossFileExtensionOrderIndependence.json new file mode 100644 index 000000000..ef20e9a28 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/CrossFileExtensionOrderIndependence.json @@ -0,0 +1,106 @@ +{ + "exported" : { + "aliases" : [ + + ], + "classes" : [ + { + "constructor" : { + "abiName" : "bjs_Archive_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + + ], + "name" : "Archive", + "properties" : [ + + ], + "swiftCallName" : "Archive" + } + ], + "enums" : [ + + ], + "exposeToGlobal" : false, + "functions" : [ + + ], + "protocols" : [ + + ], + "structs" : [ + { + "constructor" : { + "abiName" : "bjs_Archive_Record_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "label", + "name" : "label", + "type" : { + "string" : { + + } + } + } + ] + }, + "methods" : [ + { + "abiName" : "bjs_Archive_Record_describeRecord", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "describeRecord", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + } + ], + "name" : "Record", + "namespace" : [ + "Archive" + ], + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "label", + "namespace" : [ + "Archive" + ], + "type" : { + "string" : { + + } + } + } + ], + "swiftCallName" : "Archive.Record" + } + ] + }, + "moduleName" : "TestModule", + "usedExternalModules" : [ + + ] +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/CrossFileExtensionOrderIndependence.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/CrossFileExtensionOrderIndependence.swift new file mode 100644 index 000000000..c8df6b29e --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/CrossFileExtensionOrderIndependence.swift @@ -0,0 +1,128 @@ +extension Archive.Record: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> Archive.Record { + let label = String.bridgeJSStackPop() + return Archive.Record(label: label) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + self.label.bridgeJSStackPush() + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_Archive_Record(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_Archive_Record())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_Archive_Record") +fileprivate func _bjs_struct_lower_Archive_Record_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_Archive_Record_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_Archive_Record(_ objectId: Int32) -> Void { + return _bjs_struct_lower_Archive_Record_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_Archive_Record") +fileprivate func _bjs_struct_lift_Archive_Record_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_Archive_Record_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_Archive_Record() -> Int32 { + return _bjs_struct_lift_Archive_Record_extern() +} + +@_expose(wasm, "bjs_Archive_Record_init") +@_cdecl("bjs_Archive_Record_init") +public func _bjs_Archive_Record_init(_ labelBytes: Int32, _ labelLength: Int32) -> Void { + #if arch(wasm32) + let ret = Archive.Record(label: String.bridgeJSLiftParameter(labelBytes, labelLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Archive_Record_describeRecord") +@_cdecl("bjs_Archive_Record_describeRecord") +public func _bjs_Archive_Record_describeRecord() -> Void { + #if arch(wasm32) + let ret = Archive.Record.bridgeJSLiftParameter().describeRecord() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Archive_init") +@_cdecl("bjs_Archive_init") +public func _bjs_Archive_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = Archive() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Archive_deinit") +@_cdecl("bjs_Archive_deinit") +public func _bjs_Archive_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension Archive: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_Archive_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_Archive_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_Archive_wrap") +fileprivate func _bjs_Archive_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_Archive_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_Archive_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_Archive_wrap_extern(pointer) +} + +extension Archive.Record: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Archive.Record.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Archive.Record.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/CrossFileNestedTypeExtension.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/CrossFileNestedTypeExtension.json new file mode 100644 index 000000000..ad8a71bb7 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/CrossFileNestedTypeExtension.json @@ -0,0 +1,100 @@ +{ + "exported" : { + "aliases" : [ + + ], + "classes" : [ + { + "constructor" : { + "abiName" : "bjs_Workspace_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "name", + "name" : "name", + "type" : { + "string" : { + + } + } + } + ] + }, + "methods" : [ + { + "abiName" : "bjs_Workspace_describe", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "describe", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + } + ], + "name" : "Workspace", + "properties" : [ + + ], + "swiftCallName" : "Workspace" + } + ], + "enums" : [ + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "personal" + }, + { + "associatedValues" : [ + + ], + "name" : "shared" + } + ], + "emitStyle" : "const", + "name" : "Kind", + "namespace" : [ + "Workspace" + ], + "rawType" : "String", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Workspace.Kind", + "tsFullPath" : "Workspace.Kind" + } + ], + "exposeToGlobal" : false, + "functions" : [ + + ], + "protocols" : [ + + ], + "structs" : [ + + ] + }, + "moduleName" : "TestModule", + "usedExternalModules" : [ + + ] +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/CrossFileNestedTypeExtension.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/CrossFileNestedTypeExtension.swift new file mode 100644 index 000000000..7601f0f72 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/CrossFileNestedTypeExtension.swift @@ -0,0 +1,74 @@ +extension Workspace.Kind: _BridgedSwiftEnumNoPayload, _BridgedSwiftRawValueEnum { +} + +@_expose(wasm, "bjs_Workspace_init") +@_cdecl("bjs_Workspace_init") +public func _bjs_Workspace_init(_ nameBytes: Int32, _ nameLength: Int32) -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = Workspace(name: String.bridgeJSLiftParameter(nameBytes, nameLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Workspace_describe") +@_cdecl("bjs_Workspace_describe") +public func _bjs_Workspace_describe(_ _self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = Workspace.bridgeJSLiftParameter(_self).describe() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Workspace_deinit") +@_cdecl("bjs_Workspace_deinit") +public func _bjs_Workspace_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension Workspace: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_Workspace_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_Workspace_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_Workspace_wrap") +fileprivate func _bjs_Workspace_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_Workspace_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_Workspace_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_Workspace_wrap_extern(pointer) +} + +extension Workspace.Kind: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Workspace.Kind.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Workspace.Kind.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DefaultParameters.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DefaultParameters.swift index 507827646..e2e74e532 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DefaultParameters.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DefaultParameters.swift @@ -636,4 +636,33 @@ fileprivate func _bjs_ConstructorDefaults_wrap_extern(_ pointer: UnsafeMutableRa #endif @inline(never) fileprivate func _bjs_ConstructorDefaults_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_ConstructorDefaults_wrap_extern(pointer) -} \ No newline at end of file +} + +extension Config: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Config.bridgeJSMakeTypeHandle() +} + +extension MathOperations: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = MathOperations.bridgeJSMakeTypeHandle() +} + +extension Status: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Status.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Config.bridgeJSTypeID, + MathOperations.bridgeJSTypeID, + Status.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DictionaryTypes.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DictionaryTypes.swift index 26a4c087e..2990eeabe 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DictionaryTypes.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DictionaryTypes.swift @@ -149,6 +149,10 @@ fileprivate func _bjs_Box_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int return _bjs_Box_wrap_extern(pointer) } +extension Counters: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Counters.bridgeJSMakeTypeHandle() +} + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_importMirrorDictionary") fileprivate func bjs_importMirrorDictionary_extern() -> Void @@ -168,4 +172,19 @@ func _$importMirrorDictionary(_ values: [String: Double]) throws(JSException) -> throw error } return [String: Double].bridgeJSLiftReturn() -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Counters.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DocComments.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DocComments.swift index f91df6c26..fab694b18 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DocComments.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DocComments.swift @@ -314,4 +314,28 @@ fileprivate func _bjs_Greeter_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> #endif @inline(never) fileprivate func _bjs_Greeter_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_Greeter_wrap_extern(pointer) -} \ No newline at end of file +} + +extension Point: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Point.bridgeJSMakeTypeHandle() +} + +extension Color: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Color.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Point.bridgeJSTypeID, + Color.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAlias.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAlias.json index 0d63db899..c876db410 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAlias.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAlias.json @@ -31,6 +31,7 @@ } ] }, + "isFinal" : true, "methods" : [ ], diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAlias.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAlias.swift index 1e74a127b..5689b143f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAlias.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAlias.swift @@ -51,4 +51,23 @@ fileprivate func _bjs_ColorBox_wrap_extern(_ pointer: UnsafeMutableRawPointer) - return _bjs_ColorBox_wrap_extern(pointer) } -extension Color: _BridgedSwiftAlias, _BridgedSwiftStackType {} \ No newline at end of file +extension ColorBox: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ColorBox.bridgeJSMakeTypeHandle() +} + +extension Color: _BridgedSwiftAlias, _BridgedSwiftStackType {} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + ColorBox.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValue.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValue.swift index 6d5549699..4ca3236f8 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValue.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValue.swift @@ -631,4 +631,73 @@ fileprivate func _bjs_User_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> In #endif @inline(never) fileprivate func _bjs_User_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_User_wrap_extern(pointer) -} \ No newline at end of file +} + +extension Point: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Point.bridgeJSMakeTypeHandle() +} + +extension APIResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = APIResult.bridgeJSMakeTypeHandle() +} + +extension ComplexResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ComplexResult.bridgeJSMakeTypeHandle() +} + +extension Utilities.Result: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Utilities.Result.bridgeJSMakeTypeHandle() +} + +extension NetworkingResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = NetworkingResult.bridgeJSMakeTypeHandle() +} + +extension APIOptionalResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = APIOptionalResult.bridgeJSMakeTypeHandle() +} + +extension Precision: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Precision.bridgeJSMakeTypeHandle() +} + +extension CardinalDirection: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = CardinalDirection.bridgeJSMakeTypeHandle() +} + +extension TypedPayloadResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TypedPayloadResult.bridgeJSMakeTypeHandle() +} + +extension AllTypesResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = AllTypesResult.bridgeJSMakeTypeHandle() +} + +extension OptionalAllTypesResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = OptionalAllTypesResult.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Point.bridgeJSTypeID, + APIResult.bridgeJSTypeID, + ComplexResult.bridgeJSTypeID, + Utilities.Result.bridgeJSTypeID, + NetworkingResult.bridgeJSTypeID, + APIOptionalResult.bridgeJSTypeID, + Precision.bridgeJSTypeID, + CardinalDirection.bridgeJSTypeID, + TypedPayloadResult.bridgeJSTypeID, + AllTypesResult.bridgeJSTypeID, + OptionalAllTypesResult.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValueImport.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValueImport.swift index 55d1992a3..2c275a7a3 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValueImport.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValueImport.swift @@ -26,6 +26,10 @@ extension PayloadSignal: _BridgedSwiftAssociatedValueEnum { } } +extension PayloadSignal: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PayloadSignal.bridgeJSMakeTypeHandle() +} + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_PayloadSignalControls_roundTrip_static") fileprivate func bjs_PayloadSignalControls_roundTrip_static_extern(_ signal: Int32) -> Int32 @@ -109,4 +113,19 @@ func _$PayloadSignalControls_roundTripOptional(_ self: JSObject, _ signal: Optio throw error } return Optional.bridgeJSLiftReturn(ret) -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + PayloadSignal.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumCase.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumCase.swift index 66692ee14..dab981312 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumCase.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumCase.swift @@ -227,4 +227,38 @@ public func _bjs_roundTripOptionalTSDirection(_ inputIsSome: Int32, _ inputValue #else fatalError("Only available on WebAssembly") #endif -} \ No newline at end of file +} + +extension Direction: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Direction.bridgeJSMakeTypeHandle() +} + +extension Status: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Status.bridgeJSMakeTypeHandle() +} + +extension TSDirection: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TSDirection.bridgeJSMakeTypeHandle() +} + +extension PublicStatus: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PublicStatus.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Direction.bridgeJSTypeID, + Status.bridgeJSTypeID, + TSDirection.bridgeJSTypeID, + PublicStatus.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumCaseImport.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumCaseImport.swift index f297e1620..6ed293525 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumCaseImport.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumCaseImport.swift @@ -33,6 +33,10 @@ extension Signal: _BridgedSwiftCaseEnum { } } +extension Signal: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Signal.bridgeJSMakeTypeHandle() +} + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_SignalControls_roundTrip_static") fileprivate func bjs_SignalControls_roundTrip_static_extern(_ signal: Int32) -> Int32 @@ -94,4 +98,19 @@ func _$SignalControls_current(_ self: JSObject) throws(JSException) -> Signal { throw error } return Signal.bridgeJSLiftReturn(ret) -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Signal.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumNamespace.Global.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumNamespace.Global.swift index 4f588f6c7..9d6908bcc 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumNamespace.Global.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumNamespace.Global.swift @@ -358,4 +358,38 @@ fileprivate func _bjs_Formatting_Converter_wrap_extern(_ pointer: UnsafeMutableR #endif @inline(never) fileprivate func _bjs_Formatting_Converter_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_Formatting_Converter_wrap_extern(pointer) -} \ No newline at end of file +} + +extension Networking.API.Method: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Networking.API.Method.bridgeJSMakeTypeHandle() +} + +extension Configuration.LogLevel: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Configuration.LogLevel.bridgeJSMakeTypeHandle() +} + +extension Configuration.Port: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Configuration.Port.bridgeJSMakeTypeHandle() +} + +extension Internal.SupportedMethod: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Internal.SupportedMethod.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Networking.API.Method.bridgeJSTypeID, + Configuration.LogLevel.bridgeJSTypeID, + Configuration.Port.bridgeJSTypeID, + Internal.SupportedMethod.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumNamespace.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumNamespace.swift index 4f588f6c7..9d6908bcc 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumNamespace.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumNamespace.swift @@ -358,4 +358,38 @@ fileprivate func _bjs_Formatting_Converter_wrap_extern(_ pointer: UnsafeMutableR #endif @inline(never) fileprivate func _bjs_Formatting_Converter_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_Formatting_Converter_wrap_extern(pointer) -} \ No newline at end of file +} + +extension Networking.API.Method: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Networking.API.Method.bridgeJSMakeTypeHandle() +} + +extension Configuration.LogLevel: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Configuration.LogLevel.bridgeJSMakeTypeHandle() +} + +extension Configuration.Port: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Configuration.Port.bridgeJSMakeTypeHandle() +} + +extension Internal.SupportedMethod: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Internal.SupportedMethod.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Networking.API.Method.bridgeJSTypeID, + Configuration.LogLevel.bridgeJSTypeID, + Configuration.Port.bridgeJSTypeID, + Internal.SupportedMethod.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumRawType.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumRawType.swift index e70a6b0aa..2dbb21422 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumRawType.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumRawType.swift @@ -451,6 +451,54 @@ public func _bjs_validateSession(_ session: Int64) -> Void { #endif } +extension Theme: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Theme.bridgeJSMakeTypeHandle() +} + +extension TSTheme: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TSTheme.bridgeJSMakeTypeHandle() +} + +extension FeatureFlag: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = FeatureFlag.bridgeJSMakeTypeHandle() +} + +extension HttpStatus: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = HttpStatus.bridgeJSMakeTypeHandle() +} + +extension TSHttpStatus: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TSHttpStatus.bridgeJSMakeTypeHandle() +} + +extension Priority: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Priority.bridgeJSMakeTypeHandle() +} + +extension FileSize: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = FileSize.bridgeJSMakeTypeHandle() +} + +extension UserId: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = UserId.bridgeJSMakeTypeHandle() +} + +extension TokenId: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TokenId.bridgeJSMakeTypeHandle() +} + +extension SessionId: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = SessionId.bridgeJSMakeTypeHandle() +} + +extension Precision: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Precision.bridgeJSMakeTypeHandle() +} + +extension Ratio: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Ratio.bridgeJSMakeTypeHandle() +} + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_takesFeatureFlag") fileprivate func bjs_takesFeatureFlag_extern(_ flagBytes: Int32, _ flagLength: Int32) -> Void @@ -490,4 +538,30 @@ func _$returnsFeatureFlag() throws(JSException) -> FeatureFlag { throw error } return FeatureFlag.bridgeJSLiftReturn(ret) -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Theme.bridgeJSTypeID, + TSTheme.bridgeJSTypeID, + FeatureFlag.bridgeJSTypeID, + HttpStatus.bridgeJSTypeID, + TSHttpStatus.bridgeJSTypeID, + Priority.bridgeJSTypeID, + FileSize.bridgeJSTypeID, + UserId.bridgeJSTypeID, + TokenId.bridgeJSTypeID, + SessionId.bridgeJSTypeID, + Precision.bridgeJSTypeID, + Ratio.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ExtensionNestedTypes.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ExtensionNestedTypes.json new file mode 100644 index 000000000..e6cf2b271 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ExtensionNestedTypes.json @@ -0,0 +1,370 @@ +{ + "exported" : { + "aliases" : [ + + ], + "classes" : [ + { + "constructor" : { + "abiName" : "bjs_Library_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "name", + "name" : "name", + "type" : { + "string" : { + + } + } + } + ] + }, + "methods" : [ + { + "abiName" : "bjs_Library_describe", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "describe", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_Library_rename", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "rename", + "parameters" : [ + { + "label" : "_", + "name" : "title", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_Library_shelf", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "shelf", + "parameters" : [ + { + "label" : "label", + "name" : "label", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "swiftStruct" : { + "_0" : "Library.Shelf" + } + } + } + ], + "name" : "Library", + "properties" : [ + { + "isReadonly" : false, + "isStatic" : false, + "name" : "name", + "type" : { + "string" : { + + } + } + } + ], + "swiftCallName" : "Library" + } + ], + "enums" : [ + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "caseEnum" : { + "_0" : "Message.Update" + } + } + } + ], + "name" : "update" + }, + { + "associatedValues" : [ + + ], + "name" : "delete" + } + ], + "emitStyle" : "const", + "name" : "Message", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Message", + "tsFullPath" : "Message" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "fiction" + }, + { + "associatedValues" : [ + + ], + "name" : "reference" + } + ], + "emitStyle" : "const", + "name" : "Genre", + "namespace" : [ + "Library" + ], + "rawType" : "String", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Library.Genre", + "tsFullPath" : "Library.Genre" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "flip" + }, + { + "associatedValues" : [ + + ], + "name" : "rotate" + } + ], + "emitStyle" : "const", + "name" : "Update", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Message.Update", + "tsFullPath" : "Update" + } + ], + "exposeToGlobal" : false, + "functions" : [ + { + "abiName" : "bjs_roundTripMessage", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "roundTripMessage", + "parameters" : [ + { + "label" : "_", + "name" : "message", + "type" : { + "associatedValueEnum" : { + "_0" : "Message" + } + } + } + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "Message" + } + } + } + ], + "protocols" : [ + + ], + "structs" : [ + { + "constructor" : { + "abiName" : "bjs_Library_Shelf_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "label", + "name" : "label", + "type" : { + "string" : { + + } + } + } + ] + }, + "methods" : [ + { + "abiName" : "bjs_Library_Shelf_describeShelf", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "describeShelf", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + } + ], + "name" : "Shelf", + "namespace" : [ + "Library" + ], + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "label", + "namespace" : [ + "Library" + ], + "type" : { + "string" : { + + } + } + }, + { + "isReadonly" : true, + "isStatic" : true, + "name" : "capacity", + "staticContext" : { + "structName" : { + "_0" : "Library_Shelf" + } + }, + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "Library.Shelf" + }, + { + "constructor" : { + "abiName" : "bjs_Library_Shelf_Divider_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "slot", + "name" : "slot", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ] + }, + "methods" : [ + + ], + "name" : "Divider", + "namespace" : [ + "Library", + "Shelf" + ], + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "slot", + "namespace" : [ + "Library", + "Shelf" + ], + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "Library.Shelf.Divider" + } + ] + }, + "moduleName" : "TestModule", + "usedExternalModules" : [ + + ] +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ExtensionNestedTypes.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ExtensionNestedTypes.swift new file mode 100644 index 000000000..d7efa630c --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ExtensionNestedTypes.swift @@ -0,0 +1,342 @@ +extension Message: _BridgedSwiftAssociatedValueEnum { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPopPayload(_ caseId: Int32) -> Message { + switch caseId { + case 0: + return .update(Message.Update.bridgeJSStackPop()) + case 1: + return .delete + default: + fatalError("Unknown Message case ID: \(caseId)") + } + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPushPayload() -> Int32 { + switch self { + case .update(let param0): + param0.bridgeJSStackPush() + return Int32(0) + case .delete: + return Int32(1) + } + } +} + +extension Library.Genre: _BridgedSwiftEnumNoPayload, _BridgedSwiftRawValueEnum { +} + +extension Message.Update: _BridgedSwiftCaseEnum { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> Message.Update { + return bridgeJSLiftParameter(value) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> Message.Update { + return Message.Update(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSLowerParameter() + } + + @_spi(BridgeJS) @usableFromInline init?(bridgeJSRawValue: Int32) { + switch bridgeJSRawValue { + case 0: + self = .flip + case 1: + self = .rotate + default: + return nil + } + } + + @_spi(BridgeJS) @usableFromInline var bridgeJSRawValue: Int32 { + switch self { + case .flip: + return 0 + case .rotate: + return 1 + } + } +} + +extension Library.Shelf: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> Library.Shelf { + let label = String.bridgeJSStackPop() + return Library.Shelf(label: label) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + self.label.bridgeJSStackPush() + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_Library_Shelf(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_Library_Shelf())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_Library_Shelf") +fileprivate func _bjs_struct_lower_Library_Shelf_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_Library_Shelf_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_Library_Shelf(_ objectId: Int32) -> Void { + return _bjs_struct_lower_Library_Shelf_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_Library_Shelf") +fileprivate func _bjs_struct_lift_Library_Shelf_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_Library_Shelf_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_Library_Shelf() -> Int32 { + return _bjs_struct_lift_Library_Shelf_extern() +} + +@_expose(wasm, "bjs_Library_Shelf_init") +@_cdecl("bjs_Library_Shelf_init") +public func _bjs_Library_Shelf_init(_ labelBytes: Int32, _ labelLength: Int32) -> Void { + #if arch(wasm32) + let ret = Library.Shelf(label: String.bridgeJSLiftParameter(labelBytes, labelLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_Shelf_static_capacity_get") +@_cdecl("bjs_Library_Shelf_static_capacity_get") +public func _bjs_Library_Shelf_static_capacity_get() -> Int32 { + #if arch(wasm32) + let ret = Library.Shelf.capacity + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_Shelf_describeShelf") +@_cdecl("bjs_Library_Shelf_describeShelf") +public func _bjs_Library_Shelf_describeShelf() -> Void { + #if arch(wasm32) + let ret = Library.Shelf.bridgeJSLiftParameter().describeShelf() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension Library.Shelf.Divider: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> Library.Shelf.Divider { + let slot = Int.bridgeJSStackPop() + return Library.Shelf.Divider(slot: slot) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + self.slot.bridgeJSStackPush() + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_Library_Shelf_Divider(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_Library_Shelf_Divider())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_Library_Shelf_Divider") +fileprivate func _bjs_struct_lower_Library_Shelf_Divider_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_Library_Shelf_Divider_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_Library_Shelf_Divider(_ objectId: Int32) -> Void { + return _bjs_struct_lower_Library_Shelf_Divider_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_Library_Shelf_Divider") +fileprivate func _bjs_struct_lift_Library_Shelf_Divider_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_Library_Shelf_Divider_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_Library_Shelf_Divider() -> Int32 { + return _bjs_struct_lift_Library_Shelf_Divider_extern() +} + +@_expose(wasm, "bjs_Library_Shelf_Divider_init") +@_cdecl("bjs_Library_Shelf_Divider_init") +public func _bjs_Library_Shelf_Divider_init(_ slot: Int32) -> Void { + #if arch(wasm32) + let ret = Library.Shelf.Divider(slot: Int.bridgeJSLiftParameter(slot)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_roundTripMessage") +@_cdecl("bjs_roundTripMessage") +public func _bjs_roundTripMessage(_ message: Int32) -> Void { + #if arch(wasm32) + let ret = roundTripMessage(_: Message.bridgeJSLiftParameter(message)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_init") +@_cdecl("bjs_Library_init") +public func _bjs_Library_init(_ nameBytes: Int32, _ nameLength: Int32) -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = Library(name: String.bridgeJSLiftParameter(nameBytes, nameLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_describe") +@_cdecl("bjs_Library_describe") +public func _bjs_Library_describe(_ _self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = Library.bridgeJSLiftParameter(_self).describe() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_rename") +@_cdecl("bjs_Library_rename") +public func _bjs_Library_rename(_ _self: UnsafeMutableRawPointer, _ titleBytes: Int32, _ titleLength: Int32) -> Void { + #if arch(wasm32) + let ret = Library.bridgeJSLiftParameter(_self).rename(_: String.bridgeJSLiftParameter(titleBytes, titleLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_shelf") +@_cdecl("bjs_Library_shelf") +public func _bjs_Library_shelf(_ _self: UnsafeMutableRawPointer, _ labelBytes: Int32, _ labelLength: Int32) -> Void { + #if arch(wasm32) + let ret = Library.bridgeJSLiftParameter(_self).shelf(label: String.bridgeJSLiftParameter(labelBytes, labelLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_name_get") +@_cdecl("bjs_Library_name_get") +public func _bjs_Library_name_get(_ _self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = Library.bridgeJSLiftParameter(_self).name + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_name_set") +@_cdecl("bjs_Library_name_set") +public func _bjs_Library_name_set(_ _self: UnsafeMutableRawPointer, _ valueBytes: Int32, _ valueLength: Int32) -> Void { + #if arch(wasm32) + Library.bridgeJSLiftParameter(_self).name = String.bridgeJSLiftParameter(valueBytes, valueLength) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_deinit") +@_cdecl("bjs_Library_deinit") +public func _bjs_Library_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension Library: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_Library_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_Library_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_Library_wrap") +fileprivate func _bjs_Library_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_Library_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_Library_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_Library_wrap_extern(pointer) +} + +extension Library.Shelf: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Library.Shelf.bridgeJSMakeTypeHandle() +} + +extension Library.Shelf.Divider: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Library.Shelf.Divider.bridgeJSMakeTypeHandle() +} + +extension Message: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Message.bridgeJSMakeTypeHandle() +} + +extension Library.Genre: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Library.Genre.bridgeJSMakeTypeHandle() +} + +extension Message.Update: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Message.Update.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Library.Shelf.bridgeJSTypeID, + Library.Shelf.Divider.bridgeJSTypeID, + Message.bridgeJSTypeID, + Library.Genre.bridgeJSTypeID, + Message.Update.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ExtensionOrderIndependence.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ExtensionOrderIndependence.json new file mode 100644 index 000000000..9096006ae --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ExtensionOrderIndependence.json @@ -0,0 +1,106 @@ +{ + "exported" : { + "aliases" : [ + + ], + "classes" : [ + { + "constructor" : { + "abiName" : "bjs_Depot_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + + ], + "name" : "Depot", + "properties" : [ + + ], + "swiftCallName" : "Depot" + } + ], + "enums" : [ + + ], + "exposeToGlobal" : false, + "functions" : [ + + ], + "protocols" : [ + + ], + "structs" : [ + { + "constructor" : { + "abiName" : "bjs_Depot_Crate_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "label", + "name" : "label", + "type" : { + "string" : { + + } + } + } + ] + }, + "methods" : [ + { + "abiName" : "bjs_Depot_Crate_describeCrate", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "describeCrate", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + } + ], + "name" : "Crate", + "namespace" : [ + "Depot" + ], + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "label", + "namespace" : [ + "Depot" + ], + "type" : { + "string" : { + + } + } + } + ], + "swiftCallName" : "Depot.Crate" + } + ] + }, + "moduleName" : "TestModule", + "usedExternalModules" : [ + + ] +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ExtensionOrderIndependence.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ExtensionOrderIndependence.swift new file mode 100644 index 000000000..cc8091bbe --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ExtensionOrderIndependence.swift @@ -0,0 +1,128 @@ +extension Depot.Crate: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> Depot.Crate { + let label = String.bridgeJSStackPop() + return Depot.Crate(label: label) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + self.label.bridgeJSStackPush() + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_Depot_Crate(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_Depot_Crate())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_Depot_Crate") +fileprivate func _bjs_struct_lower_Depot_Crate_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_Depot_Crate_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_Depot_Crate(_ objectId: Int32) -> Void { + return _bjs_struct_lower_Depot_Crate_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_Depot_Crate") +fileprivate func _bjs_struct_lift_Depot_Crate_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_Depot_Crate_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_Depot_Crate() -> Int32 { + return _bjs_struct_lift_Depot_Crate_extern() +} + +@_expose(wasm, "bjs_Depot_Crate_init") +@_cdecl("bjs_Depot_Crate_init") +public func _bjs_Depot_Crate_init(_ labelBytes: Int32, _ labelLength: Int32) -> Void { + #if arch(wasm32) + let ret = Depot.Crate(label: String.bridgeJSLiftParameter(labelBytes, labelLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Depot_Crate_describeCrate") +@_cdecl("bjs_Depot_Crate_describeCrate") +public func _bjs_Depot_Crate_describeCrate() -> Void { + #if arch(wasm32) + let ret = Depot.Crate.bridgeJSLiftParameter().describeCrate() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Depot_init") +@_cdecl("bjs_Depot_init") +public func _bjs_Depot_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = Depot() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Depot_deinit") +@_cdecl("bjs_Depot_deinit") +public func _bjs_Depot_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension Depot: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_Depot_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_Depot_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_Depot_wrap") +fileprivate func _bjs_Depot_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_Depot_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_Depot_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_Depot_wrap_extern(pointer) +} + +extension Depot.Crate: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Depot.Crate.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Depot.Crate.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ExtensionScopeParity.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ExtensionScopeParity.json new file mode 100644 index 000000000..2e25e938e --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ExtensionScopeParity.json @@ -0,0 +1,151 @@ +{ + "exported" : { + "aliases" : [ + + ], + "classes" : [ + { + "constructor" : { + "abiName" : "bjs_app_Toolbox_Mallet_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + + ], + "name" : "Mallet", + "namespace" : [ + "app", + "Toolbox" + ], + "properties" : [ + + ], + "swiftCallName" : "Toolbox.Mallet" + }, + { + "constructor" : { + "abiName" : "bjs_app_Toolbox_Hammer_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + + ], + "name" : "Hammer", + "namespace" : [ + "app", + "Toolbox" + ], + "properties" : [ + + ], + "swiftCallName" : "Toolbox.Hammer" + } + ], + "enums" : [ + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "Toolbox", + "namespace" : [ + "app" + ], + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Toolbox", + "tsFullPath" : "app.Toolbox" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "ready" + } + ], + "emitStyle" : "const", + "name" : "Signal", + "rawType" : "String", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Signal", + "tsFullPath" : "Signal" + } + ], + "exposeToGlobal" : false, + "functions" : [ + + ], + "protocols" : [ + + ], + "structs" : [ + { + "constructor" : { + "abiName" : "bjs_Meta_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "note", + "name" : "note", + "type" : { + "string" : { + + } + } + } + ] + }, + "methods" : [ + + ], + "name" : "Meta", + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "note", + "type" : { + "string" : { + + } + } + } + ], + "swiftCallName" : "Signal.Meta" + } + ] + }, + "moduleName" : "TestModule", + "usedExternalModules" : [ + + ] +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ExtensionScopeParity.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ExtensionScopeParity.swift new file mode 100644 index 000000000..7fe6db4d2 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ExtensionScopeParity.swift @@ -0,0 +1,167 @@ +extension Signal: _BridgedSwiftEnumNoPayload, _BridgedSwiftRawValueEnum { +} + +extension Signal.Meta: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> Signal.Meta { + let note = String.bridgeJSStackPop() + return Signal.Meta(note: note) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + self.note.bridgeJSStackPush() + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_Meta(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_Meta())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_Meta") +fileprivate func _bjs_struct_lower_Meta_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_Meta_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_Meta(_ objectId: Int32) -> Void { + return _bjs_struct_lower_Meta_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_Meta") +fileprivate func _bjs_struct_lift_Meta_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_Meta_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_Meta() -> Int32 { + return _bjs_struct_lift_Meta_extern() +} + +@_expose(wasm, "bjs_Meta_init") +@_cdecl("bjs_Meta_init") +public func _bjs_Meta_init(_ noteBytes: Int32, _ noteLength: Int32) -> Void { + #if arch(wasm32) + let ret = Signal.Meta(note: String.bridgeJSLiftParameter(noteBytes, noteLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_app_Toolbox_Mallet_init") +@_cdecl("bjs_app_Toolbox_Mallet_init") +public func _bjs_app_Toolbox_Mallet_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = Toolbox.Mallet() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_app_Toolbox_Mallet_deinit") +@_cdecl("bjs_app_Toolbox_Mallet_deinit") +public func _bjs_app_Toolbox_Mallet_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension Toolbox.Mallet: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_app_Toolbox_Mallet_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_app_Toolbox_Mallet_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_app_Toolbox_Mallet_wrap") +fileprivate func _bjs_app_Toolbox_Mallet_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_app_Toolbox_Mallet_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_app_Toolbox_Mallet_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_app_Toolbox_Mallet_wrap_extern(pointer) +} + +@_expose(wasm, "bjs_app_Toolbox_Hammer_init") +@_cdecl("bjs_app_Toolbox_Hammer_init") +public func _bjs_app_Toolbox_Hammer_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = Toolbox.Hammer() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_app_Toolbox_Hammer_deinit") +@_cdecl("bjs_app_Toolbox_Hammer_deinit") +public func _bjs_app_Toolbox_Hammer_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension Toolbox.Hammer: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_app_Toolbox_Hammer_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_app_Toolbox_Hammer_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_app_Toolbox_Hammer_wrap") +fileprivate func _bjs_app_Toolbox_Hammer_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_app_Toolbox_Hammer_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_app_Toolbox_Hammer_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_app_Toolbox_Hammer_wrap_extern(pointer) +} + +extension Signal.Meta: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Signal.Meta.bridgeJSMakeTypeHandle() +} + +extension Signal: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Signal.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Signal.Meta.bridgeJSTypeID, + Signal.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GenericImports.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GenericImports.json new file mode 100644 index 000000000..c7f3e98ae --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GenericImports.json @@ -0,0 +1,669 @@ +{ + "exported" : { + "aliases" : [ + + ], + "classes" : [ + { + "constructor" : { + "abiName" : "bjs_GenericImportBox_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "value", + "name" : "value", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ] + }, + "isFinal" : true, + "methods" : [ + { + "abiName" : "bjs_GenericImportBox_get", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "get", + "parameters" : [ + + ], + "returnType" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "name" : "GenericImportBox", + "properties" : [ + { + "isReadonly" : false, + "isStatic" : false, + "name" : "value", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "GenericImportBox" + } + ], + "enums" : [ + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "red" + }, + { + "associatedValues" : [ + + ], + "name" : "green" + } + ], + "emitStyle" : "const", + "name" : "GenericColor", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GenericColor", + "tsFullPath" : "GenericColor" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "light" + }, + { + "associatedValues" : [ + + ], + "name" : "dark" + } + ], + "emitStyle" : "const", + "name" : "GenericMode", + "rawType" : "String", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GenericMode", + "tsFullPath" : "GenericMode" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "label" : "value", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "name" : "number" + }, + { + "associatedValues" : [ + { + "label" : "value", + "type" : { + "string" : { + + } + } + } + ], + "name" : "text" + } + ], + "emitStyle" : "const", + "name" : "GenericTagged", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GenericTagged", + "tsFullPath" : "GenericTagged" + } + ], + "exposeToGlobal" : false, + "functions" : [ + + ], + "protocols" : [ + + ], + "structs" : [ + { + "methods" : [ + + ], + "name" : "GenericPoint", + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "x", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + }, + { + "isReadonly" : true, + "isStatic" : false, + "name" : "y", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "GenericPoint" + } + ] + }, + "imported" : { + "children" : [ + { + "functions" : [ + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "genericRoundTrip", + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "genericParse", + "parameters" : [ + { + "name" : "json", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T", + "U" + ], + "name" : "importGenericCombine", + "parameters" : [ + { + "name" : "a", + "type" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "name" : "b", + "type" : { + "generic" : { + "_0" : "U" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "U" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T", + "t" + ], + "name" : "importGenericCaseDistinct", + "parameters" : [ + { + "name" : "a", + "type" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "name" : "b", + "type" : { + "generic" : { + "_0" : "t" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "importGenericArray", + "parameters" : [ + { + "name" : "values", + "type" : { + "array" : { + "_0" : { + "generic" : { + "_0" : "T" + } + } + } + } + } + ], + "returnType" : { + "array" : { + "_0" : { + "generic" : { + "_0" : "T" + } + } + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "importGenericOptional", + "parameters" : [ + { + "name" : "value", + "type" : { + "nullable" : { + "_0" : { + "generic" : { + "_0" : "T" + } + }, + "_1" : "null" + } + } + } + ], + "returnType" : { + "nullable" : { + "_0" : { + "generic" : { + "_0" : "T" + } + }, + "_1" : "null" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "importGenericDictionary", + "parameters" : [ + { + "name" : "values", + "type" : { + "dictionary" : { + "_0" : { + "generic" : { + "_0" : "T" + } + } + } + } + } + ], + "returnType" : { + "dictionary" : { + "_0" : { + "generic" : { + "_0" : "T" + } + } + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "importGenericAfterOptionalArray", + "parameters" : [ + { + "name" : "values", + "type" : { + "nullable" : { + "_0" : { + "array" : { + "_0" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + }, + "_1" : "null" + } + } + }, + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "types" : [ + { + "accessLevel" : "internal", + "constructor" : { + "accessLevel" : "internal", + "genericParameters" : [ + "T", + "U" + ], + "parameters" : [ + { + "name" : "tag", + "type" : { + "string" : { + + } + } + }, + { + "name" : "first", + "type" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "name" : "second", + "type" : { + "generic" : { + "_0" : "U" + } + } + } + ] + }, + "getters" : [ + + ], + "methods" : [ + + ], + "name" : "GenericPairFactory", + "setters" : [ + + ], + "staticMethods" : [ + + ] + }, + { + "accessLevel" : "internal", + "constructor" : { + "accessLevel" : "internal", + "genericParameters" : [ + "T" + ], + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ] + }, + "getters" : [ + + ], + "methods" : [ + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "accept", + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "returnType" : { + "void" : { + + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "identity", + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "name" : "GenericConsumer", + "setters" : [ + + ], + "staticMethods" : [ + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "box", + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + } + ] + } + ] + } + ] + }, + "moduleName" : "TestModule", + "usedExternalModules" : [ + + ] +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GenericImports.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GenericImports.swift new file mode 100644 index 000000000..01ed6196e --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GenericImports.swift @@ -0,0 +1,505 @@ +extension GenericColor: _BridgedSwiftCaseEnum { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> GenericColor { + return bridgeJSLiftParameter(value) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> GenericColor { + return GenericColor(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSLowerParameter() + } + + @_spi(BridgeJS) @usableFromInline init?(bridgeJSRawValue: Int32) { + switch bridgeJSRawValue { + case 0: + self = .red + case 1: + self = .green + default: + return nil + } + } + + @_spi(BridgeJS) @usableFromInline var bridgeJSRawValue: Int32 { + switch self { + case .red: + return 0 + case .green: + return 1 + } + } +} + +extension GenericMode: _BridgedSwiftEnumNoPayload, _BridgedSwiftRawValueEnum { +} + +extension GenericTagged: _BridgedSwiftAssociatedValueEnum { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPopPayload(_ caseId: Int32) -> GenericTagged { + switch caseId { + case 0: + return .number(value: Int.bridgeJSStackPop()) + case 1: + return .text(value: String.bridgeJSStackPop()) + default: + fatalError("Unknown GenericTagged case ID: \(caseId)") + } + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPushPayload() -> Int32 { + switch self { + case .number(let value): + value.bridgeJSStackPush() + return Int32(0) + case .text(let value): + value.bridgeJSStackPush() + return Int32(1) + } + } +} + +extension GenericPoint: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> GenericPoint { + let y = Int.bridgeJSStackPop() + let x = Int.bridgeJSStackPop() + return GenericPoint(x: x, y: y) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + self.x.bridgeJSStackPush() + self.y.bridgeJSStackPush() + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_GenericPoint(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_GenericPoint())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_GenericPoint") +fileprivate func _bjs_struct_lower_GenericPoint_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_GenericPoint_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_GenericPoint(_ objectId: Int32) -> Void { + return _bjs_struct_lower_GenericPoint_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_GenericPoint") +fileprivate func _bjs_struct_lift_GenericPoint_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_GenericPoint_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_GenericPoint() -> Int32 { + return _bjs_struct_lift_GenericPoint_extern() +} + +@_expose(wasm, "bjs_GenericImportBox_init") +@_cdecl("bjs_GenericImportBox_init") +public func _bjs_GenericImportBox_init(_ value: Int32) -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = GenericImportBox(value: Int.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_GenericImportBox_get") +@_cdecl("bjs_GenericImportBox_get") +public func _bjs_GenericImportBox_get(_ _self: UnsafeMutableRawPointer) -> Int32 { + #if arch(wasm32) + let ret = GenericImportBox.bridgeJSLiftParameter(_self).get() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_GenericImportBox_value_get") +@_cdecl("bjs_GenericImportBox_value_get") +public func _bjs_GenericImportBox_value_get(_ _self: UnsafeMutableRawPointer) -> Int32 { + #if arch(wasm32) + let ret = GenericImportBox.bridgeJSLiftParameter(_self).value + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_GenericImportBox_value_set") +@_cdecl("bjs_GenericImportBox_value_set") +public func _bjs_GenericImportBox_value_set(_ _self: UnsafeMutableRawPointer, _ value: Int32) -> Void { + #if arch(wasm32) + GenericImportBox.bridgeJSLiftParameter(_self).value = Int.bridgeJSLiftParameter(value) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_GenericImportBox_deinit") +@_cdecl("bjs_GenericImportBox_deinit") +public func _bjs_GenericImportBox_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension GenericImportBox: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_GenericImportBox_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_GenericImportBox_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_GenericImportBox_wrap") +fileprivate func _bjs_GenericImportBox_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_GenericImportBox_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_GenericImportBox_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_GenericImportBox_wrap_extern(pointer) +} + +extension GenericPoint: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericPoint.bridgeJSMakeTypeHandle() +} + +extension GenericImportBox: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericImportBox.bridgeJSMakeTypeHandle() +} + +extension GenericColor: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericColor.bridgeJSMakeTypeHandle() +} + +extension GenericMode: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericMode.bridgeJSMakeTypeHandle() +} + +extension GenericTagged: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericTagged.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_genericRoundTrip") +fileprivate func bjs_genericRoundTrip_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_genericRoundTrip_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_genericRoundTrip(_ _generic0TypeId: Int32) -> Void { + return bjs_genericRoundTrip_extern(_generic0TypeId) +} + +func _$genericRoundTrip(_ value: T) throws(JSException) -> T { + value.bridgeJSStackPush() + bjs_genericRoundTrip(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_genericParse") +fileprivate func bjs_genericParse_extern(_ jsonBytes: Int32, _ jsonLength: Int32, _ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_genericParse_extern(_ jsonBytes: Int32, _ jsonLength: Int32, _ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_genericParse(_ jsonBytes: Int32, _ jsonLength: Int32, _ _generic0TypeId: Int32) -> Void { + return bjs_genericParse_extern(jsonBytes, jsonLength, _generic0TypeId) +} + +func _$genericParse(_ json: String) throws(JSException) -> T { + json.bridgeJSWithLoweredParameter { (jsonBytes, jsonLength) in + bjs_genericParse(jsonBytes, jsonLength, T.bridgeJSTypeID) + } + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_importGenericCombine") +fileprivate func bjs_importGenericCombine_extern(_ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Void +#else +fileprivate func bjs_importGenericCombine_extern(_ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_importGenericCombine(_ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Void { + return bjs_importGenericCombine_extern(_generic0TypeId, _generic1TypeId) +} + +func _$importGenericCombine(_ a: T, _ b: U) throws(JSException) -> U { + b.bridgeJSStackPush() + a.bridgeJSStackPush() + bjs_importGenericCombine(T.bridgeJSTypeID, U.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return U.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_importGenericCaseDistinct") +fileprivate func bjs_importGenericCaseDistinct_extern(_ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Void +#else +fileprivate func bjs_importGenericCaseDistinct_extern(_ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_importGenericCaseDistinct(_ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Void { + return bjs_importGenericCaseDistinct_extern(_generic0TypeId, _generic1TypeId) +} + +func _$importGenericCaseDistinct(_ a: T, _ b: t) throws(JSException) -> T { + b.bridgeJSStackPush() + a.bridgeJSStackPush() + bjs_importGenericCaseDistinct(T.bridgeJSTypeID, t.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_importGenericArray") +fileprivate func bjs_importGenericArray_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_importGenericArray_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_importGenericArray(_ _generic0TypeId: Int32) -> Void { + return bjs_importGenericArray_extern(_generic0TypeId) +} + +func _$importGenericArray(_ values: [T]) throws(JSException) -> [T] { + let _ = values.bridgeJSLowerParameter() + bjs_importGenericArray(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return [T].bridgeJSLiftReturn() +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_importGenericOptional") +fileprivate func bjs_importGenericOptional_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_importGenericOptional_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_importGenericOptional(_ _generic0TypeId: Int32) -> Void { + return bjs_importGenericOptional_extern(_generic0TypeId) +} + +func _$importGenericOptional(_ value: Optional) throws(JSException) -> Optional { + value.bridgeJSStackPush() + bjs_importGenericOptional(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return Optional.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_importGenericDictionary") +fileprivate func bjs_importGenericDictionary_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_importGenericDictionary_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_importGenericDictionary(_ _generic0TypeId: Int32) -> Void { + return bjs_importGenericDictionary_extern(_generic0TypeId) +} + +func _$importGenericDictionary(_ values: [String: T]) throws(JSException) -> [String: T] { + let _ = values.bridgeJSLowerParameter() + bjs_importGenericDictionary(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return [String: T].bridgeJSLiftReturn() +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_importGenericAfterOptionalArray") +fileprivate func bjs_importGenericAfterOptionalArray_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_importGenericAfterOptionalArray_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_importGenericAfterOptionalArray(_ _generic0TypeId: Int32) -> Void { + return bjs_importGenericAfterOptionalArray_extern(_generic0TypeId) +} + +func _$importGenericAfterOptionalArray(_ values: Optional<[Int]>, _ value: T) throws(JSException) -> T { + value.bridgeJSStackPush() + let _ = values.bridgeJSLowerParameter() + bjs_importGenericAfterOptionalArray(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_GenericPairFactory_init") +fileprivate func bjs_GenericPairFactory_init_extern(_ tagBytes: Int32, _ tagLength: Int32, _ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Int32 +#else +fileprivate func bjs_GenericPairFactory_init_extern(_ tagBytes: Int32, _ tagLength: Int32, _ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_GenericPairFactory_init(_ tagBytes: Int32, _ tagLength: Int32, _ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Int32 { + return bjs_GenericPairFactory_init_extern(tagBytes, tagLength, _generic0TypeId, _generic1TypeId) +} + +func _$GenericPairFactory_init(_ tag: String, _ first: T, _ second: U) throws(JSException) -> JSObject { + let ret0 = tag.bridgeJSWithLoweredParameter { (tagBytes, tagLength) in + second.bridgeJSStackPush() + first.bridgeJSStackPush() + let ret = bjs_GenericPairFactory_init(tagBytes, tagLength, T.bridgeJSTypeID, U.bridgeJSTypeID) + return ret + } + let ret = ret0 + if let error = _swift_js_take_exception() { + throw error + } + return JSObject.bridgeJSLiftReturn(ret) +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_GenericConsumer_init") +fileprivate func bjs_GenericConsumer_init_extern(_ _generic0TypeId: Int32) -> Int32 +#else +fileprivate func bjs_GenericConsumer_init_extern(_ _generic0TypeId: Int32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_GenericConsumer_init(_ _generic0TypeId: Int32) -> Int32 { + return bjs_GenericConsumer_init_extern(_generic0TypeId) +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_GenericConsumer_box_static") +fileprivate func bjs_GenericConsumer_box_static_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_GenericConsumer_box_static_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_GenericConsumer_box_static(_ _generic0TypeId: Int32) -> Void { + return bjs_GenericConsumer_box_static_extern(_generic0TypeId) +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_GenericConsumer_accept") +fileprivate func bjs_GenericConsumer_accept_extern(_ self: Int32, _ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_GenericConsumer_accept_extern(_ self: Int32, _ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_GenericConsumer_accept(_ self: Int32, _ _generic0TypeId: Int32) -> Void { + return bjs_GenericConsumer_accept_extern(self, _generic0TypeId) +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_GenericConsumer_identity") +fileprivate func bjs_GenericConsumer_identity_extern(_ self: Int32, _ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_GenericConsumer_identity_extern(_ self: Int32, _ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_GenericConsumer_identity(_ self: Int32, _ _generic0TypeId: Int32) -> Void { + return bjs_GenericConsumer_identity_extern(self, _generic0TypeId) +} + +func _$GenericConsumer_init(_ value: T) throws(JSException) -> JSObject { + value.bridgeJSStackPush() + let ret = bjs_GenericConsumer_init(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return JSObject.bridgeJSLiftReturn(ret) +} + +func _$GenericConsumer_box(_ value: T) throws(JSException) -> T { + value.bridgeJSStackPush() + bjs_GenericConsumer_box_static(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +func _$GenericConsumer_accept(_ self: JSObject, _ value: T) throws(JSException) -> Void { + value.bridgeJSStackPush() + let selfValue = self.bridgeJSLowerParameter() + bjs_GenericConsumer_accept(selfValue, T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } +} + +func _$GenericConsumer_identity(_ self: JSObject, _ value: T) throws(JSException) -> T { + value.bridgeJSStackPush() + let selfValue = self.bridgeJSLowerParameter() + bjs_GenericConsumer_identity(selfValue, T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + GenericPoint.bridgeJSTypeID, + GenericImportBox.bridgeJSTypeID, + GenericColor.bridgeJSTypeID, + GenericMode.bridgeJSTypeID, + GenericTagged.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportArray.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportArray.swift index 9c4b49e3c..12abbd1e6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportArray.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportArray.swift @@ -41,20 +41,20 @@ func _$logStrings(_ items: [String]) throws(JSException) -> Void { #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_optionalArrayThenArray") -fileprivate func bjs_optionalArrayThenArray_extern(_ a: Int32) -> Int32 +fileprivate func bjs_optionalArrayThenArray_extern() -> Int32 #else -fileprivate func bjs_optionalArrayThenArray_extern(_ a: Int32) -> Int32 { +fileprivate func bjs_optionalArrayThenArray_extern() -> Int32 { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_optionalArrayThenArray(_ a: Int32) -> Int32 { - return bjs_optionalArrayThenArray_extern(a) +@inline(never) fileprivate func bjs_optionalArrayThenArray() -> Int32 { + return bjs_optionalArrayThenArray_extern() } func _$optionalArrayThenArray(_ a: Optional<[Int]>, _ b: [Int]) throws(JSException) -> Int { let _ = b.bridgeJSLowerParameter() - let aIsSome = a.bridgeJSLowerParameter() - let ret = bjs_optionalArrayThenArray(aIsSome) + let _ = a.bridgeJSLowerParameter() + let ret = bjs_optionalArrayThenArray() if let error = _swift_js_take_exception() { throw error } @@ -63,21 +63,21 @@ func _$optionalArrayThenArray(_ a: Optional<[Int]>, _ b: [Int]) throws(JSExcepti #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_borrowedStringAroundStackParams") -fileprivate func bjs_borrowedStringAroundStackParams_extern(_ sBytes: Int32, _ sLength: Int32, _ a: Int32) -> Int32 +fileprivate func bjs_borrowedStringAroundStackParams_extern(_ sBytes: Int32, _ sLength: Int32) -> Int32 #else -fileprivate func bjs_borrowedStringAroundStackParams_extern(_ sBytes: Int32, _ sLength: Int32, _ a: Int32) -> Int32 { +fileprivate func bjs_borrowedStringAroundStackParams_extern(_ sBytes: Int32, _ sLength: Int32) -> Int32 { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_borrowedStringAroundStackParams(_ sBytes: Int32, _ sLength: Int32, _ a: Int32) -> Int32 { - return bjs_borrowedStringAroundStackParams_extern(sBytes, sLength, a) +@inline(never) fileprivate func bjs_borrowedStringAroundStackParams(_ sBytes: Int32, _ sLength: Int32) -> Int32 { + return bjs_borrowedStringAroundStackParams_extern(sBytes, sLength) } func _$borrowedStringAroundStackParams(_ s: String, _ a: Optional<[Int]>, _ b: [Int]) throws(JSException) -> Int { let ret0 = s.bridgeJSWithLoweredParameter { (sBytes, sLength) in let _ = b.bridgeJSLowerParameter() - let aIsSome = a.bridgeJSLowerParameter() - let ret = bjs_borrowedStringAroundStackParams(sBytes, sLength, aIsSome) + let _ = a.bridgeJSLowerParameter() + let ret = bjs_borrowedStringAroundStackParams(sBytes, sLength) return ret } let ret = ret0 diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportedTypeInExportedInterface.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportedTypeInExportedInterface.swift index 62f9a3b68..b9fddf706 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportedTypeInExportedInterface.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportedTypeInExportedInterface.swift @@ -104,6 +104,10 @@ public func _bjs_roundtripFooContainer() -> Void { #endif } +extension FooContainer: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = FooContainer.bridgeJSMakeTypeHandle() +} + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_Foo_init") fileprivate func bjs_Foo_init_extern() -> Int32 @@ -122,4 +126,19 @@ func _$Foo_init() throws(JSException) -> JSObject { throw error } return JSObject.bridgeJSLiftReturn(ret) -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + FooContainer.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSNameOverride.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSNameOverride.json new file mode 100644 index 000000000..c5cd01631 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSNameOverride.json @@ -0,0 +1,524 @@ +{ + "exported" : { + "aliases" : [ + + ], + "classes" : [ + { + "constructor" : { + "abiName" : "bjs_RenamedMembers_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "title", + "name" : "title", + "type" : { + "string" : { + + } + } + }, + { + "label" : "count", + "name" : "count", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ] + }, + "methods" : [ + { + "abiName" : "bjs_RenamedMembers_makeGreeting", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "jsName" : "makeGreeting", + "name" : "greet", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_RenamedMembers_static_makeDefault", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "jsName" : "makeDefault", + "name" : "createDefault", + "parameters" : [ + + ], + "returnType" : { + "swiftHeapObject" : { + "_0" : "RenamedMembers" + } + }, + "staticContext" : { + "className" : { + "_0" : "RenamedMembers" + } + } + } + ], + "name" : "RenamedMembers", + "properties" : [ + { + "isReadonly" : false, + "isStatic" : false, + "jsName" : "label", + "name" : "title", + "type" : { + "string" : { + + } + } + }, + { + "isReadonly" : true, + "isStatic" : false, + "jsName" : "total", + "name" : "count", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + }, + { + "isReadonly" : false, + "isStatic" : true, + "jsName" : "sharedTotal", + "name" : "sharedCount", + "staticContext" : { + "className" : { + "_0" : "RenamedMembers" + } + }, + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + }, + { + "isReadonly" : true, + "isStatic" : true, + "jsName" : "readOnlyLimit", + "name" : "limit", + "staticContext" : { + "className" : { + "_0" : "RenamedMembers" + } + }, + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "RenamedMembers" + } + ], + "enums" : [ + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "active" + }, + { + "associatedValues" : [ + + ], + "name" : "inactive" + } + ], + "emitStyle" : "const", + "name" : "RenamedEnumMembers", + "staticMethods" : [ + { + "abiName" : "bjs_RenamedEnumMembers_static_describeCase", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "jsName" : "describeCase", + "name" : "describe", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + }, + "staticContext" : { + "enumName" : { + "_0" : "RenamedEnumMembers" + } + } + } + ], + "staticProperties" : [ + { + "isReadonly" : false, + "isStatic" : true, + "jsName" : "currentDefault", + "name" : "defaultValue", + "staticContext" : { + "enumName" : { + "_0" : "RenamedEnumMembers" + } + }, + "type" : { + "string" : { + + } + } + } + ], + "swiftCallName" : "RenamedEnumMembers", + "tsFullPath" : "RenamedEnumMembers" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "RenamedNamespaceMembers", + "staticMethods" : [ + { + "abiName" : "bjs_RenamedNamespaceMembers_static_plus", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "jsName" : "plus", + "name" : "add", + "namespace" : [ + "RenamedNamespaceMembers" + ], + "parameters" : [ + { + "label" : "_", + "name" : "a", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + }, + { + "label" : "_", + "name" : "b", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "returnType" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + }, + "staticContext" : { + "namespaceEnum" : { + "_0" : "RenamedNamespaceMembers" + } + } + } + ], + "staticProperties" : [ + { + "isReadonly" : false, + "isStatic" : true, + "jsName" : "theAnswer", + "name" : "answer", + "namespace" : [ + "RenamedNamespaceMembers" + ], + "staticContext" : { + "namespaceEnum" : { + "_0" : "RenamedNamespaceMembers" + } + }, + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "RenamedNamespaceMembers", + "tsFullPath" : "RenamedNamespaceMembers" + } + ], + "exposeToGlobal" : false, + "functions" : [ + { + "abiName" : "bjs_makeGreeting", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "jsName" : "makeGreeting", + "name" : "renderGreeting", + "parameters" : [ + { + "label" : "name", + "name" : "name", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_greetName", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "jsName" : "greetName", + "name" : "greet", + "parameters" : [ + { + "label" : "_", + "name" : "name", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_greetCount", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "jsName" : "greetCount", + "name" : "greet", + "parameters" : [ + { + "label" : "_", + "name" : "count", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_Utils_Text_namespacedRenamed", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "jsName" : "namespacedRenamed", + "name" : "namespacedFunction", + "namespace" : [ + "Utils", + "Text" + ], + "parameters" : [ + + ], + "returnType" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "protocols" : [ + + ], + "structs" : [ + { + "methods" : [ + { + "abiName" : "bjs_RenamedVector_magnitude", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "jsName" : "magnitude", + "name" : "length", + "parameters" : [ + + ], + "returnType" : { + "double" : { + + } + } + }, + { + "abiName" : "bjs_RenamedVector_static_fromPolar", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "jsName" : "fromPolar", + "name" : "polar", + "parameters" : [ + { + "label" : "radius", + "name" : "radius", + "type" : { + "double" : { + + } + } + }, + { + "label" : "angle", + "name" : "angle", + "type" : { + "double" : { + + } + } + } + ], + "returnType" : { + "swiftStruct" : { + "_0" : "RenamedVector" + } + }, + "staticContext" : { + "structName" : { + "_0" : "RenamedVector" + } + } + } + ], + "name" : "RenamedVector", + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "dx", + "type" : { + "double" : { + + } + } + }, + { + "isReadonly" : true, + "isStatic" : false, + "name" : "dy", + "type" : { + "double" : { + + } + } + }, + { + "isReadonly" : true, + "isStatic" : true, + "jsName" : "originVector", + "name" : "origin", + "staticContext" : { + "structName" : { + "_0" : "RenamedVector" + } + }, + "type" : { + "swiftStruct" : { + "_0" : "RenamedVector" + } + } + } + ], + "swiftCallName" : "RenamedVector" + } + ] + }, + "moduleName" : "TestModule", + "usedExternalModules" : [ + + ] +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSNameOverride.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSNameOverride.swift new file mode 100644 index 000000000..8e01bca22 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSNameOverride.swift @@ -0,0 +1,375 @@ +extension RenamedEnumMembers: _BridgedSwiftCaseEnum { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> RenamedEnumMembers { + return bridgeJSLiftParameter(value) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> RenamedEnumMembers { + return RenamedEnumMembers(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSLowerParameter() + } + + @_spi(BridgeJS) @usableFromInline init?(bridgeJSRawValue: Int32) { + switch bridgeJSRawValue { + case 0: + self = .active + case 1: + self = .inactive + default: + return nil + } + } + + @_spi(BridgeJS) @usableFromInline var bridgeJSRawValue: Int32 { + switch self { + case .active: + return 0 + case .inactive: + return 1 + } + } +} + +@_expose(wasm, "bjs_RenamedEnumMembers_static_describeCase") +@_cdecl("bjs_RenamedEnumMembers_static_describeCase") +public func _bjs_RenamedEnumMembers_static_describeCase() -> Void { + #if arch(wasm32) + let ret = RenamedEnumMembers.describe() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedEnumMembers_static_defaultValue_get") +@_cdecl("bjs_RenamedEnumMembers_static_defaultValue_get") +public func _bjs_RenamedEnumMembers_static_defaultValue_get() -> Void { + #if arch(wasm32) + let ret = RenamedEnumMembers.defaultValue + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedEnumMembers_static_defaultValue_set") +@_cdecl("bjs_RenamedEnumMembers_static_defaultValue_set") +public func _bjs_RenamedEnumMembers_static_defaultValue_set(_ valueBytes: Int32, _ valueLength: Int32) -> Void { + #if arch(wasm32) + RenamedEnumMembers.defaultValue = String.bridgeJSLiftParameter(valueBytes, valueLength) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedNamespaceMembers_static_plus") +@_cdecl("bjs_RenamedNamespaceMembers_static_plus") +public func _bjs_RenamedNamespaceMembers_static_plus(_ a: Int32, _ b: Int32) -> Int32 { + #if arch(wasm32) + let ret = RenamedNamespaceMembers.add(_: Int.bridgeJSLiftParameter(a), _: Int.bridgeJSLiftParameter(b)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedNamespaceMembers_static_answer_get") +@_cdecl("bjs_RenamedNamespaceMembers_static_answer_get") +public func _bjs_RenamedNamespaceMembers_static_answer_get() -> Int32 { + #if arch(wasm32) + let ret = RenamedNamespaceMembers.answer + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedNamespaceMembers_static_answer_set") +@_cdecl("bjs_RenamedNamespaceMembers_static_answer_set") +public func _bjs_RenamedNamespaceMembers_static_answer_set(_ value: Int32) -> Void { + #if arch(wasm32) + RenamedNamespaceMembers.answer = Int.bridgeJSLiftParameter(value) + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension RenamedVector: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> RenamedVector { + let dy = Double.bridgeJSStackPop() + let dx = Double.bridgeJSStackPop() + return RenamedVector(dx: dx, dy: dy) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + self.dx.bridgeJSStackPush() + self.dy.bridgeJSStackPush() + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_RenamedVector(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_RenamedVector())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_RenamedVector") +fileprivate func _bjs_struct_lower_RenamedVector_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_RenamedVector_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_RenamedVector(_ objectId: Int32) -> Void { + return _bjs_struct_lower_RenamedVector_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_RenamedVector") +fileprivate func _bjs_struct_lift_RenamedVector_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_RenamedVector_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_RenamedVector() -> Int32 { + return _bjs_struct_lift_RenamedVector_extern() +} + +@_expose(wasm, "bjs_RenamedVector_static_origin_get") +@_cdecl("bjs_RenamedVector_static_origin_get") +public func _bjs_RenamedVector_static_origin_get() -> Void { + #if arch(wasm32) + let ret = RenamedVector.origin + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedVector_magnitude") +@_cdecl("bjs_RenamedVector_magnitude") +public func _bjs_RenamedVector_magnitude() -> Float64 { + #if arch(wasm32) + let ret = RenamedVector.bridgeJSLiftParameter().length() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedVector_static_fromPolar") +@_cdecl("bjs_RenamedVector_static_fromPolar") +public func _bjs_RenamedVector_static_fromPolar(_ radius: Float64, _ angle: Float64) -> Void { + #if arch(wasm32) + let ret = RenamedVector.polar(radius: Double.bridgeJSLiftParameter(radius), angle: Double.bridgeJSLiftParameter(angle)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeGreeting") +@_cdecl("bjs_makeGreeting") +public func _bjs_makeGreeting(_ nameBytes: Int32, _ nameLength: Int32) -> Void { + #if arch(wasm32) + let ret = renderGreeting(name: String.bridgeJSLiftParameter(nameBytes, nameLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_greetName") +@_cdecl("bjs_greetName") +public func _bjs_greetName(_ nameBytes: Int32, _ nameLength: Int32) -> Void { + #if arch(wasm32) + let ret = greet(_: String.bridgeJSLiftParameter(nameBytes, nameLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_greetCount") +@_cdecl("bjs_greetCount") +public func _bjs_greetCount(_ count: Int32) -> Void { + #if arch(wasm32) + let ret = greet(_: Int.bridgeJSLiftParameter(count)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Utils_Text_namespacedRenamed") +@_cdecl("bjs_Utils_Text_namespacedRenamed") +public func _bjs_Utils_Text_namespacedRenamed() -> Int32 { + #if arch(wasm32) + let ret = namespacedFunction() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_init") +@_cdecl("bjs_RenamedMembers_init") +public func _bjs_RenamedMembers_init(_ titleBytes: Int32, _ titleLength: Int32, _ count: Int32) -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = RenamedMembers(title: String.bridgeJSLiftParameter(titleBytes, titleLength), count: Int.bridgeJSLiftParameter(count)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_makeGreeting") +@_cdecl("bjs_RenamedMembers_makeGreeting") +public func _bjs_RenamedMembers_makeGreeting(_ _self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = RenamedMembers.bridgeJSLiftParameter(_self).greet() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_static_makeDefault") +@_cdecl("bjs_RenamedMembers_static_makeDefault") +public func _bjs_RenamedMembers_static_makeDefault() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = RenamedMembers.createDefault() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_title_get") +@_cdecl("bjs_RenamedMembers_title_get") +public func _bjs_RenamedMembers_title_get(_ _self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = RenamedMembers.bridgeJSLiftParameter(_self).title + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_title_set") +@_cdecl("bjs_RenamedMembers_title_set") +public func _bjs_RenamedMembers_title_set(_ _self: UnsafeMutableRawPointer, _ valueBytes: Int32, _ valueLength: Int32) -> Void { + #if arch(wasm32) + RenamedMembers.bridgeJSLiftParameter(_self).title = String.bridgeJSLiftParameter(valueBytes, valueLength) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_count_get") +@_cdecl("bjs_RenamedMembers_count_get") +public func _bjs_RenamedMembers_count_get(_ _self: UnsafeMutableRawPointer) -> Int32 { + #if arch(wasm32) + let ret = RenamedMembers.bridgeJSLiftParameter(_self).count + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_static_sharedCount_get") +@_cdecl("bjs_RenamedMembers_static_sharedCount_get") +public func _bjs_RenamedMembers_static_sharedCount_get() -> Int32 { + #if arch(wasm32) + let ret = RenamedMembers.sharedCount + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_static_sharedCount_set") +@_cdecl("bjs_RenamedMembers_static_sharedCount_set") +public func _bjs_RenamedMembers_static_sharedCount_set(_ value: Int32) -> Void { + #if arch(wasm32) + RenamedMembers.sharedCount = Int.bridgeJSLiftParameter(value) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_static_limit_get") +@_cdecl("bjs_RenamedMembers_static_limit_get") +public func _bjs_RenamedMembers_static_limit_get() -> Int32 { + #if arch(wasm32) + let ret = RenamedMembers.limit + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_deinit") +@_cdecl("bjs_RenamedMembers_deinit") +public func _bjs_RenamedMembers_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension RenamedMembers: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_RenamedMembers_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_RenamedMembers_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_RenamedMembers_wrap") +fileprivate func _bjs_RenamedMembers_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_RenamedMembers_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_RenamedMembers_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_RenamedMembers_wrap_extern(pointer) +} + +extension RenamedVector: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = RenamedVector.bridgeJSMakeTypeHandle() +} + +extension RenamedEnumMembers: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = RenamedEnumMembers.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + RenamedVector.bridgeJSTypeID, + RenamedEnumMembers.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NamespacedClassSignature.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NamespacedClassSignature.json new file mode 100644 index 000000000..e6ea49859 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NamespacedClassSignature.json @@ -0,0 +1,133 @@ +{ + "exported" : { + "aliases" : [ + + ], + "classes" : [ + { + "constructor" : { + "abiName" : "bjs_Workshop_Bench_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + + ], + "name" : "Bench", + "namespace" : [ + "Workshop" + ], + "properties" : [ + + ], + "swiftCallName" : "Workshop.Bench" + } + ], + "enums" : [ + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "Workshop", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Workshop", + "tsFullPath" : "Workshop" + } + ], + "exposeToGlobal" : false, + "functions" : [ + { + "abiName" : "bjs_makeBench", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "makeBench", + "parameters" : [ + + ], + "returnType" : { + "swiftHeapObject" : { + "_0" : "Workshop.Bench" + } + } + }, + { + "abiName" : "bjs_refitBench", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "refitBench", + "parameters" : [ + { + "label" : "_", + "name" : "bench", + "type" : { + "swiftHeapObject" : { + "_0" : "Workshop.Bench" + } + } + }, + { + "label" : "_", + "name" : "transform", + "type" : { + "closure" : { + "_0" : { + "isAsync" : false, + "isThrows" : false, + "mangleName" : "10TestModule8Workshop5BenchC_8Workshop5BenchC", + "moduleName" : "TestModule", + "parameters" : [ + { + "swiftHeapObject" : { + "_0" : "Workshop.Bench" + } + } + ], + "returnType" : { + "swiftHeapObject" : { + "_0" : "Workshop.Bench" + } + }, + "sendingParameters" : false + }, + "useJSTypedClosure" : false + } + } + } + ], + "returnType" : { + "swiftHeapObject" : { + "_0" : "Workshop.Bench" + } + } + } + ], + "protocols" : [ + + ], + "structs" : [ + + ] + }, + "moduleName" : "TestModule", + "usedExternalModules" : [ + + ] +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NamespacedClassSignature.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NamespacedClassSignature.swift new file mode 100644 index 000000000..bff3007b7 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NamespacedClassSignature.swift @@ -0,0 +1,126 @@ +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "invoke_js_callback_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC") +fileprivate func invoke_js_callback_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC_extern(_ callback: Int32, _ param0: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer +#else +fileprivate func invoke_js_callback_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC_extern(_ callback: Int32, _ param0: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func invoke_js_callback_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC(_ callback: Int32, _ param0: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer { + return invoke_js_callback_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC_extern(callback, param0) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "make_swift_closure_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC") +fileprivate func make_swift_closure_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 +#else +fileprivate func make_swift_closure_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC_extern(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func make_swift_closure_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer, _ line: UInt32) -> Int32 { + return make_swift_closure_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC_extern(boxPtr, file, line) +} + +private enum _BJS_Closure_10TestModule8Workshop5BenchC_8Workshop5BenchC { + static func bridgeJSLift(_ callbackId: Int32) -> (Workshop.Bench) -> Workshop.Bench { + let callback = JSObject.bridgeJSLiftParameter(callbackId) + return { [callback] param0 in + #if arch(wasm32) + let param0Pointer = param0.bridgeJSLowerParameter() + let callbackValue = callback.bridgeJSLowerParameter() + let ret = invoke_js_callback_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC(callbackValue, param0Pointer) + return Workshop.Bench.bridgeJSLiftReturn(ret) + #else + fatalError("Only available on WebAssembly") + #endif + } + } +} + +extension JSTypedClosure where Signature == (Workshop.Bench) -> Workshop.Bench { + init(fileID: StaticString = #fileID, line: UInt32 = #line, _ body: @escaping (Workshop.Bench) -> Workshop.Bench) { + self.init( + makeClosure: make_swift_closure_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC, + body: body, + fileID: fileID, + line: line + ) + } +} + +@_expose(wasm, "invoke_swift_closure_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC") +@_cdecl("invoke_swift_closure_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC") +public func _invoke_swift_closure_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC(_ boxPtr: UnsafeMutableRawPointer, _ param0: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer { + #if arch(wasm32) + let closure = Unmanaged<_BridgeJSTypedClosureBox<(Workshop.Bench) -> Workshop.Bench>>.fromOpaque(boxPtr).takeUnretainedValue().closure + let result = closure(Workshop.Bench.bridgeJSLiftParameter(param0)) + return result.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeBench") +@_cdecl("bjs_makeBench") +public func _bjs_makeBench() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = makeBench() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_refitBench") +@_cdecl("bjs_refitBench") +public func _bjs_refitBench(_ bench: UnsafeMutableRawPointer, _ transform: Int32) -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = refitBench(_: Workshop.Bench.bridgeJSLiftParameter(bench), _: _BJS_Closure_10TestModule8Workshop5BenchC_8Workshop5BenchC.bridgeJSLift(transform)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Workshop_Bench_init") +@_cdecl("bjs_Workshop_Bench_init") +public func _bjs_Workshop_Bench_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = Workshop.Bench() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Workshop_Bench_deinit") +@_cdecl("bjs_Workshop_Bench_deinit") +public func _bjs_Workshop_Bench_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension Workshop.Bench: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_Workshop_Bench_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_Workshop_Bench_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_Workshop_Bench_wrap") +fileprivate func _bjs_Workshop_Bench_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_Workshop_Bench_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_Workshop_Bench_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_Workshop_Bench_wrap_extern(pointer) +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NestedType.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NestedType.swift index ed1a080e9..9e1b0e0f6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NestedType.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NestedType.swift @@ -176,4 +176,28 @@ fileprivate func _bjs_Player_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> #endif @inline(never) fileprivate func _bjs_Player_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_Player_wrap_extern(pointer) -} \ No newline at end of file +} + +extension User.Stats: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = User.Stats.bridgeJSMakeTypeHandle() +} + +extension Player.Stats: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Player.Stats.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + User.Stats.bridgeJSTypeID, + Player.Stats.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NestedTypeNameCollision.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NestedTypeNameCollision.json new file mode 100644 index 000000000..8683e11b1 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NestedTypeNameCollision.json @@ -0,0 +1,177 @@ +{ + "exported" : { + "aliases" : [ + + ], + "classes" : [ + + ], + "enums" : [ + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "Catalog", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Catalog", + "tsFullPath" : "Catalog" + } + ], + "exposeToGlobal" : false, + "functions" : [ + { + "abiName" : "bjs_takeEntry", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "takeEntry", + "parameters" : [ + { + "label" : "_", + "name" : "entry", + "type" : { + "swiftStruct" : { + "_0" : "Entry" + } + } + } + ], + "returnType" : { + "swiftStruct" : { + "_0" : "Entry" + } + } + }, + { + "abiName" : "bjs_takeCatalogEntry", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "takeCatalogEntry", + "parameters" : [ + { + "label" : "_", + "name" : "entry", + "type" : { + "swiftStruct" : { + "_0" : "Catalog.Entry" + } + } + } + ], + "returnType" : { + "swiftStruct" : { + "_0" : "Catalog.Entry" + } + } + } + ], + "protocols" : [ + + ], + "structs" : [ + { + "constructor" : { + "abiName" : "bjs_Catalog_Entry_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "title", + "name" : "title", + "type" : { + "string" : { + + } + } + } + ] + }, + "methods" : [ + + ], + "name" : "Entry", + "namespace" : [ + "Catalog" + ], + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "title", + "namespace" : [ + "Catalog" + ], + "type" : { + "string" : { + + } + } + } + ], + "swiftCallName" : "Catalog.Entry" + }, + { + "constructor" : { + "abiName" : "bjs_Entry_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "identifier", + "name" : "identifier", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ] + }, + "methods" : [ + + ], + "name" : "Entry", + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "identifier", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "Entry" + } + ] + }, + "moduleName" : "TestModule", + "usedExternalModules" : [ + + ] +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NestedTypeNameCollision.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NestedTypeNameCollision.swift new file mode 100644 index 000000000..266f37f09 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NestedTypeNameCollision.swift @@ -0,0 +1,159 @@ +extension Catalog.Entry: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> Catalog.Entry { + let title = String.bridgeJSStackPop() + return Catalog.Entry(title: title) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + self.title.bridgeJSStackPush() + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_Catalog_Entry(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_Catalog_Entry())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_Catalog_Entry") +fileprivate func _bjs_struct_lower_Catalog_Entry_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_Catalog_Entry_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_Catalog_Entry(_ objectId: Int32) -> Void { + return _bjs_struct_lower_Catalog_Entry_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_Catalog_Entry") +fileprivate func _bjs_struct_lift_Catalog_Entry_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_Catalog_Entry_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_Catalog_Entry() -> Int32 { + return _bjs_struct_lift_Catalog_Entry_extern() +} + +@_expose(wasm, "bjs_Catalog_Entry_init") +@_cdecl("bjs_Catalog_Entry_init") +public func _bjs_Catalog_Entry_init(_ titleBytes: Int32, _ titleLength: Int32) -> Void { + #if arch(wasm32) + let ret = Catalog.Entry(title: String.bridgeJSLiftParameter(titleBytes, titleLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension Entry: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> Entry { + let identifier = Int.bridgeJSStackPop() + return Entry(identifier: identifier) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + self.identifier.bridgeJSStackPush() + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_Entry(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_Entry())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_Entry") +fileprivate func _bjs_struct_lower_Entry_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_Entry_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_Entry(_ objectId: Int32) -> Void { + return _bjs_struct_lower_Entry_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_Entry") +fileprivate func _bjs_struct_lift_Entry_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_Entry_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_Entry() -> Int32 { + return _bjs_struct_lift_Entry_extern() +} + +@_expose(wasm, "bjs_Entry_init") +@_cdecl("bjs_Entry_init") +public func _bjs_Entry_init(_ identifier: Int32) -> Void { + #if arch(wasm32) + let ret = Entry(identifier: Int.bridgeJSLiftParameter(identifier)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_takeEntry") +@_cdecl("bjs_takeEntry") +public func _bjs_takeEntry() -> Void { + #if arch(wasm32) + let ret = takeEntry(_: Entry.bridgeJSLiftParameter()) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_takeCatalogEntry") +@_cdecl("bjs_takeCatalogEntry") +public func _bjs_takeCatalogEntry() -> Void { + #if arch(wasm32) + let ret = takeCatalogEntry(_: Catalog.Entry.bridgeJSLiftParameter()) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension Catalog.Entry: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Catalog.Entry.bridgeJSMakeTypeHandle() +} + +extension Entry: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Entry.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Catalog.Entry.bridgeJSTypeID, + Entry.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Protocol.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Protocol.swift index cfda92ac0..7c2db9a98 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Protocol.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Protocol.swift @@ -1043,4 +1043,38 @@ fileprivate func _bjs_DelegateManager_wrap_extern(_ pointer: UnsafeMutableRawPoi #endif @inline(never) fileprivate func _bjs_DelegateManager_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_DelegateManager_wrap_extern(pointer) -} \ No newline at end of file +} + +extension Direction: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Direction.bridgeJSMakeTypeHandle() +} + +extension ExampleEnum: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ExampleEnum.bridgeJSMakeTypeHandle() +} + +extension Result: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Result.bridgeJSMakeTypeHandle() +} + +extension Priority: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Priority.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Direction.bridgeJSTypeID, + ExampleEnum.bridgeJSTypeID, + Result.bridgeJSTypeID, + Priority.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/RelativeQualifiedTypes.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/RelativeQualifiedTypes.json new file mode 100644 index 000000000..0872c6d79 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/RelativeQualifiedTypes.json @@ -0,0 +1,239 @@ +{ + "exported" : { + "aliases" : [ + + ], + "classes" : [ + { + "constructor" : { + "abiName" : "bjs_Library_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + { + "abiName" : "bjs_Library_divider", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "divider", + "parameters" : [ + { + "label" : "_", + "name" : "value", + "type" : { + "swiftStruct" : { + "_0" : "Library.Shelf.Divider" + } + } + } + ], + "returnType" : { + "swiftStruct" : { + "_0" : "Library.Shelf.Divider" + } + } + } + ], + "name" : "Library", + "properties" : [ + + ], + "swiftCallName" : "Library" + }, + { + "constructor" : { + "abiName" : "bjs_Outer_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + + ], + "name" : "Outer", + "properties" : [ + + ], + "swiftCallName" : "Outer" + } + ], + "enums" : [ + + ], + "exposeToGlobal" : false, + "functions" : [ + + ], + "protocols" : [ + + ], + "structs" : [ + { + "methods" : [ + + ], + "name" : "Shelf", + "namespace" : [ + "Library" + ], + "properties" : [ + + ], + "swiftCallName" : "Library.Shelf" + }, + { + "constructor" : { + "abiName" : "bjs_Library_Shelf_Divider_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "slot", + "name" : "slot", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ] + }, + "methods" : [ + + ], + "name" : "Divider", + "namespace" : [ + "Library", + "Shelf" + ], + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "slot", + "namespace" : [ + "Library", + "Shelf" + ], + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "Library.Shelf.Divider" + }, + { + "constructor" : { + "abiName" : "bjs_Outer_Inner_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + { + "abiName" : "bjs_Outer_Inner_marker", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "marker", + "parameters" : [ + + ], + "returnType" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "name" : "Inner", + "namespace" : [ + "Outer" + ], + "properties" : [ + + ], + "swiftCallName" : "Outer.Inner" + }, + { + "methods" : [ + + ], + "name" : "Outer", + "namespace" : [ + "Outer", + "Inner" + ], + "properties" : [ + + ], + "swiftCallName" : "Outer.Inner.Outer" + }, + { + "constructor" : { + "abiName" : "bjs_Outer_Inner_Outer_Inner_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + + ], + "name" : "Inner", + "namespace" : [ + "Outer", + "Inner", + "Outer" + ], + "properties" : [ + + ], + "swiftCallName" : "Outer.Inner.Outer.Inner" + } + ] + }, + "moduleName" : "TestModule", + "usedExternalModules" : [ + + ] +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/RelativeQualifiedTypes.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/RelativeQualifiedTypes.swift new file mode 100644 index 000000000..0a6b272e9 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/RelativeQualifiedTypes.swift @@ -0,0 +1,399 @@ +extension Library.Shelf: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> Library.Shelf { + return Library.Shelf() + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_Library_Shelf(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_Library_Shelf())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_Library_Shelf") +fileprivate func _bjs_struct_lower_Library_Shelf_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_Library_Shelf_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_Library_Shelf(_ objectId: Int32) -> Void { + return _bjs_struct_lower_Library_Shelf_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_Library_Shelf") +fileprivate func _bjs_struct_lift_Library_Shelf_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_Library_Shelf_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_Library_Shelf() -> Int32 { + return _bjs_struct_lift_Library_Shelf_extern() +} + +extension Library.Shelf.Divider: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> Library.Shelf.Divider { + let slot = Int.bridgeJSStackPop() + return Library.Shelf.Divider(slot: slot) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + self.slot.bridgeJSStackPush() + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_Library_Shelf_Divider(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_Library_Shelf_Divider())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_Library_Shelf_Divider") +fileprivate func _bjs_struct_lower_Library_Shelf_Divider_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_Library_Shelf_Divider_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_Library_Shelf_Divider(_ objectId: Int32) -> Void { + return _bjs_struct_lower_Library_Shelf_Divider_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_Library_Shelf_Divider") +fileprivate func _bjs_struct_lift_Library_Shelf_Divider_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_Library_Shelf_Divider_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_Library_Shelf_Divider() -> Int32 { + return _bjs_struct_lift_Library_Shelf_Divider_extern() +} + +@_expose(wasm, "bjs_Library_Shelf_Divider_init") +@_cdecl("bjs_Library_Shelf_Divider_init") +public func _bjs_Library_Shelf_Divider_init(_ slot: Int32) -> Void { + #if arch(wasm32) + let ret = Library.Shelf.Divider(slot: Int.bridgeJSLiftParameter(slot)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension Outer.Inner: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> Outer.Inner { + return Outer.Inner() + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_Outer_Inner(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_Outer_Inner())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_Outer_Inner") +fileprivate func _bjs_struct_lower_Outer_Inner_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_Outer_Inner_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_Outer_Inner(_ objectId: Int32) -> Void { + return _bjs_struct_lower_Outer_Inner_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_Outer_Inner") +fileprivate func _bjs_struct_lift_Outer_Inner_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_Outer_Inner_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_Outer_Inner() -> Int32 { + return _bjs_struct_lift_Outer_Inner_extern() +} + +@_expose(wasm, "bjs_Outer_Inner_init") +@_cdecl("bjs_Outer_Inner_init") +public func _bjs_Outer_Inner_init() -> Void { + #if arch(wasm32) + let ret = Outer.Inner() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Outer_Inner_marker") +@_cdecl("bjs_Outer_Inner_marker") +public func _bjs_Outer_Inner_marker() -> Int32 { + #if arch(wasm32) + let ret = Outer.Inner.bridgeJSLiftParameter().marker() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension Outer.Inner.Outer: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> Outer.Inner.Outer { + return Outer.Inner.Outer() + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_Outer_Inner_Outer(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_Outer_Inner_Outer())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_Outer_Inner_Outer") +fileprivate func _bjs_struct_lower_Outer_Inner_Outer_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_Outer_Inner_Outer_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_Outer_Inner_Outer(_ objectId: Int32) -> Void { + return _bjs_struct_lower_Outer_Inner_Outer_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_Outer_Inner_Outer") +fileprivate func _bjs_struct_lift_Outer_Inner_Outer_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_Outer_Inner_Outer_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_Outer_Inner_Outer() -> Int32 { + return _bjs_struct_lift_Outer_Inner_Outer_extern() +} + +extension Outer.Inner.Outer.Inner: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> Outer.Inner.Outer.Inner { + return Outer.Inner.Outer.Inner() + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_Outer_Inner_Outer_Inner(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_Outer_Inner_Outer_Inner())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_Outer_Inner_Outer_Inner") +fileprivate func _bjs_struct_lower_Outer_Inner_Outer_Inner_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_Outer_Inner_Outer_Inner_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_Outer_Inner_Outer_Inner(_ objectId: Int32) -> Void { + return _bjs_struct_lower_Outer_Inner_Outer_Inner_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_Outer_Inner_Outer_Inner") +fileprivate func _bjs_struct_lift_Outer_Inner_Outer_Inner_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_Outer_Inner_Outer_Inner_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_Outer_Inner_Outer_Inner() -> Int32 { + return _bjs_struct_lift_Outer_Inner_Outer_Inner_extern() +} + +@_expose(wasm, "bjs_Outer_Inner_Outer_Inner_init") +@_cdecl("bjs_Outer_Inner_Outer_Inner_init") +public func _bjs_Outer_Inner_Outer_Inner_init() -> Void { + #if arch(wasm32) + let ret = Outer.Inner.Outer.Inner() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_init") +@_cdecl("bjs_Library_init") +public func _bjs_Library_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = Library() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_divider") +@_cdecl("bjs_Library_divider") +public func _bjs_Library_divider(_ _self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = Library.bridgeJSLiftParameter(_self).divider(_: Library.Shelf.Divider.bridgeJSLiftParameter()) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_deinit") +@_cdecl("bjs_Library_deinit") +public func _bjs_Library_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension Library: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_Library_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_Library_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_Library_wrap") +fileprivate func _bjs_Library_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_Library_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_Library_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_Library_wrap_extern(pointer) +} + +@_expose(wasm, "bjs_Outer_init") +@_cdecl("bjs_Outer_init") +public func _bjs_Outer_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = Outer() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Outer_deinit") +@_cdecl("bjs_Outer_deinit") +public func _bjs_Outer_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension Outer: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_Outer_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_Outer_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_Outer_wrap") +fileprivate func _bjs_Outer_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_Outer_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_Outer_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_Outer_wrap_extern(pointer) +} + +extension Library.Shelf: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Library.Shelf.bridgeJSMakeTypeHandle() +} + +extension Library.Shelf.Divider: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Library.Shelf.Divider.bridgeJSMakeTypeHandle() +} + +extension Outer.Inner: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Outer.Inner.bridgeJSMakeTypeHandle() +} + +extension Outer.Inner.Outer: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Outer.Inner.Outer.bridgeJSMakeTypeHandle() +} + +extension Outer.Inner.Outer.Inner: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Outer.Inner.Outer.Inner.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Library.Shelf.bridgeJSTypeID, + Library.Shelf.Divider.bridgeJSTypeID, + Outer.Inner.bridgeJSTypeID, + Outer.Inner.Outer.bridgeJSTypeID, + Outer.Inner.Outer.Inner.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.Global.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.Global.swift index 896258915..2d5a93c54 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.Global.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.Global.swift @@ -207,4 +207,28 @@ fileprivate func _bjs_MathUtils_wrap_extern(_ pointer: UnsafeMutableRawPointer) #endif @inline(never) fileprivate func _bjs_MathUtils_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_MathUtils_wrap_extern(pointer) -} \ No newline at end of file +} + +extension Calculator: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Calculator.bridgeJSMakeTypeHandle() +} + +extension APIResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = APIResult.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Calculator.bridgeJSTypeID, + APIResult.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.swift index 896258915..2d5a93c54 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.swift @@ -207,4 +207,28 @@ fileprivate func _bjs_MathUtils_wrap_extern(_ pointer: UnsafeMutableRawPointer) #endif @inline(never) fileprivate func _bjs_MathUtils_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_MathUtils_wrap_extern(pointer) -} \ No newline at end of file +} + +extension Calculator: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Calculator.bridgeJSMakeTypeHandle() +} + +extension APIResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = APIResult.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Calculator.bridgeJSTypeID, + APIResult.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticProperties.Global.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticProperties.Global.swift index ded55dbd4..721c5335a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticProperties.Global.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticProperties.Global.swift @@ -338,4 +338,23 @@ fileprivate func _bjs_PropertyClass_wrap_extern(_ pointer: UnsafeMutableRawPoint #endif @inline(never) fileprivate func _bjs_PropertyClass_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_PropertyClass_wrap_extern(pointer) -} \ No newline at end of file +} + +extension PropertyEnum: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PropertyEnum.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + PropertyEnum.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticProperties.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticProperties.swift index ded55dbd4..721c5335a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticProperties.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticProperties.swift @@ -338,4 +338,23 @@ fileprivate func _bjs_PropertyClass_wrap_extern(_ pointer: UnsafeMutableRawPoint #endif @inline(never) fileprivate func _bjs_PropertyClass_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_PropertyClass_wrap_extern(pointer) -} \ No newline at end of file +} + +extension PropertyEnum: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PropertyEnum.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + PropertyEnum.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StructWithNestedTypes.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StructWithNestedTypes.swift index ad99f0a03..8fc6db1a7 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StructWithNestedTypes.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StructWithNestedTypes.swift @@ -246,4 +246,53 @@ public func _bjs_Widget_Bounds_static_zero() -> Void { #else fatalError("Only available on WebAssembly") #endif -} \ No newline at end of file +} + +extension Shape: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Shape.bridgeJSMakeTypeHandle() +} + +extension Widget: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Widget.bridgeJSMakeTypeHandle() +} + +extension Widget.Layout: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Widget.Layout.bridgeJSMakeTypeHandle() +} + +extension Widget.Bounds: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Widget.Bounds.bridgeJSMakeTypeHandle() +} + +extension Shape.Kind: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Shape.Kind.bridgeJSMakeTypeHandle() +} + +extension Widget.Variant: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Widget.Variant.bridgeJSMakeTypeHandle() +} + +extension Widget.Layout.Alignment: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Widget.Layout.Alignment.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Shape.bridgeJSTypeID, + Widget.bridgeJSTypeID, + Widget.Layout.bridgeJSTypeID, + Widget.Bounds.bridgeJSTypeID, + Shape.Kind.bridgeJSTypeID, + Widget.Variant.bridgeJSTypeID, + Widget.Layout.Alignment.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosure.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosure.swift index c7ac02fb1..c2844aa9c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosure.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosure.swift @@ -992,14 +992,14 @@ public func _invoke_swift_closure_TestModule_10TestModuleSq5ThemeO_Sq5ThemeO(_ b #if arch(wasm32) @_extern(wasm, module: "bjs", name: "invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV") -fileprivate func invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV_extern(_ callback: Int32, _ param0: Int32) -> Void +fileprivate func invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV_extern(_ callback: Int32) -> Void #else -fileprivate func invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV_extern(_ callback: Int32, _ param0: Int32) -> Void { +fileprivate func invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV_extern(_ callback: Int32) -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV(_ callback: Int32, _ param0: Int32) -> Void { - return invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV_extern(callback, param0) +@inline(never) fileprivate func invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV(_ callback: Int32) -> Void { + return invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV_extern(callback) } #if arch(wasm32) @@ -1019,9 +1019,9 @@ private enum _BJS_Closure_10TestModuleSq6AnimalV_Sq6AnimalV { let callback = JSObject.bridgeJSLiftParameter(callbackId) return { [callback] param0 in #if arch(wasm32) - let param0IsSome = param0.bridgeJSLowerParameter() + let _ = param0.bridgeJSLowerParameter() let callbackValue = callback.bridgeJSLowerParameter() - invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV(callbackValue, param0IsSome) + invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV(callbackValue) return Optional.bridgeJSLiftReturn() #else fatalError("Only available on WebAssembly") @@ -2637,6 +2637,26 @@ fileprivate func _bjs_TestProcessor_wrap_extern(_ pointer: UnsafeMutableRawPoint return _bjs_TestProcessor_wrap_extern(pointer) } +extension Animal: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Animal.bridgeJSMakeTypeHandle() +} + +extension Direction: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Direction.bridgeJSMakeTypeHandle() +} + +extension Theme: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Theme.bridgeJSMakeTypeHandle() +} + +extension HttpStatus: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = HttpStatus.bridgeJSMakeTypeHandle() +} + +extension APIResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = APIResult.bridgeJSMakeTypeHandle() +} + @JSFunction func Promise_reject(_ promise: JSObject, _ value: JSValue) throws(JSException) #if arch(wasm32) @@ -2720,4 +2740,23 @@ func _$Promise_resolve_9APIResultO(_ promise: JSObject, _ value: APIResult) thro let promiseValue = promise.bridgeJSLowerParameter() promise_resolve_TestModule_9APIResultO(promiseValue, valueCaseId) if let error = _swift_js_take_exception() { throw error } -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Animal.bridgeJSTypeID, + Direction.bridgeJSTypeID, + Theme.bridgeJSTypeID, + HttpStatus.bridgeJSTypeID, + APIResult.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStruct.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStruct.swift index f98038b45..b4e54961c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStruct.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStruct.swift @@ -630,4 +630,63 @@ fileprivate func _bjs_Greeter_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> #endif @inline(never) fileprivate func _bjs_Greeter_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_Greeter_wrap_extern(pointer) -} \ No newline at end of file +} + +extension DataPoint: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = DataPoint.bridgeJSMakeTypeHandle() +} + +extension Address: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Address.bridgeJSMakeTypeHandle() +} + +extension Person: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Person.bridgeJSMakeTypeHandle() +} + +extension Session: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Session.bridgeJSMakeTypeHandle() +} + +extension Measurement: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Measurement.bridgeJSMakeTypeHandle() +} + +extension ConfigStruct: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ConfigStruct.bridgeJSMakeTypeHandle() +} + +extension Container: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Container.bridgeJSMakeTypeHandle() +} + +extension Vector2D: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Vector2D.bridgeJSMakeTypeHandle() +} + +extension Precision: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Precision.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + DataPoint.bridgeJSTypeID, + Address.bridgeJSTypeID, + Person.bridgeJSTypeID, + Session.bridgeJSTypeID, + Measurement.bridgeJSTypeID, + ConfigStruct.bridgeJSTypeID, + Container.bridgeJSTypeID, + Vector2D.bridgeJSTypeID, + Precision.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStructImports.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStructImports.swift index 38ec94c0d..0d77ebe47 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStructImports.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStructImports.swift @@ -46,6 +46,10 @@ fileprivate func _bjs_struct_lift_Point_extern() -> Int32 { return _bjs_struct_lift_Point_extern() } +extension Point: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Point.bridgeJSMakeTypeHandle() +} + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_translate") fileprivate func bjs_translate_extern(_ dx: Int32, _ dy: Int32) -> Void @@ -71,21 +75,36 @@ func _$translate(_ point: Point, _ dx: Int, _ dy: Int) throws(JSException) -> Po #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_roundTripOptional") -fileprivate func bjs_roundTripOptional_extern(_ point: Int32) -> Void +fileprivate func bjs_roundTripOptional_extern() -> Void #else -fileprivate func bjs_roundTripOptional_extern(_ point: Int32) -> Void { +fileprivate func bjs_roundTripOptional_extern() -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_roundTripOptional(_ point: Int32) -> Void { - return bjs_roundTripOptional_extern(point) +@inline(never) fileprivate func bjs_roundTripOptional() -> Void { + return bjs_roundTripOptional_extern() } func _$roundTripOptional(_ point: Optional) throws(JSException) -> Optional { - let pointIsSome = point.bridgeJSLowerParameter() - bjs_roundTripOptional(pointIsSome) + let _ = point.bridgeJSLowerParameter() + bjs_roundTripOptional() if let error = _swift_js_take_exception() { throw error } return Optional.bridgeJSLiftReturn() -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Point.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/UnsafePointer.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/UnsafePointer.swift index b97729084..69011da18 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/UnsafePointer.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/UnsafePointer.swift @@ -177,4 +177,23 @@ public func _bjs_roundTripPointerFields() -> Void { #else fatalError("Only available on WebAssembly") #endif -} \ No newline at end of file +} + +extension PointerFields: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PointerFields.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + PointerFields.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Alias.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Alias.js index 92fb5a109..b1cfb68aa 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Alias.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Alias.js @@ -37,7 +37,367 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createInnerTagValuesHelpers = () => ({ + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_M10TestModuleT16PolygonReference = { + lower: (v) => { + ptrStack.push(v.pointer); + }, + lift: () => { + const ptr = ptrStack.pop(); + const obj = _exports['PolygonReference'].__construct(ptr); + return obj; + }, + }; + const __bjs_codec_Array_M10TestModuleT16PolygonReference = __bjs_arrayCodec(__bjs_codec_M10TestModuleT16PolygonReference); + const __bjs_codec_M10TestModuleT8InnerTag = { + lower: (v) => { + const caseId = enumHelpers.M10TestModuleT8InnerTag.lower(v); + i32Stack.push(caseId); + }, + lift: () => { + const enumValue = enumHelpers.M10TestModuleT8InnerTag.lift(i32Stack.pop()); + return enumValue; + }, + }; + const __bjs_codec_Optional_M10TestModuleT8InnerTag = __bjs_optionalCodec(__bjs_codec_M10TestModuleT8InnerTag); + const __bjs_codec_Array_Optional_M10TestModuleT8InnerTag = __bjs_arrayCodec(__bjs_codec_Optional_M10TestModuleT8InnerTag); + const __bjs_codec_Surface = { + lower: (v) => { + const objId = swift.memory.retain(v); + i32Stack.push(objId); + }, + lift: () => { + const objId = i32Stack.pop(); + const obj = swift.memory.getObject(objId); + swift.memory.release(objId); + return obj; + }, + }; + const __bjs_codec_Optional_Surface = __bjs_optionalCodec(__bjs_codec_Surface); + + const __bjs_createEnumHelpers_M10TestModuleT8InnerTag = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -139,6 +499,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -284,12 +646,7 @@ export async function createInstantiator(options, swift) { TestModule["bjs_produceOptionalCanvas"] = function bjs_produceOptionalCanvas() { try { let ret = imports.produceOptionalCanvas(); - const isSome = ret != null; - if (isSome) { - const objId = swift.memory.retain(ret); - i32Stack.push(objId); - } - i32Stack.push(isSome ? 1 : 0); + __bjs_codec_Optional_Surface.lower(ret); } catch (error) { setException(error); } @@ -417,8 +774,8 @@ export async function createInstantiator(options, swift) { return TagReference.__construct(ret); } } - const InnerTagHelpers = __bjs_createInnerTagValuesHelpers(); - enumHelpers.InnerTag = InnerTagHelpers; + const __bjs_helpers_M10TestModuleT8InnerTag = __bjs_createEnumHelpers_M10TestModuleT8InnerTag(); + enumHelpers.M10TestModuleT8InnerTag = __bjs_helpers_M10TestModuleT8InnerTag; const exports = { roundtripPolygon: function bjs_roundtripPolygon(polygon) { @@ -440,24 +797,9 @@ export async function createInstantiator(options, swift) { return optResult; }, polygonArray: function bjs_polygonArray(polygons) { - for (const elem of polygons) { - ptrStack.push(elem.pointer); - } - i32Stack.push(polygons.length); + __bjs_codec_Array_M10TestModuleT16PolygonReference.lower(polygons); instance.exports.bjs_polygonArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const ptr = ptrStack.pop(); - const obj = PolygonReference.__construct(ptr); - arrayResult.push(obj); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT16PolygonReference.lift(); return arrayResult; }, validatePolygon: function bjs_validatePolygon(polygon) { @@ -477,35 +819,9 @@ export async function createInstantiator(options, swift) { return TagReference.__construct(ret); }, roundtripTags: function bjs_roundtripTags(xs) { - for (const elem of xs) { - const isSome = elem != null ? 1 : 0; - if (isSome) { - const caseId = enumHelpers.InnerTag.lower(elem); - i32Stack.push(caseId); - } - i32Stack.push(isSome); - } - i32Stack.push(xs.length); + __bjs_codec_Array_Optional_M10TestModuleT8InnerTag.lower(xs); instance.exports.bjs_roundtripTags(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const isSome1 = i32Stack.pop(); - let optValue; - if (isSome1 === 0) { - optValue = null; - } else { - const enumValue = enumHelpers.InnerTag.lift(i32Stack.pop()); - optValue = enumValue; - } - arrayResult.push(optValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Optional_M10TestModuleT8InnerTag.lift(); return arrayResult; }, describeUser: function bjs_describeUser(owner) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AliasInClosure.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AliasInClosure.js index a38fa118e..fa9095cd8 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AliasInClosure.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AliasInClosure.js @@ -131,6 +131,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayTypes.js index 419cf15d5..6d3992ce5 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayTypes.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayTypes.js @@ -44,7 +44,438 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createPointHelpers = () => ({ + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_Array_Int = __bjs_arrayCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_Array_String = __bjs_arrayCodec(__bjs_stringCodec); + const __bjs_codec_Array_Double = __bjs_arrayCodec(__bjs_primitiveCodecs.Double); + const __bjs_codec_Array_Bool = __bjs_arrayCodec(__bjs_primitiveCodecs.Bool); + const __bjs_codec_M10TestModuleT5Point = { + lower: (v) => { + structHelpers.M10TestModuleT5Point.lower(v); + }, + lift: () => { + const struct = structHelpers.M10TestModuleT5Point.lift(); + return struct; + }, + }; + const __bjs_codec_Array_M10TestModuleT5Point = __bjs_arrayCodec(__bjs_codec_M10TestModuleT5Point); + const __bjs_codec_M10TestModuleT9Direction = { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const caseId = i32Stack.pop(); + return caseId; + }, + }; + const __bjs_codec_Array_M10TestModuleT9Direction = __bjs_arrayCodec(__bjs_codec_M10TestModuleT9Direction); + const __bjs_codec_M10TestModuleT6Status = { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const rawValue = i32Stack.pop(); + return rawValue; + }, + }; + const __bjs_codec_Array_M10TestModuleT6Status = __bjs_arrayCodec(__bjs_codec_M10TestModuleT6Status); + const __bjs_codec_Surp = { + lower: (v) => { + ptrStack.push((v | 0)); + }, + lift: () => { + const pointer = ptrStack.pop(); + return pointer; + }, + }; + const __bjs_codec_Array_Surp = __bjs_arrayCodec(__bjs_codec_Surp); + const __bjs_codec_Sumrp = { + lower: (v) => { + ptrStack.push((v | 0)); + }, + lift: () => { + const pointer = ptrStack.pop(); + return pointer; + }, + }; + const __bjs_codec_Array_Sumrp = __bjs_arrayCodec(__bjs_codec_Sumrp); + const __bjs_codec_Sop = { + lower: (v) => { + ptrStack.push((v | 0)); + }, + lift: () => { + const pointer = ptrStack.pop(); + return pointer; + }, + }; + const __bjs_codec_Array_Sop = __bjs_arrayCodec(__bjs_codec_Sop); + const __bjs_codec_Optional_Int = __bjs_optionalCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_Array_Optional_Int = __bjs_arrayCodec(__bjs_codec_Optional_Int); + const __bjs_codec_Optional_String = __bjs_optionalCodec(__bjs_stringCodec); + const __bjs_codec_Array_Optional_String = __bjs_arrayCodec(__bjs_codec_Optional_String); + const __bjs_codec_Optional_Array_Int = __bjs_optionalCodec(__bjs_codec_Array_Int); + const __bjs_codec_Optional_M10TestModuleT5Point = __bjs_optionalCodec(__bjs_codec_M10TestModuleT5Point); + const __bjs_codec_Array_Optional_M10TestModuleT5Point = __bjs_arrayCodec(__bjs_codec_Optional_M10TestModuleT5Point); + const __bjs_codec_Optional_M10TestModuleT9Direction = __bjs_optionalCodec(__bjs_codec_M10TestModuleT9Direction); + const __bjs_codec_Array_Optional_M10TestModuleT9Direction = __bjs_arrayCodec(__bjs_codec_Optional_M10TestModuleT9Direction); + const __bjs_codec_Optional_M10TestModuleT6Status = __bjs_optionalCodec(__bjs_codec_M10TestModuleT6Status); + const __bjs_codec_Array_Optional_M10TestModuleT6Status = __bjs_arrayCodec(__bjs_codec_Optional_M10TestModuleT6Status); + const __bjs_codec_Array_Array_Int = __bjs_arrayCodec(__bjs_codec_Array_Int); + const __bjs_codec_Array_Array_String = __bjs_arrayCodec(__bjs_codec_Array_String); + const __bjs_codec_Array_Array_M10TestModuleT5Point = __bjs_arrayCodec(__bjs_codec_Array_M10TestModuleT5Point); + const __bjs_codec_M10TestModuleT4Item = { + lower: (v) => { + ptrStack.push(v.pointer); + }, + lift: () => { + const ptr = ptrStack.pop(); + const obj = _exports['Item'].__construct(ptr); + return obj; + }, + }; + const __bjs_codec_Array_M10TestModuleT4Item = __bjs_arrayCodec(__bjs_codec_M10TestModuleT4Item); + const __bjs_codec_Array_Array_M10TestModuleT4Item = __bjs_arrayCodec(__bjs_codec_Array_M10TestModuleT4Item); + const __bjs_codec_JSObject = { + lower: (v) => { + const objId = swift.memory.retain(v); + i32Stack.push(objId); + }, + lift: () => { + const objId = i32Stack.pop(); + const obj = swift.memory.getObject(objId); + swift.memory.release(objId); + return obj; + }, + }; + const __bjs_codec_Array_JSObject = __bjs_arrayCodec(__bjs_codec_JSObject); + const __bjs_codec_Optional_JSObject = __bjs_optionalCodec(__bjs_codec_JSObject); + const __bjs_codec_Array_Optional_JSObject = __bjs_arrayCodec(__bjs_codec_Optional_JSObject); + const __bjs_codec_Array_Array_JSObject = __bjs_arrayCodec(__bjs_codec_Array_JSObject); + const __bjs_codec_Optional_Array_String = __bjs_optionalCodec(__bjs_codec_Array_String); + + const __bjs_createStructHelpers_M10TestModuleT5Point = () => ({ lower: (value) => { f64Stack.push(value.x); f64Stack.push(value.y); @@ -132,12 +563,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_Point"] = function(objectId) { - structHelpers.Point.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT5Point.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Point"] = function() { - const value = structHelpers.Point.lift(); + const value = structHelpers.M10TestModuleT5Point.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -264,18 +697,7 @@ export async function createInstantiator(options, swift) { } TestModule["bjs_importProcessNumbers"] = function bjs_importProcessNumbers() { try { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const f64 = f64Stack.pop(); - arrayResult.push(f64); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Double.lift(); imports.importProcessNumbers(arrayResult); } catch (error) { setException(error); @@ -284,82 +706,34 @@ export async function createInstantiator(options, swift) { TestModule["bjs_importGetNumbers"] = function bjs_importGetNumbers() { try { let ret = imports.importGetNumbers(); - for (const elem of ret) { - f64Stack.push(elem); - } - i32Stack.push(ret.length); + __bjs_codec_Array_Double.lower(ret); } catch (error) { setException(error); } } TestModule["bjs_importTransformNumbers"] = function bjs_importTransformNumbers() { try { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const f64 = f64Stack.pop(); - arrayResult.push(f64); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Double.lift(); let ret = imports.importTransformNumbers(arrayResult); - for (const elem of ret) { - f64Stack.push(elem); - } - i32Stack.push(ret.length); + __bjs_codec_Array_Double.lower(ret); } catch (error) { setException(error); } } TestModule["bjs_importProcessStrings"] = function bjs_importProcessStrings() { try { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const string = strStack.pop(); - arrayResult.push(string); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_String.lift(); let ret = imports.importProcessStrings(arrayResult); - for (const elem of ret) { - const bytes = textEncoder.encode(elem); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(ret.length); + __bjs_codec_Array_String.lower(ret); } catch (error) { setException(error); } } TestModule["bjs_importProcessBooleans"] = function bjs_importProcessBooleans() { try { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const bool = i32Stack.pop() !== 0; - arrayResult.push(bool); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Bool.lift(); let ret = imports.importProcessBooleans(arrayResult); - for (const elem of ret) { - i32Stack.push(elem ? 1 : 0); - } - i32Stack.push(ret.length); + __bjs_codec_Array_Bool.lower(ret); } catch (error) { setException(error); } @@ -442,758 +816,192 @@ export async function createInstantiator(options, swift) { } constructor(nums, strs) { - for (const elem of nums) { - i32Stack.push((elem | 0)); - } - i32Stack.push(nums.length); - for (const elem1 of strs) { - const bytes = textEncoder.encode(elem1); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(strs.length); + __bjs_codec_Array_Int.lower(nums); + __bjs_codec_Array_String.lower(strs); const ret = instance.exports.bjs_MultiArrayContainer_init(); return MultiArrayContainer.__construct(ret); } get numbers() { instance.exports.bjs_MultiArrayContainer_numbers_get(this.pointer); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Int.lift(); return arrayResult; } get strings() { instance.exports.bjs_MultiArrayContainer_strings_get(this.pointer); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const string = strStack.pop(); - arrayResult.push(string); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_String.lift(); return arrayResult; } } - const PointHelpers = __bjs_createPointHelpers(); - structHelpers.Point = PointHelpers; + const __bjs_helpers_M10TestModuleT5Point = __bjs_createStructHelpers_M10TestModuleT5Point(); + structHelpers.M10TestModuleT5Point = __bjs_helpers_M10TestModuleT5Point; const exports = { processIntArray: function bjs_processIntArray(values) { - for (const elem of values) { - i32Stack.push((elem | 0)); - } - i32Stack.push(values.length); + __bjs_codec_Array_Int.lower(values); instance.exports.bjs_processIntArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Int.lift(); return arrayResult; }, processStringArray: function bjs_processStringArray(values) { - for (const elem of values) { - const bytes = textEncoder.encode(elem); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(values.length); + __bjs_codec_Array_String.lower(values); instance.exports.bjs_processStringArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const string = strStack.pop(); - arrayResult.push(string); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_String.lift(); return arrayResult; }, processDoubleArray: function bjs_processDoubleArray(values) { - for (const elem of values) { - f64Stack.push(elem); - } - i32Stack.push(values.length); + __bjs_codec_Array_Double.lower(values); instance.exports.bjs_processDoubleArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const f64 = f64Stack.pop(); - arrayResult.push(f64); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Double.lift(); return arrayResult; }, processBoolArray: function bjs_processBoolArray(values) { - for (const elem of values) { - i32Stack.push(elem ? 1 : 0); - } - i32Stack.push(values.length); + __bjs_codec_Array_Bool.lower(values); instance.exports.bjs_processBoolArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const bool = i32Stack.pop() !== 0; - arrayResult.push(bool); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Bool.lift(); return arrayResult; }, processPointArray: function bjs_processPointArray(points) { - for (const elem of points) { - structHelpers.Point.lower(elem); - } - i32Stack.push(points.length); + __bjs_codec_Array_M10TestModuleT5Point.lower(points); instance.exports.bjs_processPointArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const struct = structHelpers.Point.lift(); - arrayResult.push(struct); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT5Point.lift(); return arrayResult; }, processDirectionArray: function bjs_processDirectionArray(directions) { - for (const elem of directions) { - i32Stack.push((elem | 0)); - } - i32Stack.push(directions.length); + __bjs_codec_Array_M10TestModuleT9Direction.lower(directions); instance.exports.bjs_processDirectionArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const caseId = i32Stack.pop(); - arrayResult.push(caseId); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT9Direction.lift(); return arrayResult; }, processStatusArray: function bjs_processStatusArray(statuses) { - for (const elem of statuses) { - i32Stack.push((elem | 0)); - } - i32Stack.push(statuses.length); + __bjs_codec_Array_M10TestModuleT6Status.lower(statuses); instance.exports.bjs_processStatusArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const rawValue = i32Stack.pop(); - arrayResult.push(rawValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT6Status.lift(); return arrayResult; }, sumIntArray: function bjs_sumIntArray(values) { - for (const elem of values) { - i32Stack.push((elem | 0)); - } - i32Stack.push(values.length); + __bjs_codec_Array_Int.lower(values); const ret = instance.exports.bjs_sumIntArray(); return ret; }, findFirstPoint: function bjs_findFirstPoint(points, matching) { - for (const elem of points) { - structHelpers.Point.lower(elem); - } - i32Stack.push(points.length); + __bjs_codec_Array_M10TestModuleT5Point.lower(points); const matchingBytes = textEncoder.encode(matching); const matchingId = swift.memory.retain(matchingBytes); instance.exports.bjs_findFirstPoint(matchingId, matchingBytes.length); - const structValue = structHelpers.Point.lift(); + const structValue = structHelpers.M10TestModuleT5Point.lift(); return structValue; }, processUnsafeRawPointerArray: function bjs_processUnsafeRawPointerArray(values) { - for (const elem of values) { - ptrStack.push((elem | 0)); - } - i32Stack.push(values.length); + __bjs_codec_Array_Surp.lower(values); instance.exports.bjs_processUnsafeRawPointerArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const pointer = ptrStack.pop(); - arrayResult.push(pointer); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Surp.lift(); return arrayResult; }, processUnsafeMutableRawPointerArray: function bjs_processUnsafeMutableRawPointerArray(values) { - for (const elem of values) { - ptrStack.push((elem | 0)); - } - i32Stack.push(values.length); + __bjs_codec_Array_Sumrp.lower(values); instance.exports.bjs_processUnsafeMutableRawPointerArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const pointer = ptrStack.pop(); - arrayResult.push(pointer); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Sumrp.lift(); return arrayResult; }, processOpaquePointerArray: function bjs_processOpaquePointerArray(values) { - for (const elem of values) { - ptrStack.push((elem | 0)); - } - i32Stack.push(values.length); + __bjs_codec_Array_Sop.lower(values); instance.exports.bjs_processOpaquePointerArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const pointer = ptrStack.pop(); - arrayResult.push(pointer); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Sop.lift(); return arrayResult; }, processOptionalIntArray: function bjs_processOptionalIntArray(values) { - for (const elem of values) { - const isSome = elem != null ? 1 : 0; - if (isSome) { - i32Stack.push((elem | 0)); - } - i32Stack.push(isSome); - } - i32Stack.push(values.length); + __bjs_codec_Array_Optional_Int.lower(values); instance.exports.bjs_processOptionalIntArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const isSome1 = i32Stack.pop(); - let optValue; - if (isSome1 === 0) { - optValue = null; - } else { - const int = i32Stack.pop(); - optValue = int; - } - arrayResult.push(optValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Optional_Int.lift(); return arrayResult; }, processOptionalStringArray: function bjs_processOptionalStringArray(values) { - for (const elem of values) { - const isSome = elem != null ? 1 : 0; - if (isSome) { - const bytes = textEncoder.encode(elem); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(isSome); - } - i32Stack.push(values.length); + __bjs_codec_Array_Optional_String.lower(values); instance.exports.bjs_processOptionalStringArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const isSome1 = i32Stack.pop(); - let optValue; - if (isSome1 === 0) { - optValue = null; - } else { - const string = strStack.pop(); - optValue = string; - } - arrayResult.push(optValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Optional_String.lift(); return arrayResult; }, processOptionalArray: function bjs_processOptionalArray(values) { - const isSome = values != null; - if (isSome) { - for (const elem of values) { - i32Stack.push((elem | 0)); - } - i32Stack.push(values.length); - } - i32Stack.push(+isSome); + __bjs_codec_Optional_Array_Int.lower(values); instance.exports.bjs_processOptionalArray(); - const isSome1 = i32Stack.pop(); - let optResult; - if (isSome1) { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } - optResult = arrayResult; - } else { - optResult = null; - } - return optResult; + const optValue = __bjs_codec_Optional_Array_Int.lift(); + return optValue; }, processOptionalPointArray: function bjs_processOptionalPointArray(points) { - for (const elem of points) { - const isSome = elem != null ? 1 : 0; - if (isSome) { - structHelpers.Point.lower(elem); - } - i32Stack.push(isSome); - } - i32Stack.push(points.length); + __bjs_codec_Array_Optional_M10TestModuleT5Point.lower(points); instance.exports.bjs_processOptionalPointArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const isSome1 = i32Stack.pop(); - let optValue; - if (isSome1 === 0) { - optValue = null; - } else { - const struct = structHelpers.Point.lift(); - optValue = struct; - } - arrayResult.push(optValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Optional_M10TestModuleT5Point.lift(); return arrayResult; }, processOptionalDirectionArray: function bjs_processOptionalDirectionArray(directions) { - for (const elem of directions) { - const isSome = elem != null ? 1 : 0; - if (isSome) { - i32Stack.push((elem | 0)); - } - i32Stack.push(isSome); - } - i32Stack.push(directions.length); + __bjs_codec_Array_Optional_M10TestModuleT9Direction.lower(directions); instance.exports.bjs_processOptionalDirectionArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const isSome1 = i32Stack.pop(); - let optValue; - if (isSome1 === 0) { - optValue = null; - } else { - const caseId = i32Stack.pop(); - optValue = caseId; - } - arrayResult.push(optValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Optional_M10TestModuleT9Direction.lift(); return arrayResult; }, processOptionalStatusArray: function bjs_processOptionalStatusArray(statuses) { - for (const elem of statuses) { - const isSome = elem != null ? 1 : 0; - if (isSome) { - i32Stack.push((elem | 0)); - } - i32Stack.push(isSome); - } - i32Stack.push(statuses.length); + __bjs_codec_Array_Optional_M10TestModuleT6Status.lower(statuses); instance.exports.bjs_processOptionalStatusArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const isSome1 = i32Stack.pop(); - let optValue; - if (isSome1 === 0) { - optValue = null; - } else { - const rawValue = i32Stack.pop(); - optValue = rawValue; - } - arrayResult.push(optValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Optional_M10TestModuleT6Status.lift(); return arrayResult; }, processNestedIntArray: function bjs_processNestedIntArray(values) { - for (const elem of values) { - for (const elem1 of elem) { - i32Stack.push((elem1 | 0)); - } - i32Stack.push(elem.length); - } - i32Stack.push(values.length); + __bjs_codec_Array_Array_Int.lower(values); instance.exports.bjs_processNestedIntArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const arrayLen1 = i32Stack.pop(); - let arrayResult1; - if (arrayLen1 === -1) { - arrayResult1 = taStack.pop(); - } else { - arrayResult1 = []; - for (let i1 = 0; i1 < arrayLen1; i1++) { - const int = i32Stack.pop(); - arrayResult1.push(int); - } - arrayResult1.reverse(); - } - arrayResult.push(arrayResult1); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Array_Int.lift(); return arrayResult; }, processNestedStringArray: function bjs_processNestedStringArray(values) { - for (const elem of values) { - for (const elem1 of elem) { - const bytes = textEncoder.encode(elem1); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(elem.length); - } - i32Stack.push(values.length); + __bjs_codec_Array_Array_String.lower(values); instance.exports.bjs_processNestedStringArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const arrayLen1 = i32Stack.pop(); - let arrayResult1; - if (arrayLen1 === -1) { - arrayResult1 = taStack.pop(); - } else { - arrayResult1 = []; - for (let i1 = 0; i1 < arrayLen1; i1++) { - const string = strStack.pop(); - arrayResult1.push(string); - } - arrayResult1.reverse(); - } - arrayResult.push(arrayResult1); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Array_String.lift(); return arrayResult; }, processNestedPointArray: function bjs_processNestedPointArray(points) { - for (const elem of points) { - for (const elem1 of elem) { - structHelpers.Point.lower(elem1); - } - i32Stack.push(elem.length); - } - i32Stack.push(points.length); + __bjs_codec_Array_Array_M10TestModuleT5Point.lower(points); instance.exports.bjs_processNestedPointArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const arrayLen1 = i32Stack.pop(); - let arrayResult1; - if (arrayLen1 === -1) { - arrayResult1 = taStack.pop(); - } else { - arrayResult1 = []; - for (let i1 = 0; i1 < arrayLen1; i1++) { - const struct = structHelpers.Point.lift(); - arrayResult1.push(struct); - } - arrayResult1.reverse(); - } - arrayResult.push(arrayResult1); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Array_M10TestModuleT5Point.lift(); return arrayResult; }, processItemArray: function bjs_processItemArray(items) { - for (const elem of items) { - ptrStack.push(elem.pointer); - } - i32Stack.push(items.length); + __bjs_codec_Array_M10TestModuleT4Item.lower(items); instance.exports.bjs_processItemArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const ptr = ptrStack.pop(); - const obj = Item.__construct(ptr); - arrayResult.push(obj); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT4Item.lift(); return arrayResult; }, processNestedItemArray: function bjs_processNestedItemArray(items) { - for (const elem of items) { - for (const elem1 of elem) { - ptrStack.push(elem1.pointer); - } - i32Stack.push(elem.length); - } - i32Stack.push(items.length); + __bjs_codec_Array_Array_M10TestModuleT4Item.lower(items); instance.exports.bjs_processNestedItemArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const arrayLen1 = i32Stack.pop(); - let arrayResult1; - if (arrayLen1 === -1) { - arrayResult1 = taStack.pop(); - } else { - arrayResult1 = []; - for (let i1 = 0; i1 < arrayLen1; i1++) { - const ptr = ptrStack.pop(); - const obj = Item.__construct(ptr); - arrayResult1.push(obj); - } - arrayResult1.reverse(); - } - arrayResult.push(arrayResult1); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Array_M10TestModuleT4Item.lift(); return arrayResult; }, processJSObjectArray: function bjs_processJSObjectArray(objects) { - for (const elem of objects) { - const objId = swift.memory.retain(elem); - i32Stack.push(objId); - } - i32Stack.push(objects.length); + __bjs_codec_Array_JSObject.lower(objects); instance.exports.bjs_processJSObjectArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const objId1 = i32Stack.pop(); - const obj = swift.memory.getObject(objId1); - swift.memory.release(objId1); - arrayResult.push(obj); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_JSObject.lift(); return arrayResult; }, processOptionalJSObjectArray: function bjs_processOptionalJSObjectArray(objects) { - for (const elem of objects) { - const isSome = elem != null ? 1 : 0; - if (isSome) { - const objId = swift.memory.retain(elem); - i32Stack.push(objId); - } - i32Stack.push(isSome); - } - i32Stack.push(objects.length); + __bjs_codec_Array_Optional_JSObject.lower(objects); instance.exports.bjs_processOptionalJSObjectArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const isSome1 = i32Stack.pop(); - let optValue; - if (isSome1 === 0) { - optValue = null; - } else { - const objId1 = i32Stack.pop(); - const obj = swift.memory.getObject(objId1); - swift.memory.release(objId1); - optValue = obj; - } - arrayResult.push(optValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Optional_JSObject.lift(); return arrayResult; }, processNestedJSObjectArray: function bjs_processNestedJSObjectArray(objects) { - for (const elem of objects) { - for (const elem1 of elem) { - const objId = swift.memory.retain(elem1); - i32Stack.push(objId); - } - i32Stack.push(elem.length); - } - i32Stack.push(objects.length); + __bjs_codec_Array_Array_JSObject.lower(objects); instance.exports.bjs_processNestedJSObjectArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const arrayLen1 = i32Stack.pop(); - let arrayResult1; - if (arrayLen1 === -1) { - arrayResult1 = taStack.pop(); - } else { - arrayResult1 = []; - for (let i1 = 0; i1 < arrayLen1; i1++) { - const objId1 = i32Stack.pop(); - const obj = swift.memory.getObject(objId1); - swift.memory.release(objId1); - arrayResult1.push(obj); - } - arrayResult1.reverse(); - } - arrayResult.push(arrayResult1); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Array_JSObject.lift(); return arrayResult; }, multiArrayParams: function bjs_multiArrayParams(nums, strs) { - for (const elem of nums) { - i32Stack.push((elem | 0)); - } - i32Stack.push(nums.length); - for (const elem1 of strs) { - const bytes = textEncoder.encode(elem1); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(strs.length); + __bjs_codec_Array_Int.lower(nums); + __bjs_codec_Array_String.lower(strs); const ret = instance.exports.bjs_multiArrayParams(); return ret; }, multiOptionalArrayParams: function bjs_multiOptionalArrayParams(a, b) { - const isSome = a != null; - if (isSome) { - for (const elem of a) { - i32Stack.push((elem | 0)); - } - i32Stack.push(a.length); - } - i32Stack.push(+isSome); - const isSome1 = b != null; - if (isSome1) { - for (const elem1 of b) { - const bytes = textEncoder.encode(elem1); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(b.length); - } - i32Stack.push(+isSome1); + __bjs_codec_Optional_Array_Int.lower(a); + __bjs_codec_Optional_Array_String.lower(b); const ret = instance.exports.bjs_multiOptionalArrayParams(); return ret; }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.js index 9f2faf589..c025cf4f0 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.js @@ -41,6 +41,240 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + function __bjs_jsValueLower(value) { let kind; let payload1; @@ -130,7 +364,31 @@ export async function createInstantiator(options, swift) { return jsValue; } - const __bjs_createAsyncPointHelpers = () => ({ + const __bjs_codec_M10TestModuleT10AsyncPoint = { + lower: (v) => { + structHelpers.M10TestModuleT10AsyncPoint.lower(v); + }, + lift: () => { + const struct = structHelpers.M10TestModuleT10AsyncPoint.lift(); + return struct; + }, + }; + const __bjs_codec_Optional_M10TestModuleT10AsyncPoint = __bjs_optionalCodec(__bjs_codec_M10TestModuleT10AsyncPoint); + const __bjs_codec_Array_M10TestModuleT10AsyncPoint = __bjs_arrayCodec(__bjs_codec_M10TestModuleT10AsyncPoint); + const __bjs_codec_M10TestModuleT14AsyncDirection = { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const caseId = i32Stack.pop(); + return caseId; + }, + }; + const __bjs_codec_Array_M10TestModuleT14AsyncDirection = __bjs_arrayCodec(__bjs_codec_M10TestModuleT14AsyncDirection); + const __bjs_codec_Dict_M10TestModuleT10AsyncPoint = __bjs_dictCodec(__bjs_codec_M10TestModuleT10AsyncPoint); + const __bjs_codec_Dict_M10TestModuleT14AsyncDirection = __bjs_dictCodec(__bjs_codec_M10TestModuleT14AsyncDirection); + + const __bjs_createStructHelpers_M10TestModuleT10AsyncPoint = () => ({ lower: (value) => { i32Stack.push((value.x | 0)); i32Stack.push((value.y | 0)); @@ -217,12 +475,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_AsyncPoint"] = function(objectId) { - structHelpers.AsyncPoint.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT10AsyncPoint.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_AsyncPoint"] = function() { - const value = structHelpers.AsyncPoint.lift(); + const value = structHelpers.M10TestModuleT10AsyncPoint.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -282,7 +542,7 @@ export async function createInstantiator(options, swift) { } bjs["promise_resolve_TestModule_10AsyncPointV"] = function(promise) { try { - const structValue = structHelpers.AsyncPoint.lift(); + const structValue = structHelpers.M10TestModuleT10AsyncPoint.lift(); swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(structValue); } catch (error) { setException(error); @@ -324,34 +584,17 @@ export async function createInstantiator(options, swift) { setException(error); } } - bjs["promise_resolve_TestModule_Sq10AsyncPointV"] = function(promise, value) { + bjs["promise_resolve_TestModule_Sq10AsyncPointV"] = function(promise) { try { - let optResult; - if (value) { - const struct = structHelpers.AsyncPoint.lift(); - optResult = struct; - } else { - optResult = null; - } - swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(optResult); + const optValue = __bjs_codec_Optional_M10TestModuleT10AsyncPoint.lift(); + swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(optValue); } catch (error) { setException(error); } } bjs["promise_resolve_TestModule_Sa10AsyncPointV"] = function(promise) { try { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const struct = structHelpers.AsyncPoint.lift(); - arrayResult.push(struct); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT10AsyncPoint.lift(); swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(arrayResult); } catch (error) { setException(error); @@ -359,18 +602,7 @@ export async function createInstantiator(options, swift) { } bjs["promise_resolve_TestModule_Sa14AsyncDirectionO"] = function(promise) { try { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const caseId = i32Stack.pop(); - arrayResult.push(caseId); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT14AsyncDirection.lift(); swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(arrayResult); } catch (error) { setException(error); @@ -378,13 +610,7 @@ export async function createInstantiator(options, swift) { } bjs["promise_resolve_TestModule_SD10AsyncPointV"] = function(promise) { try { - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const struct = structHelpers.AsyncPoint.lift(); - const string = strStack.pop(); - dictResult[string] = struct; - } + const dictResult = __bjs_codec_Dict_M10TestModuleT10AsyncPoint.lift(); swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(dictResult); } catch (error) { setException(error); @@ -392,13 +618,7 @@ export async function createInstantiator(options, swift) { } bjs["promise_resolve_TestModule_SD14AsyncDirectionO"] = function(promise) { try { - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const caseId = i32Stack.pop(); - const string = strStack.pop(); - dictResult[string] = caseId; - } + const dictResult = __bjs_codec_Dict_M10TestModuleT14AsyncDirection.lift(); swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(dictResult); } catch (error) { setException(error); @@ -516,8 +736,8 @@ export async function createInstantiator(options, swift) { /** @param {WebAssembly.Instance} instance */ createExports: (instance) => { const js = swift.memory.heap; - const AsyncPointHelpers = __bjs_createAsyncPointHelpers(); - structHelpers.AsyncPoint = AsyncPointHelpers; + const __bjs_helpers_M10TestModuleT10AsyncPoint = __bjs_createStructHelpers_M10TestModuleT10AsyncPoint(); + structHelpers.M10TestModuleT10AsyncPoint = __bjs_helpers_M10TestModuleT10AsyncPoint; const exports = { asyncReturnVoid: function bjs_asyncReturnVoid() { @@ -565,14 +785,14 @@ export async function createInstantiator(options, swift) { return ret1; }, asyncRoundTripStruct: function bjs_asyncRoundTripStruct(v) { - structHelpers.AsyncPoint.lower(v); + structHelpers.M10TestModuleT10AsyncPoint.lower(v); const ret = instance.exports.bjs_asyncRoundTripStruct(); const ret1 = swift.memory.getObject(ret); swift.memory.release(ret); return ret1; }, asyncRoundTripStructThrows: function bjs_asyncRoundTripStructThrows(v) { - structHelpers.AsyncPoint.lower(v); + structHelpers.M10TestModuleT10AsyncPoint.lower(v); const ret = instance.exports.bjs_asyncRoundTripStructThrows(); const ret1 = swift.memory.getObject(ret); swift.memory.release(ret); @@ -597,8 +817,8 @@ export async function createInstantiator(options, swift) { return ret1; }, asyncCombineStructs: function bjs_asyncCombineStructs(a, b) { - structHelpers.AsyncPoint.lower(a); - structHelpers.AsyncPoint.lower(b); + structHelpers.M10TestModuleT10AsyncPoint.lower(a); + structHelpers.M10TestModuleT10AsyncPoint.lower(b); const ret = instance.exports.bjs_asyncCombineStructs(); const ret1 = swift.memory.getObject(ret); swift.memory.release(ret); @@ -643,63 +863,35 @@ export async function createInstantiator(options, swift) { return ret1; }, asyncRoundTripOptionalStruct: function bjs_asyncRoundTripOptionalStruct(v) { - const isSome = v != null; - if (isSome) { - structHelpers.AsyncPoint.lower(v); - } - i32Stack.push(+isSome); + __bjs_codec_Optional_M10TestModuleT10AsyncPoint.lower(v); const ret = instance.exports.bjs_asyncRoundTripOptionalStruct(); const ret1 = swift.memory.getObject(ret); swift.memory.release(ret); return ret1; }, asyncRoundTripStructArray: function bjs_asyncRoundTripStructArray(v) { - for (const elem of v) { - structHelpers.AsyncPoint.lower(elem); - } - i32Stack.push(v.length); + __bjs_codec_Array_M10TestModuleT10AsyncPoint.lower(v); const ret = instance.exports.bjs_asyncRoundTripStructArray(); const ret1 = swift.memory.getObject(ret); swift.memory.release(ret); return ret1; }, asyncRoundTripEnumArray: function bjs_asyncRoundTripEnumArray(v) { - for (const elem of v) { - i32Stack.push((elem | 0)); - } - i32Stack.push(v.length); + __bjs_codec_Array_M10TestModuleT14AsyncDirection.lower(v); const ret = instance.exports.bjs_asyncRoundTripEnumArray(); const ret1 = swift.memory.getObject(ret); swift.memory.release(ret); return ret1; }, asyncRoundTripStructDictionary: function bjs_asyncRoundTripStructDictionary(v) { - const entries = Object.entries(v); - for (const entry of entries) { - const [key, value] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - structHelpers.AsyncPoint.lower(value); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_M10TestModuleT10AsyncPoint.lower(v); const ret = instance.exports.bjs_asyncRoundTripStructDictionary(); const ret1 = swift.memory.getObject(ret); swift.memory.release(ret); return ret1; }, asyncRoundTripEnumDictionary: function bjs_asyncRoundTripEnumDictionary(v) { - const entries = Object.entries(v); - for (const entry of entries) { - const [key, value] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - i32Stack.push((value | 0)); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_M10TestModuleT14AsyncDirection.lower(v); const ret = instance.exports.bjs_asyncRoundTripEnumDictionary(); const ret1 = swift.memory.getObject(ret); swift.memory.release(ret); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncAssociatedValueEnum.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncAssociatedValueEnum.js index 98c0aff46..49b2ff88b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncAssociatedValueEnum.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncAssociatedValueEnum.js @@ -127,7 +127,7 @@ export async function createInstantiator(options, swift) { return jsValue; } - const __bjs_createAsyncPayloadResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT18AsyncPayloadResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -239,6 +239,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -248,7 +250,7 @@ export async function createInstantiator(options, swift) { } bjs["promise_resolve_TestModule_18AsyncPayloadResultO"] = function(promise, value) { try { - const enumValue = enumHelpers.AsyncPayloadResult.lift(value); + const enumValue = enumHelpers.M10TestModuleT18AsyncPayloadResult.lift(value); swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(enumValue); } catch (error) { setException(error); @@ -258,7 +260,7 @@ export async function createInstantiator(options, swift) { try { let optResult; if (valueIsSome) { - const enumValue = enumHelpers.AsyncPayloadResult.lift(valueCaseId); + const enumValue = enumHelpers.M10TestModuleT18AsyncPayloadResult.lift(valueCaseId); optResult = enumValue; } else { optResult = null; @@ -380,12 +382,12 @@ export async function createInstantiator(options, swift) { /** @param {WebAssembly.Instance} instance */ createExports: (instance) => { const js = swift.memory.heap; - const AsyncPayloadResultHelpers = __bjs_createAsyncPayloadResultValuesHelpers(); - enumHelpers.AsyncPayloadResult = AsyncPayloadResultHelpers; + const __bjs_helpers_M10TestModuleT18AsyncPayloadResult = __bjs_createEnumHelpers_M10TestModuleT18AsyncPayloadResult(); + enumHelpers.M10TestModuleT18AsyncPayloadResult = __bjs_helpers_M10TestModuleT18AsyncPayloadResult; const exports = { asyncRoundTripAssociatedValueEnum: function bjs_asyncRoundTripAssociatedValueEnum(value) { - const valueCaseId = enumHelpers.AsyncPayloadResult.lower(value); + const valueCaseId = enumHelpers.M10TestModuleT18AsyncPayloadResult.lower(value); const ret = instance.exports.bjs_asyncRoundTripAssociatedValueEnum(valueCaseId); const ret1 = swift.memory.getObject(ret); swift.memory.release(ret); @@ -395,7 +397,7 @@ export async function createInstantiator(options, swift) { const isSome = value != null; let result; if (isSome) { - const valueCaseId = enumHelpers.AsyncPayloadResult.lower(value); + const valueCaseId = enumHelpers.M10TestModuleT18AsyncPayloadResult.lower(value); result = valueCaseId; } else { result = 0; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncImport.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncImport.js index fa50b23f2..96c0d11e8 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncImport.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncImport.js @@ -221,6 +221,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncStaticImport.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncStaticImport.js index c359886b3..eea340c35 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncStaticImport.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncStaticImport.js @@ -153,6 +153,7 @@ export async function createInstantiator(options, swift) { addImports: (importObject, importsContext) => { bjs = {}; importObject["bjs"] = bjs; + const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { tmpRetString = decodeString(ptr, len); } @@ -220,6 +221,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ClassWithNestedTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ClassWithNestedTypes.js index 272bb8c49..ecdb0b059 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ClassWithNestedTypes.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ClassWithNestedTypes.js @@ -36,7 +36,7 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createAccount_CredentialsHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT7AccountT11Credentials = () => ({ lower: (value) => { const bytes = textEncoder.encode(value.token); const id = swift.memory.retain(bytes); @@ -124,12 +124,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_Account_Credentials"] = function(objectId) { - structHelpers.Account_Credentials.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT7AccountT11Credentials.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Account_Credentials"] = function() { - const value = structHelpers.Account_Credentials.lift(); + const value = structHelpers.M10TestModuleT7AccountT11Credentials.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -342,8 +344,8 @@ export async function createInstantiator(options, swift) { return ret; } } - const Account_CredentialsHelpers = __bjs_createAccount_CredentialsHelpers(); - structHelpers.Account_Credentials = Account_CredentialsHelpers; + const __bjs_helpers_M10TestModuleT7AccountT11Credentials = __bjs_createStructHelpers_M10TestModuleT7AccountT11Credentials(); + structHelpers.M10TestModuleT7AccountT11Credentials = __bjs_helpers_M10TestModuleT7AccountT11Credentials; const exports = { Account: Object.assign(Account, { @@ -353,7 +355,7 @@ export async function createInstantiator(options, swift) { const tokenBytes = textEncoder.encode(token); const tokenId = swift.memory.retain(tokenBytes); instance.exports.bjs_Account_Credentials_init(tokenId, tokenBytes.length); - const structValue = structHelpers.Account_Credentials.lift(); + const structValue = structHelpers.M10TestModuleT7AccountT11Credentials.lift(); return structValue; }, get maxLength() { @@ -362,7 +364,7 @@ export async function createInstantiator(options, swift) { }, empty: function() { instance.exports.bjs_Account_Credentials_static_empty(); - const structValue = structHelpers.Account_Credentials.lift(); + const structValue = structHelpers.M10TestModuleT7AccountT11Credentials.lift(); return structValue; }, }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.js index ba2b7cc77..fe1fa7b54 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.js @@ -37,7 +37,345 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createConfigHelpers = () => ({ + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_M10TestModuleT6Config = { + lower: (v) => { + structHelpers.M10TestModuleT6Config.lower(v); + }, + lift: () => { + const struct = structHelpers.M10TestModuleT6Config.lift(); + return struct; + }, + }; + const __bjs_codec_Optional_M10TestModuleT6Config = __bjs_optionalCodec(__bjs_codec_M10TestModuleT6Config); + const __bjs_codec_Array_Int = __bjs_arrayCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_Array_String = __bjs_arrayCodec(__bjs_stringCodec); + const __bjs_codec_Array_Double = __bjs_arrayCodec(__bjs_primitiveCodecs.Double); + const __bjs_codec_Array_Bool = __bjs_arrayCodec(__bjs_primitiveCodecs.Bool); + + const __bjs_createStructHelpers_M10TestModuleT6Config = () => ({ lower: (value) => { const bytes = textEncoder.encode(value.name); const id = swift.memory.retain(bytes); @@ -53,7 +391,7 @@ export async function createInstantiator(options, swift) { return { name: string, value: int, enabled: bool }; } }); - const __bjs_createMathOperationsHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT14MathOperations = () => ({ lower: (value) => { f64Stack.push(value.baseValue); }, @@ -61,12 +399,12 @@ export async function createInstantiator(options, swift) { const f64 = f64Stack.pop(); const instance1 = { baseValue: f64 }; instance1.add = function(a, b = 10.0) { - structHelpers.MathOperations.lower(this); + structHelpers.M10TestModuleT14MathOperations.lower(this); const ret = instance.exports.bjs_MathOperations_add(a, b); return ret; }.bind(instance1); instance1.multiply = function(a, b) { - structHelpers.MathOperations.lower(this); + structHelpers.M10TestModuleT14MathOperations.lower(this); const ret1 = instance.exports.bjs_MathOperations_multiply(a, b); return ret1; }.bind(instance1); @@ -149,19 +487,21 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_Config"] = function(objectId) { - structHelpers.Config.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT6Config.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Config"] = function() { - const value = structHelpers.Config.lift(); + const value = structHelpers.M10TestModuleT6Config.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_MathOperations"] = function(objectId) { - structHelpers.MathOperations.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT14MathOperations.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_MathOperations"] = function() { - const value = structHelpers.MathOperations.lift(); + const value = structHelpers.M10TestModuleT14MathOperations.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -449,11 +789,11 @@ export async function createInstantiator(options, swift) { instance.exports.bjs_ConstructorDefaults_tag_set(this.pointer, +isSome, result, result1); } } - const ConfigHelpers = __bjs_createConfigHelpers(); - structHelpers.Config = ConfigHelpers; + const __bjs_helpers_M10TestModuleT6Config = __bjs_createStructHelpers_M10TestModuleT6Config(); + structHelpers.M10TestModuleT6Config = __bjs_helpers_M10TestModuleT6Config; - const MathOperationsHelpers = __bjs_createMathOperationsHelpers(); - structHelpers.MathOperations = MathOperationsHelpers; + const __bjs_helpers_M10TestModuleT14MathOperations = __bjs_createStructHelpers_M10TestModuleT14MathOperations(); + structHelpers.M10TestModuleT14MathOperations = __bjs_helpers_M10TestModuleT14MathOperations; const exports = { testStringDefault: function bjs_testStringDefault(message = "Hello World") { @@ -535,137 +875,51 @@ export async function createInstantiator(options, swift) { return EmptyGreeter.__construct(ret); }, testOptionalStructDefault: function bjs_testOptionalStructDefault(point = null) { - const isSome = point != null; - if (isSome) { - structHelpers.Config.lower(point); - } - i32Stack.push(+isSome); + __bjs_codec_Optional_M10TestModuleT6Config.lower(point); instance.exports.bjs_testOptionalStructDefault(); - const isSome1 = i32Stack.pop(); - const optResult = isSome1 ? structHelpers.Config.lift() : null; - return optResult; + const optValue = __bjs_codec_Optional_M10TestModuleT6Config.lift(); + return optValue; }, testOptionalStructWithValueDefault: function bjs_testOptionalStructWithValueDefault(point = { name: "default", value: 42, enabled: true }) { - const isSome = point != null; - if (isSome) { - structHelpers.Config.lower(point); - } - i32Stack.push(+isSome); + __bjs_codec_Optional_M10TestModuleT6Config.lower(point); instance.exports.bjs_testOptionalStructWithValueDefault(); - const isSome1 = i32Stack.pop(); - const optResult = isSome1 ? structHelpers.Config.lift() : null; - return optResult; + const optValue = __bjs_codec_Optional_M10TestModuleT6Config.lift(); + return optValue; }, testIntArrayDefault: function bjs_testIntArrayDefault(values = [1, 2, 3]) { - for (const elem of values) { - i32Stack.push((elem | 0)); - } - i32Stack.push(values.length); + __bjs_codec_Array_Int.lower(values); instance.exports.bjs_testIntArrayDefault(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Int.lift(); return arrayResult; }, testStringArrayDefault: function bjs_testStringArrayDefault(names = ["a", "b", "c"]) { - for (const elem of names) { - const bytes = textEncoder.encode(elem); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(names.length); + __bjs_codec_Array_String.lower(names); instance.exports.bjs_testStringArrayDefault(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const string = strStack.pop(); - arrayResult.push(string); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_String.lift(); return arrayResult; }, testDoubleArrayDefault: function bjs_testDoubleArrayDefault(values = [1.5, 2.5, 3.5]) { - for (const elem of values) { - f64Stack.push(elem); - } - i32Stack.push(values.length); + __bjs_codec_Array_Double.lower(values); instance.exports.bjs_testDoubleArrayDefault(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const f64 = f64Stack.pop(); - arrayResult.push(f64); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Double.lift(); return arrayResult; }, testBoolArrayDefault: function bjs_testBoolArrayDefault(flags = [true, false, true]) { - for (const elem of flags) { - i32Stack.push(elem ? 1 : 0); - } - i32Stack.push(flags.length); + __bjs_codec_Array_Bool.lower(flags); instance.exports.bjs_testBoolArrayDefault(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const bool = i32Stack.pop() !== 0; - arrayResult.push(bool); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Bool.lift(); return arrayResult; }, testEmptyArrayDefault: function bjs_testEmptyArrayDefault(items = []) { - for (const elem of items) { - i32Stack.push((elem | 0)); - } - i32Stack.push(items.length); + __bjs_codec_Array_Int.lower(items); instance.exports.bjs_testEmptyArrayDefault(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Int.lift(); return arrayResult; }, testMixedWithArrayDefault: function bjs_testMixedWithArrayDefault(name = "test", values = [10, 20, 30], enabled = true) { const nameBytes = textEncoder.encode(name); const nameId = swift.memory.retain(nameBytes); - for (const elem of values) { - i32Stack.push((elem | 0)); - } - i32Stack.push(values.length); + __bjs_codec_Array_Int.lower(values); instance.exports.bjs_testMixedWithArrayDefault(nameId, nameBytes.length, enabled); const ret = tmpRetString; tmpRetString = undefined; @@ -678,7 +932,7 @@ export async function createInstantiator(options, swift) { MathOperations: { init: function(baseValue = 0.0) { instance.exports.bjs_MathOperations_init(baseValue); - const structValue = structHelpers.MathOperations.lift(); + const structValue = structHelpers.M10TestModuleT14MathOperations.lift(); return structValue; }, subtract: function(a, b = 5.0) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DictionaryTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DictionaryTypes.js index d0ac5307f..8ccda3c19 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DictionaryTypes.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DictionaryTypes.js @@ -31,44 +31,363 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createCountersHelpers = () => ({ + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_Dict_Int = __bjs_dictCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_Dict_String = __bjs_dictCodec(__bjs_stringCodec); + const __bjs_codec_Optional_Dict_String = __bjs_optionalCodec(__bjs_codec_Dict_String); + const __bjs_codec_Array_Int = __bjs_arrayCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_Dict_Array_Int = __bjs_dictCodec(__bjs_codec_Array_Int); + const __bjs_codec_M10TestModuleT3Box = { + lower: (v) => { + ptrStack.push(v.pointer); + }, + lift: () => { + const ptr = ptrStack.pop(); + const obj = _exports['Box'].__construct(ptr); + return obj; + }, + }; + const __bjs_codec_Dict_M10TestModuleT3Box = __bjs_dictCodec(__bjs_codec_M10TestModuleT3Box); + const __bjs_codec_Optional_M10TestModuleT3Box = __bjs_optionalCodec(__bjs_codec_M10TestModuleT3Box); + const __bjs_codec_Dict_Optional_M10TestModuleT3Box = __bjs_dictCodec(__bjs_codec_Optional_M10TestModuleT3Box); + const __bjs_codec_Dict_Double = __bjs_dictCodec(__bjs_primitiveCodecs.Double); + const __bjs_codec_Optional_Int = __bjs_optionalCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_Dict_Optional_Int = __bjs_dictCodec(__bjs_codec_Optional_Int); + + const __bjs_createStructHelpers_M10TestModuleT8Counters = () => ({ lower: (value) => { const bytes = textEncoder.encode(value.name); const id = swift.memory.retain(bytes); i32Stack.push(bytes.length); i32Stack.push(id); - const entries = Object.entries(value.counts); - for (const entry of entries) { - const [key, value] = entry; - const bytes1 = textEncoder.encode(key); - const id1 = swift.memory.retain(bytes1); - i32Stack.push(bytes1.length); - i32Stack.push(id1); - const isSome = value != null ? 1 : 0; - if (isSome) { - i32Stack.push((value | 0)); - } - i32Stack.push(isSome); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_Optional_Int.lower(value.counts); }, lift: () => { - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const int = i32Stack.pop(); - optValue = int; - } - const string = strStack.pop(); - dictResult[string] = optValue; - } - const string1 = strStack.pop(); - return { name: string1, counts: dictResult }; + const dictResult = __bjs_codec_Dict_Optional_Int.lift(); + const string = strStack.pop(); + return { name: string, counts: dictResult }; } }); @@ -148,12 +467,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_Counters"] = function(objectId) { - structHelpers.Counters.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT8Counters.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Counters"] = function() { - const value = structHelpers.Counters.lift(); + const value = structHelpers.M10TestModuleT8Counters.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -262,24 +583,9 @@ export async function createInstantiator(options, swift) { const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_importMirrorDictionary"] = function bjs_importMirrorDictionary() { try { - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const f64 = f64Stack.pop(); - const string = strStack.pop(); - dictResult[string] = f64; - } + const dictResult = __bjs_codec_Dict_Double.lift(); let ret = imports.importMirrorDictionary(dictResult); - const entries = Object.entries(ret); - for (const entry of entries) { - const [key, value] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - f64Stack.push(value); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_Double.lower(ret); } catch (error) { setException(error); } @@ -356,160 +662,44 @@ export async function createInstantiator(options, swift) { } } - const CountersHelpers = __bjs_createCountersHelpers(); - structHelpers.Counters = CountersHelpers; + const __bjs_helpers_M10TestModuleT8Counters = __bjs_createStructHelpers_M10TestModuleT8Counters(); + structHelpers.M10TestModuleT8Counters = __bjs_helpers_M10TestModuleT8Counters; const exports = { mirrorDictionary: function bjs_mirrorDictionary(values) { - const entries = Object.entries(values); - for (const entry of entries) { - const [key, value] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - i32Stack.push((value | 0)); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_Int.lower(values); instance.exports.bjs_mirrorDictionary(); - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const int = i32Stack.pop(); - const string = strStack.pop(); - dictResult[string] = int; - } + const dictResult = __bjs_codec_Dict_Int.lift(); return dictResult; }, optionalDictionary: function bjs_optionalDictionary(values) { - const isSome = values != null; - if (isSome) { - const entries = Object.entries(values); - for (const entry of entries) { - const [key, value] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - const bytes1 = textEncoder.encode(value); - const id1 = swift.memory.retain(bytes1); - i32Stack.push(bytes1.length); - i32Stack.push(id1); - } - i32Stack.push(entries.length); - } - i32Stack.push(+isSome); + __bjs_codec_Optional_Dict_String.lower(values); instance.exports.bjs_optionalDictionary(); - const isSome1 = i32Stack.pop(); - let optResult; - if (isSome1) { - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const string = strStack.pop(); - const string1 = strStack.pop(); - dictResult[string1] = string; - } - optResult = dictResult; - } else { - optResult = null; - } - return optResult; + const optValue = __bjs_codec_Optional_Dict_String.lift(); + return optValue; }, nestedDictionary: function bjs_nestedDictionary(values) { - const entries = Object.entries(values); - for (const entry of entries) { - const [key, value] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - for (const elem of value) { - i32Stack.push((elem | 0)); - } - i32Stack.push(value.length); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_Array_Int.lower(values); instance.exports.bjs_nestedDictionary(); - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i1 = 0; i1 < arrayLen; i1++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } - const string = strStack.pop(); - dictResult[string] = arrayResult; - } + const dictResult = __bjs_codec_Dict_Array_Int.lift(); return dictResult; }, boxDictionary: function bjs_boxDictionary(boxes) { - const entries = Object.entries(boxes); - for (const entry of entries) { - const [key, value] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - ptrStack.push(value.pointer); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_M10TestModuleT3Box.lower(boxes); instance.exports.bjs_boxDictionary(); - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const ptr = ptrStack.pop(); - const obj = Box.__construct(ptr); - const string = strStack.pop(); - dictResult[string] = obj; - } + const dictResult = __bjs_codec_Dict_M10TestModuleT3Box.lift(); return dictResult; }, optionalBoxDictionary: function bjs_optionalBoxDictionary(boxes) { - const entries = Object.entries(boxes); - for (const entry of entries) { - const [key, value] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - const isSome = value != null ? 1 : 0; - if (isSome) { - ptrStack.push(value.pointer); - } - i32Stack.push(isSome); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_Optional_M10TestModuleT3Box.lower(boxes); instance.exports.bjs_optionalBoxDictionary(); - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const isSome1 = i32Stack.pop(); - let optValue; - if (isSome1 === 0) { - optValue = null; - } else { - const ptr = ptrStack.pop(); - const obj = Box.__construct(ptr); - optValue = obj; - } - const string = strStack.pop(); - dictResult[string] = optValue; - } + const dictResult = __bjs_codec_Dict_Optional_M10TestModuleT3Box.lift(); return dictResult; }, roundtripCounters: function bjs_roundtripCounters(counters) { - structHelpers.Counters.lower(counters); + structHelpers.M10TestModuleT8Counters.lower(counters); instance.exports.bjs_roundtripCounters(); - const structValue = structHelpers.Counters.lift(); + const structValue = structHelpers.M10TestModuleT8Counters.lift(); return structValue; }, Box, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DocComments.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DocComments.js index f29814675..6d23d394f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DocComments.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DocComments.js @@ -37,7 +37,7 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createPointHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT5Point = () => ({ lower: (value) => { f64Stack.push(value.x); f64Stack.push(value.y); @@ -124,12 +124,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_Point"] = function(objectId) { - structHelpers.Point.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT5Point.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Point"] = function() { - const value = structHelpers.Point.lift(); + const value = structHelpers.M10TestModuleT5Point.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -347,8 +349,8 @@ export async function createInstantiator(options, swift) { instance.exports.bjs_Greeter_name_set(this.pointer, valueId, valueBytes.length); } } - const PointHelpers = __bjs_createPointHelpers(); - structHelpers.Point = PointHelpers; + const __bjs_helpers_M10TestModuleT5Point = __bjs_createStructHelpers_M10TestModuleT5Point(); + structHelpers.M10TestModuleT5Point = __bjs_helpers_M10TestModuleT5Point; const exports = { greet: function bjs_greet(name, greeting = "Hello") { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAlias.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAlias.js index 42f3fd958..d8bc06fcf 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAlias.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAlias.js @@ -106,6 +106,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.js index 36683fd58..66f85760c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.js @@ -112,7 +112,401 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createPointHelpers = () => ({ + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_Optional_String = __bjs_optionalCodec(__bjs_stringCodec); + const __bjs_codec_Optional_Bool = __bjs_optionalCodec(__bjs_primitiveCodecs.Bool); + const __bjs_codec_Optional_Int = __bjs_optionalCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_M10TestModuleT9Precision = { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const rawValue = f32Stack.pop(); + return rawValue; + }, + }; + const __bjs_codec_Optional_M10TestModuleT9Precision = __bjs_optionalCodec(__bjs_codec_M10TestModuleT9Precision); + const __bjs_codec_M10TestModuleT17CardinalDirection = { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const caseId = i32Stack.pop(); + return caseId; + }, + }; + const __bjs_codec_Optional_M10TestModuleT17CardinalDirection = __bjs_optionalCodec(__bjs_codec_M10TestModuleT17CardinalDirection); + const __bjs_codec_Array_Int = __bjs_arrayCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_M10TestModuleT5Point = { + lower: (v) => { + structHelpers.M10TestModuleT5Point.lower(v); + }, + lift: () => { + const struct = structHelpers.M10TestModuleT5Point.lift(); + return struct; + }, + }; + const __bjs_codec_Optional_M10TestModuleT5Point = __bjs_optionalCodec(__bjs_codec_M10TestModuleT5Point); + const __bjs_codec_M10TestModuleT4User = { + lower: (v) => { + ptrStack.push(v.pointer); + }, + lift: () => { + const ptr = ptrStack.pop(); + const obj = _exports['User'].__construct(ptr); + return obj; + }, + }; + const __bjs_codec_Optional_M10TestModuleT4User = __bjs_optionalCodec(__bjs_codec_M10TestModuleT4User); + const __bjs_codec_JSObject = { + lower: (v) => { + const objId = swift.memory.retain(v); + i32Stack.push(objId); + }, + lift: () => { + const objId = i32Stack.pop(); + const obj = swift.memory.getObject(objId); + swift.memory.release(objId); + return obj; + }, + }; + const __bjs_codec_Optional_JSObject = __bjs_optionalCodec(__bjs_codec_JSObject); + const __bjs_codec_M10TestModuleT9APIResult = { + lower: (v) => { + const caseId = enumHelpers.M10TestModuleT9APIResult.lower(v); + i32Stack.push(caseId); + }, + lift: () => { + const enumValue = enumHelpers.M10TestModuleT9APIResult.lift(i32Stack.pop()); + return enumValue; + }, + }; + const __bjs_codec_Optional_M10TestModuleT9APIResult = __bjs_optionalCodec(__bjs_codec_M10TestModuleT9APIResult); + const __bjs_codec_Optional_Array_Int = __bjs_optionalCodec(__bjs_codec_Array_Int); + + const __bjs_createStructHelpers_M10TestModuleT5Point = () => ({ lower: (value) => { f64Stack.push(value.x); f64Stack.push(value.y); @@ -123,7 +517,7 @@ export async function createInstantiator(options, swift) { return { x: f641, y: f64 }; } }); - const __bjs_createAPIResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT9APIResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -184,7 +578,7 @@ export async function createInstantiator(options, swift) { } } }); - const __bjs_createComplexResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT13ComplexResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -286,7 +680,7 @@ export async function createInstantiator(options, swift) { } } }); - const __bjs_createResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT9UtilitiesT6Result = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -339,7 +733,7 @@ export async function createInstantiator(options, swift) { } } }); - const __bjs_createNetworkingResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT16NetworkingResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -377,53 +771,23 @@ export async function createInstantiator(options, swift) { } } }); - const __bjs_createAPIOptionalResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT17APIOptionalResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { case APIOptionalResultValues.Tag.Success: { - const isSome = value.param0 != null ? 1 : 0; - if (isSome) { - const bytes = textEncoder.encode(value.param0); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(isSome); + __bjs_codec_Optional_String.lower(value.param0); return APIOptionalResultValues.Tag.Success; } case APIOptionalResultValues.Tag.Failure: { - const isSome = value.param1 != null ? 1 : 0; - if (isSome) { - i32Stack.push(value.param1 ? 1 : 0); - } - i32Stack.push(isSome); - const isSome1 = value.param0 != null ? 1 : 0; - if (isSome1) { - i32Stack.push((value.param0 | 0)); - } - i32Stack.push(isSome1); + __bjs_codec_Optional_Bool.lower(value.param1); + __bjs_codec_Optional_Int.lower(value.param0); return APIOptionalResultValues.Tag.Failure; } case APIOptionalResultValues.Tag.Status: { - const isSome = value.param2 != null ? 1 : 0; - if (isSome) { - const bytes = textEncoder.encode(value.param2); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(isSome); - const isSome1 = value.param1 != null ? 1 : 0; - if (isSome1) { - i32Stack.push((value.param1 | 0)); - } - i32Stack.push(isSome1); - const isSome2 = value.param0 != null ? 1 : 0; - if (isSome2) { - i32Stack.push(value.param0 ? 1 : 0); - } - i32Stack.push(isSome2); + __bjs_codec_Optional_String.lower(value.param2); + __bjs_codec_Optional_Int.lower(value.param1); + __bjs_codec_Optional_Bool.lower(value.param0); return APIOptionalResultValues.Tag.Status; } default: throw new Error("Unknown APIOptionalResultValues tag: " + String(enumTag)); @@ -433,67 +797,25 @@ export async function createInstantiator(options, swift) { tag = tag | 0; switch (tag) { case APIOptionalResultValues.Tag.Success: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const string = strStack.pop(); - optValue = string; - } + const optValue = __bjs_codec_Optional_String.lift(); return { tag: APIOptionalResultValues.Tag.Success, param0: optValue }; } case APIOptionalResultValues.Tag.Failure: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const bool = i32Stack.pop() !== 0; - optValue = bool; - } - const isSome1 = i32Stack.pop(); - let optValue1; - if (isSome1 === 0) { - optValue1 = null; - } else { - const int = i32Stack.pop(); - optValue1 = int; - } + const optValue = __bjs_codec_Optional_Bool.lift(); + const optValue1 = __bjs_codec_Optional_Int.lift(); return { tag: APIOptionalResultValues.Tag.Failure, param0: optValue1, param1: optValue }; } case APIOptionalResultValues.Tag.Status: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const string = strStack.pop(); - optValue = string; - } - const isSome1 = i32Stack.pop(); - let optValue1; - if (isSome1 === 0) { - optValue1 = null; - } else { - const int = i32Stack.pop(); - optValue1 = int; - } - const isSome2 = i32Stack.pop(); - let optValue2; - if (isSome2 === 0) { - optValue2 = null; - } else { - const bool = i32Stack.pop() !== 0; - optValue2 = bool; - } + const optValue = __bjs_codec_Optional_String.lift(); + const optValue1 = __bjs_codec_Optional_Int.lift(); + const optValue2 = __bjs_codec_Optional_Bool.lift(); return { tag: APIOptionalResultValues.Tag.Status, param0: optValue2, param1: optValue1, param2: optValue }; } default: throw new Error("Unknown APIOptionalResultValues tag returned from Swift: " + String(tag)); } } }); - const __bjs_createTypedPayloadResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT18TypedPayloadResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -506,19 +828,11 @@ export async function createInstantiator(options, swift) { return TypedPayloadResultValues.Tag.Direction; } case TypedPayloadResultValues.Tag.OptPrecision: { - const isSome = value.param0 != null ? 1 : 0; - if (isSome) { - f32Stack.push(Math.fround(value.param0)); - } - i32Stack.push(isSome); + __bjs_codec_Optional_M10TestModuleT9Precision.lower(value.param0); return TypedPayloadResultValues.Tag.OptPrecision; } case TypedPayloadResultValues.Tag.OptDirection: { - const isSome = value.param0 != null ? 1 : 0; - if (isSome) { - i32Stack.push((value.param0 | 0)); - } - i32Stack.push(isSome); + __bjs_codec_Optional_M10TestModuleT17CardinalDirection.lower(value.param0); return TypedPayloadResultValues.Tag.OptDirection; } case TypedPayloadResultValues.Tag.Empty: { @@ -539,25 +853,11 @@ export async function createInstantiator(options, swift) { return { tag: TypedPayloadResultValues.Tag.Direction, param0: caseId }; } case TypedPayloadResultValues.Tag.OptPrecision: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const rawValue = f32Stack.pop(); - optValue = rawValue; - } + const optValue = __bjs_codec_Optional_M10TestModuleT9Precision.lift(); return { tag: TypedPayloadResultValues.Tag.OptPrecision, param0: optValue }; } case TypedPayloadResultValues.Tag.OptDirection: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const caseId = i32Stack.pop(); - optValue = caseId; - } + const optValue = __bjs_codec_Optional_M10TestModuleT17CardinalDirection.lift(); return { tag: TypedPayloadResultValues.Tag.OptDirection, param0: optValue }; } case TypedPayloadResultValues.Tag.Empty: return { tag: TypedPayloadResultValues.Tag.Empty }; @@ -565,12 +865,12 @@ export async function createInstantiator(options, swift) { } } }); - const __bjs_createAllTypesResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT14AllTypesResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { case AllTypesResultValues.Tag.StructPayload: { - structHelpers.Point.lower(value.param0); + structHelpers.M10TestModuleT5Point.lower(value.param0); return AllTypesResultValues.Tag.StructPayload; } case AllTypesResultValues.Tag.ClassPayload: { @@ -583,15 +883,12 @@ export async function createInstantiator(options, swift) { return AllTypesResultValues.Tag.JsObjectPayload; } case AllTypesResultValues.Tag.NestedEnum: { - const caseId = enumHelpers.APIResult.lower(value.param0); + const caseId = enumHelpers.M10TestModuleT9APIResult.lower(value.param0); i32Stack.push(caseId); return AllTypesResultValues.Tag.NestedEnum; } case AllTypesResultValues.Tag.ArrayPayload: { - for (const elem of value.param0) { - i32Stack.push((elem | 0)); - } - i32Stack.push(value.param0.length); + __bjs_codec_Array_Int.lower(value.param0); return AllTypesResultValues.Tag.ArrayPayload; } case AllTypesResultValues.Tag.Empty: { @@ -604,7 +901,7 @@ export async function createInstantiator(options, swift) { tag = tag | 0; switch (tag) { case AllTypesResultValues.Tag.StructPayload: { - const struct = structHelpers.Point.lift(); + const struct = structHelpers.M10TestModuleT5Point.lift(); return { tag: AllTypesResultValues.Tag.StructPayload, param0: struct }; } case AllTypesResultValues.Tag.ClassPayload: { @@ -619,22 +916,11 @@ export async function createInstantiator(options, swift) { return { tag: AllTypesResultValues.Tag.JsObjectPayload, param0: obj }; } case AllTypesResultValues.Tag.NestedEnum: { - const enumValue = enumHelpers.APIResult.lift(i32Stack.pop()); + const enumValue = enumHelpers.M10TestModuleT9APIResult.lift(i32Stack.pop()); return { tag: AllTypesResultValues.Tag.NestedEnum, param0: enumValue }; } case AllTypesResultValues.Tag.ArrayPayload: { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Int.lift(); return { tag: AllTypesResultValues.Tag.ArrayPayload, param0: arrayResult }; } case AllTypesResultValues.Tag.Empty: return { tag: AllTypesResultValues.Tag.Empty }; @@ -642,53 +928,28 @@ export async function createInstantiator(options, swift) { } } }); - const __bjs_createOptionalAllTypesResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT22OptionalAllTypesResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { case OptionalAllTypesResultValues.Tag.OptStruct: { - const isSome = value.param0 != null ? 1 : 0; - if (isSome) { - structHelpers.Point.lower(value.param0); - } - i32Stack.push(isSome); + __bjs_codec_Optional_M10TestModuleT5Point.lower(value.param0); return OptionalAllTypesResultValues.Tag.OptStruct; } case OptionalAllTypesResultValues.Tag.OptClass: { - const isSome = value.param0 != null ? 1 : 0; - if (isSome) { - ptrStack.push(value.param0.pointer); - } - i32Stack.push(isSome); + __bjs_codec_Optional_M10TestModuleT4User.lower(value.param0); return OptionalAllTypesResultValues.Tag.OptClass; } case OptionalAllTypesResultValues.Tag.OptJSObject: { - const isSome = value.param0 != null ? 1 : 0; - if (isSome) { - const objId = swift.memory.retain(value.param0); - i32Stack.push(objId); - } - i32Stack.push(isSome); + __bjs_codec_Optional_JSObject.lower(value.param0); return OptionalAllTypesResultValues.Tag.OptJSObject; } case OptionalAllTypesResultValues.Tag.OptNestedEnum: { - const isSome = value.param0 != null ? 1 : 0; - if (isSome) { - const caseId = enumHelpers.APIResult.lower(value.param0); - i32Stack.push(caseId); - } - i32Stack.push(isSome); + __bjs_codec_Optional_M10TestModuleT9APIResult.lower(value.param0); return OptionalAllTypesResultValues.Tag.OptNestedEnum; } case OptionalAllTypesResultValues.Tag.OptArray: { - const isSome = value.param0 != null ? 1 : 0; - if (isSome) { - for (const elem of value.param0) { - i32Stack.push((elem | 0)); - } - i32Stack.push(value.param0.length); - } - i32Stack.push(isSome); + __bjs_codec_Optional_Array_Int.lower(value.param0); return OptionalAllTypesResultValues.Tag.OptArray; } case OptionalAllTypesResultValues.Tag.Empty: { @@ -701,72 +962,23 @@ export async function createInstantiator(options, swift) { tag = tag | 0; switch (tag) { case OptionalAllTypesResultValues.Tag.OptStruct: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const struct = structHelpers.Point.lift(); - optValue = struct; - } + const optValue = __bjs_codec_Optional_M10TestModuleT5Point.lift(); return { tag: OptionalAllTypesResultValues.Tag.OptStruct, param0: optValue }; } case OptionalAllTypesResultValues.Tag.OptClass: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const ptr = ptrStack.pop(); - const obj = _exports['User'].__construct(ptr); - optValue = obj; - } + const optValue = __bjs_codec_Optional_M10TestModuleT4User.lift(); return { tag: OptionalAllTypesResultValues.Tag.OptClass, param0: optValue }; } case OptionalAllTypesResultValues.Tag.OptJSObject: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const objId = i32Stack.pop(); - const obj = swift.memory.getObject(objId); - swift.memory.release(objId); - optValue = obj; - } + const optValue = __bjs_codec_Optional_JSObject.lift(); return { tag: OptionalAllTypesResultValues.Tag.OptJSObject, param0: optValue }; } case OptionalAllTypesResultValues.Tag.OptNestedEnum: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const enumValue = enumHelpers.APIResult.lift(i32Stack.pop()); - optValue = enumValue; - } + const optValue = __bjs_codec_Optional_M10TestModuleT9APIResult.lift(); return { tag: OptionalAllTypesResultValues.Tag.OptNestedEnum, param0: optValue }; } case OptionalAllTypesResultValues.Tag.OptArray: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } - optValue = arrayResult; - } + const optValue = __bjs_codec_Optional_Array_Int.lift(); return { tag: OptionalAllTypesResultValues.Tag.OptArray, param0: optValue }; } case OptionalAllTypesResultValues.Tag.Empty: return { tag: OptionalAllTypesResultValues.Tag.Empty }; @@ -850,12 +1062,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_Point"] = function(objectId) { - structHelpers.Point.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT5Point.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Point"] = function() { - const value = structHelpers.Point.lift(); + const value = structHelpers.M10TestModuleT5Point.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -1033,139 +1247,139 @@ export async function createInstantiator(options, swift) { } } - const PointHelpers = __bjs_createPointHelpers(); - structHelpers.Point = PointHelpers; + const __bjs_helpers_M10TestModuleT5Point = __bjs_createStructHelpers_M10TestModuleT5Point(); + structHelpers.M10TestModuleT5Point = __bjs_helpers_M10TestModuleT5Point; - const APIResultHelpers = __bjs_createAPIResultValuesHelpers(); - enumHelpers.APIResult = APIResultHelpers; + const __bjs_helpers_M10TestModuleT9APIResult = __bjs_createEnumHelpers_M10TestModuleT9APIResult(); + enumHelpers.M10TestModuleT9APIResult = __bjs_helpers_M10TestModuleT9APIResult; - const ComplexResultHelpers = __bjs_createComplexResultValuesHelpers(); - enumHelpers.ComplexResult = ComplexResultHelpers; + const __bjs_helpers_M10TestModuleT13ComplexResult = __bjs_createEnumHelpers_M10TestModuleT13ComplexResult(); + enumHelpers.M10TestModuleT13ComplexResult = __bjs_helpers_M10TestModuleT13ComplexResult; - const ResultHelpers = __bjs_createResultValuesHelpers(); - enumHelpers.Result = ResultHelpers; + const __bjs_helpers_M10TestModuleT9UtilitiesT6Result = __bjs_createEnumHelpers_M10TestModuleT9UtilitiesT6Result(); + enumHelpers.M10TestModuleT9UtilitiesT6Result = __bjs_helpers_M10TestModuleT9UtilitiesT6Result; - const NetworkingResultHelpers = __bjs_createNetworkingResultValuesHelpers(); - enumHelpers.NetworkingResult = NetworkingResultHelpers; + const __bjs_helpers_M10TestModuleT16NetworkingResult = __bjs_createEnumHelpers_M10TestModuleT16NetworkingResult(); + enumHelpers.M10TestModuleT16NetworkingResult = __bjs_helpers_M10TestModuleT16NetworkingResult; - const APIOptionalResultHelpers = __bjs_createAPIOptionalResultValuesHelpers(); - enumHelpers.APIOptionalResult = APIOptionalResultHelpers; + const __bjs_helpers_M10TestModuleT17APIOptionalResult = __bjs_createEnumHelpers_M10TestModuleT17APIOptionalResult(); + enumHelpers.M10TestModuleT17APIOptionalResult = __bjs_helpers_M10TestModuleT17APIOptionalResult; - const TypedPayloadResultHelpers = __bjs_createTypedPayloadResultValuesHelpers(); - enumHelpers.TypedPayloadResult = TypedPayloadResultHelpers; + const __bjs_helpers_M10TestModuleT18TypedPayloadResult = __bjs_createEnumHelpers_M10TestModuleT18TypedPayloadResult(); + enumHelpers.M10TestModuleT18TypedPayloadResult = __bjs_helpers_M10TestModuleT18TypedPayloadResult; - const AllTypesResultHelpers = __bjs_createAllTypesResultValuesHelpers(); - enumHelpers.AllTypesResult = AllTypesResultHelpers; + const __bjs_helpers_M10TestModuleT14AllTypesResult = __bjs_createEnumHelpers_M10TestModuleT14AllTypesResult(); + enumHelpers.M10TestModuleT14AllTypesResult = __bjs_helpers_M10TestModuleT14AllTypesResult; - const OptionalAllTypesResultHelpers = __bjs_createOptionalAllTypesResultValuesHelpers(); - enumHelpers.OptionalAllTypesResult = OptionalAllTypesResultHelpers; + const __bjs_helpers_M10TestModuleT22OptionalAllTypesResult = __bjs_createEnumHelpers_M10TestModuleT22OptionalAllTypesResult(); + enumHelpers.M10TestModuleT22OptionalAllTypesResult = __bjs_helpers_M10TestModuleT22OptionalAllTypesResult; const exports = { handle: function bjs_handle(result) { - const resultCaseId = enumHelpers.APIResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT9APIResult.lower(result); instance.exports.bjs_handle(resultCaseId); }, getResult: function bjs_getResult() { instance.exports.bjs_getResult(); - const ret = enumHelpers.APIResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT9APIResult.lift(i32Stack.pop()); return ret; }, roundtripAPIResult: function bjs_roundtripAPIResult(result) { - const resultCaseId = enumHelpers.APIResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT9APIResult.lower(result); instance.exports.bjs_roundtripAPIResult(resultCaseId); - const ret = enumHelpers.APIResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT9APIResult.lift(i32Stack.pop()); return ret; }, roundTripOptionalAPIResult: function bjs_roundTripOptionalAPIResult(result) { const isSome = result != null; let result1; if (isSome) { - const resultCaseId = enumHelpers.APIResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT9APIResult.lower(result); result1 = resultCaseId; } else { result1 = 0; } instance.exports.bjs_roundTripOptionalAPIResult(+isSome, result1); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.APIResult.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT9APIResult.lift(tag); return optResult; }, handleComplex: function bjs_handleComplex(result) { - const resultCaseId = enumHelpers.ComplexResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT13ComplexResult.lower(result); instance.exports.bjs_handleComplex(resultCaseId); }, getComplexResult: function bjs_getComplexResult() { instance.exports.bjs_getComplexResult(); - const ret = enumHelpers.ComplexResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT13ComplexResult.lift(i32Stack.pop()); return ret; }, roundtripComplexResult: function bjs_roundtripComplexResult(result) { - const resultCaseId = enumHelpers.ComplexResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT13ComplexResult.lower(result); instance.exports.bjs_roundtripComplexResult(resultCaseId); - const ret = enumHelpers.ComplexResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT13ComplexResult.lift(i32Stack.pop()); return ret; }, roundTripOptionalComplexResult: function bjs_roundTripOptionalComplexResult(result) { const isSome = result != null; let result1; if (isSome) { - const resultCaseId = enumHelpers.ComplexResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT13ComplexResult.lower(result); result1 = resultCaseId; } else { result1 = 0; } instance.exports.bjs_roundTripOptionalComplexResult(+isSome, result1); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.ComplexResult.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT13ComplexResult.lift(tag); return optResult; }, roundTripOptionalUtilitiesResult: function bjs_roundTripOptionalUtilitiesResult(result) { const isSome = result != null; let result1; if (isSome) { - const resultCaseId = enumHelpers.Result.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT9UtilitiesT6Result.lower(result); result1 = resultCaseId; } else { result1 = 0; } instance.exports.bjs_roundTripOptionalUtilitiesResult(+isSome, result1); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.Result.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT9UtilitiesT6Result.lift(tag); return optResult; }, roundTripOptionalNetworkingResult: function bjs_roundTripOptionalNetworkingResult(result) { const isSome = result != null; let result1; if (isSome) { - const resultCaseId = enumHelpers.NetworkingResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT16NetworkingResult.lower(result); result1 = resultCaseId; } else { result1 = 0; } instance.exports.bjs_roundTripOptionalNetworkingResult(+isSome, result1); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.NetworkingResult.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT16NetworkingResult.lift(tag); return optResult; }, roundTripOptionalAPIOptionalResult: function bjs_roundTripOptionalAPIOptionalResult(result) { const isSome = result != null; let result1; if (isSome) { - const resultCaseId = enumHelpers.APIOptionalResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT17APIOptionalResult.lower(result); result1 = resultCaseId; } else { result1 = 0; } instance.exports.bjs_roundTripOptionalAPIOptionalResult(+isSome, result1); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.APIOptionalResult.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT17APIOptionalResult.lift(tag); return optResult; }, compareAPIResults: function bjs_compareAPIResults(result1, result2) { const isSome = result1 != null; let result; if (isSome) { - const result1CaseId = enumHelpers.APIOptionalResult.lower(result1); + const result1CaseId = enumHelpers.M10TestModuleT17APIOptionalResult.lower(result1); result = result1CaseId; } else { result = 0; @@ -1173,74 +1387,74 @@ export async function createInstantiator(options, swift) { const isSome1 = result2 != null; let result3; if (isSome1) { - const result2CaseId = enumHelpers.APIOptionalResult.lower(result2); + const result2CaseId = enumHelpers.M10TestModuleT17APIOptionalResult.lower(result2); result3 = result2CaseId; } else { result3 = 0; } instance.exports.bjs_compareAPIResults(+isSome, result, +isSome1, result3); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.APIOptionalResult.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT17APIOptionalResult.lift(tag); return optResult; }, roundTripTypedPayloadResult: function bjs_roundTripTypedPayloadResult(result) { - const resultCaseId = enumHelpers.TypedPayloadResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT18TypedPayloadResult.lower(result); instance.exports.bjs_roundTripTypedPayloadResult(resultCaseId); - const ret = enumHelpers.TypedPayloadResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT18TypedPayloadResult.lift(i32Stack.pop()); return ret; }, roundTripOptionalTypedPayloadResult: function bjs_roundTripOptionalTypedPayloadResult(result) { const isSome = result != null; let result1; if (isSome) { - const resultCaseId = enumHelpers.TypedPayloadResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT18TypedPayloadResult.lower(result); result1 = resultCaseId; } else { result1 = 0; } instance.exports.bjs_roundTripOptionalTypedPayloadResult(+isSome, result1); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.TypedPayloadResult.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT18TypedPayloadResult.lift(tag); return optResult; }, roundTripAllTypesResult: function bjs_roundTripAllTypesResult(result) { - const resultCaseId = enumHelpers.AllTypesResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT14AllTypesResult.lower(result); instance.exports.bjs_roundTripAllTypesResult(resultCaseId); - const ret = enumHelpers.AllTypesResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT14AllTypesResult.lift(i32Stack.pop()); return ret; }, roundTripOptionalAllTypesResult: function bjs_roundTripOptionalAllTypesResult(result) { const isSome = result != null; let result1; if (isSome) { - const resultCaseId = enumHelpers.AllTypesResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT14AllTypesResult.lower(result); result1 = resultCaseId; } else { result1 = 0; } instance.exports.bjs_roundTripOptionalAllTypesResult(+isSome, result1); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.AllTypesResult.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT14AllTypesResult.lift(tag); return optResult; }, roundTripOptionalPayloadResult: function bjs_roundTripOptionalPayloadResult(result) { - const resultCaseId = enumHelpers.OptionalAllTypesResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT22OptionalAllTypesResult.lower(result); instance.exports.bjs_roundTripOptionalPayloadResult(resultCaseId); - const ret = enumHelpers.OptionalAllTypesResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT22OptionalAllTypesResult.lift(i32Stack.pop()); return ret; }, roundTripOptionalPayloadResultOpt: function bjs_roundTripOptionalPayloadResultOpt(result) { const isSome = result != null; let result1; if (isSome) { - const resultCaseId = enumHelpers.OptionalAllTypesResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT22OptionalAllTypesResult.lower(result); result1 = resultCaseId; } else { result1 = 0; } instance.exports.bjs_roundTripOptionalPayloadResultOpt(+isSome, result1); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.OptionalAllTypesResult.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT22OptionalAllTypesResult.lift(tag); return optResult; }, APIResult: APIResultValues, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValueImport.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValueImport.js index de374bd70..2b36953bb 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValueImport.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValueImport.js @@ -38,7 +38,7 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createPayloadSignalValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT13PayloadSignal = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -83,6 +83,7 @@ export async function createInstantiator(options, swift) { addImports: (importObject, importsContext) => { bjs = {}; importObject["bjs"] = bjs; + const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { tmpRetString = decodeString(ptr, len); } @@ -150,6 +151,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -250,9 +253,9 @@ export async function createInstantiator(options, swift) { const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_PayloadSignalControls_roundTrip_static"] = function bjs_PayloadSignalControls_roundTrip_static(signal) { try { - const enumValue = enumHelpers.PayloadSignal.lift(signal); + const enumValue = enumHelpers.M10TestModuleT13PayloadSignal.lift(signal); let ret = imports.PayloadSignalControls.roundTrip(enumValue); - const caseId = enumHelpers.PayloadSignal.lower(ret); + const caseId = enumHelpers.M10TestModuleT13PayloadSignal.lower(ret); return caseId; } catch (error) { setException(error); @@ -260,7 +263,7 @@ export async function createInstantiator(options, swift) { } TestModule["bjs_PayloadSignalControls_send"] = function bjs_PayloadSignalControls_send(self, signal) { try { - const enumValue = enumHelpers.PayloadSignal.lift(signal); + const enumValue = enumHelpers.M10TestModuleT13PayloadSignal.lift(signal); swift.memory.getObject(self).send(enumValue); } catch (error) { setException(error); @@ -269,7 +272,7 @@ export async function createInstantiator(options, swift) { TestModule["bjs_PayloadSignalControls_current"] = function bjs_PayloadSignalControls_current(self) { try { let ret = swift.memory.getObject(self).current(); - const caseId = enumHelpers.PayloadSignal.lower(ret); + const caseId = enumHelpers.M10TestModuleT13PayloadSignal.lower(ret); return caseId; } catch (error) { setException(error); @@ -279,7 +282,7 @@ export async function createInstantiator(options, swift) { try { let optResult; if (signalIsSome) { - const enumValue = enumHelpers.PayloadSignal.lift(signalCaseId); + const enumValue = enumHelpers.M10TestModuleT13PayloadSignal.lift(signalCaseId); optResult = enumValue; } else { optResult = null; @@ -287,7 +290,7 @@ export async function createInstantiator(options, swift) { let ret = swift.memory.getObject(self).roundTripOptional(optResult); const isSome = ret != null; if (isSome) { - const caseId = enumHelpers.PayloadSignal.lower(ret); + const caseId = enumHelpers.M10TestModuleT13PayloadSignal.lower(ret); return caseId; } else { return -1; @@ -310,8 +313,8 @@ export async function createInstantiator(options, swift) { /** @param {WebAssembly.Instance} instance */ createExports: (instance) => { const js = swift.memory.heap; - const PayloadSignalHelpers = __bjs_createPayloadSignalValuesHelpers(); - enumHelpers.PayloadSignal = PayloadSignalHelpers; + const __bjs_helpers_M10TestModuleT13PayloadSignal = __bjs_createEnumHelpers_M10TestModuleT13PayloadSignal(); + enumHelpers.M10TestModuleT13PayloadSignal = __bjs_helpers_M10TestModuleT13PayloadSignal; const exports = { PayloadSignal: PayloadSignalValues, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.js index c2ae031bb..838e3062b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.js @@ -130,6 +130,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCaseImport.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCaseImport.js index f2d6b8750..bde5fc31f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCaseImport.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCaseImport.js @@ -44,6 +44,7 @@ export async function createInstantiator(options, swift) { addImports: (importObject, importsContext) => { bjs = {}; importObject["bjs"] = bjs; + const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { tmpRetString = decodeString(ptr, len); } @@ -111,6 +112,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.js index 6c45f0333..0a691374b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.js @@ -150,6 +150,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.js index 2a9e7948a..03f0a8d9a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.js @@ -131,6 +131,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.js index 9e18a8d80..09e03e44a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.js @@ -106,6 +106,350 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_M10TestModuleT8FileSize = { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const rawValue = i64Stack.pop(); + return rawValue; + }, + }; + const __bjs_codec_Optional_M10TestModuleT8FileSize = __bjs_optionalCodec(__bjs_codec_M10TestModuleT8FileSize); + const __bjs_codec_M10TestModuleT9SessionId = { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const rawValue = i64Stack.pop(); + return rawValue; + }, + }; + const __bjs_codec_Optional_M10TestModuleT9SessionId = __bjs_optionalCodec(__bjs_codec_M10TestModuleT9SessionId); + return { /** @@ -182,6 +526,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -448,15 +794,8 @@ export async function createInstantiator(options, swift) { roundTripOptionalFileSize: function bjs_roundTripOptionalFileSize(input) { const isSome = input != null; instance.exports.bjs_roundTripOptionalFileSize(+isSome, isSome ? input : 0n); - const isSome1 = i32Stack.pop(); - let optResult; - if (isSome1) { - const rawValue = i64Stack.pop(); - optResult = rawValue; - } else { - optResult = null; - } - return optResult; + const optValue = __bjs_codec_Optional_M10TestModuleT8FileSize.lift(); + return optValue; }, setUserId: function bjs_setUserId(id) { instance.exports.bjs_setUserId(id); @@ -496,15 +835,8 @@ export async function createInstantiator(options, swift) { roundTripOptionalSessionId: function bjs_roundTripOptionalSessionId(input) { const isSome = input != null; instance.exports.bjs_roundTripOptionalSessionId(+isSome, isSome ? input : 0n); - const isSome1 = i32Stack.pop(); - let optResult; - if (isSome1) { - const rawValue = i64Stack.pop(); - optResult = rawValue; - } else { - optResult = null; - } - return optResult; + const optValue = __bjs_codec_Optional_M10TestModuleT9SessionId.lift(); + return optValue; }, setPrecision: function bjs_setPrecision(precision) { instance.exports.bjs_setPrecision(precision); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ExtensionNestedTypes.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ExtensionNestedTypes.d.ts new file mode 100644 index 000000000..df59ccefd --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ExtensionNestedTypes.d.ts @@ -0,0 +1,82 @@ +// 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 MessageValues: { + readonly Tag: { + readonly Update: 0; + readonly Delete: 1; + }; +}; + +export type MessageTag = + { tag: typeof MessageValues.Tag.Update; param0: UpdateTag } | { tag: typeof MessageValues.Tag.Delete } + +export const UpdateValues: { + readonly Flip: 0; + readonly Rotate: 1; +}; +export type UpdateTag = typeof UpdateValues[keyof typeof UpdateValues]; + +export type MessageObject = typeof MessageValues; + +export type GenreObject = typeof Library.GenreValues; + +export type UpdateObject = typeof UpdateValues; + +export namespace Library { + const GenreValues: { + readonly Fiction: "fiction"; + readonly Reference: "reference"; + }; + type GenreTag = typeof GenreValues[keyof typeof GenreValues]; + export interface Shelf { + label: string; + describeShelf(): string; + } + export namespace Shelf { + export interface Divider { + slot: number; + } + } +} +/// Represents a Swift heap object like a class instance or an actor instance. +export interface SwiftHeapObject { + /// Release the heap object. + /// + /// Note: Calling this method will release the heap object and it will no longer be accessible. + release(): void; +} +export interface Library extends SwiftHeapObject { + describe(): string; + rename(title: string): string; + shelf(label: string): Library.Shelf; + name: string; +} +export type Exports = { + roundTripMessage(message: MessageTag): MessageTag; + Message: MessageObject + Update: UpdateObject + Library: { + new(name: string): Library; + Genre: GenreObject + Shelf: { + init(label: string): Library.Shelf; + readonly capacity: number; + Divider: { + init(slot: number): Library.Shelf.Divider; + }, + }, + }, +} +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/ExtensionNestedTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ExtensionNestedTypes.js new file mode 100644 index 000000000..d031ff64b --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ExtensionNestedTypes.js @@ -0,0 +1,457 @@ +// 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 MessageValues = { + Tag: { + Update: 0, + Delete: 1, + }, +}; +export const GenreValues = { + Fiction: "fiction", + Reference: "reference", +}; + +export const UpdateValues = { + Flip: 0, + Rotate: 1, +}; + +export async function createInstantiator(options, swift) { + let instance; + let memory; + let setException; + let decodeString; + const textDecoder = new TextDecoder("utf-8"); + const textEncoder = new TextEncoder("utf-8"); + let tmpRetString; + let tmpRetBytes; + let tmpRetException; + let tmpRetOptionalBool; + let tmpRetOptionalInt; + let tmpRetOptionalFloat; + let tmpRetOptionalDouble; + let tmpRetOptionalHeapObject; + let strStack = []; + let i32Stack = []; + let i64Stack = []; + let f32Stack = []; + let f64Stack = []; + let ptrStack = []; + let taStack = []; + const enumHelpers = {}; + const structHelpers = {}; + + let _exports = null; + let bjs = null; + const __bjs_createStructHelpers_M10TestModuleT7LibraryT5Shelf = () => ({ + lower: (value) => { + const bytes = textEncoder.encode(value.label); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + const instance1 = { label: string }; + instance1.describeShelf = function() { + structHelpers.M10TestModuleT7LibraryT5Shelf.lower(this); + const ret = instance.exports.bjs_Library_Shelf_describeShelf(); + const ret1 = tmpRetString; + tmpRetString = undefined; + return ret1; + }.bind(instance1); + return instance1; + } + }); + const __bjs_createStructHelpers_M10TestModuleT7LibraryT5ShelfT7Divider = () => ({ + lower: (value) => { + i32Stack.push((value.slot | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return { slot: int }; + } + }); + const __bjs_createEnumHelpers_M10TestModuleT7Message = () => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case MessageValues.Tag.Update: { + i32Stack.push((value.param0 | 0)); + return MessageValues.Tag.Update; + } + case MessageValues.Tag.Delete: { + return MessageValues.Tag.Delete; + } + default: throw new Error("Unknown MessageValues tag: " + String(enumTag)); + } + }, + lift: (tag) => { + tag = tag | 0; + switch (tag) { + case MessageValues.Tag.Update: { + const caseId = i32Stack.pop(); + return { tag: MessageValues.Tag.Update, param0: caseId }; + } + case MessageValues.Tag.Delete: return { tag: MessageValues.Tag.Delete }; + default: throw new Error("Unknown MessageValues tag returned from Swift: " + String(tag)); + } + } + }); + + return { + /** + * @param {WebAssembly.Imports} importObject + */ + addImports: (importObject, importsContext) => { + bjs = {}; + importObject["bjs"] = bjs; + bjs["swift_js_return_string"] = function(ptr, len) { + tmpRetString = decodeString(ptr, len); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr >>> 0); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + return swift.memory.retain(decodeString(ptr, len)); + } + bjs["swift_js_init_memory_with_result"] = function(ptr, len) { + const target = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); + target.set(tmpRetBytes); + tmpRetBytes = undefined; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_push_i32"] = function(v) { + i32Stack.push(v | 0); + } + bjs["swift_js_push_f32"] = function(v) { + f32Stack.push(Math.fround(v)); + } + bjs["swift_js_push_f64"] = function(v) { + f64Stack.push(v); + } + bjs["swift_js_push_string"] = function(ptr, len) { + const value = decodeString(ptr, len); + strStack.push(value); + } + bjs["swift_js_pop_i32"] = function() { + return i32Stack.pop(); + } + bjs["swift_js_pop_f32"] = function() { + return f32Stack.pop(); + } + bjs["swift_js_pop_f64"] = function() { + return f64Stack.pop(); + } + bjs["swift_js_push_pointer"] = function(pointer) { + ptrStack.push(pointer); + } + bjs["swift_js_pop_pointer"] = function() { + return ptrStack.pop(); + } + bjs["swift_js_push_i64"] = function(v) { + i64Stack.push(v); + } + bjs["swift_js_pop_i64"] = function() { + return i64Stack.pop(); + } + const taCtors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array]; + bjs["swift_js_push_typed_array"] = function(kind, ptr, count) { + const Ctor = taCtors[kind]; + const byteLen = count * Ctor.BYTES_PER_ELEMENT; + const copy = memory.buffer.slice(ptr, ptr + byteLen); + taStack.push(Array.from(new Ctor(copy))); + } + bjs["swift_js_struct_lower_Library_Shelf"] = function(objectId) { + structHelpers.M10TestModuleT7LibraryT5Shelf.lower(swift.memory.getObject(objectId)); + } + bjs["swift_js_struct_lift_Library_Shelf"] = function() { + const value = structHelpers.M10TestModuleT7LibraryT5Shelf.lift(); + return swift.memory.retain(value); + } + bjs["swift_js_struct_lower_Library_Shelf_Divider"] = function(objectId) { + structHelpers.M10TestModuleT7LibraryT5ShelfT7Divider.lower(swift.memory.getObject(objectId)); + } + bjs["swift_js_struct_lift_Library_Shelf_Divider"] = function() { + const value = structHelpers.M10TestModuleT7LibraryT5ShelfT7Divider.lift(); + return swift.memory.retain(value); + } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; + const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); + bjs["swift_js_make_promise"] = function() { + let resolve, reject; + const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); + promise[__bjs_promiseSettlers] = { resolve, reject }; + return swift.memory.retain(promise); + } + bjs["swift_js_return_optional_bool"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalBool = null; + } else { + tmpRetOptionalBool = value !== 0; + } + } + bjs["swift_js_return_optional_int"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalInt = null; + } else { + tmpRetOptionalInt = value | 0; + } + } + bjs["swift_js_return_optional_float"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalFloat = null; + } else { + tmpRetOptionalFloat = Math.fround(value); + } + } + bjs["swift_js_return_optional_double"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalDouble = null; + } else { + tmpRetOptionalDouble = value; + } + } + bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = decodeString(ptr, len); + } + } + bjs["swift_js_return_optional_object"] = function(isSome, objectId) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = swift.memory.getObject(objectId); + } + } + bjs["swift_js_return_optional_heap_object"] = function(isSome, pointer) { + if (isSome === 0) { + tmpRetOptionalHeapObject = null; + } else { + tmpRetOptionalHeapObject = pointer; + } + } + bjs["swift_js_get_optional_int_presence"] = function() { + return tmpRetOptionalInt != null ? 1 : 0; + } + bjs["swift_js_get_optional_int_value"] = function() { + const value = tmpRetOptionalInt; + tmpRetOptionalInt = undefined; + return value; + } + bjs["swift_js_get_optional_string"] = function() { + const str = tmpRetString; + tmpRetString = undefined; + if (str == null) { + return -1; + } else { + const bytes = textEncoder.encode(str); + tmpRetBytes = bytes; + return bytes.length; + } + } + bjs["swift_js_get_optional_float_presence"] = function() { + return tmpRetOptionalFloat != null ? 1 : 0; + } + bjs["swift_js_get_optional_float_value"] = function() { + const value = tmpRetOptionalFloat; + tmpRetOptionalFloat = undefined; + return value; + } + bjs["swift_js_get_optional_double_presence"] = function() { + return tmpRetOptionalDouble != null ? 1 : 0; + } + bjs["swift_js_get_optional_double_value"] = function() { + const value = tmpRetOptionalDouble; + tmpRetOptionalDouble = undefined; + return value; + } + bjs["swift_js_get_optional_heap_object_pointer"] = function() { + const pointer = tmpRetOptionalHeapObject; + tmpRetOptionalHeapObject = undefined; + return pointer || 0; + } + bjs["swift_js_closure_unregister"] = function(funcRef) {} + // Wrapper functions for module: TestModule + if (!importObject["TestModule"]) { + importObject["TestModule"] = {}; + } + importObject["TestModule"]["bjs_Library_wrap"] = function(pointer) { + const obj = _exports['Library'].__construct(pointer); + return swift.memory.retain(obj); + }; + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + decodeString = (ptr, len) => { const bytes = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); return textDecoder.decode(bytes); } + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => { + if (state.hasReleased) { + return; + } + state.hasReleased = true; + state.identityMap?.delete(state.pointer); + state.deinit(state.pointer); + }); + + /// Represents a Swift heap object like a class instance or an actor instance. + class SwiftHeapObject { + static __wrap(pointer, deinit, prototype, identityCache) { + pointer = pointer >>> 0; + const makeFresh = (identityMap) => { + const obj = Object.create(prototype); + const state = { pointer, deinit, hasReleased: false, identityMap }; + obj.pointer = pointer; + obj.__swiftHeapObjectState = state; + swiftHeapObjectFinalizationRegistry.register(obj, state, state); + if (identityMap) { + identityMap.set(pointer, new WeakRef(obj)); + } + return obj; + }; + + if (!identityCache) { + return makeFresh(null); + } + + const cached = identityCache.get(pointer)?.deref(); + if (cached && !cached.__swiftHeapObjectState.hasReleased) { + deinit(pointer); + return cached; + } + if (identityCache.has(pointer)) { + identityCache.delete(pointer); + } + + return makeFresh(identityCache); + } + + release() { + const state = this.__swiftHeapObjectState; + if (state.hasReleased) { + return; + } + state.hasReleased = true; + swiftHeapObjectFinalizationRegistry.unregister(state); + state.identityMap?.delete(state.pointer); + state.deinit(state.pointer); + } + } + class Library extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Library_deinit, Library.prototype, null); + } + + constructor(name) { + const nameBytes = textEncoder.encode(name); + const nameId = swift.memory.retain(nameBytes); + const ret = instance.exports.bjs_Library_init(nameId, nameBytes.length); + return Library.__construct(ret); + } + describe() { + instance.exports.bjs_Library_describe(this.pointer); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + } + rename(title) { + const titleBytes = textEncoder.encode(title); + const titleId = swift.memory.retain(titleBytes); + instance.exports.bjs_Library_rename(this.pointer, titleId, titleBytes.length); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + } + shelf(label) { + const labelBytes = textEncoder.encode(label); + const labelId = swift.memory.retain(labelBytes); + instance.exports.bjs_Library_shelf(this.pointer, labelId, labelBytes.length); + const structValue = structHelpers.M10TestModuleT7LibraryT5Shelf.lift(); + return structValue; + } + get name() { + instance.exports.bjs_Library_name_get(this.pointer); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + } + set name(value) { + const valueBytes = textEncoder.encode(value); + const valueId = swift.memory.retain(valueBytes); + instance.exports.bjs_Library_name_set(this.pointer, valueId, valueBytes.length); + } + } + const __bjs_helpers_M10TestModuleT7LibraryT5Shelf = __bjs_createStructHelpers_M10TestModuleT7LibraryT5Shelf(); + structHelpers.M10TestModuleT7LibraryT5Shelf = __bjs_helpers_M10TestModuleT7LibraryT5Shelf; + + const __bjs_helpers_M10TestModuleT7LibraryT5ShelfT7Divider = __bjs_createStructHelpers_M10TestModuleT7LibraryT5ShelfT7Divider(); + structHelpers.M10TestModuleT7LibraryT5ShelfT7Divider = __bjs_helpers_M10TestModuleT7LibraryT5ShelfT7Divider; + + const __bjs_helpers_M10TestModuleT7Message = __bjs_createEnumHelpers_M10TestModuleT7Message(); + enumHelpers.M10TestModuleT7Message = __bjs_helpers_M10TestModuleT7Message; + + const exports = { + roundTripMessage: function bjs_roundTripMessage(message) { + const messageCaseId = enumHelpers.M10TestModuleT7Message.lower(message); + instance.exports.bjs_roundTripMessage(messageCaseId); + const ret = enumHelpers.M10TestModuleT7Message.lift(i32Stack.pop()); + return ret; + }, + Message: MessageValues, + Update: UpdateValues, + Library: Object.assign(Library, { + Genre: GenreValues, + Shelf: { + init: function(label) { + const labelBytes = textEncoder.encode(label); + const labelId = swift.memory.retain(labelBytes); + instance.exports.bjs_Library_Shelf_init(labelId, labelBytes.length); + const structValue = structHelpers.M10TestModuleT7LibraryT5Shelf.lift(); + return structValue; + }, + get capacity() { + const ret = instance.exports.bjs_Library_Shelf_static_capacity_get(); + return ret; + }, + Divider: { + init: function(slot) { + instance.exports.bjs_Library_Shelf_Divider_init(slot); + const structValue = structHelpers.M10TestModuleT7LibraryT5ShelfT7Divider.lift(); + return structValue; + }, + }, + }, + }), + }; + _exports = exports; + return exports; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ExtensionOrderIndependence.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ExtensionOrderIndependence.d.ts new file mode 100644 index 000000000..2b16f6a6d --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ExtensionOrderIndependence.d.ts @@ -0,0 +1,38 @@ +// 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 namespace Depot { + export interface Crate { + label: string; + describeCrate(): string; + } +} +/// Represents a Swift heap object like a class instance or an actor instance. +export interface SwiftHeapObject { + /// Release the heap object. + /// + /// Note: Calling this method will release the heap object and it will no longer be accessible. + release(): void; +} +export interface Depot extends SwiftHeapObject { +} +export type Exports = { + Depot: { + new(): Depot; + Crate: { + init(label: string): Depot.Crate; + }, + }, +} +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/ExtensionOrderIndependence.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ExtensionOrderIndependence.js new file mode 100644 index 000000000..6cc339d24 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ExtensionOrderIndependence.js @@ -0,0 +1,339 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +export async function createInstantiator(options, swift) { + let instance; + let memory; + let setException; + let decodeString; + const textDecoder = new TextDecoder("utf-8"); + const textEncoder = new TextEncoder("utf-8"); + let tmpRetString; + let tmpRetBytes; + let tmpRetException; + let tmpRetOptionalBool; + let tmpRetOptionalInt; + let tmpRetOptionalFloat; + let tmpRetOptionalDouble; + let tmpRetOptionalHeapObject; + let strStack = []; + let i32Stack = []; + let i64Stack = []; + let f32Stack = []; + let f64Stack = []; + let ptrStack = []; + let taStack = []; + const enumHelpers = {}; + const structHelpers = {}; + + let _exports = null; + let bjs = null; + const __bjs_createStructHelpers_M10TestModuleT5DepotT5Crate = () => ({ + lower: (value) => { + const bytes = textEncoder.encode(value.label); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + const instance1 = { label: string }; + instance1.describeCrate = function() { + structHelpers.M10TestModuleT5DepotT5Crate.lower(this); + const ret = instance.exports.bjs_Depot_Crate_describeCrate(); + const ret1 = tmpRetString; + tmpRetString = undefined; + return ret1; + }.bind(instance1); + return instance1; + } + }); + + return { + /** + * @param {WebAssembly.Imports} importObject + */ + addImports: (importObject, importsContext) => { + bjs = {}; + importObject["bjs"] = bjs; + bjs["swift_js_return_string"] = function(ptr, len) { + tmpRetString = decodeString(ptr, len); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr >>> 0); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + return swift.memory.retain(decodeString(ptr, len)); + } + bjs["swift_js_init_memory_with_result"] = function(ptr, len) { + const target = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); + target.set(tmpRetBytes); + tmpRetBytes = undefined; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_push_i32"] = function(v) { + i32Stack.push(v | 0); + } + bjs["swift_js_push_f32"] = function(v) { + f32Stack.push(Math.fround(v)); + } + bjs["swift_js_push_f64"] = function(v) { + f64Stack.push(v); + } + bjs["swift_js_push_string"] = function(ptr, len) { + const value = decodeString(ptr, len); + strStack.push(value); + } + bjs["swift_js_pop_i32"] = function() { + return i32Stack.pop(); + } + bjs["swift_js_pop_f32"] = function() { + return f32Stack.pop(); + } + bjs["swift_js_pop_f64"] = function() { + return f64Stack.pop(); + } + bjs["swift_js_push_pointer"] = function(pointer) { + ptrStack.push(pointer); + } + bjs["swift_js_pop_pointer"] = function() { + return ptrStack.pop(); + } + bjs["swift_js_push_i64"] = function(v) { + i64Stack.push(v); + } + bjs["swift_js_pop_i64"] = function() { + return i64Stack.pop(); + } + const taCtors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array]; + bjs["swift_js_push_typed_array"] = function(kind, ptr, count) { + const Ctor = taCtors[kind]; + const byteLen = count * Ctor.BYTES_PER_ELEMENT; + const copy = memory.buffer.slice(ptr, ptr + byteLen); + taStack.push(Array.from(new Ctor(copy))); + } + bjs["swift_js_struct_lower_Depot_Crate"] = function(objectId) { + structHelpers.M10TestModuleT5DepotT5Crate.lower(swift.memory.getObject(objectId)); + } + bjs["swift_js_struct_lift_Depot_Crate"] = function() { + const value = structHelpers.M10TestModuleT5DepotT5Crate.lift(); + return swift.memory.retain(value); + } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; + const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); + bjs["swift_js_make_promise"] = function() { + let resolve, reject; + const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); + promise[__bjs_promiseSettlers] = { resolve, reject }; + return swift.memory.retain(promise); + } + bjs["swift_js_return_optional_bool"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalBool = null; + } else { + tmpRetOptionalBool = value !== 0; + } + } + bjs["swift_js_return_optional_int"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalInt = null; + } else { + tmpRetOptionalInt = value | 0; + } + } + bjs["swift_js_return_optional_float"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalFloat = null; + } else { + tmpRetOptionalFloat = Math.fround(value); + } + } + bjs["swift_js_return_optional_double"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalDouble = null; + } else { + tmpRetOptionalDouble = value; + } + } + bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = decodeString(ptr, len); + } + } + bjs["swift_js_return_optional_object"] = function(isSome, objectId) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = swift.memory.getObject(objectId); + } + } + bjs["swift_js_return_optional_heap_object"] = function(isSome, pointer) { + if (isSome === 0) { + tmpRetOptionalHeapObject = null; + } else { + tmpRetOptionalHeapObject = pointer; + } + } + bjs["swift_js_get_optional_int_presence"] = function() { + return tmpRetOptionalInt != null ? 1 : 0; + } + bjs["swift_js_get_optional_int_value"] = function() { + const value = tmpRetOptionalInt; + tmpRetOptionalInt = undefined; + return value; + } + bjs["swift_js_get_optional_string"] = function() { + const str = tmpRetString; + tmpRetString = undefined; + if (str == null) { + return -1; + } else { + const bytes = textEncoder.encode(str); + tmpRetBytes = bytes; + return bytes.length; + } + } + bjs["swift_js_get_optional_float_presence"] = function() { + return tmpRetOptionalFloat != null ? 1 : 0; + } + bjs["swift_js_get_optional_float_value"] = function() { + const value = tmpRetOptionalFloat; + tmpRetOptionalFloat = undefined; + return value; + } + bjs["swift_js_get_optional_double_presence"] = function() { + return tmpRetOptionalDouble != null ? 1 : 0; + } + bjs["swift_js_get_optional_double_value"] = function() { + const value = tmpRetOptionalDouble; + tmpRetOptionalDouble = undefined; + return value; + } + bjs["swift_js_get_optional_heap_object_pointer"] = function() { + const pointer = tmpRetOptionalHeapObject; + tmpRetOptionalHeapObject = undefined; + return pointer || 0; + } + bjs["swift_js_closure_unregister"] = function(funcRef) {} + // Wrapper functions for module: TestModule + if (!importObject["TestModule"]) { + importObject["TestModule"] = {}; + } + importObject["TestModule"]["bjs_Depot_wrap"] = function(pointer) { + const obj = _exports['Depot'].__construct(pointer); + return swift.memory.retain(obj); + }; + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + decodeString = (ptr, len) => { const bytes = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); return textDecoder.decode(bytes); } + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => { + if (state.hasReleased) { + return; + } + state.hasReleased = true; + state.identityMap?.delete(state.pointer); + state.deinit(state.pointer); + }); + + /// Represents a Swift heap object like a class instance or an actor instance. + class SwiftHeapObject { + static __wrap(pointer, deinit, prototype, identityCache) { + pointer = pointer >>> 0; + const makeFresh = (identityMap) => { + const obj = Object.create(prototype); + const state = { pointer, deinit, hasReleased: false, identityMap }; + obj.pointer = pointer; + obj.__swiftHeapObjectState = state; + swiftHeapObjectFinalizationRegistry.register(obj, state, state); + if (identityMap) { + identityMap.set(pointer, new WeakRef(obj)); + } + return obj; + }; + + if (!identityCache) { + return makeFresh(null); + } + + const cached = identityCache.get(pointer)?.deref(); + if (cached && !cached.__swiftHeapObjectState.hasReleased) { + deinit(pointer); + return cached; + } + if (identityCache.has(pointer)) { + identityCache.delete(pointer); + } + + return makeFresh(identityCache); + } + + release() { + const state = this.__swiftHeapObjectState; + if (state.hasReleased) { + return; + } + state.hasReleased = true; + swiftHeapObjectFinalizationRegistry.unregister(state); + state.identityMap?.delete(state.pointer); + state.deinit(state.pointer); + } + } + class Depot extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Depot_deinit, Depot.prototype, null); + } + + constructor() { + const ret = instance.exports.bjs_Depot_init(); + return Depot.__construct(ret); + } + } + const __bjs_helpers_M10TestModuleT5DepotT5Crate = __bjs_createStructHelpers_M10TestModuleT5DepotT5Crate(); + structHelpers.M10TestModuleT5DepotT5Crate = __bjs_helpers_M10TestModuleT5DepotT5Crate; + + const exports = { + Depot: Object.assign(Depot, { + Crate: { + init: function(label) { + const labelBytes = textEncoder.encode(label); + const labelId = swift.memory.retain(labelBytes); + instance.exports.bjs_Depot_Crate_init(labelId, labelBytes.length); + const structValue = structHelpers.M10TestModuleT5DepotT5Crate.lift(); + return structValue; + }, + }, + }), + }; + _exports = exports; + return exports; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ExtensionScopeParity.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ExtensionScopeParity.d.ts new file mode 100644 index 000000000..9097d0270 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ExtensionScopeParity.d.ts @@ -0,0 +1,52 @@ +// 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 SignalValues: { + readonly Ready: "ready"; +}; +export type SignalTag = typeof SignalValues[keyof typeof SignalValues]; + +export interface Meta { + note: string; +} +export type SignalObject = typeof SignalValues; + +/// Represents a Swift heap object like a class instance or an actor instance. +export interface SwiftHeapObject { + /// Release the heap object. + /// + /// Note: Calling this method will release the heap object and it will no longer be accessible. + release(): void; +} +export interface Mallet extends SwiftHeapObject { +} +export interface Hammer extends SwiftHeapObject { +} +export type Exports = { + Signal: SignalObject + Meta: { + init(note: string): Meta; + }, + app: { + Toolbox: { + Hammer: { + new(): Hammer; + }, + Mallet: { + new(): Mallet; + }, + }, + }, +} +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/ExtensionScopeParity.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ExtensionScopeParity.js new file mode 100644 index 000000000..6b8ae44b1 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ExtensionScopeParity.js @@ -0,0 +1,354 @@ +// 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 SignalValues = { + Ready: "ready", +}; + +export async function createInstantiator(options, swift) { + let instance; + let memory; + let setException; + let decodeString; + const textDecoder = new TextDecoder("utf-8"); + const textEncoder = new TextEncoder("utf-8"); + let tmpRetString; + let tmpRetBytes; + let tmpRetException; + let tmpRetOptionalBool; + let tmpRetOptionalInt; + let tmpRetOptionalFloat; + let tmpRetOptionalDouble; + let tmpRetOptionalHeapObject; + let strStack = []; + let i32Stack = []; + let i64Stack = []; + let f32Stack = []; + let f64Stack = []; + let ptrStack = []; + let taStack = []; + const enumHelpers = {}; + const structHelpers = {}; + + let _exports = null; + let bjs = null; + const __bjs_createStructHelpers_M10TestModuleT6SignalT4Meta = () => ({ + lower: (value) => { + const bytes = textEncoder.encode(value.note); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return { note: string }; + } + }); + + return { + /** + * @param {WebAssembly.Imports} importObject + */ + addImports: (importObject, importsContext) => { + bjs = {}; + importObject["bjs"] = bjs; + bjs["swift_js_return_string"] = function(ptr, len) { + tmpRetString = decodeString(ptr, len); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr >>> 0); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + return swift.memory.retain(decodeString(ptr, len)); + } + bjs["swift_js_init_memory_with_result"] = function(ptr, len) { + const target = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); + target.set(tmpRetBytes); + tmpRetBytes = undefined; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_push_i32"] = function(v) { + i32Stack.push(v | 0); + } + bjs["swift_js_push_f32"] = function(v) { + f32Stack.push(Math.fround(v)); + } + bjs["swift_js_push_f64"] = function(v) { + f64Stack.push(v); + } + bjs["swift_js_push_string"] = function(ptr, len) { + const value = decodeString(ptr, len); + strStack.push(value); + } + bjs["swift_js_pop_i32"] = function() { + return i32Stack.pop(); + } + bjs["swift_js_pop_f32"] = function() { + return f32Stack.pop(); + } + bjs["swift_js_pop_f64"] = function() { + return f64Stack.pop(); + } + bjs["swift_js_push_pointer"] = function(pointer) { + ptrStack.push(pointer); + } + bjs["swift_js_pop_pointer"] = function() { + return ptrStack.pop(); + } + bjs["swift_js_push_i64"] = function(v) { + i64Stack.push(v); + } + bjs["swift_js_pop_i64"] = function() { + return i64Stack.pop(); + } + const taCtors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array]; + bjs["swift_js_push_typed_array"] = function(kind, ptr, count) { + const Ctor = taCtors[kind]; + const byteLen = count * Ctor.BYTES_PER_ELEMENT; + const copy = memory.buffer.slice(ptr, ptr + byteLen); + taStack.push(Array.from(new Ctor(copy))); + } + bjs["swift_js_struct_lower_Meta"] = function(objectId) { + structHelpers.M10TestModuleT6SignalT4Meta.lower(swift.memory.getObject(objectId)); + } + bjs["swift_js_struct_lift_Meta"] = function() { + const value = structHelpers.M10TestModuleT6SignalT4Meta.lift(); + return swift.memory.retain(value); + } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; + const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); + bjs["swift_js_make_promise"] = function() { + let resolve, reject; + const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); + promise[__bjs_promiseSettlers] = { resolve, reject }; + return swift.memory.retain(promise); + } + bjs["swift_js_return_optional_bool"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalBool = null; + } else { + tmpRetOptionalBool = value !== 0; + } + } + bjs["swift_js_return_optional_int"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalInt = null; + } else { + tmpRetOptionalInt = value | 0; + } + } + bjs["swift_js_return_optional_float"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalFloat = null; + } else { + tmpRetOptionalFloat = Math.fround(value); + } + } + bjs["swift_js_return_optional_double"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalDouble = null; + } else { + tmpRetOptionalDouble = value; + } + } + bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = decodeString(ptr, len); + } + } + bjs["swift_js_return_optional_object"] = function(isSome, objectId) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = swift.memory.getObject(objectId); + } + } + bjs["swift_js_return_optional_heap_object"] = function(isSome, pointer) { + if (isSome === 0) { + tmpRetOptionalHeapObject = null; + } else { + tmpRetOptionalHeapObject = pointer; + } + } + bjs["swift_js_get_optional_int_presence"] = function() { + return tmpRetOptionalInt != null ? 1 : 0; + } + bjs["swift_js_get_optional_int_value"] = function() { + const value = tmpRetOptionalInt; + tmpRetOptionalInt = undefined; + return value; + } + bjs["swift_js_get_optional_string"] = function() { + const str = tmpRetString; + tmpRetString = undefined; + if (str == null) { + return -1; + } else { + const bytes = textEncoder.encode(str); + tmpRetBytes = bytes; + return bytes.length; + } + } + bjs["swift_js_get_optional_float_presence"] = function() { + return tmpRetOptionalFloat != null ? 1 : 0; + } + bjs["swift_js_get_optional_float_value"] = function() { + const value = tmpRetOptionalFloat; + tmpRetOptionalFloat = undefined; + return value; + } + bjs["swift_js_get_optional_double_presence"] = function() { + return tmpRetOptionalDouble != null ? 1 : 0; + } + bjs["swift_js_get_optional_double_value"] = function() { + const value = tmpRetOptionalDouble; + tmpRetOptionalDouble = undefined; + return value; + } + bjs["swift_js_get_optional_heap_object_pointer"] = function() { + const pointer = tmpRetOptionalHeapObject; + tmpRetOptionalHeapObject = undefined; + return pointer || 0; + } + bjs["swift_js_closure_unregister"] = function(funcRef) {} + // Wrapper functions for module: TestModule + if (!importObject["TestModule"]) { + importObject["TestModule"] = {}; + } + importObject["TestModule"]["bjs_app_Toolbox_Hammer_wrap"] = function(pointer) { + const obj = _exports.app.Toolbox.Hammer.__construct(pointer); + return swift.memory.retain(obj); + }; + importObject["TestModule"]["bjs_app_Toolbox_Mallet_wrap"] = function(pointer) { + const obj = _exports.app.Toolbox.Mallet.__construct(pointer); + return swift.memory.retain(obj); + }; + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + decodeString = (ptr, len) => { const bytes = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); return textDecoder.decode(bytes); } + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => { + if (state.hasReleased) { + return; + } + state.hasReleased = true; + state.identityMap?.delete(state.pointer); + state.deinit(state.pointer); + }); + + /// Represents a Swift heap object like a class instance or an actor instance. + class SwiftHeapObject { + static __wrap(pointer, deinit, prototype, identityCache) { + pointer = pointer >>> 0; + const makeFresh = (identityMap) => { + const obj = Object.create(prototype); + const state = { pointer, deinit, hasReleased: false, identityMap }; + obj.pointer = pointer; + obj.__swiftHeapObjectState = state; + swiftHeapObjectFinalizationRegistry.register(obj, state, state); + if (identityMap) { + identityMap.set(pointer, new WeakRef(obj)); + } + return obj; + }; + + if (!identityCache) { + return makeFresh(null); + } + + const cached = identityCache.get(pointer)?.deref(); + if (cached && !cached.__swiftHeapObjectState.hasReleased) { + deinit(pointer); + return cached; + } + if (identityCache.has(pointer)) { + identityCache.delete(pointer); + } + + return makeFresh(identityCache); + } + + release() { + const state = this.__swiftHeapObjectState; + if (state.hasReleased) { + return; + } + state.hasReleased = true; + swiftHeapObjectFinalizationRegistry.unregister(state); + state.identityMap?.delete(state.pointer); + state.deinit(state.pointer); + } + } + class Mallet extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_app_Toolbox_Mallet_deinit, Mallet.prototype, null); + } + + constructor() { + const ret = instance.exports.bjs_app_Toolbox_Mallet_init(); + return Mallet.__construct(ret); + } + } + class Hammer extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_app_Toolbox_Hammer_deinit, Hammer.prototype, null); + } + + constructor() { + const ret = instance.exports.bjs_app_Toolbox_Hammer_init(); + return Hammer.__construct(ret); + } + } + const __bjs_helpers_M10TestModuleT6SignalT4Meta = __bjs_createStructHelpers_M10TestModuleT6SignalT4Meta(); + structHelpers.M10TestModuleT6SignalT4Meta = __bjs_helpers_M10TestModuleT6SignalT4Meta; + + const exports = { + Signal: SignalValues, + Meta: { + init: function(note) { + const noteBytes = textEncoder.encode(note); + const noteId = swift.memory.retain(noteBytes); + instance.exports.bjs_Meta_init(noteId, noteBytes.length); + const structValue = structHelpers.M10TestModuleT6SignalT4Meta.lift(); + return structValue; + }, + }, + app: { + Toolbox: { + Hammer, + Mallet, + }, + }, + }; + _exports = exports; + return exports; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/FixedWidthIntegers.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/FixedWidthIntegers.js index a009f8d71..56a31b784 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/FixedWidthIntegers.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/FixedWidthIntegers.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GenericImports.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GenericImports.d.ts new file mode 100644 index 000000000..026713ce3 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GenericImports.d.ts @@ -0,0 +1,87 @@ +// 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 GenericColorValues: { + readonly Red: 0; + readonly Green: 1; +}; +export type GenericColorTag = typeof GenericColorValues[keyof typeof GenericColorValues]; + +export const GenericModeValues: { + readonly Light: "light"; + readonly Dark: "dark"; +}; +export type GenericModeTag = typeof GenericModeValues[keyof typeof GenericModeValues]; + +export const GenericTaggedValues: { + readonly Tag: { + readonly Number: 0; + readonly Text: 1; + }; +}; + +export type GenericTaggedTag = + { tag: typeof GenericTaggedValues.Tag.Number; value: number } | { tag: typeof GenericTaggedValues.Tag.Text; value: string } + +export interface GenericPoint { + x: number; + y: number; +} +export type GenericColorObject = typeof GenericColorValues; + +export type GenericModeObject = typeof GenericModeValues; + +export type GenericTaggedObject = typeof GenericTaggedValues; + +/// Represents a Swift heap object like a class instance or an actor instance. +export interface SwiftHeapObject { + /// Release the heap object. + /// + /// Note: Calling this method will release the heap object and it will no longer be accessible. + release(): void; +} +export interface GenericImportBox extends SwiftHeapObject { + get(): number; + value: number; +} +export interface GenericPairFactory { +} +export interface GenericConsumer { + accept(value: T): void; + identity(value: T): T; +} +export type Exports = { + GenericColor: GenericColorObject + GenericMode: GenericModeObject + GenericTagged: GenericTaggedObject + GenericImportBox: { + new(value: number): GenericImportBox; + }, +} +export type Imports = { + genericRoundTrip(value: T): T; + genericParse(json: string): T; + importGenericCombine(a: T, b: U): U; + importGenericCaseDistinct(a: T, b: t): T; + importGenericArray(values: T[]): T[]; + importGenericOptional(value: T | null): T | null; + importGenericDictionary(values: Record): Record; + importGenericAfterOptionalArray(values: number[] | null, value: T): T; + GenericPairFactory: { + new(tag: string, first: T, second: U): GenericPairFactory; + } + GenericConsumer: { + new(value: T): GenericConsumer; + box(value: T): T; + } +} +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/GenericImports.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GenericImports.js new file mode 100644 index 000000000..d8b1fdf15 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GenericImports.js @@ -0,0 +1,941 @@ +// 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 GenericColorValues = { + Red: 0, + Green: 1, +}; + +export const GenericModeValues = { + Light: "light", + Dark: "dark", +}; + +export const GenericTaggedValues = { + Tag: { + Number: 0, + Text: 1, + }, +}; +export async function createInstantiator(options, swift) { + let instance; + let memory; + let setException; + let decodeString; + const textDecoder = new TextDecoder("utf-8"); + const textEncoder = new TextEncoder("utf-8"); + let tmpRetString; + let tmpRetBytes; + let tmpRetException; + let tmpRetOptionalBool; + let tmpRetOptionalInt; + let tmpRetOptionalFloat; + let tmpRetOptionalDouble; + let tmpRetOptionalHeapObject; + let strStack = []; + let i32Stack = []; + let i64Stack = []; + let f32Stack = []; + let f64Stack = []; + let ptrStack = []; + let taStack = []; + const enumHelpers = {}; + const structHelpers = {}; + const __bjs_codecByTypeId = new Map(); + let __bjs_typeHandlesRegistered = false; + function __bjs_registerTypeHandles() { + if (__bjs_typeHandlesRegistered) { + return; + } + __bjs_typeHandlesRegistered = true; + instance.exports["bjs_core_register_type_handles"](); + instance.exports["bjs_TestModule_register_type_handles"](); + } + function __bjs_codecForTypeId(typeId) { + __bjs_registerTypeHandles(); + const codec = __bjs_codecByTypeId.get(typeId); + if (!codec) { + throw new Error("BridgeJS: no codec registered for type ID " + typeId); + } + return codec; + } + + let _exports = null; + let bjs = null; + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_Array_Int = __bjs_arrayCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_Optional_Array_Int = __bjs_optionalCodec(__bjs_codec_Array_Int); + const __bjs_codec_M10TestModuleT12GenericPoint = { + lower: (v) => { + structHelpers.M10TestModuleT12GenericPoint.lower(v); + }, + lift: () => { + const struct = structHelpers.M10TestModuleT12GenericPoint.lift(); + return struct; + }, + }; + const __bjs_codec_M10TestModuleT16GenericImportBox = { + lower: (v) => { + ptrStack.push(v.pointer); + }, + lift: () => { + const ptr = ptrStack.pop(); + const obj = _exports['GenericImportBox'].__construct(ptr); + return obj; + }, + }; + const __bjs_codec_M10TestModuleT12GenericColor = { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const caseId = i32Stack.pop(); + return caseId; + }, + }; + const __bjs_codec_M10TestModuleT13GenericTagged = { + lower: (v) => { + const caseId = enumHelpers.M10TestModuleT13GenericTagged.lower(v); + i32Stack.push(caseId); + }, + lift: () => { + const enumValue = enumHelpers.M10TestModuleT13GenericTagged.lift(i32Stack.pop()); + return enumValue; + }, + }; + + const __bjs_createStructHelpers_M10TestModuleT12GenericPoint = () => ({ + lower: (value) => { + i32Stack.push((value.x | 0)); + i32Stack.push((value.y | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + const int1 = i32Stack.pop(); + return { x: int1, y: int }; + } + }); + const __bjs_createEnumHelpers_M10TestModuleT13GenericTagged = () => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case GenericTaggedValues.Tag.Number: { + i32Stack.push((value.value | 0)); + return GenericTaggedValues.Tag.Number; + } + case GenericTaggedValues.Tag.Text: { + const bytes = textEncoder.encode(value.value); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + return GenericTaggedValues.Tag.Text; + } + default: throw new Error("Unknown GenericTaggedValues tag: " + String(enumTag)); + } + }, + lift: (tag) => { + tag = tag | 0; + switch (tag) { + case GenericTaggedValues.Tag.Number: { + const int = i32Stack.pop(); + return { tag: GenericTaggedValues.Tag.Number, value: int }; + } + case GenericTaggedValues.Tag.Text: { + const string = strStack.pop(); + return { tag: GenericTaggedValues.Tag.Text, value: string }; + } + default: throw new Error("Unknown GenericTaggedValues tag returned from Swift: " + String(tag)); + } + } + }); + + return { + /** + * @param {WebAssembly.Imports} importObject + */ + addImports: (importObject, importsContext) => { + bjs = {}; + importObject["bjs"] = bjs; + const imports = options.getImports(importsContext); + bjs["swift_js_return_string"] = function(ptr, len) { + tmpRetString = decodeString(ptr, len); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr >>> 0); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + return swift.memory.retain(decodeString(ptr, len)); + } + bjs["swift_js_init_memory_with_result"] = function(ptr, len) { + const target = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); + target.set(tmpRetBytes); + tmpRetBytes = undefined; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_push_i32"] = function(v) { + i32Stack.push(v | 0); + } + bjs["swift_js_push_f32"] = function(v) { + f32Stack.push(Math.fround(v)); + } + bjs["swift_js_push_f64"] = function(v) { + f64Stack.push(v); + } + bjs["swift_js_push_string"] = function(ptr, len) { + const value = decodeString(ptr, len); + strStack.push(value); + } + bjs["swift_js_pop_i32"] = function() { + return i32Stack.pop(); + } + bjs["swift_js_pop_f32"] = function() { + return f32Stack.pop(); + } + bjs["swift_js_pop_f64"] = function() { + return f64Stack.pop(); + } + bjs["swift_js_push_pointer"] = function(pointer) { + ptrStack.push(pointer); + } + bjs["swift_js_pop_pointer"] = function() { + return ptrStack.pop(); + } + bjs["swift_js_push_i64"] = function(v) { + i64Stack.push(v); + } + bjs["swift_js_pop_i64"] = function() { + return i64Stack.pop(); + } + const taCtors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array]; + bjs["swift_js_push_typed_array"] = function(kind, ptr, count) { + const Ctor = taCtors[kind]; + const byteLen = count * Ctor.BYTES_PER_ELEMENT; + const copy = memory.buffer.slice(ptr, ptr + byteLen); + taStack.push(Array.from(new Ctor(copy))); + } + bjs["swift_js_struct_lower_GenericPoint"] = function(objectId) { + structHelpers.M10TestModuleT12GenericPoint.lower(swift.memory.getObject(objectId)); + } + bjs["swift_js_struct_lift_GenericPoint"] = function() { + const value = structHelpers.M10TestModuleT12GenericPoint.lift(); + return swift.memory.retain(value); + } + bjs["bjs_core_register_type_handles"] = function(base, count) { + const codecs = [ + __bjs_primitiveCodecs.Bool, + __bjs_primitiveCodecs.Int, + __bjs_primitiveCodecs.Int8, + __bjs_primitiveCodecs.UInt8, + __bjs_primitiveCodecs.Int16, + __bjs_primitiveCodecs.UInt16, + __bjs_primitiveCodecs.Int32, + __bjs_primitiveCodecs.UInt32, + __bjs_primitiveCodecs.UInt, + __bjs_primitiveCodecs.Int64, + __bjs_primitiveCodecs.UInt64, + __bjs_primitiveCodecs.Float, + __bjs_primitiveCodecs.Double, + __bjs_primitiveCodecs.String, + __bjs_primitiveCodecs.JSValue, + ]; + const typeIds = new Int32Array(memory.buffer, base >>> 0, count >>> 0); + for (let i = 0; i < count; i++) { + __bjs_codecByTypeId.set(typeIds[i], codecs[i]); + } + } + bjs["bjs_TestModule_register_type_handles"] = function(base, count) { + const codecs = [ + __bjs_codec_M10TestModuleT12GenericPoint, + __bjs_codec_M10TestModuleT16GenericImportBox, + __bjs_codec_M10TestModuleT12GenericColor, + __bjs_stringCodec, + __bjs_codec_M10TestModuleT13GenericTagged, + ]; + const typeIds = new Int32Array(memory.buffer, base >>> 0, count >>> 0); + for (let i = 0; i < count; i++) { + __bjs_codecByTypeId.set(typeIds[i], codecs[i]); + } + } + const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); + bjs["swift_js_make_promise"] = function() { + let resolve, reject; + const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); + promise[__bjs_promiseSettlers] = { resolve, reject }; + return swift.memory.retain(promise); + } + bjs["swift_js_return_optional_bool"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalBool = null; + } else { + tmpRetOptionalBool = value !== 0; + } + } + bjs["swift_js_return_optional_int"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalInt = null; + } else { + tmpRetOptionalInt = value | 0; + } + } + bjs["swift_js_return_optional_float"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalFloat = null; + } else { + tmpRetOptionalFloat = Math.fround(value); + } + } + bjs["swift_js_return_optional_double"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalDouble = null; + } else { + tmpRetOptionalDouble = value; + } + } + bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = decodeString(ptr, len); + } + } + bjs["swift_js_return_optional_object"] = function(isSome, objectId) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = swift.memory.getObject(objectId); + } + } + bjs["swift_js_return_optional_heap_object"] = function(isSome, pointer) { + if (isSome === 0) { + tmpRetOptionalHeapObject = null; + } else { + tmpRetOptionalHeapObject = pointer; + } + } + bjs["swift_js_get_optional_int_presence"] = function() { + return tmpRetOptionalInt != null ? 1 : 0; + } + bjs["swift_js_get_optional_int_value"] = function() { + const value = tmpRetOptionalInt; + tmpRetOptionalInt = undefined; + return value; + } + bjs["swift_js_get_optional_string"] = function() { + const str = tmpRetString; + tmpRetString = undefined; + if (str == null) { + return -1; + } else { + const bytes = textEncoder.encode(str); + tmpRetBytes = bytes; + return bytes.length; + } + } + bjs["swift_js_get_optional_float_presence"] = function() { + return tmpRetOptionalFloat != null ? 1 : 0; + } + bjs["swift_js_get_optional_float_value"] = function() { + const value = tmpRetOptionalFloat; + tmpRetOptionalFloat = undefined; + return value; + } + bjs["swift_js_get_optional_double_presence"] = function() { + return tmpRetOptionalDouble != null ? 1 : 0; + } + bjs["swift_js_get_optional_double_value"] = function() { + const value = tmpRetOptionalDouble; + tmpRetOptionalDouble = undefined; + return value; + } + bjs["swift_js_get_optional_heap_object_pointer"] = function() { + const pointer = tmpRetOptionalHeapObject; + tmpRetOptionalHeapObject = undefined; + return pointer || 0; + } + bjs["swift_js_closure_unregister"] = function(funcRef) {} + // Wrapper functions for module: TestModule + if (!importObject["TestModule"]) { + importObject["TestModule"] = {}; + } + importObject["TestModule"]["bjs_GenericImportBox_wrap"] = function(pointer) { + const obj = _exports['GenericImportBox'].__construct(pointer); + return swift.memory.retain(obj); + }; + const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; + TestModule["bjs_genericRoundTrip"] = function bjs_genericRoundTrip(tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const value = codecT.lift(); + let ret = imports.genericRoundTrip(value); + codecT.lower(ret); + } catch (error) { + setException(error); + } + } + TestModule["bjs_genericParse"] = function bjs_genericParse(jsonBytes, jsonCount, tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const string = decodeString(jsonBytes, jsonCount); + let ret = imports.genericParse(string); + codecT.lower(ret); + } catch (error) { + setException(error); + } + } + TestModule["bjs_importGenericCombine"] = function bjs_importGenericCombine(tTypeId, uTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const codecU = __bjs_codecForTypeId(uTypeId); + const a = codecT.lift(); + const b = codecU.lift(); + let ret = imports.importGenericCombine(a, b); + codecU.lower(ret); + } catch (error) { + setException(error); + } + } + TestModule["bjs_importGenericCaseDistinct"] = function bjs_importGenericCaseDistinct(tTypeId, tTypeId1) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const codect = __bjs_codecForTypeId(tTypeId1); + const a = codecT.lift(); + const b = codect.lift(); + let ret = imports.importGenericCaseDistinct(a, b); + codecT.lower(ret); + } catch (error) { + setException(error); + } + } + TestModule["bjs_importGenericArray"] = function bjs_importGenericArray(tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const values = __bjs_arrayCodec(codecT).lift(); + let ret = imports.importGenericArray(values); + __bjs_arrayCodec(codecT).lower(ret); + } catch (error) { + setException(error); + } + } + TestModule["bjs_importGenericOptional"] = function bjs_importGenericOptional(tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const value = __bjs_optionalCodec(codecT).lift(); + let ret = imports.importGenericOptional(value); + __bjs_optionalCodec(codecT).lower(ret); + } catch (error) { + setException(error); + } + } + TestModule["bjs_importGenericDictionary"] = function bjs_importGenericDictionary(tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const values = __bjs_dictCodec(codecT).lift(); + let ret = imports.importGenericDictionary(values); + __bjs_dictCodec(codecT).lower(ret); + } catch (error) { + setException(error); + } + } + TestModule["bjs_importGenericAfterOptionalArray"] = function bjs_importGenericAfterOptionalArray(tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const optValue = __bjs_codec_Optional_Array_Int.lift(); + const value = codecT.lift(); + let ret = imports.importGenericAfterOptionalArray(optValue, value); + codecT.lower(ret); + } catch (error) { + setException(error); + } + } + TestModule["bjs_GenericPairFactory_init"] = function bjs_GenericPairFactory_init(tagBytes, tagCount, tTypeId, uTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const codecU = __bjs_codecForTypeId(uTypeId); + const string = decodeString(tagBytes, tagCount); + const first = codecT.lift(); + const second = codecU.lift(); + return swift.memory.retain(new imports.GenericPairFactory(string, first, second)); + } catch (error) { + setException(error); + return 0 + } + } + TestModule["bjs_GenericConsumer_init"] = function bjs_GenericConsumer_init(tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const value = codecT.lift(); + return swift.memory.retain(new imports.GenericConsumer(value)); + } catch (error) { + setException(error); + return 0 + } + } + TestModule["bjs_GenericConsumer_box_static"] = function bjs_GenericConsumer_box_static(tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const value = codecT.lift(); + let ret = imports.GenericConsumer.box(value); + codecT.lower(ret); + } catch (error) { + setException(error); + } + } + TestModule["bjs_GenericConsumer_accept"] = function bjs_GenericConsumer_accept(self, tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const value = codecT.lift(); + swift.memory.getObject(self).accept(value); + } catch (error) { + setException(error); + } + } + TestModule["bjs_GenericConsumer_identity"] = function bjs_GenericConsumer_identity(self, tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const value = codecT.lift(); + let ret = swift.memory.getObject(self).identity(value); + codecT.lower(ret); + } catch (error) { + setException(error); + } + } + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + decodeString = (ptr, len) => { const bytes = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); return textDecoder.decode(bytes); } + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => { + if (state.hasReleased) { + return; + } + state.hasReleased = true; + state.identityMap?.delete(state.pointer); + state.deinit(state.pointer); + }); + + /// Represents a Swift heap object like a class instance or an actor instance. + class SwiftHeapObject { + static __wrap(pointer, deinit, prototype, identityCache) { + pointer = pointer >>> 0; + const makeFresh = (identityMap) => { + const obj = Object.create(prototype); + const state = { pointer, deinit, hasReleased: false, identityMap }; + obj.pointer = pointer; + obj.__swiftHeapObjectState = state; + swiftHeapObjectFinalizationRegistry.register(obj, state, state); + if (identityMap) { + identityMap.set(pointer, new WeakRef(obj)); + } + return obj; + }; + + if (!identityCache) { + return makeFresh(null); + } + + const cached = identityCache.get(pointer)?.deref(); + if (cached && !cached.__swiftHeapObjectState.hasReleased) { + deinit(pointer); + return cached; + } + if (identityCache.has(pointer)) { + identityCache.delete(pointer); + } + + return makeFresh(identityCache); + } + + release() { + const state = this.__swiftHeapObjectState; + if (state.hasReleased) { + return; + } + state.hasReleased = true; + swiftHeapObjectFinalizationRegistry.unregister(state); + state.identityMap?.delete(state.pointer); + state.deinit(state.pointer); + } + } + class GenericImportBox extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_GenericImportBox_deinit, GenericImportBox.prototype, null); + } + + constructor(value) { + const ret = instance.exports.bjs_GenericImportBox_init(value); + return GenericImportBox.__construct(ret); + } + get() { + const ret = instance.exports.bjs_GenericImportBox_get(this.pointer); + return ret; + } + get value() { + const ret = instance.exports.bjs_GenericImportBox_value_get(this.pointer); + return ret; + } + set value(value) { + instance.exports.bjs_GenericImportBox_value_set(this.pointer, value); + } + } + const __bjs_helpers_M10TestModuleT12GenericPoint = __bjs_createStructHelpers_M10TestModuleT12GenericPoint(); + structHelpers.M10TestModuleT12GenericPoint = __bjs_helpers_M10TestModuleT12GenericPoint; + + const __bjs_helpers_M10TestModuleT13GenericTagged = __bjs_createEnumHelpers_M10TestModuleT13GenericTagged(); + enumHelpers.M10TestModuleT13GenericTagged = __bjs_helpers_M10TestModuleT13GenericTagged; + + const exports = { + GenericColor: GenericColorValues, + GenericMode: GenericModeValues, + GenericTagged: GenericTaggedValues, + GenericImportBox, + }; + _exports = exports; + return exports; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalGetter.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalGetter.js index b1d830768..adb70913c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalGetter.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalGetter.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalThisImports.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalThisImports.js index 6f43c2d9c..760a6b50c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalThisImports.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalThisImports.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.ConfigPointer.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.ConfigPointer.js index 83f53d8a6..1e1d14696 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.ConfigPointer.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.ConfigPointer.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.PerClass.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.PerClass.js index bb6f36902..c85aee3af 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.PerClass.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.PerClass.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.js index bb6f36902..c85aee3af 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportArray.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportArray.js index 07341894e..c92ea6ad3 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportArray.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportArray.js @@ -31,6 +31,333 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_Array_Int = __bjs_arrayCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_Array_String = __bjs_arrayCodec(__bjs_stringCodec); + const __bjs_codec_Optional_Array_Int = __bjs_optionalCodec(__bjs_codec_Array_Int); + return { /** @@ -107,6 +434,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -207,119 +535,38 @@ export async function createInstantiator(options, swift) { const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_roundtrip"] = function bjs_roundtrip() { try { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Int.lift(); let ret = imports.roundtrip(arrayResult); - for (const elem of ret) { - i32Stack.push((elem | 0)); - } - i32Stack.push(ret.length); + __bjs_codec_Array_Int.lower(ret); } catch (error) { setException(error); } } TestModule["bjs_logStrings"] = function bjs_logStrings() { try { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const string = strStack.pop(); - arrayResult.push(string); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_String.lift(); imports.logStrings(arrayResult); } catch (error) { setException(error); } } - TestModule["bjs_optionalArrayThenArray"] = function bjs_optionalArrayThenArray(a) { + TestModule["bjs_optionalArrayThenArray"] = function bjs_optionalArrayThenArray() { try { - let optResult; - if (a) { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } - optResult = arrayResult; - } else { - optResult = null; - } - const arrayLen1 = i32Stack.pop(); - let arrayResult1; - if (arrayLen1 === -1) { - arrayResult1 = taStack.pop(); - } else { - arrayResult1 = []; - for (let i1 = 0; i1 < arrayLen1; i1++) { - const int1 = i32Stack.pop(); - arrayResult1.push(int1); - } - arrayResult1.reverse(); - } - let ret = imports.optionalArrayThenArray(optResult, arrayResult1); + const optValue = __bjs_codec_Optional_Array_Int.lift(); + const arrayResult = __bjs_codec_Array_Int.lift(); + let ret = imports.optionalArrayThenArray(optValue, arrayResult); return ret; } catch (error) { setException(error); return 0 } } - TestModule["bjs_borrowedStringAroundStackParams"] = function bjs_borrowedStringAroundStackParams(sBytes, sCount, a) { + TestModule["bjs_borrowedStringAroundStackParams"] = function bjs_borrowedStringAroundStackParams(sBytes, sCount) { try { const string = decodeString(sBytes, sCount); - let optResult; - if (a) { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } - optResult = arrayResult; - } else { - optResult = null; - } - const arrayLen1 = i32Stack.pop(); - let arrayResult1; - if (arrayLen1 === -1) { - arrayResult1 = taStack.pop(); - } else { - arrayResult1 = []; - for (let i1 = 0; i1 < arrayLen1; i1++) { - const int1 = i32Stack.pop(); - arrayResult1.push(int1); - } - arrayResult1.reverse(); - } - let ret = imports.borrowedStringAroundStackParams(string, optResult, arrayResult1); + const optValue = __bjs_codec_Optional_Array_Int.lift(); + const arrayResult = __bjs_codec_Array_Int.lift(); + let ret = imports.borrowedStringAroundStackParams(string, optValue, arrayResult); return ret; } catch (error) { setException(error); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportedTypeInExportedInterface.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportedTypeInExportedInterface.js index 4328e4d4e..363f6c595 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportedTypeInExportedInterface.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportedTypeInExportedInterface.js @@ -31,7 +31,346 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createFooContainerHelpers = () => ({ + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_Foo = { + lower: (v) => { + const objId = swift.memory.retain(v); + i32Stack.push(objId); + }, + lift: () => { + const objId = i32Stack.pop(); + const obj = swift.memory.getObject(objId); + swift.memory.release(objId); + return obj; + }, + }; + const __bjs_codec_Array_Foo = __bjs_arrayCodec(__bjs_codec_Foo); + const __bjs_codec_Optional_Foo = __bjs_optionalCodec(__bjs_codec_Foo); + const __bjs_codec_Array_Optional_Foo = __bjs_arrayCodec(__bjs_codec_Optional_Foo); + + const __bjs_createStructHelpers_M10TestModuleT12FooContainer = () => ({ lower: (value) => { let id; if (value.foo != null) { @@ -40,24 +379,10 @@ export async function createInstantiator(options, swift) { id = undefined; } i32Stack.push(id !== undefined ? id : 0); - const isSome = value.optionalFoo != null ? 1 : 0; - if (isSome) { - const objId = swift.memory.retain(value.optionalFoo); - i32Stack.push(objId); - } - i32Stack.push(isSome); + __bjs_codec_Optional_Foo.lower(value.optionalFoo); }, lift: () => { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const objId = i32Stack.pop(); - const obj = swift.memory.getObject(objId); - swift.memory.release(objId); - optValue = obj; - } + const optValue = __bjs_codec_Optional_Foo.lift(); const objectId = i32Stack.pop(); let value; if (objectId !== 0) { @@ -146,12 +471,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_FooContainer"] = function(objectId) { - structHelpers.FooContainer.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT12FooContainer.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_FooContainer"] = function() { - const value = structHelpers.FooContainer.lift(); + const value = structHelpers.M10TestModuleT12FooContainer.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -272,8 +599,8 @@ export async function createInstantiator(options, swift) { /** @param {WebAssembly.Instance} instance */ createExports: (instance) => { const js = swift.memory.heap; - const FooContainerHelpers = __bjs_createFooContainerHelpers(); - structHelpers.FooContainer = FooContainerHelpers; + const __bjs_helpers_M10TestModuleT12FooContainer = __bjs_createStructHelpers_M10TestModuleT12FooContainer(); + structHelpers.M10TestModuleT12FooContainer = __bjs_helpers_M10TestModuleT12FooContainer; const exports = { makeFoo: function bjs_makeFoo() { @@ -289,66 +616,21 @@ export async function createInstantiator(options, swift) { return ret1; }, processFooArray: function bjs_processFooArray(foos) { - for (const elem of foos) { - const objId = swift.memory.retain(elem); - i32Stack.push(objId); - } - i32Stack.push(foos.length); + __bjs_codec_Array_Foo.lower(foos); instance.exports.bjs_processFooArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const objId1 = i32Stack.pop(); - const obj = swift.memory.getObject(objId1); - swift.memory.release(objId1); - arrayResult.push(obj); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Foo.lift(); return arrayResult; }, processOptionalFooArray: function bjs_processOptionalFooArray(foos) { - for (const elem of foos) { - const isSome = elem != null ? 1 : 0; - if (isSome) { - const objId = swift.memory.retain(elem); - i32Stack.push(objId); - } - i32Stack.push(isSome); - } - i32Stack.push(foos.length); + __bjs_codec_Array_Optional_Foo.lower(foos); instance.exports.bjs_processOptionalFooArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const isSome1 = i32Stack.pop(); - let optValue; - if (isSome1 === 0) { - optValue = null; - } else { - const objId1 = i32Stack.pop(); - const obj = swift.memory.getObject(objId1); - swift.memory.release(objId1); - optValue = obj; - } - arrayResult.push(optValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Optional_Foo.lift(); return arrayResult; }, roundtripFooContainer: function bjs_roundtripFooContainer(container) { - structHelpers.FooContainer.lower(container); + structHelpers.M10TestModuleT12FooContainer.lower(container); instance.exports.bjs_roundtripFooContainer(); - const structValue = structHelpers.FooContainer.lift(); + const structValue = structHelpers.M10TestModuleT12FooContainer.lift(); return structValue; }, }; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.js index 8d1ac2698..e8fe5ec10 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClass.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClass.js index 08215f159..15b48d4b9 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClass.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClass.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClassStaticFunctions.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClassStaticFunctions.js index a38b0a391..5eaba3c8f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClassStaticFunctions.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClassStaticFunctions.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportBareModule.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportBareModule.js index 1c995923a..6d1b1b6fb 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportBareModule.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportBareModule.js @@ -112,6 +112,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportBareModuleFallback.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportBareModuleFallback.js index 038374240..9428698be 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportBareModuleFallback.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportBareModuleFallback.js @@ -109,6 +109,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportModule.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportModule.js index e03dcbab4..aacf5e61a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportModule.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportModule.js @@ -109,6 +109,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSNameOverride.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSNameOverride.d.ts new file mode 100644 index 000000000..d31aeebe3 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSNameOverride.d.ts @@ -0,0 +1,68 @@ +// 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 RenamedEnumMembersValues: { + readonly Active: 0; + readonly Inactive: 1; +}; +export type RenamedEnumMembersTag = typeof RenamedEnumMembersValues[keyof typeof RenamedEnumMembersValues]; + +export interface RenamedVector { + dx: number; + dy: number; + magnitude(): number; +} +export type RenamedEnumMembersObject = typeof RenamedEnumMembersValues & { + describeCase(): string; + currentDefault: string; +}; + +/// Represents a Swift heap object like a class instance or an actor instance. +export interface SwiftHeapObject { + /// Release the heap object. + /// + /// Note: Calling this method will release the heap object and it will no longer be accessible. + release(): void; +} +export interface RenamedMembers extends SwiftHeapObject { + makeGreeting(): string; + label: string; + readonly total: number; +} +export type Exports = { + makeGreeting(name: string): string; + greetName(name: string): string; + greetCount(count: number): string; + RenamedEnumMembers: RenamedEnumMembersObject + RenamedMembers: { + new(title: string, count: number): RenamedMembers; + makeDefault(): RenamedMembers; + sharedTotal: number; + readonly readOnlyLimit: number; + }, + RenamedNamespaceMembers: { + theAnswer: number; + plus(a: number, b: number): number; + }, + RenamedVector: { + readonly originVector: RenamedVector; + fromPolar(radius: number, angle: number): RenamedVector; + }, + Utils: { + Text: { + namespacedRenamed(): number; + }, + }, +} +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/JSNameOverride.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSNameOverride.js new file mode 100644 index 000000000..68ac11976 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSNameOverride.js @@ -0,0 +1,444 @@ +// 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 RenamedEnumMembersValues = { + Active: 0, + Inactive: 1, +}; + +export async function createInstantiator(options, swift) { + let instance; + let memory; + let setException; + let decodeString; + const textDecoder = new TextDecoder("utf-8"); + const textEncoder = new TextEncoder("utf-8"); + let tmpRetString; + let tmpRetBytes; + let tmpRetException; + let tmpRetOptionalBool; + let tmpRetOptionalInt; + let tmpRetOptionalFloat; + let tmpRetOptionalDouble; + let tmpRetOptionalHeapObject; + let strStack = []; + let i32Stack = []; + let i64Stack = []; + let f32Stack = []; + let f64Stack = []; + let ptrStack = []; + let taStack = []; + const enumHelpers = {}; + const structHelpers = {}; + + let _exports = null; + let bjs = null; + const __bjs_createStructHelpers_M10TestModuleT13RenamedVector = () => ({ + lower: (value) => { + f64Stack.push(value.dx); + f64Stack.push(value.dy); + }, + lift: () => { + const f64 = f64Stack.pop(); + const f641 = f64Stack.pop(); + const instance1 = { dx: f641, dy: f64 }; + instance1.magnitude = function() { + structHelpers.M10TestModuleT13RenamedVector.lower(this); + const ret = instance.exports.bjs_RenamedVector_magnitude(); + return ret; + }.bind(instance1); + return instance1; + } + }); + + return { + /** + * @param {WebAssembly.Imports} importObject + */ + addImports: (importObject, importsContext) => { + bjs = {}; + importObject["bjs"] = bjs; + bjs["swift_js_return_string"] = function(ptr, len) { + tmpRetString = decodeString(ptr, len); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr >>> 0); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + return swift.memory.retain(decodeString(ptr, len)); + } + bjs["swift_js_init_memory_with_result"] = function(ptr, len) { + const target = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); + target.set(tmpRetBytes); + tmpRetBytes = undefined; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_push_i32"] = function(v) { + i32Stack.push(v | 0); + } + bjs["swift_js_push_f32"] = function(v) { + f32Stack.push(Math.fround(v)); + } + bjs["swift_js_push_f64"] = function(v) { + f64Stack.push(v); + } + bjs["swift_js_push_string"] = function(ptr, len) { + const value = decodeString(ptr, len); + strStack.push(value); + } + bjs["swift_js_pop_i32"] = function() { + return i32Stack.pop(); + } + bjs["swift_js_pop_f32"] = function() { + return f32Stack.pop(); + } + bjs["swift_js_pop_f64"] = function() { + return f64Stack.pop(); + } + bjs["swift_js_push_pointer"] = function(pointer) { + ptrStack.push(pointer); + } + bjs["swift_js_pop_pointer"] = function() { + return ptrStack.pop(); + } + bjs["swift_js_push_i64"] = function(v) { + i64Stack.push(v); + } + bjs["swift_js_pop_i64"] = function() { + return i64Stack.pop(); + } + const taCtors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array]; + bjs["swift_js_push_typed_array"] = function(kind, ptr, count) { + const Ctor = taCtors[kind]; + const byteLen = count * Ctor.BYTES_PER_ELEMENT; + const copy = memory.buffer.slice(ptr, ptr + byteLen); + taStack.push(Array.from(new Ctor(copy))); + } + bjs["swift_js_struct_lower_RenamedVector"] = function(objectId) { + structHelpers.M10TestModuleT13RenamedVector.lower(swift.memory.getObject(objectId)); + } + bjs["swift_js_struct_lift_RenamedVector"] = function() { + const value = structHelpers.M10TestModuleT13RenamedVector.lift(); + return swift.memory.retain(value); + } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; + const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); + bjs["swift_js_make_promise"] = function() { + let resolve, reject; + const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); + promise[__bjs_promiseSettlers] = { resolve, reject }; + return swift.memory.retain(promise); + } + bjs["swift_js_return_optional_bool"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalBool = null; + } else { + tmpRetOptionalBool = value !== 0; + } + } + bjs["swift_js_return_optional_int"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalInt = null; + } else { + tmpRetOptionalInt = value | 0; + } + } + bjs["swift_js_return_optional_float"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalFloat = null; + } else { + tmpRetOptionalFloat = Math.fround(value); + } + } + bjs["swift_js_return_optional_double"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalDouble = null; + } else { + tmpRetOptionalDouble = value; + } + } + bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = decodeString(ptr, len); + } + } + bjs["swift_js_return_optional_object"] = function(isSome, objectId) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = swift.memory.getObject(objectId); + } + } + bjs["swift_js_return_optional_heap_object"] = function(isSome, pointer) { + if (isSome === 0) { + tmpRetOptionalHeapObject = null; + } else { + tmpRetOptionalHeapObject = pointer; + } + } + bjs["swift_js_get_optional_int_presence"] = function() { + return tmpRetOptionalInt != null ? 1 : 0; + } + bjs["swift_js_get_optional_int_value"] = function() { + const value = tmpRetOptionalInt; + tmpRetOptionalInt = undefined; + return value; + } + bjs["swift_js_get_optional_string"] = function() { + const str = tmpRetString; + tmpRetString = undefined; + if (str == null) { + return -1; + } else { + const bytes = textEncoder.encode(str); + tmpRetBytes = bytes; + return bytes.length; + } + } + bjs["swift_js_get_optional_float_presence"] = function() { + return tmpRetOptionalFloat != null ? 1 : 0; + } + bjs["swift_js_get_optional_float_value"] = function() { + const value = tmpRetOptionalFloat; + tmpRetOptionalFloat = undefined; + return value; + } + bjs["swift_js_get_optional_double_presence"] = function() { + return tmpRetOptionalDouble != null ? 1 : 0; + } + bjs["swift_js_get_optional_double_value"] = function() { + const value = tmpRetOptionalDouble; + tmpRetOptionalDouble = undefined; + return value; + } + bjs["swift_js_get_optional_heap_object_pointer"] = function() { + const pointer = tmpRetOptionalHeapObject; + tmpRetOptionalHeapObject = undefined; + return pointer || 0; + } + bjs["swift_js_closure_unregister"] = function(funcRef) {} + // Wrapper functions for module: TestModule + if (!importObject["TestModule"]) { + importObject["TestModule"] = {}; + } + importObject["TestModule"]["bjs_RenamedMembers_wrap"] = function(pointer) { + const obj = _exports['RenamedMembers'].__construct(pointer); + return swift.memory.retain(obj); + }; + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + decodeString = (ptr, len) => { const bytes = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); return textDecoder.decode(bytes); } + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => { + if (state.hasReleased) { + return; + } + state.hasReleased = true; + state.identityMap?.delete(state.pointer); + state.deinit(state.pointer); + }); + + /// Represents a Swift heap object like a class instance or an actor instance. + class SwiftHeapObject { + static __wrap(pointer, deinit, prototype, identityCache) { + pointer = pointer >>> 0; + const makeFresh = (identityMap) => { + const obj = Object.create(prototype); + const state = { pointer, deinit, hasReleased: false, identityMap }; + obj.pointer = pointer; + obj.__swiftHeapObjectState = state; + swiftHeapObjectFinalizationRegistry.register(obj, state, state); + if (identityMap) { + identityMap.set(pointer, new WeakRef(obj)); + } + return obj; + }; + + if (!identityCache) { + return makeFresh(null); + } + + const cached = identityCache.get(pointer)?.deref(); + if (cached && !cached.__swiftHeapObjectState.hasReleased) { + deinit(pointer); + return cached; + } + if (identityCache.has(pointer)) { + identityCache.delete(pointer); + } + + return makeFresh(identityCache); + } + + release() { + const state = this.__swiftHeapObjectState; + if (state.hasReleased) { + return; + } + state.hasReleased = true; + swiftHeapObjectFinalizationRegistry.unregister(state); + state.identityMap?.delete(state.pointer); + state.deinit(state.pointer); + } + } + class RenamedMembers extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_RenamedMembers_deinit, RenamedMembers.prototype, null); + } + + constructor(title, count) { + const titleBytes = textEncoder.encode(title); + const titleId = swift.memory.retain(titleBytes); + const ret = instance.exports.bjs_RenamedMembers_init(titleId, titleBytes.length, count); + return RenamedMembers.__construct(ret); + } + makeGreeting() { + instance.exports.bjs_RenamedMembers_makeGreeting(this.pointer); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + } + static makeDefault() { + const ret = instance.exports.bjs_RenamedMembers_static_makeDefault(); + return RenamedMembers.__construct(ret); + } + get label() { + instance.exports.bjs_RenamedMembers_title_get(this.pointer); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + } + set label(value) { + const valueBytes = textEncoder.encode(value); + const valueId = swift.memory.retain(valueBytes); + instance.exports.bjs_RenamedMembers_title_set(this.pointer, valueId, valueBytes.length); + } + get total() { + const ret = instance.exports.bjs_RenamedMembers_count_get(this.pointer); + return ret; + } + static get sharedTotal() { + const ret = instance.exports.bjs_RenamedMembers_static_sharedCount_get(); + return ret; + } + static set sharedTotal(value) { + instance.exports.bjs_RenamedMembers_static_sharedCount_set(value); + } + static get readOnlyLimit() { + const ret = instance.exports.bjs_RenamedMembers_static_limit_get(); + return ret; + } + } + const __bjs_helpers_M10TestModuleT13RenamedVector = __bjs_createStructHelpers_M10TestModuleT13RenamedVector(); + structHelpers.M10TestModuleT13RenamedVector = __bjs_helpers_M10TestModuleT13RenamedVector; + + const exports = { + makeGreeting: function bjs_makeGreeting(name) { + const nameBytes = textEncoder.encode(name); + const nameId = swift.memory.retain(nameBytes); + instance.exports.bjs_makeGreeting(nameId, nameBytes.length); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + greetName: function bjs_greetName(name) { + const nameBytes = textEncoder.encode(name); + const nameId = swift.memory.retain(nameBytes); + instance.exports.bjs_greetName(nameId, nameBytes.length); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + greetCount: function bjs_greetCount(count) { + instance.exports.bjs_greetCount(count); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + RenamedEnumMembers: { + ...RenamedEnumMembersValues, + describeCase: function() { + instance.exports.bjs_RenamedEnumMembers_static_describeCase(); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + get currentDefault() { + instance.exports.bjs_RenamedEnumMembers_static_defaultValue_get(); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + set currentDefault(value) { + const valueBytes = textEncoder.encode(value); + const valueId = swift.memory.retain(valueBytes); + instance.exports.bjs_RenamedEnumMembers_static_defaultValue_set(valueId, valueBytes.length); + } + }, + RenamedMembers, + RenamedNamespaceMembers: { + get theAnswer() { + const ret = instance.exports.bjs_RenamedNamespaceMembers_static_answer_get(); + return ret; + }, + set theAnswer(value) { + instance.exports.bjs_RenamedNamespaceMembers_static_answer_set(value); + }, + plus: function bjs_RenamedNamespaceMembers_static_plus(a, b) { + const ret = instance.exports.bjs_RenamedNamespaceMembers_static_plus(a, b); + return ret; + }, + }, + RenamedVector: { + get originVector() { + instance.exports.bjs_RenamedVector_static_origin_get(); + const structValue = structHelpers.M10TestModuleT13RenamedVector.lift(); + return structValue; + }, + fromPolar: function(radius, angle) { + instance.exports.bjs_RenamedVector_static_fromPolar(radius, angle); + const structValue = structHelpers.M10TestModuleT13RenamedVector.lift(); + return structValue; + }, + }, + Utils: { + Text: { + namespacedRenamed: function bjs_Utils_Text_namespacedRenamed() { + const ret = instance.exports.bjs_Utils_Text_namespacedRenamed(); + return ret; + }, + }, + }, + }; + _exports = exports; + return exports; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSTypedArrayTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSTypedArrayTypes.js index 5c713cc78..f02f6bcf2 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSTypedArrayTypes.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSTypedArrayTypes.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSValue.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSValue.js index ae59008ba..9fe12ff47 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSValue.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSValue.js @@ -31,6 +31,240 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + function __bjs_jsValueLower(value) { let kind; let payload1; @@ -120,6 +354,9 @@ export async function createInstantiator(options, swift) { return jsValue; } + const __bjs_codec_Array_JSValue = __bjs_arrayCodec(__bjs_primitiveCodecs.JSValue); + const __bjs_codec_Optional_Array_JSValue = __bjs_optionalCodec(__bjs_codec_Array_JSValue); + return { /** @@ -196,6 +433,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -316,29 +554,9 @@ export async function createInstantiator(options, swift) { } TestModule["bjs_jsEchoJSValueArray"] = function bjs_jsEchoJSValueArray() { try { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const jsValuePayload2 = f64Stack.pop(); - const jsValuePayload1 = i32Stack.pop(); - const jsValueKind = i32Stack.pop(); - const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); - arrayResult.push(jsValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_JSValue.lift(); let ret = imports.jsEchoJSValueArray(arrayResult); - for (const elem of ret) { - const [elemKind, elemPayload1, elemPayload2] = __bjs_jsValueLower(elem); - i32Stack.push(elemKind); - i32Stack.push(elemPayload1); - f64Stack.push(elemPayload2); - } - i32Stack.push(ret.length); + __bjs_codec_Array_JSValue.lower(ret); } catch (error) { setException(error); } @@ -564,67 +782,16 @@ export async function createInstantiator(options, swift) { return optResult; }, roundTripJSValueArray: function bjs_roundTripJSValueArray(values) { - for (const elem of values) { - const [elemKind, elemPayload1, elemPayload2] = __bjs_jsValueLower(elem); - i32Stack.push(elemKind); - i32Stack.push(elemPayload1); - f64Stack.push(elemPayload2); - } - i32Stack.push(values.length); + __bjs_codec_Array_JSValue.lower(values); instance.exports.bjs_roundTripJSValueArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const jsValuePayload2 = f64Stack.pop(); - const jsValuePayload1 = i32Stack.pop(); - const jsValueKind = i32Stack.pop(); - const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); - arrayResult.push(jsValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_JSValue.lift(); return arrayResult; }, roundTripOptionalJSValueArray: function bjs_roundTripOptionalJSValueArray(values) { - const isSome = values != null; - if (isSome) { - for (const elem of values) { - const [elemKind, elemPayload1, elemPayload2] = __bjs_jsValueLower(elem); - i32Stack.push(elemKind); - i32Stack.push(elemPayload1); - f64Stack.push(elemPayload2); - } - i32Stack.push(values.length); - } - i32Stack.push(+isSome); + __bjs_codec_Optional_Array_JSValue.lower(values); instance.exports.bjs_roundTripOptionalJSValueArray(); - const isSome1 = i32Stack.pop(); - let optResult; - if (isSome1) { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const jsValuePayload2 = f64Stack.pop(); - const jsValuePayload1 = i32Stack.pop(); - const jsValueKind = i32Stack.pop(); - const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); - arrayResult.push(jsValue); - } - arrayResult.reverse(); - } - optResult = arrayResult; - } else { - optResult = null; - } - return optResult; + const optValue = __bjs_codec_Optional_Array_JSValue.lift(); + return optValue; }, JSValueHolder, }; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.js index 39ecf8d99..5db38dde5 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.js index 62d7651e8..66818952b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.js index 69bfe5ff1..a732808a6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NamespacedClassSignature.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NamespacedClassSignature.d.ts new file mode 100644 index 000000000..7c7c4ce3a --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NamespacedClassSignature.d.ts @@ -0,0 +1,33 @@ +// 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`. + +/// Represents a Swift heap object like a class instance or an actor instance. +export interface SwiftHeapObject { + /// Release the heap object. + /// + /// Note: Calling this method will release the heap object and it will no longer be accessible. + release(): void; +} +export interface Bench extends SwiftHeapObject { +} +export type Exports = { + makeBench(): Bench; + refitBench(bench: Bench, transform: (arg0: Bench) => Bench): Bench; + Workshop: { + Bench: { + new(): Bench; + }, + }, +} +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/NamespacedClassSignature.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NamespacedClassSignature.js new file mode 100644 index 000000000..082d85f65 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NamespacedClassSignature.js @@ -0,0 +1,361 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +export async function createInstantiator(options, swift) { + let instance; + let memory; + let setException; + let decodeString; + const textDecoder = new TextDecoder("utf-8"); + const textEncoder = new TextEncoder("utf-8"); + let tmpRetString; + let tmpRetBytes; + let tmpRetException; + let tmpRetOptionalBool; + let tmpRetOptionalInt; + let tmpRetOptionalFloat; + let tmpRetOptionalDouble; + let tmpRetOptionalHeapObject; + let strStack = []; + let i32Stack = []; + let i64Stack = []; + let f32Stack = []; + let f64Stack = []; + let ptrStack = []; + let taStack = []; + const enumHelpers = {}; + const structHelpers = {}; + + let _exports = null; + let bjs = null; + const swiftClosureRegistry = (typeof FinalizationRegistry === "undefined") ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => { + if (state.unregistered) { return; } + instance?.exports?.bjs_release_swift_closure(state.pointer); + }); + const makeClosure = (pointer, file, line, func) => { + const state = { pointer, file, line, unregistered: false }; + const real = (...args) => { + if (state.unregistered) { + const bytes = new Uint8Array(memory.buffer, state.file >>> 0); + let length = 0; + while (bytes[length] !== 0) { length += 1; } + const fileID = decodeString(state.file, length); + throw new Error(`Attempted to call a released JSTypedClosure created at ${fileID}:${state.line}`); + } + return func(...args); + }; + real.__unregister = () => { + if (state.unregistered) { return; } + state.unregistered = true; + swiftClosureRegistry.unregister(state); + }; + swiftClosureRegistry.register(real, state, state); + return swift.memory.retain(real); + }; + + + return { + /** + * @param {WebAssembly.Imports} importObject + */ + addImports: (importObject, importsContext) => { + bjs = {}; + importObject["bjs"] = bjs; + bjs["swift_js_return_string"] = function(ptr, len) { + tmpRetString = decodeString(ptr, len); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr >>> 0); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + return swift.memory.retain(decodeString(ptr, len)); + } + bjs["swift_js_init_memory_with_result"] = function(ptr, len) { + const target = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); + target.set(tmpRetBytes); + tmpRetBytes = undefined; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_push_i32"] = function(v) { + i32Stack.push(v | 0); + } + bjs["swift_js_push_f32"] = function(v) { + f32Stack.push(Math.fround(v)); + } + bjs["swift_js_push_f64"] = function(v) { + f64Stack.push(v); + } + bjs["swift_js_push_string"] = function(ptr, len) { + const value = decodeString(ptr, len); + strStack.push(value); + } + bjs["swift_js_pop_i32"] = function() { + return i32Stack.pop(); + } + bjs["swift_js_pop_f32"] = function() { + return f32Stack.pop(); + } + bjs["swift_js_pop_f64"] = function() { + return f64Stack.pop(); + } + bjs["swift_js_push_pointer"] = function(pointer) { + ptrStack.push(pointer); + } + bjs["swift_js_pop_pointer"] = function() { + return ptrStack.pop(); + } + bjs["swift_js_push_i64"] = function(v) { + i64Stack.push(v); + } + bjs["swift_js_pop_i64"] = function() { + return i64Stack.pop(); + } + const taCtors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array]; + bjs["swift_js_push_typed_array"] = function(kind, ptr, count) { + const Ctor = taCtors[kind]; + const byteLen = count * Ctor.BYTES_PER_ELEMENT; + const copy = memory.buffer.slice(ptr, ptr + byteLen); + taStack.push(Array.from(new Ctor(copy))); + } + bjs["bjs_core_register_type_handles"] = function() {}; + const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); + bjs["swift_js_make_promise"] = function() { + let resolve, reject; + const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); + promise[__bjs_promiseSettlers] = { resolve, reject }; + return swift.memory.retain(promise); + } + bjs["swift_js_return_optional_bool"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalBool = null; + } else { + tmpRetOptionalBool = value !== 0; + } + } + bjs["swift_js_return_optional_int"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalInt = null; + } else { + tmpRetOptionalInt = value | 0; + } + } + bjs["swift_js_return_optional_float"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalFloat = null; + } else { + tmpRetOptionalFloat = Math.fround(value); + } + } + bjs["swift_js_return_optional_double"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalDouble = null; + } else { + tmpRetOptionalDouble = value; + } + } + bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = decodeString(ptr, len); + } + } + bjs["swift_js_return_optional_object"] = function(isSome, objectId) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = swift.memory.getObject(objectId); + } + } + bjs["swift_js_return_optional_heap_object"] = function(isSome, pointer) { + if (isSome === 0) { + tmpRetOptionalHeapObject = null; + } else { + tmpRetOptionalHeapObject = pointer; + } + } + bjs["swift_js_get_optional_int_presence"] = function() { + return tmpRetOptionalInt != null ? 1 : 0; + } + bjs["swift_js_get_optional_int_value"] = function() { + const value = tmpRetOptionalInt; + tmpRetOptionalInt = undefined; + return value; + } + bjs["swift_js_get_optional_string"] = function() { + const str = tmpRetString; + tmpRetString = undefined; + if (str == null) { + return -1; + } else { + const bytes = textEncoder.encode(str); + tmpRetBytes = bytes; + return bytes.length; + } + } + bjs["swift_js_get_optional_float_presence"] = function() { + return tmpRetOptionalFloat != null ? 1 : 0; + } + bjs["swift_js_get_optional_float_value"] = function() { + const value = tmpRetOptionalFloat; + tmpRetOptionalFloat = undefined; + return value; + } + bjs["swift_js_get_optional_double_presence"] = function() { + return tmpRetOptionalDouble != null ? 1 : 0; + } + bjs["swift_js_get_optional_double_value"] = function() { + const value = tmpRetOptionalDouble; + tmpRetOptionalDouble = undefined; + return value; + } + bjs["swift_js_get_optional_heap_object_pointer"] = function() { + const pointer = tmpRetOptionalHeapObject; + tmpRetOptionalHeapObject = undefined; + return pointer || 0; + } + bjs["swift_js_closure_unregister"] = function(funcRef) {} + bjs["swift_js_closure_unregister"] = function(funcRef) { + const func = swift.memory.getObject(funcRef); + func.__unregister(); + } + bjs["invoke_js_callback_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC"] = function(callbackId, param0) { + try { + const callback = swift.memory.getObject(callbackId); + let ret = callback(_exports.Workshop.Bench.__construct(param0)); + return ret.pointer; + } catch (error) { + setException(error); + return 0 + } + } + bjs["make_swift_closure_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC"] = function(boxPtr, file, line) { + const lower_closure_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC = function(param0) { + const ret = instance.exports.invoke_swift_closure_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC(boxPtr, param0.pointer); + if (tmpRetException) { + const error = swift.memory.getObject(tmpRetException); + swift.memory.release(tmpRetException); + tmpRetException = undefined; + throw error; + } + return _exports.Workshop.Bench.__construct(ret); + }; + return makeClosure(boxPtr, file, line, lower_closure_TestModule_10TestModule8Workshop5BenchC_8Workshop5BenchC); + } + // Wrapper functions for module: TestModule + if (!importObject["TestModule"]) { + importObject["TestModule"] = {}; + } + importObject["TestModule"]["bjs_Workshop_Bench_wrap"] = function(pointer) { + const obj = _exports.Workshop.Bench.__construct(pointer); + return swift.memory.retain(obj); + }; + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + decodeString = (ptr, len) => { const bytes = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); return textDecoder.decode(bytes); } + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => { + if (state.hasReleased) { + return; + } + state.hasReleased = true; + state.identityMap?.delete(state.pointer); + state.deinit(state.pointer); + }); + + /// Represents a Swift heap object like a class instance or an actor instance. + class SwiftHeapObject { + static __wrap(pointer, deinit, prototype, identityCache) { + pointer = pointer >>> 0; + const makeFresh = (identityMap) => { + const obj = Object.create(prototype); + const state = { pointer, deinit, hasReleased: false, identityMap }; + obj.pointer = pointer; + obj.__swiftHeapObjectState = state; + swiftHeapObjectFinalizationRegistry.register(obj, state, state); + if (identityMap) { + identityMap.set(pointer, new WeakRef(obj)); + } + return obj; + }; + + if (!identityCache) { + return makeFresh(null); + } + + const cached = identityCache.get(pointer)?.deref(); + if (cached && !cached.__swiftHeapObjectState.hasReleased) { + deinit(pointer); + return cached; + } + if (identityCache.has(pointer)) { + identityCache.delete(pointer); + } + + return makeFresh(identityCache); + } + + release() { + const state = this.__swiftHeapObjectState; + if (state.hasReleased) { + return; + } + state.hasReleased = true; + swiftHeapObjectFinalizationRegistry.unregister(state); + state.identityMap?.delete(state.pointer); + state.deinit(state.pointer); + } + } + class Bench extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Workshop_Bench_deinit, Bench.prototype, null); + } + + constructor() { + const ret = instance.exports.bjs_Workshop_Bench_init(); + return Bench.__construct(ret); + } + } + const exports = { + makeBench: function bjs_makeBench() { + const ret = instance.exports.bjs_makeBench(); + return Bench.__construct(ret); + }, + refitBench: function bjs_refitBench(bench, transform) { + const callbackId = swift.memory.retain(transform); + const ret = instance.exports.bjs_refitBench(bench.pointer, callbackId); + return Bench.__construct(ret); + }, + Workshop: { + Bench, + }, + }; + _exports = exports; + return exports; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.js index aa5e3dbb4..ea49220de 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.js @@ -31,6 +31,341 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_M10TestModuleT7Greeter = { + lower: (v) => { + ptrStack.push(v.pointer); + }, + lift: () => { + const ptr = ptrStack.pop(); + const obj = _exports.__Swift.Foundation.Greeter.__construct(ptr); + return obj; + }, + }; + const __bjs_codec_Array_M10TestModuleT7Greeter = __bjs_arrayCodec(__bjs_codec_M10TestModuleT7Greeter); + return { /** @@ -106,6 +441,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -356,19 +692,7 @@ export async function createInstantiator(options, swift) { } getItems() { instance.exports.bjs_Collections_Container_getItems(this.pointer); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const ptr = ptrStack.pop(); - const obj = Greeter.__construct(ptr); - arrayResult.push(obj); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT7Greeter.lift(); return arrayResult; } addItem(item) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.js index 9a5c6473e..25bd44d05 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.js @@ -31,6 +31,341 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_M10TestModuleT7Greeter = { + lower: (v) => { + ptrStack.push(v.pointer); + }, + lift: () => { + const ptr = ptrStack.pop(); + const obj = _exports.__Swift.Foundation.Greeter.__construct(ptr); + return obj; + }, + }; + const __bjs_codec_Array_M10TestModuleT7Greeter = __bjs_arrayCodec(__bjs_codec_M10TestModuleT7Greeter); + return { /** @@ -106,6 +441,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -356,19 +692,7 @@ export async function createInstantiator(options, swift) { } getItems() { instance.exports.bjs_Collections_Container_getItems(this.pointer); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const ptr = ptrStack.pop(); - const obj = Greeter.__construct(ptr); - arrayResult.push(obj); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT7Greeter.lift(); return arrayResult; } addItem(item) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NestedType.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NestedType.js index 972f9ae74..f57c4007b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NestedType.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NestedType.js @@ -31,7 +31,7 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createUser_StatsHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT4UserT5Stats = () => ({ lower: (value) => { i32Stack.push((value.health | 0)); f64Stack.push(value.score); @@ -42,7 +42,7 @@ export async function createInstantiator(options, swift) { return { health: int, score: f64 }; } }); - const __bjs_createPlayer_StatsHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT6PlayerT5Stats = () => ({ lower: (value) => { i32Stack.push((value.level | 0)); const bytes = textEncoder.encode(value.rating); @@ -132,19 +132,21 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_User_Stats"] = function(objectId) { - structHelpers.User_Stats.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT4UserT5Stats.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_User_Stats"] = function() { - const value = structHelpers.User_Stats.lift(); + const value = structHelpers.M10TestModuleT4UserT5Stats.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Player_Stats"] = function(objectId) { - structHelpers.Player_Stats.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT6PlayerT5Stats.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Player_Stats"] = function() { - const value = structHelpers.Player_Stats.lift(); + const value = structHelpers.M10TestModuleT6PlayerT5Stats.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -344,11 +346,11 @@ export async function createInstantiator(options, swift) { return ret; } } - const User_StatsHelpers = __bjs_createUser_StatsHelpers(); - structHelpers.User_Stats = User_StatsHelpers; + const __bjs_helpers_M10TestModuleT4UserT5Stats = __bjs_createStructHelpers_M10TestModuleT4UserT5Stats(); + structHelpers.M10TestModuleT4UserT5Stats = __bjs_helpers_M10TestModuleT4UserT5Stats; - const Player_StatsHelpers = __bjs_createPlayer_StatsHelpers(); - structHelpers.Player_Stats = Player_StatsHelpers; + const __bjs_helpers_M10TestModuleT6PlayerT5Stats = __bjs_createStructHelpers_M10TestModuleT6PlayerT5Stats(); + structHelpers.M10TestModuleT6PlayerT5Stats = __bjs_helpers_M10TestModuleT6PlayerT5Stats; const exports = { Player, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NestedTypeNameCollision.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NestedTypeNameCollision.d.ts new file mode 100644 index 000000000..13c22ea11 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NestedTypeNameCollision.d.ts @@ -0,0 +1,35 @@ +// 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 interface Entry { + identifier: number; +} +export namespace Catalog { + export interface Entry { + title: string; + } +} +export type Exports = { + takeEntry(entry: Entry): Entry; + takeCatalogEntry(entry: Catalog.Entry): Catalog.Entry; + Catalog: { + Entry: { + init(title: string): Catalog.Entry; + }, + }, + Entry: { + init(identifier: number): Entry; + }, +} +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/NestedTypeNameCollision.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NestedTypeNameCollision.js new file mode 100644 index 000000000..1f4400ce9 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NestedTypeNameCollision.js @@ -0,0 +1,299 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +export async function createInstantiator(options, swift) { + let instance; + let memory; + let setException; + let decodeString; + const textDecoder = new TextDecoder("utf-8"); + const textEncoder = new TextEncoder("utf-8"); + let tmpRetString; + let tmpRetBytes; + let tmpRetException; + let tmpRetOptionalBool; + let tmpRetOptionalInt; + let tmpRetOptionalFloat; + let tmpRetOptionalDouble; + let tmpRetOptionalHeapObject; + let strStack = []; + let i32Stack = []; + let i64Stack = []; + let f32Stack = []; + let f64Stack = []; + let ptrStack = []; + let taStack = []; + const enumHelpers = {}; + const structHelpers = {}; + + let _exports = null; + let bjs = null; + const __bjs_createStructHelpers_M10TestModuleT7CatalogT5Entry = () => ({ + lower: (value) => { + const bytes = textEncoder.encode(value.title); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return { title: string }; + } + }); + const __bjs_createStructHelpers_M10TestModuleT5Entry = () => ({ + lower: (value) => { + i32Stack.push((value.identifier | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return { identifier: int }; + } + }); + + return { + /** + * @param {WebAssembly.Imports} importObject + */ + addImports: (importObject, importsContext) => { + bjs = {}; + importObject["bjs"] = bjs; + bjs["swift_js_return_string"] = function(ptr, len) { + tmpRetString = decodeString(ptr, len); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr >>> 0); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + return swift.memory.retain(decodeString(ptr, len)); + } + bjs["swift_js_init_memory_with_result"] = function(ptr, len) { + const target = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); + target.set(tmpRetBytes); + tmpRetBytes = undefined; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_push_i32"] = function(v) { + i32Stack.push(v | 0); + } + bjs["swift_js_push_f32"] = function(v) { + f32Stack.push(Math.fround(v)); + } + bjs["swift_js_push_f64"] = function(v) { + f64Stack.push(v); + } + bjs["swift_js_push_string"] = function(ptr, len) { + const value = decodeString(ptr, len); + strStack.push(value); + } + bjs["swift_js_pop_i32"] = function() { + return i32Stack.pop(); + } + bjs["swift_js_pop_f32"] = function() { + return f32Stack.pop(); + } + bjs["swift_js_pop_f64"] = function() { + return f64Stack.pop(); + } + bjs["swift_js_push_pointer"] = function(pointer) { + ptrStack.push(pointer); + } + bjs["swift_js_pop_pointer"] = function() { + return ptrStack.pop(); + } + bjs["swift_js_push_i64"] = function(v) { + i64Stack.push(v); + } + bjs["swift_js_pop_i64"] = function() { + return i64Stack.pop(); + } + const taCtors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array]; + bjs["swift_js_push_typed_array"] = function(kind, ptr, count) { + const Ctor = taCtors[kind]; + const byteLen = count * Ctor.BYTES_PER_ELEMENT; + const copy = memory.buffer.slice(ptr, ptr + byteLen); + taStack.push(Array.from(new Ctor(copy))); + } + bjs["swift_js_struct_lower_Catalog_Entry"] = function(objectId) { + structHelpers.M10TestModuleT7CatalogT5Entry.lower(swift.memory.getObject(objectId)); + } + bjs["swift_js_struct_lift_Catalog_Entry"] = function() { + const value = structHelpers.M10TestModuleT7CatalogT5Entry.lift(); + return swift.memory.retain(value); + } + bjs["swift_js_struct_lower_Entry"] = function(objectId) { + structHelpers.M10TestModuleT5Entry.lower(swift.memory.getObject(objectId)); + } + bjs["swift_js_struct_lift_Entry"] = function() { + const value = structHelpers.M10TestModuleT5Entry.lift(); + return swift.memory.retain(value); + } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; + const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); + bjs["swift_js_make_promise"] = function() { + let resolve, reject; + const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); + promise[__bjs_promiseSettlers] = { resolve, reject }; + return swift.memory.retain(promise); + } + bjs["swift_js_return_optional_bool"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalBool = null; + } else { + tmpRetOptionalBool = value !== 0; + } + } + bjs["swift_js_return_optional_int"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalInt = null; + } else { + tmpRetOptionalInt = value | 0; + } + } + bjs["swift_js_return_optional_float"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalFloat = null; + } else { + tmpRetOptionalFloat = Math.fround(value); + } + } + bjs["swift_js_return_optional_double"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalDouble = null; + } else { + tmpRetOptionalDouble = value; + } + } + bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = decodeString(ptr, len); + } + } + bjs["swift_js_return_optional_object"] = function(isSome, objectId) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = swift.memory.getObject(objectId); + } + } + bjs["swift_js_return_optional_heap_object"] = function(isSome, pointer) { + if (isSome === 0) { + tmpRetOptionalHeapObject = null; + } else { + tmpRetOptionalHeapObject = pointer; + } + } + bjs["swift_js_get_optional_int_presence"] = function() { + return tmpRetOptionalInt != null ? 1 : 0; + } + bjs["swift_js_get_optional_int_value"] = function() { + const value = tmpRetOptionalInt; + tmpRetOptionalInt = undefined; + return value; + } + bjs["swift_js_get_optional_string"] = function() { + const str = tmpRetString; + tmpRetString = undefined; + if (str == null) { + return -1; + } else { + const bytes = textEncoder.encode(str); + tmpRetBytes = bytes; + return bytes.length; + } + } + bjs["swift_js_get_optional_float_presence"] = function() { + return tmpRetOptionalFloat != null ? 1 : 0; + } + bjs["swift_js_get_optional_float_value"] = function() { + const value = tmpRetOptionalFloat; + tmpRetOptionalFloat = undefined; + return value; + } + bjs["swift_js_get_optional_double_presence"] = function() { + return tmpRetOptionalDouble != null ? 1 : 0; + } + bjs["swift_js_get_optional_double_value"] = function() { + const value = tmpRetOptionalDouble; + tmpRetOptionalDouble = undefined; + return value; + } + bjs["swift_js_get_optional_heap_object_pointer"] = function() { + const pointer = tmpRetOptionalHeapObject; + tmpRetOptionalHeapObject = undefined; + return pointer || 0; + } + bjs["swift_js_closure_unregister"] = function(funcRef) {} + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + decodeString = (ptr, len) => { const bytes = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); return textDecoder.decode(bytes); } + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + const __bjs_helpers_M10TestModuleT7CatalogT5Entry = __bjs_createStructHelpers_M10TestModuleT7CatalogT5Entry(); + structHelpers.M10TestModuleT7CatalogT5Entry = __bjs_helpers_M10TestModuleT7CatalogT5Entry; + + const __bjs_helpers_M10TestModuleT5Entry = __bjs_createStructHelpers_M10TestModuleT5Entry(); + structHelpers.M10TestModuleT5Entry = __bjs_helpers_M10TestModuleT5Entry; + + const exports = { + takeEntry: function bjs_takeEntry(entry) { + structHelpers.M10TestModuleT5Entry.lower(entry); + instance.exports.bjs_takeEntry(); + const structValue = structHelpers.M10TestModuleT5Entry.lift(); + return structValue; + }, + takeCatalogEntry: function bjs_takeCatalogEntry(entry) { + structHelpers.M10TestModuleT7CatalogT5Entry.lower(entry); + instance.exports.bjs_takeCatalogEntry(); + const structValue = structHelpers.M10TestModuleT7CatalogT5Entry.lift(); + return structValue; + }, + Catalog: { + Entry: { + init: function(title) { + const titleBytes = textEncoder.encode(title); + const titleId = swift.memory.retain(titleBytes); + instance.exports.bjs_Catalog_Entry_init(titleId, titleBytes.length); + const structValue = structHelpers.M10TestModuleT7CatalogT5Entry.lift(); + return structValue; + }, + }, + }, + Entry: { + init: function(identifier) { + instance.exports.bjs_Entry_init(identifier); + const structValue = structHelpers.M10TestModuleT5Entry.lift(); + return structValue; + }, + }, + }; + _exports = exports; + return exports; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Optionals.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Optionals.js index 5a253cdc0..b63f360e9 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Optionals.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Optionals.js @@ -31,6 +31,356 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_JSObject = { + lower: (v) => { + const objId = swift.memory.retain(v); + i32Stack.push(objId); + }, + lift: () => { + const objId = i32Stack.pop(); + const obj = swift.memory.getObject(objId); + swift.memory.release(objId); + return obj; + }, + }; + const __bjs_codec_Optional_JSObject = __bjs_optionalCodec(__bjs_codec_JSObject); + const __bjs_codec_WithOptionalJSClass = { + lower: (v) => { + const objId = swift.memory.retain(v); + i32Stack.push(objId); + }, + lift: () => { + const objId = i32Stack.pop(); + const obj = swift.memory.getObject(objId); + swift.memory.release(objId); + return obj; + }, + }; + const __bjs_codec_Optional_WithOptionalJSClass = __bjs_optionalCodec(__bjs_codec_WithOptionalJSClass); + return { /** @@ -107,6 +457,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -314,12 +665,7 @@ export async function createInstantiator(options, swift) { TestModule["bjs_WithOptionalJSClass_childOrNull_get"] = function bjs_WithOptionalJSClass_childOrNull_get(self) { try { let ret = swift.memory.getObject(self).childOrNull; - const isSome = ret != null; - if (isSome) { - const objId = swift.memory.retain(ret); - i32Stack.push(objId); - } - i32Stack.push(isSome ? 1 : 0); + __bjs_codec_Optional_WithOptionalJSClass.lower(ret); } catch (error) { setException(error); } @@ -490,12 +836,7 @@ export async function createInstantiator(options, swift) { TestModule["bjs_WithOptionalJSClass_roundTripChildOrNull"] = function bjs_WithOptionalJSClass_roundTripChildOrNull(self, valueIsSome, valueObjectId) { try { let ret = swift.memory.getObject(self).roundTripChildOrNull(valueIsSome ? swift.memory.getObject(valueObjectId) : null); - const isSome = ret != null; - if (isSome) { - const objId = swift.memory.retain(ret); - i32Stack.push(objId); - } - i32Stack.push(isSome ? 1 : 0); + __bjs_codec_Optional_WithOptionalJSClass.lower(ret); } catch (error) { setException(error); } @@ -722,17 +1063,8 @@ export async function createInstantiator(options, swift) { result = 0; } instance.exports.bjs_roundTripExportedOptionalJSObject(+isSome, result); - const isSome1 = i32Stack.pop(); - let optResult; - if (isSome1) { - const objId = i32Stack.pop(); - const obj = swift.memory.getObject(objId); - swift.memory.release(objId); - optResult = obj; - } else { - optResult = null; - } - return optResult; + const optValue = __bjs_codec_Optional_JSObject.lift(); + return optValue; }, roundTripExportedOptionalJSClass: function bjs_roundTripExportedOptionalJSClass(value) { const isSome = value != null; @@ -743,17 +1075,8 @@ export async function createInstantiator(options, swift) { result = 0; } instance.exports.bjs_roundTripExportedOptionalJSClass(+isSome, result); - const isSome1 = i32Stack.pop(); - let optResult; - if (isSome1) { - const objId = i32Stack.pop(); - const obj = swift.memory.getObject(objId); - swift.memory.release(objId); - optResult = obj; - } else { - optResult = null; - } - return optResult; + const optValue = __bjs_codec_Optional_WithOptionalJSClass.lift(); + return optValue; }, roundTripString: function bjs_roundTripString(name) { const isSome = name != null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.js index 46d57d793..d4480a65c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.js index bb4e8552d..e9b298fb2 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.js index 61560134a..beb9417df 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Protocol.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Protocol.js index b2a894ffa..f0c2d3fae 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Protocol.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Protocol.js @@ -55,7 +55,345 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createResultValuesHelpers = () => ({ + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_M10TestModuleT24MyViewControllerDelegate = { + lower: (v) => { + const objId = swift.memory.retain(v); + i32Stack.push(objId); + }, + lift: () => { + const objId = i32Stack.pop(); + const obj = swift.memory.getObject(objId); + swift.memory.release(objId); + return obj; + }, + }; + const __bjs_codec_Array_M10TestModuleT24MyViewControllerDelegate = __bjs_arrayCodec(__bjs_codec_M10TestModuleT24MyViewControllerDelegate); + const __bjs_codec_Dict_M10TestModuleT24MyViewControllerDelegate = __bjs_dictCodec(__bjs_codec_M10TestModuleT24MyViewControllerDelegate); + + const __bjs_createEnumHelpers_M10TestModuleT6Result = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -163,6 +501,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -366,7 +706,7 @@ export async function createInstantiator(options, swift) { TestModule["bjs_MyViewControllerDelegate_result_get"] = function bjs_MyViewControllerDelegate_result_get(self) { try { let ret = swift.memory.getObject(self).result; - const caseId = enumHelpers.Result.lower(ret); + const caseId = enumHelpers.M10TestModuleT6Result.lower(ret); return caseId; } catch (error) { setException(error); @@ -374,7 +714,7 @@ export async function createInstantiator(options, swift) { } TestModule["bjs_MyViewControllerDelegate_result_set"] = function bjs_MyViewControllerDelegate_result_set(self, value) { try { - const enumValue = enumHelpers.Result.lift(value); + const enumValue = enumHelpers.M10TestModuleT6Result.lift(value); swift.memory.getObject(self).result = enumValue; } catch (error) { setException(error); @@ -385,7 +725,7 @@ export async function createInstantiator(options, swift) { let ret = swift.memory.getObject(self).optionalResult; const isSome = ret != null; if (isSome) { - const caseId = enumHelpers.Result.lower(ret); + const caseId = enumHelpers.M10TestModuleT6Result.lower(ret); return caseId; } else { return -1; @@ -398,7 +738,7 @@ export async function createInstantiator(options, swift) { try { let optResult; if (valueIsSome) { - const enumValue = enumHelpers.Result.lift(valueCaseId); + const enumValue = enumHelpers.M10TestModuleT6Result.lift(valueCaseId); optResult = enumValue; } else { optResult = null; @@ -556,7 +896,7 @@ export async function createInstantiator(options, swift) { } TestModule["bjs_MyViewControllerDelegate_handleResult"] = function bjs_MyViewControllerDelegate_handleResult(self, result) { try { - const enumValue = enumHelpers.Result.lift(result); + const enumValue = enumHelpers.M10TestModuleT6Result.lift(result); swift.memory.getObject(self).handleResult(enumValue); } catch (error) { setException(error); @@ -565,7 +905,7 @@ export async function createInstantiator(options, swift) { TestModule["bjs_MyViewControllerDelegate_getResult"] = function bjs_MyViewControllerDelegate_getResult(self) { try { let ret = swift.memory.getObject(self).getResult(); - const caseId = enumHelpers.Result.lower(ret); + const caseId = enumHelpers.M10TestModuleT6Result.lower(ret); return caseId; } catch (error) { setException(error); @@ -724,11 +1064,7 @@ export async function createInstantiator(options, swift) { } constructor(delegates) { - for (const elem of delegates) { - const objId = swift.memory.retain(elem); - i32Stack.push(objId); - } - i32Stack.push(delegates.length); + __bjs_codec_Array_M10TestModuleT24MyViewControllerDelegate.lower(delegates); const ret = instance.exports.bjs_DelegateManager_init(); return DelegateManager.__construct(ret); } @@ -737,107 +1073,37 @@ export async function createInstantiator(options, swift) { } get delegates() { instance.exports.bjs_DelegateManager_delegates_get(this.pointer); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const objId = i32Stack.pop(); - const obj = swift.memory.getObject(objId); - swift.memory.release(objId); - arrayResult.push(obj); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT24MyViewControllerDelegate.lift(); return arrayResult; } set delegates(value) { - for (const elem of value) { - const objId = swift.memory.retain(elem); - i32Stack.push(objId); - } - i32Stack.push(value.length); + __bjs_codec_Array_M10TestModuleT24MyViewControllerDelegate.lower(value); instance.exports.bjs_DelegateManager_delegates_set(this.pointer); } get delegatesByName() { instance.exports.bjs_DelegateManager_delegatesByName_get(this.pointer); - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const objId = i32Stack.pop(); - const obj = swift.memory.getObject(objId); - swift.memory.release(objId); - const string = strStack.pop(); - dictResult[string] = obj; - } + const dictResult = __bjs_codec_Dict_M10TestModuleT24MyViewControllerDelegate.lift(); return dictResult; } set delegatesByName(value) { - const entries = Object.entries(value); - for (const entry of entries) { - const [key, value1] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - const objId = swift.memory.retain(value1); - i32Stack.push(objId); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_M10TestModuleT24MyViewControllerDelegate.lower(value); instance.exports.bjs_DelegateManager_delegatesByName_set(this.pointer); } } - const ResultHelpers = __bjs_createResultValuesHelpers(); - enumHelpers.Result = ResultHelpers; + const __bjs_helpers_M10TestModuleT6Result = __bjs_createEnumHelpers_M10TestModuleT6Result(); + enumHelpers.M10TestModuleT6Result = __bjs_helpers_M10TestModuleT6Result; const exports = { processDelegates: function bjs_processDelegates(delegates) { - for (const elem of delegates) { - const objId = swift.memory.retain(elem); - i32Stack.push(objId); - } - i32Stack.push(delegates.length); + __bjs_codec_Array_M10TestModuleT24MyViewControllerDelegate.lower(delegates); instance.exports.bjs_processDelegates(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const objId1 = i32Stack.pop(); - const obj = swift.memory.getObject(objId1); - swift.memory.release(objId1); - arrayResult.push(obj); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT24MyViewControllerDelegate.lift(); return arrayResult; }, processDelegatesByName: function bjs_processDelegatesByName(delegates) { - const entries = Object.entries(delegates); - for (const entry of entries) { - const [key, value] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - const objId = swift.memory.retain(value); - i32Stack.push(objId); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_M10TestModuleT24MyViewControllerDelegate.lower(delegates); instance.exports.bjs_processDelegatesByName(); - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const objId1 = i32Stack.pop(); - const obj = swift.memory.getObject(objId1); - swift.memory.release(objId1); - const string = strStack.pop(); - dictResult[string] = obj; - } + const dictResult = __bjs_codec_Dict_M10TestModuleT24MyViewControllerDelegate.lift(); return dictResult; }, Direction: DirectionValues, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ProtocolInClosure.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ProtocolInClosure.js index 01f9fe0e1..eed26c581 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ProtocolInClosure.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ProtocolInClosure.js @@ -131,6 +131,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/RelativeQualifiedTypes.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/RelativeQualifiedTypes.d.ts new file mode 100644 index 000000000..1297973a9 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/RelativeQualifiedTypes.d.ts @@ -0,0 +1,70 @@ +// 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 namespace Library { + export interface Shelf { + } + export namespace Shelf { + export interface Divider { + slot: number; + } + } +} +export namespace Outer { + export interface Inner { + marker(): number; + } + export namespace Inner { + export interface Outer { + } + export namespace Outer { + export interface Inner { + } + } + } +} +/// Represents a Swift heap object like a class instance or an actor instance. +export interface SwiftHeapObject { + /// Release the heap object. + /// + /// Note: Calling this method will release the heap object and it will no longer be accessible. + release(): void; +} +export interface Library extends SwiftHeapObject { + divider(value: Library.Shelf.Divider): Library.Shelf.Divider; +} +export interface Outer extends SwiftHeapObject { +} +export type Exports = { + Library: { + new(): Library; + Shelf: { + Divider: { + init(slot: number): Library.Shelf.Divider; + }, + }, + }, + Outer: { + new(): Outer; + Inner: { + init(): Outer.Inner; + Outer: { + Inner: { + init(): Outer.Inner.Outer.Inner; + }, + }, + }, + }, +} +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/RelativeQualifiedTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/RelativeQualifiedTypes.js new file mode 100644 index 000000000..2765d709f --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/RelativeQualifiedTypes.js @@ -0,0 +1,440 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +export async function createInstantiator(options, swift) { + let instance; + let memory; + let setException; + let decodeString; + const textDecoder = new TextDecoder("utf-8"); + const textEncoder = new TextEncoder("utf-8"); + let tmpRetString; + let tmpRetBytes; + let tmpRetException; + let tmpRetOptionalBool; + let tmpRetOptionalInt; + let tmpRetOptionalFloat; + let tmpRetOptionalDouble; + let tmpRetOptionalHeapObject; + let strStack = []; + let i32Stack = []; + let i64Stack = []; + let f32Stack = []; + let f64Stack = []; + let ptrStack = []; + let taStack = []; + const enumHelpers = {}; + const structHelpers = {}; + + let _exports = null; + let bjs = null; + const __bjs_createStructHelpers_M10TestModuleT7LibraryT5Shelf = () => ({ + lower: (value) => { + }, + lift: () => { + return { }; + } + }); + const __bjs_createStructHelpers_M10TestModuleT7LibraryT5ShelfT7Divider = () => ({ + lower: (value) => { + i32Stack.push((value.slot | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return { slot: int }; + } + }); + const __bjs_createStructHelpers_M10TestModuleT5OuterT5Inner = () => ({ + lower: (value) => { + }, + lift: () => { + const instance1 = { }; + instance1.marker = function() { + structHelpers.M10TestModuleT5OuterT5Inner.lower(this); + const ret = instance.exports.bjs_Outer_Inner_marker(); + return ret; + }.bind(instance1); + return instance1; + } + }); + const __bjs_createStructHelpers_M10TestModuleT5OuterT5InnerT5Outer = () => ({ + lower: (value) => { + }, + lift: () => { + return { }; + } + }); + const __bjs_createStructHelpers_M10TestModuleT5OuterT5InnerT5OuterT5Inner = () => ({ + lower: (value) => { + }, + lift: () => { + return { }; + } + }); + + return { + /** + * @param {WebAssembly.Imports} importObject + */ + addImports: (importObject, importsContext) => { + bjs = {}; + importObject["bjs"] = bjs; + bjs["swift_js_return_string"] = function(ptr, len) { + tmpRetString = decodeString(ptr, len); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr >>> 0); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + return swift.memory.retain(decodeString(ptr, len)); + } + bjs["swift_js_init_memory_with_result"] = function(ptr, len) { + const target = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); + target.set(tmpRetBytes); + tmpRetBytes = undefined; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_push_i32"] = function(v) { + i32Stack.push(v | 0); + } + bjs["swift_js_push_f32"] = function(v) { + f32Stack.push(Math.fround(v)); + } + bjs["swift_js_push_f64"] = function(v) { + f64Stack.push(v); + } + bjs["swift_js_push_string"] = function(ptr, len) { + const value = decodeString(ptr, len); + strStack.push(value); + } + bjs["swift_js_pop_i32"] = function() { + return i32Stack.pop(); + } + bjs["swift_js_pop_f32"] = function() { + return f32Stack.pop(); + } + bjs["swift_js_pop_f64"] = function() { + return f64Stack.pop(); + } + bjs["swift_js_push_pointer"] = function(pointer) { + ptrStack.push(pointer); + } + bjs["swift_js_pop_pointer"] = function() { + return ptrStack.pop(); + } + bjs["swift_js_push_i64"] = function(v) { + i64Stack.push(v); + } + bjs["swift_js_pop_i64"] = function() { + return i64Stack.pop(); + } + const taCtors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array]; + bjs["swift_js_push_typed_array"] = function(kind, ptr, count) { + const Ctor = taCtors[kind]; + const byteLen = count * Ctor.BYTES_PER_ELEMENT; + const copy = memory.buffer.slice(ptr, ptr + byteLen); + taStack.push(Array.from(new Ctor(copy))); + } + bjs["swift_js_struct_lower_Library_Shelf"] = function(objectId) { + structHelpers.M10TestModuleT7LibraryT5Shelf.lower(swift.memory.getObject(objectId)); + } + bjs["swift_js_struct_lift_Library_Shelf"] = function() { + const value = structHelpers.M10TestModuleT7LibraryT5Shelf.lift(); + return swift.memory.retain(value); + } + bjs["swift_js_struct_lower_Library_Shelf_Divider"] = function(objectId) { + structHelpers.M10TestModuleT7LibraryT5ShelfT7Divider.lower(swift.memory.getObject(objectId)); + } + bjs["swift_js_struct_lift_Library_Shelf_Divider"] = function() { + const value = structHelpers.M10TestModuleT7LibraryT5ShelfT7Divider.lift(); + return swift.memory.retain(value); + } + bjs["swift_js_struct_lower_Outer_Inner"] = function(objectId) { + structHelpers.M10TestModuleT5OuterT5Inner.lower(swift.memory.getObject(objectId)); + } + bjs["swift_js_struct_lift_Outer_Inner"] = function() { + const value = structHelpers.M10TestModuleT5OuterT5Inner.lift(); + return swift.memory.retain(value); + } + bjs["swift_js_struct_lower_Outer_Inner_Outer"] = function(objectId) { + structHelpers.M10TestModuleT5OuterT5InnerT5Outer.lower(swift.memory.getObject(objectId)); + } + bjs["swift_js_struct_lift_Outer_Inner_Outer"] = function() { + const value = structHelpers.M10TestModuleT5OuterT5InnerT5Outer.lift(); + return swift.memory.retain(value); + } + bjs["swift_js_struct_lower_Outer_Inner_Outer_Inner"] = function(objectId) { + structHelpers.M10TestModuleT5OuterT5InnerT5OuterT5Inner.lower(swift.memory.getObject(objectId)); + } + bjs["swift_js_struct_lift_Outer_Inner_Outer_Inner"] = function() { + const value = structHelpers.M10TestModuleT5OuterT5InnerT5OuterT5Inner.lift(); + return swift.memory.retain(value); + } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; + const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); + bjs["swift_js_make_promise"] = function() { + let resolve, reject; + const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); + promise[__bjs_promiseSettlers] = { resolve, reject }; + return swift.memory.retain(promise); + } + bjs["swift_js_return_optional_bool"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalBool = null; + } else { + tmpRetOptionalBool = value !== 0; + } + } + bjs["swift_js_return_optional_int"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalInt = null; + } else { + tmpRetOptionalInt = value | 0; + } + } + bjs["swift_js_return_optional_float"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalFloat = null; + } else { + tmpRetOptionalFloat = Math.fround(value); + } + } + bjs["swift_js_return_optional_double"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalDouble = null; + } else { + tmpRetOptionalDouble = value; + } + } + bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = decodeString(ptr, len); + } + } + bjs["swift_js_return_optional_object"] = function(isSome, objectId) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = swift.memory.getObject(objectId); + } + } + bjs["swift_js_return_optional_heap_object"] = function(isSome, pointer) { + if (isSome === 0) { + tmpRetOptionalHeapObject = null; + } else { + tmpRetOptionalHeapObject = pointer; + } + } + bjs["swift_js_get_optional_int_presence"] = function() { + return tmpRetOptionalInt != null ? 1 : 0; + } + bjs["swift_js_get_optional_int_value"] = function() { + const value = tmpRetOptionalInt; + tmpRetOptionalInt = undefined; + return value; + } + bjs["swift_js_get_optional_string"] = function() { + const str = tmpRetString; + tmpRetString = undefined; + if (str == null) { + return -1; + } else { + const bytes = textEncoder.encode(str); + tmpRetBytes = bytes; + return bytes.length; + } + } + bjs["swift_js_get_optional_float_presence"] = function() { + return tmpRetOptionalFloat != null ? 1 : 0; + } + bjs["swift_js_get_optional_float_value"] = function() { + const value = tmpRetOptionalFloat; + tmpRetOptionalFloat = undefined; + return value; + } + bjs["swift_js_get_optional_double_presence"] = function() { + return tmpRetOptionalDouble != null ? 1 : 0; + } + bjs["swift_js_get_optional_double_value"] = function() { + const value = tmpRetOptionalDouble; + tmpRetOptionalDouble = undefined; + return value; + } + bjs["swift_js_get_optional_heap_object_pointer"] = function() { + const pointer = tmpRetOptionalHeapObject; + tmpRetOptionalHeapObject = undefined; + return pointer || 0; + } + bjs["swift_js_closure_unregister"] = function(funcRef) {} + // Wrapper functions for module: TestModule + if (!importObject["TestModule"]) { + importObject["TestModule"] = {}; + } + importObject["TestModule"]["bjs_Library_wrap"] = function(pointer) { + const obj = _exports['Library'].__construct(pointer); + return swift.memory.retain(obj); + }; + importObject["TestModule"]["bjs_Outer_wrap"] = function(pointer) { + const obj = _exports['Outer'].__construct(pointer); + return swift.memory.retain(obj); + }; + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + decodeString = (ptr, len) => { const bytes = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); return textDecoder.decode(bytes); } + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => { + if (state.hasReleased) { + return; + } + state.hasReleased = true; + state.identityMap?.delete(state.pointer); + state.deinit(state.pointer); + }); + + /// Represents a Swift heap object like a class instance or an actor instance. + class SwiftHeapObject { + static __wrap(pointer, deinit, prototype, identityCache) { + pointer = pointer >>> 0; + const makeFresh = (identityMap) => { + const obj = Object.create(prototype); + const state = { pointer, deinit, hasReleased: false, identityMap }; + obj.pointer = pointer; + obj.__swiftHeapObjectState = state; + swiftHeapObjectFinalizationRegistry.register(obj, state, state); + if (identityMap) { + identityMap.set(pointer, new WeakRef(obj)); + } + return obj; + }; + + if (!identityCache) { + return makeFresh(null); + } + + const cached = identityCache.get(pointer)?.deref(); + if (cached && !cached.__swiftHeapObjectState.hasReleased) { + deinit(pointer); + return cached; + } + if (identityCache.has(pointer)) { + identityCache.delete(pointer); + } + + return makeFresh(identityCache); + } + + release() { + const state = this.__swiftHeapObjectState; + if (state.hasReleased) { + return; + } + state.hasReleased = true; + swiftHeapObjectFinalizationRegistry.unregister(state); + state.identityMap?.delete(state.pointer); + state.deinit(state.pointer); + } + } + class Library extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Library_deinit, Library.prototype, null); + } + + constructor() { + const ret = instance.exports.bjs_Library_init(); + return Library.__construct(ret); + } + divider(value) { + structHelpers.M10TestModuleT7LibraryT5ShelfT7Divider.lower(value); + instance.exports.bjs_Library_divider(this.pointer); + const structValue = structHelpers.M10TestModuleT7LibraryT5ShelfT7Divider.lift(); + return structValue; + } + } + class Outer extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Outer_deinit, Outer.prototype, null); + } + + constructor() { + const ret = instance.exports.bjs_Outer_init(); + return Outer.__construct(ret); + } + } + const __bjs_helpers_M10TestModuleT7LibraryT5Shelf = __bjs_createStructHelpers_M10TestModuleT7LibraryT5Shelf(); + structHelpers.M10TestModuleT7LibraryT5Shelf = __bjs_helpers_M10TestModuleT7LibraryT5Shelf; + + const __bjs_helpers_M10TestModuleT7LibraryT5ShelfT7Divider = __bjs_createStructHelpers_M10TestModuleT7LibraryT5ShelfT7Divider(); + structHelpers.M10TestModuleT7LibraryT5ShelfT7Divider = __bjs_helpers_M10TestModuleT7LibraryT5ShelfT7Divider; + + const __bjs_helpers_M10TestModuleT5OuterT5Inner = __bjs_createStructHelpers_M10TestModuleT5OuterT5Inner(); + structHelpers.M10TestModuleT5OuterT5Inner = __bjs_helpers_M10TestModuleT5OuterT5Inner; + + const __bjs_helpers_M10TestModuleT5OuterT5InnerT5Outer = __bjs_createStructHelpers_M10TestModuleT5OuterT5InnerT5Outer(); + structHelpers.M10TestModuleT5OuterT5InnerT5Outer = __bjs_helpers_M10TestModuleT5OuterT5InnerT5Outer; + + const __bjs_helpers_M10TestModuleT5OuterT5InnerT5OuterT5Inner = __bjs_createStructHelpers_M10TestModuleT5OuterT5InnerT5OuterT5Inner(); + structHelpers.M10TestModuleT5OuterT5InnerT5OuterT5Inner = __bjs_helpers_M10TestModuleT5OuterT5InnerT5OuterT5Inner; + + const exports = { + Library: Object.assign(Library, { + Shelf: { + Divider: { + init: function(slot) { + instance.exports.bjs_Library_Shelf_Divider_init(slot); + const structValue = structHelpers.M10TestModuleT7LibraryT5ShelfT7Divider.lift(); + return structValue; + }, + }, + }, + }), + Outer: Object.assign(Outer, { + Inner: { + init: function() { + instance.exports.bjs_Outer_Inner_init(); + const structValue = structHelpers.M10TestModuleT5OuterT5Inner.lift(); + return structValue; + }, + Outer: { + Inner: { + init: function() { + instance.exports.bjs_Outer_Inner_Outer_Inner_init(); + const structValue = structHelpers.M10TestModuleT5OuterT5InnerT5OuterT5Inner.lift(); + return structValue; + }, + }, + }, + }, + }), + }; + _exports = exports; + return exports; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.js index 25f989a00..f46f42d10 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.js @@ -42,7 +42,7 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createAPIResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT9APIResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -150,6 +150,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -351,8 +353,8 @@ export async function createInstantiator(options, swift) { return ret; } } - const APIResultHelpers = __bjs_createAPIResultValuesHelpers(); - enumHelpers.APIResult = APIResultHelpers; + const __bjs_helpers_M10TestModuleT9APIResult = __bjs_createEnumHelpers_M10TestModuleT9APIResult(); + enumHelpers.M10TestModuleT9APIResult = __bjs_helpers_M10TestModuleT9APIResult; if (typeof globalThis.Utils === 'undefined') { globalThis.Utils = {}; @@ -381,9 +383,9 @@ export async function createInstantiator(options, swift) { APIResult: { ...APIResultValues, roundtrip: function(value) { - const valueCaseId = enumHelpers.APIResult.lower(value); + const valueCaseId = enumHelpers.M10TestModuleT9APIResult.lower(value); instance.exports.bjs_APIResult_static_roundtrip(valueCaseId); - const ret = enumHelpers.APIResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT9APIResult.lift(i32Stack.pop()); return ret; } }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.js index ca4093992..37d3415a4 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.js @@ -42,7 +42,7 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createAPIResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT9APIResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -150,6 +150,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -351,8 +353,8 @@ export async function createInstantiator(options, swift) { return ret; } } - const APIResultHelpers = __bjs_createAPIResultValuesHelpers(); - enumHelpers.APIResult = APIResultHelpers; + const __bjs_helpers_M10TestModuleT9APIResult = __bjs_createEnumHelpers_M10TestModuleT9APIResult(); + enumHelpers.M10TestModuleT9APIResult = __bjs_helpers_M10TestModuleT9APIResult; const exports = { Calculator: { @@ -375,9 +377,9 @@ export async function createInstantiator(options, swift) { APIResult: { ...APIResultValues, roundtrip: function(value) { - const valueCaseId = enumHelpers.APIResult.lower(value); + const valueCaseId = enumHelpers.M10TestModuleT9APIResult.lower(value); instance.exports.bjs_APIResult_static_roundtrip(valueCaseId); - const ret = enumHelpers.APIResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT9APIResult.lift(i32Stack.pop()); return ret; } }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.js index 63dd9cba5..e2a9093b6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.js @@ -111,6 +111,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.js index b5680b9b0..f442745e5 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.js @@ -111,6 +111,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.js index 2c3da5f26..ebddbefd2 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.js index 057bf9658..d2dfa204f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StructWithNestedTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StructWithNestedTypes.js index ee5cc0a3e..9104e2084 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StructWithNestedTypes.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StructWithNestedTypes.js @@ -46,7 +46,7 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createShapeHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT5Shape = () => ({ lower: (value) => { const bytes = textEncoder.encode(value.label); const id = swift.memory.retain(bytes); @@ -58,7 +58,7 @@ export async function createInstantiator(options, swift) { return { label: string }; } }); - const __bjs_createWidgetHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT6Widget = () => ({ lower: (value) => { const bytes = textEncoder.encode(value.name); const id = swift.memory.retain(bytes); @@ -70,7 +70,7 @@ export async function createInstantiator(options, swift) { return { name: string }; } }); - const __bjs_createWidget_LayoutHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT6WidgetT6Layout = () => ({ lower: (value) => { i32Stack.push((value.padding | 0)); }, @@ -79,7 +79,7 @@ export async function createInstantiator(options, swift) { return { padding: int }; } }); - const __bjs_createWidget_BoundsHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT6WidgetT6Bounds = () => ({ lower: (value) => { i32Stack.push((value.width | 0)); i32Stack.push((value.height | 0)); @@ -166,33 +166,35 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_Shape"] = function(objectId) { - structHelpers.Shape.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT5Shape.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Shape"] = function() { - const value = structHelpers.Shape.lift(); + const value = structHelpers.M10TestModuleT5Shape.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Widget"] = function(objectId) { - structHelpers.Widget.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT6Widget.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Widget"] = function() { - const value = structHelpers.Widget.lift(); + const value = structHelpers.M10TestModuleT6Widget.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Widget_Layout"] = function(objectId) { - structHelpers.Widget_Layout.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT6WidgetT6Layout.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Widget_Layout"] = function() { - const value = structHelpers.Widget_Layout.lift(); + const value = structHelpers.M10TestModuleT6WidgetT6Layout.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Widget_Bounds"] = function(objectId) { - structHelpers.Widget_Bounds.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT6WidgetT6Bounds.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Widget_Bounds"] = function() { - const value = structHelpers.Widget_Bounds.lift(); + const value = structHelpers.M10TestModuleT6WidgetT6Bounds.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -304,17 +306,17 @@ export async function createInstantiator(options, swift) { /** @param {WebAssembly.Instance} instance */ createExports: (instance) => { const js = swift.memory.heap; - const ShapeHelpers = __bjs_createShapeHelpers(); - structHelpers.Shape = ShapeHelpers; + const __bjs_helpers_M10TestModuleT5Shape = __bjs_createStructHelpers_M10TestModuleT5Shape(); + structHelpers.M10TestModuleT5Shape = __bjs_helpers_M10TestModuleT5Shape; - const WidgetHelpers = __bjs_createWidgetHelpers(); - structHelpers.Widget = WidgetHelpers; + const __bjs_helpers_M10TestModuleT6Widget = __bjs_createStructHelpers_M10TestModuleT6Widget(); + structHelpers.M10TestModuleT6Widget = __bjs_helpers_M10TestModuleT6Widget; - const Widget_LayoutHelpers = __bjs_createWidget_LayoutHelpers(); - structHelpers.Widget_Layout = Widget_LayoutHelpers; + const __bjs_helpers_M10TestModuleT6WidgetT6Layout = __bjs_createStructHelpers_M10TestModuleT6WidgetT6Layout(); + structHelpers.M10TestModuleT6WidgetT6Layout = __bjs_helpers_M10TestModuleT6WidgetT6Layout; - const Widget_BoundsHelpers = __bjs_createWidget_BoundsHelpers(); - structHelpers.Widget_Bounds = Widget_BoundsHelpers; + const __bjs_helpers_M10TestModuleT6WidgetT6Bounds = __bjs_createStructHelpers_M10TestModuleT6WidgetT6Bounds(); + structHelpers.M10TestModuleT6WidgetT6Bounds = __bjs_helpers_M10TestModuleT6WidgetT6Bounds; const exports = { Shape: { @@ -322,7 +324,7 @@ export async function createInstantiator(options, swift) { const labelBytes = textEncoder.encode(label); const labelId = swift.memory.retain(labelBytes); instance.exports.bjs_Shape_init(labelId, labelBytes.length); - const structValue = structHelpers.Shape.lift(); + const structValue = structHelpers.M10TestModuleT5Shape.lift(); return structValue; }, Kind: KindValues, @@ -332,14 +334,14 @@ export async function createInstantiator(options, swift) { const nameBytes = textEncoder.encode(name); const nameId = swift.memory.retain(nameBytes); instance.exports.bjs_Widget_init(nameId, nameBytes.length); - const structValue = structHelpers.Widget.lift(); + const structValue = structHelpers.M10TestModuleT6Widget.lift(); return structValue; }, Variant: VariantValues, Bounds: { init: function(width, height) { instance.exports.bjs_Widget_Bounds_init(width, height); - const structValue = structHelpers.Widget_Bounds.lift(); + const structValue = structHelpers.M10TestModuleT6WidgetT6Bounds.lift(); return structValue; }, get dimensions() { @@ -348,7 +350,7 @@ export async function createInstantiator(options, swift) { }, zero: function() { instance.exports.bjs_Widget_Bounds_static_zero(); - const structValue = structHelpers.Widget_Bounds.lift(); + const structValue = structHelpers.M10TestModuleT6WidgetT6Bounds.lift(); return structValue; }, }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.js index be63f59be..92ef435fb 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosure.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosure.js index 62c2de8c6..279a9d3c6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosure.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosure.js @@ -61,6 +61,240 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + function __bjs_jsValueLower(value) { let kind; let payload1; @@ -175,7 +409,18 @@ export async function createInstantiator(options, swift) { return swift.memory.retain(real); }; - const __bjs_createAnimalHelpers = () => ({ + const __bjs_codec_M10TestModuleT6Animal = { + lower: (v) => { + structHelpers.M10TestModuleT6Animal.lower(v); + }, + lift: () => { + const struct = structHelpers.M10TestModuleT6Animal.lift(); + return struct; + }, + }; + const __bjs_codec_Optional_M10TestModuleT6Animal = __bjs_optionalCodec(__bjs_codec_M10TestModuleT6Animal); + + const __bjs_createStructHelpers_M10TestModuleT6Animal = () => ({ lower: (value) => { const bytes = textEncoder.encode(value.type); const id = swift.memory.retain(bytes); @@ -187,7 +432,7 @@ export async function createInstantiator(options, swift) { return { type: string }; } }); - const __bjs_createAPIResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT9APIResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -324,12 +569,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_Animal"] = function(objectId) { - structHelpers.Animal.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT6Animal.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Animal"] = function() { - const value = structHelpers.Animal.lift(); + const value = structHelpers.M10TestModuleT6Animal.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -347,7 +594,7 @@ export async function createInstantiator(options, swift) { } bjs["promise_resolve_TestModule_6AnimalV"] = function(promise) { try { - const structValue = structHelpers.Animal.lift(); + const structValue = structHelpers.M10TestModuleT6Animal.lift(); swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(structValue); } catch (error) { setException(error); @@ -355,7 +602,7 @@ export async function createInstantiator(options, swift) { } bjs["promise_resolve_TestModule_9APIResultO"] = function(promise, value) { try { - const enumValue = enumHelpers.APIResult.lift(value); + const enumValue = enumHelpers.M10TestModuleT9APIResult.lift(value); swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(enumValue); } catch (error) { setException(error); @@ -517,18 +764,18 @@ export async function createInstantiator(options, swift) { bjs["invoke_js_callback_TestModule_10TestModule6AnimalV_6AnimalV"] = function(callbackId) { try { const callback = swift.memory.getObject(callbackId); - const structValue = structHelpers.Animal.lift(); + const structValue = structHelpers.M10TestModuleT6Animal.lift(); let ret = callback(structValue); - structHelpers.Animal.lower(ret); + structHelpers.M10TestModuleT6Animal.lower(ret); } catch (error) { setException(error); } } bjs["make_swift_closure_TestModule_10TestModule6AnimalV_6AnimalV"] = function(boxPtr, file, line) { const lower_closure_TestModule_10TestModule6AnimalV_6AnimalV = function(param0) { - structHelpers.Animal.lower(param0); + structHelpers.M10TestModuleT6Animal.lower(param0); instance.exports.invoke_swift_closure_TestModule_10TestModule6AnimalV_6AnimalV(boxPtr); - const structValue = structHelpers.Animal.lift(); + const structValue = structHelpers.M10TestModuleT6Animal.lift(); if (tmpRetException) { const error = swift.memory.getObject(tmpRetException); swift.memory.release(tmpRetException); @@ -565,9 +812,9 @@ export async function createInstantiator(options, swift) { bjs["invoke_js_callback_TestModule_10TestModule9APIResultO_9APIResultO"] = function(callbackId, param0) { try { const callback = swift.memory.getObject(callbackId); - const enumValue = enumHelpers.APIResult.lift(param0); + const enumValue = enumHelpers.M10TestModuleT9APIResult.lift(param0); let ret = callback(enumValue); - const caseId = enumHelpers.APIResult.lower(ret); + const caseId = enumHelpers.M10TestModuleT9APIResult.lower(ret); return caseId; } catch (error) { setException(error); @@ -575,9 +822,9 @@ export async function createInstantiator(options, swift) { } bjs["make_swift_closure_TestModule_10TestModule9APIResultO_9APIResultO"] = function(boxPtr, file, line) { const lower_closure_TestModule_10TestModule9APIResultO_9APIResultO = function(param0) { - const param0CaseId = enumHelpers.APIResult.lower(param0); + const param0CaseId = enumHelpers.M10TestModuleT9APIResult.lower(param0); instance.exports.invoke_swift_closure_TestModule_10TestModule9APIResultO_9APIResultO(boxPtr, param0CaseId); - const ret = enumHelpers.APIResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT9APIResult.lift(i32Stack.pop()); if (tmpRetException) { const error = swift.memory.getObject(tmpRetException); swift.memory.release(tmpRetException); @@ -852,43 +1099,28 @@ export async function createInstantiator(options, swift) { }; return makeClosure(boxPtr, file, line, lower_closure_TestModule_10TestModuleSq5ThemeO_Sq5ThemeO); } - bjs["invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV"] = function(callbackId, param0) { + bjs["invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV"] = function(callbackId) { try { const callback = swift.memory.getObject(callbackId); - let optResult; - if (param0) { - const struct = structHelpers.Animal.lift(); - optResult = struct; - } else { - optResult = null; - } - let ret = callback(optResult); - const isSome = ret != null; - if (isSome) { - structHelpers.Animal.lower(ret); - } - i32Stack.push(isSome ? 1 : 0); + const optValue = __bjs_codec_Optional_M10TestModuleT6Animal.lift(); + let ret = callback(optValue); + __bjs_codec_Optional_M10TestModuleT6Animal.lower(ret); } catch (error) { setException(error); } } bjs["make_swift_closure_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV"] = function(boxPtr, file, line) { const lower_closure_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV = function(param0) { - const isSome = param0 != null; - if (isSome) { - structHelpers.Animal.lower(param0); - } - i32Stack.push(+isSome); + __bjs_codec_Optional_M10TestModuleT6Animal.lower(param0); instance.exports.invoke_swift_closure_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV(boxPtr); - const isSome1 = i32Stack.pop(); - const optResult = isSome1 ? structHelpers.Animal.lift() : null; + const optValue = __bjs_codec_Optional_M10TestModuleT6Animal.lift(); if (tmpRetException) { const error = swift.memory.getObject(tmpRetException); swift.memory.release(tmpRetException); tmpRetException = undefined; throw error; } - return optResult; + return optValue; }; return makeClosure(boxPtr, file, line, lower_closure_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV); } @@ -930,7 +1162,7 @@ export async function createInstantiator(options, swift) { const callback = swift.memory.getObject(callbackId); let optResult; if (param0IsSome) { - const enumValue = enumHelpers.APIResult.lift(param0CaseId); + const enumValue = enumHelpers.M10TestModuleT9APIResult.lift(param0CaseId); optResult = enumValue; } else { optResult = null; @@ -938,7 +1170,7 @@ export async function createInstantiator(options, swift) { let ret = callback(optResult); const isSome = ret != null; if (isSome) { - const caseId = enumHelpers.APIResult.lower(ret); + const caseId = enumHelpers.M10TestModuleT9APIResult.lower(ret); return caseId; } else { return -1; @@ -952,14 +1184,14 @@ export async function createInstantiator(options, swift) { const isSome = param0 != null; let result; if (isSome) { - const param0CaseId = enumHelpers.APIResult.lower(param0); + const param0CaseId = enumHelpers.M10TestModuleT9APIResult.lower(param0); result = param0CaseId; } else { result = 0; } instance.exports.invoke_swift_closure_TestModule_10TestModuleSq9APIResultO_Sq9APIResultO(boxPtr, +isSome, result); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.APIResult.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT9APIResult.lift(tag); if (tmpRetException) { const error = swift.memory.getObject(tmpRetException); swift.memory.release(tmpRetException); @@ -1227,7 +1459,7 @@ export async function createInstantiator(options, swift) { bjs["invoke_js_callback_TestModule_10TestModules6AnimalV_y"] = function(callbackId) { try { const callback = swift.memory.getObject(callbackId); - const structValue = structHelpers.Animal.lift(); + const structValue = structHelpers.M10TestModuleT6Animal.lift(); callback(structValue); } catch (error) { setException(error); @@ -1235,7 +1467,7 @@ export async function createInstantiator(options, swift) { } bjs["make_swift_closure_TestModule_10TestModules6AnimalV_y"] = function(boxPtr, file, line) { const lower_closure_TestModule_10TestModules6AnimalV_y = function(param0) { - structHelpers.Animal.lower(param0); + structHelpers.M10TestModuleT6Animal.lower(param0); instance.exports.invoke_swift_closure_TestModule_10TestModules6AnimalV_y(boxPtr); if (tmpRetException) { const error = swift.memory.getObject(tmpRetException); @@ -1271,7 +1503,7 @@ export async function createInstantiator(options, swift) { bjs["invoke_js_callback_TestModule_10TestModules9APIResultO_y"] = function(callbackId, param0) { try { const callback = swift.memory.getObject(callbackId); - const enumValue = enumHelpers.APIResult.lift(param0); + const enumValue = enumHelpers.M10TestModuleT9APIResult.lift(param0); callback(enumValue); } catch (error) { setException(error); @@ -1279,7 +1511,7 @@ export async function createInstantiator(options, swift) { } bjs["make_swift_closure_TestModule_10TestModules9APIResultO_y"] = function(boxPtr, file, line) { const lower_closure_TestModule_10TestModules9APIResultO_y = function(param0) { - const param0CaseId = enumHelpers.APIResult.lower(param0); + const param0CaseId = enumHelpers.M10TestModuleT9APIResult.lower(param0); instance.exports.invoke_swift_closure_TestModule_10TestModules9APIResultO_y(boxPtr, param0CaseId); if (tmpRetException) { const error = swift.memory.getObject(tmpRetException); @@ -1414,11 +1646,11 @@ export async function createInstantiator(options, swift) { return TestProcessor.__construct(ret); } } - const AnimalHelpers = __bjs_createAnimalHelpers(); - structHelpers.Animal = AnimalHelpers; + const __bjs_helpers_M10TestModuleT6Animal = __bjs_createStructHelpers_M10TestModuleT6Animal(); + structHelpers.M10TestModuleT6Animal = __bjs_helpers_M10TestModuleT6Animal; - const APIResultHelpers = __bjs_createAPIResultValuesHelpers(); - enumHelpers.APIResult = APIResultHelpers; + const __bjs_helpers_M10TestModuleT9APIResult = __bjs_createEnumHelpers_M10TestModuleT9APIResult(); + enumHelpers.M10TestModuleT9APIResult = __bjs_helpers_M10TestModuleT9APIResult; const exports = { roundtripAnimal: function bjs_roundtripAnimal(animalClosure) { @@ -1569,7 +1801,7 @@ export async function createInstantiator(options, swift) { const typeBytes = textEncoder.encode(type); const typeId = swift.memory.retain(typeBytes); instance.exports.bjs_Animal_init(typeId, typeBytes.length); - const structValue = structHelpers.Animal.lift(); + const structValue = structHelpers.M10TestModuleT6Animal.lift(); return structValue; }, }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosureImports.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosureImports.js index d03915f87..96c78dd22 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosureImports.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosureImports.js @@ -221,6 +221,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.js index 92a99becb..fc3d9ddbb 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.js @@ -36,7 +36,357 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createDataPointHelpers = () => ({ + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_Optional_Int = __bjs_optionalCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_Optional_Bool = __bjs_optionalCodec(__bjs_primitiveCodecs.Bool); + const __bjs_codec_Optional_String = __bjs_optionalCodec(__bjs_stringCodec); + const __bjs_codec_M10TestModuleT9Precision = { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const rawValue = f32Stack.pop(); + return rawValue; + }, + }; + const __bjs_codec_Optional_M10TestModuleT9Precision = __bjs_optionalCodec(__bjs_codec_M10TestModuleT9Precision); + const __bjs_codec_JSObject = { + lower: (v) => { + const objId = swift.memory.retain(v); + i32Stack.push(objId); + }, + lift: () => { + const objId = i32Stack.pop(); + const obj = swift.memory.getObject(objId); + swift.memory.release(objId); + return obj; + }, + }; + const __bjs_codec_Optional_JSObject = __bjs_optionalCodec(__bjs_codec_JSObject); + + const __bjs_createStructHelpers_M10TestModuleT9DataPoint = () => ({ lower: (value) => { f64Stack.push(value.x); f64Stack.push(value.y); @@ -44,41 +394,19 @@ export async function createInstantiator(options, swift) { const id = swift.memory.retain(bytes); i32Stack.push(bytes.length); i32Stack.push(id); - const isSome = value.optCount != null ? 1 : 0; - if (isSome) { - i32Stack.push((value.optCount | 0)); - } - i32Stack.push(isSome); - const isSome1 = value.optFlag != null ? 1 : 0; - if (isSome1) { - i32Stack.push(value.optFlag ? 1 : 0); - } - i32Stack.push(isSome1); + __bjs_codec_Optional_Int.lower(value.optCount); + __bjs_codec_Optional_Bool.lower(value.optFlag); }, lift: () => { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const bool = i32Stack.pop() !== 0; - optValue = bool; - } - const isSome1 = i32Stack.pop(); - let optValue1; - if (isSome1 === 0) { - optValue1 = null; - } else { - const int = i32Stack.pop(); - optValue1 = int; - } + const optValue = __bjs_codec_Optional_Bool.lift(); + const optValue1 = __bjs_codec_Optional_Int.lift(); const string = strStack.pop(); const f64 = f64Stack.pop(); const f641 = f64Stack.pop(); return { x: f641, y: f64, label: string, optCount: optValue1, optFlag: optValue }; } }); - const __bjs_createAddressHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT7Address = () => ({ lower: (value) => { const bytes = textEncoder.encode(value.street); const id = swift.memory.retain(bytes); @@ -88,59 +416,34 @@ export async function createInstantiator(options, swift) { const id1 = swift.memory.retain(bytes1); i32Stack.push(bytes1.length); i32Stack.push(id1); - const isSome = value.zipCode != null ? 1 : 0; - if (isSome) { - i32Stack.push((value.zipCode | 0)); - } - i32Stack.push(isSome); + __bjs_codec_Optional_Int.lower(value.zipCode); }, lift: () => { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const int = i32Stack.pop(); - optValue = int; - } + const optValue = __bjs_codec_Optional_Int.lift(); const string = strStack.pop(); const string1 = strStack.pop(); return { street: string1, city: string, zipCode: optValue }; } }); - const __bjs_createPersonHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT6Person = () => ({ lower: (value) => { const bytes = textEncoder.encode(value.name); const id = swift.memory.retain(bytes); i32Stack.push(bytes.length); i32Stack.push(id); i32Stack.push((value.age | 0)); - structHelpers.Address.lower(value.address); - const isSome = value.email != null ? 1 : 0; - if (isSome) { - const bytes1 = textEncoder.encode(value.email); - const id1 = swift.memory.retain(bytes1); - i32Stack.push(bytes1.length); - i32Stack.push(id1); - } - i32Stack.push(isSome); + structHelpers.M10TestModuleT7Address.lower(value.address); + __bjs_codec_Optional_String.lower(value.email); }, lift: () => { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const string = strStack.pop(); - optValue = string; - } - const struct = structHelpers.Address.lift(); + const optValue = __bjs_codec_Optional_String.lift(); + const struct = structHelpers.M10TestModuleT7Address.lift(); const int = i32Stack.pop(); - const string1 = strStack.pop(); - return { name: string1, age: int, address: struct, email: optValue }; + const string = strStack.pop(); + return { name: string, age: int, address: struct, email: optValue }; } }); - const __bjs_createSessionHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT7Session = () => ({ lower: (value) => { i32Stack.push((value.id | 0)); ptrStack.push(value.owner.pointer); @@ -152,38 +455,27 @@ export async function createInstantiator(options, swift) { return { id: int, owner: obj }; } }); - const __bjs_createMeasurementHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT11Measurement = () => ({ lower: (value) => { f64Stack.push(value.value); f32Stack.push(Math.fround(value.precision)); - const isSome = value.optionalPrecision != null ? 1 : 0; - if (isSome) { - f32Stack.push(Math.fround(value.optionalPrecision)); - } - i32Stack.push(isSome); + __bjs_codec_Optional_M10TestModuleT9Precision.lower(value.optionalPrecision); }, lift: () => { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const rawValue = f32Stack.pop(); - optValue = rawValue; - } - const rawValue1 = f32Stack.pop(); + const optValue = __bjs_codec_Optional_M10TestModuleT9Precision.lift(); + const rawValue = f32Stack.pop(); const f64 = f64Stack.pop(); - return { value: f64, precision: rawValue1, optionalPrecision: optValue }; + return { value: f64, precision: rawValue, optionalPrecision: optValue }; } }); - const __bjs_createConfigStructHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT12ConfigStruct = () => ({ lower: (value) => { }, lift: () => { return { }; } }); - const __bjs_createContainerHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT9Container = () => ({ lower: (value) => { let id; if (value.object != null) { @@ -192,24 +484,10 @@ export async function createInstantiator(options, swift) { id = undefined; } i32Stack.push(id !== undefined ? id : 0); - const isSome = value.optionalObject != null ? 1 : 0; - if (isSome) { - const objId = swift.memory.retain(value.optionalObject); - i32Stack.push(objId); - } - i32Stack.push(isSome); + __bjs_codec_Optional_JSObject.lower(value.optionalObject); }, lift: () => { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const objId = i32Stack.pop(); - const obj = swift.memory.getObject(objId); - swift.memory.release(objId); - optValue = obj; - } + const optValue = __bjs_codec_Optional_JSObject.lift(); const objectId = i32Stack.pop(); let value; if (objectId !== 0) { @@ -221,7 +499,7 @@ export async function createInstantiator(options, swift) { return { object: value, optionalObject: optValue }; } }); - const __bjs_createVector2DHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT8Vector2D = () => ({ lower: (value) => { f64Stack.push(value.dx); f64Stack.push(value.dy); @@ -231,18 +509,18 @@ export async function createInstantiator(options, swift) { const f641 = f64Stack.pop(); const instance1 = { dx: f641, dy: f64 }; instance1.magnitude = function() { - structHelpers.Vector2D.lower(this); + structHelpers.M10TestModuleT8Vector2D.lower(this); const ret = instance.exports.bjs_Vector2D_magnitude(); return ret; }.bind(instance1); instance1.scaled = function(factor) { - structHelpers.Vector2D.lower(this); + structHelpers.M10TestModuleT8Vector2D.lower(this); const ret1 = instance.exports.bjs_Vector2D_scaled(factor); - const structValue = structHelpers.Vector2D.lift(); + const structValue = structHelpers.M10TestModuleT8Vector2D.lift(); return structValue; }.bind(instance1); instance1.describe = function() { - structHelpers.Vector2D.lower(this); + structHelpers.M10TestModuleT8Vector2D.lower(this); const ret2 = instance.exports.bjs_Vector2D_describe(); const ret3 = tmpRetString; tmpRetString = undefined; @@ -327,61 +605,63 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_DataPoint"] = function(objectId) { - structHelpers.DataPoint.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT9DataPoint.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_DataPoint"] = function() { - const value = structHelpers.DataPoint.lift(); + const value = structHelpers.M10TestModuleT9DataPoint.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Address"] = function(objectId) { - structHelpers.Address.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT7Address.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Address"] = function() { - const value = structHelpers.Address.lift(); + const value = structHelpers.M10TestModuleT7Address.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Person"] = function(objectId) { - structHelpers.Person.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT6Person.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Person"] = function() { - const value = structHelpers.Person.lift(); + const value = structHelpers.M10TestModuleT6Person.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Session"] = function(objectId) { - structHelpers.Session.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT7Session.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Session"] = function() { - const value = structHelpers.Session.lift(); + const value = structHelpers.M10TestModuleT7Session.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Measurement"] = function(objectId) { - structHelpers.Measurement.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT11Measurement.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Measurement"] = function() { - const value = structHelpers.Measurement.lift(); + const value = structHelpers.M10TestModuleT11Measurement.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_ConfigStruct"] = function(objectId) { - structHelpers.ConfigStruct.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT12ConfigStruct.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_ConfigStruct"] = function() { - const value = structHelpers.ConfigStruct.lift(); + const value = structHelpers.M10TestModuleT12ConfigStruct.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Container"] = function(objectId) { - structHelpers.Container.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT9Container.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Container"] = function() { - const value = structHelpers.Container.lift(); + const value = structHelpers.M10TestModuleT9Container.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Vector2D"] = function(objectId) { - structHelpers.Vector2D.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT8Vector2D.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Vector2D"] = function() { - const value = structHelpers.Vector2D.lift(); + const value = structHelpers.M10TestModuleT8Vector2D.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -582,41 +862,41 @@ export async function createInstantiator(options, swift) { instance.exports.bjs_Greeter_name_set(this.pointer, valueId, valueBytes.length); } } - const DataPointHelpers = __bjs_createDataPointHelpers(); - structHelpers.DataPoint = DataPointHelpers; + const __bjs_helpers_M10TestModuleT9DataPoint = __bjs_createStructHelpers_M10TestModuleT9DataPoint(); + structHelpers.M10TestModuleT9DataPoint = __bjs_helpers_M10TestModuleT9DataPoint; - const AddressHelpers = __bjs_createAddressHelpers(); - structHelpers.Address = AddressHelpers; + const __bjs_helpers_M10TestModuleT7Address = __bjs_createStructHelpers_M10TestModuleT7Address(); + structHelpers.M10TestModuleT7Address = __bjs_helpers_M10TestModuleT7Address; - const PersonHelpers = __bjs_createPersonHelpers(); - structHelpers.Person = PersonHelpers; + const __bjs_helpers_M10TestModuleT6Person = __bjs_createStructHelpers_M10TestModuleT6Person(); + structHelpers.M10TestModuleT6Person = __bjs_helpers_M10TestModuleT6Person; - const SessionHelpers = __bjs_createSessionHelpers(); - structHelpers.Session = SessionHelpers; + const __bjs_helpers_M10TestModuleT7Session = __bjs_createStructHelpers_M10TestModuleT7Session(); + structHelpers.M10TestModuleT7Session = __bjs_helpers_M10TestModuleT7Session; - const MeasurementHelpers = __bjs_createMeasurementHelpers(); - structHelpers.Measurement = MeasurementHelpers; + const __bjs_helpers_M10TestModuleT11Measurement = __bjs_createStructHelpers_M10TestModuleT11Measurement(); + structHelpers.M10TestModuleT11Measurement = __bjs_helpers_M10TestModuleT11Measurement; - const ConfigStructHelpers = __bjs_createConfigStructHelpers(); - structHelpers.ConfigStruct = ConfigStructHelpers; + const __bjs_helpers_M10TestModuleT12ConfigStruct = __bjs_createStructHelpers_M10TestModuleT12ConfigStruct(); + structHelpers.M10TestModuleT12ConfigStruct = __bjs_helpers_M10TestModuleT12ConfigStruct; - const ContainerHelpers = __bjs_createContainerHelpers(); - structHelpers.Container = ContainerHelpers; + const __bjs_helpers_M10TestModuleT9Container = __bjs_createStructHelpers_M10TestModuleT9Container(); + structHelpers.M10TestModuleT9Container = __bjs_helpers_M10TestModuleT9Container; - const Vector2DHelpers = __bjs_createVector2DHelpers(); - structHelpers.Vector2D = Vector2DHelpers; + const __bjs_helpers_M10TestModuleT8Vector2D = __bjs_createStructHelpers_M10TestModuleT8Vector2D(); + structHelpers.M10TestModuleT8Vector2D = __bjs_helpers_M10TestModuleT8Vector2D; const exports = { roundtrip: function bjs_roundtrip(session) { - structHelpers.Person.lower(session); + structHelpers.M10TestModuleT6Person.lower(session); instance.exports.bjs_roundtrip(); - const structValue = structHelpers.Person.lift(); + const structValue = structHelpers.M10TestModuleT6Person.lift(); return structValue; }, roundtripContainer: function bjs_roundtripContainer(container) { - structHelpers.Container.lower(container); + structHelpers.M10TestModuleT9Container.lower(container); instance.exports.bjs_roundtripContainer(); - const structValue = structHelpers.Container.lift(); + const structValue = structHelpers.M10TestModuleT9Container.lift(); return structValue; }, Precision: PrecisionValues, @@ -661,7 +941,7 @@ export async function createInstantiator(options, swift) { const isSome = optCount != null; const isSome1 = optFlag != null; instance.exports.bjs_DataPoint_init(x, y, labelId, labelBytes.length, +isSome, isSome ? optCount : 0, +isSome1, isSome1 ? optFlag ? 1 : 0 : 0); - const structValue = structHelpers.DataPoint.lift(); + const structValue = structHelpers.M10TestModuleT9DataPoint.lift(); return structValue; }, get dimensions() { @@ -670,7 +950,7 @@ export async function createInstantiator(options, swift) { }, origin: function() { instance.exports.bjs_DataPoint_static_origin(); - const structValue = structHelpers.DataPoint.lift(); + const structValue = structHelpers.M10TestModuleT9DataPoint.lift(); return structValue; }, }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStructImports.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStructImports.js index 4a2e18d6b..134d7c28e 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStructImports.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStructImports.js @@ -31,7 +31,341 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createPointHelpers = () => ({ + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_M10TestModuleT5Point = { + lower: (v) => { + structHelpers.M10TestModuleT5Point.lower(v); + }, + lift: () => { + const struct = structHelpers.M10TestModuleT5Point.lift(); + return struct; + }, + }; + const __bjs_codec_Optional_M10TestModuleT5Point = __bjs_optionalCodec(__bjs_codec_M10TestModuleT5Point); + + const __bjs_createStructHelpers_M10TestModuleT5Point = () => ({ lower: (value) => { i32Stack.push((value.x | 0)); i32Stack.push((value.y | 0)); @@ -119,12 +453,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_Point"] = function(objectId) { - structHelpers.Point.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT5Point.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Point"] = function() { - const value = structHelpers.Point.lift(); + const value = structHelpers.M10TestModuleT5Point.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -225,28 +561,18 @@ export async function createInstantiator(options, swift) { const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_translate"] = function bjs_translate(dx, dy) { try { - const structValue = structHelpers.Point.lift(); + const structValue = structHelpers.M10TestModuleT5Point.lift(); let ret = imports.translate(structValue, dx, dy); - structHelpers.Point.lower(ret); + structHelpers.M10TestModuleT5Point.lower(ret); } catch (error) { setException(error); } } - TestModule["bjs_roundTripOptional"] = function bjs_roundTripOptional(point) { + TestModule["bjs_roundTripOptional"] = function bjs_roundTripOptional() { try { - let optResult; - if (point) { - const struct = structHelpers.Point.lift(); - optResult = struct; - } else { - optResult = null; - } - let ret = imports.roundTripOptional(optResult); - const isSome = ret != null; - if (isSome) { - structHelpers.Point.lower(ret); - } - i32Stack.push(isSome ? 1 : 0); + const optValue = __bjs_codec_Optional_M10TestModuleT5Point.lift(); + let ret = imports.roundTripOptional(optValue); + __bjs_codec_Optional_M10TestModuleT5Point.lower(ret); } catch (error) { setException(error); } @@ -265,8 +591,8 @@ export async function createInstantiator(options, swift) { /** @param {WebAssembly.Instance} instance */ createExports: (instance) => { const js = swift.memory.heap; - const PointHelpers = __bjs_createPointHelpers(); - structHelpers.Point = PointHelpers; + const __bjs_helpers_M10TestModuleT5Point = __bjs_createStructHelpers_M10TestModuleT5Point(); + structHelpers.M10TestModuleT5Point = __bjs_helpers_M10TestModuleT5Point; const exports = { }; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftTypedClosureAccess.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftTypedClosureAccess.js index 66d6494fd..500a005a3 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftTypedClosureAccess.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftTypedClosureAccess.js @@ -131,6 +131,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.js index 6ff126525..58ff6a85a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/UnsafePointer.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/UnsafePointer.js index 457bfa973..416e5c281 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/UnsafePointer.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/UnsafePointer.js @@ -31,7 +31,7 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createPointerFieldsHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT13PointerFields = () => ({ lower: (value) => { ptrStack.push((value.raw | 0)); ptrStack.push((value.mutRaw | 0)); @@ -124,12 +124,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_PointerFields"] = function(objectId) { - structHelpers.PointerFields.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT13PointerFields.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_PointerFields"] = function() { - const value = structHelpers.PointerFields.lift(); + const value = structHelpers.M10TestModuleT13PointerFields.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -241,8 +243,8 @@ export async function createInstantiator(options, swift) { /** @param {WebAssembly.Instance} instance */ createExports: (instance) => { const js = swift.memory.heap; - const PointerFieldsHelpers = __bjs_createPointerFieldsHelpers(); - structHelpers.PointerFields = PointerFieldsHelpers; + const __bjs_helpers_M10TestModuleT13PointerFields = __bjs_createStructHelpers_M10TestModuleT13PointerFields(); + structHelpers.M10TestModuleT13PointerFields = __bjs_helpers_M10TestModuleT13PointerFields; const exports = { takeUnsafeRawPointer: function bjs_takeUnsafeRawPointer(p) { @@ -281,15 +283,15 @@ export async function createInstantiator(options, swift) { return ret; }, roundTripPointerFields: function bjs_roundTripPointerFields(value) { - structHelpers.PointerFields.lower(value); + structHelpers.M10TestModuleT13PointerFields.lower(value); instance.exports.bjs_roundTripPointerFields(); - const structValue = structHelpers.PointerFields.lift(); + const structValue = structHelpers.M10TestModuleT13PointerFields.lift(); return structValue; }, PointerFields: { init: function(raw, mutRaw, opaque, ptr, mutPtr) { instance.exports.bjs_PointerFields_init(raw, mutRaw, opaque, ptr, mutPtr); - const structValue = structHelpers.PointerFields.lift(); + const structValue = structHelpers.M10TestModuleT13PointerFields.lift(); return structValue; }, }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.js index 3c75771c5..81b09eaf4 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/PackageToJS/Sources/PackageToJS.swift b/Plugins/PackageToJS/Sources/PackageToJS.swift index c1d09af0a..c8adb9346 100644 --- a/Plugins/PackageToJS/Sources/PackageToJS.swift +++ b/Plugins/PackageToJS/Sources/PackageToJS.swift @@ -69,15 +69,31 @@ struct PackageToJS { var packageOptions: PackageOptions } - static func deriveBuildConfiguration(wasmProductArtifact: URL) -> (configuration: String, triple: String) { + /// Derives the build configuration from the path of the wasm product artifact. + /// Returns "debug" or "release" + static func deriveBuildConfiguration(wasmProductArtifact: URL) -> String { + // For "--build-system swiftbuild" + // e.g. path/to/.build/out/Products/Debug-webassembly-wasm32/Basic.wasm + // ref: https://github.com/swiftlang/swift-build/blob/48498f5450c85da3f8c09808168f0286d207329b/Sources/SWBCore/Core.swift#L631-L643 + // + // For "--build-system native" // e.g. path/to/.build/wasm32-unknown-wasi/debug/Basic.wasm -> ("debug", "wasm32-unknown-wasi") // First, resolve symlink to get the actual path as SwiftPM 6.0 and earlier returns unresolved // symlink path for product artifact. let wasmProductArtifact = wasmProductArtifact.resolvingSymlinksInPath() - let buildConfiguration = wasmProductArtifact.deletingLastPathComponent().lastPathComponent - let triple = wasmProductArtifact.deletingLastPathComponent().deletingLastPathComponent().lastPathComponent - return (buildConfiguration, triple) + let swiftBuildSuffix = "-webassembly-wasm32" + let parentDirName = wasmProductArtifact.deletingLastPathComponent().lastPathComponent + if parentDirName.hasSuffix(swiftBuildSuffix) { + // This is SwiftBuild backend mode + let swiftBuildConfig = String(parentDirName.dropLast(swiftBuildSuffix.count)) + guard let mappedConfig = ["Debug": "debug", "Release": "release"][swiftBuildConfig] else { + fatalError("Unknown SwiftPM build configuration: \(swiftBuildConfig)") + } + return mappedConfig + } + // This is native backend mode, the parent directory name is the build configuration + return parentDirName } static func runTest(testRunner: URL, currentDirectoryURL: URL, outputDir: URL, testOptions: TestOptions) throws { @@ -426,8 +442,6 @@ struct PackagingPlanner { let wasmProductArtifact: BuildPath /// The build configuration let configuration: String - /// The target triple - let triple: String /// The system interface to use let system: any PackagingSystem @@ -441,7 +455,6 @@ struct PackagingPlanner { wasmProductArtifact: BuildPath, wasmFilename: String, configuration: String, - triple: String, // NOTE: We should use `ProcessInfo.processInfo.arguments[0]` instead of `CommandLine.arguments[0]` // because the latter may not always be the full executable path (e.g. when invoked through PATH lookup). // https://github.com/swiftlang/swift-foundation/blob/f5143f96d01cdb6d280665de8221b75fc8631d95/Sources/FoundationEssentials/ProcessInfo/ProcessInfo.swift#L47 @@ -458,7 +471,6 @@ struct PackagingPlanner { self.selfPath = selfPath self.wasmProductArtifact = wasmProductArtifact self.configuration = configuration - self.triple = triple self.system = system } @@ -469,7 +481,7 @@ struct PackagingPlanner { make: inout MiniMake, buildOptions: PackageToJS.BuildOptions ) throws -> MiniMake.TaskKey { - let (allTasks, _, _, _) = try planBuildInternal( + let (allTasks, _, _, _, _) = try planBuildInternal( make: &make, noOptimize: buildOptions.noOptimize, debugInfoFormat: buildOptions.debugInfoFormat @@ -489,7 +501,8 @@ struct PackagingPlanner { allTasks: [MiniMake.TaskKey], outputDirTask: MiniMake.TaskKey, intermediatesDirTask: MiniMake.TaskKey, - packageJsonTask: MiniMake.TaskKey + packageJsonTask: MiniMake.TaskKey, + wasmImportsTask: MiniMake.TaskKey ) { // Prepare output directory let outputDirTask = make.addTask( @@ -575,20 +588,8 @@ struct PackagingPlanner { } packageInputs.append(wasm) - let wasmImportsPath = intermediatesDir.appending(path: "wasm-imports.json") - let wasmImportsTask = make.addTask( - inputFiles: [selfPath, finalWasmPath], - inputTasks: [outputDirTask, intermediatesDirTask, wasm], - output: wasmImportsPath - ) { - let metadata = try parseImports( - moduleBytes: try Data(contentsOf: URL(fileURLWithPath: $1.resolve(path: finalWasmPath).path)) - ) - let jsonEncoder = JSONEncoder() - jsonEncoder.outputFormatting = .prettyPrinted - let jsonData = try jsonEncoder.encode(metadata) - try system.writeFile(atPath: $1.resolve(path: $0.output).path, content: jsonData) - } + let wasmImportsPath = self.wasmImportsPath + let wasmImportsTask = planWasmImports(make: &make, intermediatesDirTask: intermediatesDirTask) packageInputs.append(wasmImportsTask) @@ -606,55 +607,20 @@ struct PackagingPlanner { file: "Plugins/PackageToJS/Templates/package.json", output: "package.json", outputDirTask: outputDirTask, + wasmImportsTask: wasmImportsTask, inputFiles: [], inputTasks: [] ) packageInputs.append(packageJsonTask) if !skeletons.isEmpty { - let bridge = try loadBridgeJS() - let skeletonFiles = skeletons.map { BuildPath(absolute: $0.source.path) } - let bridgeJs = outputDir.appending(path: "bridge-js.js") - let bridgeDts = outputDir.appending(path: "bridge-js.d.ts") - let bridgeModules = outputDir.appending(path: "bridge-js-modules") packageInputs.append( - make.addTask(inputFiles: skeletonFiles + [selfPath], output: bridgeJs) { _, scope in - let output = try bridge.link.link() - try system.writeFile( - atPath: scope.resolve(path: bridgeJs).path, - content: Data(output.outputJs.utf8) - ) - try system.writeFile( - atPath: scope.resolve(path: bridgeDts).path, - content: Data(output.outputDts.utf8) - ) - } - ) - let bridgeModulesStamp = intermediatesDir.appending(path: "bridge-js-modules.stamp") - packageInputs.append( - make.addTask( - inputFiles: skeletonFiles + bridge.modules.map(\.source) + [selfPath], - inputTasks: [outputDirTask, intermediatesDirTask], - output: bridgeModulesStamp - ) { _, scope in - let modulesDirectory = scope.resolve(path: bridgeModules) - try system.removeItemIfExists(atPath: modulesDirectory.path) - if !bridge.modules.isEmpty { - try system.createDirectory(atPath: modulesDirectory.path) - } - for module in bridge.modules { - let destination = scope.resolve(path: outputDir.appending(path: module.relativeOutputPath)) - try system.createDirectory(atPath: destination.deletingLastPathComponent().path) - try system.syncFile( - from: scope.resolve(path: module.source).path, - to: destination.path - ) - } - try system.writeFile( - atPath: scope.resolve(path: bridgeModulesStamp).path, - content: Data() - ) - } + contentsOf: try planBridgeJS( + make: &make, + outputDirTask: outputDirTask, + intermediatesDirTask: intermediatesDirTask, + wasmImportsTask: wasmImportsTask + ) ) } @@ -678,22 +644,20 @@ struct PackagingPlanner { file: file, output: output, outputDirTask: outputDirTask, - inputFiles: [wasmImportsPath], - inputTasks: [platformsDirTask, wasmImportsTask], - wasmImportsPath: wasmImportsPath + wasmImportsTask: wasmImportsTask, + inputFiles: [], + inputTasks: [platformsDirTask] ) ) } - return (packageInputs, outputDirTask, intermediatesDirTask, packageJsonTask) + return (packageInputs, outputDirTask, intermediatesDirTask, packageJsonTask, wasmImportsTask) } private func loadBridgeJS() throws -> ( link: BridgeJSLink, modules: [JavaScriptModuleInput] ) { - var link = BridgeJSLink( - sharedMemory: Self.isSharedMemoryEnabled(triple: triple) - ) + var link = BridgeJSLink() var moduleSources: [String: BuildPath] = [:] for input in skeletons { @@ -731,30 +695,195 @@ struct PackagingPlanner { ) } + /// Plan the artifacts that several per-runner test bundles packaged as subdirectories + /// share. + /// + /// Node resolves `node_modules` by walking up the directory tree, so a single install + /// here serves every runner underneath, avoiding one install per test target. The glue + /// generated here describes every test target rather than the one target a runner links + /// in, so that test preludes - which are loaded for every runner and import it by a + /// fixed path - see the whole package's API. + func planSharedTestArtifacts(make: inout MiniMake) throws -> MiniMake.TaskKey { + let outputDirTask = make.addTask( + inputFiles: [selfPath], + output: outputDir, + attributes: [.silent] + ) { + try system.createDirectory(atPath: $1.resolve(path: $0.output).path) + } + let intermediatesDirTask = make.addTask( + inputFiles: [selfPath], + output: intermediatesDir, + attributes: [.silent] + ) { + try system.createDirectory(atPath: $1.resolve(path: $0.output).path) + } + let wasmImportsTask = planWasmImports(make: &make, intermediatesDirTask: intermediatesDirTask) + let packageJsonTask = planCopyTemplateFile( + make: &make, + file: "Plugins/PackageToJS/Templates/package.json", + output: "package.json", + outputDirTask: outputDirTask, + wasmImportsTask: wasmImportsTask, + inputFiles: [], + inputTasks: [] + ) + var tasks = [ + planNpmInstall( + make: &make, + intermediatesDirTask: intermediatesDirTask, + packageJsonTask: packageJsonTask + ) + ] + if !skeletons.isEmpty { + tasks.append( + contentsOf: try planBridgeJS( + make: &make, + outputDirTask: outputDirTask, + intermediatesDirTask: intermediatesDirTask, + wasmImportsTask: wasmImportsTask + ) + ) + } + return make.addTask( + inputTasks: tasks, + output: BuildPath(phony: "shared-test-artifacts"), + attributes: [.phony, .silent] + ) + } + + /// Plan the tasks generating the BridgeJS glue and syncing the JavaScript modules it + /// imports into the output directory + private func planBridgeJS( + make: inout MiniMake, + outputDirTask: MiniMake.TaskKey, + intermediatesDirTask: MiniMake.TaskKey, + wasmImportsTask: MiniMake.TaskKey + ) throws -> [MiniMake.TaskKey] { + let bridge = try loadBridgeJS() + let skeletonFiles = skeletons.map { BuildPath(absolute: $0.source.path) } + let wasmImportsPath = self.wasmImportsPath + let bridgeJs = outputDir.appending(path: "bridge-js.js") + let bridgeDts = outputDir.appending(path: "bridge-js.d.ts") + let bridgeModules = outputDir.appending(path: "bridge-js-modules") + let bridgeJsTask = make.addTask( + inputFiles: skeletonFiles + [selfPath, wasmImportsPath], + inputTasks: [outputDirTask, wasmImportsTask], + output: bridgeJs + ) { _, scope in + let features = try Self.loadWasmFeatures(at: scope.resolve(path: wasmImportsPath)) + let output = try bridge.link.link(sharedMemory: features.sharedMemory) + try system.writeFile( + atPath: scope.resolve(path: bridgeJs).path, + content: Data(output.outputJs.utf8) + ) + try system.writeFile( + atPath: scope.resolve(path: bridgeDts).path, + content: Data(output.outputDts.utf8) + ) + } + let bridgeModulesStamp = intermediatesDir.appending(path: "bridge-js-modules.stamp") + let bridgeModulesTask = make.addTask( + inputFiles: skeletonFiles + bridge.modules.map(\.source) + [selfPath], + inputTasks: [outputDirTask, intermediatesDirTask], + output: bridgeModulesStamp + ) { _, scope in + let modulesDirectory = scope.resolve(path: bridgeModules) + try system.removeItemIfExists(atPath: modulesDirectory.path) + if !bridge.modules.isEmpty { + try system.createDirectory(atPath: modulesDirectory.path) + } + for module in bridge.modules { + let destination = scope.resolve(path: outputDir.appending(path: module.relativeOutputPath)) + try system.createDirectory(atPath: destination.deletingLastPathComponent().path) + try system.syncFile( + from: scope.resolve(path: module.source).path, + to: destination.path + ) + } + try system.writeFile( + atPath: scope.resolve(path: bridgeModulesStamp).path, + content: Data() + ) + } + return [bridgeJsTask, bridgeModulesTask] + } + + /// Plan the task parsing the imports of the product .wasm file + /// + /// NOTE: The imports are parsed from the product artifact instead of the final .wasm + /// file because wasm-opt removes unreferenced imports, and the presence of an import + /// decides how the JavaScript glue code is generated. + private func planWasmImports( + make: inout MiniMake, + intermediatesDirTask: MiniMake.TaskKey + ) -> MiniMake.TaskKey { + make.addTask( + inputFiles: [selfPath, wasmProductArtifact], + inputTasks: [intermediatesDirTask], + output: wasmImportsPath + ) { + let metadata = try parseImports( + moduleBytes: try Data(contentsOf: URL(fileURLWithPath: $1.resolve(path: wasmProductArtifact).path)) + ) + let jsonEncoder = JSONEncoder() + jsonEncoder.outputFormatting = .prettyPrinted + let jsonData = try jsonEncoder.encode(metadata) + let outputPath = $1.resolve(path: $0.output) + // Every task consuming the imports depends on this file, so leave it untouched + // when the imports are unchanged. Rewriting it would give it a newer timestamp + // and re-run them (including `npm install`) for unrelated Swift source changes. + if let lastImports = try? Data(contentsOf: outputPath), lastImports == jsonData { + return + } + try system.writeFile(atPath: outputPath.path, content: jsonData) + } + } + + private func planNpmInstall( + make: inout MiniMake, + intermediatesDirTask: MiniMake.TaskKey, + packageJsonTask: MiniMake.TaskKey + ) -> MiniMake.TaskKey { + make.addTask( + inputFiles: [ + selfPath, + outputDir.appending(path: "package.json"), + ], + inputTasks: [intermediatesDirTask, packageJsonTask], + output: intermediatesDir.appending(path: "npm-install.stamp") + ) { + try system.npmInstall(packageDir: $1.resolve(path: outputDir).path) + try system.writeFile(atPath: $1.resolve(path: $0.output).path, content: Data()) + } + } + /// Construct the test build plan and return the root task key + /// + /// - Parameter installNodeModules: whether to install the test harness's npm + /// dependencies into this bundle's directory. Pass `false` when several runners share + /// a single `node_modules` planned once via `planSharedNodeModules`. func planTestBuild( - make: inout MiniMake + make: inout MiniMake, + installNodeModules: Bool = true ) throws -> (rootTask: MiniMake.TaskKey, binDir: BuildPath) { - var (allTasks, outputDirTask, intermediatesDirTask, packageJsonTask) = try planBuildInternal( + var (allTasks, outputDirTask, intermediatesDirTask, packageJsonTask, wasmImportsTask) = try planBuildInternal( make: &make, noOptimize: false, debugInfoFormat: .dwarf ) - // Install npm dependencies used in the test harness - allTasks.append( - make.addTask( - inputFiles: [ - selfPath, - outputDir.appending(path: "package.json"), - ], - inputTasks: [intermediatesDirTask, packageJsonTask], - output: intermediatesDir.appending(path: "npm-install.stamp") - ) { - try system.npmInstall(packageDir: $1.resolve(path: outputDir).path) - try system.writeFile(atPath: $1.resolve(path: $0.output).path, content: Data()) - } - ) + // Install npm dependencies used in the test harness, unless a shared node_modules is + // provided in a parent directory (see planSharedNodeModules). + if installNodeModules { + allTasks.append( + planNpmInstall( + make: &make, + intermediatesDirTask: intermediatesDirTask, + packageJsonTask: packageJsonTask + ) + ) + } let binDir = outputDir.appending(path: "bin") let binDirTask = make.addTask( @@ -779,6 +908,7 @@ struct PackagingPlanner { file: file, output: output, outputDirTask: outputDirTask, + wasmImportsTask: wasmImportsTask, inputFiles: [], inputTasks: [binDirTask] ) @@ -797,9 +927,9 @@ struct PackagingPlanner { file: String, output: String, outputDirTask: MiniMake.TaskKey, + wasmImportsTask: MiniMake.TaskKey, inputFiles: [BuildPath], - inputTasks: [MiniMake.TaskKey], - wasmImportsPath: BuildPath? = nil + inputTasks: [MiniMake.TaskKey] ) -> MiniMake.TaskKey { struct Salt: Encodable { @@ -808,9 +938,10 @@ struct PackagingPlanner { } let inputPath = selfPackageDir.appending(path: file) - let conditions: [String: Bool] = [ - "USE_SHARED_MEMORY": Self.isSharedMemoryEnabled(triple: triple), - "IS_WASI": triple.hasPrefix("wasm32-unknown-wasi"), + // NOTE: The conditions derived from the .wasm binary are not part of the salt because + // they are not known until the imports are parsed. The imports file is an input of + // this task instead, so a change in them still re-runs the preprocessing. + let staticConditions: [String: Bool] = [ "USE_WASI_CDN": options.useCDN, "HAS_BRIDGE": skeletons.count > 0, "HAS_IMPORTS": skeletons.count > 0, @@ -821,30 +952,26 @@ struct PackagingPlanner { "PACKAGE_TO_JS_MODULE_PATH": wasmFilename, "PACKAGE_TO_JS_PACKAGE_NAME": options.packageName ?? packageId.lowercased(), ] - let salt = Salt(conditions: conditions, substitutions: constantSubstitutions) + let salt = Salt(conditions: staticConditions, substitutions: constantSubstitutions) + let wasmImportsPath = self.wasmImportsPath return make.addTask( - inputFiles: [selfPath, inputPath] + inputFiles, - inputTasks: [outputDirTask] + inputTasks, + inputFiles: [selfPath, inputPath, wasmImportsPath] + inputFiles, + inputTasks: [outputDirTask, wasmImportsTask] + inputTasks, output: outputDir.appending(path: output), salt: salt ) { var substitutions = constantSubstitutions + let features = try Self.loadWasmFeatures(at: $1.resolve(path: wasmImportsPath)) - if let wasmImportsPath = wasmImportsPath { - let wasmImportsPath = $1.resolve(path: wasmImportsPath) - let importEntries = try JSONDecoder().decode( - [ImportEntry].self, - from: Data(contentsOf: wasmImportsPath) - ) - let memoryImport = importEntries.first { - $0.module == "env" && $0.name == "memory" - } - if case .memory(let type) = memoryImport?.kind { - substitutions["PACKAGE_TO_JS_MEMORY_INITIAL"] = type.minimum.description - substitutions["PACKAGE_TO_JS_MEMORY_MAXIMUM"] = (type.maximum ?? type.minimum).description - substitutions["PACKAGE_TO_JS_MEMORY_SHARED"] = type.shared.description - } + var conditions = staticConditions + conditions["USE_SHARED_MEMORY"] = features.sharedMemory + conditions["IS_WASI"] = features.isWASI + + if let memory = features.importedMemory { + substitutions["PACKAGE_TO_JS_MEMORY_INITIAL"] = memory.minimum.description + substitutions["PACKAGE_TO_JS_MEMORY_MAXIMUM"] = (memory.maximum ?? memory.minimum).description + substitutions["PACKAGE_TO_JS_MEMORY_SHARED"] = memory.shared.description } let inputPath = $1.resolve(path: inputPath) @@ -855,8 +982,38 @@ struct PackagingPlanner { } } - private static func isSharedMemoryEnabled(triple: String) -> Bool { - return triple == "wasm32-unknown-wasip1-threads" + /// The path to the JSON file describing the imports of the product .wasm file + var wasmImportsPath: BuildPath { + intermediatesDir.appending(path: "wasm-imports.json") + } + + static func loadWasmFeatures(at wasmImportsPath: URL) throws -> WasmFeatures { + let importEntries = try JSONDecoder().decode( + [ImportEntry].self, + from: Data(contentsOf: wasmImportsPath) + ) + return WasmFeatures(imports: importEntries) + } +} + +/// The traits of a .wasm binary that affect the JavaScript code generated for it +struct WasmFeatures { + /// Whether the module requires a WASI implementation to be instantiated + let isWASI: Bool + /// Whether the module uses shared memory + let sharedMemory: Bool + /// The type of the memory imported by the module if any + let importedMemory: MemoryType? + + init(imports: [ImportEntry]) { + self.isWASI = imports.contains { $0.module == "wasi_snapshot_preview1" } + let memoryImport = imports.first { $0.module == "env" && $0.name == "memory" } + if case .memory(let type) = memoryImport?.kind { + self.importedMemory = type + } else { + self.importedMemory = nil + } + self.sharedMemory = self.importedMemory?.shared ?? false } } diff --git a/Plugins/PackageToJS/Sources/PackageToJSPlugin.swift b/Plugins/PackageToJS/Sources/PackageToJSPlugin.swift index cc16de20a..560b3e980 100644 --- a/Plugins/PackageToJS/Sources/PackageToJSPlugin.swift +++ b/Plugins/PackageToJS/Sources/PackageToJSPlugin.swift @@ -8,7 +8,17 @@ @preconcurrency import struct Foundation.CocoaError @preconcurrency import func Foundation.fputs @preconcurrency import func Foundation.exit -@preconcurrency import var Foundation.stderr + +#if canImport(Darwin) +@preconcurrency import var Darwin.stderr +#elseif canImport(Glibc) +@preconcurrency import var Glibc.stderr +#elseif canImport(Musl) +@preconcurrency import var Musl.stderr +#elseif canImport(Android) +@preconcurrency import var Android.stderr +#endif + import PackagePlugin /// The main entry point for the PackageToJS plugin. @@ -264,69 +274,202 @@ struct PackageToJSPlugin: CommandPlugin { let skeletonCollector = SkeletonCollector(context: context) let skeletons = skeletonCollector.collectFromTests() - // NOTE: Find the product artifact from the default build directory + // NOTE: Find the product artifact(s) from the default build directory // because PackageManager.BuildResult doesn't include the // product artifact for tests. // This doesn't work when `--scratch-path` is used but // we don't have a way to guess the correct path. (we can find // the path by building a dummy executable product but it's // not worth the overhead) - var productArtifact: URL? - for fileExtension in ["wasm", "xctest"] { - let packageDir = context.package.directoryURL - let path = packageDir.appending(path: ".build/debug/\(productName).\(fileExtension)").path - if FileManager.default.fileExists(atPath: path) { - productArtifact = URL(fileURLWithPath: path) - break - } - } - guard let productArtifact = productArtifact else { - throw PackageToJSError( - "Failed to find '\(productName).wasm' or '\(productName).xctest'" - ) - } - let outputDir = + let productArtifacts = try findTestProductArtifacts( + productName: productName, + context: context, + options: testOptions.packageOptions + ) + + let baseOutputDir = if let outputPath = testOptions.packageOptions.outputPath { URL(fileURLWithPath: outputPath) } else { context.pluginWorkDirectoryURL.appending(path: "PackageTests") } - var make = MiniMake( - explain: testOptions.packageOptions.explain, - printProgress: self.printProgress - ) - let planner = PackagingPlanner( - options: testOptions.packageOptions, - context: context, - selfPackage: selfPackage, - skeletons: skeletons, - outputDir: outputDir, - wasmProductArtifact: productArtifact, - // If the product artifact doesn't have a .wasm extension, add it - // to deliver it with the correct MIME type when serving the test - // files for browser tests. - wasmFilename: productArtifact.lastPathComponent.hasSuffix(".wasm") - ? productArtifact.lastPathComponent - : productArtifact.lastPathComponent + ".wasm" - ) - let (rootTask, binDir) = try planner.planTestBuild( - make: &make - ) - cleanIfBuildGraphChanged(root: rootTask, make: make, context: context) - print("Packaging tests...") - let scope = MiniMake.VariableScope(variables: [:]) - try make.build(output: rootTask, scope: scope) - print("Packaging tests finished") - if !testOptions.buildOnly { - let testRunner = scope.resolve(path: binDir.appending(path: "test.js")) - try PackageToJS.runTest( - testRunner: testRunner, - currentDirectoryURL: context.pluginWorkDirectoryURL, + // With multiple runners, package what they share into the base directory once: the + // test harness's npm dependencies, and the glue describing every test target that + // preludes import by a fixed path. Each runner is packaged into a subdirectory of + // it. + let hasSharedArtifacts = productArtifacts.count > 1 + if hasSharedArtifacts, let firstArtifact = productArtifacts.first { + var make = MiniMake( + explain: testOptions.packageOptions.explain, + printProgress: self.printProgress + ) + let planner = PackagingPlanner( + options: testOptions.packageOptions, + context: context, + selfPackage: selfPackage, + skeletons: skeletons, + outputDir: baseOutputDir, + wasmProductArtifact: firstArtifact, + wasmFilename: firstArtifact.lastPathComponent.hasSuffix(".wasm") + ? firstArtifact.lastPathComponent + : firstArtifact.lastPathComponent + ".wasm" + ) + let rootTask = try planner.planSharedTestArtifacts(make: &make) + print("Packaging shared test artifacts...") + try make.build(output: rootTask, scope: MiniMake.VariableScope(variables: [:])) + } + + // The native build system links every test target into a single combined + // `PackageTests` binary, but SwiftBuild produces one runner per test + // target. Package and run each artifact. When there is more than one, give each its + // own output subdirectory and build fingerprint so their harnesses don't clobber one + // another, and keep going after a failure so every target's results are reported. + var anyTestFailed = false + for productArtifact in productArtifacts { + let runnerName = productArtifact.deletingPathExtension().lastPathComponent + let outputDir = + productArtifacts.count == 1 + ? baseOutputDir + : baseOutputDir.appending(path: runnerName) + + var make = MiniMake( + explain: testOptions.packageOptions.explain, + printProgress: self.printProgress + ) + let planner = PackagingPlanner( + options: testOptions.packageOptions, + context: context, + selfPackage: selfPackage, + // Generate the glue from what this binary actually links in: the combined + // binary holds every test target, while a per-target runner holds one. + skeletons: runnerSkeletons( + runnerName: runnerName, + isCombinedBinary: !hasSharedArtifacts, + context: context, + aggregated: skeletons + ), outputDir: outputDir, - testOptions: testOptions + wasmProductArtifact: productArtifact, + // If the product artifact doesn't have a .wasm extension, add it + // to deliver it with the correct MIME type when serving the test + // files for browser tests. + wasmFilename: productArtifact.lastPathComponent.hasSuffix(".wasm") + ? productArtifact.lastPathComponent + : productArtifact.lastPathComponent + ".wasm" + ) + let (rootTask, binDir) = try planner.planTestBuild( + make: &make, + installNodeModules: !hasSharedArtifacts ) + cleanIfBuildGraphChanged( + root: rootTask, + make: make, + context: context, + fingerprintName: productArtifacts.count == 1 ? "minimake.json" : "minimake-\(runnerName).json" + ) + if productArtifacts.count == 1 { + print("Packaging tests...") + } else { + print("Packaging tests for '\(runnerName)'...") + } + let scope = MiniMake.VariableScope(variables: [:]) + try make.build(output: rootTask, scope: scope) + print("Packaging tests finished") + + if !testOptions.buildOnly { + let testRunner = scope.resolve(path: binDir.appending(path: "test.js")) + do { + try PackageToJS.runTest( + testRunner: testRunner, + currentDirectoryURL: context.pluginWorkDirectoryURL, + outputDir: outputDir, + testOptions: testOptions + ) + } catch { + // Keep running the remaining test runners, but remember the failure so + // the overall command still exits non-zero. + printStderr("\(runnerName): \(error)") + anyTestFailed = true + } + } } + + if anyTestFailed { + exit(1) + } + } + + /// The skeletons describing the API a single test binary exposes. + /// + /// The native build system links every test target into one binary, so it gets the + /// skeletons of all of them. SwiftBuild produces a `-test-runner` per test + /// target, which only exposes that target and its dependencies. + private func runnerSkeletons( + runnerName: String, + isCombinedBinary: Bool, + context: PluginContext, + aggregated: [BridgeJSSkeletonInput] + ) -> [BridgeJSSkeletonInput] { + let testRunnerSuffix = "-test-runner" + guard !isCombinedBinary, runnerName.hasSuffix(testRunnerSuffix) else { + return aggregated + } + let targetName = String(runnerName.dropLast(testRunnerSuffix.count)) + return SkeletonCollector(context: context).collectFromTest(targetName: targetName) + } + + /// Locate the test product artifact(s) to run. + /// + /// The native build system links all test targets into a single combined + /// `PackageTests` binary. SwiftBuild instead emits one + /// `-test-runner.wasm` per test target and only an aggregate + /// orchestration product, so fall back to discovering those runners. + private func findTestProductArtifacts( + productName: String, + context: PluginContext, + options: PackageToJS.PackageOptions + ) throws -> [URL] { + let fileManager = FileManager.default + let packageDir = context.package.directoryURL + let configuration = (options.configuration ?? "debug").lowercased() + + // Native combined test binary. + for fileExtension in ["wasm", "xctest"] { + let path = packageDir.appending(path: ".build/\(configuration)/\(productName).\(fileExtension)").path + if fileManager.fileExists(atPath: path) { + return [URL(fileURLWithPath: path)] + } + } + + // SwiftBuild per-test-target runners: + // .build/out/Products/-webassembly-wasm32/-test-runner.wasm + let productsDir = packageDir.appending(path: ".build/out/Products") + if let configDirs = try? fileManager.contentsOfDirectory( + at: productsDir, + includingPropertiesForKeys: nil + ) { + let wasmConfigDirs = configDirs.filter { $0.lastPathComponent.hasSuffix("-webassembly-wasm32") } + let chosenDir = + wasmConfigDirs.first { $0.lastPathComponent.lowercased().hasPrefix(configuration) } + ?? wasmConfigDirs.first + if let chosenDir, + let entries = try? fileManager.contentsOfDirectory(at: chosenDir, includingPropertiesForKeys: nil) + { + let runners = + entries + .filter { $0.lastPathComponent.hasSuffix("-test-runner.wasm") } + .sorted { $0.lastPathComponent < $1.lastPathComponent } + if !runners.isEmpty { + return runners + } + } + } + + throw PackageToJSError( + "Failed to find '\(productName).wasm' or '\(productName).xctest' (native build system), " + + "or any '*-test-runner.wasm' under .build/out/Products (swiftbuild build system)" + ) } private func buildWasm( @@ -414,9 +557,10 @@ struct PackageToJSPlugin: CommandPlugin { private func cleanIfBuildGraphChanged( root: MiniMake.TaskKey, make: MiniMake, - context: PluginContext + context: PluginContext, + fingerprintName: String = "minimake.json" ) { - let buildFingerprint = context.pluginWorkDirectoryURL.appending(path: "minimake.json") + let buildFingerprint = context.pluginWorkDirectoryURL.appending(path: fingerprintName) let lastBuildFingerprint = try? Data(contentsOf: buildFingerprint) let currentBuildFingerprint = try? make.computeFingerprint(root: root) if lastBuildFingerprint != currentBuildFingerprint { @@ -721,16 +865,28 @@ class SkeletonCollector { } func collectFromTests() -> [BridgeJSSkeletonInput] { - let tests = context.package.targets.filter { - guard let target = $0 as? SwiftSourceModuleTarget else { return false } - return target.kind == .test - } - for test in tests { + for test in testTargets { visit(target: test, package: context.package) } return skeletons } + /// Collect the skeletons of a single test target and everything it links in. + func collectFromTest(targetName: String) -> [BridgeJSSkeletonInput] { + guard let test = testTargets.first(where: { $0.name == targetName }) else { + return [] + } + visit(target: test, package: context.package) + return skeletons + } + + private var testTargets: [Target] { + context.package.targets.filter { + guard let target = $0 as? SwiftSourceModuleTarget else { return false } + return target.kind == .test + } + } + private func visit(product: Product, package: Package) { if visitedProducts.contains(product.id) { return } visitedProducts.insert(product.id) @@ -799,7 +955,7 @@ extension PackagingPlanner { wasmFilename: String ) { let outputBaseName = outputDir.lastPathComponent - let (configuration, triple) = PackageToJS.deriveBuildConfiguration(wasmProductArtifact: wasmProductArtifact) + let configuration = PackageToJS.deriveBuildConfiguration(wasmProductArtifact: wasmProductArtifact) let system = DefaultPackagingSystem(printWarning: printStderr, which: which(_:)) self.init( options: options, @@ -813,7 +969,6 @@ extension PackagingPlanner { wasmProductArtifact: BuildPath(absolute: wasmProductArtifact.path), wasmFilename: wasmFilename, configuration: configuration, - triple: triple, system: system ) } diff --git a/Plugins/PackageToJS/Sources/ParseWasm.swift b/Plugins/PackageToJS/Sources/ParseWasm.swift index 4372b32c5..31cd4a692 100644 --- a/Plugins/PackageToJS/Sources/ParseWasm.swift +++ b/Plugins/PackageToJS/Sources/ParseWasm.swift @@ -186,27 +186,29 @@ func parseImports(moduleBytes: Data) throws -> [ImportEntry] { let name = try parseState.readName() let type = try parseState.readByte() + let kind: ImportEntry.ImportKind switch type { case 0x00: // Function let index = try parseState.readUnsignedLEB128() guard index < UInt32(types.count) else { throw ParseError.unexpectedEndOfData } + kind = .function case 0x01: // Table _ = try parseTableType(parseState) + kind = .table case 0x02: // Memory - let limits = try parseLimits(parseState) - imports.append( - ImportEntry(module: module, name: name, kind: .memory(type: limits)) - ) + kind = .memory(type: try parseLimits(parseState)) case 0x03: // Global _ = try parseGlobalType(parseState) + kind = .global default: throw ParseError.unknownImportDescriptorType(type) } + imports.append(ImportEntry(module: module, name: name, kind: kind)) } // Skip the rest of the module return imports diff --git a/Plugins/PackageToJS/Templates/instantiate.js b/Plugins/PackageToJS/Templates/instantiate.js index 36d840099..7ceafe715 100644 --- a/Plugins/PackageToJS/Templates/instantiate.js +++ b/Plugins/PackageToJS/Templates/instantiate.js @@ -70,6 +70,7 @@ async function createInstantiator(options, swift) { swift_js_closure_unregister: unexpectedBjsCall, swift_js_push_typed_array: unexpectedBjsCall, swift_js_make_promise: unexpectedBjsCall, + bjs_core_register_type_handles: unexpectedBjsCall, }; }, /** @param {WebAssembly.Instance} instance */ @@ -84,7 +85,7 @@ async function createInstantiator(options, swift) { /** @type {import('./instantiate.d').instantiate} */ export async function instantiate(options) { - const result = await _instantiate(options); + const { instantiator, ...result } = await _instantiate(options); /* #if IS_WASI */ options.wasi.initialize(result.instance); /* #endif */ @@ -94,7 +95,7 @@ export async function instantiate(options) { /** @type {import('./instantiate.d').instantiateForThread} */ export async function instantiateForThread(tid, startArg, options) { - const result = await _instantiate(options); + const { instantiator, ...result } = await _instantiate(options); /* #if IS_WASI */ options.wasi.setInstance(result.instance); /* #endif */ @@ -102,7 +103,7 @@ export async function instantiateForThread(tid, startArg, options) { return result; } -/** @type {import('./instantiate.d').instantiate} */ +/** @param {import('./instantiate.d').InstantiateOptions} options */ async function _instantiate(options) { const _WebAssembly = options.WebAssembly || WebAssembly; const moduleSource = options.module; @@ -184,5 +185,6 @@ async function _instantiate(options) { instance, swift, exports, + instantiator, }; } diff --git a/Plugins/PackageToJS/Tests/PackagingPlannerTests.swift b/Plugins/PackageToJS/Tests/PackagingPlannerTests.swift index 12187a201..4cff48e6c 100644 --- a/Plugins/PackageToJS/Tests/PackagingPlannerTests.swift +++ b/Plugins/PackageToJS/Tests/PackagingPlannerTests.swift @@ -76,7 +76,6 @@ import Testing wasmProductArtifact: BuildPath(prefix: "WASM_PRODUCT_ARTIFACT"), wasmFilename: "main.wasm", configuration: configuration, - triple: "wasm32-unknown-wasi", selfPath: BuildPath(prefix: "PLANNER_SOURCE_PATH"), system: system ) @@ -106,7 +105,6 @@ import Testing wasmProductArtifact: BuildPath(prefix: "WASM_PRODUCT_ARTIFACT"), wasmFilename: "main.wasm", configuration: "debug", - triple: "wasm32-unknown-wasi", selfPath: BuildPath(prefix: "PLANNER_SOURCE_PATH"), system: system ) @@ -172,7 +170,6 @@ import Testing wasmProductArtifact: BuildPath(absolute: wasm.path), wasmFilename: "main.wasm", configuration: "debug", - triple: "wasm32-unknown-wasi", selfPath: BuildPath(absolute: plannerSource.path), system: system ) @@ -266,7 +263,6 @@ import Testing wasmProductArtifact: BuildPath(absolute: wasm.path), wasmFilename: "main.wasm", configuration: "debug", - triple: "wasm32-unknown-wasi", selfPath: BuildPath(absolute: plannerSource.path), system: system ) @@ -345,7 +341,6 @@ import Testing wasmProductArtifact: BuildPath(absolute: wasm.path), wasmFilename: "main.wasm", configuration: "debug", - triple: "wasm32-unknown-wasi", selfPath: BuildPath(absolute: plannerSource.path), system: system ) @@ -370,3 +365,57 @@ import Testing } } } + +@Suite struct WasmFeaturesTests { + private func memoryImport(shared: Bool) -> ImportEntry { + ImportEntry( + module: "env", + name: "memory", + kind: .memory(type: MemoryType(minimum: 17, maximum: 65536, shared: shared, index: .i32)) + ) + } + + @Test func noImports() { + let features = WasmFeatures(imports: []) + #expect(features.isWASI == false) + #expect(features.sharedMemory == false) + #expect(features.importedMemory == nil) + } + + @Test func wasiImport() { + let features = WasmFeatures(imports: [ + ImportEntry(module: "wasi_snapshot_preview1", name: "proc_exit", kind: .function) + ]) + #expect(features.isWASI == true) + #expect(features.sharedMemory == false) + } + + @Test func unsharedMemoryImport() { + let features = WasmFeatures(imports: [memoryImport(shared: false)]) + #expect(features.sharedMemory == false) + #expect(features.importedMemory?.minimum == 17) + } + + @Test func sharedMemoryImport() { + let features = WasmFeatures(imports: [ + memoryImport(shared: true), + ImportEntry(module: "wasi", name: "thread-spawn", kind: .function), + ]) + #expect(features.sharedMemory == true) + #expect(features.isWASI == false) + } + + /// Only the memory imported as "env.memory" is the one instantiated by the generated + /// JavaScript, so a memory imported under another name must not be picked up. + @Test func otherMemoryImport() { + let features = WasmFeatures(imports: [ + ImportEntry( + module: "other", + name: "memory", + kind: .memory(type: MemoryType(minimum: 1, maximum: nil, shared: true, index: .i32)) + ) + ]) + #expect(features.sharedMemory == false) + #expect(features.importedMemory == nil) + } +} diff --git a/Plugins/PackageToJS/Tests/ParseWasmTests.swift b/Plugins/PackageToJS/Tests/ParseWasmTests.swift new file mode 100644 index 000000000..7da67b6d6 --- /dev/null +++ b/Plugins/PackageToJS/Tests/ParseWasmTests.swift @@ -0,0 +1,52 @@ +import Foundation +import Testing + +@testable import PackageToJS + +@Suite struct ParseWasmTests { + /// A module importing `wasi_snapshot_preview1.proc_exit`, `env.memory` and `env.__stack_pointer` + private var moduleBytes: Data { + var bytes: [UInt8] = [ + 0x00, 0x61, 0x73, 0x6D, // magic + 0x01, 0x00, 0x00, 0x00, // version + ] + // Type section: [(i32) -> ()] + let typeSection: [UInt8] = [0x01, 0x60, 0x01, 0x7F, 0x00] + bytes += [0x01, UInt8(typeSection.count)] + typeSection + + var importSection: [UInt8] = [0x03] // 3 imports + func name(_ value: String) -> [UInt8] { + [UInt8(value.utf8.count)] + Array(value.utf8) + } + importSection += name("wasi_snapshot_preview1") + name("proc_exit") + [0x00, 0x00] + importSection += name("env") + name("memory") + [0x02, 0x00, 0x11] + importSection += name("env") + name("__stack_pointer") + [0x03, 0x7F, 0x01] + bytes += [0x02, UInt8(importSection.count)] + importSection + + return Data(bytes) + } + + @Test func parseAllImportKinds() throws { + let imports = try parseImports(moduleBytes: moduleBytes) + #expect(imports.count == 3) + #expect(imports[0].module == "wasi_snapshot_preview1") + #expect(imports[0].name == "proc_exit") + if case .function = imports[0].kind { + } else { + Issue.record("expected a function import, got \(imports[0].kind)") + } + #expect(imports[2].name == "__stack_pointer") + if case .global = imports[2].kind { + } else { + Issue.record("expected a global import, got \(imports[2].kind)") + } + } + + /// WASI is detected by the imported functions, so they must not be dropped while parsing. + @Test func deriveFeaturesFromParsedImports() throws { + let features = WasmFeatures(imports: try parseImports(moduleBytes: moduleBytes)) + #expect(features.isWASI == true) + #expect(features.sharedMemory == false) + #expect(features.importedMemory?.minimum == 17) + } +} diff --git a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_debug.json b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_debug.json index 49cee1f90..fefcda9b2 100644 --- a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_debug.json +++ b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_debug.json @@ -17,13 +17,11 @@ ], "inputs" : [ "$PLANNER_SOURCE_PATH", - "$OUTPUT\/main.wasm" + "$WASM_PRODUCT_ARTIFACT" ], "output" : "$INTERMEDIATES\/wasm-imports.json", "wants" : [ - "$OUTPUT", - "$INTERMEDIATES", - "$OUTPUT\/main.wasm" + "$INTERMEDIATES" ] }, { @@ -48,11 +46,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/index.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -65,11 +63,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/index.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -82,11 +80,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/instantiate.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -99,11 +97,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/instantiate.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -125,12 +123,14 @@ ], "inputs" : [ "$PLANNER_SOURCE_PATH", - "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/package.json" + "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/package.json", + "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/package.json", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ - "$OUTPUT" + "$OUTPUT", + "$INTERMEDIATES\/wasm-imports.json" ] }, { @@ -155,11 +155,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/browser.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -172,11 +172,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/browser.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -189,11 +189,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/browser.worker.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -206,11 +206,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/node.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -223,11 +223,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/node.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -240,11 +240,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/runtime.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -257,11 +257,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/runtime.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { diff --git a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release.json b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release.json index 6b1e1090c..32fc2b670 100644 --- a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release.json +++ b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release.json @@ -31,13 +31,11 @@ ], "inputs" : [ "$PLANNER_SOURCE_PATH", - "$OUTPUT\/main.wasm" + "$WASM_PRODUCT_ARTIFACT" ], "output" : "$INTERMEDIATES\/wasm-imports.json", "wants" : [ - "$OUTPUT", - "$INTERMEDIATES", - "$OUTPUT\/main.wasm" + "$INTERMEDIATES" ] }, { @@ -62,11 +60,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/index.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -79,11 +77,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/index.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -96,11 +94,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/instantiate.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -113,11 +111,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/instantiate.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -140,12 +138,14 @@ ], "inputs" : [ "$PLANNER_SOURCE_PATH", - "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/package.json" + "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/package.json", + "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/package.json", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ - "$OUTPUT" + "$OUTPUT", + "$INTERMEDIATES\/wasm-imports.json" ] }, { @@ -170,11 +170,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/browser.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -187,11 +187,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/browser.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -204,11 +204,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/browser.worker.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -221,11 +221,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/node.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -238,11 +238,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/node.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -255,11 +255,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/runtime.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -272,11 +272,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/runtime.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { diff --git a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_dwarf.json b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_dwarf.json index 49cee1f90..fefcda9b2 100644 --- a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_dwarf.json +++ b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_dwarf.json @@ -17,13 +17,11 @@ ], "inputs" : [ "$PLANNER_SOURCE_PATH", - "$OUTPUT\/main.wasm" + "$WASM_PRODUCT_ARTIFACT" ], "output" : "$INTERMEDIATES\/wasm-imports.json", "wants" : [ - "$OUTPUT", - "$INTERMEDIATES", - "$OUTPUT\/main.wasm" + "$INTERMEDIATES" ] }, { @@ -48,11 +46,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/index.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -65,11 +63,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/index.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -82,11 +80,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/instantiate.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -99,11 +97,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/instantiate.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -125,12 +123,14 @@ ], "inputs" : [ "$PLANNER_SOURCE_PATH", - "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/package.json" + "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/package.json", + "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/package.json", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ - "$OUTPUT" + "$OUTPUT", + "$INTERMEDIATES\/wasm-imports.json" ] }, { @@ -155,11 +155,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/browser.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -172,11 +172,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/browser.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -189,11 +189,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/browser.worker.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -206,11 +206,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/node.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -223,11 +223,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/node.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -240,11 +240,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/runtime.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -257,11 +257,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/runtime.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { diff --git a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_name.json b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_name.json index 6b1e1090c..32fc2b670 100644 --- a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_name.json +++ b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_name.json @@ -31,13 +31,11 @@ ], "inputs" : [ "$PLANNER_SOURCE_PATH", - "$OUTPUT\/main.wasm" + "$WASM_PRODUCT_ARTIFACT" ], "output" : "$INTERMEDIATES\/wasm-imports.json", "wants" : [ - "$OUTPUT", - "$INTERMEDIATES", - "$OUTPUT\/main.wasm" + "$INTERMEDIATES" ] }, { @@ -62,11 +60,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/index.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -79,11 +77,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/index.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -96,11 +94,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/instantiate.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -113,11 +111,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/instantiate.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -140,12 +138,14 @@ ], "inputs" : [ "$PLANNER_SOURCE_PATH", - "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/package.json" + "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/package.json", + "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/package.json", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ - "$OUTPUT" + "$OUTPUT", + "$INTERMEDIATES\/wasm-imports.json" ] }, { @@ -170,11 +170,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/browser.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -187,11 +187,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/browser.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -204,11 +204,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/browser.worker.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -221,11 +221,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/node.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -238,11 +238,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/node.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -255,11 +255,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/runtime.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -272,11 +272,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/runtime.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { diff --git a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_no_optimize.json b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_no_optimize.json index 49cee1f90..fefcda9b2 100644 --- a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_no_optimize.json +++ b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planBuild_release_no_optimize.json @@ -17,13 +17,11 @@ ], "inputs" : [ "$PLANNER_SOURCE_PATH", - "$OUTPUT\/main.wasm" + "$WASM_PRODUCT_ARTIFACT" ], "output" : "$INTERMEDIATES\/wasm-imports.json", "wants" : [ - "$OUTPUT", - "$INTERMEDIATES", - "$OUTPUT\/main.wasm" + "$INTERMEDIATES" ] }, { @@ -48,11 +46,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/index.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -65,11 +63,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/index.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -82,11 +80,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/instantiate.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -99,11 +97,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/instantiate.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -125,12 +123,14 @@ ], "inputs" : [ "$PLANNER_SOURCE_PATH", - "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/package.json" + "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/package.json", + "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/package.json", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ - "$OUTPUT" + "$OUTPUT", + "$INTERMEDIATES\/wasm-imports.json" ] }, { @@ -155,11 +155,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/browser.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -172,11 +172,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/browser.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -189,11 +189,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/browser.worker.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -206,11 +206,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/node.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -223,11 +223,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/node.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -240,11 +240,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/runtime.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -257,11 +257,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/runtime.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { diff --git a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planTestBuild.json b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planTestBuild.json index 5f16f6e8e..b6b382ae3 100644 --- a/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planTestBuild.json +++ b/Plugins/PackageToJS/Tests/__Snapshots__/PackagingPlannerTests/planTestBuild.json @@ -31,13 +31,11 @@ ], "inputs" : [ "$PLANNER_SOURCE_PATH", - "$OUTPUT\/main.wasm" + "$WASM_PRODUCT_ARTIFACT" ], "output" : "$INTERMEDIATES\/wasm-imports.json", "wants" : [ - "$OUTPUT", - "$INTERMEDIATES", - "$OUTPUT\/main.wasm" + "$INTERMEDIATES" ] }, { @@ -70,12 +68,14 @@ ], "inputs" : [ "$PLANNER_SOURCE_PATH", - "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/bin\/test.js" + "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/bin\/test.js", + "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/bin\/test.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", + "$INTERMEDIATES\/wasm-imports.json", "$OUTPUT\/bin" ] }, @@ -89,11 +89,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/index.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -106,11 +106,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/index.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -123,11 +123,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/instantiate.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -140,11 +140,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/instantiate.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -166,12 +166,14 @@ ], "inputs" : [ "$PLANNER_SOURCE_PATH", - "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/package.json" + "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/package.json", + "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/package.json", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ - "$OUTPUT" + "$OUTPUT", + "$INTERMEDIATES\/wasm-imports.json" ] }, { @@ -196,11 +198,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/browser.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -213,11 +215,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/browser.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -230,11 +232,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/browser.worker.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -247,11 +249,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/node.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -264,11 +266,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/platforms\/node.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -281,11 +283,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/runtime.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -298,11 +300,11 @@ "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/runtime.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", - "$OUTPUT\/platforms", - "$INTERMEDIATES\/wasm-imports.json" + "$INTERMEDIATES\/wasm-imports.json", + "$OUTPUT\/platforms" ] }, { @@ -311,12 +313,14 @@ ], "inputs" : [ "$PLANNER_SOURCE_PATH", - "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/test.browser.html" + "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/test.browser.html", + "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/test.browser.html", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", + "$INTERMEDIATES\/wasm-imports.json", "$OUTPUT\/bin" ] }, @@ -326,12 +330,14 @@ ], "inputs" : [ "$PLANNER_SOURCE_PATH", - "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/test.d.ts" + "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/test.d.ts", + "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/test.d.ts", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", + "$INTERMEDIATES\/wasm-imports.json", "$OUTPUT\/bin" ] }, @@ -341,12 +347,14 @@ ], "inputs" : [ "$PLANNER_SOURCE_PATH", - "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/test.js" + "$SELF_PACKAGE\/Plugins\/PackageToJS\/Templates\/test.js", + "$INTERMEDIATES\/wasm-imports.json" ], "output" : "$OUTPUT\/test.js", - "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIklTX1dBU0kiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfU0hBUkVEX01FTU9SWSI6ZmFsc2UsIlVTRV9XQVNJX0NETiI6ZmFsc2V9LCJzdWJzdGl0dXRpb25zIjp7IlBBQ0tBR0VfVE9fSlNfTU9EVUxFX1BBVEgiOiJtYWluLndhc20iLCJQQUNLQUdFX1RPX0pTX1BBQ0tBR0VfTkFNRSI6InRlc3QifX0=", + "salt" : "eyJjb25kaXRpb25zIjp7IkhBU19CUklER0UiOmZhbHNlLCJIQVNfSU1QT1JUUyI6ZmFsc2UsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX0JST1dTRVIiOnRydWUsIlRBUkdFVF9ERUZBVUxUX1BMQVRGT1JNX05PREUiOmZhbHNlLCJVU0VfV0FTSV9DRE4iOmZhbHNlfSwic3Vic3RpdHV0aW9ucyI6eyJQQUNLQUdFX1RPX0pTX01PRFVMRV9QQVRIIjoibWFpbi53YXNtIiwiUEFDS0FHRV9UT19KU19QQUNLQUdFX05BTUUiOiJ0ZXN0In19", "wants" : [ "$OUTPUT", + "$INTERMEDIATES\/wasm-imports.json", "$OUTPUT\/bin" ] }, diff --git a/Sources/JavaScriptKit/BridgeJSIntrinsics.swift b/Sources/JavaScriptKit/BridgeJSIntrinsics.swift index 4eeae4dac..ab0a9f4f0 100644 --- a/Sources/JavaScriptKit/BridgeJSIntrinsics.swift +++ b/Sources/JavaScriptKit/BridgeJSIntrinsics.swift @@ -204,6 +204,45 @@ extension _BridgedSwiftStackType { } } +/// A type usable as a generic argument of an imported `@JSFunction`. +public protocol BridgedSwiftGenericBridgeable: _BridgedSwiftStackType +where StackLiftResult == Self { + @_spi(BridgeJS) static var bridgeJSTypeHandle: BridgeJSTypeHandle { get } +} + +extension BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static var bridgeJSTypeID: Int32 { bridgeJSTypeHandle.typeID } + + @_spi(BridgeJS) public static func bridgeJSMakeTypeHandle() -> BridgeJSTypeHandle { + #if hasFeature(Embedded) + return BridgeJSTypeHandle() + #else + return BridgeJSTypeHandle(Self.self) + #endif + } +} + +/// A per-type identity token for generic bridging. +public final class BridgeJSTypeHandle: Sendable { + #if hasFeature(Embedded) + public init() {} + #else + public nonisolated(unsafe) let type: any BridgedSwiftGenericBridgeable.Type + + public init(_ type: any BridgedSwiftGenericBridgeable.Type) { + self.type = type + } + #endif + + @_spi(BridgeJS) public var typeID: Int32 { + #if arch(wasm32) + return Int32(bitPattern: UInt32(UInt(bitPattern: Unmanaged.passUnretained(self).toOpaque()))) + #else + _onlyAvailableOnWasm() + #endif + } +} + /// Types that bridge with the same (isSome, value) ABI as Optional. /// Used by JSUndefinedOr so all bridge methods delegate to Optional. public protocol _BridgedAsOptional { @@ -808,6 +847,49 @@ extension String: _BridgedSwiftStackType { } } +extension Bool: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Bool.bridgeJSMakeTypeHandle() +} +extension Int: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Int.bridgeJSMakeTypeHandle() +} +extension Float: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Float.bridgeJSMakeTypeHandle() +} +extension Double: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Double.bridgeJSMakeTypeHandle() +} +extension String: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = String.bridgeJSMakeTypeHandle() +} +extension UInt: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = UInt.bridgeJSMakeTypeHandle() +} +extension Int8: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Int8.bridgeJSMakeTypeHandle() +} +extension UInt8: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = UInt8.bridgeJSMakeTypeHandle() +} +extension Int16: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Int16.bridgeJSMakeTypeHandle() +} +extension UInt16: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = UInt16.bridgeJSMakeTypeHandle() +} +extension Int32: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Int32.bridgeJSMakeTypeHandle() +} +extension UInt32: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = UInt32.bridgeJSMakeTypeHandle() +} +extension Int64: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Int64.bridgeJSMakeTypeHandle() +} +extension UInt64: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = UInt64.bridgeJSMakeTypeHandle() +} + extension JSObject: _BridgedSwiftStackType { // JSObject is a non-final class, so we must explicitly specify the associated type // rather than relying on the default `Self` (which Swift requires for covariant returns). @@ -914,6 +996,42 @@ extension JSValue: _BridgedSwiftStackType { } } +extension JSValue: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = JSValue.bridgeJSMakeTypeHandle() +} + +// Keep this order in sync with BridgeType.genericBridgeablePrimitives. +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_core_register_type_handles") +private func _bjs_core_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_core_register_type_handles") +public func _bjs_core_register_type_handles() { + // BEGIN bjs_core_type_handles + let typeIds: [Int32] = [ + Bool.bridgeJSTypeID, + Int.bridgeJSTypeID, + Int8.bridgeJSTypeID, + UInt8.bridgeJSTypeID, + Int16.bridgeJSTypeID, + UInt16.bridgeJSTypeID, + Int32.bridgeJSTypeID, + UInt32.bridgeJSTypeID, + UInt.bridgeJSTypeID, + Int64.bridgeJSTypeID, + UInt64.bridgeJSTypeID, + Float.bridgeJSTypeID, + Double.bridgeJSTypeID, + String.bridgeJSTypeID, + JSValue.bridgeJSTypeID, + ] + // END bjs_core_type_handles + typeIds.withUnsafeBufferPointer { buffer in + _bjs_core_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif + /// A protocol that Swift heap objects exposed to JavaScript via `@JS class` must conform to. /// /// The conformance is automatically synthesized by the BridgeJS code generator. @@ -1945,14 +2063,8 @@ extension _BridgedAsOptional where Wrapped: _BridgedSwiftStackType, Wrapped.Stac extension _BridgedAsOptional where Wrapped: _BridgedSwiftStackType, Wrapped.StackLiftResult == Wrapped, Wrapped: _BridgedSwiftTypeLoweredIntoVoidType { - @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { - switch asOptional { - case .none: - return 0 - case .some(let array): - array.bridgeJSLowerReturn() - return 1 - } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() { + Wrapped.bridgeJSStackPushAsOptional(asOptional) } @_spi(BridgeJS) public consuming func bridgeJSLowerReturn() -> Void { @@ -2369,24 +2481,6 @@ extension _BridgedAsOptional where Wrapped: _BridgedSwiftAssociatedValueEnum { } } -extension _BridgedAsOptional where Wrapped: _BridgedSwiftStruct { - @_spi(BridgeJS) public static func bridgeJSLiftParameter(_ isSome: Int32) -> Self { - if isSome == 0 { - return Self(optional: nil) - } else { - return Self(optional: Wrapped.bridgeJSStackPop()) - } - } - - @_spi(BridgeJS) public consuming func bridgeJSLowerReturn() -> Void { - Wrapped.bridgeJSStackPushAsOptional(asOptional) - } - - @_spi(BridgeJS) public static func bridgeJSLiftParameter() -> Self { - Self.bridgeJSStackPop() - } -} - // MARK: - Array Support extension Array: _BridgedSwiftTypeLoweredIntoVoidType @@ -2462,41 +2556,6 @@ where Key == String, Value: _BridgedSwiftStackType, Value.StackLiftResult == Val } } -extension _BridgedAsOptional { - @_spi(BridgeJS) public consuming func bridgeJSLowerParameter() -> Int32 - where Wrapped == Dictionary, Value: _BridgedSwiftStackType, Value.StackLiftResult == Value { - switch asOptional { - case .none: - return 0 - case .some(let dict): - dict.bridgeJSStackPush() - return 1 - } - } - - @_spi(BridgeJS) public static func bridgeJSLiftParameter(_ isSome: Int32) -> Self - where Wrapped == Dictionary, Value: _BridgedSwiftStackType, Value.StackLiftResult == Value { - if isSome == 0 { - return Self(optional: nil) - } - return Self(optional: Dictionary.bridgeJSStackPop()) - } - - @_spi(BridgeJS) public static func bridgeJSLiftReturn() -> Self - where Wrapped == Dictionary, Value: _BridgedSwiftStackType, Value.StackLiftResult == Value { - let isSome = _swift_js_pop_i32() - if isSome == 0 { - return Self(optional: nil) - } - return Self(optional: Dictionary.bridgeJSStackPop()) - } - - @_spi(BridgeJS) public consuming func bridgeJSLowerReturn() -> Void - where Wrapped == Dictionary, Value: _BridgedSwiftStackType, Value.StackLiftResult == Value { - Wrapped.bridgeJSStackPushAsOptional(asOptional) - } -} - // MARK: Async Promise Awaiting /// Protocol for type-erasing `JSTypedClosure` in `_bjs_awaitPromise`. diff --git a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Exporting-Swift/Exporting-Swift-Function.md b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Exporting-Swift/Exporting-Swift-Function.md index c26841041..098a931af 100644 --- a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Exporting-Swift/Exporting-Swift-Function.md +++ b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Exporting-Swift/Exporting-Swift-Function.md @@ -37,6 +37,27 @@ export type Exports = { } ``` +### Renaming functions in JavaScript + +If a different name is more appropriate in JavaScript or to export multiple overloaded Swift functions with distinct JavaScript names, you can pass a JavaScript identifier as the first argument to `@JS`. + +```swift +import JavaScriptKit + +@JS("greetName") public func greet(_ name: String) -> String { + return "Hello, \(name)!" +} + +@JS("greetPerson") public func greet(_ person: Person) -> String { + return "Hello, \(person.name)!" +} +``` + +```javascript +exports.greetName("World"); +exports.greetPerson({ name: "World" }); +``` + ### Throwing functions Swift functions can throw JavaScript errors using `throws(JSException)`. diff --git a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Generating-from-TypeScript.md b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Generating-from-TypeScript.md index 9c0a80dc1..5a47746d6 100644 --- a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Generating-from-TypeScript.md +++ b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Generating-from-TypeScript.md @@ -416,4 +416,4 @@ When a TypeScript name is not a valid Swift identifier (e.g. contains dashes, sp ## Limitations - No first-class support for async/Promise-returning functions;. -- No generic type parameter can appear on a bridged function signature. \ No newline at end of file +- No generic type parameter can appear on a bridged function signature generated from TypeScript; a type parameter is lowered to `JSObject`. Generic imports are available only through `@JSFunction` declarations written in Swift — see . \ No newline at end of file diff --git a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Importing-JavaScript/Importing-JS-Function.md b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Importing-JavaScript/Importing-JS-Function.md index 1b2be6cb0..ebc9ac857 100644 --- a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Importing-JavaScript/Importing-JS-Function.md +++ b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Importing-JavaScript/Importing-JS-Function.md @@ -77,11 +77,23 @@ If you used `from: .global` or `.module`, do not pass the function in `getImport Bound functions are `throws(JSException)`. Call them with `try` or `try?`; they throw when the JavaScript implementation throws. +## Generic functions + +A `@JSFunction` can be generic over a type parameter constrained to `BridgedSwiftGenericBridgeable`, so one declaration serves every bridged type: + +```swift +@JSFunction func parse(_ json: String) throws(JSException) -> T + +let user: User = try parse(jsonString) // T inferred from the call site +``` + +`T` can be any supported primitive, `String`, `JSValue`, or a `@JS` struct, `@JS` enum, or `final @JS class` (see ), used bare or wrapped as `[T]`, `T?`, or `[String: T]`. A function may declare multiple type parameters, and a return-only generic (`func make() -> T`) works too. Generic initializers, methods, and static methods on `@JSClass` types are supported the same way. `async` generic functions and `where` clauses are not supported. + ## Supported features | Feature | Status | |:--|:--| | Primitive parameter/result types (e.g. `Double`, `Bool`) | ✅ | | `String` parameter/result type | ✅ | +| Generic parameter/result types (constrained to `BridgedSwiftGenericBridgeable`) | ✅ | | Async function | ❌ | -| Generics | ❌ | diff --git a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Supported-Types.md b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Supported-Types.md index 5c609ab72..539f7ce15 100644 --- a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Supported-Types.md +++ b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Supported-Types.md @@ -31,6 +31,10 @@ When using `JSTypedArray` (or convenience typealiases) in `@JS` signatures, t See for usage details. +## Generic type parameters + +An imported `@JSFunction` can be generic over a type parameter constrained to `BridgedSwiftGenericBridgeable` (see ); exported `@JS` functions cannot yet. The constraint is satisfied by all supported primitives, `String`, `JSValue`, and any `@JS` struct, `@JS` enum, or `final @JS class`, including ones from another linked module. Do not write the conformance by hand; marking the type `@JS` is what provides it, together with the JavaScript side of the bridge. + ## See Also - diff --git a/Sources/JavaScriptKit/Macros.swift b/Sources/JavaScriptKit/Macros.swift index 2750f8268..a1cdc0c44 100644 --- a/Sources/JavaScriptKit/Macros.swift +++ b/Sources/JavaScriptKit/Macros.swift @@ -140,6 +140,7 @@ public enum JSName: ExpressibleByStringLiteral { /// /// For detailed usage information, see the article . /// +/// - Parameter name: A different name to use in the exported JavaScript. /// - Parameter namespace: A dot-separated string that defines the namespace hierarchy in JavaScript. /// Each segment becomes a nested object in the resulting JavaScript structure. /// - Parameter enumStyle: Controls how enums are emitted to TypeScript for this declaration: @@ -151,6 +152,7 @@ public enum JSName: ExpressibleByStringLiteral { /// - Important: This feature is still experimental. No API stability is guaranteed, and the API may change in future releases. @attached(peer) public macro JS( + _ name: String? = nil, as aliasOf: Any.Type? = nil, namespace: String? = nil, enumStyle: JSEnumStyle = .const, diff --git a/Tests/BridgeJSGlobalTests/Generated/BridgeJS.swift b/Tests/BridgeJSGlobalTests/Generated/BridgeJS.swift index 4e35a1c9f..91638a428 100644 --- a/Tests/BridgeJSGlobalTests/Generated/BridgeJS.swift +++ b/Tests/BridgeJSGlobalTests/Generated/BridgeJS.swift @@ -353,4 +353,38 @@ fileprivate func _bjs_GlobalUtils_PublicConverter_wrap_extern(_ pointer: UnsafeM #endif @inline(never) fileprivate func _bjs_GlobalUtils_PublicConverter_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_GlobalUtils_PublicConverter_wrap_extern(pointer) -} \ No newline at end of file +} + +extension GlobalNetworking.API.CallMethod: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GlobalNetworking.API.CallMethod.bridgeJSMakeTypeHandle() +} + +extension GlobalConfiguration.PublicLogLevel: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GlobalConfiguration.PublicLogLevel.bridgeJSMakeTypeHandle() +} + +extension GlobalConfiguration.AvailablePort: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GlobalConfiguration.AvailablePort.bridgeJSMakeTypeHandle() +} + +extension Internal.SupportedServerMethod: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Internal.SupportedServerMethod.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_BridgeJSGlobalTests_register_type_handles") +fileprivate func _bjs_BridgeJSGlobalTests_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_BridgeJSGlobalTests_register_type_handles") +public func _bjs_BridgeJSGlobalTests_register_type_handles() { + let typeIds: [Int32] = [ + GlobalNetworking.API.CallMethod.bridgeJSTypeID, + GlobalConfiguration.PublicLogLevel.bridgeJSTypeID, + GlobalConfiguration.AvailablePort.bridgeJSTypeID, + Internal.SupportedServerMethod.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_BridgeJSGlobalTests_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Tests/BridgeJSRuntimeTests/CrossFileNestedTypeClassAPIs.swift b/Tests/BridgeJSRuntimeTests/CrossFileNestedTypeClassAPIs.swift new file mode 100644 index 000000000..8663f1fe5 --- /dev/null +++ b/Tests/BridgeJSRuntimeTests/CrossFileNestedTypeClassAPIs.swift @@ -0,0 +1,13 @@ +import JavaScriptKit + +@JS class Workspace { + let name: String + + @JS init(name: String) { + self.name = name + } + + @JS func describe() -> String { + name + } +} diff --git a/Tests/BridgeJSRuntimeTests/CrossFileNestedTypeExtensionAPIs.swift b/Tests/BridgeJSRuntimeTests/CrossFileNestedTypeExtensionAPIs.swift new file mode 100644 index 000000000..c50446ee2 --- /dev/null +++ b/Tests/BridgeJSRuntimeTests/CrossFileNestedTypeExtensionAPIs.swift @@ -0,0 +1,8 @@ +import JavaScriptKit + +extension Workspace { + @JS enum Kind: String { + case personal + case shared + } +} diff --git a/Tests/BridgeJSRuntimeTests/ExtensionNestedTypesAPIs.swift b/Tests/BridgeJSRuntimeTests/ExtensionNestedTypesAPIs.swift new file mode 100644 index 000000000..b09807ac7 --- /dev/null +++ b/Tests/BridgeJSRuntimeTests/ExtensionNestedTypesAPIs.swift @@ -0,0 +1,70 @@ +import JavaScriptKit + +@JS class Library { + @JS var name: String + + @JS init(name: String) { + self.name = name + } + + @JS func describe() -> String { + name + } +} + +extension Library { + typealias Title = String + + @JS enum Genre: String { + case fiction + case reference + } + + @JS struct Shelf { + var label: String + + @JS init(label: String) { + self.label = label + } + + @JS static var capacity: Int { 32 } + } + + @JS func rename(_ title: Title) -> Title { + title + } + + @JS func shelf(label: String) -> Shelf { + Shelf(label: label) + } +} + +extension Library.Shelf { + @JS struct Divider { + var slot: Int + + @JS init(slot: Int) { + self.slot = slot + } + } + + @JS func describeShelf() -> String { + "Shelf: " + label + } +} + +@JS enum Message { + case update(Update) + case delete +} + +extension Message { + @JS enum Update { + case flip + case rotate + } +} + +@JS func roundTripMessage(_ message: Message) -> Message { + message +} diff --git a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift index ad6f3fa24..f16bce9f2 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift @@ -4878,6 +4878,9 @@ extension AsyncImportedPayloadResult: _BridgedSwiftAssociatedValueEnum { } } +extension Workspace.Kind: _BridgedSwiftEnumNoPayload, _BridgedSwiftRawValueEnum { +} + @_expose(wasm, "bjs_DefaultArgumentExports_static_testStringDefault") @_cdecl("bjs_DefaultArgumentExports_static_testStringDefault") public func _bjs_DefaultArgumentExports_static_testStringDefault(_ messageBytes: Int32, _ messageLength: Int32) -> Void { @@ -5924,6 +5927,67 @@ public func _bjs_NestedStructGroupB_static_roundtripMetadata() -> Void { extension NestedTypeHost.Variant: _BridgedSwiftEnumNoPayload, _BridgedSwiftRawValueEnum { } +extension Message: _BridgedSwiftAssociatedValueEnum { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPopPayload(_ caseId: Int32) -> Message { + switch caseId { + case 0: + return .update(Message.Update.bridgeJSStackPop()) + case 1: + return .delete + default: + fatalError("Unknown Message case ID: \(caseId)") + } + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPushPayload() -> Int32 { + switch self { + case .update(let param0): + param0.bridgeJSStackPush() + return Int32(0) + case .delete: + return Int32(1) + } + } +} + +extension Library.Genre: _BridgedSwiftEnumNoPayload, _BridgedSwiftRawValueEnum { +} + +extension Message.Update: _BridgedSwiftCaseEnum { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> Message.Update { + return bridgeJSLiftParameter(value) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> Message.Update { + return Message.Update(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSLowerParameter() + } + + @_spi(BridgeJS) @usableFromInline init?(bridgeJSRawValue: Int32) { + switch bridgeJSRawValue { + case 0: + self = .flip + case 1: + self = .rotate + default: + return nil + } + } + + @_spi(BridgeJS) @usableFromInline var bridgeJSRawValue: Int32 { + switch self { + case .flip: + return 0 + case .rotate: + return 1 + } + } +} + extension LightColor: _BridgedSwiftCaseEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { return bridgeJSRawValue @@ -5991,6 +6055,75 @@ extension ImportedPayloadSignal: _BridgedSwiftAssociatedValueEnum { } } +extension GenericRTColor: _BridgedSwiftCaseEnum { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> GenericRTColor { + return bridgeJSLiftParameter(value) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> GenericRTColor { + return GenericRTColor(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSLowerParameter() + } + + @_spi(BridgeJS) @usableFromInline init?(bridgeJSRawValue: Int32) { + switch bridgeJSRawValue { + case 0: + self = .red + case 1: + self = .green + case 2: + self = .blue + default: + return nil + } + } + + @_spi(BridgeJS) @usableFromInline var bridgeJSRawValue: Int32 { + switch self { + case .red: + return 0 + case .green: + return 1 + case .blue: + return 2 + } + } +} + +extension GenericRTMode: _BridgedSwiftEnumNoPayload, _BridgedSwiftRawValueEnum { +} + +extension GenericRTLevel: _BridgedSwiftEnumNoPayload, _BridgedSwiftRawValueEnum { +} + +extension GenericRTOutcome: _BridgedSwiftAssociatedValueEnum { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPopPayload(_ caseId: Int32) -> GenericRTOutcome { + switch caseId { + case 0: + return .ok(code: Int.bridgeJSStackPop()) + case 1: + return .fail(message: String.bridgeJSStackPop()) + default: + fatalError("Unknown GenericRTOutcome case ID: \(caseId)") + } + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPushPayload() -> Int32 { + switch self { + case .ok(let code): + code.bridgeJSStackPush() + return Int32(0) + case .fail(let message): + message.bridgeJSStackPush() + return Int32(1) + } + } +} + @_expose(wasm, "bjs_IntegerTypesSupportExports_static_roundTripInt") @_cdecl("bjs_IntegerTypesSupportExports_static_roundTripInt") public func _bjs_IntegerTypesSupportExports_static_roundTripInt(_ v: Int32) -> Int32 { @@ -6779,6 +6912,238 @@ public func _bjs_NestedTypeHost_Label_static_untitled() -> Void { #endif } +extension Library.Shelf: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> Library.Shelf { + let label = String.bridgeJSStackPop() + return Library.Shelf(label: label) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + self.label.bridgeJSStackPush() + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_Library_Shelf(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_Library_Shelf())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_Library_Shelf") +fileprivate func _bjs_struct_lower_Library_Shelf_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_Library_Shelf_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_Library_Shelf(_ objectId: Int32) -> Void { + return _bjs_struct_lower_Library_Shelf_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_Library_Shelf") +fileprivate func _bjs_struct_lift_Library_Shelf_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_Library_Shelf_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_Library_Shelf() -> Int32 { + return _bjs_struct_lift_Library_Shelf_extern() +} + +@_expose(wasm, "bjs_Library_Shelf_init") +@_cdecl("bjs_Library_Shelf_init") +public func _bjs_Library_Shelf_init(_ labelBytes: Int32, _ labelLength: Int32) -> Void { + #if arch(wasm32) + let ret = Library.Shelf(label: String.bridgeJSLiftParameter(labelBytes, labelLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_Shelf_static_capacity_get") +@_cdecl("bjs_Library_Shelf_static_capacity_get") +public func _bjs_Library_Shelf_static_capacity_get() -> Int32 { + #if arch(wasm32) + let ret = Library.Shelf.capacity + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_Shelf_describeShelf") +@_cdecl("bjs_Library_Shelf_describeShelf") +public func _bjs_Library_Shelf_describeShelf() -> Void { + #if arch(wasm32) + let ret = Library.Shelf.bridgeJSLiftParameter().describeShelf() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension Library.Shelf.Divider: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> Library.Shelf.Divider { + let slot = Int.bridgeJSStackPop() + return Library.Shelf.Divider(slot: slot) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + self.slot.bridgeJSStackPush() + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_Library_Shelf_Divider(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_Library_Shelf_Divider())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_Library_Shelf_Divider") +fileprivate func _bjs_struct_lower_Library_Shelf_Divider_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_Library_Shelf_Divider_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_Library_Shelf_Divider(_ objectId: Int32) -> Void { + return _bjs_struct_lower_Library_Shelf_Divider_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_Library_Shelf_Divider") +fileprivate func _bjs_struct_lift_Library_Shelf_Divider_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_Library_Shelf_Divider_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_Library_Shelf_Divider() -> Int32 { + return _bjs_struct_lift_Library_Shelf_Divider_extern() +} + +@_expose(wasm, "bjs_Library_Shelf_Divider_init") +@_cdecl("bjs_Library_Shelf_Divider_init") +public func _bjs_Library_Shelf_Divider_init(_ slot: Int32) -> Void { + #if arch(wasm32) + let ret = Library.Shelf.Divider(slot: Int.bridgeJSLiftParameter(slot)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension GenericRTPoint: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> GenericRTPoint { + let y = Int.bridgeJSStackPop() + let x = Int.bridgeJSStackPop() + return GenericRTPoint(x: x, y: y) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + self.x.bridgeJSStackPush() + self.y.bridgeJSStackPush() + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_GenericRTPoint(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_GenericRTPoint())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_GenericRTPoint") +fileprivate func _bjs_struct_lower_GenericRTPoint_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_GenericRTPoint_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_GenericRTPoint(_ objectId: Int32) -> Void { + return _bjs_struct_lower_GenericRTPoint_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_GenericRTPoint") +fileprivate func _bjs_struct_lift_GenericRTPoint_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_GenericRTPoint_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_GenericRTPoint() -> Int32 { + return _bjs_struct_lift_GenericRTPoint_extern() +} + +extension GenericRTNamespace.Metadata: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> GenericRTNamespace.Metadata { + let count = Int.bridgeJSStackPop() + let label = String.bridgeJSStackPop() + return GenericRTNamespace.Metadata(label: label, count: count) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + self.label.bridgeJSStackPush() + self.count.bridgeJSStackPush() + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_GenericRTNamespace_Metadata(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_GenericRTNamespace_Metadata())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_GenericRTNamespace_Metadata") +fileprivate func _bjs_struct_lower_GenericRTNamespace_Metadata_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_GenericRTNamespace_Metadata_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_GenericRTNamespace_Metadata(_ objectId: Int32) -> Void { + return _bjs_struct_lower_GenericRTNamespace_Metadata_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_GenericRTNamespace_Metadata") +fileprivate func _bjs_struct_lift_GenericRTNamespace_Metadata_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_GenericRTNamespace_Metadata_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_GenericRTNamespace_Metadata() -> Int32 { + return _bjs_struct_lift_GenericRTNamespace_Metadata_extern() +} + extension Point: _BridgedSwiftStruct { @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> Point { let y = Int.bridgeJSStackPop() @@ -7861,8 +8226,19 @@ public func _bjs_Vector2D_scaled(_ factor: Float64) -> Void { #endif } -extension JSObjectContainer: _BridgedSwiftStruct { - @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> JSObjectContainer { +@_expose(wasm, "bjs_Vector2D_describe") +@_cdecl("bjs_Vector2D_describe") +public func _bjs_Vector2D_describe() -> Void { + #if arch(wasm32) + let ret = Vector2D.bridgeJSLiftParameter().describe() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension JSObjectContainer: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> JSObjectContainer { let optionalObject = Optional.bridgeJSStackPop() let object = JSObject.bridgeJSStackPop() return JSObjectContainer(object: object, optionalObject: optionalObject) @@ -9814,6 +10190,50 @@ public func _bjs_makeAdder(_ base: Int32) -> Int32 { #endif } +@_expose(wasm, "bjs_roundTripMessage") +@_cdecl("bjs_roundTripMessage") +public func _bjs_roundTripMessage(_ message: Int32) -> Void { + #if arch(wasm32) + let ret = roundTripMessage(_: Message.bridgeJSLiftParameter(message)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_renamedEcho") +@_cdecl("bjs_renamedEcho") +public func _bjs_renamedEcho(_ valueBytes: Int32, _ valueLength: Int32) -> Void { + #if arch(wasm32) + let ret = jsNameEcho(_: String.bridgeJSLiftParameter(valueBytes, valueLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_greetName") +@_cdecl("bjs_greetName") +public func _bjs_greetName(_ nameBytes: Int32, _ nameLength: Int32) -> Void { + #if arch(wasm32) + let ret = greet(_: String.bridgeJSLiftParameter(nameBytes, nameLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_greetCount") +@_cdecl("bjs_greetCount") +public func _bjs_greetCount(_ count: Int32) -> Void { + #if arch(wasm32) + let ret = greet(_: Int.bridgeJSLiftParameter(count)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + @_expose(wasm, "bjs_roundTripPointerFields") @_cdecl("bjs_roundTripPointerFields") public func _bjs_roundTripPointerFields() -> Void { @@ -10550,6 +10970,59 @@ fileprivate func _bjs_ClosureSupportExports_wrap_extern(_ pointer: UnsafeMutable return _bjs_ClosureSupportExports_wrap_extern(pointer) } +@_expose(wasm, "bjs_Workspace_init") +@_cdecl("bjs_Workspace_init") +public func _bjs_Workspace_init(_ nameBytes: Int32, _ nameLength: Int32) -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = Workspace(name: String.bridgeJSLiftParameter(nameBytes, nameLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Workspace_describe") +@_cdecl("bjs_Workspace_describe") +public func _bjs_Workspace_describe(_ _self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = Workspace.bridgeJSLiftParameter(_self).describe() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Workspace_deinit") +@_cdecl("bjs_Workspace_deinit") +public func _bjs_Workspace_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension Workspace: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_Workspace_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_Workspace_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_Workspace_wrap") +fileprivate func _bjs_Workspace_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_Workspace_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_Workspace_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_Workspace_wrap_extern(pointer) +} + @_expose(wasm, "bjs_DefaultArgumentConstructorDefaults_init") @_cdecl("bjs_DefaultArgumentConstructorDefaults_init") public func _bjs_DefaultArgumentConstructorDefaults_init(_ nameBytes: Int32, _ nameLength: Int32, _ count: Int32, _ enabled: Int32, _ status: Int32, _ tagIsSome: Int32, _ tagBytes: Int32, _ tagLength: Int32) -> UnsafeMutableRawPointer { @@ -13162,6 +13635,261 @@ fileprivate func _bjs_NestedTypeHost_wrap_extern(_ pointer: UnsafeMutableRawPoin return _bjs_NestedTypeHost_wrap_extern(pointer) } +@_expose(wasm, "bjs_Library_init") +@_cdecl("bjs_Library_init") +public func _bjs_Library_init(_ nameBytes: Int32, _ nameLength: Int32) -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = Library(name: String.bridgeJSLiftParameter(nameBytes, nameLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_describe") +@_cdecl("bjs_Library_describe") +public func _bjs_Library_describe(_ _self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = Library.bridgeJSLiftParameter(_self).describe() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_rename") +@_cdecl("bjs_Library_rename") +public func _bjs_Library_rename(_ _self: UnsafeMutableRawPointer, _ titleBytes: Int32, _ titleLength: Int32) -> Void { + #if arch(wasm32) + let ret = Library.bridgeJSLiftParameter(_self).rename(_: String.bridgeJSLiftParameter(titleBytes, titleLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_shelf") +@_cdecl("bjs_Library_shelf") +public func _bjs_Library_shelf(_ _self: UnsafeMutableRawPointer, _ labelBytes: Int32, _ labelLength: Int32) -> Void { + #if arch(wasm32) + let ret = Library.bridgeJSLiftParameter(_self).shelf(label: String.bridgeJSLiftParameter(labelBytes, labelLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_name_get") +@_cdecl("bjs_Library_name_get") +public func _bjs_Library_name_get(_ _self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = Library.bridgeJSLiftParameter(_self).name + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_name_set") +@_cdecl("bjs_Library_name_set") +public func _bjs_Library_name_set(_ _self: UnsafeMutableRawPointer, _ valueBytes: Int32, _ valueLength: Int32) -> Void { + #if arch(wasm32) + Library.bridgeJSLiftParameter(_self).name = String.bridgeJSLiftParameter(valueBytes, valueLength) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Library_deinit") +@_cdecl("bjs_Library_deinit") +public func _bjs_Library_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension Library: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_Library_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_Library_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_Library_wrap") +fileprivate func _bjs_Library_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_Library_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_Library_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_Library_wrap_extern(pointer) +} + +@_expose(wasm, "bjs_ImportGenericBox_init") +@_cdecl("bjs_ImportGenericBox_init") +public func _bjs_ImportGenericBox_init(_ value: Int32) -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = ImportGenericBox(value: Int.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_ImportGenericBox_get") +@_cdecl("bjs_ImportGenericBox_get") +public func _bjs_ImportGenericBox_get(_ _self: UnsafeMutableRawPointer) -> Int32 { + #if arch(wasm32) + let ret = ImportGenericBox.bridgeJSLiftParameter(_self).get() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_ImportGenericBox_value_get") +@_cdecl("bjs_ImportGenericBox_value_get") +public func _bjs_ImportGenericBox_value_get(_ _self: UnsafeMutableRawPointer) -> Int32 { + #if arch(wasm32) + let ret = ImportGenericBox.bridgeJSLiftParameter(_self).value + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_ImportGenericBox_value_set") +@_cdecl("bjs_ImportGenericBox_value_set") +public func _bjs_ImportGenericBox_value_set(_ _self: UnsafeMutableRawPointer, _ value: Int32) -> Void { + #if arch(wasm32) + ImportGenericBox.bridgeJSLiftParameter(_self).value = Int.bridgeJSLiftParameter(value) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_ImportGenericBox_deinit") +@_cdecl("bjs_ImportGenericBox_deinit") +public func _bjs_ImportGenericBox_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension ImportGenericBox: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_ImportGenericBox_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_ImportGenericBox_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_ImportGenericBox_wrap") +fileprivate func _bjs_ImportGenericBox_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_ImportGenericBox_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_ImportGenericBox_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_ImportGenericBox_wrap_extern(pointer) +} + +@_expose(wasm, "bjs_JSNameRenamedClass_init") +@_cdecl("bjs_JSNameRenamedClass_init") +public func _bjs_JSNameRenamedClass_init(_ value: Int32) -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = JSNameRenamedClass(value: Int.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_JSNameRenamedClass_doubled") +@_cdecl("bjs_JSNameRenamedClass_doubled") +public func _bjs_JSNameRenamedClass_doubled(_ _self: UnsafeMutableRawPointer) -> Int32 { + #if arch(wasm32) + let ret = JSNameRenamedClass.bridgeJSLiftParameter(_self).timesTwo() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_JSNameRenamedClass_static_makeWithValue") +@_cdecl("bjs_JSNameRenamedClass_static_makeWithValue") +public func _bjs_JSNameRenamedClass_static_makeWithValue(_ value: Int32) -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = JSNameRenamedClass.create(value: Int.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_JSNameRenamedClass_value_get") +@_cdecl("bjs_JSNameRenamedClass_value_get") +public func _bjs_JSNameRenamedClass_value_get(_ _self: UnsafeMutableRawPointer) -> Int32 { + #if arch(wasm32) + let ret = JSNameRenamedClass.bridgeJSLiftParameter(_self).value + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_JSNameRenamedClass_value_set") +@_cdecl("bjs_JSNameRenamedClass_value_set") +public func _bjs_JSNameRenamedClass_value_set(_ _self: UnsafeMutableRawPointer, _ value: Int32) -> Void { + #if arch(wasm32) + JSNameRenamedClass.bridgeJSLiftParameter(_self).value = Int.bridgeJSLiftParameter(value) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_JSNameRenamedClass_deinit") +@_cdecl("bjs_JSNameRenamedClass_deinit") +public func _bjs_JSNameRenamedClass_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension JSNameRenamedClass: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_JSNameRenamedClass_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_JSNameRenamedClass_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_JSNameRenamedClass_wrap") +fileprivate func _bjs_JSNameRenamedClass_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_JSNameRenamedClass_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_JSNameRenamedClass_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_JSNameRenamedClass_wrap_extern(pointer) +} + @_expose(wasm, "bjs_OptionalHolder_init") @_cdecl("bjs_OptionalHolder_init") public func _bjs_OptionalHolder_init(_ nullableGreeterIsSome: Int32, _ nullableGreeterValue: UnsafeMutableRawPointer, _ undefinedNumberIsSome: Int32, _ undefinedNumberValue: Float64) -> UnsafeMutableRawPointer { @@ -13425,58 +14153,350 @@ extension Container: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwif } } -#if arch(wasm32) -@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_Container_wrap") -fileprivate func _bjs_Container_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 -#else -fileprivate func _bjs_Container_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { - fatalError("Only available on WebAssembly") +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_Container_wrap") +fileprivate func _bjs_Container_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_Container_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_Container_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_Container_wrap_extern(pointer) +} + +@_expose(wasm, "bjs_LeakCheck_init") +@_cdecl("bjs_LeakCheck_init") +public func _bjs_LeakCheck_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = LeakCheck() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_LeakCheck_deinit") +@_cdecl("bjs_LeakCheck_deinit") +public func _bjs_LeakCheck_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension LeakCheck: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + public var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_LeakCheck_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + public consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_LeakCheck_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_LeakCheck_wrap") +fileprivate func _bjs_LeakCheck_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_LeakCheck_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_LeakCheck_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_LeakCheck_wrap_extern(pointer) +} + +extension JSCoordinate: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = JSCoordinate.bridgeJSMakeTypeHandle() +} + +extension NestedStructGroupA.Metadata: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = NestedStructGroupA.Metadata.bridgeJSMakeTypeHandle() +} + +extension NestedStructGroupB.Metadata: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = NestedStructGroupB.Metadata.bridgeJSMakeTypeHandle() +} + +extension NestedTypeHost.Label: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = NestedTypeHost.Label.bridgeJSMakeTypeHandle() +} + +extension Library.Shelf: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Library.Shelf.bridgeJSMakeTypeHandle() +} + +extension Library.Shelf.Divider: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Library.Shelf.Divider.bridgeJSMakeTypeHandle() +} + +extension GenericRTPoint: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericRTPoint.bridgeJSMakeTypeHandle() +} + +extension GenericRTNamespace.Metadata: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericRTNamespace.Metadata.bridgeJSMakeTypeHandle() +} + +extension Point: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Point.bridgeJSMakeTypeHandle() +} + +extension PointerFields: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PointerFields.bridgeJSMakeTypeHandle() +} + +extension DataPoint: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = DataPoint.bridgeJSMakeTypeHandle() +} + +extension PublicPoint: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PublicPoint.bridgeJSMakeTypeHandle() +} + +extension Address: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Address.bridgeJSMakeTypeHandle() +} + +extension Contact: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Contact.bridgeJSMakeTypeHandle() +} + +extension Config: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Config.bridgeJSMakeTypeHandle() +} + +extension SessionData: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = SessionData.bridgeJSMakeTypeHandle() +} + +extension ValidationReport: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ValidationReport.bridgeJSMakeTypeHandle() +} + +extension AdvancedConfig: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = AdvancedConfig.bridgeJSMakeTypeHandle() +} + +extension MeasurementConfig: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = MeasurementConfig.bridgeJSMakeTypeHandle() +} + +extension MathOperations: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = MathOperations.bridgeJSMakeTypeHandle() +} + +extension CopyableCart: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = CopyableCart.bridgeJSMakeTypeHandle() +} + +extension CopyableCartItem: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = CopyableCartItem.bridgeJSMakeTypeHandle() +} + +extension CopyableNestedCart: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = CopyableNestedCart.bridgeJSMakeTypeHandle() +} + +extension ConfigStruct: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ConfigStruct.bridgeJSMakeTypeHandle() +} + +extension Vector2D: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Vector2D.bridgeJSMakeTypeHandle() +} + +extension JSObjectContainer: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = JSObjectContainer.bridgeJSMakeTypeHandle() +} + +extension FooContainer: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = FooContainer.bridgeJSMakeTypeHandle() +} + +extension ArrayMembers: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ArrayMembers.bridgeJSMakeTypeHandle() +} + +extension PolygonReference: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PolygonReference.bridgeJSMakeTypeHandle() +} + +extension TagReference: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TagReference.bridgeJSMakeTypeHandle() +} + +extension TagHolderReference: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TagHolderReference.bridgeJSMakeTypeHandle() +} + +extension PriorityReference: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PriorityReference.bridgeJSMakeTypeHandle() +} + +extension ImportGenericBox: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ImportGenericBox.bridgeJSMakeTypeHandle() +} + +extension Severity: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Severity.bridgeJSMakeTypeHandle() +} + +extension Shape: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Shape.bridgeJSMakeTypeHandle() +} + +extension InnerTag: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = InnerTag.bridgeJSMakeTypeHandle() +} + +extension AsyncImportedPayloadResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = AsyncImportedPayloadResult.bridgeJSMakeTypeHandle() +} + +extension Workspace.Kind: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Workspace.Kind.bridgeJSMakeTypeHandle() +} + +extension Direction: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Direction.bridgeJSMakeTypeHandle() +} + +extension Status: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Status.bridgeJSMakeTypeHandle() +} + +extension Theme: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Theme.bridgeJSMakeTypeHandle() +} + +extension HttpStatus: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = HttpStatus.bridgeJSMakeTypeHandle() +} + +extension FileSize: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = FileSize.bridgeJSMakeTypeHandle() +} + +extension SessionId: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = SessionId.bridgeJSMakeTypeHandle() +} + +extension Precision: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Precision.bridgeJSMakeTypeHandle() +} + +extension Ratio: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Ratio.bridgeJSMakeTypeHandle() +} + +extension TSDirection: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TSDirection.bridgeJSMakeTypeHandle() +} + +extension TSTheme: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TSTheme.bridgeJSMakeTypeHandle() +} + +extension AsyncPayloadResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = AsyncPayloadResult.bridgeJSMakeTypeHandle() +} + +extension Networking.API.Method: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Networking.API.Method.bridgeJSMakeTypeHandle() +} + +extension Configuration.LogLevel: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Configuration.LogLevel.bridgeJSMakeTypeHandle() +} + +extension Configuration.Port: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Configuration.Port.bridgeJSMakeTypeHandle() +} + +extension Internal.SupportedMethod: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Internal.SupportedMethod.bridgeJSMakeTypeHandle() +} + +extension APIResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = APIResult.bridgeJSMakeTypeHandle() +} + +extension ComplexResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ComplexResult.bridgeJSMakeTypeHandle() +} + +extension Utilities.Result: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Utilities.Result.bridgeJSMakeTypeHandle() +} + +extension API.NetworkingResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = API.NetworkingResult.bridgeJSMakeTypeHandle() +} + +extension AllTypesResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = AllTypesResult.bridgeJSMakeTypeHandle() +} + +extension TypedPayloadResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TypedPayloadResult.bridgeJSMakeTypeHandle() +} + +extension StaticCalculator: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = StaticCalculator.bridgeJSMakeTypeHandle() +} + +extension StaticPropertyEnum: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = StaticPropertyEnum.bridgeJSMakeTypeHandle() +} + +extension NestedTypeHost.Variant: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = NestedTypeHost.Variant.bridgeJSMakeTypeHandle() +} + +extension Message: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Message.bridgeJSMakeTypeHandle() +} + +extension Library.Genre: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Library.Genre.bridgeJSMakeTypeHandle() +} + +extension Message.Update: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Message.Update.bridgeJSMakeTypeHandle() +} + +extension LightColor: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = LightColor.bridgeJSMakeTypeHandle() +} + +extension ImportedPayloadSignal: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ImportedPayloadSignal.bridgeJSMakeTypeHandle() } -#endif -@inline(never) fileprivate func _bjs_Container_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { - return _bjs_Container_wrap_extern(pointer) + +extension GenericRTColor: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericRTColor.bridgeJSMakeTypeHandle() } -@_expose(wasm, "bjs_LeakCheck_init") -@_cdecl("bjs_LeakCheck_init") -public func _bjs_LeakCheck_init() -> UnsafeMutableRawPointer { - #if arch(wasm32) - let ret = LeakCheck() - return ret.bridgeJSLowerReturn() - #else - fatalError("Only available on WebAssembly") - #endif +extension GenericRTMode: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericRTMode.bridgeJSMakeTypeHandle() } -@_expose(wasm, "bjs_LeakCheck_deinit") -@_cdecl("bjs_LeakCheck_deinit") -public func _bjs_LeakCheck_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { - #if arch(wasm32) - Unmanaged.fromOpaque(pointer).release() - #else - fatalError("Only available on WebAssembly") - #endif +extension GenericRTLevel: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericRTLevel.bridgeJSMakeTypeHandle() } -extension LeakCheck: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { - public var jsValue: JSValue { - return .object(JSObject(id: UInt32(bitPattern: _bjs_LeakCheck_wrap(Unmanaged.passRetained(self).toOpaque())))) - } - public consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { - _bjs_LeakCheck_wrap(Unmanaged.passRetained(self).toOpaque()) - } +extension GenericRTOutcome: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericRTOutcome.bridgeJSMakeTypeHandle() } -#if arch(wasm32) -@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_LeakCheck_wrap") -fileprivate func _bjs_LeakCheck_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 -#else -fileprivate func _bjs_LeakCheck_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { - fatalError("Only available on WebAssembly") +extension OptionalAllTypesResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = OptionalAllTypesResult.bridgeJSMakeTypeHandle() } -#endif -@inline(never) fileprivate func _bjs_LeakCheck_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { - return _bjs_LeakCheck_wrap_extern(pointer) + +extension APIOptionalResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = APIOptionalResult.bridgeJSMakeTypeHandle() } @JSFunction func Promise_reject(_ promise: JSObject, _ value: JSValue) throws(JSException) @@ -13989,20 +15009,20 @@ func _$Promise_resolve_Sa11PublicPointV(_ promise: JSObject, _ value: [PublicPoi #if arch(wasm32) @_extern(wasm, module: "bjs", name: "promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV") -fileprivate func promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV_extern(_ promise: Int32, _ value: Int32) -> Void +fileprivate func promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV_extern(_ promise: Int32) -> Void #else -fileprivate func promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV_extern(_ promise: Int32, _ value: Int32) -> Void { +fileprivate func promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV_extern(_ promise: Int32) -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV(_ promise: Int32, _ value: Int32) -> Void { - return promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV_extern(promise, value) +@inline(never) fileprivate func promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV(_ promise: Int32) -> Void { + return promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV_extern(promise) } func _$Promise_resolve_Sq11PublicPointV(_ promise: JSObject, _ value: Optional) throws(JSException) -> Void { - let valueIsSome = value.bridgeJSLowerParameter() + let _ = value.bridgeJSLowerParameter() let promiseValue = promise.bridgeJSLowerParameter() - promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV(promiseValue, valueIsSome) + promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV(promiseValue) if let error = _swift_js_take_exception() { throw error } } @@ -16598,20 +17618,20 @@ func _$jsRoundTripOptionalImportedPayloadSignal(_ value: Optional Int32 +fileprivate func bjs_jsJoinOptionalArrayThenArray_extern() -> Int32 #else -fileprivate func bjs_jsJoinOptionalArrayThenArray_extern(_ a: Int32) -> Int32 { +fileprivate func bjs_jsJoinOptionalArrayThenArray_extern() -> Int32 { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_jsJoinOptionalArrayThenArray(_ a: Int32) -> Int32 { - return bjs_jsJoinOptionalArrayThenArray_extern(a) +@inline(never) fileprivate func bjs_jsJoinOptionalArrayThenArray() -> Int32 { + return bjs_jsJoinOptionalArrayThenArray_extern() } func _$jsJoinOptionalArrayThenArray(_ a: Optional<[Int]>, _ b: [Int]) throws(JSException) -> String { let _ = b.bridgeJSLowerParameter() - let aIsSome = a.bridgeJSLowerParameter() - let ret = bjs_jsJoinOptionalArrayThenArray(aIsSome) + let _ = a.bridgeJSLowerParameter() + let ret = bjs_jsJoinOptionalArrayThenArray() if let error = _swift_js_take_exception() { throw error } @@ -16620,20 +17640,20 @@ func _$jsJoinOptionalArrayThenArray(_ a: Optional<[Int]>, _ b: [Int]) throws(JSE #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsJoinOptionalStructThenArray") -fileprivate func bjs_jsJoinOptionalStructThenArray_extern(_ a: Int32) -> Int32 +fileprivate func bjs_jsJoinOptionalStructThenArray_extern() -> Int32 #else -fileprivate func bjs_jsJoinOptionalStructThenArray_extern(_ a: Int32) -> Int32 { +fileprivate func bjs_jsJoinOptionalStructThenArray_extern() -> Int32 { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_jsJoinOptionalStructThenArray(_ a: Int32) -> Int32 { - return bjs_jsJoinOptionalStructThenArray_extern(a) +@inline(never) fileprivate func bjs_jsJoinOptionalStructThenArray() -> Int32 { + return bjs_jsJoinOptionalStructThenArray_extern() } func _$jsJoinOptionalStructThenArray(_ a: Optional, _ b: [Int]) throws(JSException) -> String { let _ = b.bridgeJSLowerParameter() - let aIsSome = a.bridgeJSLowerParameter() - let ret = bjs_jsJoinOptionalStructThenArray(aIsSome) + let _ = a.bridgeJSLowerParameter() + let ret = bjs_jsJoinOptionalStructThenArray() if let error = _swift_js_take_exception() { throw error } @@ -16664,21 +17684,21 @@ func _$jsJoinEnumThenArray(_ a: ImportedPayloadSignal, _ b: [Int]) throws(JSExce #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsJoinStringThenStackParams") -fileprivate func bjs_jsJoinStringThenStackParams_extern(_ sBytes: Int32, _ sLength: Int32, _ a: Int32) -> Int32 +fileprivate func bjs_jsJoinStringThenStackParams_extern(_ sBytes: Int32, _ sLength: Int32) -> Int32 #else -fileprivate func bjs_jsJoinStringThenStackParams_extern(_ sBytes: Int32, _ sLength: Int32, _ a: Int32) -> Int32 { +fileprivate func bjs_jsJoinStringThenStackParams_extern(_ sBytes: Int32, _ sLength: Int32) -> Int32 { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_jsJoinStringThenStackParams(_ sBytes: Int32, _ sLength: Int32, _ a: Int32) -> Int32 { - return bjs_jsJoinStringThenStackParams_extern(sBytes, sLength, a) +@inline(never) fileprivate func bjs_jsJoinStringThenStackParams(_ sBytes: Int32, _ sLength: Int32) -> Int32 { + return bjs_jsJoinStringThenStackParams_extern(sBytes, sLength) } func _$jsJoinStringThenStackParams(_ s: String, _ a: Optional<[Int]>, _ b: [Int]) throws(JSException) -> String { let ret0 = s.bridgeJSWithLoweredParameter { (sBytes, sLength) in let _ = b.bridgeJSLowerParameter() - let aIsSome = a.bridgeJSLowerParameter() - let ret = bjs_jsJoinStringThenStackParams(sBytes, sLength, aIsSome) + let _ = a.bridgeJSLowerParameter() + let ret = bjs_jsJoinStringThenStackParams(sBytes, sLength) return ret } let ret = ret0 @@ -16688,6 +17708,346 @@ func _$jsJoinStringThenStackParams(_ s: String, _ a: Optional<[Int]>, _ b: [Int] return String.bridgeJSLiftReturn(ret) } +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsGenericRoundTrip") +fileprivate func bjs_jsGenericRoundTrip_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_jsGenericRoundTrip_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsGenericRoundTrip(_ _generic0TypeId: Int32) -> Void { + return bjs_jsGenericRoundTrip_extern(_generic0TypeId) +} + +func _$jsGenericRoundTrip(_ value: T) throws(JSException) -> T { + value.bridgeJSStackPush() + bjs_jsGenericRoundTrip(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsGenericRoundTripClass") +fileprivate func bjs_jsGenericRoundTripClass_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_jsGenericRoundTripClass_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsGenericRoundTripClass(_ _generic0TypeId: Int32) -> Void { + return bjs_jsGenericRoundTripClass_extern(_generic0TypeId) +} + +func _$jsGenericRoundTripClass(_ value: T) throws(JSException) -> T { + value.bridgeJSStackPush() + bjs_jsGenericRoundTripClass(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsGenericParsePoint") +fileprivate func bjs_jsGenericParsePoint_extern(_ jsonBytes: Int32, _ jsonLength: Int32, _ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_jsGenericParsePoint_extern(_ jsonBytes: Int32, _ jsonLength: Int32, _ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsGenericParsePoint(_ jsonBytes: Int32, _ jsonLength: Int32, _ _generic0TypeId: Int32) -> Void { + return bjs_jsGenericParsePoint_extern(jsonBytes, jsonLength, _generic0TypeId) +} + +func _$jsGenericParsePoint(_ json: String) throws(JSException) -> T { + json.bridgeJSWithLoweredParameter { (jsonBytes, jsonLength) in + bjs_jsGenericParsePoint(jsonBytes, jsonLength, T.bridgeJSTypeID) + } + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsImportPickFirst") +fileprivate func bjs_jsImportPickFirst_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_jsImportPickFirst_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsImportPickFirst(_ _generic0TypeId: Int32) -> Void { + return bjs_jsImportPickFirst_extern(_generic0TypeId) +} + +func _$jsImportPickFirst(_ a: T, _ b: T) throws(JSException) -> T { + b.bridgeJSStackPush() + a.bridgeJSStackPush() + bjs_jsImportPickFirst(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsImportMakeInt") +fileprivate func bjs_jsImportMakeInt_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_jsImportMakeInt_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsImportMakeInt(_ _generic0TypeId: Int32) -> Void { + return bjs_jsImportMakeInt_extern(_generic0TypeId) +} + +func _$jsImportMakeInt() throws(JSException) -> T { + bjs_jsImportMakeInt(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsImportCombineSecond") +fileprivate func bjs_jsImportCombineSecond_extern(_ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Void +#else +fileprivate func bjs_jsImportCombineSecond_extern(_ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsImportCombineSecond(_ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Void { + return bjs_jsImportCombineSecond_extern(_generic0TypeId, _generic1TypeId) +} + +func _$jsImportCombineSecond(_ a: T, _ b: U) throws(JSException) -> U { + b.bridgeJSStackPush() + a.bridgeJSStackPush() + bjs_jsImportCombineSecond(T.bridgeJSTypeID, U.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return U.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsGenericArrayRoundTrip") +fileprivate func bjs_jsGenericArrayRoundTrip_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_jsGenericArrayRoundTrip_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsGenericArrayRoundTrip(_ _generic0TypeId: Int32) -> Void { + return bjs_jsGenericArrayRoundTrip_extern(_generic0TypeId) +} + +func _$jsGenericArrayRoundTrip(_ values: [T]) throws(JSException) -> [T] { + let _ = values.bridgeJSLowerParameter() + bjs_jsGenericArrayRoundTrip(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return [T].bridgeJSLiftReturn() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsGenericOptionalRoundTrip") +fileprivate func bjs_jsGenericOptionalRoundTrip_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_jsGenericOptionalRoundTrip_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsGenericOptionalRoundTrip(_ _generic0TypeId: Int32) -> Void { + return bjs_jsGenericOptionalRoundTrip_extern(_generic0TypeId) +} + +func _$jsGenericOptionalRoundTrip(_ value: Optional) throws(JSException) -> Optional { + value.bridgeJSStackPush() + bjs_jsGenericOptionalRoundTrip(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return Optional.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsGenericDictRoundTrip") +fileprivate func bjs_jsGenericDictRoundTrip_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_jsGenericDictRoundTrip_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsGenericDictRoundTrip(_ _generic0TypeId: Int32) -> Void { + return bjs_jsGenericDictRoundTrip_extern(_generic0TypeId) +} + +func _$jsGenericDictRoundTrip(_ values: [String: T]) throws(JSException) -> [String: T] { + let _ = values.bridgeJSLowerParameter() + bjs_jsGenericDictRoundTrip(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return [String: T].bridgeJSLiftReturn() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsGenericAfterOptionalArray") +fileprivate func bjs_jsGenericAfterOptionalArray_extern(_ _generic0TypeId: Int32) -> Int32 +#else +fileprivate func bjs_jsGenericAfterOptionalArray_extern(_ _generic0TypeId: Int32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsGenericAfterOptionalArray(_ _generic0TypeId: Int32) -> Int32 { + return bjs_jsGenericAfterOptionalArray_extern(_generic0TypeId) +} + +func _$jsGenericAfterOptionalArray(_ values: Optional<[Int]>, _ value: T) throws(JSException) -> String { + value.bridgeJSStackPush() + let _ = values.bridgeJSLowerParameter() + let ret = bjs_jsGenericAfterOptionalArray(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return String.bridgeJSLiftReturn(ret) +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsGenericThrowOrRoundTrip") +fileprivate func bjs_jsGenericThrowOrRoundTrip_extern(_ shouldThrow: Int32, _ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_jsGenericThrowOrRoundTrip_extern(_ shouldThrow: Int32, _ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsGenericThrowOrRoundTrip(_ shouldThrow: Int32, _ _generic0TypeId: Int32) -> Void { + return bjs_jsGenericThrowOrRoundTrip_extern(shouldThrow, _generic0TypeId) +} + +func _$jsGenericThrowOrRoundTrip(_ shouldThrow: Bool, _ value: T) throws(JSException) -> T { + value.bridgeJSStackPush() + let shouldThrowValue = shouldThrow.bridgeJSLowerParameter() + bjs_jsGenericThrowOrRoundTrip(shouldThrowValue, T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_ImportGenericConsumer_init") +fileprivate func bjs_ImportGenericConsumer_init_extern() -> Int32 +#else +fileprivate func bjs_ImportGenericConsumer_init_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_ImportGenericConsumer_init() -> Int32 { + return bjs_ImportGenericConsumer_init_extern() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_ImportGenericConsumer_box_static") +fileprivate func bjs_ImportGenericConsumer_box_static_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_ImportGenericConsumer_box_static_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_ImportGenericConsumer_box_static(_ _generic0TypeId: Int32) -> Void { + return bjs_ImportGenericConsumer_box_static_extern(_generic0TypeId) +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_ImportGenericConsumer_identity") +fileprivate func bjs_ImportGenericConsumer_identity_extern(_ self: Int32, _ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_ImportGenericConsumer_identity_extern(_ self: Int32, _ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_ImportGenericConsumer_identity(_ self: Int32, _ _generic0TypeId: Int32) -> Void { + return bjs_ImportGenericConsumer_identity_extern(self, _generic0TypeId) +} + +func _$ImportGenericConsumer_init() throws(JSException) -> JSObject { + let ret = bjs_ImportGenericConsumer_init() + if let error = _swift_js_take_exception() { + throw error + } + return JSObject.bridgeJSLiftReturn(ret) +} + +func _$ImportGenericConsumer_box(_ value: T) throws(JSException) -> T { + value.bridgeJSStackPush() + bjs_ImportGenericConsumer_box_static(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +func _$ImportGenericConsumer_identity(_ self: JSObject, _ value: T) throws(JSException) -> T { + value.bridgeJSStackPush() + let selfValue = self.bridgeJSLowerParameter() + bjs_ImportGenericConsumer_identity(selfValue, T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_ImportGenericBoxed_init") +fileprivate func bjs_ImportGenericBoxed_init_extern(_ _generic0TypeId: Int32) -> Int32 +#else +fileprivate func bjs_ImportGenericBoxed_init_extern(_ _generic0TypeId: Int32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_ImportGenericBoxed_init(_ _generic0TypeId: Int32) -> Int32 { + return bjs_ImportGenericBoxed_init_extern(_generic0TypeId) +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_ImportGenericBoxed_unwrap") +fileprivate func bjs_ImportGenericBoxed_unwrap_extern(_ self: Int32, _ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_ImportGenericBoxed_unwrap_extern(_ self: Int32, _ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_ImportGenericBoxed_unwrap(_ self: Int32, _ _generic0TypeId: Int32) -> Void { + return bjs_ImportGenericBoxed_unwrap_extern(self, _generic0TypeId) +} + +func _$ImportGenericBoxed_init(_ value: T) throws(JSException) -> JSObject { + value.bridgeJSStackPush() + let ret = bjs_ImportGenericBoxed_init(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return JSObject.bridgeJSLiftReturn(ret) +} + +func _$ImportGenericBoxed_unwrap(_ self: JSObject) throws(JSException) -> T { + let selfValue = self.bridgeJSLowerParameter() + bjs_ImportGenericBoxed_unwrap(selfValue, T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsTranslatePoint") fileprivate func bjs_jsTranslatePoint_extern(_ dx: Int32, _ dy: Int32) -> Void @@ -16713,19 +18073,19 @@ func _$jsTranslatePoint(_ point: Point, _ dx: Int, _ dy: Int) throws(JSException #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsRoundTripOptionalPoint") -fileprivate func bjs_jsRoundTripOptionalPoint_extern(_ point: Int32) -> Void +fileprivate func bjs_jsRoundTripOptionalPoint_extern() -> Void #else -fileprivate func bjs_jsRoundTripOptionalPoint_extern(_ point: Int32) -> Void { +fileprivate func bjs_jsRoundTripOptionalPoint_extern() -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_jsRoundTripOptionalPoint(_ point: Int32) -> Void { - return bjs_jsRoundTripOptionalPoint_extern(point) +@inline(never) fileprivate func bjs_jsRoundTripOptionalPoint() -> Void { + return bjs_jsRoundTripOptionalPoint_extern() } func _$jsRoundTripOptionalPoint(_ point: Optional) throws(JSException) -> Optional { - let pointIsSome = point.bridgeJSLowerParameter() - bjs_jsRoundTripOptionalPoint(pointIsSome) + let _ = point.bridgeJSLowerParameter() + bjs_jsRoundTripOptionalPoint() if let error = _swift_js_take_exception() { throw error } @@ -17782,50 +19142,50 @@ fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringUndefined_s #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static") -fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static_extern(_ v: Int32) -> Void +fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static_extern() -> Void #else -fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static_extern(_ v: Int32) -> Void { +fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static_extern() -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static(_ v: Int32) -> Void { - return bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static_extern(v) +@inline(never) fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static() -> Void { + return bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static_extern() } #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static") -fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static_extern(_ v: Int32) -> Void +fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static_extern() -> Void #else -fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static_extern(_ v: Int32) -> Void { +fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static_extern() -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static(_ v: Int32) -> Void { - return bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static_extern(v) +@inline(never) fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static() -> Void { + return bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static_extern() } #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static") -fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static_extern(_ v: Int32) -> Void +fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static_extern() -> Void #else -fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static_extern(_ v: Int32) -> Void { +fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static_extern() -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static(_ v: Int32) -> Void { - return bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static_extern(v) +@inline(never) fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static() -> Void { + return bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static_extern() } #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static") -fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static_extern(_ v: Int32) -> Void +fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static_extern() -> Void #else -fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static_extern(_ v: Int32) -> Void { +fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static_extern() -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static(_ v: Int32) -> Void { - return bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static_extern(v) +@inline(never) fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static() -> Void { + return bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static_extern() } #if arch(wasm32) @@ -17891,8 +19251,8 @@ func _$OptionalSupportImports_jsRoundTripOptionalStringUndefined(_ name: JSUndef } func _$OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull(_ v: Optional<[JSValue]>) throws(JSException) -> Optional<[JSValue]> { - let vIsSome = v.bridgeJSLowerParameter() - bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static(vIsSome) + let _ = v.bridgeJSLowerParameter() + bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static() if let error = _swift_js_take_exception() { throw error } @@ -17900,8 +19260,8 @@ func _$OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull(_ v: Optional< } func _$OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined(_ v: JSUndefinedOr<[JSValue]>) throws(JSException) -> JSUndefinedOr<[JSValue]> { - let vIsSome = v.bridgeJSLowerParameter() - bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static(vIsSome) + let _ = v.bridgeJSLowerParameter() + bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static() if let error = _swift_js_take_exception() { throw error } @@ -17909,8 +19269,8 @@ func _$OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined(_ v: JSUn } func _$OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull(_ v: Optional<[String: String]>) throws(JSException) -> Optional<[String: String]> { - let vIsSome = v.bridgeJSLowerParameter() - bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static(vIsSome) + let _ = v.bridgeJSLowerParameter() + bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static() if let error = _swift_js_take_exception() { throw error } @@ -17918,8 +19278,8 @@ func _$OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull(_ } func _$OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined(_ v: JSUndefinedOr<[String: String]>) throws(JSException) -> JSUndefinedOr<[String: String]> { - let vIsSome = v.bridgeJSLowerParameter() - bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static(vIsSome) + let _ = v.bridgeJSLowerParameter() + bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static() if let error = _swift_js_take_exception() { throw error } @@ -18062,4 +19422,91 @@ func _$SwiftClassSupportImports_jsConsumeOptionalLeakCheck(_ value: Optional?, _ count: Int32) + +@_expose(wasm, "bjs_BridgeJSRuntimeTests_register_type_handles") +public func _bjs_BridgeJSRuntimeTests_register_type_handles() { + let typeIds: [Int32] = [ + JSCoordinate.bridgeJSTypeID, + NestedStructGroupA.Metadata.bridgeJSTypeID, + NestedStructGroupB.Metadata.bridgeJSTypeID, + NestedTypeHost.Label.bridgeJSTypeID, + Library.Shelf.bridgeJSTypeID, + Library.Shelf.Divider.bridgeJSTypeID, + GenericRTPoint.bridgeJSTypeID, + GenericRTNamespace.Metadata.bridgeJSTypeID, + Point.bridgeJSTypeID, + PointerFields.bridgeJSTypeID, + DataPoint.bridgeJSTypeID, + PublicPoint.bridgeJSTypeID, + Address.bridgeJSTypeID, + Contact.bridgeJSTypeID, + Config.bridgeJSTypeID, + SessionData.bridgeJSTypeID, + ValidationReport.bridgeJSTypeID, + AdvancedConfig.bridgeJSTypeID, + MeasurementConfig.bridgeJSTypeID, + MathOperations.bridgeJSTypeID, + CopyableCart.bridgeJSTypeID, + CopyableCartItem.bridgeJSTypeID, + CopyableNestedCart.bridgeJSTypeID, + ConfigStruct.bridgeJSTypeID, + Vector2D.bridgeJSTypeID, + JSObjectContainer.bridgeJSTypeID, + FooContainer.bridgeJSTypeID, + ArrayMembers.bridgeJSTypeID, + PolygonReference.bridgeJSTypeID, + TagReference.bridgeJSTypeID, + TagHolderReference.bridgeJSTypeID, + PriorityReference.bridgeJSTypeID, + ImportGenericBox.bridgeJSTypeID, + Severity.bridgeJSTypeID, + Shape.bridgeJSTypeID, + InnerTag.bridgeJSTypeID, + AsyncImportedPayloadResult.bridgeJSTypeID, + Workspace.Kind.bridgeJSTypeID, + Direction.bridgeJSTypeID, + Status.bridgeJSTypeID, + Theme.bridgeJSTypeID, + HttpStatus.bridgeJSTypeID, + FileSize.bridgeJSTypeID, + SessionId.bridgeJSTypeID, + Precision.bridgeJSTypeID, + Ratio.bridgeJSTypeID, + TSDirection.bridgeJSTypeID, + TSTheme.bridgeJSTypeID, + AsyncPayloadResult.bridgeJSTypeID, + Networking.API.Method.bridgeJSTypeID, + Configuration.LogLevel.bridgeJSTypeID, + Configuration.Port.bridgeJSTypeID, + Internal.SupportedMethod.bridgeJSTypeID, + APIResult.bridgeJSTypeID, + ComplexResult.bridgeJSTypeID, + Utilities.Result.bridgeJSTypeID, + API.NetworkingResult.bridgeJSTypeID, + AllTypesResult.bridgeJSTypeID, + TypedPayloadResult.bridgeJSTypeID, + StaticCalculator.bridgeJSTypeID, + StaticPropertyEnum.bridgeJSTypeID, + NestedTypeHost.Variant.bridgeJSTypeID, + Message.bridgeJSTypeID, + Library.Genre.bridgeJSTypeID, + Message.Update.bridgeJSTypeID, + LightColor.bridgeJSTypeID, + ImportedPayloadSignal.bridgeJSTypeID, + GenericRTColor.bridgeJSTypeID, + GenericRTMode.bridgeJSTypeID, + GenericRTLevel.bridgeJSTypeID, + GenericRTOutcome.bridgeJSTypeID, + OptionalAllTypesResult.bridgeJSTypeID, + APIOptionalResult.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_BridgeJSRuntimeTests_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json index e2a8575e1..c1a3e26cc 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json +++ b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json @@ -127,6 +127,7 @@ } ] }, + "isFinal" : true, "methods" : [ { "abiName" : "bjs_PolygonReference_vertexCount", @@ -265,6 +266,7 @@ "swiftCallName" : "PolygonReference" }, { + "isFinal" : true, "methods" : [ { "abiName" : "bjs_TagReference_describe", @@ -327,6 +329,7 @@ } ] }, + "isFinal" : true, "methods" : [ { "abiName" : "bjs_TagHolderReference_describe", @@ -380,6 +383,7 @@ "swiftCallName" : "TagHolderReference" }, { + "isFinal" : true, "methods" : [ { "abiName" : "bjs_PriorityReference_describe", @@ -827,6 +831,51 @@ ], "swiftCallName" : "ClosureSupportExports" }, + { + "constructor" : { + "abiName" : "bjs_Workspace_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "name", + "name" : "name", + "type" : { + "string" : { + + } + } + } + ] + }, + "methods" : [ + { + "abiName" : "bjs_Workspace_describe", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "describe", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + } + ], + "name" : "Workspace", + "properties" : [ + + ], + "swiftCallName" : "Workspace" + }, { "constructor" : { "abiName" : "bjs_DefaultArgumentConstructorDefaults_init", @@ -4842,7 +4891,7 @@ }, { "constructor" : { - "abiName" : "bjs_OptionalHolder_init", + "abiName" : "bjs_Library_init", "effects" : { "isAsync" : false, "isStatic" : false, @@ -4850,76 +4899,103 @@ }, "parameters" : [ { - "label" : "nullableGreeter", - "name" : "nullableGreeter", - "type" : { - "nullable" : { - "_0" : { - "swiftHeapObject" : { - "_0" : "Greeter" - } - }, - "_1" : "null" - } - } - }, - { - "label" : "undefinedNumber", - "name" : "undefinedNumber", + "label" : "name", + "name" : "name", "type" : { - "nullable" : { - "_0" : { - "double" : { + "string" : { - } - }, - "_1" : "undefined" } } } ] }, "methods" : [ + { + "abiName" : "bjs_Library_describe", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "describe", + "parameters" : [ - ], - "name" : "OptionalHolder", - "properties" : [ + ], + "returnType" : { + "string" : { + + } + } + }, { - "isReadonly" : false, - "isStatic" : false, - "name" : "nullableGreeter", - "type" : { - "nullable" : { - "_0" : { - "swiftHeapObject" : { - "_0" : "Greeter" + "abiName" : "bjs_Library_rename", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "rename", + "parameters" : [ + { + "label" : "_", + "name" : "title", + "type" : { + "string" : { + } - }, - "_1" : "null" + } + } + ], + "returnType" : { + "string" : { + } } }, + { + "abiName" : "bjs_Library_shelf", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "shelf", + "parameters" : [ + { + "label" : "label", + "name" : "label", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "swiftStruct" : { + "_0" : "Library.Shelf" + } + } + } + ], + "name" : "Library", + "properties" : [ { "isReadonly" : false, "isStatic" : false, - "name" : "undefinedNumber", + "name" : "name", "type" : { - "nullable" : { - "_0" : { - "double" : { + "string" : { - } - }, - "_1" : "undefined" } } } ], - "swiftCallName" : "OptionalHolder" + "swiftCallName" : "Library" }, { "constructor" : { - "abiName" : "bjs_OptionalPropertyHolder_init", + "abiName" : "bjs_ImportGenericBox_init", "effects" : { "isAsync" : false, "isStatic" : false, @@ -4927,80 +5003,63 @@ }, "parameters" : [ { - "label" : "optionalName", - "name" : "optionalName", + "label" : "value", + "name" : "value", "type" : { - "nullable" : { + "integer" : { "_0" : { - "string" : { - - } - }, - "_1" : "null" + "isSigned" : true, + "width" : "word" + } } } } ] }, + "isFinal" : true, "methods" : [ - - ], - "name" : "OptionalPropertyHolder", - "properties" : [ { - "isReadonly" : false, - "isStatic" : false, - "name" : "optionalName", - "type" : { - "nullable" : { - "_0" : { - "string" : { + "abiName" : "bjs_ImportGenericBox_get", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "get", + "parameters" : [ - } - }, - "_1" : "null" - } - } - }, - { - "isReadonly" : false, - "isStatic" : false, - "name" : "optionalAge", - "type" : { - "nullable" : { + ], + "returnType" : { + "integer" : { "_0" : { - "integer" : { - "_0" : { - "isSigned" : true, - "width" : "word" - } - } - }, - "_1" : "null" + "isSigned" : true, + "width" : "word" + } } } - }, + } + ], + "name" : "ImportGenericBox", + "properties" : [ { "isReadonly" : false, "isStatic" : false, - "name" : "optionalGreeter", + "name" : "value", "type" : { - "nullable" : { + "integer" : { "_0" : { - "swiftHeapObject" : { - "_0" : "Greeter" - } - }, - "_1" : "null" + "isSigned" : true, + "width" : "word" + } } } } ], - "swiftCallName" : "OptionalPropertyHolder" + "swiftCallName" : "ImportGenericBox" }, { "constructor" : { - "abiName" : "bjs_Container_init", + "abiName" : "bjs_JSNameRenamedClass_init", "effects" : { "isAsync" : false, "isStatic" : false, @@ -5008,187 +5067,444 @@ }, "parameters" : [ { - "label" : "location", - "name" : "location", - "type" : { - "swiftStruct" : { - "_0" : "DataPoint" - } - } - }, - { - "label" : "config", - "name" : "config", + "label" : "value", + "name" : "value", "type" : { - "nullable" : { + "integer" : { "_0" : { - "swiftStruct" : { - "_0" : "Config" - } - }, - "_1" : "null" + "isSigned" : true, + "width" : "word" + } } } } ] }, "methods" : [ - - ], - "name" : "Container", - "properties" : [ { - "isReadonly" : false, - "isStatic" : false, - "name" : "location", - "type" : { - "swiftStruct" : { - "_0" : "DataPoint" + "abiName" : "bjs_JSNameRenamedClass_doubled", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "jsName" : "doubled", + "name" : "timesTwo", + "parameters" : [ + + ], + "returnType" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } } } }, + { + "abiName" : "bjs_JSNameRenamedClass_static_makeWithValue", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "jsName" : "makeWithValue", + "name" : "create", + "parameters" : [ + { + "label" : "value", + "name" : "value", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "returnType" : { + "swiftHeapObject" : { + "_0" : "JSNameRenamedClass" + } + }, + "staticContext" : { + "className" : { + "_0" : "JSNameRenamedClass" + } + } + } + ], + "name" : "JSNameRenamedClass", + "properties" : [ { "isReadonly" : false, "isStatic" : false, - "name" : "config", + "jsName" : "current", + "name" : "value", "type" : { - "nullable" : { + "integer" : { "_0" : { - "swiftStruct" : { - "_0" : "Config" - } - }, - "_1" : "null" + "isSigned" : true, + "width" : "word" + } } } } ], - "swiftCallName" : "Container" + "swiftCallName" : "JSNameRenamedClass" }, { "constructor" : { - "abiName" : "bjs_LeakCheck_init", + "abiName" : "bjs_OptionalHolder_init", "effects" : { "isAsync" : false, "isStatic" : false, "isThrows" : false }, "parameters" : [ + { + "label" : "nullableGreeter", + "name" : "nullableGreeter", + "type" : { + "nullable" : { + "_0" : { + "swiftHeapObject" : { + "_0" : "Greeter" + } + }, + "_1" : "null" + } + } + }, + { + "label" : "undefinedNumber", + "name" : "undefinedNumber", + "type" : { + "nullable" : { + "_0" : { + "double" : { + } + }, + "_1" : "undefined" + } + } + } ] }, - "explicitAccessControl" : "public", "methods" : [ ], - "name" : "LeakCheck", + "name" : "OptionalHolder", "properties" : [ - - ], - "swiftCallName" : "LeakCheck" - } - ], - "enums" : [ - { - "cases" : [ - { - "associatedValues" : [ - - ], - "name" : "notice" - }, { - "associatedValues" : [ - - ], - "name" : "warning" + "isReadonly" : false, + "isStatic" : false, + "name" : "nullableGreeter", + "type" : { + "nullable" : { + "_0" : { + "swiftHeapObject" : { + "_0" : "Greeter" + } + }, + "_1" : "null" + } + } }, { - "associatedValues" : [ + "isReadonly" : false, + "isStatic" : false, + "name" : "undefinedNumber", + "type" : { + "nullable" : { + "_0" : { + "double" : { - ], - "name" : "error" + } + }, + "_1" : "undefined" + } + } } ], - "emitStyle" : "const", - "name" : "Severity", - "staticMethods" : [ - - ], - "staticProperties" : [ - - ], - "swiftCallName" : "Severity", - "tsFullPath" : "Severity" + "swiftCallName" : "OptionalHolder" }, { - "cases" : [ - { - "associatedValues" : [ - { - "type" : { - "alias" : { - "name" : "Polygon", - "underlying" : { - "swiftHeapObject" : { - "_0" : "PolygonReference" - } + "constructor" : { + "abiName" : "bjs_OptionalPropertyHolder_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "optionalName", + "name" : "optionalName", + "type" : { + "nullable" : { + "_0" : { + "string" : { + } - } + }, + "_1" : "null" } } - ], - "name" : "polygon" - }, - { - "associatedValues" : [ - - ], - "name" : "empty" - } - ], - "emitStyle" : "const", - "name" : "Shape", - "staticMethods" : [ + } + ] + }, + "methods" : [ ], - "staticProperties" : [ + "name" : "OptionalPropertyHolder", + "properties" : [ + { + "isReadonly" : false, + "isStatic" : false, + "name" : "optionalName", + "type" : { + "nullable" : { + "_0" : { + "string" : { - ], - "swiftCallName" : "Shape", - "tsFullPath" : "Shape" - }, - { - "cases" : [ + } + }, + "_1" : "null" + } + } + }, { - "associatedValues" : [ - { - "type" : { + "isReadonly" : false, + "isStatic" : false, + "name" : "optionalAge", + "type" : { + "nullable" : { + "_0" : { "integer" : { "_0" : { "isSigned" : true, "width" : "word" } } - } + }, + "_1" : "null" } - ], - "name" : "payload" + } }, { - "associatedValues" : [ - - ], - "name" : "empty" + "isReadonly" : false, + "isStatic" : false, + "name" : "optionalGreeter", + "type" : { + "nullable" : { + "_0" : { + "swiftHeapObject" : { + "_0" : "Greeter" + } + }, + "_1" : "null" + } + } } ], - "emitStyle" : "const", - "name" : "InnerTag", - "staticMethods" : [ - - ], - "staticProperties" : [ - + "swiftCallName" : "OptionalPropertyHolder" + }, + { + "constructor" : { + "abiName" : "bjs_Container_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "location", + "name" : "location", + "type" : { + "swiftStruct" : { + "_0" : "DataPoint" + } + } + }, + { + "label" : "config", + "name" : "config", + "type" : { + "nullable" : { + "_0" : { + "swiftStruct" : { + "_0" : "Config" + } + }, + "_1" : "null" + } + } + } + ] + }, + "methods" : [ + + ], + "name" : "Container", + "properties" : [ + { + "isReadonly" : false, + "isStatic" : false, + "name" : "location", + "type" : { + "swiftStruct" : { + "_0" : "DataPoint" + } + } + }, + { + "isReadonly" : false, + "isStatic" : false, + "name" : "config", + "type" : { + "nullable" : { + "_0" : { + "swiftStruct" : { + "_0" : "Config" + } + }, + "_1" : "null" + } + } + } + ], + "swiftCallName" : "Container" + }, + { + "constructor" : { + "abiName" : "bjs_LeakCheck_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "explicitAccessControl" : "public", + "methods" : [ + + ], + "name" : "LeakCheck", + "properties" : [ + + ], + "swiftCallName" : "LeakCheck" + } + ], + "enums" : [ + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "notice" + }, + { + "associatedValues" : [ + + ], + "name" : "warning" + }, + { + "associatedValues" : [ + + ], + "name" : "error" + } + ], + "emitStyle" : "const", + "name" : "Severity", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Severity", + "tsFullPath" : "Severity" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "alias" : { + "name" : "Polygon", + "underlying" : { + "swiftHeapObject" : { + "_0" : "PolygonReference" + } + } + } + } + } + ], + "name" : "polygon" + }, + { + "associatedValues" : [ + + ], + "name" : "empty" + } + ], + "emitStyle" : "const", + "name" : "Shape", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Shape", + "tsFullPath" : "Shape" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "name" : "payload" + }, + { + "associatedValues" : [ + + ], + "name" : "empty" + } + ], + "emitStyle" : "const", + "name" : "InnerTag", + "staticMethods" : [ + + ], + "staticProperties" : [ + ], "swiftCallName" : "InnerTag", "tsFullPath" : "InnerTag" @@ -7341,6 +7657,36 @@ "swiftCallName" : "AsyncImportedPayloadResult", "tsFullPath" : "AsyncImportedPayloadResult" }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "personal" + }, + { + "associatedValues" : [ + + ], + "name" : "shared" + } + ], + "emitStyle" : "const", + "name" : "Kind", + "namespace" : [ + "Workspace" + ], + "rawType" : "String", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Workspace.Kind", + "tsFullPath" : "Workspace.Kind" + }, { "cases" : [ @@ -10166,45 +10512,133 @@ "cases" : [ { "associatedValues" : [ - + { + "type" : { + "caseEnum" : { + "_0" : "Message.Update" + } + } + } ], - "name" : "red" + "name" : "update" }, { "associatedValues" : [ ], - "name" : "yellow" + "name" : "delete" + } + ], + "emitStyle" : "const", + "name" : "Message", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Message", + "tsFullPath" : "Message" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "fiction" }, { "associatedValues" : [ ], - "name" : "green" + "name" : "reference" } ], "emitStyle" : "const", - "name" : "LightColor", + "name" : "Genre", + "namespace" : [ + "Library" + ], + "rawType" : "String", "staticMethods" : [ ], "staticProperties" : [ ], - "swiftCallName" : "LightColor", - "tsFullPath" : "LightColor" + "swiftCallName" : "Library.Genre", + "tsFullPath" : "Library.Genre" }, { "cases" : [ { "associatedValues" : [ - { - "type" : { - "string" : { - } - } - } + ], + "name" : "flip" + }, + { + "associatedValues" : [ + + ], + "name" : "rotate" + } + ], + "emitStyle" : "const", + "name" : "Update", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Message.Update", + "tsFullPath" : "Update" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "red" + }, + { + "associatedValues" : [ + + ], + "name" : "yellow" + }, + { + "associatedValues" : [ + + ], + "name" : "green" + } + ], + "emitStyle" : "const", + "name" : "LightColor", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "LightColor", + "tsFullPath" : "LightColor" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } ], "name" : "start" }, @@ -10244,6 +10678,152 @@ { "cases" : [ + ], + "emitStyle" : "const", + "name" : "GenericRTNamespace", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GenericRTNamespace", + "tsFullPath" : "GenericRTNamespace" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "red" + }, + { + "associatedValues" : [ + + ], + "name" : "green" + }, + { + "associatedValues" : [ + + ], + "name" : "blue" + } + ], + "emitStyle" : "const", + "name" : "GenericRTColor", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GenericRTColor", + "tsFullPath" : "GenericRTColor" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "light" + }, + { + "associatedValues" : [ + + ], + "name" : "dark" + } + ], + "emitStyle" : "const", + "name" : "GenericRTMode", + "rawType" : "String", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GenericRTMode", + "tsFullPath" : "GenericRTMode" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "low", + "rawValue" : "1" + }, + { + "associatedValues" : [ + + ], + "name" : "high", + "rawValue" : "9" + } + ], + "emitStyle" : "const", + "name" : "GenericRTLevel", + "rawType" : "Int", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GenericRTLevel", + "tsFullPath" : "GenericRTLevel" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "label" : "code", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "name" : "ok" + }, + { + "associatedValues" : [ + { + "label" : "message", + "type" : { + "string" : { + + } + } + } + ], + "name" : "fail" + } + ], + "emitStyle" : "const", + "name" : "GenericRTOutcome", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GenericRTOutcome", + "tsFullPath" : "GenericRTOutcome" + }, + { + "cases" : [ + ], "emitStyle" : "const", "name" : "IntegerTypesSupportExports", @@ -16833,92 +17413,46 @@ } }, { - "abiName" : "bjs_roundTripPointerFields", + "abiName" : "bjs_roundTripMessage", "effects" : { "isAsync" : false, "isStatic" : false, "isThrows" : false }, - "name" : "roundTripPointerFields", + "name" : "roundTripMessage", "parameters" : [ { "label" : "_", - "name" : "value", + "name" : "message", "type" : { - "swiftStruct" : { - "_0" : "PointerFields" + "associatedValueEnum" : { + "_0" : "Message" } } } ], "returnType" : { - "swiftStruct" : { - "_0" : "PointerFields" + "associatedValueEnum" : { + "_0" : "Message" } } }, { - "abiName" : "bjs_testStructDefault", + "abiName" : "bjs_renamedEcho", "effects" : { "isAsync" : false, "isStatic" : false, "isThrows" : false }, - "name" : "testStructDefault", + "jsName" : "renamedEcho", + "name" : "jsNameEcho", "parameters" : [ { - "defaultValue" : { - "structLiteral" : { - "_0" : "DataPoint", - "_1" : [ - { - "name" : "x", - "value" : { - "float" : { - "_0" : 1 - } - } - }, - { - "name" : "y", - "value" : { - "float" : { - "_0" : 2 - } - } - }, - { - "name" : "label", - "value" : { - "string" : { - "_0" : "default" - } - } - }, - { - "name" : "optCount", - "value" : { - "null" : { - - } - } - }, - { - "name" : "optFlag", - "value" : { - "null" : { - - } - } - } - ] - } - }, - "label" : "point", - "name" : "point", + "label" : "_", + "name" : "value", "type" : { - "swiftStruct" : { - "_0" : "DataPoint" + "string" : { + } } } @@ -16930,21 +17464,173 @@ } }, { - "abiName" : "bjs_cartToJSObject", + "abiName" : "bjs_greetName", "effects" : { "isAsync" : false, "isStatic" : false, "isThrows" : false }, - "name" : "cartToJSObject", + "jsName" : "greetName", + "name" : "greet", "parameters" : [ { "label" : "_", - "name" : "cart", + "name" : "name", "type" : { - "swiftStruct" : { - "_0" : "CopyableCart" - } + "string" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_greetCount", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "jsName" : "greetCount", + "name" : "greet", + "parameters" : [ + { + "label" : "_", + "name" : "count", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_roundTripPointerFields", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "roundTripPointerFields", + "parameters" : [ + { + "label" : "_", + "name" : "value", + "type" : { + "swiftStruct" : { + "_0" : "PointerFields" + } + } + } + ], + "returnType" : { + "swiftStruct" : { + "_0" : "PointerFields" + } + } + }, + { + "abiName" : "bjs_testStructDefault", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "testStructDefault", + "parameters" : [ + { + "defaultValue" : { + "structLiteral" : { + "_0" : "DataPoint", + "_1" : [ + { + "name" : "x", + "value" : { + "float" : { + "_0" : 1 + } + } + }, + { + "name" : "y", + "value" : { + "float" : { + "_0" : 2 + } + } + }, + { + "name" : "label", + "value" : { + "string" : { + "_0" : "default" + } + } + }, + { + "name" : "optCount", + "value" : { + "null" : { + + } + } + }, + { + "name" : "optFlag", + "value" : { + "null" : { + + } + } + } + ] + } + }, + "label" : "point", + "name" : "point", + "type" : { + "swiftStruct" : { + "_0" : "DataPoint" + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_cartToJSObject", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "cartToJSObject", + "parameters" : [ + { + "label" : "_", + "name" : "cart", + "type" : { + "swiftStruct" : { + "_0" : "CopyableCart" + } } } ], @@ -18286,28 +18972,71 @@ "swiftCallName" : "NestedTypeHost.Label" }, { + "constructor" : { + "abiName" : "bjs_Library_Shelf_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "label", + "name" : "label", + "type" : { + "string" : { + + } + } + } + ] + }, "methods" : [ + { + "abiName" : "bjs_Library_Shelf_describeShelf", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "describeShelf", + "parameters" : [ + ], + "returnType" : { + "string" : { + + } + } + } + ], + "name" : "Shelf", + "namespace" : [ + "Library" ], - "name" : "Point", "properties" : [ { "isReadonly" : true, "isStatic" : false, - "name" : "x", + "name" : "label", + "namespace" : [ + "Library" + ], "type" : { - "integer" : { - "_0" : { - "isSigned" : true, - "width" : "word" - } + "string" : { + } } }, { "isReadonly" : true, - "isStatic" : false, - "name" : "y", + "isStatic" : true, + "name" : "capacity", + "staticContext" : { + "structName" : { + "_0" : "Library_Shelf" + } + }, "type" : { "integer" : { "_0" : { @@ -18318,11 +19047,11 @@ } } ], - "swiftCallName" : "Point" + "swiftCallName" : "Library.Shelf" }, { "constructor" : { - "abiName" : "bjs_PointerFields_init", + "abiName" : "bjs_Library_Shelf_Divider_init", "effects" : { "isAsync" : false, "isStatic" : false, @@ -18330,41 +19059,204 @@ }, "parameters" : [ { - "label" : "raw", - "name" : "raw", - "type" : { - "unsafePointer" : { - "_0" : { - "kind" : "unsafeRawPointer" - } - } - } - }, - { - "label" : "mutRaw", - "name" : "mutRaw", + "label" : "slot", + "name" : "slot", "type" : { - "unsafePointer" : { + "integer" : { "_0" : { - "kind" : "unsafeMutableRawPointer" + "isSigned" : true, + "width" : "word" } } } - }, - { - "label" : "opaque", - "name" : "opaque", - "type" : { - "unsafePointer" : { - "_0" : { - "kind" : "opaquePointer" - } + } + ] + }, + "methods" : [ + + ], + "name" : "Divider", + "namespace" : [ + "Library", + "Shelf" + ], + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "slot", + "namespace" : [ + "Library", + "Shelf" + ], + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" } } - }, - { - "label" : "ptr", - "name" : "ptr", + } + } + ], + "swiftCallName" : "Library.Shelf.Divider" + }, + { + "methods" : [ + + ], + "name" : "GenericRTPoint", + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "x", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + }, + { + "isReadonly" : true, + "isStatic" : false, + "name" : "y", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "GenericRTPoint" + }, + { + "methods" : [ + + ], + "name" : "Metadata", + "namespace" : [ + "GenericRTNamespace" + ], + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "label", + "namespace" : [ + "GenericRTNamespace" + ], + "type" : { + "string" : { + + } + } + }, + { + "isReadonly" : true, + "isStatic" : false, + "name" : "count", + "namespace" : [ + "GenericRTNamespace" + ], + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "GenericRTNamespace.Metadata" + }, + { + "methods" : [ + + ], + "name" : "Point", + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "x", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + }, + { + "isReadonly" : true, + "isStatic" : false, + "name" : "y", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "Point" + }, + { + "constructor" : { + "abiName" : "bjs_PointerFields_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "raw", + "name" : "raw", + "type" : { + "unsafePointer" : { + "_0" : { + "kind" : "unsafeRawPointer" + } + } + } + }, + { + "label" : "mutRaw", + "name" : "mutRaw", + "type" : { + "unsafePointer" : { + "_0" : { + "kind" : "unsafeMutableRawPointer" + } + } + } + }, + { + "label" : "opaque", + "name" : "opaque", + "type" : { + "unsafePointer" : { + "_0" : { + "kind" : "opaquePointer" + } + } + } + }, + { + "label" : "ptr", + "name" : "ptr", "type" : { "unsafePointer" : { "_0" : { @@ -19680,6 +20572,23 @@ "_0" : "Vector2D" } } + }, + { + "abiName" : "bjs_Vector2D_describe", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "describe", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } } ], "name" : "Vector2D", @@ -23124,78 +24033,407 @@ } }, { - "accessLevel" : "internal", - "effects" : { - "isAsync" : false, - "isStatic" : false, - "isThrows" : true - }, - "name" : "makeDefault", - "parameters" : [ - - ], - "returnType" : { - "jsObject" : { - "_0" : "StaticBox" + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "name" : "makeDefault", + "parameters" : [ + + ], + "returnType" : { + "jsObject" : { + "_0" : "StaticBox" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "jsName" : "with-dashes", + "name" : "with_dashes", + "parameters" : [ + + ], + "returnType" : { + "jsObject" : { + "_0" : "StaticBox" + } + } + } + ] + }, + { + "accessLevel" : "internal", + "constructor" : { + "accessLevel" : "internal", + "parameters" : [ + { + "name" : "name", + "type" : { + "string" : { + + } + } + }, + { + "name" : "age", + "type" : { + "double" : { + + } + } + }, + { + "name" : "isCat", + "type" : { + "bool" : { + + } + } + } + ] + }, + "from" : "global", + "getters" : [ + { + "accessLevel" : "internal", + "name" : "name", + "type" : { + "string" : { + + } + } + }, + { + "accessLevel" : "internal", + "name" : "age", + "type" : { + "double" : { + + } + } + }, + { + "accessLevel" : "internal", + "name" : "isCat", + "type" : { + "bool" : { + + } + } + } + ], + "methods" : [ + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "name" : "bark", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "name" : "getIsCat", + "parameters" : [ + + ], + "returnType" : { + "bool" : { + + } + } + } + ], + "name" : "Animal", + "setters" : [ + { + "accessLevel" : "internal", + "functionName" : "name_set", + "name" : "name", + "type" : { + "string" : { + + } + } + }, + { + "accessLevel" : "internal", + "functionName" : "age_set", + "name" : "age", + "type" : { + "double" : { + + } + } + }, + { + "accessLevel" : "internal", + "functionName" : "isCat_set", + "name" : "isCat", + "type" : { + "bool" : { + + } + } + } + ], + "staticMethods" : [ + + ] + } + ] + }, + { + "functions" : [ + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "name" : "jsRoundTripLightColor", + "parameters" : [ + { + "name" : "value", + "type" : { + "caseEnum" : { + "_0" : "LightColor" + } + } + } + ], + "returnType" : { + "caseEnum" : { + "_0" : "LightColor" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "name" : "jsRoundTripImportedPayloadSignal", + "parameters" : [ + { + "name" : "value", + "type" : { + "associatedValueEnum" : { + "_0" : "ImportedPayloadSignal" + } + } + } + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "ImportedPayloadSignal" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "name" : "jsRoundTripOptionalImportedPayloadSignal", + "parameters" : [ + { + "name" : "value", + "type" : { + "nullable" : { + "_0" : { + "associatedValueEnum" : { + "_0" : "ImportedPayloadSignal" + } + }, + "_1" : "null" + } + } + } + ], + "returnType" : { + "nullable" : { + "_0" : { + "associatedValueEnum" : { + "_0" : "ImportedPayloadSignal" + } + }, + "_1" : "null" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "name" : "jsJoinOptionalArrayThenArray", + "parameters" : [ + { + "name" : "a", + "type" : { + "nullable" : { + "_0" : { + "array" : { + "_0" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + }, + "_1" : "null" + } + } + }, + { + "name" : "b", + "type" : { + "array" : { + "_0" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "name" : "jsJoinOptionalStructThenArray", + "parameters" : [ + { + "name" : "a", + "type" : { + "nullable" : { + "_0" : { + "swiftStruct" : { + "_0" : "Point" + } + }, + "_1" : "null" + } + } + }, + { + "name" : "b", + "type" : { + "array" : { + "_0" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "name" : "jsJoinEnumThenArray", + "parameters" : [ + { + "name" : "a", + "type" : { + "associatedValueEnum" : { + "_0" : "ImportedPayloadSignal" } } }, { - "accessLevel" : "internal", - "effects" : { - "isAsync" : false, - "isStatic" : false, - "isThrows" : true - }, - "jsName" : "with-dashes", - "name" : "with_dashes", - "parameters" : [ - - ], - "returnType" : { - "jsObject" : { - "_0" : "StaticBox" + "name" : "b", + "type" : { + "array" : { + "_0" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } } } } - ] + ], + "returnType" : { + "string" : { + + } + } }, { "accessLevel" : "internal", - "constructor" : { - "accessLevel" : "internal", - "parameters" : [ - { - "name" : "name", - "type" : { - "string" : { - - } - } - }, - { - "name" : "age", - "type" : { - "double" : { - - } - } - }, - { - "name" : "isCat", - "type" : { - "bool" : { - - } - } - } - ] + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true }, - "from" : "global", - "getters" : [ + "name" : "jsJoinStringThenStackParams", + "parameters" : [ { - "accessLevel" : "internal", - "name" : "name", + "name" : "s", "type" : { "string" : { @@ -23203,101 +24441,190 @@ } }, { - "accessLevel" : "internal", - "name" : "age", + "name" : "a", "type" : { - "double" : { - + "nullable" : { + "_0" : { + "array" : { + "_0" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + }, + "_1" : "null" } } }, { - "accessLevel" : "internal", - "name" : "isCat", + "name" : "b", "type" : { - "bool" : { - + "array" : { + "_0" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } } } } ], - "methods" : [ - { - "accessLevel" : "internal", - "effects" : { - "isAsync" : false, - "isStatic" : false, - "isThrows" : true - }, - "name" : "bark", - "parameters" : [ + "returnType" : { + "string" : { - ], - "returnType" : { - "string" : { + } + } + } + ], + "types" : [ + ] + }, + { + "functions" : [ + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "jsGenericRoundTrip", + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" } } - }, + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "jsGenericRoundTripClass", + "parameters" : [ { - "accessLevel" : "internal", - "effects" : { - "isAsync" : false, - "isStatic" : false, - "isThrows" : true - }, - "name" : "getIsCat", - "parameters" : [ - - ], - "returnType" : { - "bool" : { - + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" } } } ], - "name" : "Animal", - "setters" : [ + "returnType" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "jsGenericParsePoint", + "parameters" : [ { - "accessLevel" : "internal", - "functionName" : "name_set", - "name" : "name", + "name" : "json", "type" : { "string" : { } } - }, + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "jsImportPickFirst", + "parameters" : [ { - "accessLevel" : "internal", - "functionName" : "age_set", - "name" : "age", + "name" : "a", "type" : { - "double" : { - + "generic" : { + "_0" : "T" } } }, { - "accessLevel" : "internal", - "functionName" : "isCat_set", - "name" : "isCat", + "name" : "b", "type" : { - "bool" : { - + "generic" : { + "_0" : "T" } } } ], - "staticMethods" : [ - - ] - } - ] - }, - { - "functions" : [ + "returnType" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "jsImportMakeInt", + "parameters" : [ + + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + }, { "accessLevel" : "internal", "effects" : { @@ -23305,20 +24632,32 @@ "isStatic" : false, "isThrows" : true }, - "name" : "jsRoundTripLightColor", + "genericParameters" : [ + "T", + "U" + ], + "name" : "jsImportCombineSecond", "parameters" : [ { - "name" : "value", + "name" : "a", "type" : { - "caseEnum" : { - "_0" : "LightColor" + "generic" : { + "_0" : "T" + } + } + }, + { + "name" : "b", + "type" : { + "generic" : { + "_0" : "U" } } } ], "returnType" : { - "caseEnum" : { - "_0" : "LightColor" + "generic" : { + "_0" : "U" } } }, @@ -23329,20 +24668,31 @@ "isStatic" : false, "isThrows" : true }, - "name" : "jsRoundTripImportedPayloadSignal", + "genericParameters" : [ + "T" + ], + "name" : "jsGenericArrayRoundTrip", "parameters" : [ { - "name" : "value", + "name" : "values", "type" : { - "associatedValueEnum" : { - "_0" : "ImportedPayloadSignal" + "array" : { + "_0" : { + "generic" : { + "_0" : "T" + } + } } } } ], "returnType" : { - "associatedValueEnum" : { - "_0" : "ImportedPayloadSignal" + "array" : { + "_0" : { + "generic" : { + "_0" : "T" + } + } } } }, @@ -23353,15 +24703,18 @@ "isStatic" : false, "isThrows" : true }, - "name" : "jsRoundTripOptionalImportedPayloadSignal", + "genericParameters" : [ + "T" + ], + "name" : "jsGenericOptionalRoundTrip", "parameters" : [ { "name" : "value", "type" : { "nullable" : { "_0" : { - "associatedValueEnum" : { - "_0" : "ImportedPayloadSignal" + "generic" : { + "_0" : "T" } }, "_1" : "null" @@ -23372,8 +24725,8 @@ "returnType" : { "nullable" : { "_0" : { - "associatedValueEnum" : { - "_0" : "ImportedPayloadSignal" + "generic" : { + "_0" : "T" } }, "_1" : "null" @@ -23387,38 +24740,18 @@ "isStatic" : false, "isThrows" : true }, - "name" : "jsJoinOptionalArrayThenArray", + "genericParameters" : [ + "T" + ], + "name" : "jsGenericDictRoundTrip", "parameters" : [ { - "name" : "a", - "type" : { - "nullable" : { - "_0" : { - "array" : { - "_0" : { - "integer" : { - "_0" : { - "isSigned" : true, - "width" : "word" - } - } - } - } - }, - "_1" : "null" - } - } - }, - { - "name" : "b", + "name" : "values", "type" : { - "array" : { + "dictionary" : { "_0" : { - "integer" : { - "_0" : { - "isSigned" : true, - "width" : "word" - } + "generic" : { + "_0" : "T" } } } @@ -23426,8 +24759,12 @@ } ], "returnType" : { - "string" : { - + "dictionary" : { + "_0" : { + "generic" : { + "_0" : "T" + } + } } } }, @@ -23438,15 +24775,25 @@ "isStatic" : false, "isThrows" : true }, - "name" : "jsJoinOptionalStructThenArray", + "genericParameters" : [ + "T" + ], + "name" : "jsGenericAfterOptionalArray", "parameters" : [ { - "name" : "a", + "name" : "values", "type" : { "nullable" : { "_0" : { - "swiftStruct" : { - "_0" : "Point" + "array" : { + "_0" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } } }, "_1" : "null" @@ -23454,17 +24801,10 @@ } }, { - "name" : "b", + "name" : "value", "type" : { - "array" : { - "_0" : { - "integer" : { - "_0" : { - "isSigned" : true, - "width" : "word" - } - } - } + "generic" : { + "_0" : "T" } } } @@ -23482,100 +24822,161 @@ "isStatic" : false, "isThrows" : true }, - "name" : "jsJoinEnumThenArray", + "genericParameters" : [ + "T" + ], + "name" : "jsGenericThrowOrRoundTrip", "parameters" : [ { - "name" : "a", + "name" : "shouldThrow", "type" : { - "associatedValueEnum" : { - "_0" : "ImportedPayloadSignal" + "bool" : { + } } }, { - "name" : "b", + "name" : "value", "type" : { - "array" : { - "_0" : { - "integer" : { - "_0" : { - "isSigned" : true, - "width" : "word" - } - } - } + "generic" : { + "_0" : "T" } } } ], "returnType" : { - "string" : { - + "generic" : { + "_0" : "T" } } - }, + } + ], + "types" : [ { "accessLevel" : "internal", - "effects" : { - "isAsync" : false, - "isStatic" : false, - "isThrows" : true + "constructor" : { + "accessLevel" : "internal", + "parameters" : [ + + ] }, - "name" : "jsJoinStringThenStackParams", - "parameters" : [ - { - "name" : "s", - "type" : { - "string" : { + "getters" : [ - } - } - }, + ], + "methods" : [ { - "name" : "a", - "type" : { - "nullable" : { - "_0" : { - "array" : { - "_0" : { - "integer" : { - "_0" : { - "isSigned" : true, - "width" : "word" - } - } - } + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "identity", + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" } - }, - "_1" : "null" + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" } } - }, + } + ], + "name" : "ImportGenericConsumer", + "setters" : [ + + ], + "staticMethods" : [ { - "name" : "b", - "type" : { - "array" : { - "_0" : { - "integer" : { - "_0" : { - "isSigned" : true, - "width" : "word" - } + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "box", + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" } } } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } } } + ] + }, + { + "accessLevel" : "internal", + "constructor" : { + "accessLevel" : "internal", + "genericParameters" : [ + "T" + ], + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ] + }, + "getters" : [ + ], - "returnType" : { - "string" : { + "methods" : [ + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "unwrap", + "parameters" : [ + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } } - } - } - ], - "types" : [ + ], + "name" : "ImportGenericBoxed", + "setters" : [ + + ], + "staticMethods" : [ + ] + } ] }, { diff --git a/Tests/BridgeJSRuntimeTests/ImportGenericAPIs.swift b/Tests/BridgeJSRuntimeTests/ImportGenericAPIs.swift new file mode 100644 index 000000000..bfd63839f --- /dev/null +++ b/Tests/BridgeJSRuntimeTests/ImportGenericAPIs.swift @@ -0,0 +1,280 @@ +import Testing +import JavaScriptKit + +@JS struct GenericRTPoint { + var x: Int + var y: Int +} + +@JS enum GenericRTNamespace { + @JS struct Metadata { + var label: String + var count: Int + } +} + +@JS enum GenericRTColor { + case red + case green + case blue +} + +@JS enum GenericRTMode: String { + case light + case dark +} + +@JS enum GenericRTLevel: Int { + case low = 1 + case high = 9 +} + +@JS enum GenericRTOutcome { + case ok(code: Int) + case fail(message: String) +} + +@JS final class ImportGenericBox { + @JS var value: Int + @JS init(value: Int) { + self.value = value + } + @JS func get() -> Int { + value + } +} + +@JSFunction func jsGenericRoundTrip(_ value: T) throws(JSException) -> T +@JSFunction func jsGenericRoundTripClass(_ value: T) throws(JSException) -> T +@JSFunction func jsGenericParsePoint(_ json: String) throws(JSException) -> T +@JSFunction func jsImportPickFirst(_ a: T, _ b: T) throws(JSException) -> T +@JSFunction func jsImportMakeInt() throws(JSException) -> T +@JSFunction func jsImportCombineSecond( + _ a: T, + _ b: U +) throws(JSException) -> U +@JSFunction func jsGenericArrayRoundTrip(_ values: [T]) throws(JSException) -> [T] +@JSFunction func jsGenericOptionalRoundTrip(_ value: T?) throws(JSException) -> T? +@JSFunction func jsGenericDictRoundTrip( + _ values: [String: T] +) throws(JSException) -> [String: T] +@JSFunction func jsGenericAfterOptionalArray( + _ values: [Int]?, + _ value: T +) throws(JSException) -> String + +@JSClass struct ImportGenericConsumer { + @JSFunction init() throws(JSException) + @JSFunction func identity(_ value: T) throws(JSException) -> T + @JSFunction static func box(_ value: T) throws(JSException) -> T +} + +@JSFunction func jsGenericThrowOrRoundTrip( + _ shouldThrow: Bool, + _ value: T +) throws(JSException) -> T + +@JSClass struct ImportGenericBoxed { + @JSFunction init(_ value: T) throws(JSException) + @JSFunction func unwrap() throws(JSException) -> T +} + +@Suite struct ImportGenericAPITests { + @Test func genericRoundTripScalars() throws { + #expect(try jsGenericRoundTrip(42) == 42) + #expect(try jsGenericRoundTrip(-7) == -7) + #expect(try jsGenericRoundTrip(3.5) == 3.5) + #expect(try jsGenericRoundTrip(Float(1.25)) == Float(1.25)) + #expect(try jsGenericRoundTrip(true) == true) + #expect(try jsGenericRoundTrip(false) == false) + #expect(try jsGenericRoundTrip("hello") == "hello") + #expect(try jsGenericRoundTrip("") == "") + } + + @Test func genericRoundTripNumerics() throws { + #expect(try jsGenericRoundTrip(Int8(-5)) == Int8(-5)) + #expect(try jsGenericRoundTrip(Int8.min) == Int8.min) + #expect(try jsGenericRoundTrip(Int8.max) == Int8.max) + #expect(try jsGenericRoundTrip(UInt8(200)) == UInt8(200)) + #expect(try jsGenericRoundTrip(UInt8.max) == UInt8.max) + #expect(try jsGenericRoundTrip(Int16(-1000)) == Int16(-1000)) + #expect(try jsGenericRoundTrip(UInt16(60000)) == UInt16(60000)) + #expect(try jsGenericRoundTrip(Int32(-123456)) == Int32(-123456)) + #expect(try jsGenericRoundTrip(UInt32(3_000_000_000)) == UInt32(3_000_000_000)) + #expect(try jsGenericRoundTrip(UInt32.max) == UInt32.max) + #expect(try jsGenericRoundTrip(UInt(42)) == UInt(42)) + #expect(try jsGenericRoundTrip(UInt(4_000_000_000)) == UInt(4_000_000_000)) + #expect(try jsGenericRoundTrip(Int64(-9_000_000_000)) == Int64(-9_000_000_000)) + #expect(try jsGenericRoundTrip(Int64.min) == Int64.min) + #expect(try jsGenericRoundTrip(Int64.max) == Int64.max) + #expect(try jsGenericRoundTrip(UInt64(18_000_000_000_000_000_000)) == UInt64(18_000_000_000_000_000_000)) + #expect(try jsGenericRoundTrip(UInt64.max) == UInt64.max) + } + + @Test func genericRoundTripJSValue() throws { + let number = try jsGenericRoundTrip(JSValue.number(3.5)) + #expect(number.number == 3.5) + let string = try jsGenericRoundTrip(JSValue.string("hi")) + #expect(string.string == "hi") + let boolean = try jsGenericRoundTrip(JSValue.boolean(true)) + #expect(boolean.boolean == true) + #expect(try jsGenericRoundTrip(JSValue.null).isNull) + #expect(try jsGenericRoundTrip(JSValue.undefined).isUndefined) + let object = JSObject.global.Object.function!.new() + object.tag = 7 + let roundTripped = try jsGenericRoundTrip(JSValue.object(object)) + #expect(roundTripped.object?.tag.number == 7) + } + + @Test func genericWrappedRoundTrip() throws { + #expect(try jsGenericArrayRoundTrip([1, 2, 3]) == [1, 2, 3]) + #expect(try jsGenericArrayRoundTrip(["a", "b"]) == ["a", "b"]) + #expect(try jsGenericArrayRoundTrip([Int]()) == []) + #expect(try jsGenericOptionalRoundTrip(Optional.some(7)) == 7) + #expect(try jsGenericOptionalRoundTrip(Optional.none) == nil) + #expect(try jsGenericOptionalRoundTrip(Optional.some("hi")) == "hi") + let outcome = try jsGenericOptionalRoundTrip(Optional.some(.ok(code: 5))) + guard case .some(.ok(let code)) = outcome else { + Issue.record("expected .ok") + return + } + #expect(code == 5) + #expect(try jsGenericOptionalRoundTrip(Optional.none) == nil) + #expect(try jsGenericDictRoundTrip(["x": 1, "y": 2]) == ["x": 1, "y": 2]) + #expect(try jsGenericDictRoundTrip([String: String]()) == [:]) + } + + @Test func genericRoundTripEnums() throws { + #expect(try jsGenericRoundTrip(GenericRTColor.red) == .red) + #expect(try jsGenericRoundTrip(GenericRTColor.blue) == .blue) + #expect(try jsGenericRoundTrip(GenericRTMode.dark) == .dark) + #expect(try jsGenericRoundTrip(GenericRTMode.light).rawValue == "light") + #expect(try jsGenericRoundTrip(GenericRTLevel.high) == .high) + let outcome = try jsGenericRoundTrip(GenericRTOutcome.ok(code: 42)) + guard case .ok(let code) = outcome else { + Issue.record("expected .ok") + return + } + #expect(code == 42) + let failure = try jsGenericRoundTrip(GenericRTOutcome.fail(message: "boom")) + guard case .fail(let message) = failure else { + Issue.record("expected .fail") + return + } + #expect(message == "boom") + } + + @Test func genericRoundTripStruct() throws { + let point = try jsGenericRoundTrip(GenericRTPoint(x: 1, y: 2)) + #expect(point.x == 1) + #expect(point.y == 2) + } + + @Test func genericRoundTripNestedStruct() throws { + let metadata = try jsGenericRoundTrip(GenericRTNamespace.Metadata(label: "alpha", count: 7)) + #expect(metadata.label == "alpha") + #expect(metadata.count == 7) + } + + @Test func genericParse() throws { + let point: GenericRTPoint = try jsGenericParsePoint("{\"x\": 10, \"y\": 20}") + #expect(point.x == 10) + #expect(point.y == 20) + let n: Int = try jsGenericParsePoint("42") + #expect(n == 42) + let string: String = try jsGenericParsePoint("\"hi\"") + #expect(string == "hi") + } + + @Test func genericPickFirstMultiUse() throws { + #expect(try jsImportPickFirst(10, 20) as Int == 10) + #expect(try jsImportPickFirst("a", "b") as String == "a") + let firstPoint = try jsImportPickFirst(GenericRTPoint(x: 1, y: 2), GenericRTPoint(x: 3, y: 4)) + #expect(firstPoint.x == 1) + #expect(firstPoint.y == 2) + } + + @Test func genericMakeReturnOnly() throws { + let made: Int = try jsImportMakeInt() + #expect(made == 123) + } + + @Test func genericCombineSecondMultiParameter() throws { + #expect(try jsImportCombineSecond(7, "hello") as String == "hello") + #expect(try jsImportCombineSecond("x", 9) as Int == 9) + let point = try jsImportCombineSecond(42, GenericRTPoint(x: 5, y: 6)) + #expect(point.x == 5) + #expect(point.y == 6) + } + + @Test func genericRoundTripHeapObjectClass() throws { + let box = ImportGenericBox(value: 314) + #expect(box.get() == 314) + let sameBox = try jsGenericRoundTripClass(box) + #expect(sameBox.get() == 314) + sameBox.value = 271 + #expect(box.get() == 271) + } + + @Test func genericMixedConsecutiveCalls() throws { + #expect(try jsGenericRoundTrip(1) == 1) + #expect(try jsGenericRoundTrip("two") == "two") + #expect(try jsGenericRoundTrip(3.0) == 3.0) + let p = try jsGenericRoundTrip(GenericRTPoint(x: 4, y: 5)) + #expect(p.x == 4) + #expect(p.y == 5) + } + + @Test func importGenericInstanceMethod() throws { + let consumer = try ImportGenericConsumer() + #expect(try consumer.identity(42) == 42) + #expect(try consumer.identity(-7) == -7) + #expect(try consumer.identity("hi") == "hi") + #expect(try consumer.identity(true) == true) + #expect(try consumer.identity(false) == false) + let point = try consumer.identity(GenericRTPoint(x: 3, y: 4)) + #expect(point.x == 3) + #expect(point.y == 4) + } + + /// A generic parameter shares the stacks with any other stack-lowered + /// parameter, so both have to arrive in declaration order. + @Test func genericAlongsideOptionalArray() throws { + #expect(try jsGenericAfterOptionalArray([1, 2], 42) == "[1,2]|42") + #expect(try jsGenericAfterOptionalArray([1, 2], GenericRTPoint(x: 3, y: 4)) == #"[1,2]|{"x":3,"y":4}"#) + #expect(try jsGenericAfterOptionalArray(nil, "x") == #"null|"x""#) + } + + @Test func genericImportPropagatesJSException() throws { + #expect(try jsGenericThrowOrRoundTrip(false, 42) == 42) + #expect(try jsGenericThrowOrRoundTrip(false, GenericRTPoint(x: 1, y: 2)).x == 1) + do { + let _: Int = try jsGenericThrowOrRoundTrip(true, 0) + Issue.record("Expected exception") + } catch { + #expect(error.description.contains("TestError")) + } + // A throwing generic call must not strand its argument on the shared + // stack: the next call has to read its own value back. + #expect(try jsGenericThrowOrRoundTrip(false, GenericRTPoint(x: 7, y: 8)).y == 8) + } + + @Test func importGenericConstructor() throws { + let boxedInt = try ImportGenericBoxed(42) + #expect(try boxedInt.unwrap() == 42) + let boxedText = try ImportGenericBoxed("boxed") + #expect(try boxedText.unwrap() == "boxed") + let boxedPoint = try ImportGenericBoxed(GenericRTPoint(x: 1, y: 2)) + let point: GenericRTPoint = try boxedPoint.unwrap() + #expect(point.x == 1) + #expect(point.y == 2) + } + + @Test func importGenericStaticMethod() throws { + #expect(try ImportGenericConsumer.box(7) == 7) + #expect(try ImportGenericConsumer.box("s") == "s") + #expect(try ImportGenericConsumer.box(true) == true) + let color = try ImportGenericConsumer.box(GenericRTColor.green) + #expect(color == .green) + } +} diff --git a/Tests/BridgeJSRuntimeTests/JSNameAPIs.swift b/Tests/BridgeJSRuntimeTests/JSNameAPIs.swift new file mode 100644 index 000000000..48efcff59 --- /dev/null +++ b/Tests/BridgeJSRuntimeTests/JSNameAPIs.swift @@ -0,0 +1,34 @@ +import JavaScriptKit + +@JS("renamedEcho") func jsNameEcho(_ value: String) -> String { + return "echo: \(value)" +} + +@JS("greetName") func greet(_ name: String) -> String { + return "Hello, \(name)!" +} + +@JS("greetCount") func greet(_ count: Int) -> String { + return "Hello, \(count) people!" +} + +@JS class JSNameRenamedClass { + private var storage: Int + + @JS init(value: Int) { + self.storage = value + } + + @JS("current") var value: Int { + get { storage } + set { storage = newValue } + } + + @JS("doubled") func timesTwo() -> Int { + return storage * 2 + } + + @JS("makeWithValue") static func create(value: Int) -> JSNameRenamedClass { + return JSNameRenamedClass(value: value) + } +} diff --git a/Tests/BridgeJSRuntimeTests/StructAPIs.swift b/Tests/BridgeJSRuntimeTests/StructAPIs.swift index c2216c808..e11856d41 100644 --- a/Tests/BridgeJSRuntimeTests/StructAPIs.swift +++ b/Tests/BridgeJSRuntimeTests/StructAPIs.swift @@ -200,6 +200,10 @@ extension Vector2D { @JS func scaled(by factor: Double) -> Vector2D { return Vector2D(dx: dx * factor, dy: dy * factor) } + + @JS func describe() -> String { + return "Vector2D(\(dx), \(dy))" + } } @JS func roundTripDataPoint(_ data: DataPoint) -> DataPoint { diff --git a/Tests/prelude.mjs b/Tests/prelude.mjs index 42a0e3ea4..78271e1ba 100644 --- a/Tests/prelude.mjs +++ b/Tests/prelude.mjs @@ -161,6 +161,38 @@ export async function setupOptions(options, context) { jsJoinOptionalStructThenArray: joinStackParams, jsJoinEnumThenArray: joinStackParams, jsJoinStringThenStackParams: joinStackParams, + jsGenericRoundTrip: (v) => v, + jsGenericRoundTripClass: (v) => v, + jsGenericParsePoint: (json) => JSON.parse(json), + jsImportPickFirst: (a, b) => a, + jsImportMakeInt: () => 123, + jsImportCombineSecond: (a, b) => b, + jsGenericThrowOrRoundTrip: (shouldThrow, v) => { + if (shouldThrow) { + throw new Error("TestError"); + } + return v; + }, + jsGenericArrayRoundTrip: (v) => v, + jsGenericOptionalRoundTrip: (v) => v, + jsGenericDictRoundTrip: (v) => v, + jsGenericAfterOptionalArray: (a, b) => `${JSON.stringify(a)}|${JSON.stringify(b)}`, + ImportGenericConsumer: class { + identity(value) { + return value; + } + static box(value) { + return value; + } + }, + ImportGenericBoxed: class { + constructor(value) { + this.value = value; + } + unwrap() { + return this.value; + } + }, roundTripArrayMembers: (value) => { return value; }, @@ -281,6 +313,18 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { assert.equal(exports.roundTripUnsafeMutablePointer(p), p); } + assert.equal(exports.renamedEcho("hi"), "echo: hi"); + assert.equal(exports.jsNameEcho, undefined); + assert.equal(exports.greetName("John"), "Hello, John!"); + assert.equal(exports.greetCount(3), "Hello, 3 people!"); + const renamed = new exports.JSNameRenamedClass(21); + assert.equal(renamed.doubled(), 42); + assert.equal(renamed.current, 21); + renamed.current = 5; + assert.equal(renamed.doubled(), 10); + const madeRenamed = exports.JSNameRenamedClass.makeWithValue(7); + assert.equal(madeRenamed.current, 7); + const g = new exports.Greeter("John"); assert.equal(g.greet(), "Hello, John!"); @@ -699,6 +743,29 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { assert.equal(exports.NestedTypeHost.Label.untitled().text, "untitled"); nestedHost.release(); + const library = new exports.Library("Central"); + assert.equal(library.describe(), "Central"); + assert.equal(library.rename("Annex"), "Annex"); + assert.equal(exports.Library.Genre.Fiction, "fiction"); + assert.equal(exports.Library.Genre.Reference, "reference"); + const shelf = exports.Library.Shelf.init("History"); + assert.equal(shelf.label, "History"); + assert.equal(exports.Library.Shelf.capacity, 32); + assert.equal(library.shelf("Science").label, "Science"); + assert.equal(shelf.describeShelf(), "Shelf: History"); + assert.equal(exports.Library.Shelf.Divider.init(5).slot, 5); + const updateMessage = { tag: exports.Message.Tag.Update, param0: exports.Update.Flip }; + assert.deepEqual(exports.roundTripMessage(updateMessage), updateMessage); + const deleteMessage = { tag: exports.Message.Tag.Delete }; + assert.deepEqual(exports.roundTripMessage(deleteMessage), deleteMessage); + library.release(); + + const workspace = new exports.Workspace("Docs"); + assert.equal(workspace.describe(), "Docs"); + assert.equal(exports.Workspace.Kind.Personal, "personal"); + assert.equal(exports.Workspace.Kind.Shared, "shared"); + workspace.release(); + const s1 = { tag: exports.APIResult.Tag.Success, param0: "Cześć 🙋‍♂️" }; const f1 = { tag: exports.APIResult.Tag.Failure, param0: 42 }; const i1 = { tag: APIResultValues.Tag.Info }; @@ -871,6 +938,7 @@ function testStructSupport(exports) { const scaled = vec.scaled(2.0); assert.equal(scaled.dx, 6.0); assert.equal(scaled.dy, 8.0); + assert.equal(vec.describe(), "Vector2D(3.0, 4.0)"); const publicPoint = { x: 9, y: -3 }; assert.deepEqual(exports.roundTripPublicPoint(publicPoint), publicPoint);