13
13
// RUN: %empty-directory(%t)
14
14
//
15
15
// RUN: %target-clang %S/Inputs/SwiftObjectNSObject/SwiftObjectNSObject.m -c -o %t/SwiftObjectNSObject.o -g
16
- // RUN: %target-build-swift %s -I %S/Inputs/SwiftObjectNSObject/ -Xlinker %t/SwiftObjectNSObject.o -o %t/SwiftObjectNSObject
16
+ // RUN: %target-build-swift %s -g - I %S/Inputs/SwiftObjectNSObject/ -Xlinker %t/SwiftObjectNSObject.o -o %t/SwiftObjectNSObject
17
17
// RUN: %target-codesign %t/SwiftObjectNSObject
18
18
// RUN: %target-run %t/SwiftObjectNSObject 2> %t/log.txt
19
+ // RUN: cat %t/log.txt 1>&2
19
20
// RUN: %FileCheck %s < %t/log.txt
20
21
// REQUIRES: executable_test
21
22
@@ -39,22 +40,159 @@ class D : C {
39
40
@objc override class func cClassOverride( ) -> Int { return 8 }
40
41
}
41
42
42
- @_silgen_name ( " TestSwiftObjectNSObject " )
43
+ class E : Equatable , CustomStringConvertible {
44
+ var i : Int
45
+ static func == ( lhs: E , rhs: E ) -> Bool { lhs. i == rhs. i }
46
+ init ( i: Int ) { self . i = i }
47
+ var description : String { " \( type ( of: self ) ) (i: \( self . i) ) " }
48
+ }
49
+
50
+ class E1 : E {
51
+ }
52
+
53
+ class E2 : E {
54
+ }
55
+
56
+ class F : CustomStringConvertible {
57
+ var i : Int
58
+ init ( i: Int ) { self . i = i }
59
+ var description : String { " \( type ( of: self ) ) (i: \( self . i) ) " }
60
+ }
61
+
62
+ class F1 : F , Equatable {
63
+ static func == ( lhs: F1 , rhs: F1 ) -> Bool { lhs. i == rhs. i }
64
+ }
65
+
66
+ class F2 : F , Equatable {
67
+ static func == ( lhs: F2 , rhs: F2 ) -> Bool { lhs. i == rhs. i }
68
+ }
69
+
70
+ class H : E , Hashable {
71
+ static func == ( lhs: H , rhs: H ) -> Bool { lhs. i == rhs. i }
72
+ func hash( into hasher: inout Hasher ) { hasher. combine ( i + 17 ) }
73
+ }
74
+
75
+ @_silgen_name ( " TestSwiftObjectNSObject " )
43
76
func TestSwiftObjectNSObject( _ c: C , _ d: D )
77
+ @_silgen_name( " TestSwiftObjectNSObjectEquals" )
78
+ func TestSwiftObjectNSObjectEquals( _: AnyObject , _: AnyObject )
79
+ @_silgen_name( " TestSwiftObjectNSObjectNotEquals" )
80
+ func TestSwiftObjectNSObjectNotEquals( _: AnyObject , _: AnyObject )
81
+ @_silgen_name( " TestSwiftObjectNSObjectHashValue" )
82
+ func TestSwiftObjectNSObjectHashValue( _: AnyObject , _: Int )
83
+ @_silgen_name( " TestSwiftObjectNSObjectDefaultHashValue" )
84
+ func TestSwiftObjectNSObjectDefaultHashValue( _: AnyObject )
85
+ @_silgen_name( " TestSwiftObjectNSObjectAssertNoErrors" )
86
+ func TestSwiftObjectNSObjectAssertNoErrors()
87
+
88
+ // Verify that Obj-C isEqual: provides same answer as Swift ==
89
+ func TestEquatableEquals<T: Equatable & AnyObject>(_ e1: T, _ e2: T) {
90
+ if e1 == e2 {
91
+ TestSwiftObjectNSObjectEquals(e1, e2)
92
+ } else {
93
+ TestSwiftObjectNSObjectNotEquals(e1, e2)
94
+ }
95
+ }
96
+
97
+ func TestNonEquatableEquals(_ e1: AnyObject, _ e2: AnyObject) {
98
+ TestSwiftObjectNSObjectNotEquals(e1, e2)
99
+ }
100
+
101
+ // Verify that Obj-C hashValue matches Swift hashValue for Hashable types
102
+ func TestHashable(_ h: H)
103
+ {
104
+ TestSwiftObjectNSObjectHashValue(h, h.hashValue)
105
+ }
106
+
107
+ // Test Obj-C hashValue for Swift types that are Equatable but not Hashable
108
+ func TestEquatableHash(_ e: AnyObject)
109
+ {
110
+ // These should have a constant hash value
111
+ TestSwiftObjectNSObjectHashValue(e, 1)
112
+ }
113
+
114
+ func TestNonEquatableHash(_ e: AnyObject)
115
+ {
116
+ TestSwiftObjectNSObjectDefaultHashValue(e)
117
+ }
118
+
119
+ // Check NSLog() output from TestSwiftObjectNSObject().
44
120
45
- // This check is for NSLog() output from TestSwiftObjectNSObject().
46
121
// CHECK: c ##SwiftObjectNSObject.C##
47
122
// CHECK-NEXT: d ##SwiftObjectNSObject.D##
48
123
// CHECK-NEXT: S ##{{.*}}SwiftObject##
49
124
125
+ // Full message is longer, but this is the essential part...
126
+ // CHECK-NEXT: Obj-C `-hash` {{.*}} type `SwiftObjectNSObject.E` {{.*}} Equatable but not Hashable
127
+ // CHECK-NEXT: Obj-C `-hash` {{.*}} type `SwiftObjectNSObject.E1` {{.*}} Equatable but not Hashable
128
+ // CHECK-NEXT: Obj-C `-hash` {{.*}} type `SwiftObjectNSObject.E2` {{.*}} Equatable but not Hashable
129
+
50
130
// Temporarily disable this test on older OSes until we have time to
51
131
// look into why it's failing there. rdar://problem/47870743
52
132
if #available(OSX 10.12, iOS 10.0, *) {
133
+ // Test a large number of Obj-C APIs
53
134
TestSwiftObjectNSObject(C(), D())
54
- // does not return
135
+
136
+ // ** Equatable types with an Equatable parent class
137
+ // Same type and class
138
+ TestEquatableEquals(E(i: 1), E(i: 1))
139
+ TestEquatableEquals(E(i: 790), E(i: 790))
140
+ TestEquatableEquals(E1(i: 1), E1(i: 1))
141
+ TestEquatableEquals(E1(i: 18), E1(i: 18))
142
+ TestEquatableEquals(E2(i: 1), E2(i: 1))
143
+ TestEquatableEquals(E2(i: 2), E2(i: 2))
144
+ // Different class
145
+ TestEquatableEquals(E1(i: 1), E2(i: 1))
146
+ TestEquatableEquals(E1(i: 1), E(i: 1))
147
+ TestEquatableEquals(E2(i: 1), E(i: 1))
148
+ // Different value
149
+ TestEquatableEquals(E(i: 1), E(i: 2))
150
+ TestEquatableEquals(E1(i: 1), E1(i: 2))
151
+ TestEquatableEquals(E2(i: 1), E2(i: 2))
152
+
153
+ // ** Non-Equatable parent class
154
+ // Same class and value
155
+ TestEquatableEquals(F1(i: 1), F1(i: 1))
156
+ TestEquatableEquals(F1(i: 1), F1(i: 2))
157
+ TestEquatableEquals(F2(i: 1), F2(i: 1))
158
+ TestEquatableEquals(F2(i: 1), F2(i: 2))
159
+
160
+ // Different class and/or value
161
+ TestNonEquatableEquals(F(i: 1), F(i: 2))
162
+ TestNonEquatableEquals(F(i: 1), F(i: 1))
163
+ TestNonEquatableEquals(F1(i: 1), F2(i: 1))
164
+ TestNonEquatableEquals(F1(i: 1), F(i: 1))
165
+
166
+ // Two equatable types with no common parent class
167
+ TestNonEquatableEquals(F1(i: 1), E(i: 1))
168
+ TestEquatableEquals(H(i:1), E(i:1))
169
+
170
+ // Equatable but not Hashable: alway have the same Obj-C hashValue
171
+ TestEquatableHash(E(i: 1))
172
+ TestEquatableHash(E1(i: 3))
173
+ TestEquatableHash(E2(i: 8))
174
+
175
+ // Neither Equatable nor Hashable
176
+ TestNonEquatableHash(C())
177
+ TestNonEquatableHash(D())
178
+
179
+ // Hashable types are also Equatable
180
+ TestEquatableEquals(H(i:1), H(i:1))
181
+ TestEquatableEquals(H(i:1), H(i:2))
182
+ TestEquatableEquals(H(i:2), H(i:1))
183
+
184
+ // Verify Obj-C hash value agrees with Swift
185
+ TestHashable(H(i:1))
186
+ TestHashable(H(i:2))
187
+ TestHashable(H(i:18))
188
+
189
+ TestSwiftObjectNSObjectAssertNoErrors()
55
190
} else {
56
191
// Horrible hack to satisfy FileCheck
57
192
fputs( " c ##SwiftObjectNSObject. C##\n" , stderr)
58
193
fputs ( " d ##SwiftObjectNSObject.D## \n " , stderr)
59
194
fputs ( " S ##Swift._SwiftObject## \n " , stderr)
195
+ fputs ( " Obj-C `-hash` ... type `SwiftObjectNSObject.E` ... Equatable but not Hashable " , stderr)
196
+ fputs ( " Obj-C `-hash` ... type `SwiftObjectNSObject.E1` ... Equatable but not Hashable " , stderr)
197
+ fputs ( " Obj-C `-hash` ... type `SwiftObjectNSObject.E2` ... Equatable but not Hashable " , stderr)
60
198
}
0 commit comments