@@ -47,15 +47,15 @@ func isExprMigrated(_ node: ExprSyntax) -> Bool {
4747 . editorPlaceholderExpr, . floatLiteralExpr, . forceUnwrapExpr, . functionCallExpr,
4848 . genericSpecializationExpr, . ifExpr, . infixOperatorExpr, . inOutExpr,
4949 . integerLiteralExpr, . isExpr, . memberAccessExpr, . nilLiteralExpr, . optionalChainingExpr,
50- . packElementExpr, . packExpansionExpr, . patternExpr,
50+ . packElementExpr, . packExpansionExpr, . patternExpr, . postfixIfConfigExpr ,
5151 . postfixOperatorExpr, . prefixOperatorExpr, . regexLiteralExpr, . sequenceExpr,
5252 . simpleStringLiteralExpr, . subscriptCallExpr, . stringLiteralExpr, . superExpr,
5353 . switchExpr, . tryExpr, . tupleExpr, . typeExpr, . unresolvedAsExpr, . unresolvedIsExpr,
5454 . unresolvedTernaryExpr, . ternaryExpr:
5555 break
5656
5757 // Known unimplemented kinds.
58- case . keyPathExpr, . macroExpansionExpr, . postfixIfConfigExpr :
58+ case . keyPathExpr, . macroExpansionExpr:
5959 return false
6060
6161 // Unknown expr kinds.
@@ -141,15 +141,14 @@ extension ASTGenVisitor {
141141 return self . generate ( nilLiteralExpr: node) . asExpr
142142 case . optionalChainingExpr( let node) :
143143 return self . generate ( optionalChainingExpr: node) . asExpr
144- break
145144 case . packElementExpr( let node) :
146145 return self . generate ( packElementExpr: node) . asExpr
147146 case . packExpansionExpr( let node) :
148147 return self . generate ( packExpansionExpr: node) . asExpr
149148 case . patternExpr( let node) :
150149 return self . generate ( patternExpr: node) . asExpr
151- case . postfixIfConfigExpr:
152- break
150+ case . postfixIfConfigExpr( let node ) :
151+ return self . generate ( postfixIfConfigExpr : node )
153152 case . postfixOperatorExpr( let node) :
154153 return self . generate ( postfixOperatorExpr: node) . asExpr
155154 case . prefixOperatorExpr( let node) :
@@ -188,6 +187,45 @@ extension ASTGenVisitor {
188187 preconditionFailure ( " isExprMigrated() mismatch " )
189188 }
190189
190+ func generate( expr node: ExprSyntax , postfixIfConfigBaseExpr: BridgedExpr ? = nil ) -> BridgedExpr {
191+ if let postfixIfConfigBaseExpr {
192+ // Generating tail part of a postfix #if expression.
193+ return self . generatePostfixIfConfigExprSuffix ( expr: node, baseExpr: postfixIfConfigBaseExpr)
194+ } else {
195+ return self . generate ( expr: node)
196+ }
197+ }
198+
199+ /// Generate function for interior of postfix #if expressions. The base expression is provided by the caller.
200+ ///
201+ /// ```
202+ /// foo // <- baseExpr
203+ /// #if FLAG
204+ /// .bar(arg)?[idx]!++ // <- node
205+ /// #endif
206+ /// ```
207+ func generatePostfixIfConfigExprSuffix( expr node: ExprSyntax , baseExpr: BridgedExpr ) -> BridgedExpr {
208+ switch node. as ( ExprSyntaxEnum . self) {
209+ case . memberAccessExpr( let node) :
210+ return self . generate ( memberAccessExpr: node, postfixIfConfigBaseExpr: baseExpr)
211+ case . postfixIfConfigExpr( let node) :
212+ return self . generate ( postfixIfConfigExpr: node, postfixIfConfigBaseExpr: baseExpr)
213+ case . functionCallExpr( let node) :
214+ return self . generate ( functionCallExpr: node, postfixIfConfigBaseExpr: baseExpr) . asExpr
215+ case . subscriptCallExpr( let node) :
216+ return self . generate ( subscriptCallExpr: node, postfixIfConfigBaseExpr: baseExpr) . asExpr
217+ case . postfixOperatorExpr( let node) :
218+ return self . generate ( postfixOperatorExpr: node, postfixIfConfigBaseExpr: baseExpr) . asExpr
219+ case . optionalChainingExpr( let node) :
220+ return self . generate ( optionalChainingExpr: node, postfixIfConfigBaseExpr: baseExpr) . asExpr
221+ case . forceUnwrapExpr( let node) :
222+ return self . generate ( forceUnwrapExpr: node, postfixIfConfigBaseExpr: baseExpr) . asExpr
223+ default :
224+ // FIXME: Diagnose 'invalid expression for a postfix #if expression'
225+ preconditionFailure ( " expected postfix expression suffix in #if expression clause " )
226+ }
227+ }
228+
191229 func generate( arrowExpr node: ArrowExprSyntax ) -> BridgedArrowExpr {
192230 let asyncLoc : BridgedSourceLoc
193231 let throwsLoc : BridgedSourceLoc
@@ -292,10 +330,10 @@ extension ASTGenVisitor {
292330 )
293331 }
294332
295- func generate( forceUnwrapExpr node: ForceUnwrapExprSyntax ) -> BridgedForceValueExpr {
333+ func generate( forceUnwrapExpr node: ForceUnwrapExprSyntax , postfixIfConfigBaseExpr : BridgedExpr ? = nil ) -> BridgedForceValueExpr {
296334 return . createParsed(
297335 self . ctx,
298- subExpr: self . generate ( expr: node. expression) ,
336+ subExpr: self . generate ( expr: node. expression, postfixIfConfigBaseExpr : postfixIfConfigBaseExpr ) ,
299337 exclaimLoc: self . generateSourceLoc ( node. exclamationMark)
300338 )
301339 }
@@ -365,7 +403,7 @@ extension ASTGenVisitor {
365403 )
366404 }
367405
368- func generate( functionCallExpr node: FunctionCallExprSyntax ) -> BridgedCallExpr {
406+ func generate( functionCallExpr node: FunctionCallExprSyntax , postfixIfConfigBaseExpr : BridgedExpr ? = nil ) -> BridgedCallExpr {
369407 if !node. arguments. isEmpty || node. trailingClosure == nil {
370408 if node. leftParen == nil {
371409 self . diagnose (
@@ -379,7 +417,7 @@ extension ASTGenVisitor {
379417 }
380418 }
381419
382- let callee = generate ( expr: node. calledExpression)
420+ let callee = self . generate ( expr: node. calledExpression, postfixIfConfigBaseExpr : postfixIfConfigBaseExpr )
383421 let arguments = generateArgumentList (
384422 leftParen: node. leftParen,
385423 labeledExprList: node. arguments,
@@ -497,25 +535,40 @@ extension ASTGenVisitor {
497535 )
498536 }
499537
500- func generate( memberAccessExpr node: MemberAccessExprSyntax ) -> BridgedExpr {
538+ func generate( memberAccessExpr node: MemberAccessExprSyntax , postfixIfConfigBaseExpr: BridgedExpr ? = nil ) -> BridgedExpr {
539+ let baseExpr : BridgedExpr ?
540+ if let base = node. base {
541+ baseExpr = self . generate ( expr: base, postfixIfConfigBaseExpr: postfixIfConfigBaseExpr)
542+ } else if let postfixIfConfigBaseExpr {
543+ // Dot member syntax right after '#if' line. E.g.
544+ // foo // <- postfixIfConfigBaseExpr
545+ // #if FLAG
546+ // .bar // <- Generating this.
547+ // .baz
548+ // #endif
549+ baseExpr = postfixIfConfigBaseExpr
550+ } else {
551+ baseExpr = nil
552+ }
553+
501554 let dotLoc = self . generateSourceLoc ( node. period)
502555 let nameAndLoc = generateDeclNameRef ( declReferenceExpr: node. declName)
503556
504- if let base = node . base {
557+ if let baseExpr {
505558 if node. declName. baseName. keywordKind == . `self` {
506559 // TODO: Diagnose if there's arguments
507560 assert ( node. declName. argumentNames == nil )
508561
509562 return BridgedDotSelfExpr . createParsed (
510563 self . ctx,
511- subExpr: self . generate ( expr : base ) ,
564+ subExpr: baseExpr ,
512565 dotLoc: dotLoc,
513566 selfLoc: self . generateSourceLoc ( node. declName)
514567 ) . asExpr
515568 } else {
516569 return BridgedUnresolvedDotExpr . createParsed (
517570 self . ctx,
518- base: self . generate ( expr : base ) ,
571+ base: baseExpr ,
519572 dotLoc: dotLoc,
520573 name: nameAndLoc. name,
521574 nameLoc: nameAndLoc. loc
@@ -548,10 +601,10 @@ extension ASTGenVisitor {
548601 )
549602 }
550603
551- func generate( optionalChainingExpr node: OptionalChainingExprSyntax ) -> BridgedBindOptionalExpr {
604+ func generate( optionalChainingExpr node: OptionalChainingExprSyntax , postfixIfConfigBaseExpr : BridgedExpr ? = nil ) -> BridgedBindOptionalExpr {
552605 return . createParsed(
553606 self . ctx,
554- subExpr: self . generate ( expr: node. expression) ,
607+ subExpr: self . generate ( expr: node. expression, postfixIfConfigBaseExpr : postfixIfConfigBaseExpr ) ,
555608 questionLoc: self . generateSourceLoc ( node. questionMark)
556609 )
557610 }
@@ -600,14 +653,46 @@ extension ASTGenVisitor {
600653 )
601654 }
602655
603- func generate( postfixOperatorExpr node: PostfixOperatorExprSyntax ) -> BridgedPostfixUnaryExpr {
656+ func generate( postfixIfConfigExpr node: PostfixIfConfigExprSyntax , postfixIfConfigBaseExpr: BridgedExpr ? = nil ) -> BridgedExpr {
657+ let baseExpr : BridgedExpr
658+ if let base = node. base {
659+ baseExpr = self . generate ( expr: base, postfixIfConfigBaseExpr: postfixIfConfigBaseExpr)
660+ } else if let postfixIfConfigBaseExpr {
661+ // This is a nested postifx #if expression. E.g.
662+ //
663+ // foo // <- postfixIfConfigBaseExpr
664+ // #if FLAG
665+ // #if FLAG2 // <- This
666+ // .bar
667+ // #endif
668+ // .baz
669+ // #endif
670+ //
671+ baseExpr = postfixIfConfigBaseExpr
672+ } else {
673+ // FIXME: Diagnostics
674+ preconditionFailure ( " expected PostfixIfConfigExprSyntax.base not nil " )
675+ }
676+
677+ guard let active = self . activeClause ( in: node. config) else {
678+ return baseExpr
679+ }
680+ guard case . postfixExpression( let parsedTail) = active. elements else {
681+ // FIXME: Diagnostics
682+ preconditionFailure ( " expected postfixExpression in IfConfigClauseSyntax.Elements " )
683+ }
684+ return self . generatePostfixIfConfigExprSuffix ( expr: parsedTail, baseExpr: baseExpr)
685+ }
686+
687+ func generate( postfixOperatorExpr node: PostfixOperatorExprSyntax , postfixIfConfigBaseExpr: BridgedExpr ? = nil ) -> BridgedPostfixUnaryExpr {
688+ let operand = self . generate ( expr: node. expression, postfixIfConfigBaseExpr: postfixIfConfigBaseExpr)
604689 return . createParsed(
605690 self . ctx,
606691 operator: self . createOperatorRefExpr (
607692 token: node. operator,
608693 kind: . postfixOperator
609694 ) . asExpr,
610- operand: self . generate ( expr : node . expression )
695+ operand: operand
611696 )
612697 }
613698
@@ -691,8 +776,8 @@ extension ASTGenVisitor {
691776 ) . asExpr
692777 }
693778
694- func generate( subscriptCallExpr node: SubscriptCallExprSyntax ) -> BridgedSubscriptExpr {
695- let callee = generate ( expr: node. calledExpression)
779+ func generate( subscriptCallExpr node: SubscriptCallExprSyntax , postfixIfConfigBaseExpr : BridgedExpr ? = nil ) -> BridgedSubscriptExpr {
780+ let callee = generate ( expr: node. calledExpression, postfixIfConfigBaseExpr : postfixIfConfigBaseExpr )
696781 let arguments = generateArgumentList (
697782 leftParen: node. leftSquare,
698783 labeledExprList: node. arguments,
0 commit comments