Skip to content

Commit 45ed26d

Browse files
authored
Bring code generation into this repo, update to latest specs, support async functions natively (#10)
I rebuilt the code generation using the official (JS-based) WebIDL parser. Taking inspiration from `webidl2swift`, this will hopefully improve on that package by not having to maintain the parser component. I also: - Added `async` versions of Promise-returning functions - Added enormous numbers of Web APIs that were previously not included - both existing and new APIs! The full list of included specs is in `IDLBuilder`, and it would be great to expand that. - Expanded support for wrapped closure properties (using code generation for now, until we get variadic generics) - Moved the code generation pipeline into this repo, to make it easier to make changes TODOs: - [x] Add back support for union types - This will probably happen by calculating the Cartesian product of all union-typed function parameters, to avoid unnecessary user-side ceremony - Union return types (if present) will still have to be enums, I think, though. - [x] Add back support for type-erased protocol types (`AnyParentNode`) - [ ] mark parameters as taking the protocol rather than the enum - [x] Rewrite dictionaries to not subclass `JSObject` because that is bad - [ ] Do something about the fact that JS can run in different contexts (e.g. window-side code vs the plethora of worker types) - [x] Implement iterators and async iterators properly - this requires upstream changes to JavaScriptKit that I will be tackling later to enable usage of Symbol keys - [ ] add support for readonly closure properties - [ ] re-evaluate entries in the `ignored` dictionary in `IDLBuilder`, and make as many APIs as possible work (or manually re-implement them) - [ ] Add and error-check remaining web APIs - [ ] test with real code - [ ] configure GitHub Actions to periodically update the generated code
1 parent e45d37f commit 45ed26d

File tree

505 files changed

+20192
-4757
lines changed

Some content is hidden

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

505 files changed

+20192
-4757
lines changed

Diff for: .github/workflows/test.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ on:
77

88
jobs:
99
macos_test:
10-
runs-on: macos-11.0
10+
runs-on: macos-12
1111

1212
steps:
1313
- uses: actions/checkout@v2
1414
- name: Run the test suite on macOS
1515
shell: bash
1616
run: |
1717
set -ex
18-
sudo xcode-select --switch /Applications/Xcode_12.3.app/Contents/Developer/
18+
sudo xcode-select --switch /Applications/Xcode_13.3.1.app/Contents/Developer/
1919
2020
brew install swiftwasm/tap/carton
2121

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
/Packages
44
/*.xcodeproj
55
xcuserdata/
6+
node_modules

Diff for: Package.resolved

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
"package": "JavaScriptKit",
66
"repositoryURL": "https://github.com/swiftwasm/JavaScriptKit.git",
77
"state": {
8-
"branch": null,
9-
"revision": "b7a02434c6e973c08c3fd5069105ef44dd82b891",
10-
"version": "0.9.0"
8+
"branch": "main",
9+
"revision": "95d0c4cd78b48ffc7e19c618d57c3244917be09a",
10+
"version": null
1111
}
1212
}
1313
]

Diff for: Package.swift

+9-5
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,25 @@ let package = Package(
1212
.library(
1313
name: "DOMKit",
1414
targets: ["DOMKit"]),
15+
.library(name: "WebIDL", targets: ["WebIDL"]),
16+
.executable(name: "WebIDLToSwift", targets: ["WebIDLToSwift"]),
1517
],
1618
dependencies: [
1719
.package(
18-
name: "JavaScriptKit",
1920
url: "https://github.com/swiftwasm/JavaScriptKit.git",
20-
.upToNextMinor(from: "0.9.0")),
21+
.branch("main")),
2122
],
2223
targets: [
2324
.target(
2425
name: "DOMKitDemo",
25-
dependencies: ["DOMKit"]
26-
),
26+
dependencies: ["DOMKit"]),
2727
.target(
2828
name: "DOMKit",
29-
dependencies: ["JavaScriptKit"]),
29+
dependencies: ["JavaScriptKit", .product(name: "JavaScriptEventLoop", package: "JavaScriptKit")]),
30+
.target(name: "WebIDL"),
31+
.target(
32+
name: "WebIDLToSwift",
33+
dependencies: ["WebIDL"]),
3034
.testTarget(
3135
name: "DOMKitTests",
3236
dependencies: ["DOMKit"]),

Diff for: Sources/DOMKit/ECMAScript/ArrayBuffer.swift

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ public typealias Int32Array = JSTypedArray<Int32>
1111
public typealias Uint8Array = JSTypedArray<UInt8>
1212
public typealias Uint16Array = JSTypedArray<UInt16>
1313
public typealias Uint32Array = JSTypedArray<UInt32>
14-
//public typealias Uint8ClampedArray = JSTypedArray<Uint8Clamped>
1514
public typealias Float32Array = JSTypedArray<Float32>
1615
public typealias Float64Array = JSTypedArray<Float64>
1716

Diff for: Sources/DOMKit/ECMAScript/ArrayBufferView.swift

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// This file was auto-generated by WebIDLToSwift. DO NOT EDIT!
2+
3+
import JavaScriptEventLoop
4+
import JavaScriptKit
5+
6+
// TODO: expand this to BigInt arrays
7+
public protocol AnyArrayBufferView: ConvertibleToJSValue {}
8+
extension DataView: AnyArrayBufferView {}
9+
extension JSTypedArray: AnyArrayBufferView {}
10+
11+
public enum ArrayBufferView: JSValueCompatible, AnyArrayBufferView {
12+
case dataView(DataView)
13+
// case bigInt64Array(BigInt64Array)
14+
// case bigUint64Array(BigUint64Array)
15+
case float32Array(Float32Array)
16+
case float64Array(Float64Array)
17+
case int16Array(Int16Array)
18+
case int32Array(Int32Array)
19+
case int8Array(Int8Array)
20+
case uint16Array(Uint16Array)
21+
case uint32Array(Uint32Array)
22+
case uint8Array(Uint8Array)
23+
case uint8ClampedArray(Uint8ClampedArray)
24+
25+
public static func construct(from value: JSValue) -> Self? {
26+
// if let bigInt64Array: BigInt64Array = value.fromJSValue() {
27+
// return .bigInt64Array(bigInt64Array)
28+
// }
29+
// if let bigUint64Array: BigUint64Array = value.fromJSValue() {
30+
// return .bigUint64Array(bigUint64Array)
31+
// }
32+
if let dataView: DataView = value.fromJSValue() {
33+
return .dataView(dataView)
34+
}
35+
if let float32Array: Float32Array = value.fromJSValue() {
36+
return .float32Array(float32Array)
37+
}
38+
if let float64Array: Float64Array = value.fromJSValue() {
39+
return .float64Array(float64Array)
40+
}
41+
if let int16Array: Int16Array = value.fromJSValue() {
42+
return .int16Array(int16Array)
43+
}
44+
if let int32Array: Int32Array = value.fromJSValue() {
45+
return .int32Array(int32Array)
46+
}
47+
if let int8Array: Int8Array = value.fromJSValue() {
48+
return .int8Array(int8Array)
49+
}
50+
if let uint16Array: Uint16Array = value.fromJSValue() {
51+
return .uint16Array(uint16Array)
52+
}
53+
if let uint32Array: Uint32Array = value.fromJSValue() {
54+
return .uint32Array(uint32Array)
55+
}
56+
if let uint8Array: Uint8Array = value.fromJSValue() {
57+
return .uint8Array(uint8Array)
58+
}
59+
if let uint8ClampedArray: Uint8ClampedArray = value.fromJSValue() {
60+
return .uint8ClampedArray(uint8ClampedArray)
61+
}
62+
return nil
63+
}
64+
65+
public var jsValue: JSValue {
66+
switch self {
67+
// case let .bigInt64Array(bigInt64Array):
68+
// return bigInt64Array.jsValue
69+
// case let .bigUint64Array(bigUint64Array):
70+
// return bigUint64Array.jsValue
71+
case let .dataView(dataView):
72+
return dataView.jsValue
73+
case let .float32Array(float32Array):
74+
return float32Array.jsValue
75+
case let .float64Array(float64Array):
76+
return float64Array.jsValue
77+
case let .int16Array(int16Array):
78+
return int16Array.jsValue
79+
case let .int32Array(int32Array):
80+
return int32Array.jsValue
81+
case let .int8Array(int8Array):
82+
return int8Array.jsValue
83+
case let .uint16Array(uint16Array):
84+
return uint16Array.jsValue
85+
case let .uint32Array(uint32Array):
86+
return uint32Array.jsValue
87+
case let .uint8Array(uint8Array):
88+
return uint8Array.jsValue
89+
case let .uint8ClampedArray(uint8ClampedArray):
90+
return uint8ClampedArray.jsValue
91+
}
92+
}
93+
}

Diff for: Sources/DOMKit/ECMAScript/Attributes.swift

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import JavaScriptKit
2+
3+
@propertyWrapper public struct ReadWriteAttribute<Wrapped: JSValueCompatible> {
4+
@usableFromInline let jsObject: JSObject
5+
@usableFromInline let name: JSString
6+
7+
public init(jsObject: JSObject, name: JSString) {
8+
self.jsObject = jsObject
9+
self.name = name
10+
}
11+
12+
@inlinable public var wrappedValue: Wrapped {
13+
get { ReadWriteAttribute[name, in: jsObject] }
14+
nonmutating set { ReadWriteAttribute[name, in: jsObject] = newValue }
15+
}
16+
17+
@inlinable public static subscript(name: JSString, in jsObject: JSObject) -> Wrapped {
18+
get { jsObject[name].fromJSValue()! }
19+
set { jsObject[name] = newValue.jsValue }
20+
}
21+
}
22+
23+
@propertyWrapper public struct ReadonlyAttribute<Wrapped: ConstructibleFromJSValue> {
24+
@usableFromInline let jsObject: JSObject
25+
@usableFromInline let name: JSString
26+
27+
public init(jsObject: JSObject, name: JSString) {
28+
self.jsObject = jsObject
29+
self.name = name
30+
}
31+
32+
@inlinable public var wrappedValue: Wrapped {
33+
ReadonlyAttribute[name, in: jsObject]
34+
}
35+
36+
@inlinable public static subscript(name: JSString, in jsObject: JSObject) -> Wrapped {
37+
jsObject[name].fromJSValue()!
38+
}
39+
}

Diff for: Sources/DOMKit/ECMAScript/BridgedDictionary.swift

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import JavaScriptKit
2+
3+
public class BridgedDictionary: JSValueCompatible {
4+
public let jsObject: JSObject
5+
6+
public var jsValue: JSValue {
7+
jsObject.jsValue
8+
}
9+
10+
public required init(unsafelyWrapping jsObject: JSObject) {
11+
self.jsObject = jsObject
12+
}
13+
14+
public static func construct(from value: JSValue) -> Self? {
15+
if let object = value.object {
16+
return Self.construct(from: object)
17+
}
18+
return nil
19+
}
20+
21+
public static func construct(from object: JSObject) -> Self? {
22+
Self(unsafelyWrapping: object)
23+
}
24+
}

Diff for: Sources/DOMKit/ECMAScript/CanvasImageSource.swift

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// This file was auto-generated by WebIDLToSwift. DO NOT EDIT!
2+
3+
import JavaScriptEventLoop
4+
import JavaScriptKit
5+
6+
public protocol Any_CanvasImageSource: ConvertibleToJSValue {}
7+
extension HTMLCanvasElement: Any_CanvasImageSource {}
8+
extension HTMLOrSVGImageElement: Any_CanvasImageSource {}
9+
extension HTMLVideoElement: Any_CanvasImageSource {}
10+
extension ImageBitmap: Any_CanvasImageSource {}
11+
extension OffscreenCanvas: Any_CanvasImageSource {}
12+
//extension VideoFrame: Any_CanvasImageSource {}
13+
14+
public enum CanvasImageSource: JSValueCompatible, Any_CanvasImageSource {
15+
case htmlCanvasElement(HTMLCanvasElement)
16+
case htmlOrSVGImageElement(HTMLOrSVGImageElement)
17+
case htmlVideoElement(HTMLVideoElement)
18+
case imageBitmap(ImageBitmap)
19+
case offscreenCanvas(OffscreenCanvas)
20+
// case videoFrame(VideoFrame)
21+
22+
var htmlCanvasElement: HTMLCanvasElement? {
23+
switch self {
24+
case let .htmlCanvasElement(htmlCanvasElement): return htmlCanvasElement
25+
default: return nil
26+
}
27+
}
28+
29+
var htmlOrSVGImageElement: HTMLOrSVGImageElement? {
30+
switch self {
31+
case let .htmlOrSVGImageElement(htmlOrSVGImageElement): return htmlOrSVGImageElement
32+
default: return nil
33+
}
34+
}
35+
36+
var htmlVideoElement: HTMLVideoElement? {
37+
switch self {
38+
case let .htmlVideoElement(htmlVideoElement): return htmlVideoElement
39+
default: return nil
40+
}
41+
}
42+
43+
var imageBitmap: ImageBitmap? {
44+
switch self {
45+
case let .imageBitmap(imageBitmap): return imageBitmap
46+
default: return nil
47+
}
48+
}
49+
50+
var offscreenCanvas: OffscreenCanvas? {
51+
switch self {
52+
case let .offscreenCanvas(offscreenCanvas): return offscreenCanvas
53+
default: return nil
54+
}
55+
}
56+
57+
// var videoFrame: VideoFrame? {
58+
// switch self {
59+
// case let .videoFrame(videoFrame): return videoFrame
60+
// default: return nil
61+
// }
62+
// }
63+
64+
public static func construct(from value: JSValue) -> Self? {
65+
if let htmlCanvasElement: HTMLCanvasElement = value.fromJSValue() {
66+
return .htmlCanvasElement(htmlCanvasElement)
67+
}
68+
if let htmlOrSVGImageElement: HTMLOrSVGImageElement = value.fromJSValue() {
69+
return .htmlOrSVGImageElement(htmlOrSVGImageElement)
70+
}
71+
if let htmlVideoElement: HTMLVideoElement = value.fromJSValue() {
72+
return .htmlVideoElement(htmlVideoElement)
73+
}
74+
if let imageBitmap: ImageBitmap = value.fromJSValue() {
75+
return .imageBitmap(imageBitmap)
76+
}
77+
if let offscreenCanvas: OffscreenCanvas = value.fromJSValue() {
78+
return .offscreenCanvas(offscreenCanvas)
79+
}
80+
// if let videoFrame: VideoFrame = value.fromJSValue() {
81+
// return .videoFrame(videoFrame)
82+
// }
83+
return nil
84+
}
85+
86+
public var jsValue: JSValue {
87+
switch self {
88+
case let .htmlCanvasElement(htmlCanvasElement):
89+
return htmlCanvasElement.jsValue
90+
case let .htmlOrSVGImageElement(htmlOrSVGImageElement):
91+
return htmlOrSVGImageElement.jsValue
92+
case let .htmlVideoElement(htmlVideoElement):
93+
return htmlVideoElement.jsValue
94+
case let .imageBitmap(imageBitmap):
95+
return imageBitmap.jsValue
96+
case let .offscreenCanvas(offscreenCanvas):
97+
return offscreenCanvas.jsValue
98+
// case let .videoFrame(videoFrame):
99+
// return videoFrame.jsValue
100+
}
101+
}
102+
}

0 commit comments

Comments
 (0)