Revision: 8555
Author: [email protected]
Date: Tue Aug 17 08:39:10 2010
Log: Rolling back r8550: Change to CompilationStateBuilder to prevent recursive invalidation on changed units.

Broke some users.

Review by: [email protected]
http://code.google.com/p/google-web-toolkit/source/detail?r=8555

Deleted:
 /trunk/dev/core/src/com/google/gwt/dev/javac/Dependencies.java
Modified:
 /trunk/dev/core/src/com/google/gwt/dev/javac/CompilationState.java
 /trunk/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
 /trunk/dev/core/src/com/google/gwt/dev/javac/CompilationUnit.java
 /trunk/dev/core/src/com/google/gwt/dev/javac/CompilationUnitBuilder.java
 /trunk/dev/core/src/com/google/gwt/dev/javac/CompilationUnitImpl.java
/trunk/dev/core/src/com/google/gwt/dev/javac/CompilationUnitInvalidator.java
 /trunk/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
 /trunk/dev/core/src/com/google/gwt/dev/javac/SourceFileCompilationUnit.java
 /trunk/dev/core/src/com/google/gwt/dev/util/Util.java
 /trunk/dev/core/test/com/google/gwt/dev/javac/CompilationStateTest.java
 /trunk/dev/core/test/com/google/gwt/dev/javac/CompilationStateTestBase.java
/trunk/dev/core/test/com/google/gwt/dev/javac/CompilationUnitFileReferenceTest.java

=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/javac/Dependencies.java Tue Aug 17 04:56:43 2010
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright 2010 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.javac;
-
-import com.google.gwt.dev.util.collect.HashMap;
-import com.google.gwt.dev.util.collect.Lists;
-
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-/**
- * Tracks dependencies from a {...@link CompilationUnit} to {...@link CompiledClass
- * CompiledClasses}.
- */
-class Dependencies {
- Map<String, CompiledClass> qualified = new HashMap<String, CompiledClass>();
-  Map<String, CompiledClass> simple = new HashMap<String, CompiledClass>();
-  private final String myPackage;
-  private List<String> unresolvedQualified;
-  private List<String> unresolvedSimple;
-
-  Dependencies() {
-    this.myPackage = "";
-  }
-
-  /**
- * Initializes the set of simple and qualified dependency names, but does not
-   * resolve them.
-   */
-  Dependencies(String myPackage, List<String> unresolvedQualified,
-      List<String> unresolvedSimple) {
-    this.myPackage = (myPackage.length() == 0) ? "" : (myPackage + '.');
-    this.unresolvedQualified = unresolvedQualified;
-    this.unresolvedSimple = unresolvedSimple;
-  }
-
-  /**
-   * Returns the list of deps that cannot be resolved at all.
-   */
-  List<String> findMissingDeps(Set<String> allValidClasses) {
-    List<String> result = Lists.create();
-    for (Entry<String, CompiledClass> entry : qualified.entrySet()) {
-      String sourceName = entry.getKey();
-      boolean expected = entry.getValue() != null;
-      boolean actual = allValidClasses.contains(sourceName);
-      if (expected != actual) {
-        result = Lists.add(result, sourceName);
-      }
-    }
-    for (Entry<String, CompiledClass> entry : simple.entrySet()) {
-      String sourceName = entry.getKey();
-      boolean expected = entry.getValue() != null;
-      boolean actual = allValidClasses.contains(myPackage + sourceName)
-          || allValidClasses.contains("java.lang." + sourceName);
-      if (expected != actual) {
-        result = Lists.add(result, sourceName);
-      }
-    }
-    return result;
-  }
-
-  /**
-   * Resolves unqualified dependencies against the global list of all valid
-   * classes. Must be called before {...@link #validate(String, Map, Map)}.
-   */
-  void resolve(Map<String, CompiledClass> allValidClasses) {
-    for (String ref : unresolvedQualified) {
-      CompiledClass cc = allValidClasses.get(ref);
-      qualified.put(ref, cc);
-    }
-
-    for (String ref : unresolvedSimple) {
-      CompiledClass cc = findBySimpleName(ref, allValidClasses);
-      allValidClasses.get(ref);
-      simple.put(ref, cc);
-    }
-    unresolvedQualified = unresolvedSimple = null;
-  }
-
-  /**
- * Validate that all of my existing dependencies can be found in the global
-   * set of valid classes, and resolve to structurally identical APIs.
-   *
-   * @return <code>true</code> if all of my dependencies are valid
-   */
-  boolean validate(Map<String, CompiledClass> allValidClasses,
-      Map<CompiledClass, CompiledClass> cachedStructurallySame) {
-    for (Entry<String, CompiledClass> entry : qualified.entrySet()) {
-      CompiledClass theirs = allValidClasses.get(entry.getKey());
-      if (!validateClass(cachedStructurallySame, entry, theirs)) {
-        return false;
-      }
-    }
-    for (Entry<String, CompiledClass> entry : simple.entrySet()) {
- CompiledClass theirs = findBySimpleName(entry.getKey(), allValidClasses);
-      if (!validateClass(cachedStructurallySame, entry, theirs)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /**
- * Tries to resolve a simple name using Java lookup rules, first checking the
-   * current package, then java.lang.
-   */
-  private CompiledClass findBySimpleName(String ref,
-      Map<String, CompiledClass> allValidClasses) {
-    CompiledClass cc = allValidClasses.get(myPackage + ref);
-    if (cc != null) {
-      return cc;
-    }
-    return allValidClasses.get("java.lang." + ref);
-  }
-
- private boolean hasStructuralChanges(CompiledClass mine, CompiledClass theirs) {
-    try {
-      ClassFileReader cfr = new ClassFileReader(theirs.getBytes(), null);
-      return cfr.hasStructuralChanges(mine.getBytes());
-    } catch (ClassFormatException e) {
- throw new RuntimeException("Unexpected error reading compiled class", e);
-    }
-  }
-
- private boolean structurallySame(CompiledClass mine, CompiledClass theirs,
-      Map<CompiledClass, CompiledClass> cachedStructurallySame) {
-    if (cachedStructurallySame.get(mine) == theirs) {
-      return true;
-    }
-    if (cachedStructurallySame.containsKey(mine)) {
-      return false;
-    }
-    boolean isSame = !hasStructuralChanges(mine, theirs);
-    if (isSame) {
-      cachedStructurallySame.put(mine, theirs);
-    } else {
-      cachedStructurallySame.put(mine, null);
-    }
-    return isSame;
-  }
-
-  /**
- * Returns true if my class is the same as their class. Uses caching to avoid - * recomputing diffs. Updates the my entry to 'their' class if non-identical
-   * objects have the same structure.
-   */
-  private boolean validateClass(
-      Map<CompiledClass, CompiledClass> cachedStructurallySame,
-      Entry<String, CompiledClass> entry, CompiledClass theirs) {
-    CompiledClass mine = entry.getValue();
-    boolean result;
-    if (mine == theirs) {
-      // Identical.
-      result = true;
-    } else if ((mine == null) != (theirs == null)) {
-      result = false;
-    } else if (structurallySame(mine, theirs, cachedStructurallySame)) {
-      // Update our entry for identity.
-      entry.setValue(theirs);
-      result = true;
-    } else {
-      result = false;
-    }
-    return result;
-  }
-}
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/javac/CompilationState.java Tue Aug 17 04:56:43 2010 +++ /trunk/dev/core/src/com/google/gwt/dev/javac/CompilationState.java Tue Aug 17 08:39:10 2010
@@ -149,7 +149,7 @@
       }
     }
     CompilationUnitInvalidator.retainValidUnits(logger, units,
-        compileMoreLater.getValidClasses());
+        compileMoreLater.getValidDependencies());
     mediator.addNewUnits(logger, units);
   }
 }
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java Tue Aug 17 04:56:43 2010 +++ /trunk/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java Tue Aug 17 08:39:10 2010
@@ -29,7 +29,6 @@
 import org.apache.commons.collections.map.AbstractReferenceMap;
 import org.apache.commons.collections.map.ReferenceIdentityMap;
 import org.apache.commons.collections.map.ReferenceMap;
