Skip to content

Clean up use of closure property wrappers #59

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions Sources/WebIDLToSwift/ClosurePattern.swift
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -121,6 +121,7 @@ struct ClosurePattern: SwiftRepresentable, Equatable, Hashable, Comparable {
"""
}


var toJSValue: SwiftSource {
let escaping: SwiftSource = nullable ? "" : "@escaping"
return """
Expand All @@ -132,7 +133,6 @@ struct ClosurePattern: SwiftRepresentable, Equatable, Hashable, Comparable {

var swiftRepresentation: SwiftSource {
"""
\(propertyWrapper)
\(toJSValue)
"""
}
Expand Down
5 changes: 2 additions & 3 deletions Sources/WebIDLToSwift/IDLBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 = """
Expand Down Expand Up @@ -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))
"""
}
Expand Down
3 changes: 0 additions & 3 deletions Sources/WebIDLToSwift/MergeDeclarations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> = ["WorkerNavigator"]
static let validExposures: Set<String> = ["Window"]
Expand Down
21 changes: 18 additions & 3 deletions Sources/WebIDLToSwift/WebIDL+SwiftRepresentation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)"
Expand All @@ -23,7 +23,7 @@ extension IDLArgument: SwiftRepresentable {
}
}

extension IDLAttribute: SwiftRepresentable, Initializable {
extension IDLAttribute: SwiftRepresentable {
private var wrapperName: SwiftSource {
"_\(raw: name)"
}
Expand Down Expand Up @@ -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 """
Expand All @@ -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
""" :
""
)

"""
}

Expand Down Expand Up @@ -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 """
Expand Down
Loading