blob: f9eecd356805468f81e942ecafb92a5872ad0a17 [file] [log] [blame]
/*
* 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.jjs.impl.GwtAstBuilder;
import com.google.gwt.dev.util.DiskCacheToken;
import com.google.gwt.dev.util.Util;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* A convenient way to serialize a {@CompilationUnit}.
*/
public class CachedCompilationUnit extends CompilationUnit {
private static final boolean normalizeTimestamps = Boolean.parseBoolean(
System.getProperty("gwt.normalizeTimestamps", "false"));
private final DiskCacheToken astToken;
private final long astVersion;
private transient Collection<CompiledClass> compiledClasses;
private final ContentId contentId;
private final Dependencies dependencies;
private final boolean isError;
private final boolean isGenerated;
private final boolean isSuperSource;
private final boolean hasJsInteropRootType;
private transient List<JsniMethod> jsniMethods;
private final long lastModified;
private final MethodArgNamesLookup methodArgNamesLookup;
private final CategorizedProblem[] problems;
private final String resourceLocation;
private final String resourcePath;
private final String typeName;
/**
* Shallow copy of a CachedCompiliationUnit, replacing some parameters in the new copy.
*
* @param unit Unit to clone.
* @param lastModified last modified date to replace in the clone
* @param resourceLocation location to replace in the clone.
*/
public CachedCompilationUnit(CachedCompilationUnit unit, long lastModified,
String resourceLocation) {
assert unit != null;
this.compiledClasses = CompiledClass.copyForUnit(unit.getCompiledClasses(), this);
this.hasJsInteropRootType = unit.hasJsInteropRootType;
this.contentId = unit.getContentId();
this.dependencies = unit.getDependencies();
this.resourcePath = unit.getResourcePath();
this.resourceLocation = Util.stripJarPathPrefix(resourceLocation);
this.jsniMethods = unit.getJsniMethods();
this.methodArgNamesLookup = unit.getMethodArgs();
this.typeName = unit.getTypeName();
this.isError = unit.isError();
this.isGenerated = unit.isGenerated();
this.isSuperSource = unit.isSuperSource();
this.problems = unit.problems;
this.astToken = unit.astToken;
this.astVersion = unit.astVersion;
// Override these fields
this.lastModified = normalizeTimestamps ? 0 : lastModified;
}
/**
* Create a compilation unit that can be serialized from another
* {@link CompilationUnit}.
*
* @param unit A unit to copy
* @param astToken A valid {@DiskCache} token for this unit's
* serialized AST types.
*/
@SuppressWarnings("deprecation")
CachedCompilationUnit(CompilationUnit unit, long astToken) {
assert unit != null;
this.compiledClasses = CompiledClass.copyForUnit(unit.getCompiledClasses(), this);
this.hasJsInteropRootType = unit.hasJsInteropRootType();
this.contentId = unit.getContentId();
this.dependencies = unit.getDependencies();
this.resourcePath = unit.getResourcePath();
this.resourceLocation = Util.stripJarPathPrefix(unit.getResourceLocation());
this.jsniMethods = unit.getJsniMethods();
this.lastModified = normalizeTimestamps ? 0 : unit.getLastModified();
this.methodArgNamesLookup = unit.getMethodArgs();
this.typeName = unit.getTypeName();
this.isError = unit.isError();
this.isGenerated = unit.isGenerated();
this.isSuperSource = unit.isSuperSource();
CategorizedProblem[] problemsIn = unit.getProblems();
if (problemsIn == null) {
this.problems = null;
} else {
this.problems = new CategorizedProblem[problemsIn.length];
for (int i = 0; i < problemsIn.length; i++) {
this.problems[i] = new SerializableCategorizedProblem(problemsIn[i]);
}
}
this.astToken = new DiskCacheToken(astToken);
this.astVersion = GwtAstBuilder.getSerializationVersion();
}
@Override
public CachedCompilationUnit asCachedCompilationUnit() {
return this;
}
@Override
public Collection<CompiledClass> getCompiledClasses() {
return compiledClasses;
}
@Override
public List<JsniMethod> getJsniMethods() {
return jsniMethods;
}
@Override
public long getLastModified() {
return lastModified;
}
@Override
public MethodArgNamesLookup getMethodArgs() {
return methodArgNamesLookup;
}
@Override
public String getResourceLocation() {
return resourceLocation;
}
@Override
public String getResourcePath() {
return resourcePath;
}
@Override
public String getTypeName() {
return typeName;
}
@Override
public byte[] getTypesSerialized() {
return astToken.readByteArray();
}
@Override
public boolean isError() {
return isError;
}
@Override
@Deprecated
public boolean isGenerated() {
return isGenerated;
}
@Override
@Deprecated
public boolean isSuperSource() {
return isSuperSource;
}
@Override
boolean hasJsInteropRootType() {
return hasJsInteropRootType;
}
@Override
ContentId getContentId() {
return contentId;
}
@Override
Dependencies getDependencies() {
return dependencies;
}
@Override
CategorizedProblem[] getProblems() {
return problems;
}
long getTypesSerializedVersion() {
return astVersion;
}
@SuppressWarnings("unchecked")
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
this.compiledClasses = (Collection<CompiledClass>) ois.readObject();
this.jsniMethods = (List<JsniMethod>) ois.readObject();
}
private <T> Collection<T> sort(Collection<T> collection, Comparator<T> comparator) {
if (collection == null) {
return null;
}
// copy because the source may be unmodifiable or singleton
ArrayList<T> copy = new ArrayList<T>(collection);
Collections.sort(copy, comparator);
return copy;
}
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
oos.writeObject(sort(this.compiledClasses, new Comparator<CompiledClass>() {
@Override
public int compare(CompiledClass o1, CompiledClass o2) {
return o1.getSourceName().compareTo(o2.getSourceName());
}
}));
oos.writeObject(sort(this.jsniMethods, new Comparator<JsniMethod>() {
@Override
public int compare(JsniMethod o1, JsniMethod o2) {
return o1.name().compareTo(o2.name());
}
}));
}
}