Author: [email protected]
Date: Mon Jun 15 17:51:24 2009
New Revision: 5561
Modified:
trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JIfStatement.java
trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
trunk/user/test/com/google/gwt/dev/jjs/test/CompilerTest.java
Log:
GenerateJavaAST no longer visits code in a block that
follows an if(true) block that itself contains a
throw, a return, or any other unconditional break
in control flow. This prevents the compiler from
becoming confused when it wanders into parts of the
JDT AST that the JDT compile did not fill all the way in.
Review by: scottb
Modified: trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JIfStatement.java
==============================================================================
--- trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JIfStatement.java
(original)
+++ trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JIfStatement.java Mon Jun
15 17:51:24 2009
@@ -61,8 +61,22 @@
@Override
public boolean unconditionalControlBreak() {
- if (thenStmt != null && thenStmt.unconditionalControlBreak()
- && elseStmt != null && elseStmt.unconditionalControlBreak()) {
+ boolean thenBreaks = thenStmt != null
+ && thenStmt.unconditionalControlBreak();
+ if (thenBreaks && ifExpr == JBooleanLiteral.get(true)) {
+ // if(true) { /* unconditional break */ }
+ return true;
+ }
+
+ boolean elseBreaks = elseStmt != null
+ && elseStmt.unconditionalControlBreak();
+ if (elseBreaks && ifExpr == JBooleanLiteral.get(false)) {
+ // if(false) { } else { /* unconditional break */ }
+ return true;
+ }
+
+ if (thenBreaks && elseBreaks) {
+ // both branches have an unconditional break
return true;
}
return false;
Modified:
trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
==============================================================================
--- trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
(original)
+++ trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java Mon
Jun 15 17:51:24 2009
@@ -728,15 +728,7 @@
}
// user code (finally!)
- if (x.statements != null) {
- for (int i = 0, n = x.statements.length; i < n; ++i) {
- Statement origStmt = x.statements[i];
- JStatement jstmt = dispProcessStatement(origStmt);
- if (jstmt != null) {
- block.addStmt(jstmt);
- }
- }
- }
+ block.addStmts(processStatements(x.statements));
currentMethodScope = null;
currentMethod = null;
@@ -1473,14 +1465,8 @@
currentMethodBody = (JMethodBody) method.getBody();
currentMethodScope = x.scope;
- if (x.statements != null) {
- for (int i = 0, n = x.statements.length; i < n; ++i) {
- Statement origStmt = x.statements[i];
- JStatement jstmt = dispProcessStatement(origStmt);
- if (jstmt != null) {
- currentMethodBody.getBlock().addStmt(jstmt);
- }
- }
+ if (currentMethodBody != null) {
+
currentMethodBody.getBlock().addStmts(processStatements(x.statements));
}
currentMethodScope = null;
currentMethodBody = null;
@@ -1510,14 +1496,7 @@
SourceInfo info = makeSourceInfo(x);
JBlock block = new JBlock(info);
- if (x.statements != null) {
- for (int i = 0, n = x.statements.length; i < n; ++i) {
- JStatement jstmt = dispProcessStatement(x.statements[i]);
- if (jstmt != null) {
- block.addStmt(jstmt);
- }
- }
- }
+ block.addStmts(processStatements(x.statements));
return block;
}
@@ -1767,7 +1746,15 @@
program.getIndexedMethod("Enum.ordinal"));
}
JBlock block = new JBlock(info);
- block.addStmts(processStatements(x.statements));
+ // Don't use processStatements here, because it stops at control
breaks
+ if (x.statements != null) {
+ for (Statement stmt : x.statements) {
+ JStatement jstmt = dispProcessStatement(stmt);
+ if (jstmt != null) {
+ block.addStmt(jstmt);
+ }
+ }
+ }
return new JSwitchStatement(info, expression, block);
}
@@ -1824,13 +1811,22 @@
List<JStatement> processStatements(Statement[] statements) {
List<JStatement> jstatements = new ArrayList<JStatement>();
if (statements != null) {
- for (int i = 0, n = statements.length; i < n; ++i) {
- JStatement jstmt = dispProcessStatement(statements[i]);
+ for (Statement stmt : statements) {
+ JStatement jstmt = dispProcessStatement(stmt);
if (jstmt != null) {
jstatements.add(jstmt);
+ if (jstmt.unconditionalControlBreak()) {
+ /*
+ * Stop processing statements, because the remaining ones are
+ * unreachable. The JDT compiler might not have fully
fleshed out
+ * the unreachable statements.
+ */
+ break;
+ }
}
}
}
+
return jstatements;
}
Modified: trunk/user/test/com/google/gwt/dev/jjs/test/CompilerTest.java
==============================================================================
--- trunk/user/test/com/google/gwt/dev/jjs/test/CompilerTest.java
(original)
+++ trunk/user/test/com/google/gwt/dev/jjs/test/CompilerTest.java Mon Jun
15 17:51:24 2009
@@ -557,6 +557,33 @@
assertFalse(e);
}
+ /**
+ * Test that code considered unreachable by the JDT does not crash the
GWT
+ * compiler.
+ */
+ public void testDeadCode2() {
+ class SillyList {
+ }
+
+ final SillyList outerLocalVariable = new SillyList();
+
+ new SillyList() {
+ private void pretendToUse(SillyList x) {
+ }
+
+ void blah() {
+ if (true) {
+ throw new RuntimeException();
+ }
+ /*
+ * This code is unreachable, and so outerLocalVariable is never
actually
+ * read by reachable code.
+ */
+ pretendToUse(outerLocalVariable);
+ }
+ };
+ }
+
public void testDeadTypes() {
if (false) {
new Object() {
--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---