55// UNSUPPORTED: use_os_stdlib
66// UNSUPPORTED: back_deployment_runtime
77
8- class MyLabel {
8+ class MyLabel : Hashable {
99 var text = " label "
1010 static var isVisible = true
11+ func x( val value: Int ) -> Int { return value }
12+ static func y( val value: Int ) -> Int { return value }
13+ func saveClosure( _ closure: @escaping ( ) -> Void ) {
14+ storedClosure = closure
15+ }
16+ func executeStoredClosure( ) {
17+ storedClosure ? ( )
18+ }
19+ private var storedClosure : ( ( ) -> Void ) ?
20+
21+ required init ( ) { }
22+ required init ( customText: String ) {
23+ text = customText
24+ }
25+
26+ static func == ( lhs: MyLabel , rhs: MyLabel ) -> Bool {
27+ return lhs === rhs
28+ }
29+ func hash( into hasher: inout Hasher ) {
30+ hasher. combine ( ObjectIdentifier ( self ) )
31+ }
1132}
1233
1334class Controller {
@@ -57,11 +78,6 @@ class Controller {
5778 }
5879}
5980
60- struct S {
61- var a : Int
62- static let b : Double = 100.0
63- }
64-
6581struct Container < V> {
6682 var v : V
6783 init ( _ v: V ) {
@@ -70,16 +86,30 @@ struct Container<V> {
7086 func useKeyPath< V2: AnyObject > ( _ keyPath: KeyPath < V , V2 > ) -> String {
7187 return ( v [ keyPath: keyPath] as! MyLabel ) . text
7288 }
89+ func invokeKeyPathMethod< V2, R> (
90+ _ keyPath: KeyPath < V , V2 > ,
91+ method: KeyPath < V2 , ( Int ) -> R > ,
92+ arg: Int
93+ ) -> R {
94+ let instance = v [ keyPath: keyPath]
95+ return instance [ keyPath: method] ( arg)
96+ }
7397}
7498
7599extension Container where V: Controller {
76100 func test( ) -> String {
77101 return useKeyPath ( \. label)
78102 }
103+ func testKeyPathMethod( ) -> Int {
104+ let result = invokeKeyPathMethod ( \. label, method: \MyLabel . x ( val: ) , arg: 10 )
105+ return result
106+ }
79107}
80108
81109// CHECK: label
82110print ( Container ( Controller ( ) ) . test ( ) )
111+ // CHECK: 10
112+ print ( Container ( Controller ( ) ) . testKeyPathMethod ( ) )
83113
84114struct MetatypeContainer < V> {
85115 var v : V . Type
@@ -92,10 +122,38 @@ struct MetatypeContainer<V> {
92122 }
93123 return false
94124 }
125+ func getKeyPathMethodVal( ) -> Int {
126+ if let labelType = v as? MyLabel . Type {
127+ return labelType. y ( val: 20 )
128+ }
129+ return 0
130+ }
131+ func createInstanceWithDefaultInit( ) -> MyLabel ? {
132+ if let labelType = v as? MyLabel . Type {
133+ return labelType. init ( )
134+ }
135+ return nil
136+ }
137+ func createInstanceWithCustomInit( customText: String ) -> MyLabel ? {
138+ if let labelType = v as? MyLabel . Type {
139+ return labelType. init ( customText: customText)
140+ }
141+ return nil
142+ }
95143}
96144
97145// CHECK: true
98146print ( MetatypeContainer ( MyLabel . self) . useMetatypeKeyPath ( ) )
147+ // CHECK: 20
148+ print ( MetatypeContainer ( MyLabel . self) . getKeyPathMethodVal ( ) )
149+ // CHECK: label
150+ if let instance = MetatypeContainer ( MyLabel . self) . createInstanceWithDefaultInit ( ) {
151+ print ( instance. text)
152+ }
153+ // CHECK: Custom Label
154+ if let customInstance = MetatypeContainer ( MyLabel . self) . createInstanceWithCustomInit ( customText: " Custom Label " ) {
155+ print ( customInstance. text)
156+ }
99157
100158public class GenericController < U> {
101159 init ( _ u: U ) {
@@ -116,13 +174,28 @@ public func generic_class_constrained_keypath<U, V>(_ c: V) where V : GenericCon
116174// CHECK: label
117175generic_class_constrained_keypath ( GenericController ( 5 ) )
118176
177+ struct S {
178+ var year = 2024
179+ static let millenium : Int = 3
180+ init ( ) { }
181+ init ( val value: Int = 2024 ) { year = value }
182+
183+ var add : ( Int , Int ) -> Int { return { $0 + $1 } }
184+ func add( this: Int ) -> Int { this + this}
185+ func add( that: Int ) -> Int { that + that }
186+ static func subtract( _ val: Int ) -> Int { return millenium - val }
187+ nonisolated func nonisolatedNextYear( ) -> Int { year + 1 }
188+ consuming func consume( ) { print ( year) }
189+ subscript( index: Int ) -> Int { return year + index}
190+ }
191+
119192// CHECK: {{\\Controller\.secondLabel!\.text|\\Controller\.<computed 0x.* \(Optional<MyLabel>\)>!\.<computed 0x.* \(String\)>}}
120193print ( \Controller . secondLabel!. text)
121194
122195// CHECK: {{\\Controller\.subscript\(_: String\)|\\Controller\.<computed 0x.* \(String\)>}}
123196print ( \Controller [ " abc " ] )
124- // CHECK: \S.a
125- print ( \S . a )
197+ // CHECK: \S.year
198+ print ( \S . year )
126199// CHECK: {{\\Controller\.subscript\(int: Int, str: String, _: Int\)|\\Controller\.<computed 0x.* \(Int\)>}}
127200print ( \Controller [ int: 0 , str: " " , 0 ] )
128201// CHECK: {{\\Controller\.thirdLabel|\\Controller\.<computed 0x.* \(Optional<MyLabel>\)>}}
@@ -146,13 +219,98 @@ print(\Controller[array: [42], array2: [42]])
146219// CHECK: {{\\Controller\.(fourthLabel|<computed .* \(Optional<MyLabel\.Type>\)>)!\.<computed .* \(Bool\)>}}
147220print ( \Controller . fourthLabel!. isVisible)
148221
149- // CHECK: \S.Type.<computed {{.*}} (Double )>
150- print ( \S . Type. b )
222+ // CHECK: \S.Type.<computed {{.*}} (Int )>
223+ print ( \S . Type. millenium )
151224// CHECK: {{\\Controller\.(fifthLabel|<computed .* \(Optional<MyLabel\.Type>\)>)\?\.<computed .* \(Bool\)>?}}
152225print ( \Controller . fifthLabel? . isVisible)
153226// CHECK: \Int.Type.<computed {{.*}} (Int)>
154227print ( \Int . Type. zero)
155228
229+ // CHECK: \S.Type.<computed {{.*}} (() -> S)>
230+ print ( \S . Type. init)
231+ // CHECK: \S.Type.<computed {{.*}} (S)>
232+ print ( \S . Type. init ( ) )
233+ // CHECK: \S.Type.<computed {{.*}} ((Int) -> S)>
234+ print ( \S . Type. init ( val: ) )
235+ // CHECK: \S.Type.<computed {{.*}} (S)>
236+ print ( \S . Type. init ( val: 2025 ) )
237+ // CHECK: \S.Type.<computed {{.*}} (S)>.year
238+ print ( \S . Type. init ( val: 2025 ) . year)
239+ // CHECK: 2024
240+ let kp = \S . Type. init ( ) [ 0 ]
241+ let result = S . self [ keyPath: kp]
242+ print ( result)
243+ // CHECK: 7
244+ let kpAdd = \S . add
245+ let resultAdd = S ( ) [ keyPath: kpAdd] ( 3 , 4 )
246+ print ( resultAdd)
247+ // CHECK: \S.<computed {{.*}} ((Int) -> Int)>
248+ print ( \S . add ( this: ) )
249+ // CHECK: \S.<computed {{.*}} (Int)>
250+ print ( \S . add ( that: 1 ) )
251+ // CHECK: \S.Type.<computed {{.*}} ((Int) -> Int)>
252+ print ( \S . Type. subtract)
253+ // CHECK: \S.Type.<computed {{.*}} (Int)>
254+ print ( \S . Type. subtract ( 1 ) )
255+ // CHECK: \S.<computed {{.*}} (() -> Int)>
256+ print ( \S . nonisolatedNextYear)
257+ // CHECK: \S.<computed {{.*}} (Int)>
258+ print ( \S . nonisolatedNextYear ( ) )
259+ // CHECK: \S.Type.<computed {{.*}} (S)>.<computed {{.*}} (Int)>
260+ print ( \S . Type. init ( val: 2025 ) . nonisolatedNextYear ( ) )
261+ // CHECK: 2026
262+ let kpMethodProperty = \S . Type. init ( val: 2025 ) . nonisolatedNextYear ( ) . description
263+ let resultMethodProperty = S . self [ keyPath: kpMethodProperty]
264+ print ( resultMethodProperty)
265+ // CHECK: \S.Type.<computed {{.*}} (S)>.<computed {{.*}} (Int)>.<computed {{.*}} (Int)>
266+ print ( \S . Type. init ( val: 2025 ) . nonisolatedNextYear ( ) . signum ( ) )
267+ // // CHECK: \S.<computed {{.*}} (())>
268+ print ( \S . consume ( ) )
269+
270+ // CHECK: false
271+ print ( \S . add ( that: 1 ) == \S . add ( this: 1 ) )
272+ // CHECK: false
273+ print ( \S . add ( that: 1 ) == \S . add ( this: 2 ) )
274+ // CHECK: false
275+ print ( \S . Type. init ( val: 2024 ) == \S . Type. init ( val: 2025 ) )
276+ // CHECK: false
277+ print ( \S . Type. init ( val: 2024 ) . nonisolatedNextYear ( ) == \S . Type. init ( val: 2025 ) )
278+ // CHECK: true
279+ print ( \S . Type. init ( val: 2024 ) . add ( this: 1 ) != \S . Type. init ( val: 2025 ) )
280+
281+ class E : Hashable {
282+ static func == ( lhs: E , rhs: E ) -> Bool { return lhs === rhs }
283+ func hash( into hasher: inout Hasher ) {
284+ hasher. combine ( ObjectIdentifier ( self ) )
285+ }
286+ }
287+ struct BaseType {
288+ func foo( hashableParam e: E ) { }
289+ }
290+ let hashableInstance = E ( )
291+ // CHECK: \BaseType.<computed {{.*}} (())>
292+ print ( \BaseType . foo ( hashableParam: hashableInstance) )
293+
294+ protocol Describable {
295+ func describe( ) -> String
296+ }
297+ struct C : Describable {
298+ var name : String
299+ func describe( ) -> String { return " \( name) " }
300+ }
301+ // CHECK: \C.<computed {{.*}} (() -> String)>
302+ print ( \C . describe)
303+
304+ // CHECK: false
305+ print ( \S . Type. init ( val: 2025 ) == \S . Type. init ( val: 2026 ) )
306+ // CHECK: false
307+ print ( \S . Type. init ( val: 2025 ) . nonisolatedNextYear ( ) == \S . Type. init ( val: 2026 ) . nonisolatedNextYear ( ) )
308+ // CHECK: true
309+ print ( \S . Type. init ( val: 2025 ) . nonisolatedNextYear ( ) == \S . Type. init ( val: 2025 ) . nonisolatedNextYear ( ) )
310+ // CHECK: false
311+ print ( \MyLabel . x ( val: 10 ) == \MyLabel . x ( val: 20 ) )
312+ // CHECK: true
313+ print ( \MyLabel . Type. y ( val: 10 ) == \MyLabel . Type. y ( val: 10 ) )
156314
157315do {
158316 struct S {
@@ -208,3 +366,48 @@ do {
208366 // CHECK: true
209367 print ( StaticExample < MyLabel > ( ) . isVisible)
210368}
369+
370+ do {
371+ @dynamicMemberLookup
372+ struct InstanceDynamicMemberLookup < T> {
373+ var obj : T
374+
375+ subscript< U> ( dynamicMember member: KeyPath < T , ( Int ) -> U > ) -> ( Int ) -> U {
376+ get { obj [ keyPath: member] }
377+ }
378+ }
379+
380+ // CHECK: 50
381+ let instanceDynamicLookup = InstanceDynamicMemberLookup ( obj: MyLabel ( ) )
382+ print ( instanceDynamicLookup. x ( 50 ) )
383+ }
384+
385+ extension MyLabel {
386+ static var defaultInitializer : ( ) -> MyLabel { return MyLabel . init }
387+ static var customInitializer : ( String ) -> MyLabel { return MyLabel . init ( customText: ) }
388+ }
389+
390+ do {
391+ @dynamicMemberLookup
392+ struct StaticDynamicMemberLookup < T> {
393+ subscript< U> ( dynamicMember keyPath: KeyPath < T . Type , ( Int ) -> U > ) -> ( Int ) -> U {
394+ return T . self [ keyPath: keyPath]
395+ }
396+ subscript< U> ( dynamicMember keyPath: KeyPath < T . Type , ( ) -> U > ) -> ( ) -> U {
397+ return T . self [ keyPath: keyPath]
398+ }
399+ subscript< U> ( dynamicMember keyPath: KeyPath < T . Type , ( String ) -> U > ) -> ( String ) -> U {
400+ return T . self [ keyPath: keyPath]
401+ }
402+ }
403+
404+ // CHECK: 60
405+ let staticDynamicLookup = StaticDynamicMemberLookup < MyLabel > ( )
406+ print ( staticDynamicLookup. y ( 60 ) )
407+ // CHECK: label
408+ let defaultInstance = staticDynamicLookup. defaultInitializer ( )
409+ print ( defaultInstance. text)
410+ // CHECK: Custom Label
411+ let customInstance = staticDynamicLookup. customInitializer ( " Custom Label " )
412+ print ( customInstance. text)
413+ }
0 commit comments