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
-~----------~----~----~----~------~----~------~--~---

Reply via email to