Modifies CompiledClass to be serializable
Review at http://gwt-code-reviews.appspot.com/1329802
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9681 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/javac/CompiledClass.java b/dev/core/src/com/google/gwt/dev/javac/CompiledClass.java
index a0e0585..6779fed 100644
--- a/dev/core/src/com/google/gwt/dev/javac/CompiledClass.java
+++ b/dev/core/src/com/google/gwt/dev/javac/CompiledClass.java
@@ -19,57 +19,51 @@
import com.google.gwt.dev.util.Name.InternalName;
import com.google.gwt.dev.util.StringInterner;
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.compiler.ClassFile;
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 org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.NestedTypeBinding;
-import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
/**
* Encapsulates the state of a single compiled class file.
*/
-public final class CompiledClass {
+public final class CompiledClass implements Serializable {
private static final DiskCache diskCache = new DiskCache();
+ private final CompiledClass enclosingClass;
+ private final String internalName;
+ private final boolean isLocal;
+ private CompilationUnit unit;
+
/**
- * Returns <code>true</code> if this is a local type, or if this type is
- * nested inside of any local type.
+ * 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 static boolean isLocalType(SourceTypeBinding binding) {
- SourceTypeBinding b = binding;
- while (!b.isStatic()) {
- if (b instanceof LocalTypeBinding) {
- return true;
- }
- b = ((NestedTypeBinding) b).enclosingType;
- }
- return false;
- }
-
- protected final CompiledClass enclosingClass;
- protected final String internalName;
- protected final boolean isLocal;
- protected CompilationUnit unit;
-
- /**
- * A token to retrieve this object's bytes from the disk cache.
- */
- private final long cacheToken;
-
+ private transient long cacheToken;
private transient NameEnvironmentAnswer nameEnvironmentAnswer;
- CompiledClass(ClassFile classFile, CompiledClass enclosingClass) {
+ /**
+ * Create a compiled class from raw class bytes.
+ *
+ * @param classBytes - byte code for this class
+ * @param enclosingClass - outer class
+ * @param isLocal Is this class a local class? (See the JLS rev 2 section
+ * 14.3)
+ * @param internalName the internal binary name for this class. e.g. {@code
+ * java/util/Map$Entry}. See
+ * {@link "http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#14757"}
+ */
+ CompiledClass(byte[] classBytes, CompiledClass enclosingClass,
+ boolean isLocal, String internalName) {
this.enclosingClass = enclosingClass;
- SourceTypeBinding binding = classFile.referenceBinding;
- this.internalName = StringInterner.get().intern(
- CharOperation.charToString(binding.constantPoolName()));
- byte[] bytes = classFile.getBytes();
- this.cacheToken = diskCache.writeByteArray(bytes);
- this.isLocal = isLocalType(binding);
+ this.internalName = StringInterner.get().intern(internalName);
+ this.cacheToken = diskCache.writeByteArray(classBytes);
+ this.isLocal = isLocal;
}
/**
@@ -84,7 +78,8 @@
}
/**
- * Returns the binary class name, e.g. {@code java/util/Map$Entry}.
+ * Returns the class internal binary name for this type, e.g. {@code
+ * java/util/Map$Entry}.
*/
public String getInternalName() {
return internalName;
@@ -138,4 +133,16 @@
assert this.unit == null;
this.unit = unit;
}
+
+ private void readObject(ObjectInputStream inputStream)
+ throws ClassNotFoundException, IOException {
+ inputStream.defaultReadObject();
+ this.cacheToken = diskCache.transferFromStream(inputStream);
+ }
+
+ private void writeObject(ObjectOutputStream outputStream) throws IOException {
+ outputStream.defaultWriteObject();
+ byte[] byteCode = diskCache.readByteArray(cacheToken);
+ diskCache.transferToStream(cacheToken, outputStream);
+ }
}
diff --git a/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java b/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
index fb752ef..464f8b0 100644
--- a/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
@@ -52,8 +52,10 @@
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
+import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
+import org.eclipse.jdt.internal.compiler.lookup.NestedTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.UnresolvedReferenceBinding;
@@ -129,14 +131,6 @@
}
}
/**
- * Interface for processing units on the fly during compilation.
- */
- public interface UnitProcessor {
- void process(CompilationUnitBuilder builder,
- CompilationUnitDeclaration cud, List<CompiledClass> compiledClasses);
- }
-
- /**
* Static cache of all the JRE package names.
*/
public static class JreIndex {
@@ -181,6 +175,14 @@
}
/**
+ * Interface for processing units on the fly during compilation.
+ */
+ public interface UnitProcessor {
+ void process(CompilationUnitBuilder builder,
+ CompilationUnitDeclaration cud, List<CompiledClass> compiledClasses);
+ }
+
+ /**
* Adapts a {@link CompilationUnit} for a JDT compile.
*/
private static class Adapter implements ICompilationUnit {
@@ -261,7 +263,9 @@
enclosingClass = results.get(enclosingClassFile);
assert enclosingClass != null;
}
- CompiledClass result = new CompiledClass(classFile, enclosingClass);
+ String internalName = CharOperation.charToString(classFile.fileName());
+ CompiledClass result = new CompiledClass(classFile.getBytes(),
+ enclosingClass, isLocalType(classFile), internalName);
results.put(classFile, result);
}
}
@@ -357,7 +361,7 @@
}
}
}
-
+
/**
* Compiles the given set of units. The units will be internally modified to
* reflect the results of compilation.
@@ -439,6 +443,21 @@
return null;
}
+ /**
+ * Returns <code>true</code> if this is a local type, or if this type is
+ * nested inside of any local type.
+ */
+ private static boolean isLocalType(ClassFile classFile) {
+ SourceTypeBinding b = classFile.referenceBinding;
+ while (!b.isStatic()) {
+ if (b instanceof LocalTypeBinding) {
+ return true;
+ }
+ b = ((NestedTypeBinding) b).enclosingType;
+ }
+ return false;
+ }
+
private AdditionalTypeProviderDelegate additionalTypeProviderDelegate;
/**
diff --git a/dev/core/test/com/google/gwt/dev/javac/CompiledClassTest.java b/dev/core/test/com/google/gwt/dev/javac/CompiledClassTest.java
new file mode 100644
index 0000000..8d78d85
--- /dev/null
+++ b/dev/core/test/com/google/gwt/dev/javac/CompiledClassTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.javac;
+
+import com.google.gwt.dev.util.Util;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+public class CompiledClassTest extends TestCase {
+ static byte[] dummyByteCode = {
+ (byte) 0xDE, (byte) 0xAD, (byte)0xBE, (byte)0xEF
+ };
+ static final String DUMMY_NAME = "com.example.DeadBeef";
+
+ public void testCompiledClassSerialization() throws Exception {
+ CompiledClass writeObject = new CompiledClass(dummyByteCode, null, false, DUMMY_NAME);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ Util.writeObjectToStream(outputStream, writeObject);
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
+ CompiledClass readObject = Util.readStreamAsObject(inputStream, CompiledClass.class);
+ assertEquals(4, readObject.getBytes().length);
+ byte[] readBytes = readObject.getBytes();
+ for (int i = 0; i < 4 ; ++i) {
+ assertEquals(dummyByteCode[i], readBytes[i]);
+ }
+ }
+}