-import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
@@ -39,12 +38,9 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.Map.Entry;

 /**
  * Manages a centralized cache for compiled units.
@@ -69,7 +65,8 @@
           public ReferenceBinding resolveType(String typeName) {
             ReferenceBinding resolveType = compiler.resolveType(typeName);
             if (resolveType != null) {
- jsniDeps.add(String.valueOf(resolveType.qualifiedSourceName()));
+              String fileName = String.valueOf(resolveType.getFileName());
+              jsniDeps.add(fileName);
             }
             return resolveType;
           }
@@ -84,21 +81,8 @@
         CompilationUnitInvalidator.reportErrors(logger, cud,
             builder.getSource());

-        String packageName = Shared.getPackageName(builder.getTypeName());
-        List<String> unresolvedQualified = new ArrayList<String>();
-        List<String> unresolvedSimple = new ArrayList<String>();
- for (char[] simpleRef : cud.compilationResult().simpleNameReferences) {
-          unresolvedSimple.add(canonical(String.valueOf(simpleRef)));
-        }
- for (char[][] qualifiedRef : cud.compilationResult().qualifiedReferences) { - unresolvedQualified.add(canonical(CharOperation.toString(qualifiedRef)));
-        }
-        for (String jsniDep : jsniDeps) {
-          unresolvedQualified.add(canonical(jsniDep));
-        }
-        Dependencies dependencies = new Dependencies(packageName,
-            unresolvedQualified, unresolvedSimple);
-
+        Set<ContentId> dependencies = compiler.computeDependencies(cud,
+            jsniDeps);
         CompilationUnit unit = builder.build(compiledClasses, dependencies,
             jsniMethods.values(), methodArgs,
             cud.compilationResult().getProblems());
@@ -115,26 +99,9 @@
         } else if (builder instanceof GeneratedCompilationUnitBuilder) {
           keepAliveRecentlyGenerated.put(unit.getTypeName(), unit);
         }
-
-        newlyBuiltUnits.add(unit);
-      }
-
-      private String canonical(String str) {
-        String result = internedTypeNames.get(str);
-        if (result != null) {
-          return result;
-        }
-        internedTypeNames.put(str, str);
-        return str;
+        resultUnits.put(unit.getTypeName(), unit);
       }
     }
-
-    /**
-     * A global cache of all currently-valid class files. This is used to
- * validate dependencies when reusing previously cached units, to make sure
-     * they can be recompiled if necessary.
-     */
- private final Map<String, CompiledClass> allValidClasses = new HashMap<String, CompiledClass>();

     /**
      * The JDT compiler.
@@ -142,14 +109,6 @@
     private final JdtCompiler compiler = new JdtCompiler(
         new UnitProcessorImpl());

-    /**
-     * Memory efficiency only. Stores canonical versions of dependency type
- * names so that String instances can be shared among many units. Otherwise, - * we'd get many duplicate String objects since we have to build them from
-     * JDT's char arrays.
-     */
- private final Map<String, String> internedTypeNames = new HashMap<String, String>();
-
     /**
      * Continuation state for JSNI checking.
      */
@@ -157,7 +116,8 @@

     private transient TreeLogger logger;

-    private transient Collection<CompilationUnit> newlyBuiltUnits;
+    private transient Map<String, CompilationUnit> resultUnits;
+ private final Set<ContentId> validDependencies = new HashSet<ContentId>();

     public CompileMoreLater(AdditionalTypeProviderDelegate delegate) {
       compiler.setAdditionalTypeProviderDelegate(delegate);
@@ -173,81 +133,25 @@
         compilationStateBuilderProcess.end();
       }
     }
