@@ -256,6 +256,293 @@ final class ExpressionTests: ParserTestCase {
256
256
)
257
257
}
258
258
259
+ func testKeyPathMethodAndInitializers( ) {
260
+ assertParse (
261
+ #"\Foo.method()"# ,
262
+ substructure: KeyPathExprSyntax (
263
+ root: TypeSyntax ( " Foo " ) ,
264
+ components: KeyPathComponentListSyntax ( [
265
+ KeyPathComponentSyntax (
266
+ period: . periodToken( ) ,
267
+ component: KeyPathComponentSyntax . Component (
268
+ KeyPathMethodComponentSyntax (
269
+ declName: DeclReferenceExprSyntax ( baseName: . identifier( " method " ) ) ,
270
+ leftParen: . leftParenToken( ) ,
271
+ arguments: LabeledExprListSyntax ( [ ] ) ,
272
+ rightParen: . rightParenToken( )
273
+ )
274
+ )
275
+ )
276
+ ] )
277
+ ) ,
278
+ experimentalFeatures: . keypathWithMethodMembers
279
+ )
280
+
281
+ assertParse (
282
+ #"\Foo.method(10)"# ,
283
+ substructure: KeyPathExprSyntax (
284
+ root: TypeSyntax ( " Foo " ) ,
285
+ components: KeyPathComponentListSyntax ( [
286
+ KeyPathComponentSyntax (
287
+ period: . periodToken( ) ,
288
+ component: . init(
289
+ KeyPathMethodComponentSyntax (
290
+ declName: DeclReferenceExprSyntax ( baseName: . identifier( " method " ) ) ,
291
+ leftParen: . leftParenToken( ) ,
292
+ arguments: LabeledExprListSyntax ( [
293
+ LabeledExprSyntax (
294
+ label: nil ,
295
+ colon: nil ,
296
+ expression: ExprSyntax ( " 10 " )
297
+ )
298
+ ] ) ,
299
+ rightParen: . rightParenToken( )
300
+ )
301
+ )
302
+ )
303
+ ] )
304
+ ) ,
305
+ experimentalFeatures: . keypathWithMethodMembers
306
+ )
307
+
308
+ assertParse (
309
+ #"\Foo.method(arg: 10)"# ,
310
+ substructure: KeyPathExprSyntax (
311
+ root: TypeSyntax ( " Foo " ) ,
312
+ components: KeyPathComponentListSyntax ( [
313
+ KeyPathComponentSyntax (
314
+ period: . periodToken( ) ,
315
+ component: . init(
316
+ KeyPathMethodComponentSyntax (
317
+ declName: DeclReferenceExprSyntax ( baseName: . identifier( " method " ) ) ,
318
+ leftParen: . leftParenToken( ) ,
319
+ arguments: LabeledExprListSyntax ( [
320
+ LabeledExprSyntax (
321
+ label: . identifier( " arg " ) ,
322
+ colon: . colonToken( ) ,
323
+ expression: ExprSyntax ( " 10 " )
324
+ )
325
+ ] ) ,
326
+ rightParen: . rightParenToken( )
327
+ )
328
+ )
329
+ )
330
+ ] )
331
+ ) ,
332
+ experimentalFeatures: . keypathWithMethodMembers
333
+ )
334
+
335
+ assertParse (
336
+ #"\Foo.method(_:)"# ,
337
+ substructure: KeyPathExprSyntax (
338
+ root: TypeSyntax ( " Foo " ) ,
339
+ components: KeyPathComponentListSyntax ( [
340
+ KeyPathComponentSyntax (
341
+ period: . periodToken( ) ,
342
+ component: . init(
343
+ KeyPathPropertyComponentSyntax (
344
+ declName: DeclReferenceExprSyntax (
345
+ baseName: . identifier( " method " ) ,
346
+ argumentNames: DeclNameArgumentsSyntax (
347
+ leftParen: . leftParenToken( ) ,
348
+ arguments: [
349
+ DeclNameArgumentSyntax ( name: . wildcardToken( ) , colon: . colonToken( ) )
350
+ ] ,
351
+ rightParen: . rightParenToken( )
352
+ )
353
+ )
354
+ )
355
+ )
356
+ )
357
+ ] )
358
+ ) ,
359
+ experimentalFeatures: . keypathWithMethodMembers
360
+ )
361
+
362
+ assertParse (
363
+ #"\Foo.method(arg:)"# ,
364
+ substructure: KeyPathExprSyntax (
365
+ root: TypeSyntax ( " Foo " ) ,
366
+ components: KeyPathComponentListSyntax ( [
367
+ KeyPathComponentSyntax (
368
+ period: . periodToken( ) ,
369
+ component: . init(
370
+ KeyPathPropertyComponentSyntax (
371
+ declName: DeclReferenceExprSyntax (
372
+ baseName: . identifier( " method " ) ,
373
+ argumentNames: DeclNameArgumentsSyntax (
374
+ leftParen: . leftParenToken( ) ,
375
+ arguments: [
376
+ DeclNameArgumentSyntax ( name: . identifier( " arg " ) , colon: . colonToken( ) )
377
+ ] ,
378
+ rightParen: . rightParenToken( )
379
+ )
380
+ )
381
+ )
382
+ )
383
+ )
384
+ ] )
385
+ ) ,
386
+ experimentalFeatures: . keypathWithMethodMembers
387
+ )
388
+
389
+ assertParse (
390
+ #"\Foo.method().anotherMethod(arg: 10)"# ,
391
+ substructure: KeyPathExprSyntax (
392
+ root: TypeSyntax ( " Foo " ) ,
393
+ components: KeyPathComponentListSyntax ( [
394
+ KeyPathComponentSyntax (
395
+ period: . periodToken( ) ,
396
+ component: . init(
397
+ KeyPathMethodComponentSyntax (
398
+ declName: DeclReferenceExprSyntax ( baseName: . identifier( " method " ) ) ,
399
+ leftParen: . leftParenToken( ) ,
400
+ arguments: LabeledExprListSyntax ( [ ] ) ,
401
+ rightParen: . rightParenToken( )
402
+ )
403
+ )
404
+ ) ,
405
+ KeyPathComponentSyntax (
406
+ period: . periodToken( ) ,
407
+ component: . init(
408
+ KeyPathMethodComponentSyntax (
409
+ declName: DeclReferenceExprSyntax ( baseName: . identifier( " anotherMethod " ) ) ,
410
+ leftParen: . leftParenToken( ) ,
411
+ arguments: LabeledExprListSyntax ( [
412
+ LabeledExprSyntax (
413
+ label: . identifier( " arg " ) ,
414
+ colon: . colonToken( ) ,
415
+ expression: ExprSyntax ( " 10 " )
416
+ )
417
+ ] ) ,
418
+ rightParen: . rightParenToken( )
419
+ )
420
+ )
421
+ ) ,
422
+ ] )
423
+ ) ,
424
+ experimentalFeatures: . keypathWithMethodMembers
425
+ )
426
+
427
+ assertParse (
428
+ #"\Foo.Type.init()"# ,
429
+ substructure: KeyPathExprSyntax (
430
+ root: TypeSyntax (
431
+ MetatypeTypeSyntax ( baseType: TypeSyntax ( " Foo " ) , metatypeSpecifier: . keyword( . Type) )
432
+ ) ,
433
+ components: KeyPathComponentListSyntax ( [
434
+ KeyPathComponentSyntax (
435
+ period: . periodToken( ) ,
436
+ component: KeyPathComponentSyntax . Component (
437
+ KeyPathMethodComponentSyntax (
438
+ declName: DeclReferenceExprSyntax ( baseName: . keyword( . init( " init " ) !) ) ,
439
+ leftParen: . leftParenToken( ) ,
440
+ arguments: LabeledExprListSyntax ( [ ] ) ,
441
+ rightParen: . rightParenToken( )
442
+ )
443
+ )
444
+ )
445
+ ] )
446
+ ) ,
447
+ experimentalFeatures: . keypathWithMethodMembers
448
+ )
449
+
450
+ assertParse (
451
+ #"""
452
+ \Foo.method1️⃣(2️⃣
453
+ """# ,
454
+ diagnostics: [
455
+ DiagnosticSpec (
456
+ locationMarker: " 1️⃣ " ,
457
+ message: " consecutive statements on a line must be separated by newline or ';' " ,
458
+ fixIts: [ " insert newline " , " insert ';' " ]
459
+ ) ,
460
+ DiagnosticSpec (
461
+ locationMarker: " 2️⃣ " ,
462
+ message: " expected value and ')' to end tuple " ,
463
+ fixIts: [ " insert value and ')' " ]
464
+ ) ,
465
+ ] ,
466
+ fixedSource: #"""
467
+ \Foo.method
468
+ (<#expression#>)
469
+ """# ,
470
+ experimentalFeatures: . keypathWithMethodMembers
471
+ )
472
+
473
+ assertParse (
474
+ #"\Foo.1️⃣()"# ,
475
+ diagnostics: [
476
+ DiagnosticSpec ( message: " expected identifier in key path method component " , fixIts: [ " insert identifier " ] )
477
+ ] ,
478
+ fixedSource: #"\Foo.<#identifier#>()"# ,
479
+ experimentalFeatures: . keypathWithMethodMembers
480
+ )
481
+
482
+ assertParse (
483
+ #"""
484
+ S()[keyPath: \.i] = 1
485
+ """# ,
486
+ experimentalFeatures: . keypathWithMethodMembers
487
+ )
488
+
489
+ assertParse (
490
+ #"""
491
+ public let keyPath2FromLibB = \AStruct.Type.property
492
+ """# ,
493
+ experimentalFeatures: . keypathWithMethodMembers
494
+ )
495
+
496
+ assertParse (
497
+ #"""
498
+ public let keyPath9FromLibB = \AStruct.Type.init(val: 2025)
499
+ """# ,
500
+ experimentalFeatures: . keypathWithMethodMembers
501
+ )
502
+
503
+ assertParse (
504
+ #"""
505
+ _ = ([S]()).map(\.i)
506
+ """# ,
507
+ experimentalFeatures: . keypathWithMethodMembers
508
+ )
509
+
510
+ assertParse (
511
+ #"""
512
+ let some = Some(keyPath: \Demo.here)
513
+ """# ,
514
+ experimentalFeatures: . keypathWithMethodMembers
515
+ )
516
+
517
+ assertParse (
518
+ #"""
519
+ _ = ([S.Type]()).map(\.init)
520
+ """# ,
521
+ experimentalFeatures: . keypathWithMethodMembers
522
+ )
523
+
524
+ assertParse (
525
+ #"""
526
+ \Lens<Lens<Point>>.obj.x
527
+ """# ,
528
+ experimentalFeatures: . keypathWithMethodMembers
529
+ )
530
+
531
+ assertParse (
532
+ #"""
533
+ _ = \Lens<Point>.y
534
+ """# ,
535
+ experimentalFeatures: . keypathWithMethodMembers
536
+ )
537
+
538
+ assertParse (
539
+ #"""
540
+ _ = f(\String?.!.count)
541
+ """# ,
542
+ experimentalFeatures: . keypathWithMethodMembers
543
+ )
544
+ }
545
+
259
546
func testKeyPathSubscript( ) {
260
547
assertParse (
261
548
#"\Foo.Type.[2]"# ,
0 commit comments