Revision: 10521
Author:   [email protected]
Date:     Thu Aug 11 10:00:33 2011
Log:      CachedCompilationUnits were inadvertently writing
two compies when serialized, because CompiledClass
contained a reference to the previous compilation
unit used to create the CCU.

Review at http://gwt-code-reviews.appspot.com/1517803

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

Modified:
 /trunk/dev/core/src/com/google/gwt/dev/javac/CachedCompilationUnit.java
 /trunk/dev/core/src/com/google/gwt/dev/javac/CompiledClass.java

=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/javac/CachedCompilationUnit.java Thu Aug 4 06:30:44 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/javac/CachedCompilationUnit.java Thu Aug 11 10:00:33 2011
@@ -53,7 +53,7 @@
public CachedCompilationUnit(CachedCompilationUnit unit, long lastModified,
       String resourceLocation) {
     assert unit != null;
-    this.compiledClasses = unit.getCompiledClasses();
+ this.compiledClasses = CompiledClass.copyForUnit(unit.getCompiledClasses(), this);
     this.contentId = unit.getContentId();
     this.dependencies = unit.getDependencies();
     this.resourcePath = unit.getResourcePath();
@@ -85,7 +85,7 @@
   @SuppressWarnings("deprecation")
   CachedCompilationUnit(CompilationUnit unit, long astToken) {
     assert unit != null;
-    this.compiledClasses = unit.getCompiledClasses();
+ this.compiledClasses = CompiledClass.copyForUnit(unit.getCompiledClasses(), this);
     this.contentId = unit.getContentId();
     this.dependencies = unit.getDependencies();
     this.resourceLocation = unit.getResourceLocation();
@@ -109,7 +109,7 @@
     this.astToken = new DiskCacheToken(astToken);
     this.astVersion = GwtAstBuilder.getSerializationVersion();
   }
-
+
   @Override
   public CachedCompilationUnit asCachedCompilationUnit() {
     return this;
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/javac/CompiledClass.java Tue Jun 21 16:17:16 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/javac/CompiledClass.java Thu Aug 11 10:00:33 2011
@@ -16,16 +16,23 @@
 package com.google.gwt.dev.javac;

 import com.google.gwt.dev.javac.TypeOracleMediator.TypeData;
+import com.google.gwt.dev.jjs.InternalCompilerException;
 import com.google.gwt.dev.util.DiskCache;
 import com.google.gwt.dev.util.DiskCacheToken;
-import com.google.gwt.dev.util.StringInterner;
 import com.google.gwt.dev.util.Name.InternalName;
+import com.google.gwt.dev.util.StringInterner;

 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;

 import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;

 /**
  * Encapsulates the state of a single compiled class file.
@@ -34,20 +41,52 @@

   private static final DiskCache diskCache = DiskCache.INSTANCE;

-  private final CompiledClass enclosingClass;
-  private final String internalName;
-  private final String sourceName;
-  private final boolean isLocal;
-  private transient TypeData typeData;
-  private CompilationUnit unit;
-  private String signatureHash;
+ static Collection<CompiledClass> copyForUnit(Collection<CompiledClass> in, CompilationUnit newUnit) {
+    if (in == null) {
+      return null;
+    }
+    CompiledClass[] orig = new CompiledClass[in.size()];
+    List<CompiledClass> copy = new ArrayList<CompiledClass>();
+
+ Map<CompiledClass, CompiledClass> enclosingClassMap = new HashMap<CompiledClass, CompiledClass>();
+    for (CompiledClass cc : in) {
+      CompiledClass copyCc = new CompiledClass(cc, newUnit);
+      copy.add(copyCc);
+      enclosingClassMap.put(cc, copyCc);
+    }
+
+ // Update the enclosing class references. With enough effort, we could determine the + // hierarchical relationship of compiled classes and initialize the copies with the
+    // copied enclosing class, but this is less effort.
+    for (CompiledClass copyCc : copy) {
+      if (copyCc.enclosingClass == null) {
+        continue;
+      }
+      CompiledClass newRef = enclosingClassMap.get(copyCc.enclosingClass);
+      if (null == newRef) {
+ throw new InternalCompilerException("Enclosing type not found for " + copyCc.sourceName);
+      }
+      copyCc.enclosingClass = newRef;
+    }
+
+    return Collections.unmodifiableCollection(copy);
+  }

   /**
* A token to retrieve this object's bytes from the disk cache. byte code is
    * placed in the cache when the object is deserialized.
    */
   private final DiskCacheToken classBytesToken;
+  private CompiledClass enclosingClass;
+  private final String internalName;
+  private final boolean isLocal;
   private transient NameEnvironmentAnswer nameEnvironmentAnswer;
+  private String signatureHash;
+
+  private final String sourceName;
+  private transient TypeData typeData;
+
+  private CompilationUnit unit;

   /**
    * Create a compiled class from raw class bytes.
@@ -68,6 +107,20 @@
this.classBytesToken = new DiskCacheToken(diskCache.writeByteArray(classBytes));
     this.isLocal = isLocal;
   }
+
+  /**
+   * Used for cloning all compiled classes in one compilation unit.
+   */
+  private CompiledClass(CompiledClass orig, CompilationUnit newUnit) {
+    this.enclosingClass = orig.enclosingClass;
+    this.internalName = orig.internalName;
+    this.sourceName = orig.sourceName;
+    this.classBytesToken = orig.classBytesToken;
+    this.isLocal = orig.isLocal;
+    this.typeData = orig.typeData;
+    this.unit = newUnit;
+    this.signatureHash = orig.signatureHash;
+  }

   /**
    * Returns the bytes of the compiled class.
@@ -111,7 +164,7 @@
   public String getSourceName() {
     return sourceName;
   }
-
+
   public TypeData getTypeData() {
     if (typeData == null) {
       typeData =
@@ -150,5 +203,4 @@
   void initUnit(CompilationUnit unit) {
     this.unit = unit;
   }
-
-}
+}

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

Reply via email to