@@ -75,8 +75,10 @@ predicate succExit(CfgScope scope, Ast last, Completion c) { scope.exit(last, c)
75
75
76
76
/** Defines the CFG by dispatch on the various AST types. */
77
77
module Trees {
78
- class ScriptBlockTree extends PreOrderTree instanceof ScriptBlock {
79
- final override predicate last ( AstNode last , Completion c ) {
78
+ abstract class ScriptBlockTree extends ControlFlowTree instanceof ScriptBlock {
79
+ abstract predicate succEntry ( AstNode n , Completion c ) ;
80
+
81
+ override predicate last ( AstNode last , Completion c ) {
80
82
last ( super .getEndBlock ( ) , last , c )
81
83
or
82
84
not exists ( super .getEndBlock ( ) ) and
@@ -89,43 +91,58 @@ module Trees {
89
91
not exists ( super .getEndBlock ( ) ) and
90
92
not exists ( super .getProcessBlock ( ) ) and
91
93
not exists ( super .getBeginBlock ( ) ) and
92
- last = this and
93
- completionIsSimple ( c )
94
- }
95
-
96
- final override predicate propagatesAbnormal ( AstNode child ) {
97
- child = [ super .getBeginBlock ( ) , super .getProcessBlock ( ) , super .getEndBlock ( ) ]
94
+ last ( super .getParamBlock ( ) , last , c )
95
+ or
96
+ not exists ( super .getEndBlock ( ) ) and
97
+ not exists ( super .getProcessBlock ( ) ) and
98
+ not exists ( super .getBeginBlock ( ) ) and
99
+ not exists ( super .getParamBlock ( ) ) and
100
+ // No blocks at all. We end where we started
101
+ this .succEntry ( last , c )
98
102
}
99
103
100
- final override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
101
- pred = this and
104
+ override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
105
+ this . succEntry ( pred , c ) and
102
106
(
107
+ first ( super .getParamBlock ( ) , succ )
108
+ or
109
+ not exists ( super .getParamBlock ( ) ) and
103
110
first ( super .getBeginBlock ( ) , succ )
104
111
or
112
+ not exists ( super .getParamBlock ( ) ) and
105
113
not exists ( super .getBeginBlock ( ) ) and
106
114
first ( super .getProcessBlock ( ) , succ )
107
115
or
116
+ not exists ( super .getParamBlock ( ) ) and
108
117
not exists ( super .getBeginBlock ( ) ) and
109
118
not exists ( super .getProcessBlock ( ) ) and
110
119
first ( super .getEndBlock ( ) , succ )
111
- ) and
112
- completionIsSimple ( c )
120
+ )
113
121
or
114
- last ( super .getBeginBlock ( ) , pred , c ) and
115
- c instanceof NormalCompletion and
122
+ last ( super .getParamBlock ( ) , pred , c ) and
123
+ completionIsNormal ( c ) and
116
124
(
125
+ first ( super .getBeginBlock ( ) , succ )
126
+ or
127
+ not exists ( super .getBeginBlock ( ) ) and
117
128
first ( super .getProcessBlock ( ) , succ )
118
129
or
130
+ not exists ( super .getBeginBlock ( ) ) and
119
131
not exists ( super .getProcessBlock ( ) ) and
120
132
first ( super .getEndBlock ( ) , succ )
133
+ )
134
+ or
135
+ last ( super .getBeginBlock ( ) , pred , c ) and
136
+ completionIsNormal ( c ) and
137
+ (
138
+ first ( super .getProcessBlock ( ) , succ )
121
139
or
122
140
not exists ( super .getProcessBlock ( ) ) and
123
- not exists ( super .getEndBlock ( ) ) and
124
- succ = this
141
+ first ( super .getEndBlock ( ) , succ )
125
142
)
126
143
or
127
144
last ( super .getProcessBlock ( ) , pred , c ) and
128
- c instanceof NormalCompletion and
145
+ completionIsNormal ( c ) and
129
146
(
130
147
// If we process multiple items we will loop back to the process block
131
148
first ( super .getProcessBlock ( ) , succ )
@@ -134,6 +151,19 @@ module Trees {
134
151
first ( super .getEndBlock ( ) , succ )
135
152
)
136
153
}
154
+
155
+ final override predicate propagatesAbnormal ( AstNode child ) {
156
+ child = super .getParamBlock ( ) or
157
+ child = super .getBeginBlock ( ) or
158
+ child = super .getProcessBlock ( ) or
159
+ child = super .getEndBlock ( )
160
+ }
161
+ }
162
+
163
+ class TopLevelScriptBlockTree extends PreOrderTree , ScriptBlockTree {
164
+ TopLevelScriptBlockTree ( ) { this .( ScriptBlock ) .isTopLevel ( ) }
165
+
166
+ final override predicate succEntry ( Ast n , Completion c ) { n = this and completionIsSimple ( c ) }
137
167
}
138
168
139
169
class NamedBlockTree extends StandardPostOrderTree instanceof NamedBlock {
0 commit comments