@@ -58,11 +58,11 @@ module CfgScope {
5858
5959 private class EndBlockScope extends Range_ , EndBlock {
6060 final override predicate entry ( AstNode first ) {
61- first ( this .( Trees:: EndBlockTree ) .getFirstChildNode ( ) , first )
61+ first ( this .( Trees:: EndBlockTree ) .getBodyChild ( 0 , _ ) , first )
6262 }
6363
6464 final override predicate exit ( AstNode last , Completion c ) {
65- last ( this .( Trees:: EndBlockTree ) .getLastChildNode ( ) , last , c )
65+ last ( this .( Trees:: EndBlockTree ) .getLastBodyChild ( ) , last , c )
6666 }
6767 }
6868
@@ -76,11 +76,11 @@ module CfgScope {
7676
7777 private class BraceBlockScope extends Range_ , BraceBlock {
7878 final override predicate entry ( AstNode first ) {
79- first ( this .( Trees:: BraceBlockTree ) .getFirstChildNode ( ) , first )
79+ first ( this .( Trees:: BraceBlockTree ) .getBodyChild ( 0 , _ ) , first )
8080 }
8181
8282 final override predicate exit ( AstNode last , Completion c ) {
83- last ( this .( Trees:: BraceBlockTree ) .getLastChildNode ( ) , last , c )
83+ last ( this .( Trees:: BraceBlockTree ) .getLastBodyChild ( ) , last , c )
8484 }
8585 }
8686}
@@ -308,6 +308,8 @@ module Trees {
308308 final override predicate first ( AstNode first ) { this .firstInner ( first ) }
309309
310310 final override predicate last ( AstNode last , Completion c ) { this .lastInner ( last , c ) }
311+
312+ final override predicate propagatesAbnormal ( AstNode child ) { none ( ) }
311313 }
312314
313315 private class BinaryOperationTree extends StandardPostOrderTree , BinaryOperation {
@@ -343,11 +345,9 @@ module Trees {
343345
344346 private class BlockParameterTree extends NonDefaultValueParameterTree , BlockParameter { }
345347
346- /**
347- * TODO: make all StmtSequence tree classes post-order, and simplify class
348- * hierarchy.
349- */
350348 abstract class BodyStmtTree extends StmtSequenceTree , BodyStmt {
349+ override predicate first ( AstNode first ) { first = this }
350+
351351 predicate firstInner ( AstNode first ) {
352352 first ( this .getBodyChild ( 0 , _) , first )
353353 or
@@ -528,38 +528,33 @@ module Trees {
528528 }
529529 }
530530
531- abstract class BodyStmtPreOrderTree extends BodyStmtTree , PreOrderTree {
532- final override predicate last ( AstNode last , Completion c ) {
533- this .lastInner ( last , c )
534- or
535- not exists ( this .getAChild ( _) ) and
536- last = this and
537- c .isValidFor ( this )
538- }
531+ private class BooleanLiteralTree extends LeafTree , BooleanLiteral { }
539532
540- final override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
541- BodyStmtTree .super .succ ( pred , succ , c )
533+ class BraceBlockTree extends StmtSequenceTree , BraceBlock {
534+ final override predicate propagatesAbnormal ( AstNode child ) { none ( ) }
535+
536+ final override AstNode getBodyChild ( int i , boolean rescuable ) {
537+ result = this .getParameter ( i ) and rescuable = false
542538 or
543- pred = this and
544- c instanceof SimpleCompletion and
545- this .firstInner ( succ )
539+ result = StmtSequenceTree .super .getBodyChild ( i - this .getNumberOfParameters ( ) , rescuable )
546540 }
547- }
548541
549- abstract class BodyStmtPostOrderTree extends BodyStmtTree , PostOrderTree {
550542 override predicate first ( AstNode first ) { first = this }
551- }
552-
553- private class BooleanLiteralTree extends LeafTree , BooleanLiteral { }
554543
555- class BraceBlockTree extends ScopeTree , BraceBlock {
556- final override ControlFlowTree getChildNode ( int i ) {
557- result = this .getParameter ( i )
558- or
559- result = this .getStmt ( i - this .getNumberOfParameters ( ) )
544+ override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
545+ // Normal left-to-right evaluation in the body
546+ exists ( int i |
547+ last ( this .getBodyChild ( i , _) , pred , c ) and
548+ first ( this .getBodyChild ( i + 1 , _) , succ ) and
549+ c instanceof NormalCompletion
550+ )
560551 }
561552 }
562553
554+ private class CallTree extends StandardPostOrderTree , Call {
555+ override ControlFlowTree getChildNode ( int i ) { result = this .getArgument ( i ) }
556+ }
557+
563558 private class CaseTree extends PreOrderTree , CaseExpr {
564559 final override predicate propagatesAbnormal ( AstNode child ) {
565560 child = this .getValue ( ) or child = this .getABranch ( )
@@ -603,7 +598,7 @@ module Trees {
603598
604599 private class CharacterTree extends LeafTree , CharacterLiteral { }
605600
606- private class ClassDeclarationTree extends BodyStmtPreOrderTree , ClassDeclaration {
601+ private class ClassDeclarationTree extends NamespaceTree , ClassDeclaration {
607602 /** Gets the `i`th child in the body of this block. */
608603 final override AstNode getBodyChild ( int i , boolean rescuable ) {
609604 result = this .getScopeExpr ( ) and i = 0 and rescuable = false
@@ -612,8 +607,10 @@ module Trees {
612607 i = count ( this .getScopeExpr ( ) ) and
613608 rescuable = true
614609 or
615- result = this .getStmt ( i - count ( this .getScopeExpr ( ) ) - count ( this .getSuperclassExpr ( ) ) ) and
616- rescuable = true
610+ result =
611+ super
612+ .getBodyChild ( i - count ( this .getScopeExpr ( ) ) - count ( this .getSuperclassExpr ( ) ) ,
613+ rescuable )
617614 }
618615 }
619616
@@ -749,19 +746,30 @@ module Trees {
749746 final override predicate succ ( AstNode pred , AstNode succ , Completion c ) { none ( ) }
750747 }
751748
752- private class DoBlockTree extends BodyStmtPostOrderTree , DoBlock {
749+ private class DoBlockTree extends BodyStmtTree , DoBlock {
753750 /** Gets the `i`th child in the body of this block. */
754751 final override AstNode getBodyChild ( int i , boolean rescuable ) {
755752 result = this .getParameter ( i ) and rescuable = false
756753 or
757- result = BodyStmtPostOrderTree .super .getBodyChild ( i - this .getNumberOfParameters ( ) , rescuable )
754+ result = BodyStmtTree .super .getBodyChild ( i - this .getNumberOfParameters ( ) , rescuable )
758755 }
756+
757+ override predicate propagatesAbnormal ( AstNode child ) { none ( ) }
759758 }
760759
761760 private class EmptyStatementTree extends LeafTree , EmptyStmt { }
762761
763- class EndBlockTree extends ScopeTree , EndBlock {
764- final override ControlFlowTree getChildNode ( int i ) { result = this .getStmt ( i ) }
762+ class EndBlockTree extends StmtSequenceTree , EndBlock {
763+ override predicate first ( AstNode first ) { first = this }
764+
765+ override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
766+ // Normal left-to-right evaluation in the body
767+ exists ( int i |
768+ last ( this .getBodyChild ( i , _) , pred , c ) and
769+ first ( this .getBodyChild ( i + 1 , _) , succ ) and
770+ c instanceof NormalCompletion
771+ )
772+ }
765773 }
766774
767775 private class ForInTree extends LeafTree , ForIn { }
@@ -871,12 +879,12 @@ module Trees {
871879 final override AstNode getAccessNode ( ) { result = this .getDefiningAccess ( ) }
872880 }
873881
874- private class LambdaTree extends BodyStmtPostOrderTree , Lambda {
882+ private class LambdaTree extends BodyStmtTree , Lambda {
875883 /** Gets the `i`th child in the body of this block. */
876884 final override AstNode getBodyChild ( int i , boolean rescuable ) {
877885 result = this .getParameter ( i ) and rescuable = false
878886 or
879- result = BodyStmtPostOrderTree .super .getBodyChild ( i - this .getNumberOfParameters ( ) , rescuable )
887+ result = BodyStmtTree .super .getBodyChild ( i - this .getNumberOfParameters ( ) , rescuable )
880888 }
881889 }
882890
@@ -934,33 +942,51 @@ module Trees {
934942 }
935943 }
936944
937- private class MethodCallTree extends StandardPostOrderTree , MethodCall {
945+ private class MethodCallTree extends CallTree , MethodCall {
938946 final override ControlFlowTree getChildNode ( int i ) {
939947 result = this .getReceiver ( ) and i = 0
940948 or
941- result = this .getArgument ( i - count ( this . getReceiver ( ) ) )
949+ result = this .getArgument ( i - 1 )
942950 or
943- result = this .getBlock ( ) and i = count ( this . getReceiver ( ) ) + this .getNumberOfArguments ( )
951+ result = this .getBlock ( ) and i = 1 + this .getNumberOfArguments ( )
944952 }
945953 }
946954
947955 private class MethodNameTree extends LeafTree , MethodName , ASTInternal:: TTokenMethodName { }
948956
949- private class MethodTree extends BodyStmtPostOrderTree , Method {
957+ private class MethodTree extends BodyStmtTree , Method {
958+ final override predicate propagatesAbnormal ( AstNode child ) { none ( ) }
959+
950960 /** Gets the `i`th child in the body of this block. */
951961 final override AstNode getBodyChild ( int i , boolean rescuable ) {
952962 result = this .getParameter ( i ) and rescuable = false
953963 or
954- result = BodyStmtPostOrderTree .super .getBodyChild ( i - this .getNumberOfParameters ( ) , rescuable )
964+ result = BodyStmtTree .super .getBodyChild ( i - this .getNumberOfParameters ( ) , rescuable )
955965 }
956966 }
957967
958- private class ModuleDeclarationTree extends BodyStmtPreOrderTree , ModuleDeclaration {
968+ private class ModuleDeclarationTree extends NamespaceTree , ModuleDeclaration {
959969 /** Gets the `i`th child in the body of this block. */
960970 final override AstNode getBodyChild ( int i , boolean rescuable ) {
961971 result = this .getScopeExpr ( ) and i = 0 and rescuable = false
962972 or
963- result = BodyStmtPreOrderTree .super .getBodyChild ( i - count ( this .getScopeExpr ( ) ) , rescuable )
973+ result = NamespaceTree .super .getBodyChild ( i - count ( this .getScopeExpr ( ) ) , rescuable )
974+ }
975+ }
976+
977+ private class NamespaceTree extends BodyStmtTree , Namespace {
978+ final override predicate first ( AstNode first ) {
979+ this .firstInner ( first )
980+ or
981+ not exists ( this .getAChild ( _) ) and
982+ first = this
983+ }
984+
985+ final override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
986+ BodyStmtTree .super .succ ( pred , succ , c )
987+ or
988+ succ = this and
989+ this .lastInner ( pred , c )
964990 }
965991 }
966992
@@ -1106,88 +1132,43 @@ module Trees {
11061132 SimpleParameterTreeDupUnderscore ( ) { not exists ( this .getDefiningAccess ( ) ) }
11071133 }
11081134
1109- /**
1110- * Control-flow tree for any post-order StmtSequence that doesn't have a more
1111- * specific implementation.
1112- * TODO: make all StmtSequence tree classes post-order, and simplify class
1113- * hierarchy.
1114- */
1115- private class SimplePostOrderStmtSequenceTree extends StmtSequenceTree , PostOrderTree {
1116- SimplePostOrderStmtSequenceTree ( ) {
1117- this instanceof StringInterpolationComponent or
1118- this instanceof ParenthesizedExpr
1119- }
1120-
1121- final override predicate first ( AstNode first ) { first ( this .getStmt ( 0 ) , first ) }
1122-
1123- final override predicate propagatesAbnormal ( AstNode child ) { child = this .getAStmt ( ) }
1124-
1125- final override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
1126- succ = this and
1127- last ( this .getLastBodyChild ( ) , pred , c ) and
1128- c instanceof NormalCompletion
1129- or
1130- StmtSequenceTree .super .succ ( pred , succ , c )
1131- }
1132- }
1133-
1134- /**
1135- * Control-flow tree for any pre-order StmtSequence that doesn't have a more
1136- * specific implementation.
1137- * TODO: make all StmtSequence tree classes post-order, and simplify class
1138- * hierarchy.
1139- */
1140- private class SimplePreOrderStmtSequenceTree extends StmtSequenceTree , PreOrderTree {
1141- SimplePreOrderStmtSequenceTree ( ) {
1142- not this instanceof BodyStmtTree and
1143- not this instanceof EndBlock and
1144- not this instanceof StringInterpolationComponent and
1145- not this instanceof Block and
1146- not this instanceof ParenthesizedExpr
1147- }
1148-
1149- final override predicate propagatesAbnormal ( AstNode child ) { child = this .getAStmt ( ) }
1150-
1151- final override predicate last ( AstNode last , Completion c ) {
1152- last ( this .getLastStmt ( ) , last , c )
1135+ private class SingletonClassTree extends BodyStmtTree , SingletonClass {
1136+ final override predicate first ( AstNode first ) {
1137+ this .firstInner ( first )
11531138 or
1154- not exists ( this .getLastStmt ( ) ) and
1155- c .isValidFor ( this ) and
1156- last = this
1139+ not exists ( this .getAChild ( _) ) and
1140+ first = this
11571141 }
11581142
11591143 final override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
1160- pred = this and
1161- first ( this .getBodyChild ( 0 , _) , succ ) and
1162- c instanceof SimpleCompletion
1144+ BodyStmtTree .super .succ ( pred , succ , c )
11631145 or
1164- StmtSequenceTree .super .succ ( pred , succ , c )
1146+ succ = this and
1147+ this .lastInner ( pred , c )
11651148 }
1166- }
11671149
1168- private class SingletonClassTree extends BodyStmtPreOrderTree , SingletonClass {
11691150 /** Gets the `i`th child in the body of this block. */
11701151 final override AstNode getBodyChild ( int i , boolean rescuable ) {
11711152 (
11721153 result = this .getValue ( ) and i = 0 and rescuable = false
11731154 or
1174- result = BodyStmtPreOrderTree .super .getBodyChild ( i - 1 , rescuable )
1155+ result = BodyStmtTree .super .getBodyChild ( i - 1 , rescuable )
11751156 )
11761157 }
11771158 }
11781159
1179- private class SingletonMethodTree extends BodyStmtPostOrderTree , SingletonMethod {
1160+ private class SingletonMethodTree extends BodyStmtTree , SingletonMethod {
11801161 /** Gets the `i`th child in the body of this block. */
11811162 final override AstNode getBodyChild ( int i , boolean rescuable ) {
11821163 result = this .getParameter ( i ) and rescuable = false
11831164 or
1184- result = BodyStmtPostOrderTree .super .getBodyChild ( i - this .getNumberOfParameters ( ) , rescuable )
1165+ result = BodyStmtTree .super .getBodyChild ( i - this .getNumberOfParameters ( ) , rescuable )
11851166 }
11861167
11871168 override predicate first ( AstNode first ) { first ( this .getObject ( ) , first ) }
11881169
11891170 override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
1190- BodyStmtPostOrderTree .super .succ ( pred , succ , c )
1171+ BodyStmtTree .super .succ ( pred , succ , c )
11911172 or
11921173 last ( this .getObject ( ) , pred , c ) and
11931174 succ = this and
@@ -1201,8 +1182,10 @@ module Trees {
12011182
12021183 private class SplatParameterTree extends NonDefaultValueParameterTree , SplatParameter { }
12031184
1204- abstract class StmtSequenceTree extends ControlFlowTree , StmtSequence {
1205- override predicate propagatesAbnormal ( AstNode child ) { none ( ) }
1185+ class StmtSequenceTree extends PostOrderTree , StmtSequence {
1186+ override predicate propagatesAbnormal ( AstNode child ) { child = this .getAStmt ( ) }
1187+
1188+ override predicate first ( AstNode first ) { first ( this .getStmt ( 0 ) , first ) }
12061189
12071190 /** Gets the `i`th child in the body of this body statement. */
12081191 AstNode getBodyChild ( int i , boolean rescuable ) {
@@ -1224,6 +1207,10 @@ module Trees {
12241207 first ( this .getBodyChild ( i + 1 , _) , succ ) and
12251208 c instanceof NormalCompletion
12261209 )
1210+ or
1211+ succ = this and
1212+ last ( this .getLastBodyChild ( ) , pred , c ) and
1213+ c instanceof NormalCompletion
12271214 }
12281215 }
12291216
@@ -1243,10 +1230,6 @@ module Trees {
12431230 final override ControlFlowTree getChildNode ( int i ) { result = this .getComponent ( i ) }
12441231 }
12451232
1246- private class SuperCallTree extends StandardPostOrderTree , SuperCall {
1247- final override ControlFlowTree getChildNode ( int i ) { result = this .getArgument ( i ) }
1248- }
1249-
12501233 private class ToplevelTree extends BodyStmtTree , Toplevel {
12511234 final override AstNode getBodyChild ( int i , boolean rescuable ) {
12521235 result = this .getBeginBlock ( i ) and rescuable = true
@@ -1313,11 +1296,6 @@ module Trees {
13131296 )
13141297 }
13151298 }
1316-
1317- // TODO: make post-order
1318- private class YieldCallTree extends StandardPreOrderTree , YieldCall {
1319- final override ControlFlowTree getChildNode ( int i ) { result = this .getArgument ( i ) }
1320- }
13211299}
13221300
13231301private Scope parent ( Scope n ) {
0 commit comments