From 30ae01a8a99e4ce6381c8dd022351314a162f246 Mon Sep 17 00:00:00 2001 From: Krzysztof Rodak Date: Thu, 20 Nov 2025 13:40:49 +0200 Subject: [PATCH 1/4] BridgeJS: Optional global namespace generation --- .../Sources/PlayBridgeJS/main.swift | 3 +- .../Sources/BridgeJSCore/ExportSwift.swift | 8 + .../Sources/BridgeJSLink/BridgeJSLink.swift | 231 ++++++++--- .../BridgeJSSkeleton/BridgeJSSkeleton.swift | 3 + .../BridgeJSToolTests/BridgeJSLinkTests.swift | 50 ++- .../EnumAssociatedValue.Export.d.ts | 6 +- .../EnumNamespace.Export.d.ts | 12 +- .../EnumNamespace_NoGlobal.Export.d.ts | 101 +++++ .../EnumNamespace_NoGlobal.Export.js | 323 +++++++++++++++ .../Namespaces_NoGlobal.Export.d.ts | 55 +++ .../Namespaces_NoGlobal.Export.js | 311 ++++++++++++++ .../StaticFunctions_NoGlobal.Export.d.ts | 63 +++ .../StaticFunctions_NoGlobal.Export.js | 337 +++++++++++++++ .../StaticProperties_NoGlobal.Export.d.ts | 58 +++ .../StaticProperties_NoGlobal.Export.js | 386 ++++++++++++++++++ .../ExportSwiftTests/DefaultParameters.json | 3 +- .../ExportSwiftTests/EnumAssociatedValue.json | 18 +- .../ExportSwiftTests/EnumCase.json | 12 +- .../ExportSwiftTests/EnumNamespace.json | 27 +- .../ExportSwiftTests/EnumRawType.json | 36 +- .../ExportSwiftTests/Protocol.json | 12 +- .../ExportSwiftTests/StaticFunctions.json | 12 +- .../ExportSwiftTests/StaticProperties.json | 9 +- .../ExportSwiftTests/SwiftClosure.json | 12 +- Plugins/PackageToJS/Sources/PackageToJS.swift | 3 +- .../JavaScript/BridgeJS.ExportSwift.json | 84 ++-- 26 files changed, 2029 insertions(+), 146 deletions(-) create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace_NoGlobal.Export.d.ts create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace_NoGlobal.Export.js create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces_NoGlobal.Export.d.ts create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces_NoGlobal.Export.js create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions_NoGlobal.Export.d.ts create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions_NoGlobal.Export.js create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties_NoGlobal.Export.d.ts create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties_NoGlobal.Export.js diff --git a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/main.swift b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/main.swift index 35d2340d..2be8626e 100644 --- a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/main.swift +++ b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/main.swift @@ -40,7 +40,8 @@ import class Foundation.JSONDecoder children: [importSkeleton] ) ], - sharedMemory: false + sharedMemory: false, + exposeToGlobal: true ) let linked = try linker.link() diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift index 0938bfcf..4859ba6d 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift @@ -882,10 +882,18 @@ public class ExportSwift { message: "Enum visibility must be at least internal" ) + let tsFullPath: String + if let namespace = namespaceResult.namespace, !namespace.isEmpty { + tsFullPath = namespace.joined(separator: ".") + "." + name + } else { + tsFullPath = name + } + // Create enum directly in dictionary let exportedEnum = ExportedEnum( name: name, swiftCallName: swiftCallName, + tsFullPath: tsFullPath, explicitAccessControl: explicitAccessControl, cases: [], // Will be populated in visit(EnumCaseDeclSyntax) rawType: SwiftEnumRawType(rawType), diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift index 478ba15d..98b57202 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift @@ -12,16 +12,19 @@ struct BridgeJSLink { var exportedSkeletons: [ExportedSkeleton] = [] var importedSkeletons: [ImportedModuleSkeleton] = [] let sharedMemory: Bool + let exposeToGlobal: Bool private let namespaceBuilder = NamespaceBuilder() init( exportedSkeletons: [ExportedSkeleton] = [], importedSkeletons: [ImportedModuleSkeleton] = [], - sharedMemory: Bool + sharedMemory: Bool, + exposeToGlobal: Bool = true ) { self.exportedSkeletons = exportedSkeletons self.importedSkeletons = importedSkeletons self.sharedMemory = sharedMemory + self.exposeToGlobal = exposeToGlobal } mutating func addExportedSkeletonFile(data: Data) throws { @@ -77,7 +80,7 @@ struct BridgeJSLink { var enumStaticAssignments: [String] = [] } - private func collectLinkData() throws -> LinkData { + private func collectLinkData(exposeToGlobal: Bool) throws -> LinkData { var data = LinkData() // Swift heap object class definitions @@ -873,8 +876,8 @@ struct BridgeJSLink { for property in proto.properties { let propertySignature = property.isReadonly - ? "readonly \(property.name): \(property.type.tsType);" - : "\(property.name): \(property.type.tsType);" + ? "readonly \(property.name): \(resolveTypeScriptType(property.type));" + : "\(property.name): \(resolveTypeScriptType(property.type));" printer.write(propertySignature) } } @@ -892,8 +895,16 @@ struct BridgeJSLink { let enumValuesName = enumDefinition.valuesName let enumObjectName = enumDefinition.objectTypeName + // Use fully-qualified path for namespaced enums + let fullEnumValuesPath: String + if let namespace = enumDefinition.namespace, !namespace.isEmpty { + fullEnumValuesPath = namespace.joined(separator: ".") + "." + enumValuesName + } else { + fullEnumValuesPath = enumValuesName + } + if !enumDefinition.staticMethods.isEmpty || !enumDefinition.staticProperties.isEmpty { - printer.write("export type \(enumObjectName) = typeof \(enumValuesName) & {") + printer.write("export type \(enumObjectName) = typeof \(fullEnumValuesPath) & {") printer.indent { for function in enumDefinition.staticMethods { printer.write( @@ -902,12 +913,12 @@ struct BridgeJSLink { } for property in enumDefinition.staticProperties { let readonly = property.isReadonly ? "readonly " : "" - printer.write("\(readonly)\(property.name): \(property.type.tsType);") + printer.write("\(readonly)\(property.name): \(resolveTypeScriptType(property.type));") } } printer.write("};") } else { - printer.write("export type \(enumObjectName) = typeof \(enumValuesName);") + printer.write("export type \(enumObjectName) = typeof \(fullEnumValuesPath);") } printer.nextLine() } @@ -916,6 +927,7 @@ struct BridgeJSLink { // Type definitions section (namespace declarations, class definitions, imported types) let namespaceDeclarationsLines = namespaceBuilder.namespaceDeclarations( exportedSkeletons: exportedSkeletons, + exposeToGlobal: exposeToGlobal, renderTSSignatureCallback: { parameters, returnType, effects in self.renderTSSignature(parameters: parameters, returnType: returnType, effects: effects) } @@ -998,7 +1010,8 @@ struct BridgeJSLink { printer.write(lines: data.topLevelEnumLines) let topLevelNamespaceCode = namespaceBuilder.buildTopLevelNamespaceInitialization( - exportedSkeletons: exportedSkeletons + exportedSkeletons: exportedSkeletons, + exposeToGlobal: exposeToGlobal ) printer.write(lines: topLevelNamespaceCode) @@ -1061,14 +1074,16 @@ struct BridgeJSLink { printer.write(lines: data.classLines) let namespaceInitCode = namespaceBuilder.buildNamespaceInitialization( - exportedSkeletons: exportedSkeletons + exportedSkeletons: exportedSkeletons, + exposeToGlobal: exposeToGlobal ) printer.write(lines: namespaceInitCode) - let propertyAssignments = try generateNamespacePropertyAssignments( - data: data, - exportedSkeletons: exportedSkeletons, - namespaceBuilder: namespaceBuilder + let propertyAssignments = try generateNamespacePropertyAssignments( + data: data, + exportedSkeletons: exportedSkeletons, + namespaceBuilder: namespaceBuilder, + exposeToGlobal: exposeToGlobal ) printer.write(lines: propertyAssignments) } @@ -1082,7 +1097,7 @@ struct BridgeJSLink { } func link() throws -> (outputJs: String, outputDts: String) { - let data = try collectLinkData() + let data = try collectLinkData(exposeToGlobal: exposeToGlobal) let outputJs = try generateJavaScript(data: data) let outputDts = generateTypeScript(data: data) return (outputJs, outputDts) @@ -1140,10 +1155,15 @@ struct BridgeJSLink { private func generateNamespacePropertyAssignments( data: LinkData, exportedSkeletons: [ExportedSkeleton], - namespaceBuilder: NamespaceBuilder + namespaceBuilder: NamespaceBuilder, + exposeToGlobal: Bool ) throws -> [String] { let printer = CodeFragmentPrinter() - printer.write(lines: data.enumStaticAssignments) + + // Only write globalThis property assignments when exposeToGlobal is true + if exposeToGlobal { + printer.write(lines: data.enumStaticAssignments) + } printer.write("const exports = {") try printer.indent { @@ -1151,6 +1171,7 @@ struct BridgeJSLink { let hierarchicalLines = try namespaceBuilder.buildHierarchicalExportsObject( exportedSkeletons: exportedSkeletons, + exposeToGlobal: exposeToGlobal, renderFunctionImpl: { function in let (js, _) = try self.renderExportedFunction(function: function) return js @@ -1161,8 +1182,10 @@ struct BridgeJSLink { printer.write("};") printer.write("_exports = exports;") - let globalThisLines = namespaceBuilder.buildGlobalThisAssignments(exportedSkeletons: exportedSkeletons) - printer.write(lines: globalThisLines) + if exposeToGlobal { + let globalThisLines = namespaceBuilder.buildGlobalThisAssignments(exportedSkeletons: exportedSkeletons) + printer.write(lines: globalThisLines) + } printer.write("return exports;") @@ -1189,8 +1212,8 @@ struct BridgeJSLink { for property in type.properties { let propertySignature = property.isReadonly - ? "readonly \(property.name): \(property.type.tsType);" - : "\(property.name): \(property.type.tsType);" + ? "readonly \(property.name): \(resolveTypeScriptType(property.type));" + : "\(property.name): \(resolveTypeScriptType(property.type));" printer.write(propertySignature) } @@ -1320,16 +1343,57 @@ struct BridgeJSLink { } } + /// Returns TypeScript type string for a BridgeType, using full paths for enums + /// If the type is an enum, looks up the ExportedEnum and uses its tsFullPath + /// Otherwise, uses the default tsType property + private func resolveTypeScriptType(_ type: BridgeType) -> String { + return Self.resolveTypeScriptType(type, exportedSkeletons: exportedSkeletons) + } + + /// Static helper for resolving TypeScript types with full enum paths + /// Can be used by both BridgeJSLink and NamespaceBuilder + fileprivate static func resolveTypeScriptType(_ type: BridgeType, exportedSkeletons: [ExportedSkeleton]) -> String { + switch type { + case .caseEnum(let name), .rawValueEnum(let name, _), + .associatedValueEnum(let name), .namespaceEnum(let name): + // Look up the enum to get its tsFullPath + for skeleton in exportedSkeletons { + for enumDef in skeleton.enums { + if enumDef.name == name || enumDef.swiftCallName == name { + // Use the stored tsFullPath which has the full namespace + switch type { + case .caseEnum: + return "\(enumDef.tsFullPath)Tag" + case .rawValueEnum: + return "\(enumDef.tsFullPath)Tag" + case .associatedValueEnum: + return "\(enumDef.tsFullPath)Tag" + case .namespaceEnum: + return enumDef.tsFullPath + default: + return type.tsType + } + } + } + } + return type.tsType + case .optional(let wrapped): + return "\(resolveTypeScriptType(wrapped, exportedSkeletons: exportedSkeletons)) | null" + default: + return type.tsType + } + } + private func renderTSSignature(parameters: [Parameter], returnType: BridgeType, effects: Effects) -> String { let returnTypeWithEffect: String if effects.isAsync { - returnTypeWithEffect = "Promise<\(returnType.tsType)>" + returnTypeWithEffect = "Promise<\(resolveTypeScriptType(returnType))>" } else { - returnTypeWithEffect = returnType.tsType + returnTypeWithEffect = resolveTypeScriptType(returnType) } let parameterSignatures = parameters.map { param in let optional = param.hasDefault ? "?" : "" - return "\(param.name)\(optional): \(param.type.tsType)" + return "\(param.name)\(optional): \(resolveTypeScriptType(param.type))" } return "(\(parameterSignatures.joined(separator: ", "))): \(returnTypeWithEffect)" } @@ -2179,12 +2243,18 @@ extension BridgeJSLink { ) } - func buildNamespaceInitialization(exportedSkeletons: [ExportedSkeleton]) -> [String] { + func buildNamespaceInitialization(exportedSkeletons: [ExportedSkeleton], exposeToGlobal: Bool) -> [String] { + guard exposeToGlobal else { return [] } let allNamespacePaths = collectAllNamespacePaths(exportedSkeletons: exportedSkeletons) return generateNamespaceInitializationCode(namespacePaths: allNamespacePaths) } - func buildTopLevelNamespaceInitialization(exportedSkeletons: [ExportedSkeleton]) -> [String] { + func buildTopLevelNamespaceInitialization( + exportedSkeletons: [ExportedSkeleton], + exposeToGlobal: Bool + ) -> [String] { + guard exposeToGlobal else { return [] } + var namespacedEnumPaths: Set<[String]> = [] for skeleton in exportedSkeletons { for enumDef in skeleton.enums where enumDef.namespace != nil && enumDef.enumType != .namespace { @@ -2408,6 +2478,7 @@ extension BridgeJSLink { fileprivate func buildHierarchicalExportsObject( exportedSkeletons: [ExportedSkeleton], + exposeToGlobal: Bool, renderFunctionImpl: (ExportedFunction) throws -> [String] ) throws -> [String] { let printer = CodeFragmentPrinter() @@ -2575,6 +2646,7 @@ extension BridgeJSLink { /// - Returns: Array of TypeScript declaration lines defining the global namespace structure func namespaceDeclarations( exportedSkeletons: [ExportedSkeleton], + exposeToGlobal: Bool, renderTSSignatureCallback: @escaping ([Parameter], BridgeType, Effects) -> String ) -> [String] { let printer = CodeFragmentPrinter() @@ -2585,38 +2657,76 @@ extension BridgeJSLink { guard !rootNode.children.isEmpty else { return printer.lines } - printer.write("export {};") - printer.nextLine() - printer.write("declare global {") - printer.indent() + + if exposeToGlobal { + printer.write("export {};") + printer.nextLine() + printer.write("declare global {") + printer.indent() + } + + func hasContent(node: NamespaceNode) -> Bool { + // Enums are always included + if !node.content.enums.isEmpty { + return true + } + + // When exposeToGlobal is true, classes, functions, and properties are included + if exposeToGlobal { + if !node.content.classes.isEmpty || !node.content.functions.isEmpty + || !node.content.staticProperties.isEmpty + { + return true + } + } + + // Check if any child has content + for (_, childNode) in node.children { + if hasContent(node: childNode) { + return true + } + } + + return false + } func generateNamespaceDeclarations(node: NamespaceNode, depth: Int) { let sortedChildren = node.children.sorted { $0.key < $1.key } for (childName, childNode) in sortedChildren { - printer.write("namespace \(childName) {") + // Skip empty namespaces + guard hasContent(node: childNode) else { + continue + } + + let exportKeyword = exposeToGlobal ? "" : "export " + printer.write("\(exportKeyword)namespace \(childName) {") printer.indent() - let sortedClasses = childNode.content.classes.sorted { $0.name < $1.name } - for klass in sortedClasses { - printer.write("class \(klass.name) {") - printer.indent { - if let constructor = klass.constructor { - let constructorSignature = - "constructor(\(constructor.parameters.map { "\($0.name): \($0.type.tsType)" }.joined(separator: ", ")));" - printer.write(constructorSignature) - } + // Only include classes when exposeToGlobal is true + if exposeToGlobal { + let sortedClasses = childNode.content.classes.sorted { $0.name < $1.name } + for klass in sortedClasses { + printer.write("class \(klass.name) {") + printer.indent { + if let constructor = klass.constructor { + let constructorSignature = + "constructor(\(constructor.parameters.map { "\($0.name): \($0.type.tsType)" }.joined(separator: ", ")));" + printer.write(constructorSignature) + } - let sortedMethods = klass.methods.sorted { $0.name < $1.name } - for method in sortedMethods { - let methodSignature = - "\(method.name)\(renderTSSignatureCallback(method.parameters, method.returnType, method.effects));" - printer.write(methodSignature) + let sortedMethods = klass.methods.sorted { $0.name < $1.name } + for method in sortedMethods { + let methodSignature = + "\(method.name)\(renderTSSignatureCallback(method.parameters, method.returnType, method.effects));" + printer.write(methodSignature) + } } + printer.write("}") } - printer.write("}") } + // Generate enum definitions within declare global namespace let sortedEnums = childNode.content.enums.sorted { $0.name < $1.name } for enumDefinition in sortedEnums { let style: EnumEmitStyle = enumDefinition.emitStyle @@ -2721,16 +2831,19 @@ extension BridgeJSLink { } } - let sortedFunctions = childNode.content.functions.sorted { $0.name < $1.name } - for function in sortedFunctions { - let signature = - "\(function.name)\(renderTSSignatureCallback(function.parameters, function.returnType, function.effects));" - printer.write(signature) - } - let sortedProperties = childNode.content.staticProperties.sorted { $0.name < $1.name } - for property in sortedProperties { - let readonly = property.isReadonly ? "var " : "let " - printer.write("\(readonly)\(property.name): \(property.type.tsType);") + // Only include functions and properties when exposeToGlobal is true + if exposeToGlobal { + let sortedFunctions = childNode.content.functions.sorted { $0.name < $1.name } + for function in sortedFunctions { + let signature = + "\(function.name)\(renderTSSignatureCallback(function.parameters, function.returnType, function.effects));" + printer.write(signature) + } + let sortedProperties = childNode.content.staticProperties.sorted { $0.name < $1.name } + for property in sortedProperties { + let readonly = property.isReadonly ? "var " : "let " + printer.write("\(readonly)\(property.name): \(property.type.tsType);") + } } generateNamespaceDeclarations(node: childNode, depth: depth + 1) @@ -2742,9 +2855,11 @@ extension BridgeJSLink { generateNamespaceDeclarations(node: rootNode, depth: 1) - printer.unindent() - printer.write("}") - printer.nextLine() + if exposeToGlobal { + printer.unindent() + printer.write("}") + printer.nextLine() + } return printer.lines } diff --git a/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift b/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift index 1b59ddfc..a862f3c3 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift @@ -265,6 +265,7 @@ public struct ExportedEnum: Codable, Equatable, Sendable { public let name: String public let swiftCallName: String + public let tsFullPath: String public let explicitAccessControl: String? public var cases: [EnumCase] public let rawType: SwiftEnumRawType? @@ -293,6 +294,7 @@ public struct ExportedEnum: Codable, Equatable, Sendable { public init( name: String, swiftCallName: String, + tsFullPath: String, explicitAccessControl: String?, cases: [EnumCase], rawType: SwiftEnumRawType?, @@ -303,6 +305,7 @@ public struct ExportedEnum: Codable, Equatable, Sendable { ) { self.name = name self.swiftCallName = swiftCallName + self.tsFullPath = tsFullPath self.explicitAccessControl = explicitAccessControl self.cases = cases self.rawType = rawType diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift index 37edf830..b837451d 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift @@ -55,7 +55,7 @@ import Testing let encoder = JSONEncoder() encoder.outputFormatting = [.prettyPrinted, .sortedKeys] let outputSkeletonData = try encoder.encode(outputSkeleton) - var bridgeJSLink = BridgeJSLink(sharedMemory: false) + var bridgeJSLink = BridgeJSLink(sharedMemory: false, exposeToGlobal: true) try bridgeJSLink.addExportedSkeletonFile(data: outputSkeletonData) try snapshot(bridgeJSLink: bridgeJSLink, name: name + ".Export") } @@ -74,8 +74,54 @@ import Testing encoder.outputFormatting = [.prettyPrinted, .sortedKeys] let outputSkeletonData = try encoder.encode(importTS.skeleton) - var bridgeJSLink = BridgeJSLink(sharedMemory: false) + var bridgeJSLink = BridgeJSLink(sharedMemory: false, exposeToGlobal: true) try bridgeJSLink.addImportedSkeletonFile(data: outputSkeletonData) try snapshot(bridgeJSLink: bridgeJSLink, name: name + ".Import") } + + @Test(arguments: [ + "Namespaces.swift", + "StaticFunctions.swift", + "StaticProperties.swift", + "EnumNamespace.swift" + ]) + func testWithoutGlobal(inputFile: String) throws { + let url = Self.inputsDirectory.appendingPathComponent(inputFile) + let sourceFile = Parser.parse(source: try String(contentsOf: url, encoding: .utf8)) + let swiftAPI = ExportSwift(progress: .silent, moduleName: "TestModule") + try swiftAPI.addSourceFile(sourceFile, inputFile) + + let (_, outputSkeleton) = try #require(try swiftAPI.finalize()) + let encoder = JSONEncoder() + encoder.outputFormatting = [.prettyPrinted, .sortedKeys] + let outputSkeletonData = try encoder.encode(outputSkeleton) + + var bridgeJSLink = BridgeJSLink(sharedMemory: false, exposeToGlobal: false) + try bridgeJSLink.addExportedSkeletonFile(data: outputSkeletonData) + + let (outputJs, outputDts) = try bridgeJSLink.link() + + // Verify no global declarations + #expect(!outputDts.contains("declare global")) + #expect(!outputJs.contains("globalThis.")) + + // Save snapshots + let name = url.deletingPathExtension().lastPathComponent + "_NoGlobal.Export" + try assertSnapshot( + name: name, + filePath: #filePath, + function: #function, + sourceLocation: #_sourceLocation, + input: outputJs.data(using: .utf8)!, + fileExtension: "js" + ) + try assertSnapshot( + name: name, + filePath: #filePath, + function: #function, + sourceLocation: #_sourceLocation, + input: outputDts.data(using: .utf8)!, + fileExtension: "d.ts" + ) + } } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts index e79f4119..5523b89e 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts @@ -47,9 +47,9 @@ export type APIResultObject = typeof APIResultValues; export type ComplexResultObject = typeof ComplexResultValues; -export type ResultObject = typeof ResultValues; +export type ResultObject = typeof Utilities.ResultValues; -export type NetworkingResultObject = typeof NetworkingResultValues; +export type NetworkingResultObject = typeof API.NetworkingResultValues; export type APIOptionalResultObject = typeof APIOptionalResultValues; @@ -89,7 +89,7 @@ export type Exports = { roundtripComplexResult(result: ComplexResultTag): ComplexResultTag; roundTripOptionalComplexResult(result: ComplexResultTag | null): ComplexResultTag | null; roundTripOptionalUtilitiesResult(result: Utilities.ResultTag | null): Utilities.ResultTag | null; - roundTripOptionalNetworkingResult(result: NetworkingResultTag | null): NetworkingResultTag | null; + roundTripOptionalNetworkingResult(result: API.NetworkingResultTag | null): API.NetworkingResultTag | null; roundTripOptionalAPIOptionalResult(result: APIOptionalResultTag | null): APIOptionalResultTag | null; APIResult: APIResultObject ComplexResult: ComplexResultObject 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 b7c1549a..4261ca3b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.d.ts @@ -4,13 +4,13 @@ // To update this file, just rebuild your project or run // `swift package bridge-js`. -export type MethodObject = typeof MethodValues; +export type MethodObject = typeof Networking.API.MethodValues; -export type LogLevelObject = typeof LogLevelValues; +export type LogLevelObject = typeof Configuration.LogLevelValues; -export type PortObject = typeof PortValues; +export type PortObject = typeof Configuration.PortValues; -export type SupportedMethodObject = typeof SupportedMethodValues; +export type SupportedMethodObject = typeof Networking.APIV2.Internal.SupportedMethodValues; export {}; @@ -48,7 +48,7 @@ declare global { namespace Internal { class TestServer { constructor(); - call(method: Internal.SupportedMethodTag): void; + call(method: Networking.APIV2.Internal.SupportedMethodTag): void; } const SupportedMethodValues: { readonly Get: 0; @@ -80,7 +80,7 @@ export interface HTTPServer extends SwiftHeapObject { call(method: Networking.API.MethodTag): void; } export interface TestServer extends SwiftHeapObject { - call(method: Internal.SupportedMethodTag): void; + call(method: Networking.APIV2.Internal.SupportedMethodTag): void; } export type Exports = { Configuration: { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace_NoGlobal.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace_NoGlobal.Export.d.ts new file mode 100644 index 00000000..b8b92d14 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace_NoGlobal.Export.d.ts @@ -0,0 +1,101 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +export type MethodObject = typeof Networking.API.MethodValues; + +export type LogLevelObject = typeof Configuration.LogLevelValues; + +export type PortObject = typeof Configuration.PortValues; + +export type SupportedMethodObject = typeof Networking.APIV2.Internal.SupportedMethodValues; + +export namespace Configuration { + const LogLevelValues: { + readonly Debug: "debug"; + readonly Info: "info"; + readonly Warning: "warning"; + readonly Error: "error"; + }; + type LogLevelTag = typeof LogLevelValues[keyof typeof LogLevelValues]; + const PortValues: { + readonly Http: 80; + readonly Https: 443; + readonly Development: 3000; + }; + type PortTag = typeof PortValues[keyof typeof PortValues]; +} +export namespace Networking { + export namespace API { + const MethodValues: { + readonly Get: 0; + readonly Post: 1; + readonly Put: 2; + readonly Delete: 3; + }; + type MethodTag = typeof MethodValues[keyof typeof MethodValues]; + } + export namespace APIV2 { + export namespace Internal { + const SupportedMethodValues: { + readonly Get: 0; + readonly Post: 1; + }; + type SupportedMethodTag = typeof SupportedMethodValues[keyof typeof SupportedMethodValues]; + } + } +} +/// 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 Converter extends SwiftHeapObject { + toString(value: number): string; +} +export interface HTTPServer extends SwiftHeapObject { + call(method: Networking.API.MethodTag): void; +} +export interface TestServer extends SwiftHeapObject { + call(method: Networking.APIV2.Internal.SupportedMethodTag): void; +} +export type Exports = { + Configuration: { + LogLevel: LogLevelObject + Port: PortObject + }, + Networking: { + API: { + HTTPServer: { + new(): HTTPServer; + } + Method: MethodObject + }, + APIV2: { + Internal: { + TestServer: { + new(): TestServer; + } + SupportedMethod: SupportedMethodObject + }, + }, + }, + Utils: { + Converter: { + new(): Converter; + } + }, +} +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/EnumNamespace_NoGlobal.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace_NoGlobal.Export.js new file mode 100644 index 00000000..9fed226d --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace_NoGlobal.Export.js @@ -0,0 +1,323 @@ +// 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 MethodValues = { + Get: 0, + Post: 1, + Put: 2, + Delete: 3, +}; + +export const LogLevelValues = { + Debug: "debug", + Info: "info", + Warning: "warning", + Error: "error", +}; + +export const PortValues = { + Http: 80, + Https: 443, + Development: 3000, +}; + +export const SupportedMethodValues = { + Get: 0, + Post: 1, +}; + +export async function createInstantiator(options, swift) { + let instance; + let memory; + let setException; + const textDecoder = new TextDecoder("utf-8"); + const textEncoder = new TextEncoder("utf-8"); + let tmpRetString; + let tmpRetBytes; + let tmpRetException; + let tmpRetOptionalBool; + let tmpRetOptionalInt; + let tmpRetOptionalFloat; + let tmpRetOptionalDouble; + let tmpRetOptionalHeapObject; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; + + let _exports = null; + let bjs = null; + + 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) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + tmpRetString = textDecoder.decode(bytes); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + return swift.memory.retain(textDecoder.decode(bytes)); + } + bjs["swift_js_init_memory_with_result"] = function(ptr, len) { + const target = new Uint8Array(memory.buffer, ptr, len); + target.set(tmpRetBytes); + tmpRetBytes = undefined; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; + } + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); + } + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); + } + bjs["swift_js_push_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); + } + bjs["swift_js_return_optional_bool"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalBool = null; + } else { + tmpRetOptionalBool = value !== 0; + } + } + bjs["swift_js_return_optional_int"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalInt = null; + } else { + tmpRetOptionalInt = value | 0; + } + } + bjs["swift_js_return_optional_float"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalFloat = null; + } else { + tmpRetOptionalFloat = Math.fround(value); + } + } + bjs["swift_js_return_optional_double"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalDouble = null; + } else { + tmpRetOptionalDouble = value; + } + } + bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) { + if (isSome === 0) { + tmpRetString = null; + } else { + const bytes = new Uint8Array(memory.buffer, ptr, len); + tmpRetString = textDecoder.decode(bytes); + } + } + 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; + } + // Wrapper functions for module: TestModule + if (!importObject["TestModule"]) { + importObject["TestModule"] = {}; + } + importObject["TestModule"]["bjs_Converter_wrap"] = function(pointer) { + const obj = Converter.__construct(pointer); + return swift.memory.retain(obj); + }; + importObject["TestModule"]["bjs_HTTPServer_wrap"] = function(pointer) { + const obj = HTTPServer.__construct(pointer); + return swift.memory.retain(obj); + }; + importObject["TestModule"]["bjs_TestServer_wrap"] = function(pointer) { + const obj = TestServer.__construct(pointer); + return swift.memory.retain(obj); + }; + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + /// Represents a Swift heap object like a class instance or an actor instance. + class SwiftHeapObject { + static __wrap(pointer, deinit, prototype) { + const obj = Object.create(prototype); + obj.pointer = pointer; + obj.hasReleased = false; + obj.deinit = deinit; + obj.registry = new FinalizationRegistry((pointer) => { + deinit(pointer); + }); + obj.registry.register(this, obj.pointer); + return obj; + } + + release() { + this.registry.unregister(this); + this.deinit(this.pointer); + } + } + class Converter extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Converter_deinit, Converter.prototype); + } + + constructor() { + const ret = instance.exports.bjs_Converter_init(); + return Converter.__construct(ret); + } + toString(value) { + instance.exports.bjs_Converter_toString(this.pointer, value); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + } + } + class HTTPServer extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_HTTPServer_deinit, HTTPServer.prototype); + } + + constructor() { + const ret = instance.exports.bjs_HTTPServer_init(); + return HTTPServer.__construct(ret); + } + call(method) { + instance.exports.bjs_HTTPServer_call(this.pointer, method); + } + } + class TestServer extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_TestServer_deinit, TestServer.prototype); + } + + constructor() { + const ret = instance.exports.bjs_TestServer_init(); + return TestServer.__construct(ret); + } + call(method) { + instance.exports.bjs_TestServer_call(this.pointer, method); + } + } + const exports = { + Configuration: { + LogLevel: LogLevelValues, + Port: PortValues, + }, + Networking: { + API: { + HTTPServer, + Method: MethodValues, + }, + APIV2: { + Internal: { + TestServer, + SupportedMethod: SupportedMethodValues, + }, + }, + }, + Utils: { + Converter, + }, + }; + _exports = exports; + return exports; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces_NoGlobal.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces_NoGlobal.Export.d.ts new file mode 100644 index 00000000..67a89533 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces_NoGlobal.Export.d.ts @@ -0,0 +1,55 @@ +// 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 Greeter extends SwiftHeapObject { + greet(): string; +} +export interface Converter extends SwiftHeapObject { + toString(value: number): string; +} +export interface UUID extends SwiftHeapObject { + uuidString(): string; +} +export type Exports = { + plainFunction(): string; + MyModule: { + Utils: { + namespacedFunction(): string; + }, + }, + Utils: { + Converters: { + Converter: { + new(): Converter; + } + }, + }, + __Swift: { + Foundation: { + Greeter: { + new(name: string): Greeter; + } + UUID: { + } + }, + }, +} +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/Namespaces_NoGlobal.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces_NoGlobal.Export.js new file mode 100644 index 00000000..08601bd5 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces_NoGlobal.Export.js @@ -0,0 +1,311 @@ +// 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; + 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 tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; + + let _exports = null; + let bjs = null; + + 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) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + tmpRetString = textDecoder.decode(bytes); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + return swift.memory.retain(textDecoder.decode(bytes)); + } + bjs["swift_js_init_memory_with_result"] = function(ptr, len) { + const target = new Uint8Array(memory.buffer, ptr, len); + target.set(tmpRetBytes); + tmpRetBytes = undefined; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; + } + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); + } + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); + } + bjs["swift_js_push_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); + } + bjs["swift_js_return_optional_bool"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalBool = null; + } else { + tmpRetOptionalBool = value !== 0; + } + } + bjs["swift_js_return_optional_int"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalInt = null; + } else { + tmpRetOptionalInt = value | 0; + } + } + bjs["swift_js_return_optional_float"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalFloat = null; + } else { + tmpRetOptionalFloat = Math.fround(value); + } + } + bjs["swift_js_return_optional_double"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalDouble = null; + } else { + tmpRetOptionalDouble = value; + } + } + bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) { + if (isSome === 0) { + tmpRetString = null; + } else { + const bytes = new Uint8Array(memory.buffer, ptr, len); + tmpRetString = textDecoder.decode(bytes); + } + } + 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; + } + // Wrapper functions for module: TestModule + if (!importObject["TestModule"]) { + importObject["TestModule"] = {}; + } + importObject["TestModule"]["bjs_Greeter_wrap"] = function(pointer) { + const obj = Greeter.__construct(pointer); + return swift.memory.retain(obj); + }; + importObject["TestModule"]["bjs_Converter_wrap"] = function(pointer) { + const obj = Converter.__construct(pointer); + return swift.memory.retain(obj); + }; + importObject["TestModule"]["bjs_UUID_wrap"] = function(pointer) { + const obj = UUID.__construct(pointer); + return swift.memory.retain(obj); + }; + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + /// Represents a Swift heap object like a class instance or an actor instance. + class SwiftHeapObject { + static __wrap(pointer, deinit, prototype) { + const obj = Object.create(prototype); + obj.pointer = pointer; + obj.hasReleased = false; + obj.deinit = deinit; + obj.registry = new FinalizationRegistry((pointer) => { + deinit(pointer); + }); + obj.registry.register(this, obj.pointer); + return obj; + } + + release() { + this.registry.unregister(this); + this.deinit(this.pointer); + } + } + class Greeter extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Greeter_deinit, Greeter.prototype); + } + + constructor(name) { + const nameBytes = textEncoder.encode(name); + const nameId = swift.memory.retain(nameBytes); + const ret = instance.exports.bjs_Greeter_init(nameId, nameBytes.length); + swift.memory.release(nameId); + return Greeter.__construct(ret); + } + greet() { + instance.exports.bjs_Greeter_greet(this.pointer); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + } + } + class Converter extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_Converter_deinit, Converter.prototype); + } + + constructor() { + const ret = instance.exports.bjs_Converter_init(); + return Converter.__construct(ret); + } + toString(value) { + instance.exports.bjs_Converter_toString(this.pointer, value); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + } + } + class UUID extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_UUID_deinit, UUID.prototype); + } + + uuidString() { + instance.exports.bjs_UUID_uuidString(this.pointer); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + } + } + const exports = { + plainFunction: function bjs_plainFunction() { + instance.exports.bjs_plainFunction(); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + MyModule: { + Utils: { + namespacedFunction: function bjs_MyModule_Utils_namespacedFunction() { + instance.exports.bjs_MyModule_Utils_namespacedFunction(); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + }, + }, + Utils: { + Converters: { + Converter, + }, + }, + __Swift: { + Foundation: { + Greeter, + UUID, + }, + }, + }; + _exports = exports; + return exports; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions_NoGlobal.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions_NoGlobal.Export.d.ts new file mode 100644 index 00000000..e938ddb9 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions_NoGlobal.Export.d.ts @@ -0,0 +1,63 @@ +// 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 CalculatorValues: { + readonly Scientific: 0; + readonly Basic: 1; +}; +export type CalculatorTag = typeof CalculatorValues[keyof typeof CalculatorValues]; + +export const APIResultValues: { + readonly Tag: { + readonly Success: 0; + readonly Failure: 1; + }; +}; + +export type APIResultTag = + { tag: typeof APIResultValues.Tag.Success; param0: string } | { tag: typeof APIResultValues.Tag.Failure; param0: number } + +export type CalculatorObject = typeof CalculatorValues & { + square(value: number): number; +}; + +export type APIResultObject = typeof APIResultValues & { + roundtrip(value: APIResultTag): APIResultTag; +}; + +/// 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 MathUtils extends SwiftHeapObject { + multiply(x: number, y: number): number; +} +export type Exports = { + MathUtils: { + new(): MathUtils; + subtract(a: number, b: number): number; + add(a: number, b: number): number; + } + Calculator: CalculatorObject + APIResult: APIResultObject + Utils: { + String: { + uppercase(text: string): string; + }, + }, +} +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/StaticFunctions_NoGlobal.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions_NoGlobal.Export.js new file mode 100644 index 00000000..8522168f --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions_NoGlobal.Export.js @@ -0,0 +1,337 @@ +// 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 CalculatorValues = { + Scientific: 0, + Basic: 1, +}; + +export const APIResultValues = { + Tag: { + Success: 0, + Failure: 1, + }, +}; + +const __bjs_createAPIResultValuesHelpers = () => { + return (tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case APIResultValues.Tag.Success: { + const bytes = textEncoder.encode(value.param0); + const id = swift.memory.retain(bytes); + tmpParamInts.push(bytes.length); + tmpParamInts.push(id); + const cleanup = () => { + swift.memory.release(id); + }; + return { caseId: APIResultValues.Tag.Success, cleanup }; + } + case APIResultValues.Tag.Failure: { + tmpParamInts.push((value.param0 | 0)); + const cleanup = undefined; + return { caseId: APIResultValues.Tag.Failure, cleanup }; + } + default: throw new Error("Unknown APIResultValues tag: " + String(enumTag)); + } + }, + raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s) => { + const tag = tmpRetTag | 0; + switch (tag) { + case APIResultValues.Tag.Success: { + const string = tmpRetStrings.pop(); + return { tag: APIResultValues.Tag.Success, param0: string }; + } + case APIResultValues.Tag.Failure: { + const int = tmpRetInts.pop(); + return { tag: APIResultValues.Tag.Failure, param0: int }; + } + default: throw new Error("Unknown APIResultValues tag returned from Swift: " + String(tag)); + } + } + }); +}; +export async function createInstantiator(options, swift) { + let instance; + let memory; + let setException; + const textDecoder = new TextDecoder("utf-8"); + const textEncoder = new TextEncoder("utf-8"); + let tmpRetString; + let tmpRetBytes; + let tmpRetException; + let tmpRetOptionalBool; + let tmpRetOptionalInt; + let tmpRetOptionalFloat; + let tmpRetOptionalDouble; + let tmpRetOptionalHeapObject; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; + const enumHelpers = {}; + + let _exports = null; + let bjs = null; + + 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) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + tmpRetString = textDecoder.decode(bytes); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + return swift.memory.retain(textDecoder.decode(bytes)); + } + bjs["swift_js_init_memory_with_result"] = function(ptr, len) { + const target = new Uint8Array(memory.buffer, ptr, len); + target.set(tmpRetBytes); + tmpRetBytes = undefined; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; + } + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); + } + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); + } + bjs["swift_js_push_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); + } + bjs["swift_js_return_optional_bool"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalBool = null; + } else { + tmpRetOptionalBool = value !== 0; + } + } + bjs["swift_js_return_optional_int"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalInt = null; + } else { + tmpRetOptionalInt = value | 0; + } + } + bjs["swift_js_return_optional_float"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalFloat = null; + } else { + tmpRetOptionalFloat = Math.fround(value); + } + } + bjs["swift_js_return_optional_double"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalDouble = null; + } else { + tmpRetOptionalDouble = value; + } + } + bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) { + if (isSome === 0) { + tmpRetString = null; + } else { + const bytes = new Uint8Array(memory.buffer, ptr, len); + tmpRetString = textDecoder.decode(bytes); + } + } + 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; + } + // Wrapper functions for module: TestModule + if (!importObject["TestModule"]) { + importObject["TestModule"] = {}; + } + importObject["TestModule"]["bjs_MathUtils_wrap"] = function(pointer) { + const obj = MathUtils.__construct(pointer); + return swift.memory.retain(obj); + }; + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + const APIResultHelpers = __bjs_createAPIResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift); + enumHelpers.APIResult = APIResultHelpers; + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + /// Represents a Swift heap object like a class instance or an actor instance. + class SwiftHeapObject { + static __wrap(pointer, deinit, prototype) { + const obj = Object.create(prototype); + obj.pointer = pointer; + obj.hasReleased = false; + obj.deinit = deinit; + obj.registry = new FinalizationRegistry((pointer) => { + deinit(pointer); + }); + obj.registry.register(this, obj.pointer); + return obj; + } + + release() { + this.registry.unregister(this); + this.deinit(this.pointer); + } + } + class MathUtils extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_MathUtils_deinit, MathUtils.prototype); + } + + constructor() { + const ret = instance.exports.bjs_MathUtils_init(); + return MathUtils.__construct(ret); + } + static subtract(a, b) { + const ret = instance.exports.bjs_MathUtils_static_subtract(a, b); + return ret; + } + static add(a, b) { + const ret = instance.exports.bjs_MathUtils_static_add(a, b); + return ret; + } + multiply(x, y) { + const ret = instance.exports.bjs_MathUtils_multiply(this.pointer, x, y); + return ret; + } + } + const exports = { + MathUtils, + Calculator: { + ...CalculatorValues, + square: function(value) { + const ret = instance.exports.bjs_Calculator_static_square(value); + return ret; + } + }, + APIResult: { + ...APIResultValues, + roundtrip: function(value) { + const { caseId: valueCaseId, cleanup: valueCleanup } = enumHelpers.APIResult.lower(value); + instance.exports.bjs_APIResult_static_roundtrip(valueCaseId); + const ret = enumHelpers.APIResult.raise(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + if (valueCleanup) { valueCleanup(); } + return ret; + } + }, + Utils: { + String: { + uppercase: function bjs_Utils_String_static_uppercase(text) { + const textBytes = textEncoder.encode(text); + const textId = swift.memory.retain(textBytes); + instance.exports.bjs_Utils_String_static_uppercase(textId, textBytes.length); + const ret = tmpRetString; + tmpRetString = undefined; + swift.memory.release(textId); + return ret; + }, + }, + }, + }; + _exports = exports; + return exports; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties_NoGlobal.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties_NoGlobal.Export.d.ts new file mode 100644 index 00000000..4ce689ed --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties_NoGlobal.Export.d.ts @@ -0,0 +1,58 @@ +// 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 PropertyEnumValues: { + readonly Value1: 0; + readonly Value2: 1; +}; +export type PropertyEnumTag = typeof PropertyEnumValues[keyof typeof PropertyEnumValues]; + +export type PropertyEnumObject = typeof PropertyEnumValues & { + enumProperty: string; + readonly enumConstant: number; + computedEnum: 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 PropertyClass extends SwiftHeapObject { +} +export type Exports = { + PropertyClass: { + new(): PropertyClass; + readonly staticConstant: string; + staticVariable: number; + jsObjectProperty: any; + classVariable: string; + computedProperty: string; + readonly readOnlyComputed: number; + optionalProperty: string | null; + } + PropertyEnum: PropertyEnumObject + PropertyNamespace: { + readonly namespaceConstant: string; + namespaceProperty: string; + Nested: { + readonly nestedConstant: string; + nestedDouble: number; + nestedProperty: 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/StaticProperties_NoGlobal.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties_NoGlobal.Export.js new file mode 100644 index 00000000..5d70c39b --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties_NoGlobal.Export.js @@ -0,0 +1,386 @@ +// 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 PropertyEnumValues = { + Value1: 0, + Value2: 1, +}; + +export async function createInstantiator(options, swift) { + let instance; + let memory; + let setException; + const textDecoder = new TextDecoder("utf-8"); + const textEncoder = new TextEncoder("utf-8"); + let tmpRetString; + let tmpRetBytes; + let tmpRetException; + let tmpRetOptionalBool; + let tmpRetOptionalInt; + let tmpRetOptionalFloat; + let tmpRetOptionalDouble; + let tmpRetOptionalHeapObject; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; + + let _exports = null; + let bjs = null; + + 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) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + tmpRetString = textDecoder.decode(bytes); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + return swift.memory.retain(textDecoder.decode(bytes)); + } + bjs["swift_js_init_memory_with_result"] = function(ptr, len) { + const target = new Uint8Array(memory.buffer, ptr, len); + target.set(tmpRetBytes); + tmpRetBytes = undefined; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; + } + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); + } + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); + } + bjs["swift_js_push_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); + } + bjs["swift_js_return_optional_bool"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalBool = null; + } else { + tmpRetOptionalBool = value !== 0; + } + } + bjs["swift_js_return_optional_int"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalInt = null; + } else { + tmpRetOptionalInt = value | 0; + } + } + bjs["swift_js_return_optional_float"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalFloat = null; + } else { + tmpRetOptionalFloat = Math.fround(value); + } + } + bjs["swift_js_return_optional_double"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalDouble = null; + } else { + tmpRetOptionalDouble = value; + } + } + bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) { + if (isSome === 0) { + tmpRetString = null; + } else { + const bytes = new Uint8Array(memory.buffer, ptr, len); + tmpRetString = textDecoder.decode(bytes); + } + } + 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; + } + // Wrapper functions for module: TestModule + if (!importObject["TestModule"]) { + importObject["TestModule"] = {}; + } + importObject["TestModule"]["bjs_PropertyClass_wrap"] = function(pointer) { + const obj = PropertyClass.__construct(pointer); + return swift.memory.retain(obj); + }; + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + /// Represents a Swift heap object like a class instance or an actor instance. + class SwiftHeapObject { + static __wrap(pointer, deinit, prototype) { + const obj = Object.create(prototype); + obj.pointer = pointer; + obj.hasReleased = false; + obj.deinit = deinit; + obj.registry = new FinalizationRegistry((pointer) => { + deinit(pointer); + }); + obj.registry.register(this, obj.pointer); + return obj; + } + + release() { + this.registry.unregister(this); + this.deinit(this.pointer); + } + } + class PropertyClass extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_PropertyClass_deinit, PropertyClass.prototype); + } + + constructor() { + const ret = instance.exports.bjs_PropertyClass_init(); + return PropertyClass.__construct(ret); + } + static get staticConstant() { + instance.exports.bjs_PropertyClass_static_staticConstant_get(); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + } + static get staticVariable() { + const ret = instance.exports.bjs_PropertyClass_static_staticVariable_get(); + return ret; + } + static set staticVariable(value) { + instance.exports.bjs_PropertyClass_static_staticVariable_set(value); + } + static get jsObjectProperty() { + const ret = instance.exports.bjs_PropertyClass_static_jsObjectProperty_get(); + const ret1 = swift.memory.getObject(ret); + swift.memory.release(ret); + return ret1; + } + static set jsObjectProperty(value) { + instance.exports.bjs_PropertyClass_static_jsObjectProperty_set(swift.memory.retain(value)); + } + static get classVariable() { + instance.exports.bjs_PropertyClass_static_classVariable_get(); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + } + static set classVariable(value) { + const valueBytes = textEncoder.encode(value); + const valueId = swift.memory.retain(valueBytes); + instance.exports.bjs_PropertyClass_static_classVariable_set(valueId, valueBytes.length); + swift.memory.release(valueId); + } + static get computedProperty() { + instance.exports.bjs_PropertyClass_static_computedProperty_get(); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + } + static set computedProperty(value) { + const valueBytes = textEncoder.encode(value); + const valueId = swift.memory.retain(valueBytes); + instance.exports.bjs_PropertyClass_static_computedProperty_set(valueId, valueBytes.length); + swift.memory.release(valueId); + } + static get readOnlyComputed() { + const ret = instance.exports.bjs_PropertyClass_static_readOnlyComputed_get(); + return ret; + } + static get optionalProperty() { + instance.exports.bjs_PropertyClass_static_optionalProperty_get(); + const optResult = tmpRetString; + tmpRetString = undefined; + return optResult; + } + static set optionalProperty(value) { + const isSome = value != null; + let valueId, valueBytes; + if (isSome) { + valueBytes = textEncoder.encode(value); + valueId = swift.memory.retain(valueBytes); + } + instance.exports.bjs_PropertyClass_static_optionalProperty_set(+isSome, isSome ? valueId : 0, isSome ? valueBytes.length : 0); + if (valueId != undefined) { + swift.memory.release(valueId); + } + } + } + const exports = { + PropertyClass, + PropertyEnum: { + ...PropertyEnumValues, + get enumProperty() { + instance.exports.bjs_PropertyEnum_static_enumProperty_get(); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + set enumProperty(value) { + const valueBytes = textEncoder.encode(value); + const valueId = swift.memory.retain(valueBytes); + instance.exports.bjs_PropertyEnum_static_enumProperty_set(valueId, valueBytes.length); + swift.memory.release(valueId); + }, + get enumConstant() { + const ret = instance.exports.bjs_PropertyEnum_static_enumConstant_get(); + return ret; + }, + get computedEnum() { + instance.exports.bjs_PropertyEnum_static_computedEnum_get(); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + set computedEnum(value) { + const valueBytes = textEncoder.encode(value); + const valueId = swift.memory.retain(valueBytes); + instance.exports.bjs_PropertyEnum_static_computedEnum_set(valueId, valueBytes.length); + swift.memory.release(valueId); + } + }, + PropertyNamespace: { + get namespaceProperty() { + instance.exports.bjs_PropertyNamespace_static_namespaceProperty_get(); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + set namespaceProperty(value) { + const valueBytes = textEncoder.encode(value); + const valueId = swift.memory.retain(valueBytes); + instance.exports.bjs_PropertyNamespace_static_namespaceProperty_set(valueId, valueBytes.length); + swift.memory.release(valueId); + }, + get namespaceConstant() { + instance.exports.bjs_PropertyNamespace_static_namespaceConstant_get(); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + Nested: { + get nestedProperty() { + const ret = instance.exports.bjs_PropertyNamespace_Nested_static_nestedProperty_get(); + return ret; + }, + set nestedProperty(value) { + instance.exports.bjs_PropertyNamespace_Nested_static_nestedProperty_set(value); + }, + get nestedConstant() { + instance.exports.bjs_PropertyNamespace_Nested_static_nestedConstant_get(); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + get nestedDouble() { + const ret = instance.exports.bjs_PropertyNamespace_Nested_static_nestedDouble_get(); + return ret; + }, + set nestedDouble(value) { + instance.exports.bjs_PropertyNamespace_Nested_static_nestedDouble_set(value); + }, + }, + }, + }; + _exports = exports; + return exports; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/DefaultParameters.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/DefaultParameters.json index 05d71b5f..98c09bef 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/DefaultParameters.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/DefaultParameters.json @@ -255,7 +255,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Status" + "swiftCallName" : "Status", + "tsFullPath" : "Status" } ], "functions" : [ diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json index c75e7d85..d2ab06d4 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json @@ -80,7 +80,8 @@ "staticProperties" : [ ], - "swiftCallName" : "APIResult" + "swiftCallName" : "APIResult", + "tsFullPath" : "APIResult" }, { "cases" : [ @@ -250,7 +251,8 @@ "staticProperties" : [ ], - "swiftCallName" : "ComplexResult" + "swiftCallName" : "ComplexResult", + "tsFullPath" : "ComplexResult" }, { "cases" : [ @@ -264,7 +266,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Utilities" + "swiftCallName" : "Utilities", + "tsFullPath" : "Utilities" }, { "cases" : [ @@ -337,7 +340,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Utilities.Result" + "swiftCallName" : "Utilities.Result", + "tsFullPath" : "Utilities.Result" }, { "cases" : [ @@ -384,7 +388,8 @@ "staticProperties" : [ ], - "swiftCallName" : "NetworkingResult" + "swiftCallName" : "NetworkingResult", + "tsFullPath" : "API.NetworkingResult" }, { "cases" : [ @@ -478,7 +483,8 @@ "staticProperties" : [ ], - "swiftCallName" : "APIOptionalResult" + "swiftCallName" : "APIOptionalResult", + "tsFullPath" : "APIOptionalResult" } ], "functions" : [ diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumCase.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumCase.json index 825b4105..3e738dd2 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumCase.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumCase.json @@ -38,7 +38,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Direction" + "swiftCallName" : "Direction", + "tsFullPath" : "Direction" }, { "cases" : [ @@ -69,7 +70,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Status" + "swiftCallName" : "Status", + "tsFullPath" : "Status" }, { "cases" : [ @@ -106,7 +108,8 @@ "staticProperties" : [ ], - "swiftCallName" : "TSDirection" + "swiftCallName" : "TSDirection", + "tsFullPath" : "TSDirection" }, { "cases" : [ @@ -126,7 +129,8 @@ "staticProperties" : [ ], - "swiftCallName" : "PublicStatus" + "swiftCallName" : "PublicStatus", + "tsFullPath" : "PublicStatus" } ], "functions" : [ diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.json index 0b94c1c5..1ba8279e 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.json @@ -173,7 +173,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Utils" + "swiftCallName" : "Utils", + "tsFullPath" : "Utils" }, { "cases" : [ @@ -187,7 +188,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Networking" + "swiftCallName" : "Networking", + "tsFullPath" : "Networking" }, { "cases" : [ @@ -204,7 +206,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Networking.API" + "swiftCallName" : "Networking.API", + "tsFullPath" : "Networking.API" }, { "cases" : [ @@ -245,7 +248,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Networking.API.Method" + "swiftCallName" : "Networking.API.Method", + "tsFullPath" : "Networking.API.Method" }, { "cases" : [ @@ -259,7 +263,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Configuration" + "swiftCallName" : "Configuration", + "tsFullPath" : "Configuration" }, { "cases" : [ @@ -304,7 +309,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Configuration.LogLevel" + "swiftCallName" : "Configuration.LogLevel", + "tsFullPath" : "Configuration.LogLevel" }, { "cases" : [ @@ -342,7 +348,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Configuration.Port" + "swiftCallName" : "Configuration.Port", + "tsFullPath" : "Configuration.Port" }, { "cases" : [ @@ -360,7 +367,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Internal" + "swiftCallName" : "Internal", + "tsFullPath" : "Networking.APIV2.Internal" }, { "cases" : [ @@ -390,7 +398,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Internal.SupportedMethod" + "swiftCallName" : "Internal.SupportedMethod", + "tsFullPath" : "Networking.APIV2.Internal.SupportedMethod" } ], "functions" : [ diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumRawType.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumRawType.json index b5da1726..30ec6a35 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumRawType.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumRawType.json @@ -36,7 +36,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Theme" + "swiftCallName" : "Theme", + "tsFullPath" : "Theme" }, { "cases" : [ @@ -71,7 +72,8 @@ "staticProperties" : [ ], - "swiftCallName" : "TSTheme" + "swiftCallName" : "TSTheme", + "tsFullPath" : "TSTheme" }, { "cases" : [ @@ -99,7 +101,8 @@ "staticProperties" : [ ], - "swiftCallName" : "FeatureFlag" + "swiftCallName" : "FeatureFlag", + "tsFullPath" : "FeatureFlag" }, { "cases" : [ @@ -134,7 +137,8 @@ "staticProperties" : [ ], - "swiftCallName" : "HttpStatus" + "swiftCallName" : "HttpStatus", + "tsFullPath" : "HttpStatus" }, { "cases" : [ @@ -169,7 +173,8 @@ "staticProperties" : [ ], - "swiftCallName" : "TSHttpStatus" + "swiftCallName" : "TSHttpStatus", + "tsFullPath" : "TSHttpStatus" }, { "cases" : [ @@ -218,7 +223,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Priority" + "swiftCallName" : "Priority", + "tsFullPath" : "Priority" }, { "cases" : [ @@ -260,7 +266,8 @@ "staticProperties" : [ ], - "swiftCallName" : "FileSize" + "swiftCallName" : "FileSize", + "tsFullPath" : "FileSize" }, { "cases" : [ @@ -295,7 +302,8 @@ "staticProperties" : [ ], - "swiftCallName" : "UserId" + "swiftCallName" : "UserId", + "tsFullPath" : "UserId" }, { "cases" : [ @@ -330,7 +338,8 @@ "staticProperties" : [ ], - "swiftCallName" : "TokenId" + "swiftCallName" : "TokenId", + "tsFullPath" : "TokenId" }, { "cases" : [ @@ -365,7 +374,8 @@ "staticProperties" : [ ], - "swiftCallName" : "SessionId" + "swiftCallName" : "SessionId", + "tsFullPath" : "SessionId" }, { "cases" : [ @@ -400,7 +410,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Precision" + "swiftCallName" : "Precision", + "tsFullPath" : "Precision" }, { "cases" : [ @@ -442,7 +453,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Ratio" + "swiftCallName" : "Ratio", + "tsFullPath" : "Ratio" } ], "functions" : [ diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Protocol.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Protocol.json index 46b96429..efda4d14 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Protocol.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Protocol.json @@ -285,7 +285,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Direction" + "swiftCallName" : "Direction", + "tsFullPath" : "Direction" }, { "cases" : [ @@ -313,7 +314,8 @@ "staticProperties" : [ ], - "swiftCallName" : "ExampleEnum" + "swiftCallName" : "ExampleEnum", + "tsFullPath" : "ExampleEnum" }, { "cases" : [ @@ -350,7 +352,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Result" + "swiftCallName" : "Result", + "tsFullPath" : "Result" }, { "cases" : [ @@ -385,7 +388,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Priority" + "swiftCallName" : "Priority", + "tsFullPath" : "Priority" } ], "functions" : [ diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.json index cbd0fa2b..705de937 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.json @@ -186,7 +186,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Calculator" + "swiftCallName" : "Calculator", + "tsFullPath" : "Calculator" }, { "cases" : [ @@ -252,7 +253,8 @@ "staticProperties" : [ ], - "swiftCallName" : "APIResult" + "swiftCallName" : "APIResult", + "tsFullPath" : "APIResult" }, { "cases" : [ @@ -266,7 +268,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Utils" + "swiftCallName" : "Utils", + "tsFullPath" : "Utils" }, { "cases" : [ @@ -316,7 +319,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Utils.String" + "swiftCallName" : "Utils.String", + "tsFullPath" : "Utils.String" } ], "functions" : [ diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.json index 63de88b9..1c5cdd6a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.json @@ -198,7 +198,8 @@ } } ], - "swiftCallName" : "PropertyEnum" + "swiftCallName" : "PropertyEnum", + "tsFullPath" : "PropertyEnum" }, { "cases" : [ @@ -247,7 +248,8 @@ } } ], - "swiftCallName" : "PropertyNamespace" + "swiftCallName" : "PropertyNamespace", + "tsFullPath" : "PropertyNamespace" }, { "cases" : [ @@ -320,7 +322,8 @@ } } ], - "swiftCallName" : "PropertyNamespace.Nested" + "swiftCallName" : "PropertyNamespace.Nested", + "tsFullPath" : "PropertyNamespace.Nested" } ], "functions" : [ diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClosure.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClosure.json index acb1c894..d6518fc6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClosure.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClosure.json @@ -899,7 +899,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Direction" + "swiftCallName" : "Direction", + "tsFullPath" : "Direction" }, { "cases" : [ @@ -934,7 +935,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Theme" + "swiftCallName" : "Theme", + "tsFullPath" : "Theme" }, { "cases" : [ @@ -976,7 +978,8 @@ "staticProperties" : [ ], - "swiftCallName" : "HttpStatus" + "swiftCallName" : "HttpStatus", + "tsFullPath" : "HttpStatus" }, { "cases" : [ @@ -1055,7 +1058,8 @@ "staticProperties" : [ ], - "swiftCallName" : "APIResult" + "swiftCallName" : "APIResult", + "tsFullPath" : "APIResult" } ], "functions" : [ diff --git a/Plugins/PackageToJS/Sources/PackageToJS.swift b/Plugins/PackageToJS/Sources/PackageToJS.swift index ec984043..9576c2b7 100644 --- a/Plugins/PackageToJS/Sources/PackageToJS.swift +++ b/Plugins/PackageToJS/Sources/PackageToJS.swift @@ -613,7 +613,8 @@ struct PackagingPlanner { let data = try Data(contentsOf: URL(fileURLWithPath: scope.resolve(path: $0).path)) return try decoder.decode(ImportedModuleSkeleton.self, from: data) }, - sharedMemory: Self.isSharedMemoryEnabled(triple: triple) + sharedMemory: Self.isSharedMemoryEnabled(triple: triple), + exposeToGlobal: true ) let (outputJs, outputDts) = try link.link() try system.writeFile(atPath: scope.resolve(path: bridgeJs).path, content: Data(outputJs.utf8)) diff --git a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json index c5ac3294..c1877ab3 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json +++ b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json @@ -3156,7 +3156,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Direction" + "swiftCallName" : "Direction", + "tsFullPath" : "Direction" }, { "cases" : [ @@ -3187,7 +3188,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Status" + "swiftCallName" : "Status", + "tsFullPath" : "Status" }, { "cases" : [ @@ -3222,7 +3224,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Theme" + "swiftCallName" : "Theme", + "tsFullPath" : "Theme" }, { "cases" : [ @@ -3264,7 +3267,8 @@ "staticProperties" : [ ], - "swiftCallName" : "HttpStatus" + "swiftCallName" : "HttpStatus", + "tsFullPath" : "HttpStatus" }, { "cases" : [ @@ -3301,7 +3305,8 @@ "staticProperties" : [ ], - "swiftCallName" : "TSDirection" + "swiftCallName" : "TSDirection", + "tsFullPath" : "TSDirection" }, { "cases" : [ @@ -3336,7 +3341,8 @@ "staticProperties" : [ ], - "swiftCallName" : "TSTheme" + "swiftCallName" : "TSTheme", + "tsFullPath" : "TSTheme" }, { "cases" : [ @@ -3350,7 +3356,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Utils" + "swiftCallName" : "Utils", + "tsFullPath" : "Utils" }, { "cases" : [ @@ -3364,7 +3371,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Networking" + "swiftCallName" : "Networking", + "tsFullPath" : "Networking" }, { "cases" : [ @@ -3381,7 +3389,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Networking.API" + "swiftCallName" : "Networking.API", + "tsFullPath" : "Networking.API" }, { "cases" : [ @@ -3422,7 +3431,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Networking.API.Method" + "swiftCallName" : "Networking.API.Method", + "tsFullPath" : "Networking.API.Method" }, { "cases" : [ @@ -3436,7 +3446,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Configuration" + "swiftCallName" : "Configuration", + "tsFullPath" : "Configuration" }, { "cases" : [ @@ -3481,7 +3492,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Configuration.LogLevel" + "swiftCallName" : "Configuration.LogLevel", + "tsFullPath" : "Configuration.LogLevel" }, { "cases" : [ @@ -3519,7 +3531,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Configuration.Port" + "swiftCallName" : "Configuration.Port", + "tsFullPath" : "Configuration.Port" }, { "cases" : [ @@ -3537,7 +3550,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Internal" + "swiftCallName" : "Internal", + "tsFullPath" : "Networking.APIV2.Internal" }, { "cases" : [ @@ -3567,7 +3581,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Internal.SupportedMethod" + "swiftCallName" : "Internal.SupportedMethod", + "tsFullPath" : "Networking.APIV2.Internal.SupportedMethod" }, { "cases" : [ @@ -3646,7 +3661,8 @@ "staticProperties" : [ ], - "swiftCallName" : "APIResult" + "swiftCallName" : "APIResult", + "tsFullPath" : "APIResult" }, { "cases" : [ @@ -3842,7 +3858,8 @@ "staticProperties" : [ ], - "swiftCallName" : "ComplexResult" + "swiftCallName" : "ComplexResult", + "tsFullPath" : "ComplexResult" }, { "cases" : [ @@ -3856,7 +3873,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Utilities" + "swiftCallName" : "Utilities", + "tsFullPath" : "Utilities" }, { "cases" : [ @@ -3929,7 +3947,8 @@ "staticProperties" : [ ], - "swiftCallName" : "Utilities.Result" + "swiftCallName" : "Utilities.Result", + "tsFullPath" : "Utilities.Result" }, { "cases" : [ @@ -3943,7 +3962,8 @@ "staticProperties" : [ ], - "swiftCallName" : "API" + "swiftCallName" : "API", + "tsFullPath" : "API" }, { "cases" : [ @@ -3990,7 +4010,8 @@ "staticProperties" : [ ], - "swiftCallName" : "API.NetworkingResult" + "swiftCallName" : "API.NetworkingResult", + "tsFullPath" : "API.NetworkingResult" }, { "cases" : [ @@ -4084,7 +4105,8 @@ "staticProperties" : [ ], - "swiftCallName" : "APIOptionalResult" + "swiftCallName" : "APIOptionalResult", + "tsFullPath" : "APIOptionalResult" }, { "cases" : [ @@ -4138,7 +4160,8 @@ "staticProperties" : [ ], - "swiftCallName" : "StaticCalculator" + "swiftCallName" : "StaticCalculator", + "tsFullPath" : "StaticCalculator" }, { "cases" : [ @@ -4152,7 +4175,8 @@ "staticProperties" : [ ], - "swiftCallName" : "StaticUtils" + "swiftCallName" : "StaticUtils", + "tsFullPath" : "StaticUtils" }, { "cases" : [ @@ -4202,7 +4226,8 @@ "staticProperties" : [ ], - "swiftCallName" : "StaticUtils.Nested" + "swiftCallName" : "StaticUtils.Nested", + "tsFullPath" : "StaticUtils.Nested" }, { "cases" : [ @@ -4316,7 +4341,8 @@ } } ], - "swiftCallName" : "StaticPropertyEnum" + "swiftCallName" : "StaticPropertyEnum", + "tsFullPath" : "StaticPropertyEnum" }, { "cases" : [ @@ -4365,7 +4391,8 @@ } } ], - "swiftCallName" : "StaticPropertyNamespace" + "swiftCallName" : "StaticPropertyNamespace", + "tsFullPath" : "StaticPropertyNamespace" }, { "cases" : [ @@ -4438,7 +4465,8 @@ } } ], - "swiftCallName" : "StaticPropertyNamespace.NestedProperties" + "swiftCallName" : "StaticPropertyNamespace.NestedProperties", + "tsFullPath" : "StaticPropertyNamespace.NestedProperties" } ], "functions" : [ From afe86fcc9f77e68a44c30eb48f7bc750758aac46 Mon Sep 17 00:00:00 2001 From: Krzysztof Rodak Date: Fri, 21 Nov 2025 12:16:45 +0200 Subject: [PATCH 2/4] BridgeJS: Global namespace configuration and tests --- .../JavaScript/BridgeJS.ExportSwift.json | 7 +- .../JavaScript/BridgeJS.ExportSwift.json | 1 + .../Sources/PlayBridgeJS/main.swift | 5 +- Makefile | 10 + .../BridgeJSBuildPlugin.swift | 2 + .../BridgeJSCommandPlugin.swift | 2 + .../Sources/BridgeJSCore/BridgeJSConfig.swift | 28 +- .../Sources/BridgeJSCore/ExportSwift.swift | 10 +- .../Sources/BridgeJSLink/BridgeJSLink.swift | 29 +- .../BridgeJSSkeleton/BridgeJSSkeleton.swift | 10 +- .../Sources/BridgeJSTool/BridgeJSTool.swift | 12 +- .../BridgeJSToolTests/BridgeJSLinkTests.swift | 51 +-- .../BridgeJSToolTests/ExportSwiftTests.swift | 17 +- .../EnumAssociatedValue.Export.d.ts | 41 +- .../EnumAssociatedValue.Export.js | 14 - .../EnumNamespace.Export.d.ts | 73 ++-- .../BridgeJSLinkTests/EnumNamespace.Export.js | 40 -- ....d.ts => EnumNamespace.Global.Export.d.ts} | 73 ++-- ...port.js => EnumNamespace.Global.Export.js} | 40 ++ .../BridgeJSLinkTests/Namespaces.Export.d.ts | 29 -- .../BridgeJSLinkTests/Namespaces.Export.js | 22 - ...ort.d.ts => Namespaces.Global.Export.d.ts} | 29 ++ ....Export.js => Namespaces.Global.Export.js} | 22 + .../StaticFunctions.Export.d.ts | 10 - .../StaticFunctions.Export.js | 7 - ....ts => StaticFunctions.Global.Export.d.ts} | 10 + ...rt.js => StaticFunctions.Global.Export.js} | 7 + .../StaticProperties.Export.d.ts | 14 - .../StaticProperties.Export.js | 24 - ...ts => StaticProperties.Global.Export.d.ts} | 14 + ...t.js => StaticProperties.Global.Export.js} | 24 + .../__Snapshots__/ExportSwiftTests/Async.json | 1 + .../ExportSwiftTests/DefaultParameters.json | 1 + .../ExportSwiftTests/EnumAssociatedValue.json | 1 + .../ExportSwiftTests/EnumCase.json | 1 + .../EnumNamespace.Global.json | 413 ++++++++++++++++++ .../EnumNamespace.Global.swift | 215 +++++++++ .../ExportSwiftTests/EnumNamespace.json | 1 + .../ExportSwiftTests/EnumRawType.json | 1 + .../ExportSwiftTests/Namespaces.Global.json | 180 ++++++++ .../ExportSwiftTests/Namespaces.Global.swift | 144 ++++++ .../ExportSwiftTests/Namespaces.json | 1 + .../ExportSwiftTests/Optionals.json | 1 + .../ExportSwiftTests/PrimitiveParameters.json | 1 + .../ExportSwiftTests/PrimitiveReturn.json | 1 + .../ExportSwiftTests/PropertyTypes.json | 1 + .../ExportSwiftTests/Protocol.json | 1 + .../StaticFunctions.Global.json | 334 ++++++++++++++ .../StaticFunctions.Global.swift | 192 ++++++++ .../ExportSwiftTests/StaticFunctions.json | 1 + .../StaticProperties.Global.json | 337 ++++++++++++++ .../StaticProperties.Global.swift | 338 ++++++++++++++ .../ExportSwiftTests/StaticProperties.json | 1 + .../ExportSwiftTests/StringParameter.json | 1 + .../ExportSwiftTests/StringReturn.json | 1 + .../ExportSwiftTests/SwiftClass.json | 1 + .../ExportSwiftTests/SwiftClosure.json | 1 + .../ExportSwiftTests/Throws.json | 1 + .../VoidParameterVoidReturn.json | 1 + Plugins/PackageToJS/Sources/PackageToJS.swift | 3 +- .../BridgeJS/BridgeJS-Configuration.md | 38 +- .../Exporting-Swift/Using-Namespace.md | 10 +- .../JavaScript/BridgeJS.ExportSwift.json | 1 + .../bridge-js.config.exposeToGlobal.json | 3 + .../bridge-js.config.json | 4 +- Tests/prelude.exposeToGlobal.mjs | 248 +++++++++++ Tests/prelude.mjs | 121 ++--- 67 files changed, 2863 insertions(+), 415 deletions(-) rename Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/{EnumNamespace_NoGlobal.Export.d.ts => EnumNamespace.Global.Export.d.ts} (57%) rename Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/{EnumNamespace_NoGlobal.Export.js => EnumNamespace.Global.Export.js} (87%) rename Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/{Namespaces_NoGlobal.Export.d.ts => Namespaces.Global.Export.d.ts} (70%) rename Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/{Namespaces_NoGlobal.Export.js => Namespaces.Global.Export.js} (91%) rename Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/{StaticFunctions_NoGlobal.Export.d.ts => StaticFunctions.Global.Export.d.ts} (92%) rename Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/{StaticFunctions_NoGlobal.Export.js => StaticFunctions.Global.Export.js} (97%) rename Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/{StaticProperties_NoGlobal.Export.d.ts => StaticProperties.Global.Export.d.ts} (85%) rename Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/{StaticProperties_NoGlobal.Export.js => StaticProperties.Global.Export.js} (92%) create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.json create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.swift create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.Global.json create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.Global.swift create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.Global.json create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.Global.swift create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.Global.json create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.Global.swift create mode 100644 Tests/BridgeJSRuntimeTests/bridge-js.config.exposeToGlobal.json create mode 100644 Tests/prelude.exposeToGlobal.mjs diff --git a/Benchmarks/Sources/Generated/JavaScript/BridgeJS.ExportSwift.json b/Benchmarks/Sources/Generated/JavaScript/BridgeJS.ExportSwift.json index cfec1d46..9094df26 100644 --- a/Benchmarks/Sources/Generated/JavaScript/BridgeJS.ExportSwift.json +++ b/Benchmarks/Sources/Generated/JavaScript/BridgeJS.ExportSwift.json @@ -502,7 +502,8 @@ "staticProperties" : [ ], - "swiftCallName" : "APIResult" + "swiftCallName" : "APIResult", + "tsFullPath" : "APIResult" }, { "cases" : [ @@ -698,9 +699,11 @@ "staticProperties" : [ ], - "swiftCallName" : "ComplexResult" + "swiftCallName" : "ComplexResult", + "tsFullPath" : "ComplexResult" } ], + "exposeToGlobal" : false, "functions" : [ { "abiName" : "bjs_run", diff --git a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/JavaScript/BridgeJS.ExportSwift.json b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/JavaScript/BridgeJS.ExportSwift.json index 3e00433e..f4897068 100644 --- a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/JavaScript/BridgeJS.ExportSwift.json +++ b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/JavaScript/BridgeJS.ExportSwift.json @@ -135,6 +135,7 @@ "enums" : [ ], + "exposeToGlobal" : false, "functions" : [ ], diff --git a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/main.swift b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/main.swift index 2be8626e..52cb0cc2 100644 --- a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/main.swift +++ b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/main.swift @@ -17,7 +17,7 @@ import class Foundation.JSONDecoder } func _update(swiftSource: String, dtsSource: String) throws -> PlayBridgeJSOutput { - let exportSwift = ExportSwift(progress: .silent, moduleName: "Playground") + let exportSwift = ExportSwift(progress: .silent, moduleName: "Playground", exposeToGlobal: false) let sourceFile = Parser.parse(source: swiftSource) try exportSwift.addSourceFile(sourceFile, "Playground.swift") let exportResult = try exportSwift.finalize() @@ -40,8 +40,7 @@ import class Foundation.JSONDecoder children: [importSkeleton] ) ], - sharedMemory: false, - exposeToGlobal: true + sharedMemory: false ) let linked = try linker.link() diff --git a/Makefile b/Makefile index c46431dd..453b0b64 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,16 @@ unittest: --disable-sandbox \ js test --prelude ./Tests/prelude.mjs -Xnode --expose-gc +.PHONY: unittest-with-global +unittest-with-global: + cp Tests/BridgeJSRuntimeTests/bridge-js.config.exposeToGlobal.json Tests/BridgeJSRuntimeTests/bridge-js.config.local.json + swift package --allow-writing-to-directory Tests/BridgeJSRuntimeTests \ + bridge-js --package-path Tests/BridgeJSRuntimeTests + rm -f Tests/BridgeJSRuntimeTests/bridge-js.config.local.json + env JAVASCRIPTKIT_EXPERIMENTAL_BRIDGEJS=1 swift package --swift-sdk "$(SWIFT_SDK_ID)" \ + --disable-sandbox \ + js test --prelude ./Tests/prelude.exposeToGlobal.mjs -Xnode --expose-gc + .PHONY: regenerate_swiftpm_resources regenerate_swiftpm_resources: npm run build diff --git a/Plugins/BridgeJS/Sources/BridgeJSBuildPlugin/BridgeJSBuildPlugin.swift b/Plugins/BridgeJS/Sources/BridgeJSBuildPlugin/BridgeJSBuildPlugin.swift index 9ea09520..47487bfc 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSBuildPlugin/BridgeJSBuildPlugin.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSBuildPlugin/BridgeJSBuildPlugin.swift @@ -44,6 +44,8 @@ struct BridgeJSBuildPlugin: BuildToolPlugin { "export", "--module-name", target.name, + "--target-dir", + target.directoryURL.path, "--output-skeleton", outputSkeletonPath.path, "--output-swift", diff --git a/Plugins/BridgeJS/Sources/BridgeJSCommandPlugin/BridgeJSCommandPlugin.swift b/Plugins/BridgeJS/Sources/BridgeJSCommandPlugin/BridgeJSCommandPlugin.swift index a4a2fcf1..26a0d0ef 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCommandPlugin/BridgeJSCommandPlugin.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCommandPlugin/BridgeJSCommandPlugin.swift @@ -107,6 +107,8 @@ extension BridgeJSCommandPlugin.Context { "export", "--module-name", target.name, + "--target-dir", + target.directoryURL.path, "--output-skeleton", generatedJavaScriptDirectory.appending(path: "BridgeJS.ExportSwift.json").path, "--output-swift", diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/BridgeJSConfig.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/BridgeJSConfig.swift index cf6f881e..56646b59 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/BridgeJSConfig.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/BridgeJSConfig.swift @@ -10,6 +10,31 @@ public struct BridgeJSConfig: Codable { /// If not present, the tool will be searched for in the system PATH. public var tools: [String: String]? + /// Whether to expose exported Swift APIs to the global namespace. + /// + /// When `true`, exported functions, classes, and namespaces are available + /// via `globalThis` in JavaScript. When `false`, they are only available + /// through the exports object returned by `createExports()`. + /// + /// Default: `false` + public var exposeToGlobal: Bool + + public init(tools: [String: String]? = nil, exposeToGlobal: Bool = false) { + self.tools = tools + self.exposeToGlobal = exposeToGlobal + } + + enum CodingKeys: String, CodingKey { + case tools + case exposeToGlobal + } + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + tools = try container.decodeIfPresent([String: String].self, forKey: .tools) + exposeToGlobal = try container.decodeIfPresent(Bool.self, forKey: .exposeToGlobal) ?? false + } + /// Load the configuration file from the SwiftPM package target directory. /// /// Files are loaded **in this order** and merged (later files override earlier ones): @@ -49,7 +74,8 @@ public struct BridgeJSConfig: Codable { /// Merge the current configuration with the overrides. func merging(overrides: BridgeJSConfig) -> BridgeJSConfig { return BridgeJSConfig( - tools: (tools ?? [:]).merging(overrides.tools ?? [:], uniquingKeysWith: { $1 }) + tools: (tools ?? [:]).merging(overrides.tools ?? [:], uniquingKeysWith: { $1 }), + exposeToGlobal: overrides.exposeToGlobal ) } } diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift index 4859ba6d..d4ea770a 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift @@ -20,7 +20,7 @@ import BridgeJSUtilities public class ExportSwift { let progress: ProgressReporting let moduleName: String - + private let exposeToGlobal: Bool private var exportedFunctions: [ExportedFunction] = [] private var exportedClasses: [ExportedClass] = [] private var exportedEnums: [ExportedEnum] = [] @@ -30,9 +30,10 @@ public class ExportSwift { private let enumCodegen: EnumCodegen = EnumCodegen() private let closureCodegen = ClosureCodegen() - public init(progress: ProgressReporting, moduleName: String) { + public init(progress: ProgressReporting, moduleName: String, exposeToGlobal: Bool) { self.progress = progress self.moduleName = moduleName + self.exposeToGlobal = exposeToGlobal } /// Processes a Swift source file to find declarations marked with @JS @@ -55,6 +56,8 @@ public class ExportSwift { /// Finalizes the export process and generates the bridge code /// + /// - Parameters: + /// - exposeToGlobal: Whether to expose exported APIs to the global namespace (default: false) /// - Returns: A tuple containing the generated Swift code and a skeleton /// describing the exported APIs public func finalize() throws -> (outputSwift: String, outputSkeleton: ExportedSkeleton)? { @@ -68,7 +71,8 @@ public class ExportSwift { functions: exportedFunctions, classes: exportedClasses, enums: exportedEnums, - protocols: exportedProtocols + protocols: exportedProtocols, + exposeToGlobal: exposeToGlobal ) ) } diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift index 98b57202..23884608 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift @@ -12,24 +12,26 @@ struct BridgeJSLink { var exportedSkeletons: [ExportedSkeleton] = [] var importedSkeletons: [ImportedModuleSkeleton] = [] let sharedMemory: Bool - let exposeToGlobal: Bool + var exposeToGlobal: Bool private let namespaceBuilder = NamespaceBuilder() init( exportedSkeletons: [ExportedSkeleton] = [], importedSkeletons: [ImportedModuleSkeleton] = [], - sharedMemory: Bool, - exposeToGlobal: Bool = true + sharedMemory: Bool ) { self.exportedSkeletons = exportedSkeletons self.importedSkeletons = importedSkeletons self.sharedMemory = sharedMemory - self.exposeToGlobal = exposeToGlobal + self.exposeToGlobal = exportedSkeletons.contains { $0.exposeToGlobal } } mutating func addExportedSkeletonFile(data: Data) throws { let skeleton = try JSONDecoder().decode(ExportedSkeleton.self, from: data) exportedSkeletons.append(skeleton) + if skeleton.exposeToGlobal { + exposeToGlobal = true + } } mutating func addImportedSkeletonFile(data: Data) throws { @@ -80,7 +82,7 @@ struct BridgeJSLink { var enumStaticAssignments: [String] = [] } - private func collectLinkData(exposeToGlobal: Bool) throws -> LinkData { + private func collectLinkData() throws -> LinkData { var data = LinkData() // Swift heap object class definitions @@ -1079,11 +1081,11 @@ struct BridgeJSLink { ) printer.write(lines: namespaceInitCode) - let propertyAssignments = try generateNamespacePropertyAssignments( - data: data, - exportedSkeletons: exportedSkeletons, - namespaceBuilder: namespaceBuilder, - exposeToGlobal: exposeToGlobal + let propertyAssignments = try generateNamespacePropertyAssignments( + data: data, + exportedSkeletons: exportedSkeletons, + namespaceBuilder: namespaceBuilder, + exposeToGlobal: exposeToGlobal ) printer.write(lines: propertyAssignments) } @@ -1097,7 +1099,7 @@ struct BridgeJSLink { } func link() throws -> (outputJs: String, outputDts: String) { - let data = try collectLinkData(exposeToGlobal: exposeToGlobal) + let data = try collectLinkData() let outputJs = try generateJavaScript(data: data) let outputDts = generateTypeScript(data: data) return (outputJs, outputDts) @@ -1160,7 +1162,6 @@ struct BridgeJSLink { ) throws -> [String] { let printer = CodeFragmentPrinter() - // Only write globalThis property assignments when exposeToGlobal is true if exposeToGlobal { printer.write(lines: data.enumStaticAssignments) } @@ -1171,7 +1172,6 @@ struct BridgeJSLink { let hierarchicalLines = try namespaceBuilder.buildHierarchicalExportsObject( exportedSkeletons: exportedSkeletons, - exposeToGlobal: exposeToGlobal, renderFunctionImpl: { function in let (js, _) = try self.renderExportedFunction(function: function) return js @@ -2478,7 +2478,6 @@ extension BridgeJSLink { fileprivate func buildHierarchicalExportsObject( exportedSkeletons: [ExportedSkeleton], - exposeToGlobal: Bool, renderFunctionImpl: (ExportedFunction) throws -> [String] ) throws -> [String] { let printer = CodeFragmentPrinter() @@ -2698,7 +2697,7 @@ extension BridgeJSLink { guard hasContent(node: childNode) else { continue } - + let exportKeyword = exposeToGlobal ? "" : "export " printer.write("\(exportKeyword)namespace \(childName) {") printer.indent() diff --git a/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift b/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift index a862f3c3..12970b50 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift @@ -499,19 +499,27 @@ public struct ExportedSkeleton: Codable { public let classes: [ExportedClass] public let enums: [ExportedEnum] public let protocols: [ExportedProtocol] + /// Whether to expose exported APIs to the global namespace. + /// + /// When `true`, exported functions, classes, and namespaces are available + /// via `globalThis` in JavaScript. When `false`, they are only available + /// through the exports object. + public var exposeToGlobal: Bool public init( moduleName: String, functions: [ExportedFunction], classes: [ExportedClass], enums: [ExportedEnum], - protocols: [ExportedProtocol] = [] + protocols: [ExportedProtocol] = [], + exposeToGlobal: Bool ) { self.moduleName = moduleName self.functions = functions self.classes = classes self.enums = enums self.protocols = protocols + self.exposeToGlobal = exposeToGlobal } } diff --git a/Plugins/BridgeJS/Sources/BridgeJSTool/BridgeJSTool.swift b/Plugins/BridgeJS/Sources/BridgeJSTool/BridgeJSTool.swift index dba6fe47..d5a58aba 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSTool/BridgeJSTool.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSTool/BridgeJSTool.swift @@ -162,6 +162,10 @@ import TS2Skeleton help: "The name of the module for external function references", required: true ), + "target-dir": OptionRule( + help: "The SwiftPM package target directory", + required: true + ), "output-skeleton": OptionRule( help: "The output file path for the skeleton of the exported Swift APIs", required: true @@ -181,7 +185,13 @@ import TS2Skeleton arguments: Array(arguments.dropFirst()) ) let progress = ProgressReporting(verbose: doubleDashOptions["verbose"] == "true") - let exporter = ExportSwift(progress: progress, moduleName: doubleDashOptions["module-name"]!) + let targetDirectory = URL(fileURLWithPath: doubleDashOptions["target-dir"]!) + let config = try BridgeJSConfig.load(targetDirectory: targetDirectory) + let exporter = ExportSwift( + progress: progress, + moduleName: doubleDashOptions["module-name"]!, + exposeToGlobal: config.exposeToGlobal + ) for inputFile in positionalArguments.sorted() { let sourceURL = URL(fileURLWithPath: inputFile) guard sourceURL.pathExtension == "swift" else { continue } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift index b837451d..989d05e2 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift @@ -47,16 +47,12 @@ import Testing func snapshotExport(input: String) throws { let url = Self.inputsDirectory.appendingPathComponent(input) let sourceFile = Parser.parse(source: try String(contentsOf: url, encoding: .utf8)) - let swiftAPI = ExportSwift(progress: .silent, moduleName: "TestModule") + let swiftAPI = ExportSwift(progress: .silent, moduleName: "TestModule", exposeToGlobal: false) try swiftAPI.addSourceFile(sourceFile, input) let name = url.deletingPathExtension().lastPathComponent let (_, outputSkeleton) = try #require(try swiftAPI.finalize()) - let encoder = JSONEncoder() - encoder.outputFormatting = [.prettyPrinted, .sortedKeys] - let outputSkeletonData = try encoder.encode(outputSkeleton) - var bridgeJSLink = BridgeJSLink(sharedMemory: false, exposeToGlobal: true) - try bridgeJSLink.addExportedSkeletonFile(data: outputSkeletonData) + let bridgeJSLink: BridgeJSLink = BridgeJSLink(exportedSkeletons: [outputSkeleton], sharedMemory: false) try snapshot(bridgeJSLink: bridgeJSLink, name: name + ".Export") } @@ -74,7 +70,7 @@ import Testing encoder.outputFormatting = [.prettyPrinted, .sortedKeys] let outputSkeletonData = try encoder.encode(importTS.skeleton) - var bridgeJSLink = BridgeJSLink(sharedMemory: false, exposeToGlobal: true) + var bridgeJSLink = BridgeJSLink(sharedMemory: false) try bridgeJSLink.addImportedSkeletonFile(data: outputSkeletonData) try snapshot(bridgeJSLink: bridgeJSLink, name: name + ".Import") } @@ -83,45 +79,16 @@ import Testing "Namespaces.swift", "StaticFunctions.swift", "StaticProperties.swift", - "EnumNamespace.swift" + "EnumNamespace.swift", ]) - func testWithoutGlobal(inputFile: String) throws { + func snapshotExportWithGlobal(inputFile: String) throws { let url = Self.inputsDirectory.appendingPathComponent(inputFile) let sourceFile = Parser.parse(source: try String(contentsOf: url, encoding: .utf8)) - let swiftAPI = ExportSwift(progress: .silent, moduleName: "TestModule") + let swiftAPI = ExportSwift(progress: .silent, moduleName: "TestModule", exposeToGlobal: true) try swiftAPI.addSourceFile(sourceFile, inputFile) - + let name = url.deletingPathExtension().lastPathComponent let (_, outputSkeleton) = try #require(try swiftAPI.finalize()) - let encoder = JSONEncoder() - encoder.outputFormatting = [.prettyPrinted, .sortedKeys] - let outputSkeletonData = try encoder.encode(outputSkeleton) - - var bridgeJSLink = BridgeJSLink(sharedMemory: false, exposeToGlobal: false) - try bridgeJSLink.addExportedSkeletonFile(data: outputSkeletonData) - - let (outputJs, outputDts) = try bridgeJSLink.link() - - // Verify no global declarations - #expect(!outputDts.contains("declare global")) - #expect(!outputJs.contains("globalThis.")) - - // Save snapshots - let name = url.deletingPathExtension().lastPathComponent + "_NoGlobal.Export" - try assertSnapshot( - name: name, - filePath: #filePath, - function: #function, - sourceLocation: #_sourceLocation, - input: outputJs.data(using: .utf8)!, - fileExtension: "js" - ) - try assertSnapshot( - name: name, - filePath: #filePath, - function: #function, - sourceLocation: #_sourceLocation, - input: outputDts.data(using: .utf8)!, - fileExtension: "d.ts" - ) + let bridgeJSLink: BridgeJSLink = BridgeJSLink(exportedSkeletons: [outputSkeleton], sharedMemory: false) + try snapshot(bridgeJSLink: bridgeJSLink, name: name + ".Global.Export") } } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/ExportSwiftTests.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/ExportSwiftTests.swift index e184116f..32c3aae7 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/ExportSwiftTests.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/ExportSwiftTests.swift @@ -47,11 +47,26 @@ import Testing @Test(arguments: collectInputs()) func snapshot(input: String) throws { - let swiftAPI = ExportSwift(progress: .silent, moduleName: "TestModule") + let swiftAPI = ExportSwift(progress: .silent, moduleName: "TestModule", exposeToGlobal: false) let url = Self.inputsDirectory.appendingPathComponent(input) let sourceFile = Parser.parse(source: try String(contentsOf: url, encoding: .utf8)) try swiftAPI.addSourceFile(sourceFile, input) let name = url.deletingPathExtension().lastPathComponent try snapshot(swiftAPI: swiftAPI, name: name) } + + @Test(arguments: [ + "Namespaces.swift", + "StaticFunctions.swift", + "StaticProperties.swift", + "EnumNamespace.swift", + ]) + func snapshotWithGlobal(input: String) throws { + let swiftAPI = ExportSwift(progress: .silent, moduleName: "TestModule", exposeToGlobal: true) + let url = Self.inputsDirectory.appendingPathComponent(input) + let sourceFile = Parser.parse(source: try String(contentsOf: url, encoding: .utf8)) + try swiftAPI.addSourceFile(sourceFile, input) + let name = url.deletingPathExtension().lastPathComponent + try snapshot(swiftAPI: swiftAPI, name: name + ".Global") + } } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts index 5523b89e..9df9bbea 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts @@ -53,32 +53,27 @@ export type NetworkingResultObject = typeof API.NetworkingResultValues; export type APIOptionalResultObject = typeof APIOptionalResultValues; -export {}; - -declare global { - namespace API { - const NetworkingResultValues: { - readonly Tag: { - readonly Success: 0; - readonly Failure: 1; - }; +export namespace API { + const NetworkingResultValues: { + readonly Tag: { + readonly Success: 0; + readonly Failure: 1; }; - type NetworkingResultTag = - { tag: typeof NetworkingResultValues.Tag.Success; param0: string } | { tag: typeof NetworkingResultValues.Tag.Failure; param0: string; param1: number } - } - namespace Utilities { - const ResultValues: { - readonly Tag: { - readonly Success: 0; - readonly Failure: 1; - readonly Status: 2; - }; + }; + type NetworkingResultTag = + { tag: typeof NetworkingResultValues.Tag.Success; param0: string } | { tag: typeof NetworkingResultValues.Tag.Failure; param0: string; param1: number } +} +export namespace Utilities { + const ResultValues: { + readonly Tag: { + readonly Success: 0; + readonly Failure: 1; + readonly Status: 2; }; - type ResultTag = - { tag: typeof ResultValues.Tag.Success; param0: string } | { tag: typeof ResultValues.Tag.Failure; param0: string; param1: number } | { tag: typeof ResultValues.Tag.Status; param0: boolean; param1: number; param2: string } - } + }; + type ResultTag = + { tag: typeof ResultValues.Tag.Success; param0: string } | { tag: typeof ResultValues.Tag.Failure; param0: string; param1: number } | { tag: typeof ResultValues.Tag.Status; param0: boolean; param1: number; param2: string } } - export type Exports = { handle(result: APIResultTag): void; getResult(): APIResultTag; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.js index 14c150e5..c332a403 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.js @@ -479,14 +479,6 @@ const __bjs_createAPIOptionalResultValuesHelpers = () => { } }); }; -if (typeof globalThis.API === 'undefined') { - globalThis.API = {}; -} -if (typeof globalThis.Utilities === 'undefined') { - globalThis.Utilities = {}; -} -globalThis.Utilities.ResultValues = ResultValues; -globalThis.API.NetworkingResultValues = NetworkingResultValues; export async function createInstantiator(options, swift) { let instance; let memory; @@ -692,12 +684,6 @@ export async function createInstantiator(options, swift) { /** @param {WebAssembly.Instance} instance */ createExports: (instance) => { const js = swift.memory.heap; - if (typeof globalThis.API === 'undefined') { - globalThis.API = {}; - } - if (typeof globalThis.Utilities === 'undefined') { - globalThis.Utilities = {}; - } const exports = { handle: function bjs_handle(result) { const { caseId: resultCaseId, cleanup: resultCleanup } = enumHelpers.APIResult.lower(result); 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 4261ca3b..b8b92d14 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.d.ts @@ -12,60 +12,41 @@ export type PortObject = typeof Configuration.PortValues; export type SupportedMethodObject = typeof Networking.APIV2.Internal.SupportedMethodValues; -export {}; - -declare global { - namespace Configuration { - const LogLevelValues: { - readonly Debug: "debug"; - readonly Info: "info"; - readonly Warning: "warning"; - readonly Error: "error"; - }; - type LogLevelTag = typeof LogLevelValues[keyof typeof LogLevelValues]; - const PortValues: { - readonly Http: 80; - readonly Https: 443; - readonly Development: 3000; +export namespace Configuration { + const LogLevelValues: { + readonly Debug: "debug"; + readonly Info: "info"; + readonly Warning: "warning"; + readonly Error: "error"; + }; + type LogLevelTag = typeof LogLevelValues[keyof typeof LogLevelValues]; + const PortValues: { + readonly Http: 80; + readonly Https: 443; + readonly Development: 3000; + }; + type PortTag = typeof PortValues[keyof typeof PortValues]; +} +export namespace Networking { + export namespace API { + const MethodValues: { + readonly Get: 0; + readonly Post: 1; + readonly Put: 2; + readonly Delete: 3; }; - type PortTag = typeof PortValues[keyof typeof PortValues]; + type MethodTag = typeof MethodValues[keyof typeof MethodValues]; } - namespace Networking { - namespace API { - class HTTPServer { - constructor(); - call(method: Networking.API.MethodTag): void; - } - const MethodValues: { + export namespace APIV2 { + export namespace Internal { + const SupportedMethodValues: { readonly Get: 0; readonly Post: 1; - readonly Put: 2; - readonly Delete: 3; }; - type MethodTag = typeof MethodValues[keyof typeof MethodValues]; - } - namespace APIV2 { - namespace Internal { - class TestServer { - constructor(); - call(method: Networking.APIV2.Internal.SupportedMethodTag): void; - } - const SupportedMethodValues: { - readonly Get: 0; - readonly Post: 1; - }; - type SupportedMethodTag = typeof SupportedMethodValues[keyof typeof SupportedMethodValues]; - } - } - } - namespace Utils { - class Converter { - constructor(); - toString(value: number): string; + type SupportedMethodTag = typeof SupportedMethodValues[keyof typeof SupportedMethodValues]; } } } - /// Represents a Swift heap object like a class instance or an actor instance. export interface SwiftHeapObject { /// Release the heap object. diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js index a38b5093..9fed226d 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js @@ -29,25 +29,6 @@ export const SupportedMethodValues = { Post: 1, }; -if (typeof globalThis.Configuration === 'undefined') { - globalThis.Configuration = {}; -} -if (typeof globalThis.Networking === 'undefined') { - globalThis.Networking = {}; -} -if (typeof globalThis.Networking.API === 'undefined') { - globalThis.Networking.API = {}; -} -if (typeof globalThis.Networking.APIV2 === 'undefined') { - globalThis.Networking.APIV2 = {}; -} -if (typeof globalThis.Networking.APIV2.Internal === 'undefined') { - globalThis.Networking.APIV2.Internal = {}; -} -globalThis.Networking.API.MethodValues = MethodValues; -globalThis.Configuration.LogLevelValues = LogLevelValues; -globalThis.Configuration.PortValues = PortValues; -globalThis.Networking.APIV2.Internal.SupportedMethodValues = SupportedMethodValues; export async function createInstantiator(options, swift) { let instance; let memory; @@ -314,24 +295,6 @@ export async function createInstantiator(options, swift) { instance.exports.bjs_TestServer_call(this.pointer, method); } } - if (typeof globalThis.Configuration === 'undefined') { - globalThis.Configuration = {}; - } - if (typeof globalThis.Networking === 'undefined') { - globalThis.Networking = {}; - } - if (typeof globalThis.Networking.API === 'undefined') { - globalThis.Networking.API = {}; - } - if (typeof globalThis.Networking.APIV2 === 'undefined') { - globalThis.Networking.APIV2 = {}; - } - if (typeof globalThis.Networking.APIV2.Internal === 'undefined') { - globalThis.Networking.APIV2.Internal = {}; - } - if (typeof globalThis.Utils === 'undefined') { - globalThis.Utils = {}; - } const exports = { Configuration: { LogLevel: LogLevelValues, @@ -354,9 +317,6 @@ export async function createInstantiator(options, swift) { }, }; _exports = exports; - globalThis.Utils.Converter = exports.Utils.Converter; - globalThis.Networking.API.HTTPServer = exports.Networking.API.HTTPServer; - globalThis.Networking.APIV2.Internal.TestServer = exports.Networking.APIV2.Internal.TestServer; return exports; }, } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace_NoGlobal.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.Export.d.ts similarity index 57% rename from Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace_NoGlobal.Export.d.ts rename to Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.Export.d.ts index b8b92d14..4261ca3b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace_NoGlobal.Export.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.Export.d.ts @@ -12,41 +12,60 @@ export type PortObject = typeof Configuration.PortValues; export type SupportedMethodObject = typeof Networking.APIV2.Internal.SupportedMethodValues; -export namespace Configuration { - const LogLevelValues: { - readonly Debug: "debug"; - readonly Info: "info"; - readonly Warning: "warning"; - readonly Error: "error"; - }; - type LogLevelTag = typeof LogLevelValues[keyof typeof LogLevelValues]; - const PortValues: { - readonly Http: 80; - readonly Https: 443; - readonly Development: 3000; - }; - type PortTag = typeof PortValues[keyof typeof PortValues]; -} -export namespace Networking { - export namespace API { - const MethodValues: { - readonly Get: 0; - readonly Post: 1; - readonly Put: 2; - readonly Delete: 3; +export {}; + +declare global { + namespace Configuration { + const LogLevelValues: { + readonly Debug: "debug"; + readonly Info: "info"; + readonly Warning: "warning"; + readonly Error: "error"; + }; + type LogLevelTag = typeof LogLevelValues[keyof typeof LogLevelValues]; + const PortValues: { + readonly Http: 80; + readonly Https: 443; + readonly Development: 3000; }; - type MethodTag = typeof MethodValues[keyof typeof MethodValues]; + type PortTag = typeof PortValues[keyof typeof PortValues]; } - export namespace APIV2 { - export namespace Internal { - const SupportedMethodValues: { + namespace Networking { + namespace API { + class HTTPServer { + constructor(); + call(method: Networking.API.MethodTag): void; + } + const MethodValues: { readonly Get: 0; readonly Post: 1; + readonly Put: 2; + readonly Delete: 3; }; - type SupportedMethodTag = typeof SupportedMethodValues[keyof typeof SupportedMethodValues]; + type MethodTag = typeof MethodValues[keyof typeof MethodValues]; + } + namespace APIV2 { + namespace Internal { + class TestServer { + constructor(); + call(method: Networking.APIV2.Internal.SupportedMethodTag): void; + } + const SupportedMethodValues: { + readonly Get: 0; + readonly Post: 1; + }; + type SupportedMethodTag = typeof SupportedMethodValues[keyof typeof SupportedMethodValues]; + } + } + } + namespace Utils { + class Converter { + constructor(); + toString(value: number): string; } } } + /// Represents a Swift heap object like a class instance or an actor instance. export interface SwiftHeapObject { /// Release the heap object. diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace_NoGlobal.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.Export.js similarity index 87% rename from Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace_NoGlobal.Export.js rename to Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.Export.js index 9fed226d..a38b5093 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace_NoGlobal.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.Export.js @@ -29,6 +29,25 @@ export const SupportedMethodValues = { Post: 1, }; +if (typeof globalThis.Configuration === 'undefined') { + globalThis.Configuration = {}; +} +if (typeof globalThis.Networking === 'undefined') { + globalThis.Networking = {}; +} +if (typeof globalThis.Networking.API === 'undefined') { + globalThis.Networking.API = {}; +} +if (typeof globalThis.Networking.APIV2 === 'undefined') { + globalThis.Networking.APIV2 = {}; +} +if (typeof globalThis.Networking.APIV2.Internal === 'undefined') { + globalThis.Networking.APIV2.Internal = {}; +} +globalThis.Networking.API.MethodValues = MethodValues; +globalThis.Configuration.LogLevelValues = LogLevelValues; +globalThis.Configuration.PortValues = PortValues; +globalThis.Networking.APIV2.Internal.SupportedMethodValues = SupportedMethodValues; export async function createInstantiator(options, swift) { let instance; let memory; @@ -295,6 +314,24 @@ export async function createInstantiator(options, swift) { instance.exports.bjs_TestServer_call(this.pointer, method); } } + if (typeof globalThis.Configuration === 'undefined') { + globalThis.Configuration = {}; + } + if (typeof globalThis.Networking === 'undefined') { + globalThis.Networking = {}; + } + if (typeof globalThis.Networking.API === 'undefined') { + globalThis.Networking.API = {}; + } + if (typeof globalThis.Networking.APIV2 === 'undefined') { + globalThis.Networking.APIV2 = {}; + } + if (typeof globalThis.Networking.APIV2.Internal === 'undefined') { + globalThis.Networking.APIV2.Internal = {}; + } + if (typeof globalThis.Utils === 'undefined') { + globalThis.Utils = {}; + } const exports = { Configuration: { LogLevel: LogLevelValues, @@ -317,6 +354,9 @@ export async function createInstantiator(options, swift) { }, }; _exports = exports; + globalThis.Utils.Converter = exports.Utils.Converter; + globalThis.Networking.API.HTTPServer = exports.Networking.API.HTTPServer; + globalThis.Networking.APIV2.Internal.TestServer = exports.Networking.APIV2.Internal.TestServer; return exports; }, } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.d.ts index cdf83f36..67a89533 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.d.ts @@ -4,35 +4,6 @@ // To update this file, just rebuild your project or run // `swift package bridge-js`. -export {}; - -declare global { - namespace MyModule { - namespace Utils { - namespacedFunction(): string; - } - } - namespace Utils { - namespace Converters { - class Converter { - constructor(); - toString(value: number): string; - } - } - } - namespace __Swift { - namespace Foundation { - class Greeter { - constructor(name: string); - greet(): string; - } - class UUID { - uuidString(): string; - } - } - } -} - /// Represents a Swift heap object like a class instance or an actor instance. export interface SwiftHeapObject { /// Release the heap object. diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js index 67670d20..08601bd5 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js @@ -275,24 +275,6 @@ export async function createInstantiator(options, swift) { return ret; } } - if (typeof globalThis.MyModule === 'undefined') { - globalThis.MyModule = {}; - } - if (typeof globalThis.MyModule.Utils === 'undefined') { - globalThis.MyModule.Utils = {}; - } - if (typeof globalThis.Utils === 'undefined') { - globalThis.Utils = {}; - } - if (typeof globalThis.Utils.Converters === 'undefined') { - globalThis.Utils.Converters = {}; - } - if (typeof globalThis.__Swift === 'undefined') { - globalThis.__Swift = {}; - } - if (typeof globalThis.__Swift.Foundation === 'undefined') { - globalThis.__Swift.Foundation = {}; - } const exports = { plainFunction: function bjs_plainFunction() { instance.exports.bjs_plainFunction(); @@ -323,10 +305,6 @@ export async function createInstantiator(options, swift) { }, }; _exports = exports; - globalThis.__Swift.Foundation.Greeter = exports.__Swift.Foundation.Greeter; - globalThis.Utils.Converters.Converter = exports.Utils.Converters.Converter; - globalThis.__Swift.Foundation.UUID = exports.__Swift.Foundation.UUID; - globalThis.MyModule.Utils.namespacedFunction = exports.MyModule.Utils.namespacedFunction; return exports; }, } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces_NoGlobal.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.Export.d.ts similarity index 70% rename from Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces_NoGlobal.Export.d.ts rename to Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.Export.d.ts index 67a89533..cdf83f36 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces_NoGlobal.Export.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.Export.d.ts @@ -4,6 +4,35 @@ // To update this file, just rebuild your project or run // `swift package bridge-js`. +export {}; + +declare global { + namespace MyModule { + namespace Utils { + namespacedFunction(): string; + } + } + namespace Utils { + namespace Converters { + class Converter { + constructor(); + toString(value: number): string; + } + } + } + namespace __Swift { + namespace Foundation { + class Greeter { + constructor(name: string); + greet(): string; + } + class UUID { + uuidString(): string; + } + } + } +} + /// Represents a Swift heap object like a class instance or an actor instance. export interface SwiftHeapObject { /// Release the heap object. diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces_NoGlobal.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.Export.js similarity index 91% rename from Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces_NoGlobal.Export.js rename to Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.Export.js index 08601bd5..67670d20 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces_NoGlobal.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.Export.js @@ -275,6 +275,24 @@ export async function createInstantiator(options, swift) { return ret; } } + if (typeof globalThis.MyModule === 'undefined') { + globalThis.MyModule = {}; + } + if (typeof globalThis.MyModule.Utils === 'undefined') { + globalThis.MyModule.Utils = {}; + } + if (typeof globalThis.Utils === 'undefined') { + globalThis.Utils = {}; + } + if (typeof globalThis.Utils.Converters === 'undefined') { + globalThis.Utils.Converters = {}; + } + if (typeof globalThis.__Swift === 'undefined') { + globalThis.__Swift = {}; + } + if (typeof globalThis.__Swift.Foundation === 'undefined') { + globalThis.__Swift.Foundation = {}; + } const exports = { plainFunction: function bjs_plainFunction() { instance.exports.bjs_plainFunction(); @@ -305,6 +323,10 @@ export async function createInstantiator(options, swift) { }, }; _exports = exports; + globalThis.__Swift.Foundation.Greeter = exports.__Swift.Foundation.Greeter; + globalThis.Utils.Converters.Converter = exports.Utils.Converters.Converter; + globalThis.__Swift.Foundation.UUID = exports.__Swift.Foundation.UUID; + globalThis.MyModule.Utils.namespacedFunction = exports.MyModule.Utils.namespacedFunction; return exports; }, } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Export.d.ts index 069c1628..e938ddb9 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Export.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Export.d.ts @@ -28,16 +28,6 @@ export type APIResultObject = typeof APIResultValues & { roundtrip(value: APIResultTag): APIResultTag; }; -export {}; - -declare global { - namespace Utils { - namespace String { - uppercase(text: string): string; - } - } -} - /// Represents a Swift heap object like a class instance or an actor instance. export interface SwiftHeapObject { /// Release the heap object. diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Export.js index 3e445992..8522168f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Export.js @@ -297,12 +297,6 @@ export async function createInstantiator(options, swift) { return ret; } } - if (typeof globalThis.Utils === 'undefined') { - globalThis.Utils = {}; - } - if (typeof globalThis.Utils.String === 'undefined') { - globalThis.Utils.String = {}; - } const exports = { MathUtils, Calculator: { @@ -337,7 +331,6 @@ export async function createInstantiator(options, swift) { }, }; _exports = exports; - globalThis.Utils.String.uppercase = exports.Utils.String.uppercase; return exports; }, } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions_NoGlobal.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.Export.d.ts similarity index 92% rename from Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions_NoGlobal.Export.d.ts rename to Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.Export.d.ts index e938ddb9..069c1628 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions_NoGlobal.Export.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.Export.d.ts @@ -28,6 +28,16 @@ export type APIResultObject = typeof APIResultValues & { roundtrip(value: APIResultTag): APIResultTag; }; +export {}; + +declare global { + namespace Utils { + namespace String { + uppercase(text: string): string; + } + } +} + /// Represents a Swift heap object like a class instance or an actor instance. export interface SwiftHeapObject { /// Release the heap object. diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions_NoGlobal.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.Export.js similarity index 97% rename from Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions_NoGlobal.Export.js rename to Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.Export.js index 8522168f..3e445992 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions_NoGlobal.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.Export.js @@ -297,6 +297,12 @@ export async function createInstantiator(options, swift) { return ret; } } + if (typeof globalThis.Utils === 'undefined') { + globalThis.Utils = {}; + } + if (typeof globalThis.Utils.String === 'undefined') { + globalThis.Utils.String = {}; + } const exports = { MathUtils, Calculator: { @@ -331,6 +337,7 @@ export async function createInstantiator(options, swift) { }, }; _exports = exports; + globalThis.Utils.String.uppercase = exports.Utils.String.uppercase; return exports; }, } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Export.d.ts index fea3c4b5..4ce689ed 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Export.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Export.d.ts @@ -16,20 +16,6 @@ export type PropertyEnumObject = typeof PropertyEnumValues & { computedEnum: string; }; -export {}; - -declare global { - namespace PropertyNamespace { - var namespaceConstant: string; - let namespaceProperty: string; - namespace Nested { - var nestedConstant: string; - let nestedDouble: number; - let nestedProperty: number; - } - } -} - /// Represents a Swift heap object like a class instance or an actor instance. export interface SwiftHeapObject { /// Release the heap object. diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Export.js index 09a2b0de..5d70c39b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Export.js @@ -303,12 +303,6 @@ export async function createInstantiator(options, swift) { } } } - if (typeof globalThis.PropertyNamespace === 'undefined') { - globalThis.PropertyNamespace = {}; - } - if (typeof globalThis.PropertyNamespace.Nested === 'undefined') { - globalThis.PropertyNamespace.Nested = {}; - } const exports = { PropertyClass, PropertyEnum: { @@ -386,24 +380,6 @@ export async function createInstantiator(options, swift) { }, }; _exports = exports; - Object.defineProperty(globalThis.PropertyNamespace, 'namespaceProperty', { - get: () => exports.PropertyNamespace.namespaceProperty, - set: (value) => { exports.PropertyNamespace.namespaceProperty = value; } - }); - Object.defineProperty(globalThis.PropertyNamespace, 'namespaceConstant', { - get: () => exports.PropertyNamespace.namespaceConstant, - }); - Object.defineProperty(globalThis.PropertyNamespace.Nested, 'nestedProperty', { - get: () => exports.PropertyNamespace.Nested.nestedProperty, - set: (value) => { exports.PropertyNamespace.Nested.nestedProperty = value; } - }); - Object.defineProperty(globalThis.PropertyNamespace.Nested, 'nestedConstant', { - get: () => exports.PropertyNamespace.Nested.nestedConstant, - }); - Object.defineProperty(globalThis.PropertyNamespace.Nested, 'nestedDouble', { - get: () => exports.PropertyNamespace.Nested.nestedDouble, - set: (value) => { exports.PropertyNamespace.Nested.nestedDouble = value; } - }); return exports; }, } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties_NoGlobal.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.Export.d.ts similarity index 85% rename from Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties_NoGlobal.Export.d.ts rename to Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.Export.d.ts index 4ce689ed..fea3c4b5 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties_NoGlobal.Export.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.Export.d.ts @@ -16,6 +16,20 @@ export type PropertyEnumObject = typeof PropertyEnumValues & { computedEnum: string; }; +export {}; + +declare global { + namespace PropertyNamespace { + var namespaceConstant: string; + let namespaceProperty: string; + namespace Nested { + var nestedConstant: string; + let nestedDouble: number; + let nestedProperty: number; + } + } +} + /// Represents a Swift heap object like a class instance or an actor instance. export interface SwiftHeapObject { /// Release the heap object. diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties_NoGlobal.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.Export.js similarity index 92% rename from Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties_NoGlobal.Export.js rename to Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.Export.js index 5d70c39b..09a2b0de 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties_NoGlobal.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.Export.js @@ -303,6 +303,12 @@ export async function createInstantiator(options, swift) { } } } + if (typeof globalThis.PropertyNamespace === 'undefined') { + globalThis.PropertyNamespace = {}; + } + if (typeof globalThis.PropertyNamespace.Nested === 'undefined') { + globalThis.PropertyNamespace.Nested = {}; + } const exports = { PropertyClass, PropertyEnum: { @@ -380,6 +386,24 @@ export async function createInstantiator(options, swift) { }, }; _exports = exports; + Object.defineProperty(globalThis.PropertyNamespace, 'namespaceProperty', { + get: () => exports.PropertyNamespace.namespaceProperty, + set: (value) => { exports.PropertyNamespace.namespaceProperty = value; } + }); + Object.defineProperty(globalThis.PropertyNamespace, 'namespaceConstant', { + get: () => exports.PropertyNamespace.namespaceConstant, + }); + Object.defineProperty(globalThis.PropertyNamespace.Nested, 'nestedProperty', { + get: () => exports.PropertyNamespace.Nested.nestedProperty, + set: (value) => { exports.PropertyNamespace.Nested.nestedProperty = value; } + }); + Object.defineProperty(globalThis.PropertyNamespace.Nested, 'nestedConstant', { + get: () => exports.PropertyNamespace.Nested.nestedConstant, + }); + Object.defineProperty(globalThis.PropertyNamespace.Nested, 'nestedDouble', { + get: () => exports.PropertyNamespace.Nested.nestedDouble, + set: (value) => { exports.PropertyNamespace.Nested.nestedDouble = value; } + }); return exports; }, } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Async.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Async.json index 41696d63..2e295991 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Async.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Async.json @@ -5,6 +5,7 @@ "enums" : [ ], + "exposeToGlobal" : false, "functions" : [ { "abiName" : "bjs_asyncReturnVoid", diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/DefaultParameters.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/DefaultParameters.json index 98c09bef..ccb4cb28 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/DefaultParameters.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/DefaultParameters.json @@ -259,6 +259,7 @@ "tsFullPath" : "Status" } ], + "exposeToGlobal" : false, "functions" : [ { "abiName" : "bjs_testStringDefault", diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json index d2ab06d4..52279ce0 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json @@ -487,6 +487,7 @@ "tsFullPath" : "APIOptionalResult" } ], + "exposeToGlobal" : false, "functions" : [ { "abiName" : "bjs_handle", diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumCase.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumCase.json index 3e738dd2..9effaaec 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumCase.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumCase.json @@ -133,6 +133,7 @@ "tsFullPath" : "PublicStatus" } ], + "exposeToGlobal" : false, "functions" : [ { "abiName" : "bjs_setDirection", diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.json new file mode 100644 index 00000000..8aeb6c78 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.json @@ -0,0 +1,413 @@ +{ + "classes" : [ + { + "constructor" : { + "abiName" : "bjs_Converter_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + { + "abiName" : "bjs_Converter_toString", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "toString", + "namespace" : [ + "Utils" + ], + "parameters" : [ + { + "label" : "value", + "name" : "value", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + } + } + ], + "name" : "Converter", + "namespace" : [ + "Utils" + ], + "properties" : [ + + ], + "swiftCallName" : "Utils.Converter" + }, + { + "constructor" : { + "abiName" : "bjs_HTTPServer_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + { + "abiName" : "bjs_HTTPServer_call", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "call", + "namespace" : [ + "Networking", + "API" + ], + "parameters" : [ + { + "label" : "_", + "name" : "method", + "type" : { + "caseEnum" : { + "_0" : "Networking.API.Method" + } + } + } + ], + "returnType" : { + "void" : { + + } + } + } + ], + "name" : "HTTPServer", + "namespace" : [ + "Networking", + "API" + ], + "properties" : [ + + ], + "swiftCallName" : "Networking.API.HTTPServer" + }, + { + "constructor" : { + "abiName" : "bjs_TestServer_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + { + "abiName" : "bjs_TestServer_call", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "call", + "namespace" : [ + "Networking", + "APIV2", + "Internal" + ], + "parameters" : [ + { + "label" : "_", + "name" : "method", + "type" : { + "caseEnum" : { + "_0" : "Internal.SupportedMethod" + } + } + } + ], + "returnType" : { + "void" : { + + } + } + } + ], + "name" : "TestServer", + "namespace" : [ + "Networking", + "APIV2", + "Internal" + ], + "properties" : [ + + ], + "swiftCallName" : "Internal.TestServer" + } + ], + "enums" : [ + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "Utils", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Utils", + "tsFullPath" : "Utils" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "Networking", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Networking", + "tsFullPath" : "Networking" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "API", + "namespace" : [ + "Networking" + ], + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Networking.API", + "tsFullPath" : "Networking.API" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "get" + }, + { + "associatedValues" : [ + + ], + "name" : "post" + }, + { + "associatedValues" : [ + + ], + "name" : "put" + }, + { + "associatedValues" : [ + + ], + "name" : "delete" + } + ], + "emitStyle" : "const", + "name" : "Method", + "namespace" : [ + "Networking", + "API" + ], + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Networking.API.Method", + "tsFullPath" : "Networking.API.Method" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "Configuration", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Configuration", + "tsFullPath" : "Configuration" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "debug", + "rawValue" : "debug" + }, + { + "associatedValues" : [ + + ], + "name" : "info", + "rawValue" : "info" + }, + { + "associatedValues" : [ + + ], + "name" : "warning", + "rawValue" : "warning" + }, + { + "associatedValues" : [ + + ], + "name" : "error", + "rawValue" : "error" + } + ], + "emitStyle" : "const", + "name" : "LogLevel", + "namespace" : [ + "Configuration" + ], + "rawType" : "String", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Configuration.LogLevel", + "tsFullPath" : "Configuration.LogLevel" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "http", + "rawValue" : "80" + }, + { + "associatedValues" : [ + + ], + "name" : "https", + "rawValue" : "443" + }, + { + "associatedValues" : [ + + ], + "name" : "development", + "rawValue" : "3000" + } + ], + "emitStyle" : "const", + "name" : "Port", + "namespace" : [ + "Configuration" + ], + "rawType" : "Int", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Configuration.Port", + "tsFullPath" : "Configuration.Port" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "Internal", + "namespace" : [ + "Networking", + "APIV2" + ], + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Internal", + "tsFullPath" : "Networking.APIV2.Internal" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "get" + }, + { + "associatedValues" : [ + + ], + "name" : "post" + } + ], + "emitStyle" : "const", + "name" : "SupportedMethod", + "namespace" : [ + "Networking", + "APIV2", + "Internal" + ], + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Internal.SupportedMethod", + "tsFullPath" : "Networking.APIV2.Internal.SupportedMethod" + } + ], + "exposeToGlobal" : true, + "functions" : [ + + ], + "moduleName" : "TestModule", + "protocols" : [ + + ] +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.swift new file mode 100644 index 00000000..ca201f3d --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.swift @@ -0,0 +1,215 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +@_spi(BridgeJS) import JavaScriptKit + +extension Networking.API.Method: _BridgedSwiftCaseEnum { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> Networking.API.Method { + return bridgeJSLiftParameter(value) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> Networking.API.Method { + return Networking.API.Method(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSLowerParameter() + } + + private init?(bridgeJSRawValue: Int32) { + switch bridgeJSRawValue { + case 0: + self = .get + case 1: + self = .post + case 2: + self = .put + case 3: + self = .delete + default: + return nil + } + } + + private var bridgeJSRawValue: Int32 { + switch self { + case .get: + return 0 + case .post: + return 1 + case .put: + return 2 + case .delete: + return 3 + } + } +} + +extension Configuration.LogLevel: _BridgedSwiftEnumNoPayload { +} + +extension Configuration.Port: _BridgedSwiftEnumNoPayload { +} + +extension Internal.SupportedMethod: _BridgedSwiftCaseEnum { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> Internal.SupportedMethod { + return bridgeJSLiftParameter(value) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> Internal.SupportedMethod { + return Internal.SupportedMethod(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSLowerParameter() + } + + private init?(bridgeJSRawValue: Int32) { + switch bridgeJSRawValue { + case 0: + self = .get + case 1: + self = .post + default: + return nil + } + } + + private var bridgeJSRawValue: Int32 { + switch self { + case .get: + return 0 + case .post: + return 1 + } + } +} + +@_expose(wasm, "bjs_Converter_init") +@_cdecl("bjs_Converter_init") +public func _bjs_Converter_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = Utils.Converter() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Converter_toString") +@_cdecl("bjs_Converter_toString") +public func _bjs_Converter_toString(_self: UnsafeMutableRawPointer, value: Int32) -> Void { + #if arch(wasm32) + let ret = Utils.Converter.bridgeJSLiftParameter(_self).toString(value: Int.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Converter_deinit") +@_cdecl("bjs_Converter_deinit") +public func _bjs_Converter_deinit(pointer: UnsafeMutableRawPointer) { + Unmanaged.fromOpaque(pointer).release() +} + +extension Utils.Converter: ConvertibleToJSValue, _BridgedSwiftHeapObject { + var jsValue: JSValue { + #if arch(wasm32) + @_extern(wasm, module: "TestModule", name: "bjs_Converter_wrap") + func _bjs_Converter_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_Converter_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif + return .object(JSObject(id: UInt32(bitPattern: _bjs_Converter_wrap(Unmanaged.passRetained(self).toOpaque())))) + } +} + +@_expose(wasm, "bjs_HTTPServer_init") +@_cdecl("bjs_HTTPServer_init") +public func _bjs_HTTPServer_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = Networking.API.HTTPServer() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_HTTPServer_call") +@_cdecl("bjs_HTTPServer_call") +public func _bjs_HTTPServer_call(_self: UnsafeMutableRawPointer, method: Int32) -> Void { + #if arch(wasm32) + Networking.API.HTTPServer.bridgeJSLiftParameter(_self).call(_: Networking.API.Method.bridgeJSLiftParameter(method)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_HTTPServer_deinit") +@_cdecl("bjs_HTTPServer_deinit") +public func _bjs_HTTPServer_deinit(pointer: UnsafeMutableRawPointer) { + Unmanaged.fromOpaque(pointer).release() +} + +extension Networking.API.HTTPServer: ConvertibleToJSValue, _BridgedSwiftHeapObject { + var jsValue: JSValue { + #if arch(wasm32) + @_extern(wasm, module: "TestModule", name: "bjs_HTTPServer_wrap") + func _bjs_HTTPServer_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_HTTPServer_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif + return .object(JSObject(id: UInt32(bitPattern: _bjs_HTTPServer_wrap(Unmanaged.passRetained(self).toOpaque())))) + } +} + +@_expose(wasm, "bjs_TestServer_init") +@_cdecl("bjs_TestServer_init") +public func _bjs_TestServer_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = Internal.TestServer() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_TestServer_call") +@_cdecl("bjs_TestServer_call") +public func _bjs_TestServer_call(_self: UnsafeMutableRawPointer, method: Int32) -> Void { + #if arch(wasm32) + Internal.TestServer.bridgeJSLiftParameter(_self).call(_: Internal.SupportedMethod.bridgeJSLiftParameter(method)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_TestServer_deinit") +@_cdecl("bjs_TestServer_deinit") +public func _bjs_TestServer_deinit(pointer: UnsafeMutableRawPointer) { + Unmanaged.fromOpaque(pointer).release() +} + +extension Internal.TestServer: ConvertibleToJSValue, _BridgedSwiftHeapObject { + var jsValue: JSValue { + #if arch(wasm32) + @_extern(wasm, module: "TestModule", name: "bjs_TestServer_wrap") + func _bjs_TestServer_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_TestServer_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif + return .object(JSObject(id: UInt32(bitPattern: _bjs_TestServer_wrap(Unmanaged.passRetained(self).toOpaque())))) + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.json index 1ba8279e..94d1bb06 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.json @@ -402,6 +402,7 @@ "tsFullPath" : "Networking.APIV2.Internal.SupportedMethod" } ], + "exposeToGlobal" : false, "functions" : [ ], diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumRawType.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumRawType.json index 30ec6a35..4bf1644c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumRawType.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumRawType.json @@ -457,6 +457,7 @@ "tsFullPath" : "Ratio" } ], + "exposeToGlobal" : false, "functions" : [ { "abiName" : "bjs_setTheme", diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.Global.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.Global.json new file mode 100644 index 00000000..bde86c44 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.Global.json @@ -0,0 +1,180 @@ +{ + "classes" : [ + { + "constructor" : { + "abiName" : "bjs_Greeter_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "name", + "name" : "name", + "type" : { + "string" : { + + } + } + } + ] + }, + "methods" : [ + { + "abiName" : "bjs_Greeter_greet", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "greet", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + } + ], + "name" : "Greeter", + "namespace" : [ + "__Swift", + "Foundation" + ], + "properties" : [ + + ], + "swiftCallName" : "Greeter" + }, + { + "constructor" : { + "abiName" : "bjs_Converter_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + { + "abiName" : "bjs_Converter_toString", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "toString", + "parameters" : [ + { + "label" : "value", + "name" : "value", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + } + } + ], + "name" : "Converter", + "namespace" : [ + "Utils", + "Converters" + ], + "properties" : [ + + ], + "swiftCallName" : "Converter" + }, + { + "methods" : [ + { + "abiName" : "bjs_UUID_uuidString", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "uuidString", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + } + ], + "name" : "UUID", + "namespace" : [ + "__Swift", + "Foundation" + ], + "properties" : [ + + ], + "swiftCallName" : "UUID" + } + ], + "enums" : [ + + ], + "exposeToGlobal" : true, + "functions" : [ + { + "abiName" : "bjs_plainFunction", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "plainFunction", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_MyModule_Utils_namespacedFunction", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "namespacedFunction", + "namespace" : [ + "MyModule", + "Utils" + ], + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + } + ], + "moduleName" : "TestModule", + "protocols" : [ + + ] +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.Global.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.Global.swift new file mode 100644 index 00000000..f868fa11 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.Global.swift @@ -0,0 +1,144 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +@_spi(BridgeJS) import JavaScriptKit + +@_expose(wasm, "bjs_plainFunction") +@_cdecl("bjs_plainFunction") +public func _bjs_plainFunction() -> Void { + #if arch(wasm32) + let ret = plainFunction() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_MyModule_Utils_namespacedFunction") +@_cdecl("bjs_MyModule_Utils_namespacedFunction") +public func _bjs_MyModule_Utils_namespacedFunction() -> Void { + #if arch(wasm32) + let ret = namespacedFunction() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Greeter_init") +@_cdecl("bjs_Greeter_init") +public func _bjs_Greeter_init(nameBytes: Int32, nameLength: Int32) -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = Greeter(name: String.bridgeJSLiftParameter(nameBytes, nameLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Greeter_greet") +@_cdecl("bjs_Greeter_greet") +public func _bjs_Greeter_greet(_self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = Greeter.bridgeJSLiftParameter(_self).greet() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Greeter_deinit") +@_cdecl("bjs_Greeter_deinit") +public func _bjs_Greeter_deinit(pointer: UnsafeMutableRawPointer) { + Unmanaged.fromOpaque(pointer).release() +} + +extension Greeter: ConvertibleToJSValue, _BridgedSwiftHeapObject { + var jsValue: JSValue { + #if arch(wasm32) + @_extern(wasm, module: "TestModule", name: "bjs_Greeter_wrap") + func _bjs_Greeter_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_Greeter_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif + return .object(JSObject(id: UInt32(bitPattern: _bjs_Greeter_wrap(Unmanaged.passRetained(self).toOpaque())))) + } +} + +@_expose(wasm, "bjs_Converter_init") +@_cdecl("bjs_Converter_init") +public func _bjs_Converter_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = Converter() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Converter_toString") +@_cdecl("bjs_Converter_toString") +public func _bjs_Converter_toString(_self: UnsafeMutableRawPointer, value: Int32) -> Void { + #if arch(wasm32) + let ret = Converter.bridgeJSLiftParameter(_self).toString(value: Int.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Converter_deinit") +@_cdecl("bjs_Converter_deinit") +public func _bjs_Converter_deinit(pointer: UnsafeMutableRawPointer) { + Unmanaged.fromOpaque(pointer).release() +} + +extension Converter: ConvertibleToJSValue, _BridgedSwiftHeapObject { + var jsValue: JSValue { + #if arch(wasm32) + @_extern(wasm, module: "TestModule", name: "bjs_Converter_wrap") + func _bjs_Converter_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_Converter_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif + return .object(JSObject(id: UInt32(bitPattern: _bjs_Converter_wrap(Unmanaged.passRetained(self).toOpaque())))) + } +} + +@_expose(wasm, "bjs_UUID_uuidString") +@_cdecl("bjs_UUID_uuidString") +public func _bjs_UUID_uuidString(_self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = UUID.bridgeJSLiftParameter(_self).uuidString() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_UUID_deinit") +@_cdecl("bjs_UUID_deinit") +public func _bjs_UUID_deinit(pointer: UnsafeMutableRawPointer) { + Unmanaged.fromOpaque(pointer).release() +} + +extension UUID: ConvertibleToJSValue, _BridgedSwiftHeapObject { + var jsValue: JSValue { + #if arch(wasm32) + @_extern(wasm, module: "TestModule", name: "bjs_UUID_wrap") + func _bjs_UUID_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_UUID_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif + return .object(JSObject(id: UInt32(bitPattern: _bjs_UUID_wrap(Unmanaged.passRetained(self).toOpaque())))) + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.json index dc613452..910fcfc2 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.json @@ -132,6 +132,7 @@ "enums" : [ ], + "exposeToGlobal" : false, "functions" : [ { "abiName" : "bjs_plainFunction", diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Optionals.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Optionals.json index 104b11d5..eb92b21d 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Optionals.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Optionals.json @@ -157,6 +157,7 @@ "enums" : [ ], + "exposeToGlobal" : false, "functions" : [ { "abiName" : "bjs_roundTripOptionalClass", diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.json index e54d0ad5..ccd504f4 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.json @@ -5,6 +5,7 @@ "enums" : [ ], + "exposeToGlobal" : false, "functions" : [ { "abiName" : "bjs_check", diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.json index 99c5aff0..6210c866 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.json @@ -5,6 +5,7 @@ "enums" : [ ], + "exposeToGlobal" : false, "functions" : [ { "abiName" : "bjs_checkInt", diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PropertyTypes.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PropertyTypes.json index 94641103..14f0cc0f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PropertyTypes.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PropertyTypes.json @@ -253,6 +253,7 @@ "enums" : [ ], + "exposeToGlobal" : false, "functions" : [ { "abiName" : "bjs_createPropertyHolder", diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Protocol.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Protocol.json index efda4d14..487533b3 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Protocol.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Protocol.json @@ -392,6 +392,7 @@ "tsFullPath" : "Priority" } ], + "exposeToGlobal" : false, "functions" : [ ], diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.Global.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.Global.json new file mode 100644 index 00000000..8a2923a0 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.Global.json @@ -0,0 +1,334 @@ +{ + "classes" : [ + { + "constructor" : { + "abiName" : "bjs_MathUtils_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + { + "abiName" : "bjs_MathUtils_static_subtract", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "name" : "subtract", + "parameters" : [ + { + "label" : "a", + "name" : "a", + "type" : { + "int" : { + + } + } + }, + { + "label" : "b", + "name" : "b", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "int" : { + + } + }, + "staticContext" : { + "className" : { + "_0" : "MathUtils" + } + } + }, + { + "abiName" : "bjs_MathUtils_static_add", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "name" : "add", + "parameters" : [ + { + "label" : "a", + "name" : "a", + "type" : { + "int" : { + + } + } + }, + { + "label" : "b", + "name" : "b", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "int" : { + + } + }, + "staticContext" : { + "className" : { + "_0" : "MathUtils" + } + } + }, + { + "abiName" : "bjs_MathUtils_multiply", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "multiply", + "parameters" : [ + { + "label" : "x", + "name" : "x", + "type" : { + "int" : { + + } + } + }, + { + "label" : "y", + "name" : "y", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "int" : { + + } + } + } + ], + "name" : "MathUtils", + "properties" : [ + + ], + "swiftCallName" : "MathUtils" + } + ], + "enums" : [ + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "scientific" + }, + { + "associatedValues" : [ + + ], + "name" : "basic" + } + ], + "emitStyle" : "const", + "name" : "Calculator", + "staticMethods" : [ + { + "abiName" : "bjs_Calculator_static_square", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "name" : "square", + "parameters" : [ + { + "label" : "value", + "name" : "value", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "int" : { + + } + }, + "staticContext" : { + "enumName" : { + "_0" : "Calculator" + } + } + } + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Calculator", + "tsFullPath" : "Calculator" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "failure" + } + ], + "emitStyle" : "const", + "name" : "APIResult", + "staticMethods" : [ + { + "abiName" : "bjs_APIResult_static_roundtrip", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "name" : "roundtrip", + "parameters" : [ + { + "label" : "value", + "name" : "value", + "type" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + } + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + }, + "staticContext" : { + "enumName" : { + "_0" : "APIResult" + } + } + } + ], + "staticProperties" : [ + + ], + "swiftCallName" : "APIResult", + "tsFullPath" : "APIResult" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "Utils", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Utils", + "tsFullPath" : "Utils" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "String", + "namespace" : [ + "Utils" + ], + "staticMethods" : [ + { + "abiName" : "bjs_Utils_String_static_uppercase", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "name" : "uppercase", + "namespace" : [ + "Utils", + "String" + ], + "parameters" : [ + { + "label" : "_", + "name" : "text", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + }, + "staticContext" : { + "namespaceEnum" : { + + } + } + } + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Utils.String", + "tsFullPath" : "Utils.String" + } + ], + "exposeToGlobal" : true, + "functions" : [ + + ], + "moduleName" : "TestModule", + "protocols" : [ + + ] +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.Global.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.Global.swift new file mode 100644 index 00000000..7aa91b91 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.Global.swift @@ -0,0 +1,192 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +@_spi(BridgeJS) import JavaScriptKit + +extension Calculator: _BridgedSwiftCaseEnum { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> Calculator { + return bridgeJSLiftParameter(value) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> Calculator { + return Calculator(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSLowerParameter() + } + + private init?(bridgeJSRawValue: Int32) { + switch bridgeJSRawValue { + case 0: + self = .scientific + case 1: + self = .basic + default: + return nil + } + } + + private var bridgeJSRawValue: Int32 { + switch self { + case .scientific: + return 0 + case .basic: + return 1 + } + } +} + +@_expose(wasm, "bjs_Calculator_static_square") +@_cdecl("bjs_Calculator_static_square") +public func _bjs_Calculator_static_square(value: Int32) -> Int32 { + #if arch(wasm32) + let ret = Calculator.square(value: Int.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension APIResult: _BridgedSwiftAssociatedValueEnum { + private static func _bridgeJSLiftFromCaseId(_ caseId: Int32) -> APIResult { + switch caseId { + case 0: + return .success(String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 1: + return .failure(Int.bridgeJSLiftParameter(_swift_js_pop_param_int32())) + default: + fatalError("Unknown APIResult case ID: \(caseId)") + } + } + + // MARK: Protocol Export + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + switch self { + case .success(let param0): + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) + } + return Int32(0) + case .failure(let param0): + _swift_js_push_int(Int32(param0)) + return Int32(1) + } + } + + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ caseId: Int32) -> APIResult { + return _bridgeJSLiftFromCaseId(caseId) + } + + // MARK: ExportSwift + + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ caseId: Int32) -> APIResult { + return _bridgeJSLiftFromCaseId(caseId) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_push_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) + } + case .failure(let param0): + _swift_js_push_tag(Int32(1)) + _swift_js_push_int(Int32(param0)) + } + } +} + +@_expose(wasm, "bjs_APIResult_static_roundtrip") +@_cdecl("bjs_APIResult_static_roundtrip") +public func _bjs_APIResult_static_roundtrip(value: Int32) -> Void { + #if arch(wasm32) + let ret = APIResult.roundtrip(value: APIResult.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Utils_String_static_uppercase") +@_cdecl("bjs_Utils_String_static_uppercase") +public func _bjs_Utils_String_static_uppercase(textBytes: Int32, textLength: Int32) -> Void { + #if arch(wasm32) + let ret = Utils.String.uppercase(_: String.bridgeJSLiftParameter(textBytes, textLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_MathUtils_init") +@_cdecl("bjs_MathUtils_init") +public func _bjs_MathUtils_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = MathUtils() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_MathUtils_static_subtract") +@_cdecl("bjs_MathUtils_static_subtract") +public func _bjs_MathUtils_static_subtract(a: Int32, b: Int32) -> Int32 { + #if arch(wasm32) + let ret = MathUtils.subtract(a: Int.bridgeJSLiftParameter(a), b: Int.bridgeJSLiftParameter(b)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_MathUtils_static_add") +@_cdecl("bjs_MathUtils_static_add") +public func _bjs_MathUtils_static_add(a: Int32, b: Int32) -> Int32 { + #if arch(wasm32) + let ret = MathUtils.add(a: Int.bridgeJSLiftParameter(a), b: Int.bridgeJSLiftParameter(b)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_MathUtils_multiply") +@_cdecl("bjs_MathUtils_multiply") +public func _bjs_MathUtils_multiply(_self: UnsafeMutableRawPointer, x: Int32, y: Int32) -> Int32 { + #if arch(wasm32) + let ret = MathUtils.bridgeJSLiftParameter(_self).multiply(x: Int.bridgeJSLiftParameter(x), y: Int.bridgeJSLiftParameter(y)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_MathUtils_deinit") +@_cdecl("bjs_MathUtils_deinit") +public func _bjs_MathUtils_deinit(pointer: UnsafeMutableRawPointer) { + Unmanaged.fromOpaque(pointer).release() +} + +extension MathUtils: ConvertibleToJSValue, _BridgedSwiftHeapObject { + var jsValue: JSValue { + #if arch(wasm32) + @_extern(wasm, module: "TestModule", name: "bjs_MathUtils_wrap") + func _bjs_MathUtils_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_MathUtils_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif + return .object(JSObject(id: UInt32(bitPattern: _bjs_MathUtils_wrap(Unmanaged.passRetained(self).toOpaque())))) + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.json index 705de937..13f707bd 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.json @@ -323,6 +323,7 @@ "tsFullPath" : "Utils.String" } ], + "exposeToGlobal" : false, "functions" : [ ], diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.Global.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.Global.json new file mode 100644 index 00000000..d7af9918 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.Global.json @@ -0,0 +1,337 @@ +{ + "classes" : [ + { + "constructor" : { + "abiName" : "bjs_PropertyClass_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + + ], + "name" : "PropertyClass", + "properties" : [ + { + "isReadonly" : true, + "isStatic" : true, + "name" : "staticConstant", + "staticContext" : { + "className" : { + "_0" : "PropertyClass" + } + }, + "type" : { + "string" : { + + } + } + }, + { + "isReadonly" : false, + "isStatic" : true, + "name" : "staticVariable", + "staticContext" : { + "className" : { + "_0" : "PropertyClass" + } + }, + "type" : { + "int" : { + + } + } + }, + { + "isReadonly" : false, + "isStatic" : true, + "name" : "jsObjectProperty", + "staticContext" : { + "className" : { + "_0" : "PropertyClass" + } + }, + "type" : { + "jsObject" : { + + } + } + }, + { + "isReadonly" : false, + "isStatic" : true, + "name" : "classVariable", + "staticContext" : { + "className" : { + "_0" : "PropertyClass" + } + }, + "type" : { + "string" : { + + } + } + }, + { + "isReadonly" : false, + "isStatic" : true, + "name" : "computedProperty", + "staticContext" : { + "className" : { + "_0" : "PropertyClass" + } + }, + "type" : { + "string" : { + + } + } + }, + { + "isReadonly" : true, + "isStatic" : true, + "name" : "readOnlyComputed", + "staticContext" : { + "className" : { + "_0" : "PropertyClass" + } + }, + "type" : { + "int" : { + + } + } + }, + { + "isReadonly" : false, + "isStatic" : true, + "name" : "optionalProperty", + "staticContext" : { + "className" : { + "_0" : "PropertyClass" + } + }, + "type" : { + "optional" : { + "_0" : { + "string" : { + + } + } + } + } + } + ], + "swiftCallName" : "PropertyClass" + } + ], + "enums" : [ + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "value1" + }, + { + "associatedValues" : [ + + ], + "name" : "value2" + } + ], + "emitStyle" : "const", + "name" : "PropertyEnum", + "staticMethods" : [ + + ], + "staticProperties" : [ + { + "isReadonly" : false, + "isStatic" : true, + "name" : "enumProperty", + "staticContext" : { + "enumName" : { + "_0" : "PropertyEnum" + } + }, + "type" : { + "string" : { + + } + } + }, + { + "isReadonly" : true, + "isStatic" : true, + "name" : "enumConstant", + "staticContext" : { + "enumName" : { + "_0" : "PropertyEnum" + } + }, + "type" : { + "int" : { + + } + } + }, + { + "isReadonly" : false, + "isStatic" : true, + "name" : "computedEnum", + "staticContext" : { + "enumName" : { + "_0" : "PropertyEnum" + } + }, + "type" : { + "string" : { + + } + } + } + ], + "swiftCallName" : "PropertyEnum", + "tsFullPath" : "PropertyEnum" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "PropertyNamespace", + "staticMethods" : [ + + ], + "staticProperties" : [ + { + "isReadonly" : false, + "isStatic" : true, + "name" : "namespaceProperty", + "namespace" : [ + "PropertyNamespace" + ], + "staticContext" : { + "namespaceEnum" : { + + } + }, + "type" : { + "string" : { + + } + } + }, + { + "isReadonly" : true, + "isStatic" : true, + "name" : "namespaceConstant", + "namespace" : [ + "PropertyNamespace" + ], + "staticContext" : { + "namespaceEnum" : { + + } + }, + "type" : { + "string" : { + + } + } + } + ], + "swiftCallName" : "PropertyNamespace", + "tsFullPath" : "PropertyNamespace" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "Nested", + "namespace" : [ + "PropertyNamespace" + ], + "staticMethods" : [ + + ], + "staticProperties" : [ + { + "isReadonly" : false, + "isStatic" : true, + "name" : "nestedProperty", + "namespace" : [ + "PropertyNamespace", + "Nested" + ], + "staticContext" : { + "namespaceEnum" : { + + } + }, + "type" : { + "int" : { + + } + } + }, + { + "isReadonly" : true, + "isStatic" : true, + "name" : "nestedConstant", + "namespace" : [ + "PropertyNamespace", + "Nested" + ], + "staticContext" : { + "namespaceEnum" : { + + } + }, + "type" : { + "string" : { + + } + } + }, + { + "isReadonly" : false, + "isStatic" : true, + "name" : "nestedDouble", + "namespace" : [ + "PropertyNamespace", + "Nested" + ], + "staticContext" : { + "namespaceEnum" : { + + } + }, + "type" : { + "double" : { + + } + } + } + ], + "swiftCallName" : "PropertyNamespace.Nested", + "tsFullPath" : "PropertyNamespace.Nested" + } + ], + "exposeToGlobal" : true, + "functions" : [ + + ], + "moduleName" : "TestModule", + "protocols" : [ + + ] +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.Global.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.Global.swift new file mode 100644 index 00000000..72d561a0 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.Global.swift @@ -0,0 +1,338 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +@_spi(BridgeJS) import JavaScriptKit + +extension PropertyEnum: _BridgedSwiftCaseEnum { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> PropertyEnum { + return bridgeJSLiftParameter(value) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> PropertyEnum { + return PropertyEnum(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSLowerParameter() + } + + private init?(bridgeJSRawValue: Int32) { + switch bridgeJSRawValue { + case 0: + self = .value1 + case 1: + self = .value2 + default: + return nil + } + } + + private var bridgeJSRawValue: Int32 { + switch self { + case .value1: + return 0 + case .value2: + return 1 + } + } +} + +@_expose(wasm, "bjs_PropertyEnum_static_enumProperty_get") +@_cdecl("bjs_PropertyEnum_static_enumProperty_get") +public func _bjs_PropertyEnum_static_enumProperty_get() -> Void { + #if arch(wasm32) + let ret = PropertyEnum.enumProperty + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyEnum_static_enumProperty_set") +@_cdecl("bjs_PropertyEnum_static_enumProperty_set") +public func _bjs_PropertyEnum_static_enumProperty_set(valueBytes: Int32, valueLength: Int32) -> Void { + #if arch(wasm32) + PropertyEnum.enumProperty = String.bridgeJSLiftParameter(valueBytes, valueLength) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyEnum_static_enumConstant_get") +@_cdecl("bjs_PropertyEnum_static_enumConstant_get") +public func _bjs_PropertyEnum_static_enumConstant_get() -> Int32 { + #if arch(wasm32) + let ret = PropertyEnum.enumConstant + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyEnum_static_computedEnum_get") +@_cdecl("bjs_PropertyEnum_static_computedEnum_get") +public func _bjs_PropertyEnum_static_computedEnum_get() -> Void { + #if arch(wasm32) + let ret = PropertyEnum.computedEnum + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyEnum_static_computedEnum_set") +@_cdecl("bjs_PropertyEnum_static_computedEnum_set") +public func _bjs_PropertyEnum_static_computedEnum_set(valueBytes: Int32, valueLength: Int32) -> Void { + #if arch(wasm32) + PropertyEnum.computedEnum = String.bridgeJSLiftParameter(valueBytes, valueLength) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyNamespace_static_namespaceProperty_get") +@_cdecl("bjs_PropertyNamespace_static_namespaceProperty_get") +public func _bjs_PropertyNamespace_static_namespaceProperty_get() -> Void { + #if arch(wasm32) + let ret = PropertyNamespace.namespaceProperty + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyNamespace_static_namespaceProperty_set") +@_cdecl("bjs_PropertyNamespace_static_namespaceProperty_set") +public func _bjs_PropertyNamespace_static_namespaceProperty_set(valueBytes: Int32, valueLength: Int32) -> Void { + #if arch(wasm32) + PropertyNamespace.namespaceProperty = String.bridgeJSLiftParameter(valueBytes, valueLength) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyNamespace_static_namespaceConstant_get") +@_cdecl("bjs_PropertyNamespace_static_namespaceConstant_get") +public func _bjs_PropertyNamespace_static_namespaceConstant_get() -> Void { + #if arch(wasm32) + let ret = PropertyNamespace.namespaceConstant + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyNamespace_Nested_static_nestedProperty_get") +@_cdecl("bjs_PropertyNamespace_Nested_static_nestedProperty_get") +public func _bjs_PropertyNamespace_Nested_static_nestedProperty_get() -> Int32 { + #if arch(wasm32) + let ret = PropertyNamespace.Nested.nestedProperty + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyNamespace_Nested_static_nestedProperty_set") +@_cdecl("bjs_PropertyNamespace_Nested_static_nestedProperty_set") +public func _bjs_PropertyNamespace_Nested_static_nestedProperty_set(value: Int32) -> Void { + #if arch(wasm32) + PropertyNamespace.Nested.nestedProperty = Int.bridgeJSLiftParameter(value) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyNamespace_Nested_static_nestedConstant_get") +@_cdecl("bjs_PropertyNamespace_Nested_static_nestedConstant_get") +public func _bjs_PropertyNamespace_Nested_static_nestedConstant_get() -> Void { + #if arch(wasm32) + let ret = PropertyNamespace.Nested.nestedConstant + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyNamespace_Nested_static_nestedDouble_get") +@_cdecl("bjs_PropertyNamespace_Nested_static_nestedDouble_get") +public func _bjs_PropertyNamespace_Nested_static_nestedDouble_get() -> Float64 { + #if arch(wasm32) + let ret = PropertyNamespace.Nested.nestedDouble + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyNamespace_Nested_static_nestedDouble_set") +@_cdecl("bjs_PropertyNamespace_Nested_static_nestedDouble_set") +public func _bjs_PropertyNamespace_Nested_static_nestedDouble_set(value: Float64) -> Void { + #if arch(wasm32) + PropertyNamespace.Nested.nestedDouble = Double.bridgeJSLiftParameter(value) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyClass_init") +@_cdecl("bjs_PropertyClass_init") +public func _bjs_PropertyClass_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = PropertyClass() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyClass_static_staticConstant_get") +@_cdecl("bjs_PropertyClass_static_staticConstant_get") +public func _bjs_PropertyClass_static_staticConstant_get() -> Void { + #if arch(wasm32) + let ret = PropertyClass.staticConstant + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyClass_static_staticVariable_get") +@_cdecl("bjs_PropertyClass_static_staticVariable_get") +public func _bjs_PropertyClass_static_staticVariable_get() -> Int32 { + #if arch(wasm32) + let ret = PropertyClass.staticVariable + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyClass_static_staticVariable_set") +@_cdecl("bjs_PropertyClass_static_staticVariable_set") +public func _bjs_PropertyClass_static_staticVariable_set(value: Int32) -> Void { + #if arch(wasm32) + PropertyClass.staticVariable = Int.bridgeJSLiftParameter(value) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyClass_static_jsObjectProperty_get") +@_cdecl("bjs_PropertyClass_static_jsObjectProperty_get") +public func _bjs_PropertyClass_static_jsObjectProperty_get() -> Int32 { + #if arch(wasm32) + let ret = PropertyClass.jsObjectProperty + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyClass_static_jsObjectProperty_set") +@_cdecl("bjs_PropertyClass_static_jsObjectProperty_set") +public func _bjs_PropertyClass_static_jsObjectProperty_set(value: Int32) -> Void { + #if arch(wasm32) + PropertyClass.jsObjectProperty = JSObject.bridgeJSLiftParameter(value) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyClass_static_classVariable_get") +@_cdecl("bjs_PropertyClass_static_classVariable_get") +public func _bjs_PropertyClass_static_classVariable_get() -> Void { + #if arch(wasm32) + let ret = PropertyClass.classVariable + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyClass_static_classVariable_set") +@_cdecl("bjs_PropertyClass_static_classVariable_set") +public func _bjs_PropertyClass_static_classVariable_set(valueBytes: Int32, valueLength: Int32) -> Void { + #if arch(wasm32) + PropertyClass.classVariable = String.bridgeJSLiftParameter(valueBytes, valueLength) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyClass_static_computedProperty_get") +@_cdecl("bjs_PropertyClass_static_computedProperty_get") +public func _bjs_PropertyClass_static_computedProperty_get() -> Void { + #if arch(wasm32) + let ret = PropertyClass.computedProperty + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyClass_static_computedProperty_set") +@_cdecl("bjs_PropertyClass_static_computedProperty_set") +public func _bjs_PropertyClass_static_computedProperty_set(valueBytes: Int32, valueLength: Int32) -> Void { + #if arch(wasm32) + PropertyClass.computedProperty = String.bridgeJSLiftParameter(valueBytes, valueLength) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyClass_static_readOnlyComputed_get") +@_cdecl("bjs_PropertyClass_static_readOnlyComputed_get") +public func _bjs_PropertyClass_static_readOnlyComputed_get() -> Int32 { + #if arch(wasm32) + let ret = PropertyClass.readOnlyComputed + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyClass_static_optionalProperty_get") +@_cdecl("bjs_PropertyClass_static_optionalProperty_get") +public func _bjs_PropertyClass_static_optionalProperty_get() -> Void { + #if arch(wasm32) + let ret = PropertyClass.optionalProperty + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyClass_static_optionalProperty_set") +@_cdecl("bjs_PropertyClass_static_optionalProperty_set") +public func _bjs_PropertyClass_static_optionalProperty_set(valueIsSome: Int32, valueBytes: Int32, valueLength: Int32) -> Void { + #if arch(wasm32) + PropertyClass.optionalProperty = Optional.bridgeJSLiftParameter(valueIsSome, valueBytes, valueLength) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PropertyClass_deinit") +@_cdecl("bjs_PropertyClass_deinit") +public func _bjs_PropertyClass_deinit(pointer: UnsafeMutableRawPointer) { + Unmanaged.fromOpaque(pointer).release() +} + +extension PropertyClass: ConvertibleToJSValue, _BridgedSwiftHeapObject { + var jsValue: JSValue { + #if arch(wasm32) + @_extern(wasm, module: "TestModule", name: "bjs_PropertyClass_wrap") + func _bjs_PropertyClass_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_PropertyClass_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif + return .object(JSObject(id: UInt32(bitPattern: _bjs_PropertyClass_wrap(Unmanaged.passRetained(self).toOpaque())))) + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.json index 1c5cdd6a..fb3a12b6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.json @@ -326,6 +326,7 @@ "tsFullPath" : "PropertyNamespace.Nested" } ], + "exposeToGlobal" : false, "functions" : [ ], diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringParameter.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringParameter.json index cf6b0025..bec03d8f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringParameter.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringParameter.json @@ -5,6 +5,7 @@ "enums" : [ ], + "exposeToGlobal" : false, "functions" : [ { "abiName" : "bjs_checkString", diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringReturn.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringReturn.json index f34a04f9..86221037 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringReturn.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringReturn.json @@ -5,6 +5,7 @@ "enums" : [ ], + "exposeToGlobal" : false, "functions" : [ { "abiName" : "bjs_checkString", diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClass.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClass.json index fc99462b..9f1f934e 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClass.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClass.json @@ -105,6 +105,7 @@ "enums" : [ ], + "exposeToGlobal" : false, "functions" : [ { "abiName" : "bjs_takeGreeter", diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClosure.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClosure.json index d6518fc6..2a8a6404 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClosure.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClosure.json @@ -1062,6 +1062,7 @@ "tsFullPath" : "APIResult" } ], + "exposeToGlobal" : false, "functions" : [ ], diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Throws.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Throws.json index d8533915..9b2e6104 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Throws.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Throws.json @@ -5,6 +5,7 @@ "enums" : [ ], + "exposeToGlobal" : false, "functions" : [ { "abiName" : "bjs_throwsSomething", diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/VoidParameterVoidReturn.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/VoidParameterVoidReturn.json index df3f5041..508107ee 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/VoidParameterVoidReturn.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/VoidParameterVoidReturn.json @@ -5,6 +5,7 @@ "enums" : [ ], + "exposeToGlobal" : false, "functions" : [ { "abiName" : "bjs_check", diff --git a/Plugins/PackageToJS/Sources/PackageToJS.swift b/Plugins/PackageToJS/Sources/PackageToJS.swift index 9576c2b7..ec984043 100644 --- a/Plugins/PackageToJS/Sources/PackageToJS.swift +++ b/Plugins/PackageToJS/Sources/PackageToJS.swift @@ -613,8 +613,7 @@ struct PackagingPlanner { let data = try Data(contentsOf: URL(fileURLWithPath: scope.resolve(path: $0).path)) return try decoder.decode(ImportedModuleSkeleton.self, from: data) }, - sharedMemory: Self.isSharedMemoryEnabled(triple: triple), - exposeToGlobal: true + sharedMemory: Self.isSharedMemoryEnabled(triple: triple) ) let (outputJs, outputDts) = try link.link() try system.writeFile(atPath: scope.resolve(path: bridgeJs).path, content: Data(outputJs.utf8)) diff --git a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/BridgeJS-Configuration.md b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/BridgeJS-Configuration.md index 835cf6be..78b5d2d3 100644 --- a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/BridgeJS-Configuration.md +++ b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/BridgeJS-Configuration.md @@ -38,14 +38,51 @@ Later files override settings from earlier files. This allows teams to commit a ## Configuration Options +### `exposeToGlobal` + +Controls whether exported Swift APIs are exposed to the JavaScript global namespace (`globalThis`). + +When `true`, exported functions, classes, and namespaces are available via `globalThis` in JavaScript. When `false`, they are only available through the exports object returned by `createExports()`. +Using Exports provides better module isolation and support multiple WebAssembly instances in the same JavaScript context. + +Example: + +```json +{ + "exposeToGlobal": true +} +``` + +**With `exposeToGlobal: true`:** + +```javascript +// APIs available on globalThis +const greeter = new globalThis.MyModule.Greeter("World"); +console.log(greeter.greet()); // "Hello, World!" + +// Also available via exports +const greeter2 = new exports.MyModule.Greeter("Alice"); +``` + +**With `exposeToGlobal: false` (default):** + +```javascript +// APIs only available via exports +const greeter = new exports.MyModule.Greeter("World"); + +// globalThis.MyModule is undefined +``` + ### `tools` Specify custom paths for external executables. This is particularly useful when working in environments like Xcode where the system PATH may not be inherited, or when you need to use a specific version of tools for your project. Currently supported tools: + - `node` - Node.js runtime (required for TypeScript processing) Example: + ```json { "tools": { @@ -59,4 +96,3 @@ BridgeJS resolves tool paths in the following priority order: 1. **Configuration files** (`bridge-js.config.local.json` > `bridge-js.config.json`) 2. **Environment variables** (`JAVASCRIPTKIT_NODE_EXEC`) 3. **System PATH lookup** - diff --git a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Exporting-Swift/Using-Namespace.md b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Exporting-Swift/Using-Namespace.md index 427dd597..0c4027b7 100644 --- a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Exporting-Swift/Using-Namespace.md +++ b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Exporting-Swift/Using-Namespace.md @@ -73,18 +73,20 @@ import JavaScriptKit } ``` -In JavaScript, this class is accessible through its namespace in two ways: +In JavaScript, this class is accessible through its namespace: ```javascript -// Recommended: Access via the exports object (supports multiple WASM instances) +// Always available: Access via the exports object (supports multiple WASM instances) const greeter = new exports.__Swift.Foundation.Greeter("World"); console.log(greeter.greet()); // "Hello, World!" -// Alternative: Access via globalThis and through its namespace +// When exposeToGlobal: true - Also available via globalThis const greeter = new globalThis.__Swift.Foundation.Greeter("World"); console.log(greeter.greet()); // "Hello, World!" ``` +> Note: Global namespace access via `globalThis` is only available when `exposeToGlobal: true` is set in your `bridge-js.config.json`. See for more details. + The generated TypeScript declaration will organize the class within its namespace: ```typescript @@ -114,4 +116,4 @@ export interface Greeter extends SwiftHeapObject { } ``` -Using namespaces can be preferable for projects with many global functions, as they help prevent naming collisions. Namespaces also provide intuitive hierarchies for organizing your exported Swift code, and they do not affect the code generated by `@JS` declarations without namespaces. \ No newline at end of file +Using namespaces can be preferable for projects with many global functions, as they help prevent naming collisions. Namespaces also provide intuitive hierarchies for organizing your exported Swift code, and they do not affect the code generated by `@JS` declarations without namespaces. diff --git a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json index c1877ab3..69564e72 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json +++ b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json @@ -4469,6 +4469,7 @@ "tsFullPath" : "StaticPropertyNamespace.NestedProperties" } ], + "exposeToGlobal" : false, "functions" : [ { "abiName" : "bjs_roundTripVoid", diff --git a/Tests/BridgeJSRuntimeTests/bridge-js.config.exposeToGlobal.json b/Tests/BridgeJSRuntimeTests/bridge-js.config.exposeToGlobal.json new file mode 100644 index 00000000..b1b55698 --- /dev/null +++ b/Tests/BridgeJSRuntimeTests/bridge-js.config.exposeToGlobal.json @@ -0,0 +1,3 @@ +{ + "exposeToGlobal": true +} \ No newline at end of file diff --git a/Tests/BridgeJSRuntimeTests/bridge-js.config.json b/Tests/BridgeJSRuntimeTests/bridge-js.config.json index 9e26dfee..55a95efa 100644 --- a/Tests/BridgeJSRuntimeTests/bridge-js.config.json +++ b/Tests/BridgeJSRuntimeTests/bridge-js.config.json @@ -1 +1,3 @@ -{} \ No newline at end of file +{ + "exposeToGlobal": false +} \ No newline at end of file diff --git a/Tests/prelude.exposeToGlobal.mjs b/Tests/prelude.exposeToGlobal.mjs new file mode 100644 index 00000000..47e36b4d --- /dev/null +++ b/Tests/prelude.exposeToGlobal.mjs @@ -0,0 +1,248 @@ +/** @type {import('../.build/plugins/PackageToJS/outputs/PackageTests/test.d.ts').SetupOptionsFn} */ +export async function setupOptions(options, context) { + Error.stackTraceLimit = 100; + setupTestGlobals(globalThis); + return { + ...options, + getImports: (importsContext) => { + return { + "jsRoundTripVoid": () => { + return; + }, + "jsRoundTripNumber": (v) => { + return v; + }, + "jsRoundTripBool": (v) => { + return v; + }, + "jsRoundTripString": (v) => { + return v; + }, + "jsThrowOrVoid": (shouldThrow) => { + if (shouldThrow) { + throw new Error("TestError"); + } + }, + "jsThrowOrNumber": (shouldThrow) => { + if (shouldThrow) { + throw new Error("TestError"); + } + return 1; + }, + "jsThrowOrBool": (shouldThrow) => { + if (shouldThrow) { + throw new Error("TestError"); + } + return true; + }, + "jsThrowOrString": (shouldThrow) => { + if (shouldThrow) { + throw new Error("TestError"); + } + return "Hello, world!"; + }, + JsGreeter: class { + /** + * @param {string} name + * @param {string} prefix + */ + constructor(name, prefix) { + this.name = name; + this.prefix = prefix; + } + greet() { + return `${this.prefix}, ${this.name}!`; + } + /** @param {string} name */ + changeName(name) { + this.name = name; + } + }, + runAsyncWorks: async () => { + const exports = importsContext.getExports(); + if (!exports) { + throw new Error("No exports!?"); + } + BridgeJSRuntimeTests_runAsyncWorks(exports); + return; + } + }; + }, + addToCoreImports(importObject, importsContext) { + const { getInstance, getExports } = importsContext; + options.addToCoreImports?.(importObject, importsContext); + importObject["JavaScriptEventLoopTestSupportTests"] = { + "isMainThread": () => context.isMainThread, + } + const bridgeJSRuntimeTests = importObject["BridgeJSRuntimeTests"] || {}; + bridgeJSRuntimeTests["runJsWorks"] = () => { + const exports = getExports(); + if (!exports) { + throw new Error("No exports!?"); + } + return BridgeJSRuntimeTests_runJsWorks(getInstance(), exports); + } + importObject["BridgeJSRuntimeTests"] = bridgeJSRuntimeTests; + } + } +} + +import assert from "node:assert"; + +/** @param {import('./../.build/plugins/PackageToJS/outputs/PackageTests/bridge-js.d.ts').Exports} exports */ +function BridgeJSRuntimeTests_runJsWorks(instance, exports) { + // Repetition tests to satisfy testAll + const g = new exports.Greeter("John"); + g.release(); + const calc = exports.createCalculator(); + calc.release(); + + assert.equal(globalThis.Networking.API.MethodValues.Get, 0); + assert.equal(globalThis.Networking.API.MethodValues.Post, 1); + assert.equal(globalThis.Networking.API.MethodValues.Put, 2); + assert.equal(globalThis.Networking.API.MethodValues.Delete, 3); + + assert.equal(globalThis.Configuration.LogLevelValues.Debug, "debug"); + assert.equal(globalThis.Configuration.LogLevelValues.Info, "info"); + assert.equal(globalThis.Configuration.LogLevelValues.Warning, "warning"); + assert.equal(globalThis.Configuration.LogLevelValues.Error, "error"); + assert.equal(globalThis.Configuration.PortValues.Http, 80); + assert.equal(globalThis.Configuration.PortValues.Https, 443); + assert.equal(globalThis.Configuration.PortValues.Development, 3000); + + assert.equal(globalThis.Networking.APIV2.Internal.SupportedMethodValues.Get, 0); + assert.equal(globalThis.Networking.APIV2.Internal.SupportedMethodValues.Post, 1); + + const globalConverter = new globalThis.Utils.Converter(); + assert.equal(globalConverter.toString(99), "99"); + globalConverter.release(); + + const globalHttpServer = new globalThis.Networking.API.HTTPServer(); + globalHttpServer.call(globalThis.Networking.API.MethodValues.Get); + globalHttpServer.release(); + + const globalTestServer = new globalThis.Networking.APIV2.Internal.TestServer(); + globalTestServer.call(globalThis.Networking.APIV2.Internal.SupportedMethodValues.Post); + globalTestServer.release(); + + assert.equal(globalThis.StaticPropertyNamespace.namespaceProperty, "namespace"); + assert.equal(globalThis.StaticPropertyNamespace.namespaceConstant, "constant"); + + globalThis.StaticPropertyNamespace.namespaceProperty = "modified namespace"; + assert.equal(globalThis.StaticPropertyNamespace.namespaceProperty, "modified namespace"); + + assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedProperty, 999); + assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedConstant, "nested"); + assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedDouble, 1.414); + + globalThis.StaticPropertyNamespace.NestedProperties.nestedProperty = 1000; + globalThis.StaticPropertyNamespace.NestedProperties.nestedDouble = 2.828; + assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedProperty, 1000); + assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedDouble, 2.828); + + // // Verify both globalThis and exports point to same objects + // assert.equal(globalThis.StaticPropertyNamespace.namespaceProperty, exports.StaticPropertyNamespace.namespaceProperty); + // assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedProperty, exports.StaticPropertyNamespace.NestedProperties.nestedProperty); + + // // Verify enum values accessible via globalThis match exports + // assert.equal(exports.Configuration.LogLevel.Debug, globalThis.Configuration.LogLevelValues.Debug); + // assert.equal(exports.Networking.API.Method.Get, globalThis.Networking.API.MethodValues.Get); +} + +/** @param {import('./../.build/plugins/PackageToJS/outputs/PackageTests/bridge-js.d.ts').Exports} exports */ +async function BridgeJSRuntimeTests_runAsyncWorks(exports) { + await exports.asyncRoundTripVoid(); +} + +function setupTestGlobals(global) { + global.globalObject1 = { + prop_1: { + nested_prop: 1, + }, + prop_2: 2, + prop_3: true, + prop_4: [3, 4, "str_elm_1", null, undefined, 5], + prop_5: { + func1: function () { + return; + }, + func2: function () { + return 1; + }, + func3: function (n) { + return n * 2; + }, + func4: function (a, b, c) { + return a + b + c; + }, + func5: function (x) { + return "Hello, " + x; + }, + func6: function (c, a, b) { + if (c) { + return a; + } else { + return b; + } + }, + }, + prop_6: { + call_host_1: () => { + return global.globalObject1.prop_6.host_func_1(); + }, + }, + prop_7: 3.14, + prop_8: [0, , 2, 3, , , 6], + eval_closure: function (fn) { + return fn(arguments[1]); + }, + observable_obj: { + set_called: false, + target: new Proxy( + { + nested: {}, + }, + { + set(target, key, value) { + global.globalObject1.observable_obj.set_called = true; + target[key] = value; + return true; + }, + } + ), + }, + }; + + global.Animal = function (name, age, isCat) { + if (age < 0) { + throw new Error("Invalid age " + age); + } + this.name = name; + this.age = age; + this.bark = () => { + return isCat ? "nyan" : "wan"; + }; + this.isCat = isCat; + this.getIsCat = function () { + return this.isCat; + }; + this.setName = function (name) { + this.name = name; + }; + }; + + global.callThrowingClosure = (c) => { + try { + c(); + } catch (error) { + return error; + } + }; + + global.objectDecodingTest = { + obj: {}, + fn: () => { }, + sym: Symbol("s"), + bi: BigInt(3) + }; +} diff --git a/Tests/prelude.mjs b/Tests/prelude.mjs index 77123fec..640a6561 100644 --- a/Tests/prelude.mjs +++ b/Tests/prelude.mjs @@ -341,36 +341,20 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { assert.equal(exports.StaticPropertyEnum.enumVariable, 500); // Namespace enum static properties - assert.equal(globalThis.StaticPropertyNamespace.namespaceProperty, "namespace"); - assert.equal(globalThis.StaticPropertyNamespace.namespaceConstant, "constant"); - - globalThis.StaticPropertyNamespace.namespaceProperty = "modified namespace"; - assert.equal(globalThis.StaticPropertyNamespace.namespaceProperty, "modified namespace"); - - assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedProperty, 999); - assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedConstant, "nested"); - assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedDouble, 1.414); - - globalThis.StaticPropertyNamespace.NestedProperties.nestedProperty = 1000; - globalThis.StaticPropertyNamespace.NestedProperties.nestedDouble = 2.828; - assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedProperty, 1000); - assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedDouble, 2.828); + assert.equal(exports.StaticPropertyNamespace.namespaceProperty, "namespace"); + assert.equal(exports.StaticPropertyNamespace.namespaceConstant, "constant"); + exports.StaticPropertyNamespace.namespaceProperty = "modified namespace"; assert.equal(exports.StaticPropertyNamespace.namespaceProperty, "modified namespace"); - assert.equal(exports.StaticPropertyNamespace.namespaceConstant, "constant"); - exports.StaticPropertyNamespace.namespaceProperty = "exports modified"; - assert.equal(exports.StaticPropertyNamespace.namespaceProperty, "exports modified"); - assert.equal(globalThis.StaticPropertyNamespace.namespaceProperty, "exports modified"); - assert.equal(exports.StaticPropertyNamespace.NestedProperties.nestedProperty, 1000); + assert.equal(exports.StaticPropertyNamespace.NestedProperties.nestedProperty, 999); assert.equal(exports.StaticPropertyNamespace.NestedProperties.nestedConstant, "nested"); + assert.equal(exports.StaticPropertyNamespace.NestedProperties.nestedDouble, 1.414); + + exports.StaticPropertyNamespace.NestedProperties.nestedProperty = 1000; + exports.StaticPropertyNamespace.NestedProperties.nestedDouble = 2.828; + assert.equal(exports.StaticPropertyNamespace.NestedProperties.nestedProperty, 1000); assert.equal(exports.StaticPropertyNamespace.NestedProperties.nestedDouble, 2.828); - exports.StaticPropertyNamespace.NestedProperties.nestedProperty = 2000; - exports.StaticPropertyNamespace.NestedProperties.nestedDouble = 3.14; - assert.equal(exports.StaticPropertyNamespace.NestedProperties.nestedProperty, 2000); - assert.equal(exports.StaticPropertyNamespace.NestedProperties.nestedDouble, 3.14); - assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedProperty, 2000); - assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedDouble, 3.14); // Test class without @JS init constructor const calc = exports.createCalculator(); @@ -440,21 +424,10 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { assert.equal(exports.setTSTheme(TSTheme.Light), TSTheme.Light); assert.equal(exports.getTSTheme(), TSTheme.Light); - assert.equal(globalThis.Networking.API.MethodValues.Get, 0); - assert.equal(globalThis.Networking.API.MethodValues.Post, 1); - assert.equal(globalThis.Networking.API.MethodValues.Put, 2); - assert.equal(globalThis.Networking.API.MethodValues.Delete, 3); assert.equal(exports.Networking.API.Method.Get, 0); assert.equal(exports.Networking.API.Method.Post, 1); assert.equal(exports.Networking.API.Method.Put, 2); assert.equal(exports.Networking.API.Method.Delete, 3); - assert.equal(globalThis.Configuration.LogLevelValues.Debug, "debug"); - assert.equal(globalThis.Configuration.LogLevelValues.Info, "info"); - assert.equal(globalThis.Configuration.LogLevelValues.Warning, "warning"); - assert.equal(globalThis.Configuration.LogLevelValues.Error, "error"); - assert.equal(globalThis.Configuration.PortValues.Http, 80); - assert.equal(globalThis.Configuration.PortValues.Https, 443); - assert.equal(globalThis.Configuration.PortValues.Development, 3000); assert.equal(exports.Configuration.LogLevel.Debug, "debug"); assert.equal(exports.Configuration.LogLevel.Info, "info"); assert.equal(exports.Configuration.LogLevel.Warning, "warning"); @@ -462,19 +435,16 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { assert.equal(exports.Configuration.Port.Http, 80); assert.equal(exports.Configuration.Port.Https, 443); assert.equal(exports.Configuration.Port.Development, 3000); - assert.equal(globalThis.Networking.APIV2.Internal.SupportedMethodValues.Get, 0); - assert.equal(globalThis.Networking.APIV2.Internal.SupportedMethodValues.Post, 1); assert.equal(exports.Networking.APIV2.Internal.SupportedMethod.Get, 0); assert.equal(exports.Networking.APIV2.Internal.SupportedMethod.Post, 1); - assert.equal(exports.roundtripNetworkingAPIMethod(globalThis.Networking.API.MethodValues.Get), globalThis.Networking.API.MethodValues.Get); - assert.equal(exports.roundtripConfigurationLogLevel(globalThis.Configuration.LogLevelValues.Debug), globalThis.Configuration.LogLevelValues.Debug); - assert.equal(exports.roundtripConfigurationPort(globalThis.Configuration.PortValues.Http), globalThis.Configuration.PortValues.Http); - assert.equal(exports.processConfigurationLogLevel(globalThis.Configuration.LogLevelValues.Debug), globalThis.Configuration.PortValues.Development); - assert.equal(exports.processConfigurationLogLevel(globalThis.Configuration.LogLevelValues.Info), globalThis.Configuration.PortValues.Http); - assert.equal(exports.processConfigurationLogLevel(globalThis.Configuration.LogLevelValues.Warning), globalThis.Configuration.PortValues.Https); - assert.equal(exports.processConfigurationLogLevel(globalThis.Configuration.LogLevelValues.Error), globalThis.Configuration.PortValues.Development); - assert.equal(exports.roundtripInternalSupportedMethod(globalThis.Networking.APIV2.Internal.SupportedMethodValues.Get), globalThis.Networking.APIV2.Internal.SupportedMethodValues.Get); + assert.equal(exports.roundtripNetworkingAPIMethod(exports.Networking.API.Method.Get), exports.Networking.API.Method.Get); + assert.equal(exports.roundtripConfigurationLogLevel(exports.Configuration.LogLevel.Debug), exports.Configuration.LogLevel.Debug); + assert.equal(exports.roundtripConfigurationPort(exports.Configuration.Port.Http), exports.Configuration.Port.Http); + assert.equal(exports.processConfigurationLogLevel(exports.Configuration.LogLevel.Debug), exports.Configuration.Port.Development); + assert.equal(exports.processConfigurationLogLevel(exports.Configuration.LogLevel.Info), exports.Configuration.Port.Http); + assert.equal(exports.processConfigurationLogLevel(exports.Configuration.LogLevel.Warning), exports.Configuration.Port.Https); + assert.equal(exports.roundtripInternalSupportedMethod(exports.Networking.APIV2.Internal.SupportedMethod.Get), exports.Networking.APIV2.Internal.SupportedMethod.Get); const converter = new exports.Utils.Converter(); assert.equal(converter.toString(42), "42"); @@ -482,27 +452,15 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { converter.release(); const httpServer = new exports.Networking.API.HTTPServer(); - httpServer.call(globalThis.Networking.API.MethodValues.Get); - httpServer.call(globalThis.Networking.API.MethodValues.Post); + httpServer.call(exports.Networking.API.Method.Get); + httpServer.call(exports.Networking.API.Method.Post); httpServer.release(); const testServer = new exports.Networking.APIV2.Internal.TestServer(); - testServer.call(globalThis.Networking.APIV2.Internal.SupportedMethodValues.Get); - testServer.call(globalThis.Networking.APIV2.Internal.SupportedMethodValues.Post); + testServer.call(exports.Networking.APIV2.Internal.SupportedMethod.Get); + testServer.call(exports.Networking.APIV2.Internal.SupportedMethod.Post); testServer.release(); - const globalConverter = new globalThis.Utils.Converter(); - assert.equal(globalConverter.toString(99), "99"); - globalConverter.release(); - - const globalHttpServer = new globalThis.Networking.API.HTTPServer(); - globalHttpServer.call(globalThis.Networking.API.MethodValues.Get); - globalHttpServer.release(); - - const globalTestServer = new globalThis.Networking.APIV2.Internal.TestServer(); - globalTestServer.call(globalThis.Networking.APIV2.Internal.SupportedMethodValues.Post); - globalTestServer.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 }; @@ -555,27 +513,27 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { assert.deepEqual(exports.makeComplexResultComprehensive(true, false, 10, 20, 1.5, 2.5, "First", "Second", "Third"), { tag: exports.ComplexResult.Tag.Comprehensive, param0: true, param1: false, param2: 10, param3: 20, param4: 1.5, param5: 2.5, param6: "First", param7: "Second", param8: "Third" }); assert.deepEqual(exports.makeComplexResultInfo(), { tag: exports.ComplexResult.Tag.Info }); - const urSuccess = { tag: globalThis.Utilities.ResultValues.Tag.Success, param0: "Utility operation completed" }; - const urFailure = { tag: globalThis.Utilities.ResultValues.Tag.Failure, param0: "Utility error occurred", param1: 500 }; - const urStatus = { tag: globalThis.Utilities.ResultValues.Tag.Status, param0: true, param1: 200, param2: "Utility status OK" }; + const urSuccess = { tag: exports.Utilities.Result.Tag.Success, param0: "Utility operation completed" }; + const urFailure = { tag: exports.Utilities.Result.Tag.Failure, param0: "Utility error occurred", param1: 500 }; + const urStatus = { tag: exports.Utilities.Result.Tag.Status, param0: true, param1: 200, param2: "Utility status OK" }; assert.deepEqual(exports.roundtripUtilitiesResult(urSuccess), urSuccess); assert.deepEqual(exports.roundtripUtilitiesResult(urFailure), urFailure); assert.deepEqual(exports.roundtripUtilitiesResult(urStatus), urStatus); - assert.deepEqual(exports.makeUtilitiesResultSuccess("Test"), { tag: globalThis.Utilities.ResultValues.Tag.Success, param0: "Test" }); - assert.deepEqual(exports.makeUtilitiesResultSuccess("ok"), { tag: globalThis.Utilities.ResultValues.Tag.Success, param0: "ok" }); - assert.deepEqual(exports.makeUtilitiesResultFailure("Error", 123), { tag: globalThis.Utilities.ResultValues.Tag.Failure, param0: "Error", param1: 123 }); - assert.deepEqual(exports.makeUtilitiesResultStatus(true, 200, "OK"), { tag: globalThis.Utilities.ResultValues.Tag.Status, param0: true, param1: 200, param2: "OK" }); + assert.deepEqual(exports.makeUtilitiesResultSuccess("Test"), { tag: exports.Utilities.Result.Tag.Success, param0: "Test" }); + assert.deepEqual(exports.makeUtilitiesResultSuccess("ok"), { tag: exports.Utilities.Result.Tag.Success, param0: "ok" }); + assert.deepEqual(exports.makeUtilitiesResultFailure("Error", 123), { tag: exports.Utilities.Result.Tag.Failure, param0: "Error", param1: 123 }); + assert.deepEqual(exports.makeUtilitiesResultStatus(true, 200, "OK"), { tag: exports.Utilities.Result.Tag.Status, param0: true, param1: 200, param2: "OK" }); - const nrSuccess = { tag: globalThis.API.NetworkingResultValues.Tag.Success, param0: "Network request successful" }; - const nrFailure = { tag: globalThis.API.NetworkingResultValues.Tag.Failure, param0: "Network timeout", param1: 408 }; + const nrSuccess = { tag: exports.API.NetworkingResult.Tag.Success, param0: "Network request successful" }; + const nrFailure = { tag: exports.API.NetworkingResult.Tag.Failure, param0: "Network timeout", param1: 408 }; assert.deepEqual(exports.roundtripAPINetworkingResult(nrSuccess), nrSuccess); assert.deepEqual(exports.roundtripAPINetworkingResult(nrFailure), nrFailure); - assert.deepEqual(exports.makeAPINetworkingResultSuccess("Connected"), { tag: globalThis.API.NetworkingResultValues.Tag.Success, param0: "Connected" }); - assert.deepEqual(exports.makeAPINetworkingResultFailure("Timeout", 408), { tag: globalThis.API.NetworkingResultValues.Tag.Failure, param0: "Timeout", param1: 408 }); + assert.deepEqual(exports.makeAPINetworkingResultSuccess("Connected"), { tag: exports.API.NetworkingResult.Tag.Success, param0: "Connected" }); + assert.deepEqual(exports.makeAPINetworkingResultFailure("Timeout", 408), { tag: exports.API.NetworkingResult.Tag.Failure, param0: "Timeout", param1: 408 }); assert.equal(exports.roundTripOptionalString(null), null); assert.equal(exports.roundTripOptionalInt(null), null); @@ -604,7 +562,7 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { assert.equal(exports.roundTripOptionalHttpStatus(exports.HttpStatus.Ok), HttpStatusValues.Ok); assert.equal(exports.roundTripOptionalTSDirection(TSDirection.North), TSDirection.North); assert.equal(exports.roundTripOptionalTSTheme(TSTheme.Light), TSTheme.Light); - assert.equal(exports.roundTripOptionalNetworkingAPIMethod(globalThis.Networking.API.MethodValues.Get), globalThis.Networking.API.MethodValues.Get); + assert.equal(exports.roundTripOptionalNetworkingAPIMethod(exports.Networking.API.Method.Get), exports.Networking.API.Method.Get); assert.deepEqual(exports.roundTripOptionalAPIResult(p1), p1); assert.deepEqual(exports.roundTripOptionalComplexResult(cl1), cl1); @@ -671,9 +629,8 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { assert.equal(StaticCalculatorValues.Basic, 1); assert.equal(StaticCalculatorValues.Scientific, exports.StaticCalculator.Scientific); assert.equal(StaticCalculatorValues.Basic, exports.StaticCalculator.Basic); - assert.equal(globalThis.StaticUtils.Nested.roundtrip("hello world"), "hello world"); + assert.equal(exports.StaticUtils.Nested.roundtrip("hello world"), "hello world"); assert.equal(exports.StaticUtils.Nested.roundtrip("test"), "test"); - assert.equal(exports.StaticUtils.Nested.roundtrip("exports api"), "exports api"); // Test default parameters assert.equal(exports.testStringDefault(), "Hello World"); @@ -744,9 +701,9 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { function testClosureSupport(exports) { const upperTransform = (text) => text.toUpperCase(); const processor = new exports.TextProcessor(upperTransform); - + assert.equal(processor.process("hello"), "HELLO"); - + const multiParamTransform = (count, text, ratio) => { return `${text.toUpperCase()}-${count}-${ratio.toFixed(2)}`; }; @@ -767,14 +724,14 @@ function testClosureSupport(exports) { const addDr = exports.makeFormatter("Dr."); assert.equal(addDr("Ada"), "Dr. Ada"); assert.equal(addDr("Grace"), "Dr. Grace"); - + const addProf = exports.makeFormatter("Prof."); assert.equal(addProf("Hopper"), "Prof. Hopper"); const add10 = exports.makeAdder(10); assert.equal(add10(5), 15); assert.equal(add10(32), 42); - + const add100 = exports.makeAdder(100); assert.equal(add100(23), 123); @@ -821,12 +778,12 @@ function testClosureSupport(exports) { return value !== null ? `Got: ${value}` : `Got: null`; }); assert.equal(optResult1, "Got: test | Got: null"); - + const optResult2 = processor.processOptionalInt((value) => { return value !== null ? `Number: ${value}` : `Number: null`; }); assert.equal(optResult2, "Number: 42 | Number: null"); - + const optResult3 = processor.processOptionalGreeter((greeter) => { return greeter !== null ? `Greeter: ${greeter.name}` : `Greeter: null`; }); From 0f70f64d6c781efdfae9da5a32d5f518348a921c Mon Sep 17 00:00:00 2001 From: Krzysztof Rodak Date: Thu, 27 Nov 2025 10:34:07 +0100 Subject: [PATCH 3/4] BridgeJS: Properly treat exposeToGlobal on module level --- .../Sources/BridgeJSLink/BridgeJSLink.swift | 124 ++++++++++-------- 1 file changed, 71 insertions(+), 53 deletions(-) diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift index 23884608..bd32169f 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift @@ -12,7 +12,6 @@ struct BridgeJSLink { var exportedSkeletons: [ExportedSkeleton] = [] var importedSkeletons: [ImportedModuleSkeleton] = [] let sharedMemory: Bool - var exposeToGlobal: Bool private let namespaceBuilder = NamespaceBuilder() init( @@ -23,15 +22,11 @@ struct BridgeJSLink { self.exportedSkeletons = exportedSkeletons self.importedSkeletons = importedSkeletons self.sharedMemory = sharedMemory - self.exposeToGlobal = exportedSkeletons.contains { $0.exposeToGlobal } } mutating func addExportedSkeletonFile(data: Data) throws { let skeleton = try JSONDecoder().decode(ExportedSkeleton.self, from: data) exportedSkeletons.append(skeleton) - if skeleton.exposeToGlobal { - exposeToGlobal = true - } } mutating func addImportedSkeletonFile(data: Data) throws { @@ -929,7 +924,6 @@ struct BridgeJSLink { // Type definitions section (namespace declarations, class definitions, imported types) let namespaceDeclarationsLines = namespaceBuilder.namespaceDeclarations( exportedSkeletons: exportedSkeletons, - exposeToGlobal: exposeToGlobal, renderTSSignatureCallback: { parameters, returnType, effects in self.renderTSSignature(parameters: parameters, returnType: returnType, effects: effects) } @@ -1012,8 +1006,7 @@ struct BridgeJSLink { printer.write(lines: data.topLevelEnumLines) let topLevelNamespaceCode = namespaceBuilder.buildTopLevelNamespaceInitialization( - exportedSkeletons: exportedSkeletons, - exposeToGlobal: exposeToGlobal + exportedSkeletons: exportedSkeletons ) printer.write(lines: topLevelNamespaceCode) @@ -1076,16 +1069,14 @@ struct BridgeJSLink { printer.write(lines: data.classLines) let namespaceInitCode = namespaceBuilder.buildNamespaceInitialization( - exportedSkeletons: exportedSkeletons, - exposeToGlobal: exposeToGlobal + exportedSkeletons: exportedSkeletons ) printer.write(lines: namespaceInitCode) let propertyAssignments = try generateNamespacePropertyAssignments( data: data, exportedSkeletons: exportedSkeletons, - namespaceBuilder: namespaceBuilder, - exposeToGlobal: exposeToGlobal + namespaceBuilder: namespaceBuilder ) printer.write(lines: propertyAssignments) } @@ -1157,12 +1148,13 @@ struct BridgeJSLink { private func generateNamespacePropertyAssignments( data: LinkData, exportedSkeletons: [ExportedSkeleton], - namespaceBuilder: NamespaceBuilder, - exposeToGlobal: Bool + namespaceBuilder: NamespaceBuilder ) throws -> [String] { let printer = CodeFragmentPrinter() - if exposeToGlobal { + // Only include enum static assignments for modules with exposeToGlobal + let hasAnyGlobalExposure = exportedSkeletons.contains { $0.exposeToGlobal } + if hasAnyGlobalExposure { printer.write(lines: data.enumStaticAssignments) } @@ -1182,10 +1174,8 @@ struct BridgeJSLink { printer.write("};") printer.write("_exports = exports;") - if exposeToGlobal { - let globalThisLines = namespaceBuilder.buildGlobalThisAssignments(exportedSkeletons: exportedSkeletons) - printer.write(lines: globalThisLines) - } + let globalThisLines = namespaceBuilder.buildGlobalThisAssignments(exportedSkeletons: exportedSkeletons) + printer.write(lines: globalThisLines) printer.write("return exports;") @@ -2243,20 +2233,21 @@ extension BridgeJSLink { ) } - func buildNamespaceInitialization(exportedSkeletons: [ExportedSkeleton], exposeToGlobal: Bool) -> [String] { - guard exposeToGlobal else { return [] } - let allNamespacePaths = collectAllNamespacePaths(exportedSkeletons: exportedSkeletons) + func buildNamespaceInitialization(exportedSkeletons: [ExportedSkeleton]) -> [String] { + let globalSkeletons = exportedSkeletons.filter { $0.exposeToGlobal } + guard !globalSkeletons.isEmpty else { return [] } + let allNamespacePaths = collectAllNamespacePaths(exportedSkeletons: globalSkeletons) return generateNamespaceInitializationCode(namespacePaths: allNamespacePaths) } func buildTopLevelNamespaceInitialization( - exportedSkeletons: [ExportedSkeleton], - exposeToGlobal: Bool + exportedSkeletons: [ExportedSkeleton] ) -> [String] { - guard exposeToGlobal else { return [] } + let globalSkeletons = exportedSkeletons.filter { $0.exposeToGlobal } + guard !globalSkeletons.isEmpty else { return [] } var namespacedEnumPaths: Set<[String]> = [] - for skeleton in exportedSkeletons { + for skeleton in globalSkeletons { for enumDef in skeleton.enums where enumDef.namespace != nil && enumDef.enumType != .namespace { namespacedEnumPaths.insert(enumDef.namespace!) } @@ -2267,7 +2258,7 @@ extension BridgeJSLink { let printer = CodeFragmentPrinter() printer.write(lines: initCode) - for skeleton in exportedSkeletons { + for skeleton in globalSkeletons { for enumDef in skeleton.enums where enumDef.namespace != nil && enumDef.enumType != .namespace { let namespacePath = enumDef.namespace!.joined(separator: ".") printer.write("globalThis.\(namespacePath).\(enumDef.valuesName) = \(enumDef.valuesName);") @@ -2280,7 +2271,7 @@ extension BridgeJSLink { func buildGlobalThisAssignments(exportedSkeletons: [ExportedSkeleton]) -> [String] { let printer = CodeFragmentPrinter() - for skeleton in exportedSkeletons { + for skeleton in exportedSkeletons where skeleton.exposeToGlobal { for klass in skeleton.classes where klass.namespace != nil { let namespacePath = klass.namespace!.joined(separator: ".") printer.write("globalThis.\(namespacePath).\(klass.name) = exports.\(namespacePath).\(klass.name);") @@ -2645,25 +2636,60 @@ extension BridgeJSLink { /// - Returns: Array of TypeScript declaration lines defining the global namespace structure func namespaceDeclarations( exportedSkeletons: [ExportedSkeleton], - exposeToGlobal: Bool, renderTSSignatureCallback: @escaping ([Parameter], BridgeType, Effects) -> String ) -> [String] { let printer = CodeFragmentPrinter() - let rootNode = NamespaceNode(name: "") - - buildExportsTree(rootNode: rootNode, exportedSkeletons: exportedSkeletons) - - guard !rootNode.children.isEmpty else { - return printer.lines - } - - if exposeToGlobal { - printer.write("export {};") - printer.nextLine() - printer.write("declare global {") - printer.indent() + + let globalSkeletons = exportedSkeletons.filter { $0.exposeToGlobal } + let nonGlobalSkeletons = exportedSkeletons.filter { !$0.exposeToGlobal } + + if !globalSkeletons.isEmpty { + let globalRootNode = NamespaceNode(name: "") + buildExportsTree(rootNode: globalRootNode, exportedSkeletons: globalSkeletons) + + if !globalRootNode.children.isEmpty { + printer.write("export {};") + printer.nextLine() + printer.write("declare global {") + printer.indent() + generateNamespaceDeclarationsForNode( + node: globalRootNode, + depth: 1, + printer: printer, + exposeToGlobal: true, + renderTSSignatureCallback: renderTSSignatureCallback + ) + printer.unindent() + printer.write("}") + printer.nextLine() + } + } + + if !nonGlobalSkeletons.isEmpty { + let localRootNode = NamespaceNode(name: "") + buildExportsTree(rootNode: localRootNode, exportedSkeletons: nonGlobalSkeletons) + + if !localRootNode.children.isEmpty { + generateNamespaceDeclarationsForNode( + node: localRootNode, + depth: 1, + printer: printer, + exposeToGlobal: false, + renderTSSignatureCallback: renderTSSignatureCallback + ) + } } + return printer.lines + } + + private func generateNamespaceDeclarationsForNode( + node: NamespaceNode, + depth: Int, + printer: CodeFragmentPrinter, + exposeToGlobal: Bool, + renderTSSignatureCallback: @escaping ([Parameter], BridgeType, Effects) -> String + ) { func hasContent(node: NamespaceNode) -> Bool { // Enums are always included if !node.content.enums.isEmpty { @@ -2845,22 +2871,14 @@ extension BridgeJSLink { } } - generateNamespaceDeclarations(node: childNode, depth: depth + 1) + generateNamespaceDeclarationsForNode(node: childNode, depth: depth + 1, printer: printer, exposeToGlobal: exposeToGlobal, renderTSSignatureCallback: renderTSSignatureCallback) printer.unindent() printer.write("}") } } - - generateNamespaceDeclarations(node: rootNode, depth: 1) - - if exposeToGlobal { - printer.unindent() - printer.write("}") - printer.nextLine() - } - - return printer.lines + + generateNamespaceDeclarations(node: node, depth: depth) } } From 4a682aaa0e44542c56f45d539b49cbfbfd6e0c9b Mon Sep 17 00:00:00 2001 From: Krzysztof Rodak Date: Thu, 27 Nov 2025 12:12:13 +0100 Subject: [PATCH 4/4] BridgeJS: Unified prelude.mjs tests with 2 test targets BridgeJS: Extend snapshot test setup for exports <-> global this by including mixed module test case --- Makefile | 10 - Package.swift | 13 + .../Sources/BridgeJSLink/BridgeJSLink.swift | 26 +- .../BridgeJSToolTests/BridgeJSLinkTests.swift | 21 + .../Inputs/MixedGlobal.swift | 8 + .../Inputs/MixedPrivate.swift | 8 + .../DefaultParameters.Export.js | 8 +- .../BridgeJSLinkTests/MixedGlobal.Export.d.ts | 33 ++ .../BridgeJSLinkTests/MixedGlobal.Export.js | 254 +++++++++ .../MixedModules.Export.d.ts | 54 ++ .../BridgeJSLinkTests/MixedModules.Export.js | 292 ++++++++++ .../MixedPrivate.Export.d.ts | 33 ++ .../BridgeJSLinkTests/MixedPrivate.Export.js | 254 +++++++++ .../BridgeJSLinkTests/Namespaces.Export.js | 8 +- .../Namespaces.Global.Export.js | 8 +- .../BridgeJSLinkTests/SwiftClass.Export.js | 8 +- .../EnumNamespace.Global.swift | 53 +- .../ExportSwiftTests/MixedGlobal.json | 74 +++ .../ExportSwiftTests/MixedGlobal.swift | 61 ++ .../ExportSwiftTests/MixedPrivate.json | 74 +++ .../ExportSwiftTests/MixedPrivate.swift | 61 ++ .../ExportSwiftTests/Namespaces.Global.swift | 53 +- .../StaticFunctions.Global.swift | 19 +- .../StaticProperties.Global.swift | 19 +- .../Generated/BridgeJS.ExportSwift.swift | 303 ++++++++++ .../JavaScript/BridgeJS.ExportSwift.json | 537 ++++++++++++++++++ .../BridgeJSGlobalTests/GlobalAPITests.swift | 78 +++ .../bridge-js.config.json} | 0 Tests/BridgeJSGlobalTests/bridge-js.d.ts | 0 .../BridgeJSRuntimeTests/ExportAPITests.swift | 6 - .../Generated/BridgeJS.ExportSwift.swift | 11 - .../JavaScript/BridgeJS.ExportSwift.json | 17 - Tests/BridgeJSRuntimeTests/bridge-js.d.ts | 18 - Tests/prelude.exposeToGlobal.mjs | 248 -------- Tests/prelude.mjs | 50 ++ 35 files changed, 2316 insertions(+), 404 deletions(-) create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MixedGlobal.swift create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MixedPrivate.swift create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.Export.d.ts create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.Export.js create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.Export.d.ts create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.Export.js create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.Export.d.ts create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.Export.js create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/MixedGlobal.json create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/MixedGlobal.swift create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/MixedPrivate.json create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/MixedPrivate.swift create mode 100644 Tests/BridgeJSGlobalTests/Generated/BridgeJS.ExportSwift.swift create mode 100644 Tests/BridgeJSGlobalTests/Generated/JavaScript/BridgeJS.ExportSwift.json create mode 100644 Tests/BridgeJSGlobalTests/GlobalAPITests.swift rename Tests/{BridgeJSRuntimeTests/bridge-js.config.exposeToGlobal.json => BridgeJSGlobalTests/bridge-js.config.json} (100%) create mode 100644 Tests/BridgeJSGlobalTests/bridge-js.d.ts delete mode 100644 Tests/prelude.exposeToGlobal.mjs diff --git a/Makefile b/Makefile index 453b0b64..c46431dd 100644 --- a/Makefile +++ b/Makefile @@ -11,16 +11,6 @@ unittest: --disable-sandbox \ js test --prelude ./Tests/prelude.mjs -Xnode --expose-gc -.PHONY: unittest-with-global -unittest-with-global: - cp Tests/BridgeJSRuntimeTests/bridge-js.config.exposeToGlobal.json Tests/BridgeJSRuntimeTests/bridge-js.config.local.json - swift package --allow-writing-to-directory Tests/BridgeJSRuntimeTests \ - bridge-js --package-path Tests/BridgeJSRuntimeTests - rm -f Tests/BridgeJSRuntimeTests/bridge-js.config.local.json - env JAVASCRIPTKIT_EXPERIMENTAL_BRIDGEJS=1 swift package --swift-sdk "$(SWIFT_SDK_ID)" \ - --disable-sandbox \ - js test --prelude ./Tests/prelude.exposeToGlobal.mjs -Xnode --expose-gc - .PHONY: regenerate_swiftpm_resources regenerate_swiftpm_resources: npm run build diff --git a/Package.swift b/Package.swift index a8518a5a..ddf2e36e 100644 --- a/Package.swift +++ b/Package.swift @@ -180,5 +180,18 @@ let package = Package( ], linkerSettings: testingLinkerFlags ), + .testTarget( + name: "BridgeJSGlobalTests", + dependencies: ["JavaScriptKit", "JavaScriptEventLoop"], + exclude: [ + "bridge-js.config.json", + "bridge-js.d.ts", + "Generated/JavaScript", + ], + swiftSettings: [ + .enableExperimentalFeature("Extern") + ], + linkerSettings: testingLinkerFlags + ), ] ) diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift index bd32169f..7ecc2086 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift @@ -1127,13 +1127,13 @@ struct BridgeJSLink { } // Generate wrapper functions for each module - for (moduleName, classes) in modulesByName { + for (moduleName, classes) in modulesByName.sorted(by: { $0.key < $1.key }) { wrapperLines.append("// Wrapper functions for module: \(moduleName)") wrapperLines.append("if (!importObject[\"\(moduleName)\"]) {") wrapperLines.append(" importObject[\"\(moduleName)\"] = {};") wrapperLines.append("}") - for klass in classes { + for klass in classes.sorted(by: { $0.name < $1.name }) { let wrapperFunctionName = "bjs_\(klass.name)_wrap" wrapperLines.append("importObject[\"\(moduleName)\"][\"\(wrapperFunctionName)\"] = function(pointer) {") wrapperLines.append(" const obj = \(klass.name).__construct(pointer);") @@ -2639,14 +2639,14 @@ extension BridgeJSLink { renderTSSignatureCallback: @escaping ([Parameter], BridgeType, Effects) -> String ) -> [String] { let printer = CodeFragmentPrinter() - + let globalSkeletons = exportedSkeletons.filter { $0.exposeToGlobal } let nonGlobalSkeletons = exportedSkeletons.filter { !$0.exposeToGlobal } - + if !globalSkeletons.isEmpty { let globalRootNode = NamespaceNode(name: "") buildExportsTree(rootNode: globalRootNode, exportedSkeletons: globalSkeletons) - + if !globalRootNode.children.isEmpty { printer.write("export {};") printer.nextLine() @@ -2664,11 +2664,11 @@ extension BridgeJSLink { printer.nextLine() } } - + if !nonGlobalSkeletons.isEmpty { let localRootNode = NamespaceNode(name: "") buildExportsTree(rootNode: localRootNode, exportedSkeletons: nonGlobalSkeletons) - + if !localRootNode.children.isEmpty { generateNamespaceDeclarationsForNode( node: localRootNode, @@ -2682,7 +2682,7 @@ extension BridgeJSLink { return printer.lines } - + private func generateNamespaceDeclarationsForNode( node: NamespaceNode, depth: Int, @@ -2871,13 +2871,19 @@ extension BridgeJSLink { } } - generateNamespaceDeclarationsForNode(node: childNode, depth: depth + 1, printer: printer, exposeToGlobal: exposeToGlobal, renderTSSignatureCallback: renderTSSignatureCallback) + generateNamespaceDeclarationsForNode( + node: childNode, + depth: depth + 1, + printer: printer, + exposeToGlobal: exposeToGlobal, + renderTSSignatureCallback: renderTSSignatureCallback + ) printer.unindent() printer.write("}") } } - + generateNamespaceDeclarations(node: node, depth: depth) } } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift index 989d05e2..c81a224f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift @@ -91,4 +91,25 @@ import Testing let bridgeJSLink: BridgeJSLink = BridgeJSLink(exportedSkeletons: [outputSkeleton], sharedMemory: false) try snapshot(bridgeJSLink: bridgeJSLink, name: name + ".Global.Export") } + + @Test + func snapshotMixedModuleExposure() throws { + let globalURL = Self.inputsDirectory.appendingPathComponent("MixedGlobal.swift") + let globalSourceFile = Parser.parse(source: try String(contentsOf: globalURL, encoding: .utf8)) + let globalAPI = ExportSwift(progress: .silent, moduleName: "GlobalModule", exposeToGlobal: true) + try globalAPI.addSourceFile(globalSourceFile, "MixedGlobal.swift") + let (_, globalSkeleton) = try #require(try globalAPI.finalize()) + + let privateURL = Self.inputsDirectory.appendingPathComponent("MixedPrivate.swift") + let privateSourceFile = Parser.parse(source: try String(contentsOf: privateURL, encoding: .utf8)) + let privateAPI = ExportSwift(progress: .silent, moduleName: "PrivateModule", exposeToGlobal: false) + try privateAPI.addSourceFile(privateSourceFile, "MixedPrivate.swift") + let (_, privateSkeleton) = try #require(try privateAPI.finalize()) + + let bridgeJSLink = BridgeJSLink( + exportedSkeletons: [globalSkeleton, privateSkeleton], + sharedMemory: false + ) + try snapshot(bridgeJSLink: bridgeJSLink, name: "MixedModules.Export") + } } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MixedGlobal.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MixedGlobal.swift new file mode 100644 index 00000000..f65abe3a --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MixedGlobal.swift @@ -0,0 +1,8 @@ +@JS(namespace: "GlobalAPI") +func globalFunction() -> String + +@JS(namespace: "GlobalAPI") +class GlobalClass { + @JS public init() + @JS public func greet() -> String +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MixedPrivate.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MixedPrivate.swift new file mode 100644 index 00000000..0f99fced --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MixedPrivate.swift @@ -0,0 +1,8 @@ +@JS(namespace: "PrivateAPI") +func privateFunction() -> String + +@JS(namespace: "PrivateAPI") +class PrivateClass { + @JS public init() + @JS public func greet() -> String +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.Export.js index 9f56215d..fa7a7c06 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.Export.js @@ -191,6 +191,10 @@ export async function createInstantiator(options, swift) { if (!importObject["TestModule"]) { importObject["TestModule"] = {}; } + importObject["TestModule"]["bjs_ConstructorDefaults_wrap"] = function(pointer) { + const obj = ConstructorDefaults.__construct(pointer); + return swift.memory.retain(obj); + }; importObject["TestModule"]["bjs_DefaultGreeter_wrap"] = function(pointer) { const obj = DefaultGreeter.__construct(pointer); return swift.memory.retain(obj); @@ -199,10 +203,6 @@ export async function createInstantiator(options, swift) { const obj = EmptyGreeter.__construct(pointer); return swift.memory.retain(obj); }; - importObject["TestModule"]["bjs_ConstructorDefaults_wrap"] = function(pointer) { - const obj = ConstructorDefaults.__construct(pointer); - return swift.memory.retain(obj); - }; }, setInstance: (i) => { instance = i; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.Export.d.ts new file mode 100644 index 00000000..7b4cc95e --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.Export.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 GlobalClass extends SwiftHeapObject { + greet(): string; +} +export type Exports = { + GlobalAPI: { + GlobalClass: { + new(): GlobalClass; + } + globalFunction(): string; + }, +} +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/MixedGlobal.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.Export.js new file mode 100644 index 00000000..453057fa --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.Export.js @@ -0,0 +1,254 @@ +// 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; + 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 tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; + + let _exports = null; + let bjs = null; + + 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) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + tmpRetString = textDecoder.decode(bytes); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + return swift.memory.retain(textDecoder.decode(bytes)); + } + bjs["swift_js_init_memory_with_result"] = function(ptr, len) { + const target = new Uint8Array(memory.buffer, ptr, len); + target.set(tmpRetBytes); + tmpRetBytes = undefined; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; + } + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); + } + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); + } + bjs["swift_js_push_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); + } + bjs["swift_js_return_optional_bool"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalBool = null; + } else { + tmpRetOptionalBool = value !== 0; + } + } + bjs["swift_js_return_optional_int"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalInt = null; + } else { + tmpRetOptionalInt = value | 0; + } + } + bjs["swift_js_return_optional_float"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalFloat = null; + } else { + tmpRetOptionalFloat = Math.fround(value); + } + } + bjs["swift_js_return_optional_double"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalDouble = null; + } else { + tmpRetOptionalDouble = value; + } + } + bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) { + if (isSome === 0) { + tmpRetString = null; + } else { + const bytes = new Uint8Array(memory.buffer, ptr, len); + tmpRetString = textDecoder.decode(bytes); + } + } + 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; + } + // Wrapper functions for module: TestModule + if (!importObject["TestModule"]) { + importObject["TestModule"] = {}; + } + importObject["TestModule"]["bjs_GlobalClass_wrap"] = function(pointer) { + const obj = GlobalClass.__construct(pointer); + return swift.memory.retain(obj); + }; + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + /// Represents a Swift heap object like a class instance or an actor instance. + class SwiftHeapObject { + static __wrap(pointer, deinit, prototype) { + const obj = Object.create(prototype); + obj.pointer = pointer; + obj.hasReleased = false; + obj.deinit = deinit; + obj.registry = new FinalizationRegistry((pointer) => { + deinit(pointer); + }); + obj.registry.register(this, obj.pointer); + return obj; + } + + release() { + this.registry.unregister(this); + this.deinit(this.pointer); + } + } + class GlobalClass extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_GlobalClass_deinit, GlobalClass.prototype); + } + + constructor() { + const ret = instance.exports.bjs_GlobalClass_init(); + return GlobalClass.__construct(ret); + } + greet() { + instance.exports.bjs_GlobalClass_greet(this.pointer); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + } + } + const exports = { + GlobalAPI: { + GlobalClass, + globalFunction: function bjs_GlobalAPI_globalFunction() { + instance.exports.bjs_GlobalAPI_globalFunction(); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + }, + }; + _exports = exports; + return exports; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.Export.d.ts new file mode 100644 index 00000000..67a6eebc --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.Export.d.ts @@ -0,0 +1,54 @@ +// 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 {}; + +declare global { + namespace GlobalAPI { + class GlobalClass { + constructor(); + greet(): string; + } + globalFunction(): 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 GlobalClass extends SwiftHeapObject { + greet(): string; +} +export interface PrivateClass extends SwiftHeapObject { + greet(): string; +} +export type Exports = { + GlobalAPI: { + GlobalClass: { + new(): GlobalClass; + } + globalFunction(): string; + }, + PrivateAPI: { + PrivateClass: { + new(): PrivateClass; + } + privateFunction(): string; + }, +} +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/MixedModules.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.Export.js new file mode 100644 index 00000000..0ff8f450 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.Export.js @@ -0,0 +1,292 @@ +// 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; + 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 tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; + + let _exports = null; + let bjs = null; + + 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) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + tmpRetString = textDecoder.decode(bytes); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + return swift.memory.retain(textDecoder.decode(bytes)); + } + bjs["swift_js_init_memory_with_result"] = function(ptr, len) { + const target = new Uint8Array(memory.buffer, ptr, len); + target.set(tmpRetBytes); + tmpRetBytes = undefined; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; + } + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); + } + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); + } + bjs["swift_js_push_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); + } + bjs["swift_js_return_optional_bool"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalBool = null; + } else { + tmpRetOptionalBool = value !== 0; + } + } + bjs["swift_js_return_optional_int"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalInt = null; + } else { + tmpRetOptionalInt = value | 0; + } + } + bjs["swift_js_return_optional_float"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalFloat = null; + } else { + tmpRetOptionalFloat = Math.fround(value); + } + } + bjs["swift_js_return_optional_double"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalDouble = null; + } else { + tmpRetOptionalDouble = value; + } + } + bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) { + if (isSome === 0) { + tmpRetString = null; + } else { + const bytes = new Uint8Array(memory.buffer, ptr, len); + tmpRetString = textDecoder.decode(bytes); + } + } + 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; + } + // Wrapper functions for module: GlobalModule + if (!importObject["GlobalModule"]) { + importObject["GlobalModule"] = {}; + } + importObject["GlobalModule"]["bjs_GlobalClass_wrap"] = function(pointer) { + const obj = GlobalClass.__construct(pointer); + return swift.memory.retain(obj); + }; + // Wrapper functions for module: PrivateModule + if (!importObject["PrivateModule"]) { + importObject["PrivateModule"] = {}; + } + importObject["PrivateModule"]["bjs_PrivateClass_wrap"] = function(pointer) { + const obj = PrivateClass.__construct(pointer); + return swift.memory.retain(obj); + }; + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + /// Represents a Swift heap object like a class instance or an actor instance. + class SwiftHeapObject { + static __wrap(pointer, deinit, prototype) { + const obj = Object.create(prototype); + obj.pointer = pointer; + obj.hasReleased = false; + obj.deinit = deinit; + obj.registry = new FinalizationRegistry((pointer) => { + deinit(pointer); + }); + obj.registry.register(this, obj.pointer); + return obj; + } + + release() { + this.registry.unregister(this); + this.deinit(this.pointer); + } + } + class GlobalClass extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_GlobalClass_deinit, GlobalClass.prototype); + } + + constructor() { + const ret = instance.exports.bjs_GlobalClass_init(); + return GlobalClass.__construct(ret); + } + greet() { + instance.exports.bjs_GlobalClass_greet(this.pointer); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + } + } + class PrivateClass extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_PrivateClass_deinit, PrivateClass.prototype); + } + + constructor() { + const ret = instance.exports.bjs_PrivateClass_init(); + return PrivateClass.__construct(ret); + } + greet() { + instance.exports.bjs_PrivateClass_greet(this.pointer); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + } + } + if (typeof globalThis.GlobalAPI === 'undefined') { + globalThis.GlobalAPI = {}; + } + const exports = { + GlobalAPI: { + GlobalClass, + globalFunction: function bjs_GlobalAPI_globalFunction() { + instance.exports.bjs_GlobalAPI_globalFunction(); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + }, + PrivateAPI: { + PrivateClass, + privateFunction: function bjs_PrivateAPI_privateFunction() { + instance.exports.bjs_PrivateAPI_privateFunction(); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + }, + }; + _exports = exports; + globalThis.GlobalAPI.GlobalClass = exports.GlobalAPI.GlobalClass; + globalThis.GlobalAPI.globalFunction = exports.GlobalAPI.globalFunction; + return exports; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.Export.d.ts new file mode 100644 index 00000000..19385707 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.Export.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 PrivateClass extends SwiftHeapObject { + greet(): string; +} +export type Exports = { + PrivateAPI: { + PrivateClass: { + new(): PrivateClass; + } + privateFunction(): string; + }, +} +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/MixedPrivate.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.Export.js new file mode 100644 index 00000000..e422b08b --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.Export.js @@ -0,0 +1,254 @@ +// 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; + 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 tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; + + let _exports = null; + let bjs = null; + + 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) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + tmpRetString = textDecoder.decode(bytes); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + return swift.memory.retain(textDecoder.decode(bytes)); + } + bjs["swift_js_init_memory_with_result"] = function(ptr, len) { + const target = new Uint8Array(memory.buffer, ptr, len); + target.set(tmpRetBytes); + tmpRetBytes = undefined; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; + } + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); + } + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); + } + bjs["swift_js_push_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); + } + bjs["swift_js_return_optional_bool"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalBool = null; + } else { + tmpRetOptionalBool = value !== 0; + } + } + bjs["swift_js_return_optional_int"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalInt = null; + } else { + tmpRetOptionalInt = value | 0; + } + } + bjs["swift_js_return_optional_float"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalFloat = null; + } else { + tmpRetOptionalFloat = Math.fround(value); + } + } + bjs["swift_js_return_optional_double"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalDouble = null; + } else { + tmpRetOptionalDouble = value; + } + } + bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) { + if (isSome === 0) { + tmpRetString = null; + } else { + const bytes = new Uint8Array(memory.buffer, ptr, len); + tmpRetString = textDecoder.decode(bytes); + } + } + 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; + } + // Wrapper functions for module: TestModule + if (!importObject["TestModule"]) { + importObject["TestModule"] = {}; + } + importObject["TestModule"]["bjs_PrivateClass_wrap"] = function(pointer) { + const obj = PrivateClass.__construct(pointer); + return swift.memory.retain(obj); + }; + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + /// Represents a Swift heap object like a class instance or an actor instance. + class SwiftHeapObject { + static __wrap(pointer, deinit, prototype) { + const obj = Object.create(prototype); + obj.pointer = pointer; + obj.hasReleased = false; + obj.deinit = deinit; + obj.registry = new FinalizationRegistry((pointer) => { + deinit(pointer); + }); + obj.registry.register(this, obj.pointer); + return obj; + } + + release() { + this.registry.unregister(this); + this.deinit(this.pointer); + } + } + class PrivateClass extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_PrivateClass_deinit, PrivateClass.prototype); + } + + constructor() { + const ret = instance.exports.bjs_PrivateClass_init(); + return PrivateClass.__construct(ret); + } + greet() { + instance.exports.bjs_PrivateClass_greet(this.pointer); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + } + } + const exports = { + PrivateAPI: { + PrivateClass, + privateFunction: function bjs_PrivateAPI_privateFunction() { + instance.exports.bjs_PrivateAPI_privateFunction(); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + }, + }; + _exports = exports; + return exports; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js index 08601bd5..24022a43 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js @@ -185,14 +185,14 @@ export async function createInstantiator(options, swift) { if (!importObject["TestModule"]) { importObject["TestModule"] = {}; } - importObject["TestModule"]["bjs_Greeter_wrap"] = function(pointer) { - const obj = Greeter.__construct(pointer); - return swift.memory.retain(obj); - }; importObject["TestModule"]["bjs_Converter_wrap"] = function(pointer) { const obj = Converter.__construct(pointer); return swift.memory.retain(obj); }; + importObject["TestModule"]["bjs_Greeter_wrap"] = function(pointer) { + const obj = Greeter.__construct(pointer); + return swift.memory.retain(obj); + }; importObject["TestModule"]["bjs_UUID_wrap"] = function(pointer) { const obj = UUID.__construct(pointer); return swift.memory.retain(obj); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.Export.js index 67670d20..e2f13dd0 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.Export.js @@ -185,14 +185,14 @@ export async function createInstantiator(options, swift) { if (!importObject["TestModule"]) { importObject["TestModule"] = {}; } - importObject["TestModule"]["bjs_Greeter_wrap"] = function(pointer) { - const obj = Greeter.__construct(pointer); - return swift.memory.retain(obj); - }; importObject["TestModule"]["bjs_Converter_wrap"] = function(pointer) { const obj = Converter.__construct(pointer); return swift.memory.retain(obj); }; + importObject["TestModule"]["bjs_Greeter_wrap"] = function(pointer) { + const obj = Greeter.__construct(pointer); + return swift.memory.retain(obj); + }; importObject["TestModule"]["bjs_UUID_wrap"] = function(pointer) { const obj = UUID.__construct(pointer); return swift.memory.retain(obj); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js index 9a5eec43..e946b01c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js @@ -189,14 +189,14 @@ export async function createInstantiator(options, swift) { const obj = Greeter.__construct(pointer); return swift.memory.retain(obj); }; - importObject["TestModule"]["bjs_PublicGreeter_wrap"] = function(pointer) { - const obj = PublicGreeter.__construct(pointer); - return swift.memory.retain(obj); - }; importObject["TestModule"]["bjs_PackageGreeter_wrap"] = function(pointer) { const obj = PackageGreeter.__construct(pointer); return swift.memory.retain(obj); }; + importObject["TestModule"]["bjs_PublicGreeter_wrap"] = function(pointer) { + const obj = PublicGreeter.__construct(pointer); + return swift.memory.retain(obj); + }; }, setInstance: (i) => { instance = i; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.swift index ca201f3d..cf497750 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.Global.swift @@ -120,18 +120,19 @@ public func _bjs_Converter_deinit(pointer: UnsafeMutableRawPointer) { extension Utils.Converter: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { - #if arch(wasm32) - @_extern(wasm, module: "TestModule", name: "bjs_Converter_wrap") - func _bjs_Converter_wrap(_: UnsafeMutableRawPointer) -> Int32 - #else - func _bjs_Converter_wrap(_: UnsafeMutableRawPointer) -> Int32 { - fatalError("Only available on WebAssembly") - } - #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_Converter_wrap(Unmanaged.passRetained(self).toOpaque())))) } } +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_Converter_wrap") +fileprivate func _bjs_Converter_wrap(_: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_Converter_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif + @_expose(wasm, "bjs_HTTPServer_init") @_cdecl("bjs_HTTPServer_init") public func _bjs_HTTPServer_init() -> UnsafeMutableRawPointer { @@ -161,18 +162,19 @@ public func _bjs_HTTPServer_deinit(pointer: UnsafeMutableRawPointer) { extension Networking.API.HTTPServer: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { - #if arch(wasm32) - @_extern(wasm, module: "TestModule", name: "bjs_HTTPServer_wrap") - func _bjs_HTTPServer_wrap(_: UnsafeMutableRawPointer) -> Int32 - #else - func _bjs_HTTPServer_wrap(_: UnsafeMutableRawPointer) -> Int32 { - fatalError("Only available on WebAssembly") - } - #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_HTTPServer_wrap(Unmanaged.passRetained(self).toOpaque())))) } } +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_HTTPServer_wrap") +fileprivate func _bjs_HTTPServer_wrap(_: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_HTTPServer_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif + @_expose(wasm, "bjs_TestServer_init") @_cdecl("bjs_TestServer_init") public func _bjs_TestServer_init() -> UnsafeMutableRawPointer { @@ -202,14 +204,15 @@ public func _bjs_TestServer_deinit(pointer: UnsafeMutableRawPointer) { extension Internal.TestServer: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { - #if arch(wasm32) - @_extern(wasm, module: "TestModule", name: "bjs_TestServer_wrap") - func _bjs_TestServer_wrap(_: UnsafeMutableRawPointer) -> Int32 - #else - func _bjs_TestServer_wrap(_: UnsafeMutableRawPointer) -> Int32 { - fatalError("Only available on WebAssembly") - } - #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_TestServer_wrap(Unmanaged.passRetained(self).toOpaque())))) } -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_TestServer_wrap") +fileprivate func _bjs_TestServer_wrap(_: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_TestServer_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/MixedGlobal.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/MixedGlobal.json new file mode 100644 index 00000000..21e78b12 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/MixedGlobal.json @@ -0,0 +1,74 @@ +{ + "classes" : [ + { + "constructor" : { + "abiName" : "bjs_GlobalClass_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + { + "abiName" : "bjs_GlobalClass_greet", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "greet", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + } + ], + "name" : "GlobalClass", + "namespace" : [ + "GlobalAPI" + ], + "properties" : [ + + ], + "swiftCallName" : "GlobalClass" + } + ], + "enums" : [ + + ], + "exposeToGlobal" : false, + "functions" : [ + { + "abiName" : "bjs_GlobalAPI_globalFunction", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "globalFunction", + "namespace" : [ + "GlobalAPI" + ], + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + } + ], + "moduleName" : "TestModule", + "protocols" : [ + + ] +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/MixedGlobal.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/MixedGlobal.swift new file mode 100644 index 00000000..774bf075 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/MixedGlobal.swift @@ -0,0 +1,61 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +@_spi(BridgeJS) import JavaScriptKit + +@_expose(wasm, "bjs_GlobalAPI_globalFunction") +@_cdecl("bjs_GlobalAPI_globalFunction") +public func _bjs_GlobalAPI_globalFunction() -> Void { + #if arch(wasm32) + let ret = globalFunction() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_GlobalClass_init") +@_cdecl("bjs_GlobalClass_init") +public func _bjs_GlobalClass_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = GlobalClass() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_GlobalClass_greet") +@_cdecl("bjs_GlobalClass_greet") +public func _bjs_GlobalClass_greet(_self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = GlobalClass.bridgeJSLiftParameter(_self).greet() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_GlobalClass_deinit") +@_cdecl("bjs_GlobalClass_deinit") +public func _bjs_GlobalClass_deinit(pointer: UnsafeMutableRawPointer) { + Unmanaged.fromOpaque(pointer).release() +} + +extension GlobalClass: ConvertibleToJSValue, _BridgedSwiftHeapObject { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_GlobalClass_wrap(Unmanaged.passRetained(self).toOpaque())))) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_GlobalClass_wrap") +fileprivate func _bjs_GlobalClass_wrap(_: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_GlobalClass_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/MixedPrivate.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/MixedPrivate.json new file mode 100644 index 00000000..d86712af --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/MixedPrivate.json @@ -0,0 +1,74 @@ +{ + "classes" : [ + { + "constructor" : { + "abiName" : "bjs_PrivateClass_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + { + "abiName" : "bjs_PrivateClass_greet", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "greet", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + } + ], + "name" : "PrivateClass", + "namespace" : [ + "PrivateAPI" + ], + "properties" : [ + + ], + "swiftCallName" : "PrivateClass" + } + ], + "enums" : [ + + ], + "exposeToGlobal" : false, + "functions" : [ + { + "abiName" : "bjs_PrivateAPI_privateFunction", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "privateFunction", + "namespace" : [ + "PrivateAPI" + ], + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + } + ], + "moduleName" : "TestModule", + "protocols" : [ + + ] +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/MixedPrivate.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/MixedPrivate.swift new file mode 100644 index 00000000..10c62bb0 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/MixedPrivate.swift @@ -0,0 +1,61 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +@_spi(BridgeJS) import JavaScriptKit + +@_expose(wasm, "bjs_PrivateAPI_privateFunction") +@_cdecl("bjs_PrivateAPI_privateFunction") +public func _bjs_PrivateAPI_privateFunction() -> Void { + #if arch(wasm32) + let ret = privateFunction() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PrivateClass_init") +@_cdecl("bjs_PrivateClass_init") +public func _bjs_PrivateClass_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = PrivateClass() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PrivateClass_greet") +@_cdecl("bjs_PrivateClass_greet") +public func _bjs_PrivateClass_greet(_self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = PrivateClass.bridgeJSLiftParameter(_self).greet() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PrivateClass_deinit") +@_cdecl("bjs_PrivateClass_deinit") +public func _bjs_PrivateClass_deinit(pointer: UnsafeMutableRawPointer) { + Unmanaged.fromOpaque(pointer).release() +} + +extension PrivateClass: ConvertibleToJSValue, _BridgedSwiftHeapObject { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_PrivateClass_wrap(Unmanaged.passRetained(self).toOpaque())))) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_PrivateClass_wrap") +fileprivate func _bjs_PrivateClass_wrap(_: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_PrivateClass_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.Global.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.Global.swift index f868fa11..3e771446 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.Global.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.Global.swift @@ -58,18 +58,19 @@ public func _bjs_Greeter_deinit(pointer: UnsafeMutableRawPointer) { extension Greeter: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { - #if arch(wasm32) - @_extern(wasm, module: "TestModule", name: "bjs_Greeter_wrap") - func _bjs_Greeter_wrap(_: UnsafeMutableRawPointer) -> Int32 - #else - func _bjs_Greeter_wrap(_: UnsafeMutableRawPointer) -> Int32 { - fatalError("Only available on WebAssembly") - } - #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_Greeter_wrap(Unmanaged.passRetained(self).toOpaque())))) } } +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_Greeter_wrap") +fileprivate func _bjs_Greeter_wrap(_: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_Greeter_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif + @_expose(wasm, "bjs_Converter_init") @_cdecl("bjs_Converter_init") public func _bjs_Converter_init() -> UnsafeMutableRawPointer { @@ -100,18 +101,19 @@ public func _bjs_Converter_deinit(pointer: UnsafeMutableRawPointer) { extension Converter: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { - #if arch(wasm32) - @_extern(wasm, module: "TestModule", name: "bjs_Converter_wrap") - func _bjs_Converter_wrap(_: UnsafeMutableRawPointer) -> Int32 - #else - func _bjs_Converter_wrap(_: UnsafeMutableRawPointer) -> Int32 { - fatalError("Only available on WebAssembly") - } - #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_Converter_wrap(Unmanaged.passRetained(self).toOpaque())))) } } +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_Converter_wrap") +fileprivate func _bjs_Converter_wrap(_: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_Converter_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif + @_expose(wasm, "bjs_UUID_uuidString") @_cdecl("bjs_UUID_uuidString") public func _bjs_UUID_uuidString(_self: UnsafeMutableRawPointer) -> Void { @@ -131,14 +133,15 @@ public func _bjs_UUID_deinit(pointer: UnsafeMutableRawPointer) { extension UUID: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { - #if arch(wasm32) - @_extern(wasm, module: "TestModule", name: "bjs_UUID_wrap") - func _bjs_UUID_wrap(_: UnsafeMutableRawPointer) -> Int32 - #else - func _bjs_UUID_wrap(_: UnsafeMutableRawPointer) -> Int32 { - fatalError("Only available on WebAssembly") - } - #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_UUID_wrap(Unmanaged.passRetained(self).toOpaque())))) } -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_UUID_wrap") +fileprivate func _bjs_UUID_wrap(_: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_UUID_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.Global.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.Global.swift index 7aa91b91..81ea282f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.Global.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticFunctions.Global.swift @@ -179,14 +179,15 @@ public func _bjs_MathUtils_deinit(pointer: UnsafeMutableRawPointer) { extension MathUtils: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { - #if arch(wasm32) - @_extern(wasm, module: "TestModule", name: "bjs_MathUtils_wrap") - func _bjs_MathUtils_wrap(_: UnsafeMutableRawPointer) -> Int32 - #else - func _bjs_MathUtils_wrap(_: UnsafeMutableRawPointer) -> Int32 { - fatalError("Only available on WebAssembly") - } - #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_MathUtils_wrap(Unmanaged.passRetained(self).toOpaque())))) } -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_MathUtils_wrap") +fileprivate func _bjs_MathUtils_wrap(_: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_MathUtils_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.Global.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.Global.swift index 72d561a0..e34f26f8 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.Global.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StaticProperties.Global.swift @@ -325,14 +325,15 @@ public func _bjs_PropertyClass_deinit(pointer: UnsafeMutableRawPointer) { extension PropertyClass: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { - #if arch(wasm32) - @_extern(wasm, module: "TestModule", name: "bjs_PropertyClass_wrap") - func _bjs_PropertyClass_wrap(_: UnsafeMutableRawPointer) -> Int32 - #else - func _bjs_PropertyClass_wrap(_: UnsafeMutableRawPointer) -> Int32 { - fatalError("Only available on WebAssembly") - } - #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_PropertyClass_wrap(Unmanaged.passRetained(self).toOpaque())))) } -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_PropertyClass_wrap") +fileprivate func _bjs_PropertyClass_wrap(_: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_PropertyClass_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif \ No newline at end of file diff --git a/Tests/BridgeJSGlobalTests/Generated/BridgeJS.ExportSwift.swift b/Tests/BridgeJSGlobalTests/Generated/BridgeJS.ExportSwift.swift new file mode 100644 index 00000000..8e0c5f18 --- /dev/null +++ b/Tests/BridgeJSGlobalTests/Generated/BridgeJS.ExportSwift.swift @@ -0,0 +1,303 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +@_spi(BridgeJS) import JavaScriptKit + +extension GlobalNetworking.API.CallMethod: _BridgedSwiftCaseEnum { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> GlobalNetworking.API.CallMethod { + return bridgeJSLiftParameter(value) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> GlobalNetworking.API.CallMethod { + return GlobalNetworking.API.CallMethod(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSLowerParameter() + } + + private init?(bridgeJSRawValue: Int32) { + switch bridgeJSRawValue { + case 0: + self = .get + case 1: + self = .post + case 2: + self = .put + case 3: + self = .delete + default: + return nil + } + } + + private var bridgeJSRawValue: Int32 { + switch self { + case .get: + return 0 + case .post: + return 1 + case .put: + return 2 + case .delete: + return 3 + } + } +} + +extension GlobalConfiguration.PublicLogLevel: _BridgedSwiftEnumNoPayload { +} + +extension GlobalConfiguration.AvailablePort: _BridgedSwiftEnumNoPayload { +} + +extension Internal.SupportedServerMethod: _BridgedSwiftCaseEnum { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> Internal.SupportedServerMethod { + return bridgeJSLiftParameter(value) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> Internal.SupportedServerMethod { + return Internal.SupportedServerMethod(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSLowerParameter() + } + + private init?(bridgeJSRawValue: Int32) { + switch bridgeJSRawValue { + case 0: + self = .get + case 1: + self = .post + default: + return nil + } + } + + private var bridgeJSRawValue: Int32 { + switch self { + case .get: + return 0 + case .post: + return 1 + } + } +} + +@_expose(wasm, "bjs_GlobalStaticPropertyNamespace_static_namespaceProperty_get") +@_cdecl("bjs_GlobalStaticPropertyNamespace_static_namespaceProperty_get") +public func _bjs_GlobalStaticPropertyNamespace_static_namespaceProperty_get() -> Void { + #if arch(wasm32) + let ret = GlobalStaticPropertyNamespace.namespaceProperty + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_GlobalStaticPropertyNamespace_static_namespaceProperty_set") +@_cdecl("bjs_GlobalStaticPropertyNamespace_static_namespaceProperty_set") +public func _bjs_GlobalStaticPropertyNamespace_static_namespaceProperty_set(valueBytes: Int32, valueLength: Int32) -> Void { + #if arch(wasm32) + GlobalStaticPropertyNamespace.namespaceProperty = String.bridgeJSLiftParameter(valueBytes, valueLength) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_GlobalStaticPropertyNamespace_static_namespaceConstant_get") +@_cdecl("bjs_GlobalStaticPropertyNamespace_static_namespaceConstant_get") +public func _bjs_GlobalStaticPropertyNamespace_static_namespaceConstant_get() -> Void { + #if arch(wasm32) + let ret = GlobalStaticPropertyNamespace.namespaceConstant + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_GlobalStaticPropertyNamespace_NestedProperties_static_nestedProperty_get") +@_cdecl("bjs_GlobalStaticPropertyNamespace_NestedProperties_static_nestedProperty_get") +public func _bjs_GlobalStaticPropertyNamespace_NestedProperties_static_nestedProperty_get() -> Int32 { + #if arch(wasm32) + let ret = GlobalStaticPropertyNamespace.NestedProperties.nestedProperty + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_GlobalStaticPropertyNamespace_NestedProperties_static_nestedProperty_set") +@_cdecl("bjs_GlobalStaticPropertyNamespace_NestedProperties_static_nestedProperty_set") +public func _bjs_GlobalStaticPropertyNamespace_NestedProperties_static_nestedProperty_set(value: Int32) -> Void { + #if arch(wasm32) + GlobalStaticPropertyNamespace.NestedProperties.nestedProperty = Int.bridgeJSLiftParameter(value) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_GlobalStaticPropertyNamespace_NestedProperties_static_nestedConstant_get") +@_cdecl("bjs_GlobalStaticPropertyNamespace_NestedProperties_static_nestedConstant_get") +public func _bjs_GlobalStaticPropertyNamespace_NestedProperties_static_nestedConstant_get() -> Void { + #if arch(wasm32) + let ret = GlobalStaticPropertyNamespace.NestedProperties.nestedConstant + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_GlobalStaticPropertyNamespace_NestedProperties_static_nestedDouble_get") +@_cdecl("bjs_GlobalStaticPropertyNamespace_NestedProperties_static_nestedDouble_get") +public func _bjs_GlobalStaticPropertyNamespace_NestedProperties_static_nestedDouble_get() -> Float64 { + #if arch(wasm32) + let ret = GlobalStaticPropertyNamespace.NestedProperties.nestedDouble + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_GlobalStaticPropertyNamespace_NestedProperties_static_nestedDouble_set") +@_cdecl("bjs_GlobalStaticPropertyNamespace_NestedProperties_static_nestedDouble_set") +public func _bjs_GlobalStaticPropertyNamespace_NestedProperties_static_nestedDouble_set(value: Float64) -> Void { + #if arch(wasm32) + GlobalStaticPropertyNamespace.NestedProperties.nestedDouble = Double.bridgeJSLiftParameter(value) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_TestHTTPServer_init") +@_cdecl("bjs_TestHTTPServer_init") +public func _bjs_TestHTTPServer_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = GlobalNetworking.API.TestHTTPServer() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_TestHTTPServer_call") +@_cdecl("bjs_TestHTTPServer_call") +public func _bjs_TestHTTPServer_call(_self: UnsafeMutableRawPointer, method: Int32) -> Void { + #if arch(wasm32) + GlobalNetworking.API.TestHTTPServer.bridgeJSLiftParameter(_self).call(_: GlobalNetworking.API.CallMethod.bridgeJSLiftParameter(method)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_TestHTTPServer_deinit") +@_cdecl("bjs_TestHTTPServer_deinit") +public func _bjs_TestHTTPServer_deinit(pointer: UnsafeMutableRawPointer) { + Unmanaged.fromOpaque(pointer).release() +} + +extension GlobalNetworking.API.TestHTTPServer: ConvertibleToJSValue, _BridgedSwiftHeapObject { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_TestHTTPServer_wrap(Unmanaged.passRetained(self).toOpaque())))) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSGlobalTests", name: "bjs_TestHTTPServer_wrap") +fileprivate func _bjs_TestHTTPServer_wrap(_: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_TestHTTPServer_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif + +@_expose(wasm, "bjs_TestInternalServer_init") +@_cdecl("bjs_TestInternalServer_init") +public func _bjs_TestInternalServer_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = Internal.TestInternalServer() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_TestInternalServer_call") +@_cdecl("bjs_TestInternalServer_call") +public func _bjs_TestInternalServer_call(_self: UnsafeMutableRawPointer, method: Int32) -> Void { + #if arch(wasm32) + Internal.TestInternalServer.bridgeJSLiftParameter(_self).call(_: Internal.SupportedServerMethod.bridgeJSLiftParameter(method)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_TestInternalServer_deinit") +@_cdecl("bjs_TestInternalServer_deinit") +public func _bjs_TestInternalServer_deinit(pointer: UnsafeMutableRawPointer) { + Unmanaged.fromOpaque(pointer).release() +} + +extension Internal.TestInternalServer: ConvertibleToJSValue, _BridgedSwiftHeapObject { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_TestInternalServer_wrap(Unmanaged.passRetained(self).toOpaque())))) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSGlobalTests", name: "bjs_TestInternalServer_wrap") +fileprivate func _bjs_TestInternalServer_wrap(_: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_TestInternalServer_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif + +@_expose(wasm, "bjs_PublicConverter_init") +@_cdecl("bjs_PublicConverter_init") +public func _bjs_PublicConverter_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = GlobalUtils.PublicConverter() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PublicConverter_toString") +@_cdecl("bjs_PublicConverter_toString") +public func _bjs_PublicConverter_toString(_self: UnsafeMutableRawPointer, value: Int32) -> Void { + #if arch(wasm32) + let ret = GlobalUtils.PublicConverter.bridgeJSLiftParameter(_self).toString(value: Int.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_PublicConverter_deinit") +@_cdecl("bjs_PublicConverter_deinit") +public func _bjs_PublicConverter_deinit(pointer: UnsafeMutableRawPointer) { + Unmanaged.fromOpaque(pointer).release() +} + +extension GlobalUtils.PublicConverter: ConvertibleToJSValue, _BridgedSwiftHeapObject { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_PublicConverter_wrap(Unmanaged.passRetained(self).toOpaque())))) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSGlobalTests", name: "bjs_PublicConverter_wrap") +fileprivate func _bjs_PublicConverter_wrap(_: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_PublicConverter_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif \ No newline at end of file diff --git a/Tests/BridgeJSGlobalTests/Generated/JavaScript/BridgeJS.ExportSwift.json b/Tests/BridgeJSGlobalTests/Generated/JavaScript/BridgeJS.ExportSwift.json new file mode 100644 index 00000000..979311c8 --- /dev/null +++ b/Tests/BridgeJSGlobalTests/Generated/JavaScript/BridgeJS.ExportSwift.json @@ -0,0 +1,537 @@ +{ + "classes" : [ + { + "constructor" : { + "abiName" : "bjs_TestHTTPServer_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + { + "abiName" : "bjs_TestHTTPServer_call", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "call", + "namespace" : [ + "GlobalNetworking", + "API" + ], + "parameters" : [ + { + "label" : "_", + "name" : "method", + "type" : { + "caseEnum" : { + "_0" : "GlobalNetworking.API.CallMethod" + } + } + } + ], + "returnType" : { + "void" : { + + } + } + } + ], + "name" : "TestHTTPServer", + "namespace" : [ + "GlobalNetworking", + "API" + ], + "properties" : [ + + ], + "swiftCallName" : "GlobalNetworking.API.TestHTTPServer" + }, + { + "constructor" : { + "abiName" : "bjs_TestInternalServer_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + { + "abiName" : "bjs_TestInternalServer_call", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "call", + "namespace" : [ + "GlobalNetworking", + "APIV2", + "Internal" + ], + "parameters" : [ + { + "label" : "_", + "name" : "method", + "type" : { + "caseEnum" : { + "_0" : "Internal.SupportedServerMethod" + } + } + } + ], + "returnType" : { + "void" : { + + } + } + } + ], + "name" : "TestInternalServer", + "namespace" : [ + "GlobalNetworking", + "APIV2", + "Internal" + ], + "properties" : [ + + ], + "swiftCallName" : "Internal.TestInternalServer" + }, + { + "constructor" : { + "abiName" : "bjs_PublicConverter_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + { + "abiName" : "bjs_PublicConverter_toString", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "toString", + "namespace" : [ + "GlobalUtils" + ], + "parameters" : [ + { + "label" : "value", + "name" : "value", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + } + } + ], + "name" : "PublicConverter", + "namespace" : [ + "GlobalUtils" + ], + "properties" : [ + + ], + "swiftCallName" : "GlobalUtils.PublicConverter" + } + ], + "enums" : [ + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "GlobalNetworking", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GlobalNetworking", + "tsFullPath" : "GlobalNetworking" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "API", + "namespace" : [ + "GlobalNetworking" + ], + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GlobalNetworking.API", + "tsFullPath" : "GlobalNetworking.API" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "get" + }, + { + "associatedValues" : [ + + ], + "name" : "post" + }, + { + "associatedValues" : [ + + ], + "name" : "put" + }, + { + "associatedValues" : [ + + ], + "name" : "delete" + } + ], + "emitStyle" : "const", + "name" : "CallMethod", + "namespace" : [ + "GlobalNetworking", + "API" + ], + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GlobalNetworking.API.CallMethod", + "tsFullPath" : "GlobalNetworking.API.CallMethod" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "GlobalConfiguration", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GlobalConfiguration", + "tsFullPath" : "GlobalConfiguration" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "debug", + "rawValue" : "debug" + }, + { + "associatedValues" : [ + + ], + "name" : "info", + "rawValue" : "info" + }, + { + "associatedValues" : [ + + ], + "name" : "warning", + "rawValue" : "warning" + }, + { + "associatedValues" : [ + + ], + "name" : "error", + "rawValue" : "error" + } + ], + "emitStyle" : "const", + "name" : "PublicLogLevel", + "namespace" : [ + "GlobalConfiguration" + ], + "rawType" : "String", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GlobalConfiguration.PublicLogLevel", + "tsFullPath" : "GlobalConfiguration.PublicLogLevel" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "http", + "rawValue" : "80" + }, + { + "associatedValues" : [ + + ], + "name" : "https", + "rawValue" : "443" + }, + { + "associatedValues" : [ + + ], + "name" : "development", + "rawValue" : "3000" + } + ], + "emitStyle" : "const", + "name" : "AvailablePort", + "namespace" : [ + "GlobalConfiguration" + ], + "rawType" : "Int", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GlobalConfiguration.AvailablePort", + "tsFullPath" : "GlobalConfiguration.AvailablePort" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "Internal", + "namespace" : [ + "GlobalNetworking", + "APIV2" + ], + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Internal", + "tsFullPath" : "GlobalNetworking.APIV2.Internal" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "get" + }, + { + "associatedValues" : [ + + ], + "name" : "post" + } + ], + "emitStyle" : "const", + "name" : "SupportedServerMethod", + "namespace" : [ + "GlobalNetworking", + "APIV2", + "Internal" + ], + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Internal.SupportedServerMethod", + "tsFullPath" : "GlobalNetworking.APIV2.Internal.SupportedServerMethod" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "GlobalStaticPropertyNamespace", + "staticMethods" : [ + + ], + "staticProperties" : [ + { + "isReadonly" : false, + "isStatic" : true, + "name" : "namespaceProperty", + "namespace" : [ + "GlobalStaticPropertyNamespace" + ], + "staticContext" : { + "namespaceEnum" : { + + } + }, + "type" : { + "string" : { + + } + } + }, + { + "isReadonly" : true, + "isStatic" : true, + "name" : "namespaceConstant", + "namespace" : [ + "GlobalStaticPropertyNamespace" + ], + "staticContext" : { + "namespaceEnum" : { + + } + }, + "type" : { + "string" : { + + } + } + } + ], + "swiftCallName" : "GlobalStaticPropertyNamespace", + "tsFullPath" : "GlobalStaticPropertyNamespace" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "NestedProperties", + "namespace" : [ + "GlobalStaticPropertyNamespace" + ], + "staticMethods" : [ + + ], + "staticProperties" : [ + { + "isReadonly" : false, + "isStatic" : true, + "name" : "nestedProperty", + "namespace" : [ + "GlobalStaticPropertyNamespace", + "NestedProperties" + ], + "staticContext" : { + "namespaceEnum" : { + + } + }, + "type" : { + "int" : { + + } + } + }, + { + "isReadonly" : true, + "isStatic" : true, + "name" : "nestedConstant", + "namespace" : [ + "GlobalStaticPropertyNamespace", + "NestedProperties" + ], + "staticContext" : { + "namespaceEnum" : { + + } + }, + "type" : { + "string" : { + + } + } + }, + { + "isReadonly" : false, + "isStatic" : true, + "name" : "nestedDouble", + "namespace" : [ + "GlobalStaticPropertyNamespace", + "NestedProperties" + ], + "staticContext" : { + "namespaceEnum" : { + + } + }, + "type" : { + "double" : { + + } + } + } + ], + "swiftCallName" : "GlobalStaticPropertyNamespace.NestedProperties", + "tsFullPath" : "GlobalStaticPropertyNamespace.NestedProperties" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "GlobalUtils", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GlobalUtils", + "tsFullPath" : "GlobalUtils" + } + ], + "exposeToGlobal" : true, + "functions" : [ + + ], + "moduleName" : "BridgeJSGlobalTests", + "protocols" : [ + + ] +} \ No newline at end of file diff --git a/Tests/BridgeJSGlobalTests/GlobalAPITests.swift b/Tests/BridgeJSGlobalTests/GlobalAPITests.swift new file mode 100644 index 00000000..19087ff5 --- /dev/null +++ b/Tests/BridgeJSGlobalTests/GlobalAPITests.swift @@ -0,0 +1,78 @@ +import XCTest +import JavaScriptKit + +@_extern(wasm, module: "BridgeJSGlobalTests", name: "runJsWorksGlobal") +@_extern(c) +func runJsWorksGlobal() -> Void + +// Minimal set of @JS declarations for testing globalThis access +// These are namespaced items that should be accessible via globalThis + +@JS enum GlobalNetworking { + @JS enum API { + @JS enum CallMethod { + case get + case post + case put + case delete + } + @JS class TestHTTPServer { + @JS init() {} + @JS func call(_ method: CallMethod) {} + } + } +} + +@JS enum GlobalConfiguration { + @JS enum PublicLogLevel: String { + case debug = "debug" + case info = "info" + case warning = "warning" + case error = "error" + } + + @JS enum AvailablePort: Int { + case http = 80 + case https = 443 + case development = 3000 + } +} + +@JS(namespace: "GlobalNetworking.APIV2") +enum Internal { + @JS enum SupportedServerMethod { + case get + case post + } + @JS class TestInternalServer { + @JS init() {} + @JS func call(_ method: SupportedServerMethod) {} + } +} + +@JS enum GlobalStaticPropertyNamespace { + @JS nonisolated(unsafe) static var namespaceProperty: String = "namespace" + @JS static let namespaceConstant: String = "constant" + + @JS enum NestedProperties { + @JS nonisolated(unsafe) static var nestedProperty: Int = 999 + @JS static let nestedConstant: String = "nested" + @JS nonisolated(unsafe) static var nestedDouble: Double = 1.414 + } +} + +@JS enum GlobalUtils { + @JS class PublicConverter { + @JS init() {} + + @JS func toString(value: Int) -> String { + return String(value) + } + } +} + +class GlobalAPITests: XCTestCase { + func testGlobalAccess() { + runJsWorksGlobal() + } +} diff --git a/Tests/BridgeJSRuntimeTests/bridge-js.config.exposeToGlobal.json b/Tests/BridgeJSGlobalTests/bridge-js.config.json similarity index 100% rename from Tests/BridgeJSRuntimeTests/bridge-js.config.exposeToGlobal.json rename to Tests/BridgeJSGlobalTests/bridge-js.config.json diff --git a/Tests/BridgeJSGlobalTests/bridge-js.d.ts b/Tests/BridgeJSGlobalTests/bridge-js.d.ts new file mode 100644 index 00000000..e69de29b diff --git a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift index f5268b4e..ff3d9dbe 100644 --- a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift +++ b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift @@ -872,12 +872,6 @@ enum APIOptionalResult { } } -// Test functions for static properties -@JS func getAllStaticPropertyValues() -> String { - return - "const:\(StaticPropertyHolder.staticConstant),var:\(StaticPropertyHolder.staticVariable),computed:\(StaticPropertyHolder.computedProperty),readonly:\(StaticPropertyHolder.readOnlyComputed)" -} - // MARK: - Protocol Tests @JS protocol DataProcessor { diff --git a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift index 572890b0..9923eedd 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift @@ -3265,17 +3265,6 @@ public func _bjs_testEmptyInit(object: UnsafeMutableRawPointer) -> UnsafeMutable #endif } -@_expose(wasm, "bjs_getAllStaticPropertyValues") -@_cdecl("bjs_getAllStaticPropertyValues") -public func _bjs_getAllStaticPropertyValues() -> Void { - #if arch(wasm32) - let ret = getAllStaticPropertyValues() - return ret.bridgeJSLowerReturn() - #else - fatalError("Only available on WebAssembly") - #endif -} - @_expose(wasm, "bjs_formatName") @_cdecl("bjs_formatName") public func _bjs_formatName(nameBytes: Int32, nameLength: Int32, transform: Int32) -> Void { diff --git a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json index 69564e72..75964deb 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json +++ b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json @@ -7402,23 +7402,6 @@ } } }, - { - "abiName" : "bjs_getAllStaticPropertyValues", - "effects" : { - "isAsync" : false, - "isStatic" : false, - "isThrows" : false - }, - "name" : "getAllStaticPropertyValues", - "parameters" : [ - - ], - "returnType" : { - "string" : { - - } - } - }, { "abiName" : "bjs_formatName", "effects" : { diff --git a/Tests/BridgeJSRuntimeTests/bridge-js.d.ts b/Tests/BridgeJSRuntimeTests/bridge-js.d.ts index 0f0d0155..e69de29b 100644 --- a/Tests/BridgeJSRuntimeTests/bridge-js.d.ts +++ b/Tests/BridgeJSRuntimeTests/bridge-js.d.ts @@ -1,18 +0,0 @@ -export function jsRoundTripVoid(): void -export function jsRoundTripNumber(v: number): number -export function jsRoundTripBool(v: boolean): boolean -export function jsRoundTripString(v: string): string -export function jsThrowOrVoid(shouldThrow: boolean): void -export function jsThrowOrNumber(shouldThrow: boolean): number -export function jsThrowOrBool(shouldThrow: boolean): boolean -export function jsThrowOrString(shouldThrow: boolean): string - -export class JsGreeter { - name: string; - readonly prefix: string; - constructor(name: string, prefix: string); - greet(): string; - changeName(name: string): void; -} - -export function runAsyncWorks(): Promise; diff --git a/Tests/prelude.exposeToGlobal.mjs b/Tests/prelude.exposeToGlobal.mjs deleted file mode 100644 index 47e36b4d..00000000 --- a/Tests/prelude.exposeToGlobal.mjs +++ /dev/null @@ -1,248 +0,0 @@ -/** @type {import('../.build/plugins/PackageToJS/outputs/PackageTests/test.d.ts').SetupOptionsFn} */ -export async function setupOptions(options, context) { - Error.stackTraceLimit = 100; - setupTestGlobals(globalThis); - return { - ...options, - getImports: (importsContext) => { - return { - "jsRoundTripVoid": () => { - return; - }, - "jsRoundTripNumber": (v) => { - return v; - }, - "jsRoundTripBool": (v) => { - return v; - }, - "jsRoundTripString": (v) => { - return v; - }, - "jsThrowOrVoid": (shouldThrow) => { - if (shouldThrow) { - throw new Error("TestError"); - } - }, - "jsThrowOrNumber": (shouldThrow) => { - if (shouldThrow) { - throw new Error("TestError"); - } - return 1; - }, - "jsThrowOrBool": (shouldThrow) => { - if (shouldThrow) { - throw new Error("TestError"); - } - return true; - }, - "jsThrowOrString": (shouldThrow) => { - if (shouldThrow) { - throw new Error("TestError"); - } - return "Hello, world!"; - }, - JsGreeter: class { - /** - * @param {string} name - * @param {string} prefix - */ - constructor(name, prefix) { - this.name = name; - this.prefix = prefix; - } - greet() { - return `${this.prefix}, ${this.name}!`; - } - /** @param {string} name */ - changeName(name) { - this.name = name; - } - }, - runAsyncWorks: async () => { - const exports = importsContext.getExports(); - if (!exports) { - throw new Error("No exports!?"); - } - BridgeJSRuntimeTests_runAsyncWorks(exports); - return; - } - }; - }, - addToCoreImports(importObject, importsContext) { - const { getInstance, getExports } = importsContext; - options.addToCoreImports?.(importObject, importsContext); - importObject["JavaScriptEventLoopTestSupportTests"] = { - "isMainThread": () => context.isMainThread, - } - const bridgeJSRuntimeTests = importObject["BridgeJSRuntimeTests"] || {}; - bridgeJSRuntimeTests["runJsWorks"] = () => { - const exports = getExports(); - if (!exports) { - throw new Error("No exports!?"); - } - return BridgeJSRuntimeTests_runJsWorks(getInstance(), exports); - } - importObject["BridgeJSRuntimeTests"] = bridgeJSRuntimeTests; - } - } -} - -import assert from "node:assert"; - -/** @param {import('./../.build/plugins/PackageToJS/outputs/PackageTests/bridge-js.d.ts').Exports} exports */ -function BridgeJSRuntimeTests_runJsWorks(instance, exports) { - // Repetition tests to satisfy testAll - const g = new exports.Greeter("John"); - g.release(); - const calc = exports.createCalculator(); - calc.release(); - - assert.equal(globalThis.Networking.API.MethodValues.Get, 0); - assert.equal(globalThis.Networking.API.MethodValues.Post, 1); - assert.equal(globalThis.Networking.API.MethodValues.Put, 2); - assert.equal(globalThis.Networking.API.MethodValues.Delete, 3); - - assert.equal(globalThis.Configuration.LogLevelValues.Debug, "debug"); - assert.equal(globalThis.Configuration.LogLevelValues.Info, "info"); - assert.equal(globalThis.Configuration.LogLevelValues.Warning, "warning"); - assert.equal(globalThis.Configuration.LogLevelValues.Error, "error"); - assert.equal(globalThis.Configuration.PortValues.Http, 80); - assert.equal(globalThis.Configuration.PortValues.Https, 443); - assert.equal(globalThis.Configuration.PortValues.Development, 3000); - - assert.equal(globalThis.Networking.APIV2.Internal.SupportedMethodValues.Get, 0); - assert.equal(globalThis.Networking.APIV2.Internal.SupportedMethodValues.Post, 1); - - const globalConverter = new globalThis.Utils.Converter(); - assert.equal(globalConverter.toString(99), "99"); - globalConverter.release(); - - const globalHttpServer = new globalThis.Networking.API.HTTPServer(); - globalHttpServer.call(globalThis.Networking.API.MethodValues.Get); - globalHttpServer.release(); - - const globalTestServer = new globalThis.Networking.APIV2.Internal.TestServer(); - globalTestServer.call(globalThis.Networking.APIV2.Internal.SupportedMethodValues.Post); - globalTestServer.release(); - - assert.equal(globalThis.StaticPropertyNamespace.namespaceProperty, "namespace"); - assert.equal(globalThis.StaticPropertyNamespace.namespaceConstant, "constant"); - - globalThis.StaticPropertyNamespace.namespaceProperty = "modified namespace"; - assert.equal(globalThis.StaticPropertyNamespace.namespaceProperty, "modified namespace"); - - assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedProperty, 999); - assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedConstant, "nested"); - assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedDouble, 1.414); - - globalThis.StaticPropertyNamespace.NestedProperties.nestedProperty = 1000; - globalThis.StaticPropertyNamespace.NestedProperties.nestedDouble = 2.828; - assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedProperty, 1000); - assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedDouble, 2.828); - - // // Verify both globalThis and exports point to same objects - // assert.equal(globalThis.StaticPropertyNamespace.namespaceProperty, exports.StaticPropertyNamespace.namespaceProperty); - // assert.equal(globalThis.StaticPropertyNamespace.NestedProperties.nestedProperty, exports.StaticPropertyNamespace.NestedProperties.nestedProperty); - - // // Verify enum values accessible via globalThis match exports - // assert.equal(exports.Configuration.LogLevel.Debug, globalThis.Configuration.LogLevelValues.Debug); - // assert.equal(exports.Networking.API.Method.Get, globalThis.Networking.API.MethodValues.Get); -} - -/** @param {import('./../.build/plugins/PackageToJS/outputs/PackageTests/bridge-js.d.ts').Exports} exports */ -async function BridgeJSRuntimeTests_runAsyncWorks(exports) { - await exports.asyncRoundTripVoid(); -} - -function setupTestGlobals(global) { - global.globalObject1 = { - prop_1: { - nested_prop: 1, - }, - prop_2: 2, - prop_3: true, - prop_4: [3, 4, "str_elm_1", null, undefined, 5], - prop_5: { - func1: function () { - return; - }, - func2: function () { - return 1; - }, - func3: function (n) { - return n * 2; - }, - func4: function (a, b, c) { - return a + b + c; - }, - func5: function (x) { - return "Hello, " + x; - }, - func6: function (c, a, b) { - if (c) { - return a; - } else { - return b; - } - }, - }, - prop_6: { - call_host_1: () => { - return global.globalObject1.prop_6.host_func_1(); - }, - }, - prop_7: 3.14, - prop_8: [0, , 2, 3, , , 6], - eval_closure: function (fn) { - return fn(arguments[1]); - }, - observable_obj: { - set_called: false, - target: new Proxy( - { - nested: {}, - }, - { - set(target, key, value) { - global.globalObject1.observable_obj.set_called = true; - target[key] = value; - return true; - }, - } - ), - }, - }; - - global.Animal = function (name, age, isCat) { - if (age < 0) { - throw new Error("Invalid age " + age); - } - this.name = name; - this.age = age; - this.bark = () => { - return isCat ? "nyan" : "wan"; - }; - this.isCat = isCat; - this.getIsCat = function () { - return this.isCat; - }; - this.setName = function (name) { - this.name = name; - }; - }; - - global.callThrowingClosure = (c) => { - try { - c(); - } catch (error) { - return error; - } - }; - - global.objectDecodingTest = { - obj: {}, - fn: () => { }, - sym: Symbol("s"), - bi: BigInt(3) - }; -} diff --git a/Tests/prelude.mjs b/Tests/prelude.mjs index 640a6561..cfd898b3 100644 --- a/Tests/prelude.mjs +++ b/Tests/prelude.mjs @@ -88,7 +88,12 @@ export async function setupOptions(options, context) { } return BridgeJSRuntimeTests_runJsWorks(getInstance(), exports); } + const bridgeJSGlobalTests = importObject["BridgeJSGlobalTests"] || {}; + bridgeJSGlobalTests["runJsWorksGlobal"] = () => { + return BridgeJSGlobalTests_runJsWorksGlobal(); + } importObject["BridgeJSRuntimeTests"] = bridgeJSRuntimeTests; + importObject["BridgeJSGlobalTests"] = bridgeJSGlobalTests; } } } @@ -897,6 +902,51 @@ async function BridgeJSRuntimeTests_runAsyncWorks(exports) { await exports.asyncRoundTripVoid(); } +function BridgeJSGlobalTests_runJsWorksGlobal() { + assert.equal(globalThis.GlobalNetworking.API.CallMethodValues.Get, 0); + assert.equal(globalThis.GlobalNetworking.API.CallMethodValues.Post, 1); + assert.equal(globalThis.GlobalNetworking.API.CallMethodValues.Put, 2); + assert.equal(globalThis.GlobalNetworking.API.CallMethodValues.Delete, 3); + + assert.equal(globalThis.GlobalConfiguration.PublicLogLevelValues.Debug, "debug"); + assert.equal(globalThis.GlobalConfiguration.PublicLogLevelValues.Info, "info"); + assert.equal(globalThis.GlobalConfiguration.PublicLogLevelValues.Warning, "warning"); + assert.equal(globalThis.GlobalConfiguration.PublicLogLevelValues.Error, "error"); + assert.equal(globalThis.GlobalConfiguration.AvailablePortValues.Http, 80); + assert.equal(globalThis.GlobalConfiguration.AvailablePortValues.Https, 443); + assert.equal(globalThis.GlobalConfiguration.AvailablePortValues.Development, 3000); + + assert.equal(globalThis.GlobalNetworking.APIV2.Internal.SupportedServerMethodValues.Get, 0); + assert.equal(globalThis.GlobalNetworking.APIV2.Internal.SupportedServerMethodValues.Post, 1); + + const globalConverter = new globalThis.GlobalUtils.PublicConverter(); + assert.equal(globalConverter.toString(99), "99"); + globalConverter.release(); + + const globalHttpServer = new globalThis.GlobalNetworking.API.TestHTTPServer(); + globalHttpServer.call(globalThis.GlobalNetworking.API.CallMethodValues.Get); + globalHttpServer.release(); + + const globalTestServer = new globalThis.GlobalNetworking.APIV2.Internal.TestInternalServer(); + globalTestServer.call(globalThis.GlobalNetworking.APIV2.Internal.SupportedServerMethodValues.Post); + globalTestServer.release(); + + assert.equal(globalThis.GlobalStaticPropertyNamespace.namespaceProperty, "namespace"); + assert.equal(globalThis.GlobalStaticPropertyNamespace.namespaceConstant, "constant"); + + globalThis.GlobalStaticPropertyNamespace.namespaceProperty = "further modified"; + assert.equal(globalThis.GlobalStaticPropertyNamespace.namespaceProperty, "further modified"); + + assert.equal(globalThis.GlobalStaticPropertyNamespace.NestedProperties.nestedProperty, 999); + assert.equal(globalThis.GlobalStaticPropertyNamespace.NestedProperties.nestedConstant, "nested"); + assert.equal(globalThis.GlobalStaticPropertyNamespace.NestedProperties.nestedDouble, 1.414); + + globalThis.GlobalStaticPropertyNamespace.NestedProperties.nestedProperty = 2000; + globalThis.GlobalStaticPropertyNamespace.NestedProperties.nestedDouble = 3.141; + assert.equal(globalThis.GlobalStaticPropertyNamespace.NestedProperties.nestedProperty, 2000); + assert.equal(globalThis.GlobalStaticPropertyNamespace.NestedProperties.nestedDouble, 3.141); +} + function setupTestGlobals(global) { global.globalObject1 = { prop_1: {