Revision: 10312
Author:   sco...@google.com
Date:     Thu Jun  9 11:46:19 2011
Log:      JavaAstConstructor uses UnifyAst.

http://gwt-code-reviews.appspot.com/1453810/

http://code.google.com/p/google-web-toolkit/source/detail?r=10312

Added:
 /trunk/dev/core/src/com/google/gwt/dev/jjs/AstConstructor.java
Modified:
 /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncs.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java
 /trunk/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java
 /trunk/dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java

=======================================
--- /dev/null
+++ /trunk/dev/core/src/com/google/gwt/dev/jjs/AstConstructor.java Thu Jun 9 11:46:19 2011
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.jjs;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.dev.javac.CompilationState;
+import com.google.gwt.dev.javac.StandardGeneratorContext;
+import com.google.gwt.dev.jdt.RebindPermutationOracle;
+import com.google.gwt.dev.jjs.CorrelationFactory.DummyCorrelationFactory;
+import com.google.gwt.dev.jjs.ast.JProgram;
+import com.google.gwt.dev.jjs.impl.AssertionNormalizer;
+import com.google.gwt.dev.jjs.impl.AssertionRemover;
+import com.google.gwt.dev.jjs.impl.FixAssignmentToUnbox;
+import com.google.gwt.dev.jjs.impl.GwtAstBuilder;
+import com.google.gwt.dev.jjs.impl.ImplementClassLiteralsAsFields;
+import com.google.gwt.dev.jjs.impl.ReplaceRunAsyncs;
+import com.google.gwt.dev.jjs.impl.UnifyAst;
+import com.google.gwt.dev.js.ast.JsProgram;
+
+/**
+ * Constructs a full Java AST from source.
+ */
+public class AstConstructor {
+
+  /**
+ * Construct an simple AST representing an entire {@link CompilationState}.
+   * Does not support deferred binding. Implementation mostly copied from
+   * {@link JavaToJavaScriptCompiler}.
+   */
+ public static JProgram construct(TreeLogger logger, final CompilationState state,
+      JJSOptions options) throws UnableToCompleteException {
+
+    InternalCompilerException.preload();
+
+    RebindPermutationOracle rpo = new RebindPermutationOracle() {
+      @Override
+      public void clear() {
+      }
+
+      @Override
+ public String[] getAllPossibleRebindAnswers(TreeLogger logger, String sourceTypeName)
+          throws UnableToCompleteException {
+        return new String[0];
+      }
+
+      public CompilationState getCompilationState() {
+        return state;
+      }
+
+      public StandardGeneratorContext getGeneratorContext() {
+        return null;
+      }
+    };
+
+    JProgram jprogram = new JProgram(DummyCorrelationFactory.INSTANCE);
+    JsProgram jsProgram = new JsProgram(DummyCorrelationFactory.INSTANCE);
+    assert GwtAstBuilder.ENABLED;
+    UnifyAst unifyAst = new UnifyAst(jprogram, jsProgram, options, rpo);
+    unifyAst.buildEverything(logger);
+
+    // Compute all super type/sub type info
+    jprogram.typeOracle.computeBeforeAST();
+
+    // (3) Perform Java AST normalizations.
+    FixAssignmentToUnbox.exec(jprogram);
+
+    /*
+ * TODO: If we defer this until later, we could maybe use the results of the
+     * assertions to enable more optimizations.
+     */
+    if (options.isEnableAssertions()) {
+      // Turn into assertion checking calls.
+      AssertionNormalizer.exec(jprogram);
+    } else {
+      // Remove all assert statements.
+      AssertionRemover.exec(jprogram);
+    }
+
+    if (options.isRunAsyncEnabled()) {
+      ReplaceRunAsyncs.exec(logger, jprogram);
+    }
+
+    ImplementClassLiteralsAsFields.exec(jprogram);
+    return jprogram;
+  }
+}
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java Tue Jun 7 11:03:06 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java Thu Jun 9 11:46:19 2011
@@ -2901,6 +2901,13 @@

     return result;
   }
