Skip to content

Commit 6053186

Browse files
Support Dictionary and Array conversion
1 parent 29773ec commit 6053186

File tree

5 files changed

+74
-14
lines changed

5 files changed

+74
-14
lines changed

src/swift/Sources/JavaScriptKit/JSFunction.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@ public class JSFunctionRef: Equatable {
3030
}
3131

3232
public func apply(this: JSObjectRef, arguments: JSValueConvertible...) -> JSValue {
33-
let result = arguments.withRawJSValues { rawValues in
33+
apply(this: this, argumentList: arguments)
34+
}
35+
public func apply(this: JSObjectRef, argumentList: [JSValueConvertible]) -> JSValue {
36+
let result = argumentList.withRawJSValues { rawValues in
3437
rawValues.withUnsafeBufferPointer { bufferPointer -> RawJSValue in
3538
let argv = bufferPointer.baseAddress
3639
let argc = bufferPointer.count

src/swift/Sources/JavaScriptKit/JSObject.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@ public class JSObjectRef: Equatable {
77
self.id = id
88
}
99

10-
public subscript(dynamicMember name: String) -> JSFunctionRef? {
11-
get { self[dynamicMember: name].function }
10+
public subscript(dynamicMember name: String) -> ((JSValueConvertible...) -> JSValue)? {
11+
get {
12+
guard let function = self[dynamicMember: name].function else { return nil }
13+
return { (arguments: JSValueConvertible...) in
14+
function.apply(this: self, argumentList: arguments)
15+
}
16+
}
1217
}
1318

1419
public subscript(dynamicMember name: String) -> JSValue {

src/swift/Sources/JavaScriptKit/JSValue.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,34 @@ public enum JSValue: Equatable {
99
case undefined
1010
case function(JSFunctionRef)
1111

12-
var boolean: Bool? {
12+
public var boolean: Bool? {
1313
switch self {
1414
case let .boolean(boolean): return boolean
1515
default: return nil
1616
}
1717
}
1818

19-
var string: String? {
19+
public var string: String? {
2020
switch self {
2121
case let .string(string): return string
2222
default: return nil
2323
}
2424
}
25-
var number: Int32? {
25+
public var number: Int32? {
2626
switch self {
2727
case let .number(number): return number
2828
default: return nil
2929
}
3030
}
31-
var object: JSObjectRef? {
31+
public var object: JSObjectRef? {
3232
switch self {
3333
case let .object(object): return object
3434
default: return nil
3535
}
3636
}
37-
var isNull: Bool { return self == .null }
38-
var isUndefined: Bool { return self == .undefined }
39-
var function: JSFunctionRef? {
37+
public var isNull: Bool { return self == .null }
38+
public var isUndefined: Bool { return self == .undefined }
39+
public var function: JSFunctionRef? {
4040
switch self {
4141
case let .function(function): return function
4242
default: return nil

src/swift/Sources/JavaScriptKit/JSValueConvertible.swift

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,23 @@ extension String: JSValueConvertible {
2020
public func jsValue() -> JSValue { .string(self) }
2121
}
2222

23+
extension JSObjectRef: JSValueConvertible {
24+
public func jsValue() -> JSValue { .object(self) }
25+
}
26+
27+
extension JSFunctionRef: JSValueConvertible {
28+
public func jsValue() -> JSValue { .function(self) }
29+
}
30+
2331
private let Object = JSObjectRef.global().Object.function!
2432

25-
extension Dictionary: JSValueConvertible where Value: JSValueConvertible, Key == String {
33+
extension Dictionary where Value: JSValueConvertible, Key == String {
34+
public func jsValue() -> JSValue {
35+
Swift.Dictionary<Key, JSValueConvertible>.jsValue(self)()
36+
}
37+
}
38+
39+
extension Dictionary: JSValueConvertible where Value == JSValueConvertible, Key == String {
2640
public func jsValue() -> JSValue {
2741
let object = Object.new()
2842
for (key, value) in self {
@@ -34,11 +48,17 @@ extension Dictionary: JSValueConvertible where Value: JSValueConvertible, Key ==
3448

3549
private let Array = JSObjectRef.global().Array.function!
3650

37-
extension Array: JSValueConvertible where Element: JSValueConvertible {
51+
extension Array where Element: JSValueConvertible {
52+
public func jsValue() -> JSValue {
53+
Swift.Array<JSValueConvertible>.jsValue(self)()
54+
}
55+
}
56+
57+
extension Array: JSValueConvertible where Element == JSValueConvertible {
3858
public func jsValue() -> JSValue {
3959
let array = Array.new(count)
40-
for element in self {
41-
array.push!(element)
60+
for (index, element) in self.enumerated() {
61+
array[index] = element.jsValue()
4262
}
4363
return .object(array)
4464
}

test/JavaScriptKitExec/Sources/JavaScriptKitExec/main.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,35 @@ Call_Function_With_This: do {
212212
} catch {
213213
print(error)
214214
}
215+
216+
Object_Conversion: do {
217+
let array1 = [1, 2, 3]
218+
let jsArray1 = array1.jsValue().object!
219+
try expectEqual(jsArray1.length, .number(3))
220+
try expectEqual(jsArray1[0], .number(1))
221+
try expectEqual(jsArray1[1], .number(2))
222+
try expectEqual(jsArray1[2], .number(3))
223+
224+
let array2: [JSValueConvertible] = [1, "str", false]
225+
let jsArray2 = array2.jsValue().object!
226+
try expectEqual(jsArray2.length, .number(3))
227+
try expectEqual(jsArray2[0], .number(1))
228+
try expectEqual(jsArray2[1], .string("str"))
229+
try expectEqual(jsArray2[2], .boolean(false))
230+
_ = jsArray2.push!(5)
231+
try expectEqual(jsArray2.length, .number(4))
232+
_ = jsArray2.push!(jsArray1)
233+
234+
// TODO: Object identity
235+
// try expectEqual(jsArray2[4], .object(jsArray1))
236+
237+
let dict1: [String: JSValueConvertible] = [
238+
"prop1": 1,
239+
"prop2": "foo",
240+
]
241+
let jsDict1 = dict1.jsValue().object!
242+
try expectEqual(jsDict1.prop1, .number(1))
243+
try expectEqual(jsDict1.prop2, .string("foo"))
244+
} catch {
245+
print(error)
246+
}

0 commit comments

Comments
 (0)