Skip to content

Commit b123600

Browse files
mjburghardj-f1
authored andcommitted
Changes related to WebIDL support.
1 parent 376ef99 commit b123600

File tree

5 files changed

+255
-25
lines changed

5 files changed

+255
-25
lines changed

Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,7 @@ public class JSFunction: JSObject {
4343
let argv = bufferPointer.baseAddress
4444
let argc = bufferPointer.count
4545
var resultObj = JavaScriptObjectRef()
46-
_call_new(
47-
self.id, argv, Int32(argc),
48-
&resultObj
49-
)
46+
_call_new(self.id, argv, Int32(argc), &resultObj)
5047
return JSObject(id: resultObj)
5148
}
5249
}
@@ -57,6 +54,10 @@ public class JSFunction: JSObject {
5754
fatalError("unavailable")
5855
}
5956

57+
public override class func construct(from value: JSValue) -> Self? {
58+
return value.function as? Self
59+
}
60+
6061
override public func jsValue() -> JSValue {
6162
.function(self)
6263
}
@@ -89,6 +90,15 @@ public class JSClosure: JSFunction {
8990
}
9091
}
9192

93+
public required convenience init(jsValue: JSValue) {
94+
switch jsValue {
95+
case let .function(fun):
96+
self.init { fun(arguments: $0) }
97+
default:
98+
fatalError()
99+
}
100+
}
101+
92102
public func release() {
93103
Self.sharedFunctions[hostFuncRef] = nil
94104
isReleased = true

Sources/JavaScriptKit/FundamentalObjects/JSObject.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ public class JSObject: Equatable {
4343
return lhs.id == rhs.id
4444
}
4545

46+
public class func construct(from value: JSValue) -> Self? {
47+
return value.object as? Self
48+
}
49+
4650
public func jsValue() -> JSValue {
4751
.object(self)
4852
}

Sources/JavaScriptKit/JSValue.swift

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,51 @@ public enum JSValue: Equatable {
3737
}
3838
}
3939

40-
public var isNull: Bool { return self == .null }
41-
public var isUndefined: Bool { return self == .undefined }
4240
public var function: JSFunction? {
4341
switch self {
4442
case let .function(function): return function
4543
default: return nil
4644
}
4745
}
46+
47+
public var isBoolean: Bool {
48+
guard case .boolean = self else { return false }
49+
return true
50+
}
51+
52+
public var isString: Bool {
53+
guard case .string = self else { return false }
54+
return true
55+
}
56+
57+
public var isNumber: Bool {
58+
guard case .number = self else { return false }
59+
return true
60+
}
61+
62+
public var isObject: Bool {
63+
guard case .object = self else { return false }
64+
return true
65+
}
66+
67+
public var isNull: Bool {
68+
return self == .null
69+
}
70+
71+
public var isUndefined: Bool {
72+
return self == .undefined
73+
}
74+
75+
public var isFunction: Bool {
76+
guard case .function = self else { return false }
77+
return true
78+
}
79+
}
80+
81+
extension JSValue {
82+
public func fromJSValue<Type>() -> Type? where Type: JSValueConstructible {
83+
return Type.construct(from: self)
84+
}
4885
}
4986

5087
extension JSValue {
@@ -60,7 +97,13 @@ extension JSValue: ExpressibleByStringLiteral {
6097
}
6198

6299
extension JSValue: ExpressibleByIntegerLiteral {
63-
public init(integerLiteral value: Double) {
100+
public init(integerLiteral value: Int32) {
101+
self = .number(Double(value))
102+
}
103+
}
104+
105+
extension JSValue: ExpressibleByFloatLiteral {
106+
public init(floatLiteral value: Double) {
64107
self = .number(value)
65108
}
66109
}
@@ -94,3 +137,18 @@ public func setJSValue(this: JSObject, index: Int32, value: JSValue) {
94137
rawValue.payload1, rawValue.payload2, rawValue.payload3)
95138
}
96139
}
140+
141+
extension JSValue {
142+
public func isInstanceOf(_ constructor: JSFunction) -> Bool {
143+
switch self {
144+
case .boolean, .string, .number:
145+
return false
146+
case let .object(ref):
147+
return ref.isInstanceOf(constructor)
148+
case let .function(ref):
149+
return ref.isInstanceOf(constructor)
150+
case .null, .undefined:
151+
fatalError()
152+
}
153+
}
154+
}

