Skip to content

Commit 0012028

Browse files
mjburghardj-f1
authored andcommitted
Changes related to WebIDL support.
1 parent 2465f84 commit 0012028

File tree

6 files changed

+511
-67
lines changed

6 files changed

+511
-67
lines changed

IntegrationTests/TestSuites/Sources/PrimaryTests/main.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -281,26 +281,26 @@ Call_Function_With_This: do {
281281
}
282282

283283
Object_Conversion: do {
284-
// let array1 = [1, 2, 3]
285-
// let jsArray1 = array1.jsValue().object!
286-
// try expectEqual(jsArray1.length, .number(3))
287-
// try expectEqual(jsArray1[0], .number(1))
288-
// try expectEqual(jsArray1[1], .number(2))
289-
// try expectEqual(jsArray1[2], .number(3))
290-
291-
let array2: [JSValueConvertible] = [1, "str", false]
284+
let array1 = [1, 2, 3]
285+
let jsArray1 = array1.jsValue().object!
286+
try expectEqual(jsArray1.length, .number(3))
287+
try expectEqual(jsArray1[0], .number(1))
288+
try expectEqual(jsArray1[1], .number(2))
289+
try expectEqual(jsArray1[2], .number(3))
290+
291+
let array2: [JSValueEncodable] = [1, "str", false]
292292
let jsArray2 = array2.jsValue().object!
293293
try expectEqual(jsArray2.length, .number(3))
294294
try expectEqual(jsArray2[0], .number(1))
295295
try expectEqual(jsArray2[1], .string("str"))
296296
try expectEqual(jsArray2[2], .boolean(false))
297297
_ = jsArray2.push!(5)
298298
try expectEqual(jsArray2.length, .number(4))
299-
// _ = jsArray2.push!(jsArray1)
299+
_ = jsArray2.push!(jsArray1)
300300

301-
// try expectEqual(jsArray2[4], .object(jsArray1))
301+
try expectEqual(jsArray2[4], .object(jsArray1))
302302

303-
let dict1: [String: JSValueConvertible] = [
303+
let dict1: [String: JSValueEncodable] = [
304304
"prop1": 1,
305305
"prop2": "foo",
306306
]

Sources/JavaScriptKit/JSFunction.swift

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import _CJavaScriptKit
22

33
public class JSFunctionRef: JSObjectRef {
44
@discardableResult
5-
func callAsFunction(this: JSObjectRef? = nil, args: [JSValueConvertible]) -> JSValue {
5+
func callAsFunction(this: JSObjectRef? = nil, args: [JSValueEncodable]) -> JSValue {
66
let result = args.withRawJSValues { rawValues in
77
rawValues.withUnsafeBufferPointer { bufferPointer -> RawJSValue in
88
let argv = bufferPointer.baseAddress
@@ -25,28 +25,25 @@ public class JSFunctionRef: JSObjectRef {
2525
}
2626

2727
@discardableResult
28-
public func callAsFunction(this: JSObjectRef? = nil, _ args: JSValueConvertible...) -> JSValue {
28+
public func callAsFunction(this: JSObjectRef? = nil, _ args: JSValueEncodable...) -> JSValue {
2929
self(this: this, args: args)
3030
}
3131

32-
public func new(_ args: JSValueConvertible...) -> JSObjectRef {
32+
public func new(_ args: JSValueEncodable...) -> JSObjectRef {
3333
new(args: args)
3434
}
3535

3636
// Guaranteed to return an object because either:
3737
// a) the constructor explicitly returns an object, or
3838
// b) the constructor returns nothing, which causes JS to return the `this` value, or
3939
// c) the constructor returns undefined, null or a non-object, in which case JS also returns `this`.
40-
public func new(args: [JSValueConvertible]) -> JSObjectRef {
40+
public func new(args: [JSValueEncodable]) -> JSObjectRef {
4141
args.withRawJSValues { rawValues in
4242
rawValues.withUnsafeBufferPointer { bufferPointer in
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 JSObjectRef(id: resultObj)
5148
}
5249
}
@@ -57,6 +54,19 @@ public class JSFunctionRef: JSObjectRef {
5754
fatalError("unavailable")
5855
}
5956

57+
override public class func canDecode(from jsValue: JSValue) -> Bool {
58+
return jsValue.isFunction
59+
}
60+
61+
public required convenience init(jsValue: JSValue) {
62+
switch jsValue {
63+
case let .function(value):
64+
self.init(id: value.id)
65+
default:
66+
fatalError()
67+
}
68+
}
69+
6070
override public func jsValue() -> JSValue {
6171
.function(self)
6272
}
@@ -80,6 +90,15 @@ public class JSClosure: JSFunctionRef {
8090
id = objectRef
8191
}
8292

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

Sources/JavaScriptKit/JSObject.swift

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ public class JSObjectRef: Equatable {
88
}
99

1010
@_disfavoredOverload
11-
public subscript(dynamicMember name: String) -> ((JSValueConvertible...) -> JSValue)? {
11+
public subscript(dynamicMember name: String) -> ((JSValueEncodable...) -> JSValue)? {
1212
guard let function = self[name].function else { return nil }
13-
return { (arguments: JSValueConvertible...) in
14-
function(this: self, arguments)
13+
return { (arguments: JSValueEncodable...) in
14+
function(this: self, args: arguments)
1515
}
1616
}
1717

@@ -43,7 +43,20 @@ public class JSObjectRef: Equatable {
4343
return lhs.id == rhs.id
4444
}
4545

46+
public required convenience init(jsValue: JSValue) {
47+
switch jsValue {
48+
case let .object(value):
49+
self.init(id: value.id)
50+
default:
51+
fatalError()
52+
}
53+
}
54+
4655
public func jsValue() -> JSValue {
4756
.object(self)
4857
}
58+
59+
public class func canDecode(from jsValue: JSValue) -> Bool {
60+
return jsValue.isObject
61+
}
4962
}

Sources/JavaScriptKit/JSValue.swift

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,51 @@ public enum JSValue: Equatable {
4141
object.flatMap { JSArrayRef($0) }
4242
}
4343

44-
public var isNull: Bool { return self == .null }
45-
public var isUndefined: Bool { return self == .undefined }
4644
public var function: JSFunctionRef? {
4745
switch self {
4846
case let .function(function): return function
4947
default: return nil
5048
}
5149
}
50+
51+
public var isBoolean: Bool {
52+
guard case .boolean = self else { return false }
53+
return true
54+
}
55+
56+
public var isString: Bool {
57+
guard case .string = self else { return false }
58+
return true
59+
}
60+
61+
public var isNumber: Bool {
62+
guard case .number = self else { return false }
63+
return true
64+
}
65+
66+
public var isObject: Bool {
67+
guard case .object = self else { return false }
68+
return true
69+
}
70+
71+
public var isNull: Bool {
72+
return self == .null
73+
}
74+
75+
public var isUndefined: Bool {
76+
return self == .undefined
77+
}
78+
79+
public var isFunction: Bool {
80+
guard case .function = self else { return false }
81+
return true
82+
}
83+
}
84+
85+
extension JSValue {
86+
public func fromJSValue<Type>() -> Type where Type: JSValueDecodable {
87+
return Type(jsValue: self)
88+
}
5289
}
5390

5491
extension JSValue {
@@ -64,7 +101,13 @@ extension JSValue: ExpressibleByStringLiteral {
64101
}
65102

66103
extension JSValue: ExpressibleByIntegerLiteral {
67-
public init(integerLiteral value: Double) {
104+
public init(integerLiteral value: Int32) {
105+
self = .number(Double(value))
106+
}
107+
}
108+
109+
extension JSValue: ExpressibleByFloatLiteral {
110+
public init(floatLiteral value: Double) {
68111
self = .number(value)
69112
}
70113
}
@@ -98,3 +141,18 @@ public func setJSValue(this: JSObjectRef, index: Int32, value: JSValue) {
98141
rawValue.payload1, rawValue.payload2, rawValue.payload3)
99142
}
100143
}
144+
145+
extension JSValue {
146+
public func isInstanceOf(_ constructor: JSFunctionRef) -> Bool {
147+
switch self {
148+
case .boolean, .string, .number:
149+
return false
150+
case let .object(ref):
151+
return ref.isInstanceOf(constructor)
152+
case let .function(ref):
153+
return ref.isInstanceOf(constructor)
154+
case .null, .undefined:
155+
fatalError()
156+
}
157+
}
158+
}

0 commit comments

Comments
 (0)