-
-    public Map<String, CompiledClass> getValidClasses() {
-      return Collections.unmodifiableMap(allValidClasses);
-    }

     void addValidUnit(CompilationUnit unit) {
       compiler.addCompiledUnit(unit);
-      for (CompiledClass cc : unit.getCompiledClasses()) {
-        String sourceName = cc.getSourceName();
-        allValidClasses.put(sourceName, cc);
+      if (!unit.isError()) {
+        validDependencies.add(unit.getContentId());
       }
     }

-    Collection<CompilationUnit> compile(TreeLogger logger,
+    void compile(TreeLogger logger,
         Collection<CompilationUnitBuilder> builders,
-        Map<CompilationUnitBuilder, CompilationUnit> cachedUnits) {
+        Map<String, CompilationUnit> resultUnits) {
       this.logger = logger.branch(TreeLogger.DEBUG,
           "Validating newly compiled units");
-
-      // Initialize the set of valid classes to the initially cached units.
-      for (CompilationUnit unit : cachedUnits.values()) {
-        for (CompiledClass cc : unit.getCompiledClasses()) {
-          // Map by source name.
-          String sourceName = cc.getSourceName();
-          allValidClasses.put(sourceName, cc);
-        }
-      }
- Map<CompiledClass, CompiledClass> cachedStructurallySame = new IdentityHashMap<CompiledClass, CompiledClass>();
-
- Collection<CompilationUnit> resultUnits = new ArrayList<CompilationUnit>();
-      do {
-        // Compile anything that needs to be compiled.
-        this.newlyBuiltUnits = new ArrayList<CompilationUnit>();
-
-        compiler.doCompile(builders);
-        resultUnits.addAll(this.newlyBuiltUnits);
-        builders.clear();
-
-        // Resolve all newly built unit deps against the global classes.
-        for (CompilationUnit unit : this.newlyBuiltUnits) {
-          unit.getDependencies().resolve(allValidClasses);
-        }
-
-        /*
-         * Invalidate any cached units with invalid refs.
-         */
- Collection<CompilationUnit> invalidatedUnits = new ArrayList<CompilationUnit>(); - for (Iterator<Entry<CompilationUnitBuilder, CompilationUnit>> it = cachedUnits.entrySet().iterator(); it.hasNext();) {
-          Entry<CompilationUnitBuilder, CompilationUnit> entry = it.next();
-          CompilationUnit unit = entry.getValue();
- boolean isValid = unit.getDependencies().validate(allValidClasses,
-              cachedStructurallySame);
-          if (!isValid) {
-            invalidatedUnits.add(unit);
-            builders.add(entry.getKey());
-            it.remove();
-          }
-        }
-
- // Any units we invalidated must now be removed from the valid classes.
-        for (CompilationUnit unit : invalidatedUnits) {
-          for (CompiledClass cc : unit.getCompiledClasses()) {
-            allValidClasses.remove(cc.getSourceName());
-          }
-        }
-      } while (builders.size() > 0);
-
-      // Any remaining cached units are valid now.
-      resultUnits.addAll(cachedUnits.values());
-
-      // Re-report any errors on cached units we're reusing.
-      for (CompilationUnit unit : cachedUnits.values()) {
-        CompilationUnitInvalidator.reportErrors(logger, unit);
-      }
-      return resultUnits;
+      this.resultUnits = resultUnits;
+      compiler.doCompile(builders);
+    }
+
+    Set<ContentId> getValidDependencies() {
+      return validDependencies;
     }
   }

@@ -315,8 +219,6 @@
   /**
* This map of weak keys to hard values exists solely to keep the most recent
    * version of any unit from being eagerly garbage collected.
-   *
-   * WRITE-ONLY
    */
   @SuppressWarnings("unchecked")
private final Map<ResourceTag, CompilationUnit> keepAliveLatestVersion = Collections.synchronizedMap(new ReferenceIdentityMap(
@@ -325,8 +227,6 @@
   /**
    * This map of hard keys to soft values exists solely to keep the most
* recently generated version of a type from being eagerly garbage collected.
-   *
-   * WRITE-ONLY
    */
   @SuppressWarnings("unchecked")
private final Map<String, CompilationUnit> keepAliveRecentlyGenerated = Collections.synchronizedMap(new ReferenceMap(
@@ -351,8 +251,10 @@

   /**
    * Build a new compilation state from a source oracle.
+   *
+   * TODO: maybe use a finer brush than to synchronize the whole thing.
    */
-  public CompilationState doBuildFrom(TreeLogger logger,
+  public synchronized CompilationState doBuildFrom(TreeLogger logger,
       Set<Resource> resources) {
     return doBuildFrom(logger, resources, null);
   }
@@ -360,8 +262,6 @@
   /**
* Build a new compilation state from a source oracle. Allow the caller to specify
    * a compiler delegate that will handle undefined names.
-   *
-   * TODO: maybe use a finer brush than to synchronize the whole thing.
    */
   public synchronized CompilationState doBuildFrom(TreeLogger logger,
Set<Resource> resources, AdditionalTypeProviderDelegate compilerDelegate) {
@@ -369,37 +269,45 @@
SpeedTracerLogger.start(DevModeEventType.COMPILATION_STATE_BUILDER_PROCESS);

     try {
-      // Units we definitely want to build.
- List<CompilationUnitBuilder> builders = new ArrayList<CompilationUnitBuilder>();
-
-      // Units we don't want to rebuild unless we have to.
- Map<CompilationUnitBuilder, CompilationUnit> cachedUnits = new IdentityHashMap<CompilationUnitBuilder, CompilationUnit>();
-
- CompileMoreLater compileMoreLater = new CompileMoreLater(compilerDelegate); + Map<String, CompilationUnit> resultUnits = new HashMap<String, CompilationUnit>();

       // For each incoming Java source file...
       for (Resource resource : resources) {
-        String typeName = Shared.toTypeName(resource.getPath());
-        // Create a builder for all incoming units.
- ResourceCompilationUnitBuilder builder = new ResourceCompilationUnitBuilder(
-            typeName, resource);
         // Try to get an existing unit from the cache.
         String location = resource.getLocation();
         ResourceTag tag = resourceContentCache.get(location);
if (tag != null && tag.getLastModified() == resource.getLastModified()) {
           ContentId contentId = tag.getContentId();
           CompilationUnit existingUnit = unitCache.get(contentId);
-          if (existingUnit != null) {
-            cachedUnits.put(builder, existingUnit);
-            compileMoreLater.addValidUnit(existingUnit);
-            continue;
+          // Always try to recompile error units.
+          if (existingUnit != null && !existingUnit.isError()) {
+            resultUnits.put(existingUnit.getTypeName(), existingUnit);
           }
         }
-        builders.add(builder);
-      }
-      Collection<CompilationUnit> resultUnits = compileMoreLater.compile(
-          logger, builders, cachedUnits);
-      return new CompilationState(logger, resultUnits, compileMoreLater);
+      }
+
+      // Winnow the reusable set of units down to those still valid.
+      CompilationUnitInvalidator.retainValidUnits(TreeLogger.NULL,
+                                                  resultUnits.values());
+
+      // Compile everything else.
+ CompileMoreLater compileMoreLater = new CompileMoreLater(compilerDelegate); + List<CompilationUnitBuilder> builders = new ArrayList<CompilationUnitBuilder>();
+      for (Resource resource : resources) {
+        String typeName = Shared.toTypeName(resource.getPath());
+        CompilationUnit validUnit = resultUnits.get(typeName);
+        if (validUnit != null) {
+          compileMoreLater.addValidUnit(validUnit);
+          // Report any existing errors as if the unit were recompiled.
+          CompilationUnitInvalidator.reportErrors(logger, validUnit);
+        } else {
+ builders.add(new ResourceCompilationUnitBuilder(typeName, resource));
+        }
+      }
+      compileMoreLater.compile(logger, builders, resultUnits);
+
+      return new CompilationState(logger, resultUnits.values(),
+          compileMoreLater);
     } finally {
       compilationStateBuilderProcess.end();
     }
@@ -413,29 +321,38 @@
   synchronized Collection<CompilationUnit> doBuildGeneratedTypes(
       TreeLogger logger, Collection<GeneratedUnit> generatedUnits,
       CompileMoreLater compileMoreLater) {
-
-    // Units we definitely want to build.
- List<CompilationUnitBuilder> builders = new ArrayList<CompilationUnitBuilder>();
-
-    // Units we don't want to rebuild unless we have to.
- Map<CompilationUnitBuilder, CompilationUnit> cachedUnits = new IdentityHashMap<CompilationUnitBuilder, CompilationUnit>(); + Map<String, CompilationUnit> resultUnits = new HashMap<String, CompilationUnit>();

     // For each incoming generated Java source file...
     for (GeneratedUnit generatedUnit : generatedUnits) {
-      // Create a builder for all incoming units.
- GeneratedCompilationUnitBuilder builder = new GeneratedCompilationUnitBuilder(
-          generatedUnit);
       // Try to get an existing unit from the cache.
       ContentId contentId = new ContentId(generatedUnit.getTypeName(),
           generatedUnit.getStrongHash());
       CompilationUnit existingUnit = unitCache.get(contentId);
-      if (existingUnit != null) {
-        cachedUnits.put(builder, existingUnit);
-        compileMoreLater.addValidUnit(existingUnit);
-      } else {
-        builders.add(builder);
+      // Always try to recompile error units.
+      if (existingUnit != null && !existingUnit.isError()) {
+        resultUnits.put(existingUnit.getTypeName(), existingUnit);
       }
     }
-    return compileMoreLater.compile(logger, builders, cachedUnits);
+
+    // Winnow the reusable set of units down to those still valid.
+    CompilationUnitInvalidator.retainValidUnits(TreeLogger.NULL,
+        resultUnits.values(), compileMoreLater.getValidDependencies());
+    for (CompilationUnit validUnit : resultUnits.values()) {
+      compileMoreLater.addValidUnit(validUnit);
+      // Report any existing errors as if the unit were recompiled.
+      CompilationUnitInvalidator.reportErrors(logger, validUnit);
+    }
+
+    // Compile everything else.
+ List<CompilationUnitBuilder> builders = new ArrayList<CompilationUnitBuilder>();
+    for (GeneratedUnit generatedUnit : generatedUnits) {
+      if (!resultUnits.containsKey(generatedUnit.getTypeName())) {
+        builders.add(new GeneratedCompilationUnitBuilder(generatedUnit));
+      }
+    }
+
+    compileMoreLater.compile(logger, builders, resultUnits);
+    return resultUnits.values();
   }
 }
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/javac/CompilationUnit.java Tue Aug 17 04:56:43 2010 +++ /trunk/dev/core/src/com/google/gwt/dev/javac/CompilationUnit.java Tue Aug 17 08:39:10 2010
@@ -33,6 +33,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.regex.Pattern;

 /**
@@ -335,10 +336,7 @@
    */
   abstract ContentId getContentId();

-  /**
-   * The set of dependencies on other classes.
-   */
-  abstract Dependencies getDependencies();
+  abstract Set<ContentId> getDependencies();

   abstract CategorizedProblem[] getProblems();

=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/javac/CompilationUnitBuilder.java Tue Aug 17 04:56:43 2010 +++ /trunk/dev/core/src/com/google/gwt/dev/javac/CompilationUnitBuilder.java Tue Aug 17 08:39:10 2010
@@ -25,6 +25,7 @@
 import java.io.InputStream;
 import java.util.Collection;
 import java.util.List;
+import java.util.Set;

 /**
  * Builds a {...@link CompilationUnit}.
@@ -60,7 +61,7 @@

     @Override
     protected CompilationUnit makeUnit(List<CompiledClass> compiledClasses,
-        Dependencies dependencies,
+        Set<ContentId> dependencies,
         Collection<? extends JsniMethod> jsniMethods,
         MethodArgNamesLookup methodArgs, CategorizedProblem[] problems) {
       return new GeneratedCompilationUnit(generatedUnit, compiledClasses,
@@ -145,7 +146,7 @@

     @Override
     protected CompilationUnit makeUnit(List<CompiledClass> compiledClasses,
-        Dependencies dependencies,
+        Set<ContentId> dependencies,
         Collection<? extends JsniMethod> jsniMethods,
         MethodArgNamesLookup methodArgs, CategorizedProblem[] problems) {
       return new SourceFileCompilationUnit(getResource(), contentId,
@@ -158,7 +159,7 @@
     private final GeneratedUnit generatedUnit;

     public GeneratedCompilationUnit(GeneratedUnit generatedUnit,
-        List<CompiledClass> compiledClasses, Dependencies dependencies,
+        List<CompiledClass> compiledClasses, Set<ContentId> dependencies,
         Collection<? extends JsniMethod> jsniMethods,
         MethodArgNamesLookup methodArgs, CategorizedProblem[] problems) {
super(compiledClasses, dependencies, jsniMethods, methodArgs, problems);
@@ -234,7 +235,8 @@
   }

   public CompilationUnit build(List<CompiledClass> compiledClasses,
- Dependencies dependencies, Collection<? extends JsniMethod> jsniMethods,
+      Set<ContentId> dependencies,
+      Collection<? extends JsniMethod> jsniMethods,
       MethodArgNamesLookup methodArgs, CategorizedProblem[] problems) {
     // Free the source now.
     source = null;
@@ -263,7 +265,7 @@
   protected abstract String doGetSource();

   protected abstract CompilationUnit makeUnit(
-      List<CompiledClass> compiledClasses, Dependencies dependencies,
+      List<CompiledClass> compiledClasses, Set<ContentId> dependencies,
       Collection<? extends JsniMethod> jsniMethods,
       MethodArgNamesLookup methodArgs, CategorizedProblem[] errors);

=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/javac/CompilationUnitImpl.java Tue Aug 17 04:56:43 2010 +++ /trunk/dev/core/src/com/google/gwt/dev/javac/CompilationUnitImpl.java Tue Aug 17 08:39:10 2010
@@ -21,10 +21,11 @@

 import java.util.Collection;
 import java.util.List;
+import java.util.Set;

 abstract class CompilationUnitImpl extends CompilationUnit {

-  private final Dependencies dependencies;
+  private final Set<ContentId> dependencies;
   private final List<CompiledClass> exposedCompiledClasses;
   private final boolean hasErrors;
   private final List<JsniMethod> jsniMethods;
@@ -32,7 +33,8 @@
   private final CategorizedProblem[] problems;

   public CompilationUnitImpl(List<CompiledClass> compiledClasses,
- Dependencies dependencies, Collection<? extends JsniMethod> jsniMethods,
+      Set<ContentId> dependencies,
+      Collection<? extends JsniMethod> jsniMethods,
       MethodArgNamesLookup methodArgs, CategorizedProblem[] problems) {
this.exposedCompiledClasses = Lists.normalizeUnmodifiable(compiledClasses);
     this.dependencies = dependencies;
@@ -77,7 +79,7 @@
   }

   @Override
-  Dependencies getDependencies() {
+  Set<ContentId> getDependencies() {
     return dependencies;
   }

=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/javac/CompilationUnitInvalidator.java Tue Aug 17 04:56:43 2010 +++ /trunk/dev/core/src/com/google/gwt/dev/javac/CompilationUnitInvalidator.java Tue Aug 17 08:39:10 2010
@@ -27,10 +27,7 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
 import java.util.Set;
-import java.util.Map.Entry;

 /**
* Helper class to invalidate units in a set based on errors or references to
@@ -60,49 +57,39 @@

   public static void retainValidUnits(TreeLogger logger,
       Collection<CompilationUnit> units) {
-    retainValidUnits(logger, units,
-        Collections.<String, CompiledClass> emptyMap());
+    retainValidUnits(logger, units, Collections.<ContentId> emptySet());
   }

   public static void retainValidUnits(TreeLogger logger,
- Collection<CompilationUnit> units, Map<String, CompiledClass> validClasses) {
+      Collection<CompilationUnit> units, Set<ContentId> knownValidRefs) {
     logger = logger.branch(TreeLogger.TRACE, "Removing invalidated units");

     // Assume all units are valid at first.
Set<CompilationUnit> currentlyValidUnits = new HashSet<CompilationUnit>();
-    Set<String> currentlyValidClasses = new HashSet<String>();
+ Set<ContentId> currentlyValidRefs = new HashSet<ContentId>(knownValidRefs);
     for (CompilationUnit unit : units) {
       if (!unit.isError()) {
         currentlyValidUnits.add(unit);
-        for (CompiledClass cc : unit.getCompiledClasses()) {
-          currentlyValidClasses.add(cc.getSourceName());
-        }
+        currentlyValidRefs.add(unit.getContentId());
       }
     }
-    for (Entry<String, CompiledClass> entry : validClasses.entrySet()) {
-      if (!entry.getValue().getUnit().isError()) {
-        currentlyValidClasses.add(entry.getKey());
-      }
-    }

     boolean changed;
     do {
       changed = false;
for (Iterator<CompilationUnit> it = currentlyValidUnits.iterator(); it.hasNext();) {
         CompilationUnit unitToCheck = it.next();
- List<String> missingDeps = unitToCheck.getDependencies().findMissingDeps(
-            currentlyValidClasses);
-        if (missingDeps.size() > 0) {
-          TreeLogger branch = logger.branch(TreeLogger.DEBUG,
-              "Compilation unit '" + unitToCheck
-                  + "' is removed due to invalid reference(s):");
-          it.remove();
-          for (CompiledClass cc : unitToCheck.getCompiledClasses()) {
-            currentlyValidClasses.remove(cc.getSourceName());
-          }
-          changed = true;
-          for (String dep : missingDeps) {
-            branch.log(TreeLogger.DEBUG, dep);
+        TreeLogger branch = null;
+        for (ContentId ref : unitToCheck.getDependencies()) {
+          if (!currentlyValidRefs.contains(ref)) {
+            if (branch == null) {
+              branch = logger.branch(TreeLogger.DEBUG, "Compilation unit '"
+ + unitToCheck + "' is removed due to invalid reference(s):");
+              it.remove();
+              currentlyValidRefs.remove(unitToCheck.getContentId());
+              changed = true;
+            }
+            branch.log(TreeLogger.DEBUG, ref.get());
           }
         }
       }
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java Tue Aug 17 04:56:43 2010 +++ /trunk/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java Tue Aug 17 08:39:10 2010
@@ -1,12 +1,12 @@
 /*
  * Copyright 2008 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
@@ -16,8 +16,10 @@
 package com.google.gwt.dev.javac;

 import com.google.gwt.dev.jdt.SafeASTVisitor;
+import com.google.gwt.dev.jdt.TypeRefVisitor;
 import com.google.gwt.dev.util.collect.IdentityHashMap;
 import com.google.gwt.dev.util.collect.Lists;
+import com.google.gwt.dev.util.collect.Sets;
 import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
@@ -29,6 +31,7 @@
 import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
 import org.eclipse.jdt.internal.compiler.ICompilerRequestor;
 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Expression;
 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
@@ -73,7 +76,7 @@
     /**
* Checks for additional packages which may contain additional compilation
      * units.
-     *
+     *
* @param slashedPackageName the '/' separated name of the package to find
      * @return <code>true</code> if such a package exists
      */
@@ -82,7 +85,7 @@
     /**
* Finds a new compilation unit on-the-fly for the requested type, if there
      * is an alternate mechanism for doing so.
-     *
+     *
      * @param binaryName the binary name of the requested type
* @return a unit answering the name, or <code>null</code> if no such unit
      *         can be created
@@ -94,6 +97,7 @@
    * A default processor that simply collects build units.
    */
   public static final class DefaultUnitProcessor implements UnitProcessor {
+    private JdtCompiler compiler;
private final List<CompilationUnit> results = new ArrayList<CompilationUnit>();

     public DefaultUnitProcessor() {
@@ -105,11 +109,16 @@

     public void process(CompilationUnitBuilder builder,
CompilationUnitDeclaration cud, List<CompiledClass> compiledClasses) { - CompilationUnit unit = builder.build(compiledClasses, new Dependencies(),
+      CompilationUnit unit = builder.build(compiledClasses,
+          compiler.computeDependencies(cud),
           Collections.<JsniMethod> emptyList(), new MethodArgNamesLookup(),
           cud.compilationResult().getProblems());
       results.add(unit);
     }
+
+    public void setCompiler(JdtCompiler compiler) {
+      this.compiler = compiler;
+    }
   }
   /**
    * Interface for processing units on the fly during compilation.
@@ -176,6 +185,7 @@
       ICompilationUnit icu = cud.compilationResult().compilationUnit;
       Adapter adapter = (Adapter) icu;
       CompilationUnitBuilder builder = adapter.getBuilder();
+      contentIdMap.put(builder.getLocation(), builder.getContentId());
       processor.process(builder, cud, compiledClasses);
     }
   }
@@ -313,6 +323,7 @@
     try {
       DefaultUnitProcessor processor = new DefaultUnitProcessor();
       JdtCompiler compiler = new JdtCompiler(processor);
+      processor.setCompiler(compiler);
       compiler.doCompile(builders);
       return processor.getResults();
     } finally {
@@ -329,8 +340,6 @@
         | ClassFileConstants.ATTR_LINES | ClassFileConstants.ATTR_SOURCE;
     // Tricks like "boolean stopHere = true;" depend on this setting.
     options.preserveAllLocalVariables = true;
-    // Let the JDT collect compilation unit dependencies
-    options.produceReferenceInfo = true;

     // Turn off all warnings, saves some memory / speed.
options.reportUnusedDeclaredThrownExceptionIncludeDocCommentReference = false;
@@ -393,6 +402,19 @@
    */
   private transient CompilerImpl compilerImpl;

+  /**
+   * Maps resource path names to contentId to resolve dependencies.
+   */
+ private final Map<String, ContentId> contentIdMap = new HashMap<String, ContentId>();
+
+  /**
+   * Builders don't compute their contentId until their source is read;
+ * therefore we cannot eagerly lookup their contentId up front. Keep the set + * of currently compiling units in a map and lazily fetch their id only when a
+   * dependency is encountered.
+   */
+  private transient Map<String, CompilationUnitBuilder> lazyContentIdMap;
+
   private final Set<String> notPackages = new HashSet<String>();

   private final Set<String> packages = new HashSet<String>();
@@ -408,13 +430,69 @@
   public void addCompiledUnit(CompilationUnit unit) {
addPackages(Shared.getPackageName(unit.getTypeName()).replace('.', '/'));
     addBinaryTypes(unit.getCompiledClasses());
+    contentIdMap.put(unit.getDisplayLocation(), unit.getContentId());
+  }
+
+ public Set<ContentId> computeDependencies(CompilationUnitDeclaration cud) {
+    return computeDependencies(cud, Collections.<String> emptySet());
+  }
+
+  public Set<ContentId> computeDependencies(
+ final CompilationUnitDeclaration cud, Set<String> additionalDependencies) {
+    final Set<ContentId> result = new HashSet<ContentId>();
+    class DependencyVisitor extends TypeRefVisitor {
+      public DependencyVisitor() {
+        super(cud);
+      }
+
+      @Override
+      protected void onBinaryTypeRef(BinaryTypeBinding referencedType,
+ CompilationUnitDeclaration unitOfReferrer, Expression expression) {
+        String fileName = String.valueOf(referencedType.getFileName());
+        addFileReference(fileName);
+      }
+
+      @Override
+      protected void onTypeRef(SourceTypeBinding referencedType,
+          CompilationUnitDeclaration unitOfReferrer) {
+        // Map the referenced type to the target compilation unit file.
+        String fileName = String.valueOf(referencedType.getFileName());
+        addFileReference(fileName);
+      }
+
+      private void addFileReference(String fileName) {
+        if (!fileName.endsWith(".java")) {
+          // Binary-only reference, cannot compute dependency.
+          return;
+        }
+        ContentId contentId = contentIdMap.get(fileName);
+        if (contentId == null) {
+          // This may be a reference to a currently-compiling unit.
+          CompilationUnitBuilder builder = lazyContentIdMap.get(fileName);
+ assert builder != null : "Unexpected source reference ('" + fileName
+              + "') could not find builder";
+          contentId = builder.getContentId();
+        }
+        assert contentId != null;
+        result.add(contentId);
+      }
+    }
+    DependencyVisitor visitor = new DependencyVisitor();
+    cud.traverse(visitor, cud.scope);
+
+    for (String dependency : additionalDependencies) {
+      visitor.addFileReference(dependency);
+    }
+    return Sets.normalize(result);
   }

   public boolean doCompile(Collection<CompilationUnitBuilder> builders) {
+    lazyContentIdMap = new HashMap<String, CompilationUnitBuilder>();
     List<ICompilationUnit> icus = new ArrayList<ICompilationUnit>();
     for (CompilationUnitBuilder builder : builders) {
addPackages(Shared.getPackageName(builder.getTypeName()).replace('.', '/'));
       icus.add(new Adapter(builder));
+      lazyContentIdMap.put(builder.getLocation(), builder);
     }
     if (icus.isEmpty()) {
       return false;
@@ -425,6 +503,7 @@
     compilerImpl.compile(icus.toArray(new ICompilationUnit[icus.size()]));
     compilerImpl = null;
     jdtCompilerEvent.end("# icus", "" + icus.size());
+    lazyContentIdMap = null;
     return true;
   }

=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/javac/SourceFileCompilationUnit.java Tue Aug 17 04:56:43 2010 +++ /trunk/dev/core/src/com/google/gwt/dev/javac/SourceFileCompilationUnit.java Tue Aug 17 08:39:10 2010
@@ -21,6 +21,7 @@

 import java.util.Collection;
 import java.util.List;
+import java.util.Set;

 /**
  * A compilation unit that was generated.
@@ -39,7 +40,7 @@
   private final ContentId contentId;

public SourceFileCompilationUnit(Resource sourceFile, ContentId contentId,
-      List<CompiledClass> compiledClasses, Dependencies dependencies,
+      List<CompiledClass> compiledClasses, Set<ContentId> dependencies,
       Collection<? extends JsniMethod> jsniMethods,
       MethodArgNamesLookup methodArgs, CategorizedProblem[] problems) {
super(compiledClasses, dependencies, jsniMethods, methodArgs, problems);
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/util/Util.java Tue Aug 17 04:56:43 2010 +++ /trunk/dev/core/src/com/google/gwt/dev/util/Util.java Tue Aug 17 08:39:10 2010
@@ -633,11 +633,6 @@
   public static void maybeDumpSource(TreeLogger logger, String location,
       String source, String typeName) {

-    if (location.startsWith("/mock/")) {
-      // Unit test mocks, don't dump to disk.
-      return;
-    }
-
     if (isCompilationUnitOnDisk(location)) {
       // Don't write another copy.
       return;
=======================================
--- /trunk/dev/core/test/com/google/gwt/dev/javac/CompilationStateTest.java Tue Aug 17 04:56:43 2010 +++ /trunk/dev/core/test/com/google/gwt/dev/javac/CompilationStateTest.java Tue Aug 17 08:39:10 2010
@@ -31,33 +31,6 @@
  */
 public class CompilationStateTest extends CompilationStateTestBase {

- private static final MockJavaResource FOO_DIFF_API = new MockJavaResource(
-      "test.Foo") {
-    @Override
-    protected CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
-      code.append("package test;\n");
-      code.append("public class Foo {\n");
-      code.append("  public String value() { return \"Foo\"; }\n");
-      code.append("  public String value2() { return \"Foo2\"; }\n");
-      code.append("}\n");
-      return code;
-    }
-  };
-
- private static final MockJavaResource FOO_SAME_API = new MockJavaResource(
-      "test.Foo") {
-    @Override
-    protected CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
-      code.append("package test;\n");
-      code.append("public class Foo {\n");
-      code.append("  public String value() { return \"Foo2\"; }\n");
-      code.append("}\n");
-      return code;
-    }
-  };
-
   public void testAddGeneratedCompilationUnit() {
     validateCompilationState();

@@ -146,9 +119,9 @@
    * another generated unit it depends on can be reused
    */
   public void testComplexCacheInvalidation() {
-    testCachingOverMultipleRefreshes(new MockJavaResource[]{
+    testCachingOverMultipleRefreshes(new MockJavaResource[] {
         JavaResourceBase.FOO, JavaResourceBase.BAR},
-        new MockJavaResource[]{
+        new MockJavaResource[] {
             JavaResourceBase.FOO,
             new TweakedMockJavaResource(JavaResourceBase.BAR)},
         Collections.singleton(JavaResourceBase.FOO.getTypeName()));
@@ -161,31 +134,18 @@

   public void testInvalidation() {
     testCachingOverMultipleRefreshes(
-        new MockJavaResource[]{JavaResourceBase.FOO},
- new MockJavaResource[]{new TweakedMockJavaResource(JavaResourceBase.FOO)},
-        Collections.<String> emptySet());
-  }
-
-  public void testInvalidationNonstructuralDep() {
-    testCachingOverMultipleRefreshes(new MockJavaResource[]{
- JavaResourceBase.FOO, JavaResourceBase.BAR}, new MockJavaResource[]{
-        FOO_SAME_API, JavaResourceBase.BAR},
-        Collections.singleton(JavaResourceBase.BAR.getTypeName()));
+        new MockJavaResource[] {JavaResourceBase.FOO},
+        new MockJavaResource[] {new TweakedMockJavaResource(
+            JavaResourceBase.FOO)}, Collections.<String> emptySet());
   }

   public void testInvalidationOfMultipleUnits() {
-    testCachingOverMultipleRefreshes(new MockJavaResource[]{
- JavaResourceBase.FOO, JavaResourceBase.BAR}, new MockJavaResource[]{
+    testCachingOverMultipleRefreshes(new MockJavaResource[] {
+ JavaResourceBase.FOO, JavaResourceBase.BAR}, new MockJavaResource[] {
         new TweakedMockJavaResource(JavaResourceBase.FOO),
         new TweakedMockJavaResource(JavaResourceBase.BAR)},
         Collections.<String> emptySet());
   }
-
-  public void testInvalidationStructuralDep() {
-    testCachingOverMultipleRefreshes(new MockJavaResource[]{
- JavaResourceBase.FOO, JavaResourceBase.BAR}, new MockJavaResource[]{ - FOO_DIFF_API, JavaResourceBase.BAR}, Collections.<String> emptySet());
-  }

   public void testInvalidationWhenSourceUnitsChange() {
     /*
@@ -205,7 +165,7 @@
     assertNotNull(oldBar);

     // change unit in source oracle
-    oracle.replace(FOO_DIFF_API);
+    oracle.replace(new TweakedMockJavaResource(JavaResourceBase.FOO));
     rebuildCompilationState();

     /*
@@ -269,6 +229,15 @@
     assertEquals(size, state.getCompilationUnits().size());
     validateCompilationState();
   }
+
+ /* test if generatedUnits that depend on stale generatedUnits are invalidated */
+  public void testTransitiveInvalidation() {
+    testCachingOverMultipleRefreshes(new MockJavaResource[] {
+        JavaResourceBase.FOO, JavaResourceBase.BAR},
+        new MockJavaResource[] {
+            new TweakedMockJavaResource(JavaResourceBase.FOO),
+            JavaResourceBase.BAR}, Collections.<String> emptySet());
+  }

   private void testCaching(MockJavaResource... resources) {
     Set<String> reusedTypes = new HashSet<String>();
=======================================
--- /trunk/dev/core/test/com/google/gwt/dev/javac/CompilationStateTestBase.java Tue Aug 17 04:56:43 2010 +++ /trunk/dev/core/test/com/google/gwt/dev/javac/CompilationStateTestBase.java Tue Aug 17 08:39:10 2010
@@ -115,10 +115,6 @@
     Map<String, CompilationUnit> unitMap = state.getCompilationUnitMap();
     Collection<CompilationUnit> units = state.getCompilationUnits();

-    // Validate that we have as many units as resources.
-    assertEquals(oracle.getResources().size() + generatedTypeNames.length,
-        units.size());
-
     // Validate that the collections are consistent with each other.
     assertEquals(new HashSet<CompilationUnit>(unitMap.values()),
         new HashSet<CompilationUnit>(units));
=======================================
--- /trunk/dev/core/test/com/google/gwt/dev/javac/CompilationUnitFileReferenceTest.java Tue Aug 17 04:56:43 2010 +++ /trunk/dev/core/test/com/google/gwt/dev/javac/CompilationUnitFileReferenceTest.java Tue Aug 17 08:39:10 2010
@@ -45,30 +45,6 @@
     }
   };

-  public static final MockJavaResource NOPACKAGE = new MockJavaResource(
-      "NoPackage") {
-    @Override
-    protected CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
-      code.append("public class NoPackage extends test.Top {\n");
-      code.append("  public String value() { return \"NoPackage\"; }\n");
-      code.append("}\n");
-      return code;
-    }
-  };
-
-  public static final MockJavaResource NOPACKAGE2 = new MockJavaResource(
-      "NoPackage2") {
-    @Override
-    protected CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
-      code.append("public class NoPackage2 extends NoPackage {\n");
-      code.append("  public String value() { return \"NoPackage2\"; }\n");
-      code.append("}\n");
-      return code;
-    }
-  };
-
   public static final MockJavaResource OUTER = new MockJavaResource(
       "test.Outer") {
     @Override
@@ -141,11 +117,8 @@
initializeExpectedDependency(JavaResourceBase.BAR, JavaResourceBase.STRING,
         JavaResourceBase.FOO);

-    initializeExpectedDependency(NOPACKAGE, JavaResourceBase.STRING, TOP);
-    initializeExpectedDependency(NOPACKAGE2, NOPACKAGE,
-        JavaResourceBase.STRING, TOP);
-
-    initializeExpectedDependency(TOP, JavaResourceBase.STRING);
+    // TOP has a self-reference
+    initializeExpectedDependency(TOP, JavaResourceBase.STRING, TOP);
     initializeExpectedDependency(TOP3, JavaResourceBase.STRING, TOP);

     initializeExpectedDependency(OUTER, JavaResourceBase.STRING);
@@ -181,10 +154,6 @@
   public void testBinaryBindingsWithStaticInnerClass() {
     testBinaryBindings(OUTER, STATIC_INNER_SUBCLASS);
   }
-
-  public void testBinaryNoPackage() {
-    testBinaryBindings(TOP, NOPACKAGE, NOPACKAGE2);
-  }

   public void testSourceBindingsWithMemberInnerClass() {
     testSourceBindings(OUTER, MEMBER_INNER_SUBCLASS);
@@ -201,10 +170,6 @@
   public void testSourceBindingsWithStaticInnerClass() {
     testSourceBindings(OUTER, STATIC_INNER_SUBCLASS);
   }
-
-  public void testSourceNoPackage() {
-    testSourceBindings(TOP, NOPACKAGE, NOPACKAGE2);
-  }

   public void testWithGeneratedUnits() {
     addGeneratedUnits(JavaResourceBase.FOO, JavaResourceBase.BAR);
@@ -222,21 +187,14 @@
     Map<String, CompilationUnit> unitMap = state.getCompilationUnitMap();
     for (MockJavaResource file : files) {
       String typeName = file.getTypeName();
-      Dependencies dependencies = unitMap.get(typeName).getDependencies();
-      Set<CompiledClass> classDeps = new HashSet<CompiledClass>();
-      classDeps.addAll(dependencies.qualified.values());
-      classDeps.addAll(dependencies.simple.values());
-      classDeps.remove(null);
-      Set<String> actualTypeNames = new HashSet<String>();
-      for (CompiledClass cc : classDeps) {
-        actualTypeNames.add(cc.getUnit().getTypeName());
-      }
-      // Not tracking deps on Object.
-      actualTypeNames.remove("java.lang.Object");
-      // Don't care about self dep.
-      actualTypeNames.remove(typeName);
+ Set<ContentId> dependencies = unitMap.get(typeName).getDependencies();
       Set<String> expectedTypeNames = EXPECTED_DEPENDENCIES.get(typeName);
-      assertEquals(expectedTypeNames, actualTypeNames);
+      assertEquals(expectedTypeNames.size(), dependencies.size());
+      for (String expectedTypeName : expectedTypeNames) {
+        CompilationUnit expectedUnit = unitMap.get(expectedTypeName);
+        assertNotNull(expectedUnit);
+        assertTrue(dependencies.contains(expectedUnit.getContentId()));
+      }
     }
   }

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

Reply via email to