Marks types generated by invalidated generators as "modified".
Previously in per-file compilation mode when a resource was seen to be
modified the generators that read this resource were marked stale and
care was taken to make sure they were rerun. This was adequate to ensure
that any new types (that weren't created on a previous run) would be
fully processed. But it was not adequate to cause types that had been
previously generated (but which might now have modified contents) to be
reprocessed. Since only types believed to have been modified are
reprocessed, these types are now added to the modified list.
Change-Id: I7f3fe0aa6239e43db1c7f1453d662cc04ef46c2a
diff --git a/dev/core/src/com/google/gwt/dev/MinimalRebuildCache.java b/dev/core/src/com/google/gwt/dev/MinimalRebuildCache.java
index 6b709cd..4cdb863 100644
--- a/dev/core/src/com/google/gwt/dev/MinimalRebuildCache.java
+++ b/dev/core/src/com/google/gwt/dev/MinimalRebuildCache.java
@@ -33,6 +33,7 @@
import com.google.gwt.thirdparty.guava.common.collect.ImmutableList;
import com.google.gwt.thirdparty.guava.common.collect.Maps;
import com.google.gwt.thirdparty.guava.common.collect.Multimap;
+import com.google.gwt.thirdparty.guava.common.collect.Multimaps;
import com.google.gwt.thirdparty.guava.common.collect.Sets;
import com.google.gwt.thirdparty.guava.common.collect.Sets.SetView;
@@ -298,14 +299,31 @@
* Computes and returns the set of names of modified types.
* <p>
* Modified types are all those types that are nested within compilation units that are known to
- * have been modified.
+ * have been modified or were generated by a Generator that is known to have had its output
+ * invalidated.
*/
public Set<String> computeModifiedTypeNames() {
+ // Accumulate the names of types that are nested within known modified compilation units.
Set<String> modifiedTypeNames = Sets.newHashSet();
modifiedTypeNames.addAll(modifiedCompilationUnitNames);
for (String modifiedCompilationUnitName : modifiedCompilationUnitNames) {
modifiedTypeNames.addAll(nestedTypeNamesByUnitTypeName.get(modifiedCompilationUnitName));
}
+
+ // Accumulate the names of types that are nested within compilation units that are expected to
+ // be modified once invalidated Generators have been run (the Generators were invalidated
+ // because they read resources that are known to be modified).
+ Multimap<String, String> generatedTypeNameByReboundTypeNames = HashMultimap.create();
+ Multimaps.invertFrom(reboundTypeNamesByGeneratedTypeName, generatedTypeNameByReboundTypeNames);
+ Set<String> affectedReboundTypeNames = computeReboundTypesAffectedByModifiedResources();
+ for (String affectedReboundTypeName : affectedReboundTypeNames) {
+ Collection<String> generatedCompilationUnitNames =
+ generatedTypeNameByReboundTypeNames.get(affectedReboundTypeName);
+ for (String generatedCompilationUnitName : generatedCompilationUnitNames) {
+ modifiedTypeNames.addAll(nestedTypeNamesByUnitTypeName.get(generatedCompilationUnitName));
+ }
+ }
+
return modifiedTypeNames;
}
diff --git a/dev/core/test/com/google/gwt/dev/FooResourceGenerator.java b/dev/core/test/com/google/gwt/dev/FooResourceGenerator.java
index e813dc5..18432c4 100644
--- a/dev/core/test/com/google/gwt/dev/FooResourceGenerator.java
+++ b/dev/core/test/com/google/gwt/dev/FooResourceGenerator.java
@@ -48,20 +48,39 @@
}
}
- // On first run generate a class whose name depends on the contents of a read input resource.
+ // On first run generate a class whose name depends on the contents of a read input resource and
+ // another class whose name is stable but whose content changes based on the read input
+ // resource.
String generatedClassName;
try {
generatedClassName = Util.readStreamAsString(context.getResourcesOracle().getResource(
"com/foo/generatedClassName.txt").openContents()).trim();
- PrintWriter pw = context.tryCreate(logger, "com.foo", generatedClassName);
- if (pw != null) {
- pw.write("package com.foo;");
- pw.write("public class " + generatedClassName + " {}");
+ // Custom class name with stable content.
+ PrintWriter customNameClassPw = context.tryCreate(logger, "com.foo", generatedClassName);
+ if (customNameClassPw != null) {
+ customNameClassPw.write("package com.foo;");
+ customNameClassPw.write("public class " + generatedClassName + " {");
+ customNameClassPw.write(" HasCustomContent hasCustomContent = new HasCustomContent();");
+ customNameClassPw.write("}");
- pw.close();
- context.commit(logger, pw);
+ customNameClassPw.close();
+ context.commit(logger, customNameClassPw);
}
+
+ // Stable class name with custom content.
+ PrintWriter customContentClassPw = context.tryCreate(logger, "com.foo", "HasCustomContent");
+ if (customContentClassPw != null) {
+ String generatedFunctionName = generatedClassName;
+ customContentClassPw.write("package com.foo;");
+ customContentClassPw.write("public class HasCustomContent {");
+ customContentClassPw.write(" public void " + generatedFunctionName + "() {}");
+ customContentClassPw.write("}");
+
+ customContentClassPw.close();
+ context.commit(logger, customContentClassPw);
+ }
+
return "com.foo." + generatedClassName;
} catch (IOException e) {
return "";