+
+  SourceInfo makeSourceInfo(AbstractMethodDeclaration x) {
+    int startLine =
+        Util.getLineNumber(x.sourceStart, curCud.separatorPositions, 0,
+            curCud.separatorPositions.length - 1);
+ return SourceOrigin.create(x.sourceStart, x.bodyEnd, startLine, curCud.fileName);
+  }

   SourceInfo makeSourceInfo(ASTNode x) {
     int startLine =
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncs.java Wed Jun 8 16:12:42 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRunAsyncs.java Thu Jun 9 11:46:19 2011
@@ -37,6 +37,7 @@
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;

 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -172,9 +173,14 @@
         }
         if (matches.size() > 1) {
TreeLogger branch = error(info, "Multiple runAsync calls are named " + name);
+          List<String> errors = new ArrayList<String>();
           for (JRunAsync match : matches) {
- branch.log(TreeLogger.ERROR, "One call is at '" + match.getSourceInfo().getFileName()
-                + ':' + match.getSourceInfo().getStartLine() + "'");
+ errors.add("One call is at '" + match.getSourceInfo().getFileName() + ':'
+                + match.getSourceInfo().getStartLine() + "'");
+          }
+          Collections.sort(errors);
+          for (String error : errors) {
+            branch.log(TreeLogger.ERROR, error);
           }
           return;
         }
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java Fri Jun 3 15:55:09 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/UnifyAst.java Thu Jun 9 11:46:19 2011
@@ -71,6 +71,7 @@
 import com.google.gwt.dev.js.ast.JsRootScope;
 import com.google.gwt.dev.util.JsniRef;
 import com.google.gwt.dev.util.Name.BinaryName;
+import com.google.gwt.dev.util.Name.InternalName;
 import com.google.gwt.dev.util.collect.IdentityHashSet;
 import com.google.gwt.dev.util.collect.Lists;

@@ -461,6 +462,7 @@
       CLASS_IS_CLASS_METADATA_ENABLED));

   private final Map<String, CompiledClass> classFileMap;
+  private boolean errorsFound = false;
private final Map<String, JField> fieldMap = new HashMap<String, JField>();

   /**
@@ -521,8 +523,42 @@
     }
   }

-  public void exec(TreeLogger logger) {
+  /**
+   * Special AST construction, useful for tests. Everything is resolved,
+   * translated, and unified.
+   */
+ public void buildEverything(TreeLogger logger) throws UnableToCompleteException {
     this.logger = logger;
+    for (String internalName : classFileMap.keySet()) {
+      String typeName = InternalName.toBinaryName(internalName);
+      searchForType(typeName);
+    }
+
+    for (JDeclaredType type : program.getDeclaredTypes()) {
+      instantiate(type);
+      for (JField field : type.getFields()) {
+        flowInto(field);
+      }
+      for (JMethod method : type.getMethods()) {
+        flowInto(method);
+      }
+    }
+
+    mainLoop();
+
+    computeOverrides();
+    if (errorsFound) {
+      throw new UnableToCompleteException();
+    }
+  }
+
+  /**
+   * For normal compilation, only translate and stitch types reachable from
+   * entry points. This reduces memory and improves compile speed. Any
+   * unreachable elements are pruned.
+   */
+  public void exec(TreeLogger logger) throws UnableToCompleteException {
+    this.logger = logger;

     // Trace execution from entry points.
     for (JMethod entryMethod : program.getEntryMethods()) {
@@ -577,14 +613,7 @@
       }
     }

-    /*
- * Main loop: run through the queue doing deferred resolution. We could have - * made this entirely recursive, but a work queues uses much less max stack.
-     */
-    UnifyVisitor visitor = new UnifyVisitor();
-    while (!todo.isEmpty()) {
-      visitor.accept(todo.poll());
-    }
+    mainLoop();

     // Post-stitching clean-ups.

@@ -614,21 +643,9 @@
       }
     }

-    // Compute overrides.
-    for (JDeclaredType type : program.getDeclaredTypes()) {
- Map<String, Set<JMethod>> collected = new HashMap<String, Set<JMethod>>();
-      for (JMethod method : type.getMethods()) {
-        if (method.canBePolymorphic()) {
- collected.put(method.getSignature(), new LinkedHashSet<JMethod>());
-        }
-      }
-      collectUpRefsInSupers(type, collected);
-      for (JMethod method : type.getMethods()) {
-        if (method.canBePolymorphic()) {
-          Set<JMethod> uprefs = collected.get(method.getSignature());
-          method.addOverrides(Lists.create(uprefs));
-        }
-      }
+    computeOverrides();
+    if (errorsFound) {
+      throw new UnableToCompleteException();
     }
   }

