@@ -226,16 +226,6 @@ signature module AstSig<LocationSig Location> {
226226 Case getCase ( int index ) ;
227227 }
228228
229- /**
230- * Gets an integer indicating the control flow order of a case within a switch.
231- * This is most often the same as the AST order, but can be different in some
232- * languages if the language allows a default case to appear before other
233- * cases.
234- *
235- * The values do not need to be contiguous; only the relative ordering matters.
236- */
237- default int getCaseControlFlowOrder ( Switch s , Case c ) { s .getCase ( result ) = c }
238-
239229 /** A case in a switch. */
240230 class Case extends AstNode {
241231 /** Gets a pattern being matched by this case. */
@@ -253,6 +243,8 @@ signature module AstSig<LocationSig Location> {
253243 AstNode getBodyElement ( int index ) ;
254244 }
255245
246+ class DefaultCase extends Case ;
247+
256248 /**
257249 * Holds if this case can fall through to the next case if it is not
258250 * otherwise prevented with a `break` or similar.
@@ -938,7 +930,7 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
938930 *
939931 * A match-all case can still ultimately fail to match if it has a guard.
940932 */
941- default predicate matchAll ( Case c ) { none ( ) }
933+ default predicate matchAll ( Case c ) { c instanceof DefaultCase }
942934
943935 /**
944936 * Holds if `ast` may result in an abrupt completion `c` originating at
@@ -1096,6 +1088,21 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
10961088 )
10971089 }
10981090
1091+ /**
1092+ * Gets an integer indicating the control flow order of a case within a
1093+ * switch. This is equal to the AST order, except that default cases are
1094+ * always last in control flow order, even if some languages allow them
1095+ * to appear before other cases in the AST.
1096+ */
1097+ private int getCaseControlFlowOrder ( Switch s , Case c ) {
1098+ exists ( int pos | s .getCase ( pos ) = c |
1099+ // if a default case is not last in the AST, move it last in the CFG order
1100+ if c instanceof DefaultCase and exists ( s .getCase ( pos + 1 ) )
1101+ then result = strictcount ( s .getCase ( _) )
1102+ else result = pos
1103+ )
1104+ }
1105+
10991106 private Case getRankedCaseCfgOrder ( Switch s , int rnk ) {
11001107 result = rank [ rnk ] ( Case c , int i | getCaseControlFlowOrder ( s , c ) = i | c order by i )
11011108 }
0 commit comments