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