From 5a5a4635628bfe9ca301b2c2da4fdf5c50ea693b Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Fri, 28 Aug 2020 09:50:58 +0900 Subject: [PATCH 1/2] Refine public API Drop Ref suffix --- .../Sources/PrimaryTests/UnitTestUtils.swift | 4 ++-- .../Sources/PrimaryTests/main.swift | 2 +- README.md | 6 ++--- .../JSArray.swift} | 23 +++++++++++-------- Sources/JavaScriptKit/Deprecated.swift | 5 ++++ .../{ => FundamentalObjects}/JSFunction.swift | 12 +++++----- .../{ => FundamentalObjects}/JSObject.swift | 6 ++--- Sources/JavaScriptKit/JSValue.swift | 16 +++++-------- .../JavaScriptKit/JSValueConvertible.swift | 10 ++++---- Sources/JavaScriptKit/JSValueDecoder.swift | 16 ++++++------- 10 files changed, 53 insertions(+), 47 deletions(-) rename Sources/JavaScriptKit/{JSArrayRef.swift => BasicObjects/JSArray.swift} (67%) create mode 100644 Sources/JavaScriptKit/Deprecated.swift rename Sources/JavaScriptKit/{ => FundamentalObjects}/JSFunction.swift (93%) rename Sources/JavaScriptKit/{ => FundamentalObjects}/JSObject.swift (87%) diff --git a/IntegrationTests/TestSuites/Sources/PrimaryTests/UnitTestUtils.swift b/IntegrationTests/TestSuites/Sources/PrimaryTests/UnitTestUtils.swift index f4cc69663..becf261ba 100644 --- a/IntegrationTests/TestSuites/Sources/PrimaryTests/UnitTestUtils.swift +++ b/IntegrationTests/TestSuites/Sources/PrimaryTests/UnitTestUtils.swift @@ -37,7 +37,7 @@ func expectEqual( } } -func expectObject(_ value: JSValue, file: StaticString = #file, line: UInt = #line, column: UInt = #column) throws -> JSObjectRef { +func expectObject(_ value: JSValue, file: StaticString = #file, line: UInt = #line, column: UInt = #column) throws -> JSObject { switch value { case let .object(ref): return ref default: @@ -45,7 +45,7 @@ func expectObject(_ value: JSValue, file: StaticString = #file, line: UInt = #li } } -func expectArray(_ value: JSValue, file: StaticString = #file, line: UInt = #line, column: UInt = #column) throws -> JSArrayRef { +func expectArray(_ value: JSValue, file: StaticString = #file, line: UInt = #line, column: UInt = #column) throws -> JSArray { guard let array = value.array else { throw MessageError("Type of \(value) should be \"object\"", file: file, line: line, column: column) } diff --git a/IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift b/IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift index 3c3e5deca..16a78d4bc 100644 --- a/IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift +++ b/IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift @@ -1,7 +1,7 @@ import JavaScriptKit test("Literal Conversion") { - let global = JSObjectRef.global + let global = JSObject.global let inputs: [JSValue] = [ .boolean(true), .boolean(false), diff --git a/README.md b/README.md index 6ef24ef3d..155d517eb 100644 --- a/README.md +++ b/README.md @@ -47,8 +47,8 @@ Can be written in Swift using JavaScriptKit ```swift import JavaScriptKit -let alert = JSObjectRef.global.alert.function! -let document = JSObjectRef.global.document.object! +let alert = JSObject.global.alert.function! +let document = JSObject.global.document.object! let divElement = document.createElement!("div").object! divElement.innerText = "Hello, world" @@ -64,7 +64,7 @@ struct Pet: Codable { let owner: Owner } -let jsPet = JSObjectRef.global.pet +let jsPet = JSObject.global.pet let swiftPet: Pet = try JSValueDecoder().decode(from: jsPet) alert("Swift is running on browser!") diff --git a/Sources/JavaScriptKit/JSArrayRef.swift b/Sources/JavaScriptKit/BasicObjects/JSArray.swift similarity index 67% rename from Sources/JavaScriptKit/JSArrayRef.swift rename to Sources/JavaScriptKit/BasicObjects/JSArray.swift index df3937b12..85c811a39 100644 --- a/Sources/JavaScriptKit/JSArrayRef.swift +++ b/Sources/JavaScriptKit/BasicObjects/JSArray.swift @@ -1,20 +1,19 @@ +public class JSArray { + static let classObject = JSObject.global.Array.function! -public class JSArrayRef { - static let classObject = JSObjectRef.global.Array.function! - - static func isArray(_ object: JSObjectRef) -> Bool { + static func isArray(_ object: JSObject) -> Bool { classObject.isArray!(object).boolean! } - let ref: JSObjectRef + let ref: JSObject - public init?(_ ref: JSObjectRef) { + public init?(_ ref: JSObject) { guard Self.isArray(ref) else { return nil } self.ref = ref } } -extension JSArrayRef: RandomAccessCollection { +extension JSArray: RandomAccessCollection { public typealias Element = JSValue public func makeIterator() -> Iterator { @@ -22,9 +21,9 @@ extension JSArrayRef: RandomAccessCollection { } public class Iterator: IteratorProtocol { - let ref: JSObjectRef + let ref: JSObject var index = 0 - init(ref: JSObjectRef) { + init(ref: JSObject) { self.ref = ref } @@ -46,3 +45,9 @@ extension JSArrayRef: RandomAccessCollection { public var endIndex: Int { ref.length.number.map(Int.init) ?? 0 } } + +extension JSValue { + public var array: JSArray? { + object.flatMap(JSArray.init) + } +} diff --git a/Sources/JavaScriptKit/Deprecated.swift b/Sources/JavaScriptKit/Deprecated.swift new file mode 100644 index 000000000..7549120b7 --- /dev/null +++ b/Sources/JavaScriptKit/Deprecated.swift @@ -0,0 +1,5 @@ +@available(*, deprecated, renamed: "JSObject") +public typealias JSObjectRef = JSObject + +@available(*, deprecated, renamed: "JSArray") +public typealias JSArrayRef = JSArray diff --git a/Sources/JavaScriptKit/JSFunction.swift b/Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift similarity index 93% rename from Sources/JavaScriptKit/JSFunction.swift rename to Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift index f3b0c5b22..d91d5459c 100644 --- a/Sources/JavaScriptKit/JSFunction.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift @@ -1,8 +1,8 @@ import _CJavaScriptKit -public class JSFunctionRef: JSObjectRef { +public class JSFunctionRef: JSObject { @discardableResult - public func callAsFunction(this: JSObjectRef? = nil, arguments: [JSValueConvertible]) -> JSValue { + public func callAsFunction(this: JSObject? = nil, arguments: [JSValueConvertible]) -> JSValue { let result = arguments.withRawJSValues { rawValues in rawValues.withUnsafeBufferPointer { bufferPointer -> RawJSValue in let argv = bufferPointer.baseAddress @@ -25,11 +25,11 @@ public class JSFunctionRef: JSObjectRef { } @discardableResult - public func callAsFunction(this: JSObjectRef? = nil, _ arguments: JSValueConvertible...) -> JSValue { + public func callAsFunction(this: JSObject? = nil, _ arguments: JSValueConvertible...) -> JSValue { self(this: this, arguments: arguments) } - public func new(_ arguments: JSValueConvertible...) -> JSObjectRef { + public func new(_ arguments: JSValueConvertible...) -> JSObject { new(arguments: arguments) } @@ -37,7 +37,7 @@ public class JSFunctionRef: JSObjectRef { // a) the constructor explicitly returns an object, or // b) the constructor returns nothing, which causes JS to return the `this` value, or // c) the constructor returns undefined, null or a non-object, in which case JS also returns `this`. - public func new(arguments: [JSValueConvertible]) -> JSObjectRef { + public func new(arguments: [JSValueConvertible]) -> JSObject { arguments.withRawJSValues { rawValues in rawValues.withUnsafeBufferPointer { bufferPointer in let argv = bufferPointer.baseAddress @@ -47,7 +47,7 @@ public class JSFunctionRef: JSObjectRef { self.id, argv, Int32(argc), &resultObj ) - return JSObjectRef(id: resultObj) + return JSObject(id: resultObj) } } } diff --git a/Sources/JavaScriptKit/JSObject.swift b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift similarity index 87% rename from Sources/JavaScriptKit/JSObject.swift rename to Sources/JavaScriptKit/FundamentalObjects/JSObject.swift index 4a6f47f9f..e285d49b9 100644 --- a/Sources/JavaScriptKit/JSObject.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift @@ -1,7 +1,7 @@ import _CJavaScriptKit @dynamicMemberLookup -public class JSObjectRef: Equatable { +public class JSObject: Equatable { internal var id: UInt32 init(id: UInt32) { self.id = id @@ -35,11 +35,11 @@ public class JSObjectRef: Equatable { } static let _JS_Predef_Value_Global: UInt32 = 0 - public static let global = JSObjectRef(id: _JS_Predef_Value_Global) + public static let global = JSObject(id: _JS_Predef_Value_Global) deinit { _destroy_ref(id) } - public static func == (lhs: JSObjectRef, rhs: JSObjectRef) -> Bool { + public static func == (lhs: JSObject, rhs: JSObject) -> Bool { return lhs.id == rhs.id } diff --git a/Sources/JavaScriptKit/JSValue.swift b/Sources/JavaScriptKit/JSValue.swift index 14434130f..652d01f31 100644 --- a/Sources/JavaScriptKit/JSValue.swift +++ b/Sources/JavaScriptKit/JSValue.swift @@ -4,7 +4,7 @@ public enum JSValue: Equatable { case boolean(Bool) case string(String) case number(Double) - case object(JSObjectRef) + case object(JSObject) case null case undefined case function(JSFunctionRef) @@ -30,17 +30,13 @@ public enum JSValue: Equatable { } } - public var object: JSObjectRef? { + public var object: JSObject? { switch self { case let .object(object): return object default: return nil } } - public var array: JSArrayRef? { - object.flatMap { JSArrayRef($0) } - } - public var isNull: Bool { return self == .null } public var isUndefined: Bool { return self == .undefined } public var function: JSFunctionRef? { @@ -69,7 +65,7 @@ extension JSValue: ExpressibleByIntegerLiteral { } } -public func getJSValue(this: JSObjectRef, name: String) -> JSValue { +public func getJSValue(this: JSObject, name: String) -> JSValue { var rawValue = RawJSValue() _get_prop(this.id, name, Int32(name.count), &rawValue.kind, @@ -77,13 +73,13 @@ public func getJSValue(this: JSObjectRef, name: String) -> JSValue { return rawValue.jsValue() } -public func setJSValue(this: JSObjectRef, name: String, value: JSValue) { +public func setJSValue(this: JSObject, name: String, value: JSValue) { value.withRawJSValue { rawValue in _set_prop(this.id, name, Int32(name.count), rawValue.kind, rawValue.payload1, rawValue.payload2, rawValue.payload3) } } -public func getJSValue(this: JSObjectRef, index: Int32) -> JSValue { +public func getJSValue(this: JSObject, index: Int32) -> JSValue { var rawValue = RawJSValue() _get_subscript(this.id, index, &rawValue.kind, @@ -91,7 +87,7 @@ public func getJSValue(this: JSObjectRef, index: Int32) -> JSValue { return rawValue.jsValue() } -public func setJSValue(this: JSObjectRef, index: Int32, value: JSValue) { +public func setJSValue(this: JSObject, index: Int32, value: JSValue) { value.withRawJSValue { rawValue in _set_subscript(this.id, index, rawValue.kind, diff --git a/Sources/JavaScriptKit/JSValueConvertible.swift b/Sources/JavaScriptKit/JSValueConvertible.swift index 08897aa92..7ed3441cf 100644 --- a/Sources/JavaScriptKit/JSValueConvertible.swift +++ b/Sources/JavaScriptKit/JSValueConvertible.swift @@ -52,12 +52,12 @@ extension String: JSValueConvertible { public func jsValue() -> JSValue { .string(self) } } -extension JSObjectRef: JSValueConvertible { - // `JSObjectRef.jsValue` is defined in JSObjectRef.swift to be able to overridden +extension JSObject: JSValueConvertible { + // `JSObject.jsValue` is defined in JSObject.swift to be able to overridden // from `JSFunctionRef` } -private let Object = JSObjectRef.global.Object.function! +private let Object = JSObject.global.Object.function! extension Dictionary where Value: JSValueConvertible, Key == String { public func jsValue() -> JSValue { @@ -75,7 +75,7 @@ extension Dictionary: JSValueConvertible where Value == JSValueConvertible, Key } } -private let Array = JSObjectRef.global.Array.function! +private let Array = JSObject.global.Array.function! extension Array where Element: JSValueConvertible { public func jsValue() -> JSValue { @@ -111,7 +111,7 @@ extension RawJSValue: JSValueConvertible { let string = String(decodingCString: UnsafePointer(buffer), as: UTF8.self) return .string(string) case .object: - return .object(JSObjectRef(id: UInt32(payload1))) + return .object(JSObject(id: UInt32(payload1))) case .null: return .null case .undefined: diff --git a/Sources/JavaScriptKit/JSValueDecoder.swift b/Sources/JavaScriptKit/JSValueDecoder.swift index e71a0c991..e5c2d5bbd 100644 --- a/Sources/JavaScriptKit/JSValueDecoder.swift +++ b/Sources/JavaScriptKit/JSValueDecoder.swift @@ -11,12 +11,12 @@ private struct _Decoder: Decoder { let userInfo: [CodingUserInfoKey: Any] func container(keyedBy _: Key.Type) throws -> KeyedDecodingContainer where Key: CodingKey { - guard let ref = node.object else { throw _typeMismatch(at: codingPath, JSObjectRef.self, reality: node) } + guard let ref = node.object else { throw _typeMismatch(at: codingPath, JSObject.self, reality: node) } return KeyedDecodingContainer(_KeyedDecodingContainer(decoder: self, ref: ref)) } func unkeyedContainer() throws -> UnkeyedDecodingContainer { - guard let ref = node.object else { throw _typeMismatch(at: codingPath, JSObjectRef.self, reality: node) } + guard let ref = node.object else { throw _typeMismatch(at: codingPath, JSObject.self, reality: node) } return _UnkeyedDecodingContainer(decoder: self, ref: ref) } @@ -34,8 +34,8 @@ private struct _Decoder: Decoder { } private enum Object { - static let ref = JSObjectRef.global.Object.object! - static func keys(_ object: JSObjectRef) -> [String] { + static let ref = JSObject.global.Object.object! + static func keys(_ object: JSObject) -> [String] { let keys = ref.keys!(object).array! return keys.map { $0.string! } } @@ -77,14 +77,14 @@ struct _JSCodingKey: CodingKey { private struct _KeyedDecodingContainer: KeyedDecodingContainerProtocol { private let decoder: _Decoder - private let ref: JSObjectRef + private let ref: JSObject var codingPath: [CodingKey] { return decoder.codingPath } var allKeys: [Key] { Object.keys(ref).compactMap(Key.init(stringValue:)) } - init(decoder: _Decoder, ref: JSObjectRef) { + init(decoder: _Decoder, ref: JSObject) { self.decoder = decoder self.ref = ref } @@ -152,9 +152,9 @@ private struct _UnkeyedDecodingContainer: UnkeyedDecodingContainer { private var currentKey: CodingKey { return _JSCodingKey(index: currentIndex) } let decoder: _Decoder - let ref: JSObjectRef + let ref: JSObject - init(decoder: _Decoder, ref: JSObjectRef) { + init(decoder: _Decoder, ref: JSObject) { self.decoder = decoder count = ref.length.number.map(Int.init) self.ref = ref From 2ce09357f495c856ab35760cffba77b0e8907214 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Fri, 28 Aug 2020 10:08:33 +0900 Subject: [PATCH 2/2] Drop ref suffix from JSFunctionRef --- Sources/JavaScriptKit/Deprecated.swift | 3 +++ Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift | 8 ++++---- Sources/JavaScriptKit/FundamentalObjects/JSObject.swift | 2 +- Sources/JavaScriptKit/JSValue.swift | 4 ++-- Sources/JavaScriptKit/JSValueConvertible.swift | 4 ++-- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Sources/JavaScriptKit/Deprecated.swift b/Sources/JavaScriptKit/Deprecated.swift index 7549120b7..69306ac5f 100644 --- a/Sources/JavaScriptKit/Deprecated.swift +++ b/Sources/JavaScriptKit/Deprecated.swift @@ -3,3 +3,6 @@ public typealias JSObjectRef = JSObject @available(*, deprecated, renamed: "JSArray") public typealias JSArrayRef = JSArray + +@available(*, deprecated, renamed: "JSFunction") +public typealias JSFunctionRef = JSFunction diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift b/Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift index d91d5459c..8379b175f 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift @@ -1,6 +1,6 @@ import _CJavaScriptKit -public class JSFunctionRef: JSObject { +public class JSFunction: JSObject { @discardableResult public func callAsFunction(this: JSObject? = nil, arguments: [JSValueConvertible]) -> JSValue { let result = arguments.withRawJSValues { rawValues in @@ -53,7 +53,7 @@ public class JSFunctionRef: JSObject { } @available(*, unavailable, message: "Please use JSClosure instead") - public static func from(_: @escaping ([JSValue]) -> JSValue) -> JSFunctionRef { + public static func from(_: @escaping ([JSValue]) -> JSValue) -> JSFunction { fatalError("unavailable") } @@ -62,7 +62,7 @@ public class JSFunctionRef: JSObject { } } -public class JSClosure: JSFunctionRef { +public class JSClosure: JSFunction { static var sharedFunctions: [JavaScriptHostFuncRef: ([JSValue]) -> JSValue] = [:] private var hostFuncRef: JavaScriptHostFuncRef = 0 @@ -128,6 +128,6 @@ public func _call_host_function( $0.jsValue() } let result = hostFunc(arguments) - let callbackFuncRef = JSFunctionRef(id: callbackFuncRef) + let callbackFuncRef = JSFunction(id: callbackFuncRef) _ = callbackFuncRef(result) } diff --git a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift index e285d49b9..5955aa536 100644 --- a/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift +++ b/Sources/JavaScriptKit/FundamentalObjects/JSObject.swift @@ -30,7 +30,7 @@ public class JSObject: Equatable { set { setJSValue(this: self, index: Int32(index), value: newValue) } } - public func isInstanceOf(_ constructor: JSFunctionRef) -> Bool { + public func isInstanceOf(_ constructor: JSFunction) -> Bool { _instanceof(id, constructor.id) } diff --git a/Sources/JavaScriptKit/JSValue.swift b/Sources/JavaScriptKit/JSValue.swift index 652d01f31..4ac7a4579 100644 --- a/Sources/JavaScriptKit/JSValue.swift +++ b/Sources/JavaScriptKit/JSValue.swift @@ -7,7 +7,7 @@ public enum JSValue: Equatable { case object(JSObject) case null case undefined - case function(JSFunctionRef) + case function(JSFunction) public var boolean: Bool? { switch self { @@ -39,7 +39,7 @@ public enum JSValue: Equatable { public var isNull: Bool { return self == .null } public var isUndefined: Bool { return self == .undefined } - public var function: JSFunctionRef? { + public var function: JSFunction? { switch self { case let .function(function): return function default: return nil diff --git a/Sources/JavaScriptKit/JSValueConvertible.swift b/Sources/JavaScriptKit/JSValueConvertible.swift index 7ed3441cf..eb4e27452 100644 --- a/Sources/JavaScriptKit/JSValueConvertible.swift +++ b/Sources/JavaScriptKit/JSValueConvertible.swift @@ -54,7 +54,7 @@ extension String: JSValueConvertible { extension JSObject: JSValueConvertible { // `JSObject.jsValue` is defined in JSObject.swift to be able to overridden - // from `JSFunctionRef` + // from `JSFunction` } private let Object = JSObject.global.Object.function! @@ -117,7 +117,7 @@ extension RawJSValue: JSValueConvertible { case .undefined: return .undefined case .function: - return .function(JSFunctionRef(id: UInt32(payload1))) + return .function(JSFunction(id: UInt32(payload1))) default: fatalError("unreachable") }