28
28
import java .util .logging .Logger ;
29
29
30
30
/**
31
- * Removes dead code from a parse tree. The kinds of dead code that this pass
32
- * removes are:
33
- * - Any code following a return statement, such as the <code>alert</code>
34
- * call in: <code>if (x) { return; alert('unreachable'); }</code>.
35
- * - Statements that have no side effects, such as:
36
- * <code>a.b.MyClass.prototype.propertyName;</code> or <code>true;</code>.
37
- * That first kind of statement sometimes appears intentionally, so that
38
- * prototype properties can be annotated using JSDoc without actually
39
- * being initialized.
31
+ * Removes dead code from a parse tree.
32
+ *
33
+ * <p>The kinds of dead code that this pass removes are:
34
+ *
35
+ * <ul>
36
+ * <li>Any code following a return statement, such as the {@code alert} call in:<br>
37
+ * {@code if (x) { return; alert('unreachable'); }}.
38
+ * <li>Statements that have no side effects, such as:<br>
39
+ * {@code a.b.MyClass.prototype.propertyName;} or {@code true;}.<br>
40
+ * That first kind of statement sometimes appears intentionally, so that prototype properties
41
+ * can be annotated using JSDoc without actually being initialized.
42
+ * </ul>
40
43
*/
41
44
42
45
// TODO(dimvar): Besides dead code after returns, this pass removes useless live
45
48
// pass or putting them in some other, more related pass.
46
49
47
50
class UnreachableCodeElimination implements CompilerPass {
48
- private static final Logger logger =
49
- Logger .getLogger (UnreachableCodeElimination .class .getName ());
51
+ private static final Logger logger = Logger .getLogger (UnreachableCodeElimination .class .getName ());
50
52
private final AbstractCompiler compiler ;
51
53
private boolean codeChanged ;
52
54
@@ -120,19 +122,19 @@ public void visit(NodeTraversal t, Node n, Node parent) {
120
122
}
121
123
122
124
/**
123
- * Tries to remove n if it is an unconditional branch node (break, continue,
124
- * or return) and the target of n is the same as the follow of n.
125
- * That is, if removing n preserves the control flow. Also if n targets
126
- * another unconditional branch, this function will recursively try to
127
- * remove the target branch as well. The reason why we want to cascade this
128
- * removal is because we only run this pass once. If we have code such as
125
+ * Tries to remove n if it is an unconditional branch node (break, continue, or return) and the
126
+ * target of n is the same as the follow of n.
129
127
*
130
- * break -> break -> break
128
+ * <p>That is, if removing n preserves the control flow. Also if n targets another unconditional
129
+ * branch, this function will recursively try to remove the target branch as well. The reason
130
+ * why we want to cascade this removal is because we only run this pass once. If we have code
131
+ * such as
131
132
*
132
- * where all 3 breaks are useless, then the order of removal matters. When
133
- * we first look at the first break, we see that it branches to the 2nd
134
- * break. However, if we remove the last break, the 2nd break becomes
135
- * useless and finally the first break becomes useless as well.
133
+ * <p>break -> break -> break
134
+ *
135
+ * <p>where all 3 breaks are useless, then the order of removal matters. When we first look at
136
+ * the first break, we see that it branches to the 2nd break. However, if we remove the last
137
+ * break, the 2nd break becomes useless and finally the first break becomes useless as well.
136
138
*/
137
139
@ SuppressWarnings ("fallthrough" )
138
140
private void tryRemoveUnconditionalBranching (Node n ) {
@@ -148,7 +150,7 @@ private void tryRemoveUnconditionalBranching(Node n) {
148
150
149
151
// If n is null the target is the end of the function, nothing to do.
150
152
if (n == null ) {
151
- return ;
153
+ return ;
152
154
}
153
155
154
156
DiGraphNode <Node , Branch > gNode = cfg .getNode (n );
0 commit comments