@@ -673,17 +690,49 @@
       collectUpRefs(intfType, collected);
     }
   }
+
+  /**
+   * Compute all overrides.
+   */
+  private void computeOverrides() {
+    for (JDeclaredType type : program.getDeclaredTypes()) {
+ Map<String, Set<JMethod>> collected = new HashMap<String, Set<JMethod>>();
+      for (JMethod method : type.getMethods()) {
+        if (method.canBePolymorphic()) {
+ collected.put(method.getSignature(), new LinkedHashSet<JMethod>());
+        }
+      }
+      collectUpRefsInSupers(type, collected);
+      for (JMethod method : type.getMethods()) {
+        if (method.canBePolymorphic()) {
+          Set<JMethod> uprefs = collected.get(method.getSignature());
+          method.addOverrides(Lists.create(uprefs));
+        }
+      }
+    }
+  }

   private void error(JNode x, String errorMessage) {
-    // TODO: logging.
-    throw new InternalCompilerException(x, errorMessage, null);
+    errorsFound = true;
+    TreeLogger branch =
+        logger
+ .branch(TreeLogger.ERROR, "Errors in '" + x.getSourceInfo().getFileName() + "'", null);
+    // Append 'Line #: msg' to the error message.
+    StringBuffer msgBuf = new StringBuffer();
+    int line = x.getSourceInfo().getStartLine();
+    if (line > 0) {
+      msgBuf.append("Line ");
+      msgBuf.append(line);
+      msgBuf.append(": ");
+    }
+    msgBuf.append(errorMessage);
+    branch.log(TreeLogger.ERROR, msgBuf.toString());
   }

   private void flowInto(JField field) {
-    if (field == JField.NULL_FIELD) {
+    if (field == JField.NULL_FIELD || field.isExternal()) {
       return;
     }
-    assert !field.isExternal();
     if (!liveFieldsAndMethods.contains(field)) {
       liveFieldsAndMethods.add(field);
       field.setType(translate(field.getType()));
@@ -694,10 +743,9 @@
   }

   private void flowInto(JMethod method) {
-    if (method == JMethod.NULL_METHOD) {
+    if (method == JMethod.NULL_METHOD || method.isExternal()) {
       return;
     }
-    assert !method.isExternal();
     if (!liveFieldsAndMethods.contains(method)) {
       liveFieldsAndMethods.add(method);
       JType originalReturnType = translate(method.getOriginalReturnType());
@@ -784,6 +832,17 @@
     }
return type == program.getJavaScriptObject() || isJso(type.getSuperClass());
   }
+
+  /**
+ * Main loop: run through the queue doing deferred resolution. We could have + * made this entirely recursive, but a work queue uses much less max stack.
+   */
+  private void mainLoop() {
+    UnifyVisitor visitor = new UnifyVisitor();
+    while (!todo.isEmpty()) {
+      visitor.accept(todo.poll());
+    }
+  }

   private void mapApi(JDeclaredType type) {
     assert !type.isExternal();
@@ -888,47 +947,75 @@
   }

   private JDeclaredType translate(JDeclaredType type) {
-    if (type.isExternal()) {
-      String typeName = type.getName();
-      type = searchForType(typeName);
-    }
-    assert !type.isExternal();
+    if (!type.isExternal()) {
+      return type;
+    }
+
+    String typeName = type.getName();
+    JDeclaredType newType = searchForType(typeName);
+    if (newType != null) {
+      assert !newType.isExternal();
+      return newType;
+    }
+    // Error condition, should be logged.
+    errorsFound = true;
     return type;
   }

   private JField translate(JField field) {
-    if (field.isExternal()) {
-      JDeclaredType enclosingType = field.getEnclosingType();
-      String sig = enclosingType.getName() + '.' + field.getSignature();
-      field = fieldMap.get(sig);
-      if (field == null) {
-        mapApi(translate(enclosingType));
-        // Now the field should be there.
-        field = fieldMap.get(sig);
-        if (field == null) {
-          // TODO: error logging
-          throw new NoSuchFieldError(sig);
-        }
-      }
-    }
+    if (!field.isExternal()) {
+      return field;
+    }
+
+    JDeclaredType enclosingType = field.getEnclosingType();
+    String sig = enclosingType.getName() + '.' + field.getSignature();
+    JField newField = fieldMap.get(sig);
+    if (newField != null) {
+      return newField;
+    }
+
+    enclosingType = translate(enclosingType);
+    if (enclosingType.isExternal()) {
+      // Error condition, should be logged.
+      return field;
+    }
+    mapApi(enclosingType);
+
+    // Now the field should be there.
+    field = fieldMap.get(sig);
+    if (field == null) {
+      // TODO: error logging
+      throw new NoSuchFieldError(sig);
+    }
+
     assert !field.isExternal();
     return field;
   }

   private JMethod translate(JMethod method) {
-    if (method.isExternal()) {
-      JDeclaredType enclosingType = method.getEnclosingType();
-      String sig = enclosingType.getName() + '.' + method.getSignature();
-      method = methodMap.get(sig);
-      if (method == null) {
-        mapApi(translate(enclosingType));
-        // Now the method should be there.
-        method = methodMap.get(sig);
-        if (method == null) {
-          // TODO: error logging
-          throw new NoSuchMethodError(sig);
-        }
-      }
+    if (!method.isExternal()) {
+      return method;
+    }
+
+    JDeclaredType enclosingType = method.getEnclosingType();
+    String sig = enclosingType.getName() + '.' + method.getSignature();
+    JMethod newMethod = methodMap.get(sig);
+    if (newMethod != null) {
+      return newMethod;
+    }
+
+    enclosingType = translate(enclosingType);
+    if (enclosingType.isExternal()) {
+      // Error condition, should be logged.
+      return method;
+    }
+    mapApi(enclosingType);
+
+    // Now the method should be there.
+    method = methodMap.get(sig);
+    if (method == null) {
+      // TODO: error logging
+      throw new NoSuchMethodError(sig);
     }
     assert !method.isExternal();
     return method;
=======================================
--- /trunk/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java Wed Jun 8 16:12:42 2011 +++ /trunk/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java Thu Jun 9 11:46:19 2011
@@ -20,31 +20,13 @@
 import com.google.gwt.dev.javac.CompilationState;
 import com.google.gwt.dev.javac.testing.impl.JavaResourceBase;
 import com.google.gwt.dev.javac.testing.impl.MockJavaResource;
-import com.google.gwt.dev.jdt.AbstractCompiler.CompilationResults;
-import com.google.gwt.dev.jdt.BasicWebModeCompiler;
-import com.google.gwt.dev.jdt.FindDeferredBindingSitesVisitor;
-import com.google.gwt.dev.jjs.CorrelationFactory.DummyCorrelationFactory;
 import com.google.gwt.dev.jjs.ast.JDeclaredType;
 import com.google.gwt.dev.jjs.ast.JMethod;
 import com.google.gwt.dev.jjs.ast.JProgram;
-import com.google.gwt.dev.jjs.impl.AssertionNormalizer;
-import com.google.gwt.dev.jjs.impl.BuildTypeMap;
-import com.google.gwt.dev.jjs.impl.FixAssignmentToUnbox;
-import com.google.gwt.dev.jjs.impl.GenerateJavaAST;
-import com.google.gwt.dev.jjs.impl.ImplementClassLiteralsAsFields;
-import com.google.gwt.dev.jjs.impl.TypeLinker;
-import com.google.gwt.dev.jjs.impl.TypeMap;
-import com.google.gwt.dev.js.ast.JsProgram;
-
-import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;

 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;

 /**
  * Constructs a Java AST for testing.
@@ -214,65 +196,9 @@

public static JProgram construct(TreeLogger logger, CompilationState state, String... entryPoints)
       throws UnableToCompleteException {
- return construct(logger, state, TypeLinker.NULL_TYPE_LINKER, entryPoints);
-  }
-
- public static JProgram construct(TreeLogger logger, CompilationState state, TypeLinker linker,
-      String... entryPoints) throws UnableToCompleteException {
- Set<String> allRootTypes = new TreeSet<String>(Arrays.asList(entryPoints));
-    for (MockJavaResource resource : getCompilerTypes()) {
-      allRootTypes.add(resource.getTypeName());
-    }
-
-    CompilationResults units =
- BasicWebModeCompiler.getCompilationUnitDeclarations(logger, state, linker, allRootTypes
-            .toArray(new String[allRootTypes.size()]));
-
-    CompilationUnitDeclaration[] goldenCuds = units.compiledUnits;
-
- // Check for compilation problems. We don't log here because any problems
-    // found here will have already been logged by AbstractCompiler.
-    //
-    JavaToJavaScriptCompiler.checkForErrors(logger, goldenCuds, false);
-
-
-     // Find errors in usage of GWT.create() calls
-    for (CompilationUnitDeclaration jdtCud : goldenCuds) {
-      jdtCud.traverse(new FindDeferredBindingSitesVisitor(), jdtCud.scope);
-    }
-
-    JavaToJavaScriptCompiler.checkForErrors(logger, goldenCuds, true);
-
-    CorrelationFactory correlator = DummyCorrelationFactory.INSTANCE;
-    JProgram jprogram = new JProgram(correlator);
-    JsProgram jsProgram = new JsProgram(correlator);
-
-    /*
- * (1) Build a flattened map of TypeDeclarations => JType. The resulting map - * contains entries for all reference types. BuildTypeMap also parses all
-     * JSNI.
-     */
-    TypeMap typeMap = new TypeMap(jprogram);
- TypeDeclaration[] allTypeDeclarations = BuildTypeMap.exec(typeMap, units, jsProgram, linker);
-
-    // BuildTypeMap can uncover syntactic JSNI errors; report & abort
-    JavaToJavaScriptCompiler.checkForErrors(logger, goldenCuds, true);
-
-    // Compute all super type/sub type info
-    jprogram.typeOracle.computeBeforeAST();
-
-    // (2) Create our own Java AST from the JDT AST.
     JJSOptionsImpl options = new JJSOptionsImpl();
     options.setEnableAssertions(true);
-    GenerateJavaAST.exec(allTypeDeclarations, typeMap, jprogram, options);
-
-    // GenerateJavaAST can uncover semantic JSNI errors; report & abort
-    JavaToJavaScriptCompiler.checkForErrors(logger, goldenCuds, true);
-
-    // (3) Perform Java AST normalizations.
-    FixAssignmentToUnbox.exec(jprogram);
-    // Turn into assertion checking calls.
-    AssertionNormalizer.exec(jprogram);
+    JProgram jprogram = AstConstructor.construct(logger, state, options);

     // Add entry methods for entry points.
     for (String entryPoint : entryPoints) {
@@ -283,9 +209,6 @@
         }
       }
     }
-
-    ImplementClassLiteralsAsFields.exec(jprogram);
-
     // Tree is now ready to optimize.
     return jprogram;
   }
=======================================
--- /trunk/dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java Thu Apr 21 07:48:58 2011 +++ /trunk/dev/core/test/com/google/gwt/dev/jjs/impl/JJSTestBase.java Thu Jun 9 11:46:19 2011
@@ -235,11 +235,17 @@
       }
     });
     addBuiltinClasses(sourceOracle);
-    CompilationState state = CompilationStateBuilder.buildFrom(logger,
-        sourceOracle.getResources(), getAdditionalTypeProviderDelegate());
-    JProgram program = JavaAstConstructor.construct(logger, state,
-        "test.EntryPoint", "com.google.gwt.lang.Exceptions");
-    return program;
+    boolean wasEnabled = GwtAstBuilder.ENABLED;
+    try {
+      GwtAstBuilder.ENABLED = true;
+      CompilationState state = CompilationStateBuilder.buildFrom(logger,
+ sourceOracle.getResources(), getAdditionalTypeProviderDelegate());
+      JProgram program = JavaAstConstructor.construct(logger, state,
+          "test.EntryPoint", "com.google.gwt.lang.Exceptions");
+      return program;
+    } finally {
+      GwtAstBuilder.ENABLED = wasEnabled;
+    }
   }

   protected void addBuiltinClasses(MockResourceOracle sourceOracle) {

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to