@@ -46,18 +46,14 @@ func isExprMigrated(_ node: ExprSyntax) -> Bool {
46
46
. discardAssignmentExpr, . declReferenceExpr, . dictionaryExpr, . doExpr,
47
47
. editorPlaceholderExpr, . floatLiteralExpr, . forceUnwrapExpr, . functionCallExpr,
48
48
. genericSpecializationExpr, . ifExpr, . infixOperatorExpr, . inOutExpr,
49
- . integerLiteralExpr, . isExpr, . macroExpansionExpr, . memberAccessExpr, . nilLiteralExpr,
49
+ . integerLiteralExpr, . isExpr, . keyPathExpr , . macroExpansionExpr, . memberAccessExpr, . nilLiteralExpr,
50
50
. optionalChainingExpr, . packElementExpr, . packExpansionExpr, . patternExpr, . postfixIfConfigExpr,
51
51
. postfixOperatorExpr, . prefixOperatorExpr, . regexLiteralExpr, . sequenceExpr,
52
52
. simpleStringLiteralExpr, . subscriptCallExpr, . stringLiteralExpr, . superExpr,
53
53
. switchExpr, . tryExpr, . tupleExpr, . typeExpr, . unresolvedAsExpr, . unresolvedIsExpr,
54
54
. unresolvedTernaryExpr, . ternaryExpr:
55
55
break
56
56
57
- // Known unimplemented kinds.
58
- case . keyPathExpr:
59
- return false
60
-
61
57
// Unknown expr kinds.
62
58
case _ where current. is ( ExprSyntax . self) :
63
59
return false
@@ -129,8 +125,8 @@ extension ASTGenVisitor {
129
125
return self . generate ( integerLiteralExpr: node) . asExpr
130
126
case . isExpr:
131
127
preconditionFailure ( " IsExprSyntax only appear after operator folding " )
132
- case . keyPathExpr:
133
- break
128
+ case . keyPathExpr( let node ) :
129
+ return self . generate ( keyPathExpr : node )
134
130
case . macroExpansionExpr( let node) :
135
131
return self . generate ( macroExpansionExpr: node) . asExpr
136
132
case . memberAccessExpr( let node) :
@@ -535,6 +531,118 @@ extension ASTGenVisitor {
535
531
)
536
532
}
537
533
534
+ func generate( keyPathComponent node: KeyPathComponentSyntax , baseExpr: BridgedExpr ) -> BridgedExpr {
535
+ switch node. component {
536
+ case . property( let prop) :
537
+ let dotLoc = self . generateSourceLoc ( node. period)
538
+ if prop. declName. baseName. presence == . missing {
539
+ return BridgedErrorExpr . create (
540
+ self . ctx,
541
+ loc: BridgedSourceRange ( start: dotLoc, end: dotLoc)
542
+ ) . asExpr
543
+ } else if prop. declName. baseName. keywordKind == . `self` {
544
+ // TODO: Diagnose if there's arguments
545
+ assert ( prop. declName. argumentNames == nil )
546
+
547
+ return BridgedDotSelfExpr . createParsed (
548
+ self . ctx,
549
+ subExpr: baseExpr,
550
+ dotLoc: dotLoc,
551
+ selfLoc: self . generateSourceLoc ( prop. declName)
552
+ ) . asExpr
553
+ } else {
554
+ let declNameRef = self . generateDeclNameRef ( declReferenceExpr: prop. declName)
555
+ return BridgedUnresolvedDotExpr . createParsed (
556
+ self . ctx,
557
+ base: baseExpr,
558
+ dotLoc: dotLoc,
559
+ name: declNameRef. name,
560
+ nameLoc: declNameRef. loc
561
+ ) . asExpr
562
+ }
563
+
564
+ case . optional( let comp) :
565
+ if comp. questionOrExclamationMark. rawText == " ! " {
566
+ return BridgedForceValueExpr . createParsed (
567
+ self . ctx,
568
+ subExpr: baseExpr,
569
+ exclaimLoc: self . generateSourceLoc ( comp. questionOrExclamationMark)
570
+ ) . asExpr
571
+ } else {
572
+ return BridgedBindOptionalExpr . createParsed (
573
+ self . ctx,
574
+ subExpr: baseExpr,
575
+ questionLoc: self . generateSourceLoc ( comp. questionOrExclamationMark)
576
+ ) . asExpr
577
+ }
578
+
579
+ case . subscript( let comp) :
580
+ return BridgedSubscriptExpr . createParsed (
581
+ self . ctx,
582
+ baseExpr: baseExpr,
583
+ args: self . generateArgumentList (
584
+ leftParen: comp. leftSquare,
585
+ labeledExprList: comp. arguments,
586
+ rightParen: comp. rightSquare,
587
+ trailingClosure: nil ,
588
+ additionalTrailingClosures: nil
589
+ )
590
+ ) . asExpr
591
+ }
592
+ }
593
+
594
+ func generate( keyPathExpr node: KeyPathExprSyntax ) -> BridgedExpr {
595
+ guard !node. components. isEmpty else {
596
+ // FIXME: Diagnostics KeyPath expression without any component.
597
+ return BridgedErrorExpr . create ( self . ctx, loc: self . generateSourceRange ( node) ) . asExpr
598
+ }
599
+
600
+ var rootExpr : BridgedExpr ?
601
+ if let parsedType = node. root, !parsedType. is ( MissingTypeSyntax . self) {
602
+ let rootType = self . generate ( type: parsedType)
603
+ rootExpr = BridgedTypeExpr . createParsed ( self . ctx, type: rootType) . asExpr
604
+ } else {
605
+ rootExpr = nil
606
+ }
607
+
608
+ var inRoot = rootExpr != nil
609
+ var pathExpr : BridgedExpr ? = nil
610
+
611
+ for component in node. components {
612
+ if inRoot {
613
+ switch component. component {
614
+ case // "root" expression is separated by '.?' or '.[idx]'
615
+ . optional( _) where component. period != nil ,
616
+ . subscript( _) where component. period != nil :
617
+ inRoot = false
618
+ default :
619
+ rootExpr = self . generate ( keyPathComponent: component, baseExpr: rootExpr!)
620
+ continue
621
+ }
622
+ }
623
+
624
+ if pathExpr == nil {
625
+ // 'KeyPathDotExpr' is a dummy base expression.
626
+ pathExpr = BridgedKeyPathDotExpr . createParsed (
627
+ self . ctx,
628
+ // Use 'component' instead of 'component.period' because period can
629
+ // be nil (e.g. '\?'), but 'loc' must be a valid location.
630
+ loc: self . generateSourceLoc ( component)
631
+ ) . asExpr
632
+ }
633
+
634
+ pathExpr = self . generate ( keyPathComponent: component, baseExpr: pathExpr!)
635
+ }
636
+
637
+ return BridgedKeyPathExpr . createParsed (
638
+ self . ctx,
639
+ backslashLoc: self . generateSourceLoc ( node. backslash) ,
640
+ parsedRoot: rootExpr. asNullable,
641
+ parsedPath: pathExpr. asNullable,
642
+ hasLeadingDot: rootExpr == nil
643
+ ) . asExpr
644
+ }
645
+
538
646
struct FreestandingMacroExpansionInfo {
539
647
var poundLoc : BridgedSourceLoc
540
648
var macroNameRef : BridgedDeclNameRef
0 commit comments