diff --git a/Sources/WebIDLToSwift/ClosurePattern.swift b/Sources/WebIDLToSwift/ClosurePattern.swift index d06c2d9f..e6e93d94 100644 --- a/Sources/WebIDLToSwift/ClosurePattern.swift +++ b/Sources/WebIDLToSwift/ClosurePattern.swift @@ -1,6 +1,6 @@ struct ClosurePattern: SwiftRepresentable, Equatable, Hashable, Comparable { static func < (lhs: ClosurePattern, rhs: ClosurePattern) -> Bool { - lhs.name.source < rhs.name.source + lhs.closureType.source < rhs.closureType.source } let nullable: Bool @@ -22,16 +22,16 @@ struct ClosurePattern: SwiftRepresentable, Equatable, Hashable, Comparable { return nullable ? "(\(closure))?" : closure } - private var getter: SwiftSource { + func getter(name: SwiftSource) -> SwiftSource { let getFunction: SwiftSource if nullable { getFunction = """ - guard let function = jsObject[name].function else { + guard let function = jsObject[\(name)].function else { return nil } """ } else { - getFunction = "let function = jsObject[name].function!" + getFunction = "let function = jsObject[\(name)].function!" } let call: SwiftSource = "function(\(sequence: indexes.map { "_toJSValue($\($0))" }))" let closureBody: SwiftSource @@ -66,15 +66,15 @@ struct ClosurePattern: SwiftRepresentable, Equatable, Hashable, Comparable { """ } - private var setter: SwiftSource { - let setClosure: SwiftSource = "jsObject[name] = \(jsClosureWrapper(name: "newValue"))" + func setter(name: SwiftSource) -> SwiftSource { + let setClosure: SwiftSource = "jsObject[\(name)] = \(jsClosureWrapper(name: "newValue"))" if nullable { return """ if let newValue = newValue { \(setClosure) } else { - jsObject[name] = .null + jsObject[\(name)] = .null } """ } else { @@ -121,6 +121,7 @@ struct ClosurePattern: SwiftRepresentable, Equatable, Hashable, Comparable { """ } + var toJSValue: SwiftSource { let escaping: SwiftSource = nullable ? "" : "@escaping" return """ @@ -132,7 +133,6 @@ struct ClosurePattern: SwiftRepresentable, Equatable, Hashable, Comparable { var swiftRepresentation: SwiftSource { """ - \(propertyWrapper) \(toJSValue) """ } diff --git a/Sources/WebIDLToSwift/IDLBuilder.swift b/Sources/WebIDLToSwift/IDLBuilder.swift index 21429dbb..9cb8ac64 100644 --- a/Sources/WebIDLToSwift/IDLBuilder.swift +++ b/Sources/WebIDLToSwift/IDLBuilder.swift @@ -2,7 +2,7 @@ import Foundation import WebIDL enum IDLBuilder { - static let basicDependencies = ["ECMAScript", "JavaScriptKit", "JavaScriptEventLoop"] + static let basicDependencies = ["ECMAScript", "JavaScriptKit"] static let optionalDependencies = ["JavaScriptEventLoop"] static let preamble = """ @@ -95,9 +95,8 @@ enum IDLBuilder { } static func generateClosureTypes() throws -> SwiftSource { - print("Generating closure property wrappers...") + print("Generating closure wrappers...") return """ - /* variadic generics please */ \(lines: ModuleState.closurePatterns.sorted().map(\.swiftRepresentation)) """ } diff --git a/Sources/WebIDLToSwift/MergeDeclarations.swift b/Sources/WebIDLToSwift/MergeDeclarations.swift index 5b042cbe..48b7b2d9 100644 --- a/Sources/WebIDLToSwift/MergeDeclarations.swift +++ b/Sources/WebIDLToSwift/MergeDeclarations.swift @@ -7,9 +7,6 @@ enum DeclarationMerger { "CustomElementConstructor", "ArrayBufferView", "RotationMatrixType", - // Mapped to `Int32` manually. This can't be represented as `Int64` due to `BigInt` representation on JS side, - // but as a pointer it can't be represented as floating point number either. - "GLintptr", ] static let ignoredIncludeTargets: Set = ["WorkerNavigator"] static let validExposures: Set = ["Window"] diff --git a/Sources/WebIDLToSwift/WebIDL+SwiftRepresentation.swift b/Sources/WebIDLToSwift/WebIDL+SwiftRepresentation.swift index c1a0b5dd..07ec10ed 100644 --- a/Sources/WebIDLToSwift/WebIDL+SwiftRepresentation.swift +++ b/Sources/WebIDLToSwift/WebIDL+SwiftRepresentation.swift @@ -5,7 +5,7 @@ extension IDLArgument: SwiftRepresentable { let type: SwiftSource if variadic { type = "\(idlType)..." - } else if idlType.isFunction, !optional, !idlType.nullable { + } else if idlType.closurePattern != nil && !optional && !idlType.nullable { type = "@escaping \(idlType)" } else { type = "\(idlType)" @@ -23,7 +23,7 @@ extension IDLArgument: SwiftRepresentable { } } -extension IDLAttribute: SwiftRepresentable, Initializable { +extension IDLAttribute: SwiftRepresentable { private var wrapperName: SwiftSource { "_\(raw: name)" } @@ -247,12 +247,16 @@ extension MergedInterface: SwiftRepresentable { ] let access: SwiftSource = openClasses.contains(name) ? "open" : "public" + let hasAsyncSequence: Bool let header: SwiftSource if partial { header = "public extension \(name)" + hasAsyncSequence = false } else { let inheritance = (parentClasses.isEmpty ? ["JSBridgedClass"] : parentClasses) + mixins + .filter { $0 != "AsyncSequence" } header = "\(access) class \(name): \(sequence: inheritance.map(SwiftSource.init(_:)))" + hasAsyncSequence = mixins.contains { $0 == "AsyncSequence" } } return """ @@ -269,13 +273,22 @@ extension MergedInterface: SwiftRepresentable { """ : "") public required init(unsafelyWrapping jsObject: JSObject) { - \(memberInits.joined(separator: "\n")) \(parentClasses.isEmpty ? "self.jsObject = jsObject" : "super.init(unsafelyWrapping: jsObject)") } """) \(body) } + + \(hasAsyncSequence ? + """ + #if canImport(JavaScriptEventLoop) + public extension \(name): AsyncSequence {} + #endif + """ : + "" + ) + """ } @@ -380,11 +393,13 @@ extension IDLIterableDeclaration: SwiftRepresentable, Initializable { var swiftRepresentation: SwiftSource { if async { return """ + #if canImport(JavaScriptEventLoop) public typealias Element = \(idlType[0]) @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) public func makeAsyncIterator() -> ValueIterableAsyncIterator<\(ModuleState.className)> { ValueIterableAsyncIterator(sequence: self) } + #endif """ } else { return """