@@ -22,6 +22,7 @@ newtype TSynthKind =
2222 BodyStmtKind ( ) or
2323 BooleanLiteralKind ( boolean value ) { value = true or value = false } or
2424 BraceBlockKind ( ) or
25+ CaseElseBranchKind ( ) or
2526 CaseMatchKind ( ) or
2627 ClassVariableAccessKind ( ClassVariable v ) or
2728 DefinedExprKind ( ) or
@@ -80,6 +81,8 @@ class SynthKind extends TSynthKind {
8081 or
8182 this = BraceBlockKind ( ) and result = "BraceBlockKind"
8283 or
84+ this = CaseElseBranchKind ( ) and result = "CaseElseBranchKind"
85+ or
8386 this = CaseMatchKind ( ) and result = "CaseMatchKind"
8487 or
8588 this = ClassVariableAccessKind ( _) and result = "ClassVariableAccessKind"
@@ -1840,7 +1843,7 @@ private module TestPatternDesugar {
18401843 or
18411844 child = SynthChild ( InClauseKind ( ) ) and i = 1
18421845 or
1843- child = SynthChild ( ElseKind ( ) ) and i = 2
1846+ child = SynthChild ( CaseElseBranchKind ( ) ) and i = 2
18441847 )
18451848 or
18461849 parent = TInClauseSynth ( case , 1 ) and
@@ -1851,7 +1854,11 @@ private module TestPatternDesugar {
18511854 child = SynthChild ( BooleanLiteralKind ( true ) ) and i = 1
18521855 )
18531856 or
1854- parent = TElseSynth ( case , 2 ) and
1857+ parent = TCaseElseBranchSynth ( case , 2 ) and
1858+ child = SynthChild ( ElseKind ( ) ) and
1859+ i = 0
1860+ or
1861+ parent = TElseSynth ( TCaseElseBranchSynth ( case , 2 ) , 0 ) and
18551862 child = SynthChild ( BooleanLiteralKind ( false ) ) and
18561863 i = 0
18571864 )
@@ -1994,3 +2001,61 @@ private module CallableBodySynthesis {
19942001 }
19952002 }
19962003}
2004+
2005+ private module CaseElseBranchSynthesis {
2006+ pragma [ nomagic]
2007+ private predicate caseElseBranchSynthesis ( AstNode parent , int i , Child child ) {
2008+ // Wrap the else branch of a real `case`/`when` expression
2009+ exists ( Ruby:: Case g , Ruby:: Else elseNode , int elseIndex |
2010+ elseNode = g .getChild ( elseIndex ) and
2011+ (
2012+ // Create the CaseElseBranch wrapper node at the else index
2013+ parent = TCaseExpr ( g ) and
2014+ child = SynthChild ( CaseElseBranchKind ( ) ) and
2015+ i = elseIndex
2016+ or
2017+ // The body of the CaseElseBranch is the Else node
2018+ parent = TCaseElseBranchSynth ( TCaseExpr ( g ) , elseIndex ) and
2019+ child = RealChildRef ( TElseReal ( elseNode ) ) and
2020+ i = 0
2021+ )
2022+ )
2023+ or
2024+ // Wrap the else branch of a real `case`/`in` expression
2025+ exists ( Ruby:: CaseMatch g , Ruby:: Else elseNode , int elseIndex |
2026+ elseNode = g .getElse ( ) and
2027+ elseIndex = count ( g .getClauses ( _) ) and
2028+ (
2029+ // Create the CaseElseBranch wrapper node at the else index
2030+ parent = TCaseMatchReal ( g ) and
2031+ child = SynthChild ( CaseElseBranchKind ( ) ) and
2032+ i = elseIndex
2033+ or
2034+ // The body of the CaseElseBranch is the Else node
2035+ parent = TCaseElseBranchSynth ( TCaseMatchReal ( g ) , elseIndex ) and
2036+ child = RealChildRef ( TElseReal ( elseNode ) ) and
2037+ i = 0
2038+ )
2039+ )
2040+ }
2041+
2042+ private class CaseElseBranchSynthesisImpl extends Synthesis {
2043+ final override predicate child ( AstNode parent , int i , Child child ) {
2044+ caseElseBranchSynthesis ( parent , i , child )
2045+ }
2046+
2047+ final override predicate location ( AstNode n , Location l ) {
2048+ // Give the CaseElseBranch the location of the underlying Else node
2049+ exists ( Ruby:: Case g , int elseIndex |
2050+ n = TCaseElseBranchSynth ( TCaseExpr ( g ) , elseIndex ) and
2051+ l = g .getChild ( elseIndex ) .getLocation ( )
2052+ )
2053+ or
2054+ exists ( Ruby:: CaseMatch g , int elseIndex |
2055+ elseIndex = count ( g .getClauses ( _) ) and
2056+ n = TCaseElseBranchSynth ( TCaseMatchReal ( g ) , elseIndex ) and
2057+ l = g .getElse ( ) .getLocation ( )
2058+ )
2059+ }
2060+ }
2061+ }
0 commit comments