From a04bd5033f2d3d8b169f76f8909bde8e54ee621e Mon Sep 17 00:00:00 2001 From: Krzysztof Rodak Date: Tue, 3 Feb 2026 09:43:58 +0100 Subject: [PATCH] BridgeJS: Fix namespace enum with `@JS(namespace:)` attribute --- .../Sources/BridgeJSCore/ExportSwift.swift | 9 +- .../BridgeJSCore/SwiftToSkeleton.swift | 8 +- .../BridgeJSSkeleton/BridgeJSSkeleton.swift | 10 +- .../Inputs/EnumNamespace.swift | 15 +- .../EnumNamespace.Export.d.ts | 9 + .../BridgeJSLinkTests/EnumNamespace.Export.js | 24 +++ .../EnumNamespace.Global.Export.d.ts | 18 ++ .../EnumNamespace.Global.Export.js | 36 ++++ .../EnumNamespace.Global.json | 123 ++++++++++++ .../EnumNamespace.Global.swift | 47 +++++ .../ExportSwiftTests/EnumNamespace.json | 123 ++++++++++++ .../ExportSwiftTests/EnumNamespace.swift | 47 +++++ .../StaticFunctions.Global.json | 2 +- .../ExportSwiftTests/StaticFunctions.json | 2 +- .../StaticProperties.Global.json | 10 +- .../ExportSwiftTests/StaticProperties.json | 10 +- .../Generated/JavaScript/BridgeJS.json | 10 +- .../BridgeJSRuntimeTests/ExportAPITests.swift | 21 ++ .../Generated/BridgeJS.swift | 44 +++++ .../Generated/JavaScript/BridgeJS.json | 185 +++++++++++++++++- Tests/prelude.mjs | 10 + 21 files changed, 723 insertions(+), 40 deletions(-) diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift index d7d5c8200..1f8f72ad7 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift @@ -533,14 +533,9 @@ public class ExportSwift { if function.effects.isStatic, let staticContext = function.staticContext { let callName: String switch staticContext { - case .className(let baseName), .enumName(let baseName), .structName(let baseName): + case .className(let baseName), .enumName(let baseName), .structName(let baseName), + .namespaceEnum(let baseName): callName = "\(baseName).\(function.name)" - case .namespaceEnum: - if let namespace = function.namespace, !namespace.isEmpty { - callName = "\(namespace.joined(separator: ".")).\(function.name)" - } else { - callName = function.name - } } builder.call(name: callName, returnType: function.returnType) } else { diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift index ea79d3f3b..b780012f0 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift @@ -990,7 +990,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { } let isNamespaceEnum = exportedEnumByName[enumKey]?.cases.isEmpty ?? true - staticContext = isNamespaceEnum ? .namespaceEnum : .enumName(enumName) + let swiftCallName = exportedEnumByName[enumKey]?.swiftCallName ?? enumName + staticContext = isNamespaceEnum ? .namespaceEnum(swiftCallName) : .enumName(enumName) case .protocolBody(_, _): return nil case .structBody(let structName, _): @@ -1187,7 +1188,10 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { return .skipChildren } let isNamespaceEnum = exportedEnumByName[enumKey]?.cases.isEmpty ?? true - staticContext = isStatic ? (isNamespaceEnum ? .namespaceEnum : .enumName(enumName)) : nil + // Use swiftCallName for the full Swift call path (handles nested enums correctly) + let swiftCallName = exportedEnumByName[enumKey]?.swiftCallName ?? enumName + staticContext = + isStatic ? (isNamespaceEnum ? .namespaceEnum(swiftCallName) : .enumName(swiftCallName)) : nil case .topLevel: diagnose(node: node, message: "@JS var must be inside a @JS class or enum") return .skipChildren diff --git a/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift b/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift index 33cc94479..5013dda66 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift @@ -242,7 +242,7 @@ public enum StaticContext: Codable, Equatable, Sendable { case className(String) case structName(String) case enumName(String) - case namespaceEnum + case namespaceEnum(String) } // MARK: - Struct Skeleton @@ -533,13 +533,9 @@ public struct ExportedProperty: Codable, Equatable, Sendable { public func callName(prefix: String? = nil) -> String { if let staticContext = staticContext { switch staticContext { - case .className(let baseName), .enumName(let baseName), .structName(let baseName): + case .className(let baseName), .enumName(let baseName), .structName(let baseName), + .namespaceEnum(let baseName): return "\(baseName).\(name)" - case .namespaceEnum: - if let namespace = namespace, !namespace.isEmpty { - let namespacePath = namespace.joined(separator: ".") - return "\(namespacePath).\(name)" - } } } if let prefix = prefix { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/EnumNamespace.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/EnumNamespace.swift index 26a4e9c3a..dbf044834 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/EnumNamespace.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/EnumNamespace.swift @@ -53,4 +53,17 @@ enum Internal { } } -// TODO: Add namespace enum with static functions when supported +@JS(namespace: "Services.Graph") +enum GraphOperations { + @JS static func createGraph(rootId: Int) -> Int { + return rootId * 10 + } + + @JS static func nodeCount(graphId: Int) -> Int { + return graphId + } + + @JS static func validate(graphId: Int) throws(JSException) -> Bool { + return graphId > 0 + } +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.d.ts index b8b92d14e..a6934d6e7 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.d.ts @@ -84,6 +84,15 @@ export type Exports = { }, }, }, + Services: { + Graph: { + GraphOperations: { + createGraph(rootId: number): number; + nodeCount(graphId: number): number; + validate(graphId: number): boolean; + }, + }, + }, Utils: { Converter: { new(): Converter; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js index b01148873..1eb483365 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js @@ -332,6 +332,30 @@ export async function createInstantiator(options, swift) { }, }, }, + Services: { + Graph: { + GraphOperations: { + createGraph: function bjs_Services_Graph_GraphOperations_static_createGraph(rootId) { + const ret = instance.exports.bjs_Services_Graph_GraphOperations_static_createGraph(rootId); + return ret; + }, + nodeCount: function bjs_Services_Graph_GraphOperations_static_nodeCount(graphId) { + const ret = instance.exports.bjs_Services_Graph_GraphOperations_static_nodeCount(graphId); + return ret; + }, + validate: function bjs_Services_Graph_GraphOperations_static_validate(graphId) { + const ret = instance.exports.bjs_Services_Graph_GraphOperations_static_validate(graphId); + if (tmpRetException) { + const error = swift.memory.getObject(tmpRetException); + swift.memory.release(tmpRetException); + tmpRetException = undefined; + throw error; + } + return ret !== 0; + }, + }, + }, + }, Utils: { Converter, }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.Export.d.ts index 4261ca3bb..f1dc0a926 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.Export.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.Export.d.ts @@ -58,6 +58,15 @@ declare global { } } } + namespace Services { + namespace Graph { + namespace GraphOperations { + createGraph(rootId: number): number; + nodeCount(graphId: number): number; + validate(graphId: number): boolean; + } + } + } namespace Utils { class Converter { constructor(); @@ -103,6 +112,15 @@ export type Exports = { }, }, }, + Services: { + Graph: { + GraphOperations: { + createGraph(rootId: number): number; + nodeCount(graphId: number): number; + validate(graphId: number): boolean; + }, + }, + }, Utils: { Converter: { new(): Converter; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.Export.js index 77c327e8d..f48a0050e 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.Export.js @@ -349,6 +349,15 @@ export async function createInstantiator(options, swift) { if (typeof globalThis.Networking.APIV2.Internal === 'undefined') { globalThis.Networking.APIV2.Internal = {}; } + if (typeof globalThis.Services === 'undefined') { + globalThis.Services = {}; + } + if (typeof globalThis.Services.Graph === 'undefined') { + globalThis.Services.Graph = {}; + } + if (typeof globalThis.Services.Graph.GraphOperations === 'undefined') { + globalThis.Services.Graph.GraphOperations = {}; + } if (typeof globalThis.Utils === 'undefined') { globalThis.Utils = {}; } @@ -369,6 +378,30 @@ export async function createInstantiator(options, swift) { }, }, }, + Services: { + Graph: { + GraphOperations: { + createGraph: function bjs_Services_Graph_GraphOperations_static_createGraph(rootId) { + const ret = instance.exports.bjs_Services_Graph_GraphOperations_static_createGraph(rootId); + return ret; + }, + nodeCount: function bjs_Services_Graph_GraphOperations_static_nodeCount(graphId) { + const ret = instance.exports.bjs_Services_Graph_GraphOperations_static_nodeCount(graphId); + return ret; + }, + validate: function bjs_Services_Graph_GraphOperations_static_validate(graphId) { + const ret = instance.exports.bjs_Services_Graph_GraphOperations_static_validate(graphId); + if (tmpRetException) { + const error = swift.memory.getObject(tmpRetException); + swift.memory.release(tmpRetException); + tmpRetException = undefined; + throw error; + } + return ret !== 0; + }, + }, + }, + }, Utils: { Converter, }, @@ -377,6 +410,9 @@ export async function createInstantiator(options, swift) { globalThis.Utils.Converter = exports.Utils.Converter; globalThis.Networking.API.HTTPServer = exports.Networking.API.HTTPServer; globalThis.Networking.APIV2.Internal.TestServer = exports.Networking.APIV2.Internal.TestServer; + globalThis.Services.Graph.GraphOperations.createGraph = exports.Services.Graph.GraphOperations.createGraph; + globalThis.Services.Graph.GraphOperations.nodeCount = exports.Services.Graph.GraphOperations.nodeCount; + globalThis.Services.Graph.GraphOperations.validate = exports.Services.Graph.GraphOperations.validate; return exports; }, } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.json index 42a084c44..135908d7f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.json @@ -400,6 +400,129 @@ ], "swiftCallName" : "Internal.SupportedMethod", "tsFullPath" : "Networking.APIV2.Internal.SupportedMethod" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "GraphOperations", + "namespace" : [ + "Services", + "Graph" + ], + "staticMethods" : [ + { + "abiName" : "bjs_Services_Graph_GraphOperations_static_createGraph", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "name" : "createGraph", + "namespace" : [ + "Services", + "Graph", + "GraphOperations" + ], + "parameters" : [ + { + "label" : "rootId", + "name" : "rootId", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "int" : { + + } + }, + "staticContext" : { + "namespaceEnum" : { + "_0" : "GraphOperations" + } + } + }, + { + "abiName" : "bjs_Services_Graph_GraphOperations_static_nodeCount", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "name" : "nodeCount", + "namespace" : [ + "Services", + "Graph", + "GraphOperations" + ], + "parameters" : [ + { + "label" : "graphId", + "name" : "graphId", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "int" : { + + } + }, + "staticContext" : { + "namespaceEnum" : { + "_0" : "GraphOperations" + } + } + }, + { + "abiName" : "bjs_Services_Graph_GraphOperations_static_validate", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : true + }, + "name" : "validate", + "namespace" : [ + "Services", + "Graph", + "GraphOperations" + ], + "parameters" : [ + { + "label" : "graphId", + "name" : "graphId", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "bool" : { + + } + }, + "staticContext" : { + "namespaceEnum" : { + "_0" : "GraphOperations" + } + } + } + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GraphOperations", + "tsFullPath" : "Services.Graph.GraphOperations" } ], "exposeToGlobal" : true, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.swift index 9683b5307..43e3f69a4 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.swift @@ -82,6 +82,53 @@ extension Internal.SupportedMethod: _BridgedSwiftCaseEnum { } } +@_expose(wasm, "bjs_Services_Graph_GraphOperations_static_createGraph") +@_cdecl("bjs_Services_Graph_GraphOperations_static_createGraph") +public func _bjs_Services_Graph_GraphOperations_static_createGraph(_ rootId: Int32) -> Int32 { + #if arch(wasm32) + let ret = GraphOperations.createGraph(rootId: Int.bridgeJSLiftParameter(rootId)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Services_Graph_GraphOperations_static_nodeCount") +@_cdecl("bjs_Services_Graph_GraphOperations_static_nodeCount") +public func _bjs_Services_Graph_GraphOperations_static_nodeCount(_ graphId: Int32) -> Int32 { + #if arch(wasm32) + let ret = GraphOperations.nodeCount(graphId: Int.bridgeJSLiftParameter(graphId)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Services_Graph_GraphOperations_static_validate") +@_cdecl("bjs_Services_Graph_GraphOperations_static_validate") +public func _bjs_Services_Graph_GraphOperations_static_validate(_ graphId: Int32) -> Int32 { + #if arch(wasm32) + do { + let ret = try GraphOperations.validate(graphId: Int.bridgeJSLiftParameter(graphId)) + return ret.bridgeJSLowerReturn() + } catch let error { + if let error = error.thrownValue.object { + withExtendedLifetime(error) { + _swift_js_throw(Int32(bitPattern: $0.id)) + } + } else { + let jsError = JSError(message: String(describing: error)) + withExtendedLifetime(jsError.jsObject) { + _swift_js_throw(Int32(bitPattern: $0.id)) + } + } + return 0 + } + #else + fatalError("Only available on WebAssembly") + #endif +} + @_expose(wasm, "bjs_Converter_init") @_cdecl("bjs_Converter_init") public func _bjs_Converter_init() -> UnsafeMutableRawPointer { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.json index 23bb06429..374ae13f4 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.json @@ -400,6 +400,129 @@ ], "swiftCallName" : "Internal.SupportedMethod", "tsFullPath" : "Networking.APIV2.Internal.SupportedMethod" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "GraphOperations", + "namespace" : [ + "Services", + "Graph" + ], + "staticMethods" : [ + { + "abiName" : "bjs_Services_Graph_GraphOperations_static_createGraph", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "name" : "createGraph", + "namespace" : [ + "Services", + "Graph", + "GraphOperations" + ], + "parameters" : [ + { + "label" : "rootId", + "name" : "rootId", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "int" : { + + } + }, + "staticContext" : { + "namespaceEnum" : { + "_0" : "GraphOperations" + } + } + }, + { + "abiName" : "bjs_Services_Graph_GraphOperations_static_nodeCount", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "name" : "nodeCount", + "namespace" : [ + "Services", + "Graph", + "GraphOperations" + ], + "parameters" : [ + { + "label" : "graphId", + "name" : "graphId", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "int" : { + + } + }, + "staticContext" : { + "namespaceEnum" : { + "_0" : "GraphOperations" + } + } + }, + { + "abiName" : "bjs_Services_Graph_GraphOperations_static_validate", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : true + }, + "name" : "validate", + "namespace" : [ + "Services", + "Graph", + "GraphOperations" + ], + "parameters" : [ + { + "label" : "graphId", + "name" : "graphId", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "bool" : { + + } + }, + "staticContext" : { + "namespaceEnum" : { + "_0" : "GraphOperations" + } + } + } + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GraphOperations", + "tsFullPath" : "Services.Graph.GraphOperations" } ], "exposeToGlobal" : false, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.swift index 9683b5307..43e3f69a4 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.swift @@ -82,6 +82,53 @@ extension Internal.SupportedMethod: _BridgedSwiftCaseEnum { } } +@_expose(wasm, "bjs_Services_Graph_GraphOperations_static_createGraph") +@_cdecl("bjs_Services_Graph_GraphOperations_static_createGraph") +public func _bjs_Services_Graph_GraphOperations_static_createGraph(_ rootId: Int32) -> Int32 { + #if arch(wasm32) + let ret = GraphOperations.createGraph(rootId: Int.bridgeJSLiftParameter(rootId)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Services_Graph_GraphOperations_static_nodeCount") +@_cdecl("bjs_Services_Graph_GraphOperations_static_nodeCount") +public func _bjs_Services_Graph_GraphOperations_static_nodeCount(_ graphId: Int32) -> Int32 { + #if arch(wasm32) + let ret = GraphOperations.nodeCount(graphId: Int.bridgeJSLiftParameter(graphId)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Services_Graph_GraphOperations_static_validate") +@_cdecl("bjs_Services_Graph_GraphOperations_static_validate") +public func _bjs_Services_Graph_GraphOperations_static_validate(_ graphId: Int32) -> Int32 { + #if arch(wasm32) + do { + let ret = try GraphOperations.validate(graphId: Int.bridgeJSLiftParameter(graphId)) + return ret.bridgeJSLowerReturn() + } catch let error { + if let error = error.thrownValue.object { + withExtendedLifetime(error) { + _swift_js_throw(Int32(bitPattern: $0.id)) + } + } else { + let jsError = JSError(message: String(describing: error)) + withExtendedLifetime(jsError.jsObject) { + _swift_js_throw(Int32(bitPattern: $0.id)) + } + } + return 0 + } + #else + fatalError("Only available on WebAssembly") + #endif +} + @_expose(wasm, "bjs_Converter_init") @_cdecl("bjs_Converter_init") public func _bjs_Converter_init() -> UnsafeMutableRawPointer { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.Global.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.Global.json index 3b6937c30..0eec726c8 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.Global.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.Global.json @@ -311,7 +311,7 @@ }, "staticContext" : { "namespaceEnum" : { - + "_0" : "Utils.String" } } } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.json index 652465dff..372504135 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.json @@ -311,7 +311,7 @@ }, "staticContext" : { "namespaceEnum" : { - + "_0" : "Utils.String" } } } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.Global.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.Global.json index 4ec19f83c..28457fb63 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.Global.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.Global.json @@ -220,7 +220,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "PropertyNamespace" } }, "type" : { @@ -238,7 +238,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "PropertyNamespace" } }, "type" : { @@ -274,7 +274,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "PropertyNamespace.Nested" } }, "type" : { @@ -293,7 +293,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "PropertyNamespace.Nested" } }, "type" : { @@ -312,7 +312,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "PropertyNamespace.Nested" } }, "type" : { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.json index 0e8b2de22..829c20718 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.json @@ -220,7 +220,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "PropertyNamespace" } }, "type" : { @@ -238,7 +238,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "PropertyNamespace" } }, "type" : { @@ -274,7 +274,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "PropertyNamespace.Nested" } }, "type" : { @@ -293,7 +293,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "PropertyNamespace.Nested" } }, "type" : { @@ -312,7 +312,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "PropertyNamespace.Nested" } }, "type" : { diff --git a/Tests/BridgeJSGlobalTests/Generated/JavaScript/BridgeJS.json b/Tests/BridgeJSGlobalTests/Generated/JavaScript/BridgeJS.json index 8b91ea964..e7bcf59b6 100644 --- a/Tests/BridgeJSGlobalTests/Generated/JavaScript/BridgeJS.json +++ b/Tests/BridgeJSGlobalTests/Generated/JavaScript/BridgeJS.json @@ -406,7 +406,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "GlobalStaticPropertyNamespace" } }, "type" : { @@ -424,7 +424,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "GlobalStaticPropertyNamespace" } }, "type" : { @@ -460,7 +460,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "GlobalStaticPropertyNamespace.NestedProperties" } }, "type" : { @@ -479,7 +479,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "GlobalStaticPropertyNamespace.NestedProperties" } }, "type" : { @@ -498,7 +498,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "GlobalStaticPropertyNamespace.NestedProperties" } }, "type" : { diff --git a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift index 2aee862c6..f82106ac1 100644 --- a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift +++ b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift @@ -295,6 +295,16 @@ struct TestError: Error { return String(value) } } + + @JS enum StringUtils { + @JS static func uppercase(_ text: String) -> String { + return text.uppercased() + } + + @JS static func lowercase(_ text: String) -> String { + return text.lowercased() + } + } } @JS enum Networking { @@ -788,6 +798,17 @@ enum APIOptionalResult { } } +@JS(namespace: "Services.Graph") +enum GraphOperations { + @JS static func createGraph(rootId: Int) -> Int { + return rootId * 10 + } + + @JS static func nodeCount(graphId: Int) -> Int { + return graphId + } +} + // MARK: - Default Parameters @JS func testStringDefault(message: String = "Hello World") -> String { diff --git a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift index 35a53805d..42f360ce7 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift @@ -1350,6 +1350,28 @@ extension TSDirection: _BridgedSwiftCaseEnum { extension TSTheme: _BridgedSwiftEnumNoPayload { } +@_expose(wasm, "bjs_Utils_StringUtils_static_uppercase") +@_cdecl("bjs_Utils_StringUtils_static_uppercase") +public func _bjs_Utils_StringUtils_static_uppercase(_ textBytes: Int32, _ textLength: Int32) -> Void { + #if arch(wasm32) + let ret = Utils.StringUtils.uppercase(_: String.bridgeJSLiftParameter(textBytes, textLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Utils_StringUtils_static_lowercase") +@_cdecl("bjs_Utils_StringUtils_static_lowercase") +public func _bjs_Utils_StringUtils_static_lowercase(_ textBytes: Int32, _ textLength: Int32) -> Void { + #if arch(wasm32) + let ret = Utils.StringUtils.lowercase(_: String.bridgeJSLiftParameter(textBytes, textLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + extension Networking.API.Method: _BridgedSwiftCaseEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { return bridgeJSRawValue @@ -1992,6 +2014,28 @@ public func _bjs_StaticUtils_Nested_static_roundtrip(_ valueBytes: Int32, _ valu #endif } +@_expose(wasm, "bjs_Services_Graph_GraphOperations_static_createGraph") +@_cdecl("bjs_Services_Graph_GraphOperations_static_createGraph") +public func _bjs_Services_Graph_GraphOperations_static_createGraph(_ rootId: Int32) -> Int32 { + #if arch(wasm32) + let ret = GraphOperations.createGraph(rootId: Int.bridgeJSLiftParameter(rootId)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Services_Graph_GraphOperations_static_nodeCount") +@_cdecl("bjs_Services_Graph_GraphOperations_static_nodeCount") +public func _bjs_Services_Graph_GraphOperations_static_nodeCount(_ graphId: Int32) -> Int32 { + #if arch(wasm32) + let ret = GraphOperations.nodeCount(graphId: Int.bridgeJSLiftParameter(graphId)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + extension StaticPropertyEnum: _BridgedSwiftCaseEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { return bridgeJSRawValue diff --git a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json index c79139ea4..5d75ef55e 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json +++ b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json @@ -3500,6 +3500,91 @@ { "cases" : [ + ], + "emitStyle" : "const", + "name" : "StringUtils", + "namespace" : [ + "Utils" + ], + "staticMethods" : [ + { + "abiName" : "bjs_Utils_StringUtils_static_uppercase", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "name" : "uppercase", + "namespace" : [ + "Utils", + "StringUtils" + ], + "parameters" : [ + { + "label" : "_", + "name" : "text", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + }, + "staticContext" : { + "namespaceEnum" : { + "_0" : "Utils.StringUtils" + } + } + }, + { + "abiName" : "bjs_Utils_StringUtils_static_lowercase", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "name" : "lowercase", + "namespace" : [ + "Utils", + "StringUtils" + ], + "parameters" : [ + { + "label" : "_", + "name" : "text", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + }, + "staticContext" : { + "namespaceEnum" : { + "_0" : "Utils.StringUtils" + } + } + } + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Utils.StringUtils", + "tsFullPath" : "Utils.StringUtils" + }, + { + "cases" : [ + ], "emitStyle" : "const", "name" : "Networking", @@ -4356,7 +4441,7 @@ }, "staticContext" : { "namespaceEnum" : { - + "_0" : "StaticUtils.Nested" } } } @@ -4367,6 +4452,94 @@ "swiftCallName" : "StaticUtils.Nested", "tsFullPath" : "StaticUtils.Nested" }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "GraphOperations", + "namespace" : [ + "Services", + "Graph" + ], + "staticMethods" : [ + { + "abiName" : "bjs_Services_Graph_GraphOperations_static_createGraph", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "name" : "createGraph", + "namespace" : [ + "Services", + "Graph", + "GraphOperations" + ], + "parameters" : [ + { + "label" : "rootId", + "name" : "rootId", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "int" : { + + } + }, + "staticContext" : { + "namespaceEnum" : { + "_0" : "GraphOperations" + } + } + }, + { + "abiName" : "bjs_Services_Graph_GraphOperations_static_nodeCount", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "name" : "nodeCount", + "namespace" : [ + "Services", + "Graph", + "GraphOperations" + ], + "parameters" : [ + { + "label" : "graphId", + "name" : "graphId", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "int" : { + + } + }, + "staticContext" : { + "namespaceEnum" : { + "_0" : "GraphOperations" + } + } + } + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GraphOperations", + "tsFullPath" : "Services.Graph.GraphOperations" + }, { "cases" : [ { @@ -4501,7 +4674,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "StaticPropertyNamespace" } }, "type" : { @@ -4519,7 +4692,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "StaticPropertyNamespace" } }, "type" : { @@ -4555,7 +4728,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "StaticPropertyNamespace.NestedProperties" } }, "type" : { @@ -4574,7 +4747,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "StaticPropertyNamespace.NestedProperties" } }, "type" : { @@ -4593,7 +4766,7 @@ ], "staticContext" : { "namespaceEnum" : { - + "_0" : "StaticPropertyNamespace.NestedProperties" } }, "type" : { diff --git a/Tests/prelude.mjs b/Tests/prelude.mjs index 12307d605..0319ce424 100644 --- a/Tests/prelude.mjs +++ b/Tests/prelude.mjs @@ -527,6 +527,11 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { assert.equal(converter.toString(123), "123"); converter.release(); + assert.equal(exports.Utils.StringUtils.uppercase("hello"), "HELLO"); + assert.equal(exports.Utils.StringUtils.uppercase(""), ""); + assert.equal(exports.Utils.StringUtils.lowercase("WORLD"), "world"); + assert.equal(exports.Utils.StringUtils.lowercase("HeLLo"), "hello"); + const httpServer = new exports.Networking.API.HTTPServer(); httpServer.call(exports.Networking.API.Method.Get); httpServer.call(exports.Networking.API.Method.Post); @@ -717,6 +722,11 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { assert.equal(exports.StaticUtils.Nested.roundtrip("hello world"), "hello world"); assert.equal(exports.StaticUtils.Nested.roundtrip("test"), "test"); + assert.equal(exports.Services.Graph.GraphOperations.createGraph(5), 50); + assert.equal(exports.Services.Graph.GraphOperations.createGraph(0), 0); + assert.equal(exports.Services.Graph.GraphOperations.nodeCount(42), 42); + assert.equal(exports.Services.Graph.GraphOperations.nodeCount(0), 0); + // Test default parameters assert.equal(exports.testStringDefault(), "Hello World"); assert.equal(exports.testStringDefault("Custom Message"), "Custom Message");