@@ -20,16 +20,21 @@ func wantonlyWrapInAny<T>(_ x: T) -> Any {
20
20
extension LifetimeTracked: Error {}
21
21
extension String: Error {}
22
22
23
- struct KnownUnbridged: Equatable, Error {
23
+ struct KnownUnbridged: Equatable, Hashable, Error {
24
24
var x, y: LifetimeTracked
25
25
26
26
init() {
27
27
x = LifetimeTracked(17)
28
28
y = LifetimeTracked(38)
29
29
}
30
- }
31
- func ==(a: KnownUnbridged, b: KnownUnbridged) -> Bool {
32
- return a.x === b.x && a.y === b.y
30
+
31
+ public static func ==(a: KnownUnbridged, b: KnownUnbridged) -> Bool {
32
+ return a.x === b.x && a.y === b.y
33
+ }
34
+
35
+ public var hashValue: Int {
36
+ return x.hashValue ^ y.hashValue
37
+ }
33
38
}
34
39
35
40
struct KnownUnbridgedWithDescription: CustomStringConvertible,
@@ -96,22 +101,22 @@ func boxedTypeRoundTripsThroughDynamicCasting(original: KnownUnbridged,
96
101
97
102
func tupleCanBeDynamicallyCast(original: (Int, String),
98
103
bridged: AnyObject) {
99
- expectTrue(original == bridged as! (Int, String))
104
+ expectTrue(original == ( bridged as! (Int, String) ))
100
105
}
101
106
func metatypeCanBeDynamicallyCast(original: Int.Type,
102
107
bridged: AnyObject) {
103
- expectTrue(original == bridged as! Int.Type)
104
- expectTrue(original == bridged as! Any.Type)
108
+ expectTrue(original == ( bridged as! Int.Type) )
109
+ expectTrue(original == ( bridged as! Any.Type) )
105
110
}
106
111
func metatypeCanBeDynamicallyCast(original: CFString.Type,
107
112
bridged: AnyObject) {
108
- expectTrue(original == bridged as! CFString.Type)
109
- expectTrue(original == bridged as! Any.Type)
113
+ expectTrue(original == ( bridged as! CFString.Type) )
114
+ expectTrue(original == ( bridged as! Any.Type) )
110
115
}
111
116
func metatypeCanBeDynamicallyCastGenerically<T>(original: T.Type,
112
117
bridged: AnyObject) {
113
- expectTrue(original == bridged as! T.Type)
114
- expectTrue(original == bridged as! Any.Type)
118
+ expectTrue(original == ( bridged as! T.Type) )
119
+ expectTrue(original == ( bridged as! Any.Type) )
115
120
}
116
121
117
122
@@ -151,33 +156,66 @@ protocol P {}
151
156
// interesting bridging cases in different kinds of existential container.
152
157
%{
153
158
testCases = [
154
- ("classes", "LifetimeTracked(0)", "bridgedObjectPreservesIdentity", True),
155
- ("strings", '"vitameatavegamin"', "stringBridgesToEqualNSString", True),
156
- ("unbridged type", "KnownUnbridged()", "boxedTypeRoundTripsThroughDynamicCasting", True),
157
- ("tuple", '(1, "2")', "tupleCanBeDynamicallyCast", False),
158
- ("metatype", 'Int.self', "metatypeCanBeDynamicallyCast", False),
159
- ("generic metatype", 'Int.self', "metatypeCanBeDynamicallyCastGenerically", False),
160
- ("CF metatype", 'CFString.self', "metatypeCanBeDynamicallyCast", False),
161
- ("generic CF metatype", 'CFString.self', "metatypeCanBeDynamicallyCastGenerically", False),
162
- ("class metatype", 'LifetimeTracked.self', "classMetatypePreservesIdentity", False),
163
- ("objc metatype", 'NSObject.self', "classMetatypePreservesIdentity", False),
164
- ("protocol", 'P.self', "metatypeCanBeDynamicallyCastGenerically", False),
165
- ("objc protocol", 'NSCopying.self', "protocolObjectPreservesIdentity", False),
166
- ("objc protocol composition", '(NSCopying & NSCoding).self', "metatypeCanBeDynamicallyCastGenerically", False),
167
- ("mixed protocol composition", '(NSCopying & P).self', "metatypeCanBeDynamicallyCastGenerically", False),
168
- ("generic class metatype", 'LifetimeTracked.self', "classMetatypePreservesIdentityGenerically", False),
169
- ("generic objc metatype", 'NSObject.self', "classMetatypePreservesIdentityGenerically", False),
170
- ("function", 'guineaPigFunction', "functionCanBeDynamicallyCast", False),
159
+ # testName valueExpr testFunc conformsToError conformsToHashable
160
+ ("classes", "LifetimeTracked(0)", "bridgedObjectPreservesIdentity", True, True),
161
+ ("strings", '"vitameatavegamin"', "stringBridgesToEqualNSString", True, True),
162
+ ("unbridged type", "KnownUnbridged()", "boxedTypeRoundTripsThroughDynamicCasting", True, True),
163
+ ("tuple", '(1, "2")', "tupleCanBeDynamicallyCast", False, False),
164
+ ("metatype", 'Int.self', "metatypeCanBeDynamicallyCast", False, False),
165
+ ("generic metatype", 'Int.self', "metatypeCanBeDynamicallyCastGenerically", False, False),
166
+ ("CF metatype", 'CFString.self', "metatypeCanBeDynamicallyCast", False, False),
167
+ ("generic CF metatype", 'CFString.self', "metatypeCanBeDynamicallyCastGenerically", False, False),
168
+ ("class metatype", 'LifetimeTracked.self', "classMetatypePreservesIdentity", False, False),
169
+ ("objc metatype", 'NSObject.self', "classMetatypePreservesIdentity", False, False),
170
+ ("protocol", 'P.self', "metatypeCanBeDynamicallyCastGenerically", False, False),
171
+ ("objc protocol", 'NSCopying.self', "protocolObjectPreservesIdentity", False, False),
172
+ ("objc protocol composition", '(NSCopying & NSCoding).self', "metatypeCanBeDynamicallyCastGenerically", False, False),
173
+ ("mixed protocol composition", '(NSCopying & P).self', "metatypeCanBeDynamicallyCastGenerically", False, False),
174
+ ("generic class metatype", 'LifetimeTracked.self', "classMetatypePreservesIdentityGenerically", False, False),
175
+ ("generic objc metatype", 'NSObject.self', "classMetatypePreservesIdentityGenerically", False, False),
176
+ ("function", 'guineaPigFunction', "functionCanBeDynamicallyCast", False, False),
171
177
]
172
178
}%
173
179
174
- % for testName, valueExpr, testFunc, conformsToError in testCases:
180
+ % for testName, valueExpr, testFunc, conformsToError, conformsToHashable in testCases:
175
181
BridgeAnything.test("${testName}") {
176
- do {
182
+ autoreleasepool {
177
183
let x = ${valueExpr}
178
184
${testFunc}(original: x, bridged: _bridgeAnythingToObjectiveC(x))
179
185
${testFunc}(original: x, bridged: _bridgeAnythingNonVerbatimToObjectiveC(x))
180
186
187
+ // Bridge an array containing x.
188
+ let xInArray = [x]
189
+ ${testFunc}(original: x, bridged: (_bridgeAnythingToObjectiveC(xInArray) as! [AnyObject])[0])
190
+ ${testFunc}(original: x, bridged: (_bridgeAnythingToObjectiveC(xInArray) as? [AnyObject])![0])
191
+ if (x as? NSObject) != nil {
192
+ ${testFunc}(original: x, bridged: (_bridgeAnythingToObjectiveC(xInArray) as! [AnyObject])[0])
193
+ ${testFunc}(original: x, bridged: (_bridgeAnythingToObjectiveC(xInArray) as? [AnyObject])![0])
194
+ }
195
+
196
+ // Bridge a dictionary containing x as a value.
197
+ let xInDictValue = ["key" : x]
198
+ ${testFunc}(original: x, bridged: (_bridgeAnythingToObjectiveC(xInDictValue) as! [String: AnyObject])["key"]!)
199
+ ${testFunc}(original: x, bridged: (_bridgeAnythingToObjectiveC(xInDictValue) as? [String: AnyObject])!["key"]!)
200
+ if (x as? NSObject) != nil {
201
+ ${testFunc}(original: x, bridged: (_bridgeAnythingToObjectiveC(xInDictValue) as! [String: NSObject])["key"]!)
202
+ ${testFunc}(original: x, bridged: (_bridgeAnythingToObjectiveC(xInDictValue) as? [String: NSObject])!["key"]!)
203
+ }
204
+
205
+ % if conformsToHashable:
206
+ // Bridge a dictionary containing x as a key.
207
+ let xInDictKey = [x : "value"] as [AnyHashable: String]
208
+ // FIXME: need a way to express `AnyObject & Hashable`.
209
+ // The NSObject version below can't test class LifetimeTracked.
210
+ // ${testFunc}(original: x, bridged: (_bridgeAnythingToObjectiveC(xInDictKey) as! [(AnyObject & Hashable): String]).keys.first!)
211
+ // ${testFunc}(original: x, bridged: (_bridgeAnythingToObjectiveC(xInDictKey) as? [(AnyObject & Hashable): String])!.keys.first!)
212
+ if (x as? NSObject) != nil {
213
+ ${testFunc}(original: x, bridged: (_bridgeAnythingToObjectiveC(xInDictKey) as! [NSObject: String]).keys.first!)
214
+ ${testFunc}(original: x, bridged: (_bridgeAnythingToObjectiveC(xInDictKey) as? [NSObject: String])!.keys.first!)
215
+ }
216
+
217
+ % end
218
+
181
219
let xInAny: Any = x
182
220
${testFunc}(original: x, bridged: _bridgeAnythingToObjectiveC(xInAny))
183
221
${testFunc}(original: x, bridged: _bridgeAnythingNonVerbatimToObjectiveC(xInAny))
0 commit comments