Skip to content

Commit e75ecbf

Browse files
committed
Move WebIDL generated bindings
1 parent ccbaa0a commit e75ecbf

File tree

128 files changed

+323
-6
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

128 files changed

+323
-6
lines changed

Package.resolved

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ let package = Package(
1111
targets: ["DOMKit"]),
1212
],
1313
dependencies: [
14-
.package(url: "https://github.com/kateinoigakukun/JavaScriptKit.git", .revision("c90e82f")),
14+
.package(name: "JavaScriptKit", url: "https://github.com/j-f1/forked-JavaScriptKit.git", .revision("663c091")),
1515
],
1616
targets: [
1717
.target(
Lines changed: 317 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,317 @@
1+
//
2+
// JSValueConvertible.swift
3+
// DOMKit
4+
//
5+
// Created by Jed Fox on 8/1/20.
6+
//
7+
8+
import JavaScriptKit
9+
10+
public protocol JSBridgedType: JSValueCodable, CustomStringConvertible {
11+
var objectRef: JSObjectRef { get }
12+
init(objectRef: JSObjectRef)
13+
}
14+
15+
public protocol JSValueEncodable {
16+
func jsValue() -> JSValue
17+
}
18+
19+
public protocol JSValueDecodable {
20+
init(jsValue: JSValue)
21+
22+
static func canDecode(from jsValue: JSValue) -> Bool
23+
}
24+
25+
extension JSBridgedType {
26+
27+
public var description: String {
28+
return objectRef.toString!().fromJSValue()
29+
}
30+
}
31+
32+
public typealias JSValueCodable = JSValueEncodable & JSValueDecodable
33+
34+
extension JSBridgedType {
35+
36+
public static func canDecode(from jsValue: JSValue) -> Bool {
37+
jsValue.object != nil // && jsValue.instanceOf(String(describing: Self.self))
38+
}
39+
40+
public init(jsValue: JSValue) {
41+
42+
self.init(objectRef: jsValue.object!)
43+
}
44+
45+
public func jsValue() -> JSValue {
46+
return JSValue.object(objectRef)
47+
}
48+
}
49+
50+
extension JSValue: JSValueCodable {
51+
52+
public static func canDecode(from: JSValue) -> Bool {
53+
return true
54+
}
55+
56+
public init(jsValue: JSValue) {
57+
self = jsValue
58+
}
59+
60+
public func jsValue() -> JSValue { self }
61+
}
62+
63+
extension Bool: JSValueCodable {
64+
65+
public static func canDecode(from jsValue: JSValue) -> Bool {
66+
return jsValue.isBoolean
67+
}
68+
69+
public init(jsValue: JSValue) {
70+
switch jsValue {
71+
case .boolean(let value):
72+
self = value
73+
default:
74+
fatalError("JSValue \(jsValue) is not decodable to Bool")
75+
}
76+
}
77+
78+
public func jsValue() -> JSValue { .boolean(self) }
79+
}
80+
81+
extension Int: JSValueCodable {
82+
83+
public static func canDecode(from jsValue: JSValue) -> Bool {
84+
return jsValue.isNumber
85+
}
86+
87+
public init(jsValue: JSValue) {
88+
switch jsValue {
89+
case .number(let value):
90+
self = Int(value)
91+
default:
92+
fatalError()
93+
}
94+
}
95+
96+
public func jsValue() -> JSValue { .number(Double(self)) }
97+
}
98+
99+
extension Double: JSValueCodable {
100+
101+
public static func canDecode(from jsValue: JSValue) -> Bool {
102+
return jsValue.isNumber
103+
}
104+
105+
public init(jsValue: JSValue) {
106+
switch jsValue {
107+
case .number(let value):
108+
self = value
109+
default:
110+
fatalError()
111+
}
112+
}
113+
114+
public func jsValue() -> JSValue { .number(self) }
115+
}
116+
117+
extension String: JSValueCodable {
118+
119+
public static func canDecode(from jsValue: JSValue) -> Bool {
120+
return jsValue.isString
121+
}
122+
123+
public init(jsValue: JSValue) {
124+
switch jsValue {
125+
case .string(let value):
126+
self = value
127+
default:
128+
fatalError()
129+
}
130+
}
131+
132+
public func jsValue() -> JSValue { .string(self) }
133+
}
134+
135+
private let Object = JSObjectRef.global.Object.function!
136+
137+
extension Dictionary: JSValueEncodable where Value: JSValueEncodable, Key == String {
138+
139+
public func jsValue() -> JSValue {
140+
let object = Object.new()
141+
for (key, value) in self {
142+
object.js_set(key, value.jsValue())
143+
}
144+
return .object(object)
145+
}
146+
}
147+
148+
extension Dictionary: JSValueDecodable where Value: JSValueDecodable, Key == String {
149+
150+
public static func canDecode(from jsValue: JSValue) -> Bool {
151+
return jsValue.isObject
152+
}
153+
154+
public init(jsValue: JSValue) {
155+
156+
let objectRef: JSObjectRef = jsValue.object!
157+
158+
let keys: [String] = Object.keys!(objectRef.jsValue()).fromJSValue()
159+
self = Dictionary(uniqueKeysWithValues: keys.map({
160+
return ($0, objectRef[dynamicMember: $0].fromJSValue())
161+
}))
162+
}
163+
}
164+
165+
extension Optional: JSValueDecodable where Wrapped: JSValueDecodable {
166+
167+
public static func canDecode(from jsValue: JSValue) -> Bool {
168+
return jsValue.isNull || Wrapped.canDecode(from: jsValue)
169+
}
170+
171+
public init(jsValue: JSValue) {
172+
switch jsValue {
173+
case .null:
174+
self = .none
175+
default:
176+
self = Wrapped(jsValue: jsValue)
177+
}
178+
}
179+
}
180+
181+
extension Optional: JSValueEncodable where Wrapped: JSValueEncodable {
182+
183+
public func jsValue() -> JSValue {
184+
switch self {
185+
case .none: return .null
186+
case .some(let wrapped): return wrapped.jsValue()
187+
}
188+
}
189+
}
190+
191+
private let JSArray = JSObjectRef.global.Array.function!
192+
193+
extension Array: JSValueEncodable where Element: JSValueEncodable {
194+
195+
196+
public func jsValue() -> JSValue {
197+
let array = JSArray.new(count)
198+
for (index, element) in self.enumerated() {
199+
array[index] = element.jsValue()
200+
}
201+
return .object(array)
202+
}
203+
}
204+
205+
extension Array: JSValueDecodable where Element: JSValueDecodable {
206+
207+
public static func canDecode(from jsValue: JSValue) -> Bool {
208+
return jsValue.isObject
209+
}
210+
211+
public init(jsValue: JSValue) {
212+
213+
let objectRef: JSObjectRef = jsValue.object!
214+
let count: Int = objectRef.length.fromJSValue()
215+
216+
self = (0 ..< count).map {
217+
return objectRef[$0].fromJSValue()
218+
}
219+
}
220+
}
221+
222+
extension RawJSValue: JSValueEncodable {
223+
224+
public func jsValue() -> JSValue {
225+
switch kind {
226+
case JavaScriptValueKind_Invalid:
227+
fatalError()
228+
case JavaScriptValueKind_Boolean:
229+
return .boolean(payload1 != 0)
230+
case JavaScriptValueKind_Number:
231+
return .number(Double(bitPattern: UInt64(payload1) | (UInt64(payload2) << 32)))
232+
case JavaScriptValueKind_String:
233+
// +1 for null terminator
234+
let buffer = malloc(Int(payload2 + 1))!.assumingMemoryBound(to: UInt8.self)
235+
defer { free(buffer) }
236+
_load_string(payload1 as JavaScriptObjectRef, buffer)
237+
buffer[Int(payload2)] = 0
238+
let string = String(decodingCString: UnsafePointer(buffer), as: UTF8.self)
239+
return .string(string)
240+
case JavaScriptValueKind_Object:
241+
return .object(JSObjectRef(id: payload1))
242+
case JavaScriptValueKind_Null:
243+
return .null
244+
case JavaScriptValueKind_Undefined:
245+
return .undefined
246+
case JavaScriptValueKind_Function:
247+
return .function(JSFunctionRef(id: payload1))
248+
default:
249+
fatalError("unreachable")
250+
}
251+
}
252+
}
253+
254+
extension JSValue {
255+
func withRawJSValue<T>(_ body: (inout RawJSValue) -> T) -> T {
256+
let kind: JavaScriptValueKind
257+
let payload1: JavaScriptPayload
258+
let payload2: JavaScriptPayload
259+
switch self {
260+
case let .boolean(boolValue):
261+
kind = JavaScriptValueKind_Boolean
262+
payload1 = boolValue ? 1 : 0
263+
payload2 = 0
264+
case let .number(numberValue):
265+
kind = JavaScriptValueKind_Number
266+
payload1 = UInt32(numberValue.bitPattern & 0x00000000ffffffff)
267+
payload2 = UInt32((numberValue.bitPattern & 0xffffffff00000000) >> 32)
268+
case var .string(stringValue):
269+
kind = JavaScriptValueKind_String
270+
return stringValue.withUTF8 { bufferPtr in
271+
let ptrValue = UInt32(UInt(bitPattern: bufferPtr.baseAddress!))
272+
var rawValue = RawJSValue(kind: kind, payload1: ptrValue, payload2: JavaScriptPayload(bufferPtr.count))
273+
return body(&rawValue)
274+
}
275+
case let .object(ref):
276+
kind = JavaScriptValueKind_Object
277+
payload1 = ref._id
278+
payload2 = 0
279+
case .null:
280+
kind = JavaScriptValueKind_Null
281+
payload1 = 0
282+
payload2 = 0
283+
case .undefined:
284+
kind = JavaScriptValueKind_Undefined
285+
payload1 = 0
286+
payload2 = 0
287+
case let .function(functionRef):
288+
kind = JavaScriptValueKind_Function
289+
payload1 = functionRef._id
290+
payload2 = 0
291+
}
292+
var rawValue = RawJSValue(kind: kind, payload1: payload1, payload2: payload2)
293+
return body(&rawValue)
294+
}
295+
}
296+
297+
extension Array where Element == JSValueEncodable {
298+
func withRawJSValues<T>(_ body: ([RawJSValue]) -> T) -> T {
299+
func _withRawJSValues<T>(
300+
_ values: [JSValueEncodable], _ index: Int,
301+
_ results: inout [RawJSValue], _ body: ([RawJSValue]) -> T) -> T {
302+
if index == values.count { return body(results) }
303+
return values[index].jsValue().withRawJSValue { (rawValue) -> T in
304+
results.append(rawValue)
305+
return _withRawJSValues(values, index + 1, &results, body)
306+
}
307+
}
308+
var _results = [RawJSValue]()
309+
return _withRawJSValues(self, 0, &_results, body)
310+
}
311+
}
312+
313+
extension Array where Element: JSValueEncodable {
314+
func withRawJSValues<T>(_ body: ([RawJSValue]) -> T) -> T {
315+
Swift.Array<JSValueEncodable>.withRawJSValues(self)(body)
316+
}
317+
}

0 commit comments

Comments
 (0)