diff --git a/IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift b/IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift index 07937b01a..bf4c9bc4f 100644 --- a/IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift +++ b/IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift @@ -356,14 +356,14 @@ try test("Call Function With This") { try test("Object Conversion") { let array1 = [1, 2, 3] - let jsArray1 = array1.jsValue().object! + let jsArray1 = array1.jsValue.object! try expectEqual(jsArray1.length, .number(3)) try expectEqual(jsArray1[0], .number(1)) try expectEqual(jsArray1[1], .number(2)) try expectEqual(jsArray1[2], .number(3)) let array2: [ConvertibleToJSValue] = [1, "str", false] - let jsArray2 = array2.jsValue().object! + let jsArray2 = array2.jsValue.object! try expectEqual(jsArray2.length, .number(3)) try expectEqual(jsArray2[0], .number(1)) try expectEqual(jsArray2[1], .string("str")) @@ -374,11 +374,11 @@ try test("Object Conversion") { try expectEqual(jsArray2[4], .object(jsArray1)) - let dict1: [String: ConvertibleToJSValue] = [ - "prop1": 1, - "prop2": "foo", + let dict1: [String: JSValue] = [ + "prop1": 1.jsValue, + "prop2": "foo".jsValue, ] - let jsDict1 = dict1.jsValue().object! + let jsDict1 = dict1.jsValue.object! try expectEqual(jsDict1.prop1, .number(1)) try expectEqual(jsDict1.prop2, .string("foo")) } @@ -425,7 +425,7 @@ try test("Closure Identifiers") { #endif func checkArray(_ array: [T]) throws where T: TypedArrayElement & Equatable { - try expectEqual(toString(JSTypedArray(array).jsValue().object!), jsStringify(array)) + try expectEqual(toString(JSTypedArray(array).jsValue.object!), jsStringify(array)) try checkArrayUnsafeBytes(array) } @@ -488,7 +488,7 @@ try test("TypedArray_Mutation") { for i in 0..<100 { try expectEqual(i, array[i]) } - try expectEqual(toString(array.jsValue().object!), jsStringify(Array(0..<100))) + try expectEqual(toString(array.jsValue.object!), jsStringify(Array(0..<100))) } try test("Date") { @@ -797,9 +797,9 @@ try test("Hashable Conformance") { let objectConstructor = JSObject.global.Object.function! let obj = objectConstructor.new() - obj.a = 1.jsValue() + obj.a = 1.jsValue let firstHash = obj.hashValue - obj.b = 2.jsValue() + obj.b = 2.jsValue let secondHash = obj.hashValue try expectEqual(firstHash, secondHash) } @@ -819,11 +819,11 @@ try test("Symbols") { // }) // }.prop let hasInstanceObject = JSObject.global.Object.function!.new() - hasInstanceObject.prop = JSClosure { _ in .undefined }.jsValue() + hasInstanceObject.prop = JSClosure { _ in .undefined }.jsValue let hasInstanceClass = hasInstanceObject.prop.function! hasInstanceClass[JSSymbol.hasInstance] = JSClosure { _ in return .boolean(true) - }.jsValue() + }.jsValue try expectEqual(hasInstanceClass[JSSymbol.hasInstance].function!().boolean, true) try expectEqual(JSObject.global.Object.isInstanceOf(hasInstanceClass), true) } diff --git a/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift b/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift index b68889c42..8ff30c8aa 100644 --- a/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift +++ b/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift @@ -5,7 +5,7 @@ import _CJavaScriptEventLoop #if compiler(>=5.5) -@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) +@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) public final class JavaScriptEventLoop: SerialExecutor, @unchecked Sendable { /// A function that queues a given closure as a microtask into JavaScript event loop. @@ -97,7 +97,7 @@ public final class JavaScriptEventLoop: SerialExecutor, @unchecked Sendable { } } -@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) +@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) public extension JSPromise { /// Wait for the promise to complete, returning (or throwing) its result. var value: JSValue { diff --git a/Sources/JavaScriptEventLoop/JobQueue.swift b/Sources/JavaScriptEventLoop/JobQueue.swift index 56090d120..44b2f7249 100644 --- a/Sources/JavaScriptEventLoop/JobQueue.swift +++ b/Sources/JavaScriptEventLoop/JobQueue.swift @@ -6,13 +6,13 @@ import _CJavaScriptEventLoop #if compiler(>=5.5) -@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) +@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) struct QueueState: Sendable { fileprivate var headJob: UnownedJob? = nil fileprivate var isSpinning: Bool = false } -@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) +@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) extension JavaScriptEventLoop { func insertJobQueue(job newJob: UnownedJob) { @@ -58,7 +58,7 @@ extension JavaScriptEventLoop { } } -@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *) +@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) fileprivate extension UnownedJob { private func asImpl() -> UnsafeMutablePointer<_CJavaScriptEventLoop.Job> { unsafeBitCast(self, to: UnsafeMutablePointer<_CJavaScriptEventLoop.Job>.self) diff --git a/Sources/JavaScriptKit/BasicObjects/JSError.swift b/Sources/JavaScriptKit/BasicObjects/JSError.swift index 305f1d9d5..cbdac8d6e 100644 --- a/Sources/JavaScriptKit/BasicObjects/JSError.swift +++ b/Sources/JavaScriptKit/BasicObjects/JSError.swift @@ -34,7 +34,7 @@ public final class JSError: Error, JSBridgedClass { } /// Creates a new `JSValue` from this `JSError` instance. - public func jsValue() -> JSValue { + public var jsValue: JSValue { .object(jsObject) } } diff --git a/Sources/JavaScriptKit/BasicObjects/JSPromise.swift b/Sources/JavaScriptKit/BasicObjects/JSPromise.swift index 5b0d47dd4..0aa44cadd 100644 --- a/Sources/JavaScriptKit/BasicObjects/JSPromise.swift +++ b/Sources/JavaScriptKit/BasicObjects/JSPromise.swift @@ -79,7 +79,7 @@ public final class JSPromise: JSBridgedClass { @discardableResult public func then(success: @escaping (JSValue) -> ConvertibleToJSValue) -> JSPromise { let closure = JSOneshotClosure { - return success($0[0]).jsValue() + success($0[0]).jsValue } return JSPromise(unsafelyWrapping: jsObject.then!(closure).object!) } @@ -90,10 +90,10 @@ public final class JSPromise: JSBridgedClass { public func then(success: @escaping (JSValue) -> ConvertibleToJSValue, failure: @escaping (JSValue) -> ConvertibleToJSValue) -> JSPromise { let successClosure = JSOneshotClosure { - return success($0[0]).jsValue() + success($0[0]).jsValue } let failureClosure = JSOneshotClosure { - return failure($0[0]).jsValue() + failure($0[0]).jsValue } return JSPromise(unsafelyWrapping: jsObject.then!(successClosure, failureClosure).object!) } @@ -103,7 +103,7 @@ public final class JSPromise: JSBridgedClass { @discardableResult public func `catch`(failure: @escaping (JSValue) -> ConvertibleToJSValue) -> JSPromise { let closure = JSOneshotClosure { - return failure($0[0]).jsValue() + failure($0[0]).jsValue } return .init(unsafelyWrapping: jsObject.catch!(closure).object!) } diff --git a/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift b/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift index e073d7c29..ebcf35959 100644 --- a/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift +++ b/Sources/JavaScriptKit/BasicObjects/JSTypedArray.swift @@ -13,7 +13,7 @@ public protocol TypedArrayElement: ConvertibleToJSValue, ConstructibleFromJSValu /// A wrapper around all JavaScript [TypedArray](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) classes that exposes their properties in a type-safe way. /// FIXME: [BigInt-based TypedArrays are currently not supported](https://github.com/swiftwasm/JavaScriptKit/issues/56). public class JSTypedArray: JSBridgedClass, ExpressibleByArrayLiteral where Element: TypedArrayElement { - public static var constructor: JSFunction { Element.typedArrayClass } + public class var constructor: JSFunction { Element.typedArrayClass } public var jsObject: JSObject public subscript(_ index: Int) -> Element { @@ -21,7 +21,7 @@ public class JSTypedArray: JSBridgedClass, ExpressibleByArrayLiteral wh return Element.construct(from: jsObject[index])! } set { - self.jsObject[index] = newValue.jsValue() + self.jsObject[index] = newValue.jsValue } } @@ -30,7 +30,7 @@ public class JSTypedArray: JSBridgedClass, ExpressibleByArrayLiteral wh /// /// - Parameter length: The number of elements that will be allocated. public init(length: Int) { - jsObject = Element.typedArrayClass.new(length) + jsObject = Self.constructor.new(length) } required public init(unsafelyWrapping jsObject: JSObject) { @@ -45,7 +45,7 @@ public class JSTypedArray: JSBridgedClass, ExpressibleByArrayLiteral wh /// - Parameter array: The array that will be copied to create a new instance of TypedArray public convenience init(_ array: [Element]) { let jsArrayRef = array.withUnsafeBufferPointer { ptr in - _create_typed_array(Element.typedArrayClass.id, ptr.baseAddress!, Int32(array.count)) + _create_typed_array(Self.constructor.id, ptr.baseAddress!, Int32(array.count)) } self.init(unsafelyWrapping: JSObject(id: jsArrayRef)) } @@ -116,7 +116,10 @@ extension Int8: TypedArrayElement { extension UInt8: TypedArrayElement { public static var typedArrayClass = JSObject.global.Uint8Array.function! } -// TODO: Support Uint8ClampedArray? + +public class JSUInt8ClampedArray: JSTypedArray { + public class override var constructor: JSFunction { JSObject.global.Uint8ClampedArray.function! } +} extension Int16: TypedArrayElement { public static var typedArrayClass = JSObject.global.Int16Array.function! diff --git a/Sources/JavaScriptKit/ConvertibleToJSValue.swift b/Sources/JavaScriptKit/ConvertibleToJSValue.swift index deb4a523c..83680ad02 100644 --- a/Sources/JavaScriptKit/ConvertibleToJSValue.swift +++ b/Sources/JavaScriptKit/ConvertibleToJSValue.swift @@ -3,7 +3,12 @@ import _CJavaScriptKit /// Objects that can be converted to a JavaScript value, preferably in a lossless manner. public protocol ConvertibleToJSValue { /// Create a JSValue that represents this object - func jsValue() -> JSValue + var jsValue: JSValue { get } +} + +extension ConvertibleToJSValue { + @available(*, deprecated, message: "Use the .jsValue property instead") + public func jsValue() -> JSValue { jsValue } } public typealias JSValueCompatible = ConvertibleToJSValue & ConstructibleFromJSValue @@ -13,67 +18,67 @@ extension JSValue: JSValueCompatible { return value } - public func jsValue() -> JSValue { self } + public var jsValue: JSValue { self } } extension Bool: ConvertibleToJSValue { - public func jsValue() -> JSValue { .boolean(self) } + public var jsValue: JSValue { .boolean(self) } } extension Int: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension UInt: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension Float: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension Double: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(self) } + public var jsValue: JSValue { .number(self) } } extension String: ConvertibleToJSValue { - public func jsValue() -> JSValue { .string(JSString(self)) } + public var jsValue: JSValue { .string(JSString(self)) } } extension UInt8: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension UInt16: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension UInt32: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension UInt64: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension Int8: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension Int16: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension Int32: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension Int64: ConvertibleToJSValue { - public func jsValue() -> JSValue { .number(Double(self)) } + public var jsValue: JSValue { .number(Double(self)) } } extension JSString: ConvertibleToJSValue { - public func jsValue() -> JSValue { .string(self) } + public var jsValue: JSValue { .string(self) } } extension JSObject: JSValueCompatible { @@ -84,17 +89,21 @@ extension JSObject: JSValueCompatible { private let objectConstructor = JSObject.global.Object.function! private let arrayConstructor = JSObject.global.Array.function! -extension Dictionary where Value: ConvertibleToJSValue, Key == String { - public func jsValue() -> JSValue { - Swift.Dictionary.jsValue(self)() +extension Dictionary where Value == ConvertibleToJSValue, Key == String { + public var jsValue: JSValue { + let object = objectConstructor.new() + for (key, value) in self { + object[key] = value.jsValue + } + return .object(object) } } -extension Dictionary: ConvertibleToJSValue where Value == ConvertibleToJSValue, Key == String { - public func jsValue() -> JSValue { +extension Dictionary: ConvertibleToJSValue where Value: ConvertibleToJSValue, Key == String { + public var jsValue: JSValue { let object = objectConstructor.new() for (key, value) in self { - object[key] = value.jsValue() + object[key] = value.jsValue } return .object(object) } @@ -104,7 +113,7 @@ extension Dictionary: ConstructibleFromJSValue where Value: ConstructibleFromJSV public static func construct(from value: JSValue) -> Self? { guard let objectRef = value.object, - let keys: [String] = objectConstructor.keys!(objectRef.jsValue()).fromJSValue() + let keys: [String] = objectConstructor.keys!(objectRef.jsValue).fromJSValue() else { return nil } var entries = [(String, Value)]() @@ -131,25 +140,29 @@ extension Optional: ConstructibleFromJSValue where Wrapped: ConstructibleFromJSV } extension Optional: ConvertibleToJSValue where Wrapped: ConvertibleToJSValue { - public func jsValue() -> JSValue { + public var jsValue: JSValue { switch self { case .none: return .null - case let .some(wrapped): return wrapped.jsValue() + case let .some(wrapped): return wrapped.jsValue } } } -extension Array where Element: ConvertibleToJSValue { - public func jsValue() -> JSValue { - Array.jsValue(self)() +extension Array: ConvertibleToJSValue where Element: ConvertibleToJSValue { + public var jsValue: JSValue { + let array = arrayConstructor.new(count) + for (index, element) in enumerated() { + array[index] = element.jsValue + } + return .object(array) } } -extension Array: ConvertibleToJSValue where Element == ConvertibleToJSValue { - public func jsValue() -> JSValue { +extension Array where Element == ConvertibleToJSValue { + public var jsValue: JSValue { let array = arrayConstructor.new(count) for (index, element) in enumerated() { - array[index] = element.jsValue() + array[index] = element.jsValue } return .object(array) } @@ -176,7 +189,7 @@ extension Array: ConstructibleFromJSValue where Element: ConstructibleFromJSValu } extension RawJSValue: ConvertibleToJSValue { - public func jsValue() -> JSValue { + public var jsValue: JSValue { switch kind { case .invalid: fatalError() @@ -243,7 +256,7 @@ extension Array where Element == ConvertibleToJSValue { _ results: inout [RawJSValue], _ body: ([RawJSValue]) -> T ) -> T { if index == values.count { return body(results) } - return values[index].jsValue().withRawJSValue { (rawValue) -> T in + return values[index].jsValue.withRawJSValue { (rawValue) -> T in results.append(rawValue) return _withRawJSValues(values, index + 1, &results, body) } diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift b/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift index f8c2632c9..cbd44bd6e 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift @@ -137,9 +137,7 @@ func _call_host_function_impl( guard let (_, hostFunc) = JSClosure.sharedClosures[hostFuncRef] else { fatalError("The function was already released") } - let arguments = UnsafeBufferPointer(start: argv, count: Int(argc)).map { - $0.jsValue() - } + let arguments = UnsafeBufferPointer(start: argv, count: Int(argc)).map(\.jsValue) let result = hostFunc(arguments) let callbackFuncRef = JSFunction(id: callbackFuncRef) _ = callbackFuncRef(result) diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift b/Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift index 6a05a8de2..9cec5dad0 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift @@ -18,7 +18,7 @@ public class JSFunction: JSObject { /// - Returns: The result of this call. @discardableResult public func callAsFunction(this: JSObject? = nil, arguments: [ConvertibleToJSValue]) -> JSValue { - invokeNonThrowingJSFunction(self, arguments: arguments, this: this).jsValue() + invokeNonThrowingJSFunction(self, arguments: arguments, this: this).jsValue } /// A variadic arguments version of `callAsFunction`. @@ -78,7 +78,7 @@ public class JSFunction: JSObject { return value.function as? Self } - override public func jsValue() -> JSValue { + override public var jsValue: JSValue { .function(self) } } diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift index 0768817e2..427648bcc 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift @@ -39,6 +39,24 @@ public class JSObject: Equatable { } } + /// Returns the `name` member method binding this object as `this` context. + /// + /// e.g. + /// ```swift + /// let document = JSObject.global.document.object! + /// let divElement = document.createElement!("div") + /// ``` + /// + /// - Parameter name: The name of this object's member to access. + /// - Returns: The `name` member method binding this object as `this` context. + @_disfavoredOverload + public subscript(_ name: JSString) -> ((ConvertibleToJSValue...) -> JSValue)? { + guard let function = self[name].function else { return nil } + return { (arguments: ConvertibleToJSValue...) in + function(this: self, arguments: arguments) + } + } + /// A convenience method of `subscript(_ name: String) -> ((ConvertibleToJSValue...) -> JSValue)?` /// to access the member through Dynamic Member Lookup. @_disfavoredOverload @@ -134,7 +152,7 @@ public class JSObject: Equatable { return value.object as? Self } - public func jsValue() -> JSValue { + public var jsValue: JSValue { .object(self) } } diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSThrowingFunction.swift b/Sources/JavaScriptKit/FundamentalObjects/JSThrowingFunction.swift index adcd82a63..3e21f0e1b 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSThrowingFunction.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSThrowingFunction.swift @@ -50,7 +50,7 @@ public class JSThrowingFunction { ) if exceptionKind.isException { let exception = RawJSValue(kind: exceptionKind.kind, payload1: exceptionPayload1, payload2: exceptionPayload2) - return .failure(exception.jsValue()) + return .failure(exception.jsValue) } return .success(JSObject(id: resultObj)) } @@ -82,7 +82,7 @@ private func invokeJSFunction(_ jsFunc: JSFunction, arguments: [ConvertibleToJSV ) } let result = RawJSValue(kind: kindAndFlags.kind, payload1: payload1, payload2: payload2) - return (result.jsValue(), kindAndFlags.isException) + return (result.jsValue, kindAndFlags.isException) } } if isException { diff --git a/Sources/JavaScriptKit/JSBridgedType.swift b/Sources/JavaScriptKit/JSBridgedType.swift index acd1fa6ef..235d78331 100644 --- a/Sources/JavaScriptKit/JSBridgedType.swift +++ b/Sources/JavaScriptKit/JSBridgedType.swift @@ -1,21 +1,16 @@ /// Use this protocol when your type has no single JavaScript class. /// For example, a union type of multiple classes or primitive values. public protocol JSBridgedType: JSValueCompatible, CustomStringConvertible { - /// This is the value your class wraps. - var value: JSValue { get } - /// If your class is incompatible with the provided value, return `nil`. init?(from value: JSValue) } extension JSBridgedType { public static func construct(from value: JSValue) -> Self? { - return Self.init(from: value) + Self.init(from: value) } - public func jsValue() -> JSValue { value } - - public var description: String { value.description } + public var description: String { jsValue.description } } /// Conform to this protocol when your Swift class wraps a JavaScript class. @@ -33,7 +28,8 @@ public protocol JSBridgedClass: JSBridgedType { } extension JSBridgedClass { - public var value: JSValue { jsObject.jsValue() } + public var jsValue: JSValue { jsObject.jsValue } + public init?(from value: JSValue) { guard let object = value.object else { return nil } self.init(from: object) diff --git a/Sources/JavaScriptKit/JSValue.swift b/Sources/JavaScriptKit/JSValue.swift index b363db679..b001dc7ab 100644 --- a/Sources/JavaScriptKit/JSValue.swift +++ b/Sources/JavaScriptKit/JSValue.swift @@ -187,7 +187,7 @@ public func getJSValue(this: JSObject, name: JSString) -> JSValue { _get_prop(this.id, name.asInternalJSRef(), &rawValue.kind, &rawValue.payload1, &rawValue.payload2) - return rawValue.jsValue() + return rawValue.jsValue } public func setJSValue(this: JSObject, name: JSString, value: JSValue) { @@ -201,7 +201,7 @@ public func getJSValue(this: JSObject, index: Int32) -> JSValue { _get_subscript(this.id, index, &rawValue.kind, &rawValue.payload1, &rawValue.payload2) - return rawValue.jsValue() + return rawValue.jsValue } public func setJSValue(this: JSObject, index: Int32, value: JSValue) { @@ -217,7 +217,7 @@ public func getJSValue(this: JSObject, symbol: JSSymbol) -> JSValue { _get_prop(this.id, symbol.id, &rawValue.kind, &rawValue.payload1, &rawValue.payload2) - return rawValue.jsValue() + return rawValue.jsValue } public func setJSValue(this: JSObject, symbol: JSSymbol, value: JSValue) {