Sources/JavaScriptKit/JSValueConvertible.swift

Lines changed: 119 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,47 @@
11
import _CJavaScriptKit
22

3+
public protocol JSBridgedType: JSValueCodable, CustomStringConvertible {
4+
static var constructor: JSFunction? { get }
5+
6+
var objectRef: JSObject { get }
7+
init(objectRef: JSObject)
8+
}
9+
10+
extension JSBridgedType {
11+
public var description: String {
12+
return objectRef.toString!().fromJSValue()!
13+
}
14+
}
15+
316
public protocol JSValueConvertible {
417
func jsValue() -> JSValue
518
}
619

7-
extension JSValue: JSValueConvertible {
20+
public typealias JSValueCodable = JSValueConvertible & JSValueConstructible
21+
22+
extension JSBridgedType {
23+
public static func canDecode(from jsValue: JSValue) -> Bool {
24+
if let constructor = Self.constructor {
25+
return jsValue.isInstanceOf(constructor)
26+
} else {
27+
return jsValue.isObject
28+
}
29+
}
30+
31+
public init(jsValue: JSValue) {
32+
self.init(objectRef: jsValue.object!)
33+
}
34+
35+
public func jsValue() -> JSValue {
36+
return JSValue.object(objectRef)
37+
}
38+
}
39+
40+
extension JSValue: JSValueCodable {
41+
public static func construct(from value: JSValue) -> Self? {
42+
return value
43+
}
44+
845
public func jsValue() -> JSValue { self }
946
}
1047

@@ -16,20 +53,20 @@ extension Int: JSValueConvertible {
1653
public func jsValue() -> JSValue { .number(Double(self)) }
1754
}
1855

19-
extension Int8: JSValueConvertible {
56+
extension UInt: JSValueConvertible {
2057
public func jsValue() -> JSValue { .number(Double(self)) }
2158
}
2259

23-
extension Int16: JSValueConvertible {
60+
extension Float: JSValueConvertible {
2461
public func jsValue() -> JSValue { .number(Double(self)) }
2562
}
2663

27-
extension Int32: JSValueConvertible {
28-
public func jsValue() -> JSValue { .number(Double(self)) }
64+
extension Double: JSValueConvertible {
65+
public func jsValue() -> JSValue { .number(self) }
2966
}
3067

31-
extension UInt: JSValueConvertible {
32-
public func jsValue() -> JSValue { .number(Double(self)) }
68+
extension String: JSValueConvertible {
69+
public func jsValue() -> JSValue { .string(self) }
3370
}
3471

3572
extension UInt8: JSValueConvertible {
@@ -41,22 +78,30 @@ extension UInt16: JSValueConvertible {
4178
}
4279

4380
extension UInt32: JSValueConvertible {
44-
public func jsValue() -> JSValue { .number(Double(self)) }
81+
public func jsValue() -> JSValue { .number(Double(self)) }
4582
}
4683

47-
extension Float: JSValueConvertible {
84+
extension UInt64: JSValueConvertible {
4885
public func jsValue() -> JSValue { .number(Double(self)) }
4986
}
5087

51-
extension Double: JSValueConvertible {
52-
public func jsValue() -> JSValue { .number(self) }
88+
extension Int8: JSValueConvertible {
89+
public func jsValue() -> JSValue { .number(Double(self)) }
5390
}
5491

55-
extension String: JSValueConvertible {
56-
public func jsValue() -> JSValue { .string(self) }
92+
extension Int16: JSValueConvertible {
93+
public func jsValue() -> JSValue { .number(Double(self)) }
94+
}
95+
96+
extension Int32: JSValueConvertible {
97+
public func jsValue() -> JSValue { .number(Double(self)) }
5798
}
5899

59-
extension JSObject: JSValueConvertible {
100+
extension Int64: JSValueConvertible {
101+
public func jsValue() -> JSValue { .number(Double(self)) }
102+
}
103+
104+
extension JSObject: JSValueCodable {
60105
// `JSObject.jsValue` is defined in JSObject.swift to be able to overridden
61106
// from `JSFunction`
62107
}
@@ -79,24 +124,80 @@ extension Dictionary: JSValueConvertible where Value == JSValueConvertible, Key
79124
}
80125
}
81126

82-
private let Array = JSObject.global.Array.function!
127+
private let NativeJSArray = JSObject.global.Array.function!
128+
extension Dictionary: JSValueConstructible where Value: JSValueConstructible, Key == String {
129+
public static func construct(from value: JSValue) -> Self? {
130+
if let objectRef = value.object,
131+
let keys: [String] = Object.keys!(objectRef.jsValue()).fromJSValue() {
132+
var entries = [(String, Value)]()
133+
entries.reserveCapacity(keys.count)
134+
for key in keys {
135+
guard let value: Value = objectRef[key].fromJSValue() else {
136+
return nil
137+
}
138+
entries.append((key, value))
139+
}
140+
return Dictionary(uniqueKeysWithValues: entries)
141+
}
142+
return nil
143+
}
144+
}
145+
146+
extension Optional: JSValueConstructible where Wrapped: JSValueConstructible {
147+
public static func construct(from value: JSValue) -> Self? {
148+
switch value {
149+
case .null, .undefined:
150+
return nil
151+
default:
152+
return Wrapped.construct(from: value)
153+
}
154+
}
155+
}
156+
157+
extension Optional: JSValueConvertible where Wrapped: JSValueConvertible {
158+
public func jsValue() -> JSValue {
159+
switch self {
160+
case .none: return .null
161+
case let .some(wrapped): return wrapped.jsValue()
162+
}
163+
}
164+
}
83165

84166
extension Array where Element: JSValueConvertible {
85167
public func jsValue() -> JSValue {
86-
Swift.Array<JSValueConvertible>.jsValue(self)()
168+
Array<JSValueConvertible>.jsValue(self)()
87169
}
88170
}
89171

90172
extension Array: JSValueConvertible where Element == JSValueConvertible {
91173
public func jsValue() -> JSValue {
92-
let array = Array.new(count)
174+
let array = NativeJSArray.new(count)
93175
for (index, element) in enumerated() {
94176
array[index] = element.jsValue()
95177
}
96178
return .object(array)
97179
}
98180
}
99181

182+
extension Array: JSValueConstructible where Element: JSValueConstructible {
183+
public static func construct(from value: JSValue) -> [Element]? {
184+
if let objectRef = value.object,
185+
objectRef.isInstanceOf(JSObject.global.Array.function!) {
186+
let count: Int = objectRef.length.fromJSValue()!
187+
var array = [Element]()
188+
array.reserveCapacity(count)
189+
190+
for i in 0 ..< count {
191+
guard let value: Element = objectRef[i].fromJSValue() else { return nil }
192+
array.append(value)
193+
}
194+
195+
return array
196+
}
197+
return nil
198+
}
199+
}
200+
100201
extension RawJSValue: JSValueConvertible {
101202
public func jsValue() -> JSValue {
102203
switch kind {
@@ -192,6 +293,6 @@ extension Array where Element == JSValueConvertible {
192293

193294
extension Array where Element: JSValueConvertible {
194295
func withRawJSValues<T>(_ body: ([RawJSValue]) -> T) -> T {
195-
Swift.Array<JSValueConvertible>.withRawJSValues(self)(body)
296+
Array<JSValueConvertible>.withRawJSValues(self)(body)
196297
}
197298
}

0 commit comments

Comments
 (0)