diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift index 11951e7d..89bbcac4 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift @@ -784,7 +784,11 @@ struct StackCodegen { case .string: return "\(raw: enumName).bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())" - case .bool, .int, .int32, .int64, .uint, .uint32, .uint64, .float, .double: + case .float: + return "\(raw: enumName).bridgeJSLiftParameter(_swift_js_pop_param_f32())" + case .double: + return "\(raw: enumName).bridgeJSLiftParameter(_swift_js_pop_param_f64())" + case .bool, .int, .int32, .int64, .uint, .uint32, .uint64: return "\(raw: enumName).bridgeJSLiftParameter(_swift_js_pop_param_int32())" } case .associatedValueEnum(let enumName): @@ -825,7 +829,13 @@ struct StackCodegen { case .string: return "Optional<\(raw: enumName)>.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32(), _swift_js_pop_param_int32())" - case .bool, .int, .float, .double, .int32, .int64, .uint, .uint32, .uint64: + case .float: + return + "Optional<\(raw: enumName)>.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_f32())" + case .double: + return + "Optional<\(raw: enumName)>.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_f64())" + case .bool, .int, .int32, .int64, .uint, .uint32, .uint64: return "Optional<\(raw: enumName)>.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())" } @@ -880,8 +890,20 @@ struct StackCodegen { return ["_swift_js_push_int(\(raw: accessor).bridgeJSLowerParameter())"] case .caseEnum: return ["_swift_js_push_int(Int32(\(raw: accessor).bridgeJSLowerParameter()))"] - case .rawValueEnum: - return ["_swift_js_push_int(Int32(\(raw: accessor).bridgeJSLowerParameter()))"] + case .rawValueEnum(_, let rawType): + switch rawType { + case .string: + return [ + "var __bjs_\(raw: varPrefix) = \(raw: accessor).rawValue", + "__bjs_\(raw: varPrefix).withUTF8 { ptr in _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) }", + ] + case .float: + return ["_swift_js_push_f32(\(raw: accessor).bridgeJSLowerParameter())"] + case .double: + return ["_swift_js_push_f64(\(raw: accessor).bridgeJSLowerParameter())"] + default: + return ["_swift_js_push_int(Int32(\(raw: accessor).bridgeJSLowerParameter()))"] + } case .associatedValueEnum: return ["\(raw: accessor).bridgeJSLowerReturn()"] case .swiftStruct: @@ -948,6 +970,10 @@ struct StackCodegen { "var __bjs_str_\(raw: varPrefix) = \(raw: unwrappedVar).rawValue", "__bjs_str_\(raw: varPrefix).withUTF8 { ptr in _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) }", ] + case .float: + return ["_swift_js_push_f32(\(raw: unwrappedVar).bridgeJSLowerParameter())"] + case .double: + return ["_swift_js_push_f64(\(raw: unwrappedVar).bridgeJSLowerParameter())"] default: return ["_swift_js_push_int(\(raw: unwrappedVar).bridgeJSLowerParameter())"] } diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift index 6b45f677..ef5c5eb2 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift @@ -2357,6 +2357,32 @@ struct IntrinsicJSFragment: Sendable { "if(\(idVar) !== undefined) { \(JSGlueVariableScope.reservedSwift).memory.release(\(idVar)); }" ) return [idVar] + case .float: + printer.write("if (\(isSomeVar)) {") + printer.indent { + printer.write( + "\(JSGlueVariableScope.reservedTmpParamF32s).push(Math.fround(\(value)));" + ) + } + printer.write("} else {") + printer.indent { + printer.write("\(JSGlueVariableScope.reservedTmpParamF32s).push(0.0);") + } + printer.write("}") + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") + return [] + case .double: + printer.write("if (\(isSomeVar)) {") + printer.indent { + printer.write("\(JSGlueVariableScope.reservedTmpParamF64s).push(\(value));") + } + printer.write("} else {") + printer.indent { + printer.write("\(JSGlueVariableScope.reservedTmpParamF64s).push(0.0);") + } + printer.write("}") + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") + return [] default: printer.write("if (\(isSomeVar)) {") printer.indent { @@ -2596,6 +2622,22 @@ struct IntrinsicJSFragment: Sendable { return [idVar] } ) + case .float: + return IntrinsicJSFragment( + parameters: ["value"], + printCode: { arguments, scope, printer, cleanup in + printer.write("\(JSGlueVariableScope.reservedTmpParamF32s).push(Math.fround(\(arguments[0])));") + return [] + } + ) + case .double: + return IntrinsicJSFragment( + parameters: ["value"], + printCode: { arguments, scope, printer, cleanup in + printer.write("\(JSGlueVariableScope.reservedTmpParamF64s).push(\(arguments[0]));") + return [] + } + ) default: return IntrinsicJSFragment( parameters: ["value"], @@ -2795,6 +2837,24 @@ struct IntrinsicJSFragment: Sendable { return [varName] } ) + case .float: + return IntrinsicJSFragment( + parameters: [], + printCode: { arguments, scope, printer, cleanup in + let varName = scope.variable("value") + printer.write("const \(varName) = \(JSGlueVariableScope.reservedTmpRetF32s).pop();") + return [varName] + } + ) + case .double: + return IntrinsicJSFragment( + parameters: [], + printCode: { arguments, scope, printer, cleanup in + let varName = scope.variable("value") + printer.write("const \(varName) = \(JSGlueVariableScope.reservedTmpRetF64s).pop();") + return [varName] + } + ) default: return IntrinsicJSFragment( parameters: [], diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/SwiftStruct.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/SwiftStruct.swift index 3415f54a..ac316a05 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/SwiftStruct.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/SwiftStruct.swift @@ -35,6 +35,17 @@ @JS func roundtrip(_ session: Person) -> Person +@JS enum Precision: Float { + case rough = 0.1 + case fine = 0.001 +} + +@JS struct Measurement { + var value: Double + var precision: Precision + var optionalPrecision: Precision? +} + @JS struct ConfigStruct { @JS static let maxRetries: Int = 3 @JS nonisolated(unsafe) static var defaultConfig: String = "production" diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.Export.d.ts index 1d147451..7769ebcb 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.Export.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.Export.d.ts @@ -4,6 +4,12 @@ // To update this file, just rebuild your project or run // `swift package bridge-js`. +export const PrecisionValues: { + readonly Rough: 0.1; + readonly Fine: 0.001; +}; +export type PrecisionTag = typeof PrecisionValues[keyof typeof PrecisionValues]; + export interface DataPoint { x: number; y: number; @@ -26,8 +32,15 @@ export interface Session { id: number; owner: Greeter; } +export interface Measurement { + value: number; + precision: PrecisionTag; + optionalPrecision: PrecisionTag | null; +} export interface ConfigStruct { } +export type PrecisionObject = typeof PrecisionValues; + /// Represents a Swift heap object like a class instance or an actor instance. export interface SwiftHeapObject { /// Release the heap object. @@ -44,6 +57,7 @@ export type Exports = { new(name: string): Greeter; } roundtrip(session: Person): Person; + Precision: PrecisionObject DataPoint: { init(x: number, y: number, label: string, optCount: number | null, optFlag: boolean | null): DataPoint; } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.Export.js index abcd9500..91968b77 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.Export.js @@ -4,6 +4,11 @@ // To update this file, just rebuild your project or run // `swift package bridge-js`. +export const PrecisionValues = { + Rough: 0.1, + Fine: 0.001, +}; + export async function createInstantiator(options, swift) { let instance; let memory; @@ -184,6 +189,35 @@ export async function createInstantiator(options, swift) { } }); }; + const __bjs_createMeasurementHelpers = () => { + return (tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, enumHelpers) => ({ + lower: (value) => { + tmpParamF64s.push(value.value); + tmpParamF32s.push(Math.fround(value.precision)); + const isSome = value.optionalPrecision != null; + if (isSome) { + tmpParamF32s.push(Math.fround(value.optionalPrecision)); + } else { + tmpParamF32s.push(0.0); + } + tmpParamInts.push(isSome ? 1 : 0); + return { cleanup: undefined }; + }, + raise: (tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers) => { + const isSome = tmpRetInts.pop(); + let optional; + if (isSome) { + const value = tmpRetF32s.pop(); + optional = value; + } else { + optional = null; + } + const value1 = tmpRetF32s.pop(); + const f64 = tmpRetF64s.pop(); + return { value: f64, precision: value1, optionalPrecision: optional }; + } + }); + }; const __bjs_createConfigStructHelpers = () => { return (tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, enumHelpers) => ({ lower: (value) => { @@ -315,6 +349,17 @@ export async function createInstantiator(options, swift) { const value = structHelpers.Session.raise(tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); return swift.memory.retain(value); } + bjs["swift_js_struct_lower_Measurement"] = function(objectId) { + const { cleanup: cleanup } = structHelpers.Measurement.lower(swift.memory.getObject(objectId)); + if (cleanup) { + return tmpStructCleanups.push(cleanup); + } + return 0; + } + bjs["swift_js_struct_raise_Measurement"] = function() { + const value = structHelpers.Measurement.raise(tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); + return swift.memory.retain(value); + } bjs["swift_js_struct_lower_ConfigStruct"] = function(objectId) { const { cleanup: cleanup } = structHelpers.ConfigStruct.lower(swift.memory.getObject(objectId)); if (cleanup) { @@ -498,6 +543,9 @@ export async function createInstantiator(options, swift) { const SessionHelpers = __bjs_createSessionHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, enumHelpers); structHelpers.Session = SessionHelpers; + const MeasurementHelpers = __bjs_createMeasurementHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, enumHelpers); + structHelpers.Measurement = MeasurementHelpers; + const ConfigStructHelpers = __bjs_createConfigStructHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, enumHelpers); structHelpers.ConfigStruct = ConfigStructHelpers; @@ -510,6 +558,7 @@ export async function createInstantiator(options, swift) { if (cleanup) { cleanup(); } return structValue; }, + Precision: PrecisionValues, DataPoint: { init: function(x, y, label, optCount, optFlag) { const labelBytes = textEncoder.encode(label); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftStruct.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftStruct.json index c6e430ed..ca8f7c62 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftStruct.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftStruct.json @@ -56,7 +56,35 @@ } ], "enums" : [ + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "rough", + "rawValue" : "0.1" + }, + { + "associatedValues" : [ + + ], + "name" : "fine", + "rawValue" : "0.001" + } + ], + "emitStyle" : "const", + "name" : "Precision", + "rawType" : "Float", + "staticMethods" : [ + + ], + "staticProperties" : [ + ], + "swiftCallName" : "Precision", + "tsFullPath" : "Precision" + } ], "exposeToGlobal" : false, "functions" : [ @@ -345,6 +373,51 @@ ], "swiftCallName" : "Session" }, + { + "methods" : [ + + ], + "name" : "Measurement", + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "value", + "type" : { + "double" : { + + } + } + }, + { + "isReadonly" : true, + "isStatic" : false, + "name" : "precision", + "type" : { + "rawValueEnum" : { + "_0" : "Precision", + "_1" : "Float" + } + } + }, + { + "isReadonly" : true, + "isStatic" : false, + "name" : "optionalPrecision", + "type" : { + "optional" : { + "_0" : { + "rawValueEnum" : { + "_0" : "Precision", + "_1" : "Float" + } + } + } + } + } + ], + "swiftCallName" : "Measurement" + }, { "methods" : [ { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftStruct.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftStruct.swift index 001f3e4c..6c9c88ec 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftStruct.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftStruct.swift @@ -1,3 +1,6 @@ +extension Precision: _BridgedSwiftEnumNoPayload { +} + extension DataPoint: _BridgedSwiftStruct { @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter() -> DataPoint { let optFlag = Optional.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32()) @@ -232,6 +235,57 @@ fileprivate func _bjs_struct_raise_Session() -> Int32 { } #endif +extension Measurement: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter() -> Measurement { + let optionalPrecision = Optional.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_f32()) + let precision = Precision.bridgeJSLiftParameter(_swift_js_pop_param_f32()) + let value = Double.bridgeJSLiftParameter(_swift_js_pop_param_f64()) + return Measurement(value: value, precision: precision, optionalPrecision: optionalPrecision) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { + _swift_js_push_f64(self.value) + _swift_js_push_f32(self.precision.bridgeJSLowerParameter()) + let __bjs_isSome_optionalPrecision = self.optionalPrecision != nil + if let __bjs_unwrapped_optionalPrecision = self.optionalPrecision { + _swift_js_push_f32(__bjs_unwrapped_optionalPrecision.bridgeJSLowerParameter()) + } + _swift_js_push_int(__bjs_isSome_optionalPrecision ? 1 : 0) + } + + init(unsafelyCopying jsObject: JSObject) { + let __bjs_cleanupId = _bjs_struct_lower_Measurement(jsObject.bridgeJSLowerParameter()) + defer { + _swift_js_struct_cleanup(__bjs_cleanupId) + } + self = Self.bridgeJSLiftParameter() + } + + func toJSObject() -> JSObject { + var __bjs_self = self + __bjs_self.bridgeJSLowerReturn() + return JSObject(id: UInt32(bitPattern: _bjs_struct_raise_Measurement())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_Measurement") +fileprivate func _bjs_struct_lower_Measurement(_ objectId: Int32) -> Int32 +#else +fileprivate func _bjs_struct_lower_Measurement(_ objectId: Int32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_raise_Measurement") +fileprivate func _bjs_struct_raise_Measurement() -> Int32 +#else +fileprivate func _bjs_struct_raise_Measurement() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif + extension ConfigStruct: _BridgedSwiftStruct { @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter() -> ConfigStruct { return ConfigStruct() diff --git a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift index fe4a44de..411b0102 100644 --- a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift +++ b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift @@ -226,6 +226,18 @@ struct TestError: Error { case unknown = -1 } +@JS enum Precision: Float { + case rough = 0.1 + case normal = 0.01 + case fine = 0.001 +} + +@JS enum Ratio: Double { + case quarter = 0.25 + case half = 0.5 + case golden = 1.618 +} + @JS(enumStyle: .tsEnum) enum TSDirection { case north case south @@ -1390,6 +1402,17 @@ enum APIOptionalResult { cart.toJSObject() } +@JS struct MeasurementConfig { + var precision: Precision + var ratio: Ratio + var optionalPrecision: Precision? + var optionalRatio: Ratio? +} + +@JS func roundTripMeasurementConfig(_ config: MeasurementConfig) -> MeasurementConfig { + return config +} + @JS struct ConfigStruct { var name: String var value: Int diff --git a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift index f46a6d40..8b2b596f 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift @@ -1298,6 +1298,12 @@ extension Theme: _BridgedSwiftEnumNoPayload { extension HttpStatus: _BridgedSwiftEnumNoPayload { } +extension Precision: _BridgedSwiftEnumNoPayload { +} + +extension Ratio: _BridgedSwiftEnumNoPayload { +} + extension TSDirection: _BridgedSwiftCaseEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { return bridgeJSRawValue @@ -2898,6 +2904,63 @@ public func _bjs_CopyableNestedCart_static_fromJSObject(_ object: Int32) -> Void #endif } +extension MeasurementConfig: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter() -> MeasurementConfig { + let optionalRatio = Optional.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_f64()) + let optionalPrecision = Optional.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_f32()) + let ratio = Ratio.bridgeJSLiftParameter(_swift_js_pop_param_f64()) + let precision = Precision.bridgeJSLiftParameter(_swift_js_pop_param_f32()) + return MeasurementConfig(precision: precision, ratio: ratio, optionalPrecision: optionalPrecision, optionalRatio: optionalRatio) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { + _swift_js_push_f32(self.precision.bridgeJSLowerParameter()) + _swift_js_push_f64(self.ratio.bridgeJSLowerParameter()) + let __bjs_isSome_optionalPrecision = self.optionalPrecision != nil + if let __bjs_unwrapped_optionalPrecision = self.optionalPrecision { + _swift_js_push_f32(__bjs_unwrapped_optionalPrecision.bridgeJSLowerParameter()) + } + _swift_js_push_int(__bjs_isSome_optionalPrecision ? 1 : 0) + let __bjs_isSome_optionalRatio = self.optionalRatio != nil + if let __bjs_unwrapped_optionalRatio = self.optionalRatio { + _swift_js_push_f64(__bjs_unwrapped_optionalRatio.bridgeJSLowerParameter()) + } + _swift_js_push_int(__bjs_isSome_optionalRatio ? 1 : 0) + } + + init(unsafelyCopying jsObject: JSObject) { + let __bjs_cleanupId = _bjs_struct_lower_MeasurementConfig(jsObject.bridgeJSLowerParameter()) + defer { + _swift_js_struct_cleanup(__bjs_cleanupId) + } + self = Self.bridgeJSLiftParameter() + } + + func toJSObject() -> JSObject { + var __bjs_self = self + __bjs_self.bridgeJSLowerReturn() + return JSObject(id: UInt32(bitPattern: _bjs_struct_raise_MeasurementConfig())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_MeasurementConfig") +fileprivate func _bjs_struct_lower_MeasurementConfig(_ objectId: Int32) -> Int32 +#else +fileprivate func _bjs_struct_lower_MeasurementConfig(_ objectId: Int32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_raise_MeasurementConfig") +fileprivate func _bjs_struct_raise_MeasurementConfig() -> Int32 +#else +fileprivate func _bjs_struct_raise_MeasurementConfig() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif + extension ConfigStruct: _BridgedSwiftStruct { @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter() -> ConfigStruct { let value = Int.bridgeJSLiftParameter(_swift_js_pop_param_int32()) @@ -4437,6 +4500,17 @@ public func _bjs_nestedCartToJSObject() -> Int32 { #endif } +@_expose(wasm, "bjs_roundTripMeasurementConfig") +@_cdecl("bjs_roundTripMeasurementConfig") +public func _bjs_roundTripMeasurementConfig() -> Void { + #if arch(wasm32) + let ret = roundTripMeasurementConfig(_: MeasurementConfig.bridgeJSLiftParameter()) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + @_expose(wasm, "bjs_roundTripDataPoint") @_cdecl("bjs_roundTripDataPoint") public func _bjs_roundTripDataPoint() -> Void { diff --git a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json index 82c394a9..180dc6c1 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json +++ b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json @@ -3341,6 +3341,78 @@ { "associatedValues" : [ + ], + "name" : "rough", + "rawValue" : "0.1" + }, + { + "associatedValues" : [ + + ], + "name" : "normal", + "rawValue" : "0.01" + }, + { + "associatedValues" : [ + + ], + "name" : "fine", + "rawValue" : "0.001" + } + ], + "emitStyle" : "const", + "name" : "Precision", + "rawType" : "Float", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Precision", + "tsFullPath" : "Precision" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "quarter", + "rawValue" : "0.25" + }, + { + "associatedValues" : [ + + ], + "name" : "half", + "rawValue" : "0.5" + }, + { + "associatedValues" : [ + + ], + "name" : "golden", + "rawValue" : "1.618" + } + ], + "emitStyle" : "const", + "name" : "Ratio", + "rawType" : "Double", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Ratio", + "tsFullPath" : "Ratio" + }, + { + "cases" : [ + { + "associatedValues" : [ + ], "name" : "north" }, @@ -7966,6 +8038,31 @@ } } }, + { + "abiName" : "bjs_roundTripMeasurementConfig", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "roundTripMeasurementConfig", + "parameters" : [ + { + "label" : "_", + "name" : "config", + "type" : { + "swiftStruct" : { + "_0" : "MeasurementConfig" + } + } + } + ], + "returnType" : { + "swiftStruct" : { + "_0" : "MeasurementConfig" + } + } + }, { "abiName" : "bjs_roundTripDataPoint", "effects" : { @@ -9383,6 +9480,67 @@ { "methods" : [ + ], + "name" : "MeasurementConfig", + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "precision", + "type" : { + "rawValueEnum" : { + "_0" : "Precision", + "_1" : "Float" + } + } + }, + { + "isReadonly" : true, + "isStatic" : false, + "name" : "ratio", + "type" : { + "rawValueEnum" : { + "_0" : "Ratio", + "_1" : "Double" + } + } + }, + { + "isReadonly" : true, + "isStatic" : false, + "name" : "optionalPrecision", + "type" : { + "optional" : { + "_0" : { + "rawValueEnum" : { + "_0" : "Precision", + "_1" : "Float" + } + } + } + } + }, + { + "isReadonly" : true, + "isStatic" : false, + "name" : "optionalRatio", + "type" : { + "optional" : { + "_0" : { + "rawValueEnum" : { + "_0" : "Ratio", + "_1" : "Double" + } + } + } + } + } + ], + "swiftCallName" : "MeasurementConfig" + }, + { + "methods" : [ + ], "name" : "ConfigStruct", "properties" : [ diff --git a/Tests/prelude.mjs b/Tests/prelude.mjs index d9560507..65bb7d60 100644 --- a/Tests/prelude.mjs +++ b/Tests/prelude.mjs @@ -458,6 +458,13 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { assert.equal(HttpStatusValues.ServerError, 500); assert.equal(HttpStatusValues.Unknown, -1); + assert.equal(exports.Precision.Rough, 0.1); + assert.equal(exports.Precision.Normal, 0.01); + assert.equal(exports.Precision.Fine, 0.001); + assert.equal(exports.Ratio.Quarter, 0.25); + assert.equal(exports.Ratio.Half, 0.5); + assert.equal(exports.Ratio.Golden, 1.618); + assert.equal(exports.setTheme(exports.Theme.Light), exports.Theme.Light); assert.equal(exports.setTheme(exports.Theme.Dark), exports.Theme.Dark); assert.equal(exports.getTheme(), ThemeValues.Light); @@ -1089,6 +1096,22 @@ function testStructSupport(exports) { exports.ConfigStruct.defaultConfig = "staging"; assert.equal(exports.ConfigStruct.computedSetting, "Config: staging"); exports.ConfigStruct.defaultConfig = "production"; + + const { Precision, Ratio } = exports; + const mc1 = { + precision: Math.fround(Precision.Rough), + ratio: Ratio.Golden, + optionalPrecision: Math.fround(Precision.Fine), + optionalRatio: Ratio.Half + }; + assert.deepEqual(exports.roundTripMeasurementConfig(mc1), mc1); + const mc2 = { + precision: Math.fround(Precision.Normal), + ratio: Ratio.Quarter, + optionalPrecision: null, + optionalRatio: null + }; + assert.deepEqual(exports.roundTripMeasurementConfig(mc2), mc2); } /** @param {import('./../.build/plugins/PackageToJS/outputs/PackageTests/bridge-js.d.ts').Exports} exports */