Skip to content

Commit a533f69

Browse files
committed
More fixes for compatibility with Embedded Swift.
The change improves compatibility with Embedded Swift. Specifically: 1. Cleans up accessors for properties to avoid use of property wrappers, which allows binary size to be slightly reduced. 2. Fixes dictionary-like types that previously had incorrect initializers not inheriting properties from superclasses.
1 parent de5d553 commit a533f69

File tree

2 files changed

+74
-39
lines changed

2 files changed

+74
-39
lines changed

Sources/WebIDLToSwift/WebIDL+SwiftRepresentation.swift

Lines changed: 66 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -71,59 +71,90 @@ extension IDLDictionary.Member {
7171
}
7272
}
7373

74-
extension MergedDictionary: SwiftRepresentable {
74+
extension IDLDictionary.Member: SwiftRepresentable {
7575
var swiftRepresentation: SwiftSource {
76-
"""
77-
public class \(name): BridgedDictionary {
78-
\(swiftInit)
79-
\(swiftMembers.joined(separator: "\n\n"))
76+
if ModuleState.override {
77+
assert(!ModuleState.static)
78+
return ""
79+
} else {
80+
let stringKey = ModuleState.source(for: name)
81+
let getter: SwiftSource
82+
let setter: SwiftSource
83+
84+
if let closure = idlType.closurePattern {
85+
getter = "get { \(closure.getter(name: stringKey)) }"
86+
setter = "set { \(closure.setter(name: stringKey)) }"
87+
} else {
88+
getter = "get { jsObject[\(stringKey)]\(idlType.fromJSValue) }"
89+
setter = "set { jsObject[\(stringKey)] = _toJSValue(newValue) }"
90+
}
91+
92+
return """
93+
@inlinable public\(raw: ModuleState.static ? " static" : "") var \(name): \(idlType) {
94+
\(getter)
95+
\(setter)
96+
}
97+
"""
8098
}
81-
"""
8299
}
100+
}
83101

84-
private func membersWithPropertyWrapper(_ members: [IDLDictionary.Member]) -> [(IDLDictionary.Member, SwiftSource)] {
85-
members.map {
86-
($0, $0.idlType.propertyWrapper(readonly: false))
87-
}
102+
extension MergedDictionary: SwiftRepresentable {
103+
var swiftRepresentation: SwiftSource {
104+
let inheritanceClause: SwiftSource =
105+
if self.inheritance.isEmpty {
106+
": JSDictionaryCompatible"
107+
} else {
108+
": \(self.inheritance.joined(separator: ", "))"
109+
}
110+
111+
return """
112+
open class \(name)\(inheritanceClause) {
113+
\(self.inheritance.isEmpty ? "public let jsObject: JSObject" : "")
114+
115+
\(swiftInit)
116+
117+
\(lines: self.members.map(\.swiftRepresentation))
118+
}
119+
"""
88120
}
89121

90-
private var swiftInit: SwiftSource {
91-
let params: [SwiftSource] = members.map {
92-
"\($0.name): \($0.idlType.isFunction ? "@escaping " : "")\($0.idlType)"
122+
private var convenienceInit: SwiftSource {
123+
let inheritedMembers: [IDLDictionary.Member] = self.inheritance.reduce(into: []) {
124+
// FIXME: if dictionary is not found in the current module, it's coming from a dependency,
125+
// but for now we have to skip it, since `ModuleState` doesn't seem to handle dependencies.
126+
return $0.append(contentsOf: ModuleState.dictionaries[$1]?.members ?? [])
127+
}
128+
129+
let params: [SwiftSource] = (inheritedMembers + members).map {
130+
let escaping = if let closurePattern = $0.idlType.closurePattern {
131+
closurePattern.nullable || $0.isOptional ? "" : "@escaping "
132+
} else { "" }
133+
return "\($0.name): \(escaping)\($0.idlType)\($0.isOptional ? "? = nil" : "")"
93134
}
135+
94136
return """
95137
public convenience init(\(sequence: params)) {
96138
let object = JSObject.global[\(ModuleState.source(for: "Object"))].function!.new()
97-
\(lines: membersWithPropertyWrapper(members).map { member, wrapper in
98-
if member.idlType.isFunction {
99-
return """
100-
\(wrapper)[\(ModuleState.source(for: member.name)), in: object] = \(member.name)
101-
"""
102-
} else {
139+
\(lines: (inheritedMembers + members).map { member in
103140
return """
104141
object[\(ModuleState.source(for: member.name))] = _toJSValue(\(member.name))
105142
"""
106-
}
107143
})
108-
self.init(unsafelyWrapping: object)
109-
}
110144
111-
public required init(unsafelyWrapping object: JSObject) {
112-
\(lines: membersWithPropertyWrapper(members).map { member, wrapper in
113-
"_\(raw: member.name) = \(wrapper)(jsObject: object, name: \(ModuleState.source(for: member.name)))"
114-
})
115-
super.init(unsafelyWrapping: object)
145+
self.init(unsafelyWrapping: object)
116146
}
117147
"""
118148
}
119149

120-
private var swiftMembers: [SwiftSource] {
121-
self.membersWithPropertyWrapper(members).map { member, wrapper in
122-
"""
123-
@\(wrapper)
124-
public var \(member.name): \(member.idlType)\(member.optionalSuffix)
150+
private var swiftInit: SwiftSource {
151+
return """
152+
\(self.convenienceInit)
153+
154+
public required init(unsafelyWrapping object: JSObject) {
155+
\(self.inheritance.isEmpty ? "self.jsObject = object" : "super.init(unsafelyWrapping: object)")
156+
}
125157
"""
126-
}
127158
}
128159
}
129160

@@ -765,8 +796,8 @@ extension IDLTypedef: SwiftRepresentable {
765796
unionType.friendlyName = name
766797
return ""
767798
}
768-
}
769-
return "public typealias \(name) = \(idlType)"
799+
} else if let type = Self.typeNameMap[name] { aliasedType = type } else { aliasedType = "\(idlType)" }
800+
return "public typealias \(name) = \(aliasedType)"
770801
}
771802
}
772803

Sources/WebIDLToSwift/WebIDLToSwift.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ enum WebIDLToSwift {
1111

1212
static func main() {
1313
do {
14-
let mode = parseArgs()
14+
let (mode, moduleNames) = parseArgs()
1515
let packageDir = URL(fileURLWithPath: #file)
1616
.deletingLastPathComponent()
1717
.deletingLastPathComponent()
@@ -22,6 +22,9 @@ enum WebIDLToSwift {
2222
// Collect closure patterns from all modules to subsequently write them together with `baseModule`.
2323
var closurePatterns = Set<ClosurePattern>()
2424

25+
let modules = if moduleNames.isEmpty { modules } else {
26+
modules.filter { moduleNames.contains($0.swiftModule) }
27+
}
2528
for module in modules {
2629
try generate(module, packageDir: packageDir, domTypes: domTypes, patch: mode != .noPatch)
2730
closurePatterns.formUnion(ModuleState.closurePatterns)
@@ -39,8 +42,9 @@ enum WebIDLToSwift {
3942
}
4043
}
4144

42-
private static func parseArgs() -> Mode? {
45+
private static func parseArgs() -> (Mode?, moduleNames: [String]) {
4346
var mode: Mode?
47+
var moduleNames = [String]()
4448
for arg in CommandLine.arguments.dropFirst() {
4549
if arg.starts(with: "--") {
4650
if let parsed = Mode(rawValue: String(arg.dropFirst(2))) {
@@ -49,10 +53,10 @@ enum WebIDLToSwift {
4953
print("Unknown option: \(arg)")
5054
}
5155
} else {
52-
print("Unknown argument: \(arg)")
56+
moduleNames.append(arg)
5357
}
5458
}
55-
return mode
59+
return (mode, moduleNames)
5660
}
5761

5862
private static func generate(

0 commit comments

Comments
 (0)