optimization: more compact storing of type tags and enums; less calls to enumerators; fixed sourceFile comparison problem

This commit is contained in:
Eugene Zhuravlev
2012-04-07 20:46:07 +02:00
parent a51850ac56
commit 7f4f7b2532
13 changed files with 252 additions and 250 deletions
@@ -100,7 +100,7 @@ public class JavaBuilder extends ModuleLevelBuilder {
}
}
final ClassReader reader = new ClassReader(content.getBuffer(), content.getOffset(), content.getLength());
callback.associate(outputPath, Callbacks.getDefaultLookup(sourcePath), reader);
callback.associate(outputPath, sourcePath, reader);
}
}
}
@@ -18,7 +18,7 @@ import java.util.Map;
* Date: 10/7/11
*/
public class BuildDataManager implements StorageOwner {
private static final int VERSION = 1;
private static final int VERSION = 2;
private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.storage.BuildDataManager");
private static final String SRC_TO_OUTPUTS_STORAGE = "src-out";
private static final String SRC_TO_FORM_STORAGE = "src-form";
@@ -12,21 +12,10 @@ import java.util.Collection;
* To change this template use File | Settings | File Templates.
*/
public class Callbacks {
public interface SourceFileNameLookup {
String get(String sourceAttribute);
}
public static SourceFileNameLookup getDefaultLookup(final String name) {
return new SourceFileNameLookup() {
public String get(final String sourceAttribute) {
return name;
}
};
}
public interface Backend {
Collection<String> getClassFiles();
void associate(String classFileName, SourceFileNameLookup sourceLookup, ClassReader cr);
void associate(String classFileName, String sourceFileName, ClassReader cr);
void registerConstantUsage(String className, String fieldName, String fieldOwner);
void registerImports(String className, Collection<String> imports, Collection<String> staticImports);
}
@@ -7,12 +7,8 @@ import org.jetbrains.ether.RW;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import java.util.*;
/**
* Created by IntelliJ IDEA.
@@ -23,12 +19,11 @@ import java.util.Set;
*/
public class ClassRepr extends Proto {
private final DependencyContext context;
public final int sourceFileName;
public final int fileName;
public final TypeRepr.AbstractType superClass;
public final Set<TypeRepr.AbstractType> interfaces;
public final Set<TypeRepr.AbstractType> nestedClasses;
public final Set<ElementType> targets;
public final Set<ElemType> targets;
public final RetentionPolicy policy;
public final Set<FieldRepr> fields;
@@ -50,7 +45,7 @@ public class ClassRepr extends Proto {
public abstract Specifier<MethodRepr> methods();
public abstract Specifier<ElementType> targets();
public abstract Specifier<ElemType> targets();
public abstract boolean retentionChanged();
@@ -121,7 +116,7 @@ public class ClassRepr extends Proto {
}
@Override
public Specifier<ElementType> targets() {
public Specifier<ElemType> targets() {
return Difference.make(pastClass.targets, targets);
}
@@ -173,20 +168,19 @@ public class ClassRepr extends Proto {
}
}
public ClassRepr(final DependencyContext context, final int a, final int sn, final int fn, final int n, final int sig,
public ClassRepr(final DependencyContext context, final int a, final int fn, final int n, final int sig,
final int sup,
final String[] i,
final Collection<String> ns,
final Set<FieldRepr> f,
final Set<MethodRepr> m,
final Set<ElementType> targets,
final Set<ElemType> targets,
final RetentionPolicy policy,
final int outerClassName,
final boolean localClassFlag) {
super(a, sig, n);
this.context = context;
fileName = fn;
sourceFileName = sn;
superClass = TypeRepr.createClassType(context, sup);
interfaces = (Set<TypeRepr.AbstractType>)TypeRepr.createClassType(context, i, new HashSet<TypeRepr.AbstractType>());
nestedClasses = (Set<TypeRepr.AbstractType>)TypeRepr.createClassType(context, ns, new HashSet<TypeRepr.AbstractType>());
@@ -203,13 +197,12 @@ public class ClassRepr extends Proto {
try {
this.context = context;
fileName = in.readInt();
sourceFileName = in.readInt();
superClass = TypeRepr.externalizer(context).read(in);
interfaces = (Set<TypeRepr.AbstractType>)RW.read(TypeRepr.externalizer(context), new HashSet<TypeRepr.AbstractType>(), in);
nestedClasses = (Set<TypeRepr.AbstractType>)RW.read(TypeRepr.externalizer(context), new HashSet<TypeRepr.AbstractType>(), in);
fields = (Set<FieldRepr>)RW.read(FieldRepr.externalizer(context), new HashSet<FieldRepr>(), in);
methods = (Set<MethodRepr>)RW.read(MethodRepr.externalizer(context), new HashSet<MethodRepr>(), in);
targets = (Set<ElementType>)RW.read(UsageRepr.AnnotationUsage.elementTypeExternalizer, new HashSet<ElementType>(), in);
targets = (Set<ElemType>)RW.read(UsageRepr.AnnotationUsage.elementTypeExternalizer, EnumSet.noneOf(ElemType.class), in);
final String s = in.readUTF();
@@ -228,7 +221,6 @@ public class ClassRepr extends Proto {
try {
super.save(out);
out.writeInt(fileName);
out.writeInt(sourceFileName);
superClass.save(out);
RW.save(interfaces, out);
RW.save(nestedClasses, out);
@@ -270,10 +262,6 @@ public class ClassRepr extends Proto {
return UsageRepr.createClassUsage(context, name);
}
public int getSourceFileName() {
return sourceFileName;
}
public String getPackageName() {
return getPackageName(name);
}
@@ -6,7 +6,6 @@ import org.jetbrains.asm4.*;
import org.jetbrains.asm4.signature.SignatureReader;
import org.jetbrains.asm4.signature.SignatureVisitor;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
import java.util.*;
@@ -71,7 +70,7 @@ class ClassfileAnalyzer {
}
public void visitEnum(final String name, String desc, final String value) {
targets.add(ElementType.valueOf(value));
targets.add(ElemType.valueOf(value));
}
public AnnotationVisitor visitAnnotation(String name, String desc) {
@@ -88,15 +87,15 @@ class ClassfileAnalyzer {
private class AnnotationCrawler extends AnnotationVisitor {
private final TypeRepr.ClassType type;
private final ElementType target;
private final ElemType target;
private final TIntHashSet myUsedArguments = new TIntHashSet();
private AnnotationCrawler(final TypeRepr.ClassType type, final ElementType target) {
private AnnotationCrawler(final TypeRepr.ClassType type, final ElemType target) {
super(Opcodes.ASM4);
this.type = type;
this.target = target;
final Set<ElementType> targets = myAnnotationTargets.get(type);
final Set<ElemType> targets = myAnnotationTargets.get(type);
if (targets == null) {
myAnnotationTargets.put(type, EnumSet.of(target));
}
@@ -270,7 +269,6 @@ class ClassfileAnalyzer {
String superClass;
String[] interfaces;
String signature;
int sourceFile;
final Holder<String> classNameHolder = new Holder<String>();
final Holder<String> outerClassName = new Holder<String>();
@@ -285,11 +283,11 @@ class ClassfileAnalyzer {
final List<String> nestedClasses = new ArrayList<String>();
final UsageRepr.Cluster usages = new UsageRepr.Cluster();
final Set<UsageRepr.Usage> annotationUsages = new HashSet<UsageRepr.Usage>();
final Set<ElementType> targets = new HashSet<ElementType>();
final Set<ElemType> targets = EnumSet.noneOf(ElemType.class);
RetentionPolicy policy = null;
final Map<TypeRepr.ClassType, TIntHashSet> myAnnotationArguments = new HashMap<TypeRepr.ClassType, TIntHashSet>();
final Map<TypeRepr.ClassType, Set<ElementType>> myAnnotationTargets = new HashMap<TypeRepr.ClassType, Set<ElementType>>();
final Map<TypeRepr.ClassType, Set<ElemType>> myAnnotationTargets = new HashMap<TypeRepr.ClassType, Set<ElemType>>();
public ClassCrawler(final int fn) {
super(Opcodes.ASM4);
@@ -303,7 +301,7 @@ class ClassfileAnalyzer {
public Pair<ClassRepr, Pair<UsageRepr.Cluster, Set<UsageRepr.Usage>>> getResult() {
final ClassRepr repr =
takeIntoAccount ? new ClassRepr(
context, access, sourceFile, fileName, name, context.get(signature), context.get(superClass), interfaces, nestedClasses, fields, methods, targets, policy, context.get(outerClassName.get()), localClassFlag.get()) : null;
context, access, fileName, name, context.get(signature), context.get(superClass), interfaces, nestedClasses, fields, methods, targets, policy, context.get(outerClassName.get()), localClassFlag.get()) : null;
if (repr != null) {
repr.updateClassUsages(context, usages);
@@ -326,15 +324,19 @@ class ClassfileAnalyzer {
classNameHolder.set(n);
final int residence = context.get(classNameHolder.get());
if (superClass != null) {
usages.addUsage(context.get(classNameHolder.get()), UsageRepr.createClassUsage(context, context.get(superClass)));
usages.addUsage(context.get(classNameHolder.get()), UsageRepr.createClassExtendsUsage(context, context.get(superClass)));
final int superclassName = context.get(superClass);
usages.addUsage(residence, UsageRepr.createClassUsage(context, superclassName));
usages.addUsage(residence, UsageRepr.createClassExtendsUsage(context, superclassName));
}
if (interfaces != null) {
for (String it : interfaces) {
usages.addUsage(context.get(classNameHolder.get()), UsageRepr.createClassUsage(context, context.get(it)));
usages.addUsage(context.get(classNameHolder.get()), UsageRepr.createClassExtendsUsage(context, context.get(it)));
final int interfaceName = context.get(it);
usages.addUsage(residence, UsageRepr.createClassUsage(context, interfaceName));
usages.addUsage(residence, UsageRepr.createClassExtendsUsage(context, interfaceName));
}
}
@@ -343,9 +345,9 @@ class ClassfileAnalyzer {
@Override
public void visitEnd() {
for (Map.Entry<TypeRepr.ClassType, Set<ElementType>> entry : myAnnotationTargets.entrySet()) {
for (Map.Entry<TypeRepr.ClassType, Set<ElemType>> entry : myAnnotationTargets.entrySet()) {
final TypeRepr.ClassType type = entry.getKey();
final Collection<ElementType> targets = entry.getValue();
final Set<ElemType> targets = entry.getValue();
final TIntHashSet usedArguments = myAnnotationArguments.get(type);
annotationUsages.add(UsageRepr.createAnnotationUsage(context, type, usedArguments, targets));
@@ -362,13 +364,14 @@ class ClassfileAnalyzer {
return new AnnotationRetentionPolicyCrawler();
}
return new AnnotationCrawler((TypeRepr.ClassType)TypeRepr.getType(context, context.get(desc)),
(access & Opcodes.ACC_ANNOTATION) > 0 ? ElementType.ANNOTATION_TYPE : ElementType.TYPE);
return new AnnotationCrawler(
(TypeRepr.ClassType)TypeRepr.getType(context, context.get(desc)),
(access & Opcodes.ACC_ANNOTATION) > 0 ? ElemType.ANNOTATION_TYPE : ElemType.TYPE
);
}
@Override
public void visitSource(String source, String debug) {
sourceFile = context.get(source);
}
@Override
@@ -382,17 +385,13 @@ class ClassfileAnalyzer {
return new FieldVisitor(Opcodes.ASM4) {
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
return new AnnotationCrawler((TypeRepr.ClassType)TypeRepr.getType(context, context.get(desc)), ElementType.FIELD);
return new AnnotationCrawler((TypeRepr.ClassType)TypeRepr.getType(context, context.get(desc)), ElemType.FIELD);
}
};
}
@Override
public MethodVisitor visitMethod(final int access,
final String n,
final String desc,
final String signature,
final String[] exceptions) {
public MethodVisitor visitMethod(final int access, final String n, final String desc, final String signature, final String[] exceptions) {
final Holder<Object> defaultValue = new Holder<Object>();
processSignature(signature);
@@ -407,8 +406,9 @@ class ClassfileAnalyzer {
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
return new AnnotationCrawler((TypeRepr.ClassType)TypeRepr.getType(context, context.get(desc)),
n.equals("<init>") ? ElementType.CONSTRUCTOR : ElementType.METHOD);
return new AnnotationCrawler(
(TypeRepr.ClassType)TypeRepr.getType(context, context.get(desc)), "<init>".equals(n) ? ElemType.CONSTRUCTOR : ElemType.METHOD
);
}
@Override
@@ -422,7 +422,7 @@ class ClassfileAnalyzer {
@Override
public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
return new AnnotationCrawler((TypeRepr.ClassType)TypeRepr.getType(context, context.get(desc)), ElementType.PARAMETER);
return new AnnotationCrawler((TypeRepr.ClassType)TypeRepr.getType(context, context.get(desc)), ElemType.PARAMETER);
}
@Override
@@ -440,8 +440,10 @@ class ClassfileAnalyzer {
final TypeRepr.AbstractType element = typ.getDeepElementType();
if (element instanceof TypeRepr.ClassType) {
usages.addUsage(context.get(classNameHolder.get()), UsageRepr.createClassUsage(context, ((TypeRepr.ClassType)element).className));
usages.addUsage(context.get(classNameHolder.get()), UsageRepr.createClassNewUsage(context, ((TypeRepr.ClassType)element).className));
final int residence = context.get(classNameHolder.get());
final int className = ((TypeRepr.ClassType)element).className;
usages.addUsage(residence, UsageRepr.createClassUsage(context, className));
usages.addUsage(residence, UsageRepr.createClassNewUsage(context, className));
}
typ.updateClassUsages(context, name, usages);
@@ -470,13 +472,15 @@ class ClassfileAnalyzer {
final TypeRepr.AbstractType typ = type.startsWith("[") ? TypeRepr.getType(context, context.get(type)) : TypeRepr.createClassType(context, context.get(type));
if (opcode == Opcodes.NEW) {
usages.addUsage(context.get(classNameHolder.get()), UsageRepr.createClassUsage(context, ((TypeRepr.ClassType)typ).className));
usages.addUsage(context.get(classNameHolder.get()), UsageRepr.createClassNewUsage(context, ((TypeRepr.ClassType)typ).className));
final int residence = context.get(classNameHolder.get());
usages.addUsage(residence, UsageRepr.createClassUsage(context, ((TypeRepr.ClassType)typ).className));
usages.addUsage(residence, UsageRepr.createClassNewUsage(context, ((TypeRepr.ClassType)typ).className));
}
else if (opcode == Opcodes.ANEWARRAY) {
if (typ instanceof TypeRepr.ClassType) {
usages.addUsage(context.get(classNameHolder.get()), UsageRepr.createClassUsage(context, ((TypeRepr.ClassType)typ).className));
usages.addUsage(context.get(classNameHolder.get()), UsageRepr.createClassNewUsage(context, ((TypeRepr.ClassType)typ).className));
final int residence = context.get(classNameHolder.get());
usages.addUsage(residence, UsageRepr.createClassUsage(context, ((TypeRepr.ClassType)typ).className));
usages.addUsage(residence, UsageRepr.createClassNewUsage(context, ((TypeRepr.ClassType)typ).className));
}
}
@@ -487,10 +491,15 @@ class ClassfileAnalyzer {
@Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
final int residence = context.get(classNameHolder.get());
final int fieldName = context.get(name);
final int fieldOwner = context.get(owner);
final int descr = context.get(desc);
if (opcode == Opcodes.PUTFIELD || opcode == Opcodes.PUTSTATIC) {
usages.addUsage(context.get(classNameHolder.get()), UsageRepr.createFieldAssignUsage(context, context.get(name), context.get(owner), context.get(desc)));
usages.addUsage(residence, UsageRepr.createFieldAssignUsage(context, fieldName, fieldOwner, descr));
}
usages.addUsage(context.get(classNameHolder.get()), UsageRepr.createFieldUsage(context, context.get(name), context.get(owner), context.get(desc)));
usages.addUsage(residence, UsageRepr.createFieldUsage(context, fieldName, fieldOwner, descr));
super.visitFieldInsn(opcode, owner, name, desc);
}
@@ -0,0 +1,27 @@
package org.jetbrains.ether.dependencyView;
public enum ElemType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE
}
@@ -16,7 +16,6 @@ import org.jetbrains.asm4.Opcodes;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
import java.util.*;
@@ -37,6 +36,23 @@ public class Mappings {
private final static String SOURCE_TO_USAGES = "sourceToUsages.tab";
private final static String CLASS_TO_SOURCE = "classToSource.tab";
private static final IntInlineKeyDescriptor INT_KEY_DESCRIPTOR = new IntInlineKeyDescriptor();
private static final int DEFAULT_SET_CAPACITY = 32;
private static final float DEFAULT_SET_LOAD_FACTOR = 0.98f;
private static final CollectionFactory<ClassRepr> ourClassSetConstructor = new CollectionFactory<ClassRepr>() {
public Set<ClassRepr> create() {
return new HashSet<ClassRepr>(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR);
}
};
private static final CollectionFactory<UsageRepr.Cluster> ourUsageClusterSetConstructor = new CollectionFactory<UsageRepr.Cluster>() {
public Set<UsageRepr.Cluster> create() {
return new HashSet<UsageRepr.Cluster>(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR);
}
};
private static final CollectionFactory<UsageRepr.Usage> ourUsageSetConstructor = new CollectionFactory<UsageRepr.Usage>() {
public Set<UsageRepr.Usage> create() {
return new HashSet<UsageRepr.Usage>(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR);
}
};
private final boolean myIsDelta;
private final boolean myDeltaIsTransient;
@@ -46,98 +62,20 @@ public class Mappings {
private final TIntHashSet myChangedFiles;
private final Set<ClassRepr> myDeletedClasses;
private final Object myLock;
private void addDeletedClass(final ClassRepr cr) {
assert (myDeletedClasses != null);
myDeletedClasses.add(cr);
addChangedClass(cr.name);
}
private void addChangedClass(final int it) {
assert (myChangedClasses != null && myChangedFiles != null);
myChangedClasses.add(it);
final Integer file = myClassToSourceFile.get(it);
if (file != null) {
myChangedFiles.add(file);
}
myIsDifferentiated = true;
}
@NotNull
private Set<ClassRepr> getDeletedClasses() {
return myDeletedClasses != null? Collections.<ClassRepr>emptySet() : Collections.unmodifiableSet(myDeletedClasses);
}
private TIntHashSet getChangedClasses() {
return myChangedClasses;
}
private TIntHashSet getChangedFiles() {
return myChangedFiles;
}
private boolean isDifferentiated() {
return myIsDifferentiated;
}
private final File myRootDir;
private DependencyContext myContext;
private final int myInitName;
private final int myEmptyName;
private org.jetbrains.ether.dependencyView.Logger<Integer> myDebugS;
private static void debug(final String s) {
LOG.debug(s);
}
private void debug(final String comment, final int s) {
myDebugS.debug(comment, s);
}
private void debug(final String comment, final String s) {
myDebugS.debug(comment, s);
}
private void debug(final String comment, final boolean s) {
myDebugS.debug(comment, s);
}
private IntIntMultiMaplet myClassToSubclasses;
private IntIntMultiMaplet myClassToClassDependency;
private IntObjectMultiMaplet<ClassRepr> mySourceFileToClasses;
private IntObjectMultiMaplet<UsageRepr.Usage> mySourceFileToAnnotationUsages;
private IntObjectMultiMaplet<UsageRepr.Cluster> mySourceFileToUsages;
private IntIntMaplet myClassToSourceFile;
private static final int DEFAULT_SET_CAPACITY = 32;
private static final float DEFAULT_SET_LOAD_FACTOR = 0.98f;
private static final CollectionFactory<ClassRepr> ourClassSetConstructor =
new CollectionFactory<ClassRepr>() {
public Set<ClassRepr> create() {
return new HashSet<ClassRepr>(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR);
}
};
private static final CollectionFactory<UsageRepr.Cluster> ourUsageClusterSetConstructor =
new CollectionFactory<UsageRepr.Cluster>() {
public Set<UsageRepr.Cluster> create() {
return new HashSet<UsageRepr.Cluster>(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR);
}
};
private static final CollectionFactory<UsageRepr.Usage> ourUsageSetConstructor =
new CollectionFactory<UsageRepr.Usage>() {
public Set<UsageRepr.Usage> create() {
return new HashSet<UsageRepr.Usage>(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR);
}
};
private Mappings(final Mappings base) throws IOException {
myLock = base.myLock;
myIsDelta = true;
@@ -149,6 +87,7 @@ public class Mappings {
myRootDir = new File(FileUtil.toSystemIndependentName(base.myRootDir.getAbsolutePath()) + File.separatorChar + "delta");
myContext = base.myContext;
myInitName = myContext.get("<init>");
myEmptyName = myContext.get("");
myDebugS = base.myDebugS;
myRootDir.mkdirs();
createImplementation();
@@ -165,6 +104,7 @@ public class Mappings {
myRootDir = rootDir;
createImplementation();
myInitName = myContext.get("<init>");
myEmptyName = myContext.get("");
}
private void createImplementation() throws IOException {
@@ -811,7 +751,7 @@ public class Mappings {
}
private boolean empty(final int s) {
return s == myContext.get("");
return s == myEmptyName;
}
private TIntHashSet getAllSubclasses(final int root) {
@@ -858,7 +798,7 @@ public class Mappings {
debug("Protected access, softening non-incremental decision: adding all relevant subclasses for a recompilation");
debug("Root class: ", owner);
final TIntHashSet propagated = self.propagateFieldAccess(isField ? member.name : myContext.get(""), owner);
final TIntHashSet propagated = self.propagateFieldAccess(isField ? member.name : myEmptyName, owner);
propagated.forEach(new TIntProcedure() {
@Override
@@ -1043,9 +983,9 @@ public class Mappings {
affectedUsages.add(it.createUsage());
}
else {
final Collection<ElementType> removedtargets = diff.targets().removed();
final Collection<ElemType> removedtargets = diff.targets().removed();
if (removedtargets.contains(ElementType.LOCAL_VARIABLE)) {
if (removedtargets.contains(ElemType.LOCAL_VARIABLE)) {
debug("Removed target contains LOCAL_VARIABLE => a switch to non-incremental mode requested");
if (!incrementalDecision(it.outerClassName, it, affectedFiles, filter)) {
debug("End of Differentiate, returning false");
@@ -1056,7 +996,7 @@ public class Mappings {
if (!removedtargets.isEmpty()) {
debug("Removed some annotation targets, adding annotation query");
annotationQuery.add((UsageRepr.AnnotationUsage)UsageRepr
.createAnnotationUsage(myContext, TypeRepr.createClassType(myContext, it.name), null, removedtargets));
.createAnnotationUsage(myContext, TypeRepr.createClassType(myContext, it.name), null, EnumSet.copyOf(removedtargets)));
}
for (final MethodRepr m : diff.methods().added()) {
@@ -1741,7 +1681,7 @@ public class Mappings {
}
}
if (delta.isDifferentiated()) {
if (delta.myIsDifferentiated) {
for (ClassRepr repr : delta.getDeletedClasses()) {
cleanupRemovedClass(repr, null, classDependenciesToRemove);
}
@@ -1874,7 +1814,7 @@ public class Mappings {
return result;
}
public void associate(final String classFileName, final Callbacks.SourceFileNameLookup sourceFileName, final ClassReader cr) {
public void associate(final String classFileName, final String sourceFileName, final ClassReader cr) {
synchronized (myLock) {
final int classFileNameS = myContext.get(classFileName);
final Pair<ClassRepr, Pair<UsageRepr.Cluster, Set<UsageRepr.Usage>>> result =
@@ -1883,8 +1823,7 @@ public class Mappings {
final UsageRepr.Cluster localUsages = result.second.first;
final Set<UsageRepr.Usage> localAnnotationUsages = result.second.second;
final String srcFileName = sourceFileName.get(repr == null ? null : myContext.getValue(repr.getSourceFileName()));
final int sourceFileNameS = myContext.get(srcFileName);
final int sourceFileNameS = myContext.get(sourceFileName);
if (repr != null) {
final int className = repr.name;
@@ -1900,11 +1839,10 @@ public class Mappings {
final int owner = u.getOwner();
if (owner != className) {
final int sourceFile = repr.getSourceFileName();
final int ownerSourceFile = myClassToSourceFile.get(owner);
if (ownerSourceFile > 0) {
if (ownerSourceFile != sourceFile) {
if (ownerSourceFile != sourceFileNameS) {
myClassToClassDependency.put(owner, className);
}
}
@@ -2041,4 +1979,55 @@ public class Mappings {
}
});
}
private void addDeletedClass(final ClassRepr cr) {
assert (myDeletedClasses != null);
myDeletedClasses.add(cr);
addChangedClass(cr.name);
}
private void addChangedClass(final int it) {
assert (myChangedClasses != null && myChangedFiles != null);
myChangedClasses.add(it);
final Integer file = myClassToSourceFile.get(it);
if (file != null) {
myChangedFiles.add(file);
}
myIsDifferentiated = true;
}
@NotNull
private Set<ClassRepr> getDeletedClasses() {
return myDeletedClasses != null? Collections.<ClassRepr>emptySet() : Collections.unmodifiableSet(myDeletedClasses);
}
private TIntHashSet getChangedClasses() {
return myChangedClasses;
}
private TIntHashSet getChangedFiles() {
return myChangedFiles;
}
private static void debug(final String s) {
LOG.debug(s);
}
private void debug(final String comment, final int s) {
myDebugS.debug(comment, s);
}
private void debug(final String comment, final String s) {
myDebugS.debug(comment, s);
}
private void debug(final String comment, final boolean s) {
myDebugS.debug(comment, s);
}
}
@@ -112,7 +112,8 @@ class MethodRepr extends ProtoMember {
super(context, in);
try {
final DataExternalizer<TypeRepr.AbstractType> externalizer = TypeRepr.externalizer(context);
argumentTypes = RW.read(externalizer, in, new TypeRepr.AbstractType[in.readInt()]);
final int size = in.readInt();
argumentTypes = RW.read(externalizer, in, new TypeRepr.AbstractType[size]);
exceptions = (Set<TypeRepr.AbstractType>)RW.read(externalizer, new HashSet<TypeRepr.AbstractType>(), in);
}
catch (IOException e) {
@@ -14,13 +14,13 @@ import java.io.IOException;
* To change this template use File | Settings | File Templates.
*/
abstract class ProtoMember extends Proto {
private final static int STRING = 0;
private final static int NONE = 1;
private final static int INTEGER = 2;
private final static int LONG = 3;
private final static int FLOAT = 4;
private final static int DOUBLE = 5;
private final static int TYPE = 6;
private final static byte STRING = 0;
private final static byte NONE = 1;
private final static byte INTEGER = 2;
private final static byte LONG = 3;
private final static byte FLOAT = 4;
private final static byte DOUBLE = 5;
private final static byte TYPE = 6;
public final TypeRepr.AbstractType type;
public final Object value;
@@ -37,7 +37,7 @@ abstract class ProtoMember extends Proto {
private static Object loadTyped(final DataInput in) {
try {
switch (in.readInt()) {
switch (in.readByte()) {
case STRING:
return in.readUTF();
case NONE:
@@ -50,7 +50,7 @@ abstract class ProtoMember extends Proto {
return in.readFloat();
case DOUBLE:
return in.readDouble();
case TYPE :
case TYPE :
return Type.getType(in.readUTF());
}
}
@@ -80,31 +80,31 @@ abstract class ProtoMember extends Proto {
try {
if (value instanceof String) {
out.writeInt(STRING);
out.writeByte(STRING);
out.writeUTF((String)value);
}
else if (value instanceof Integer) {
out.writeInt(INTEGER);
out.writeByte(INTEGER);
out.writeInt(((Integer)value).intValue());
}
else if (value instanceof Long) {
out.writeInt(LONG);
out.writeByte(LONG);
out.writeLong(((Long)value).longValue());
}
else if (value instanceof Float) {
out.writeInt(FLOAT);
out.writeByte(FLOAT);
out.writeFloat(((Float)value).floatValue());
}
else if (value instanceof Double) {
out.writeInt(DOUBLE);
out.writeByte(DOUBLE);
out.writeDouble(((Double)value).doubleValue());
}
else if (value instanceof Type) {
out.writeInt(TYPE);
out.writeByte(TYPE);
out.writeUTF(((Type)value).getDescriptor());
}
else {
out.writeInt(NONE);
out.writeByte(NONE);
}
}
catch (IOException e) {
@@ -19,9 +19,9 @@ import java.util.Collection;
* To change this template use File | Settings | File Templates.
*/
class TypeRepr {
private final static int PRIMITIVE_TYPE = 0;
private final static int CLASS_TYPE = 1;
private final static int ARRAY_TYPE = 2;
private static final byte PRIMITIVE_TYPE = 0x0;
private static final byte CLASS_TYPE = 0x1;
private static final byte ARRAY_TYPE = 0x2;
private TypeRepr() {
@@ -49,7 +49,7 @@ class TypeRepr {
@Override
public void save(final DataOutput out) {
try {
out.writeInt(PRIMITIVE_TYPE);
out.writeByte(PRIMITIVE_TYPE);
out.writeInt(myType);
}
catch (IOException e) {
@@ -131,7 +131,7 @@ class TypeRepr {
@Override
public void save(final DataOutput out) {
try {
out.writeInt(ARRAY_TYPE);
out.writeByte(ARRAY_TYPE);
elementType.save(out);
}
catch (IOException e) {
@@ -199,7 +199,7 @@ class TypeRepr {
@Override
public void save(final DataOutput out) {
try {
out.writeInt(CLASS_TYPE);
out.writeByte(CLASS_TYPE);
out.writeInt(className);
out.writeInt(typeArgs.length);
for (AbstractType t : typeArgs) {
@@ -283,7 +283,8 @@ class TypeRepr {
loop:
while (true) {
switch (in.readInt()) {
final byte tag = in.readByte();
switch (tag) {
case PRIMITIVE_TYPE:
elementType = context.getType(new PrimitiveType(in));
break loop;
@@ -295,6 +296,9 @@ class TypeRepr {
case ARRAY_TYPE:
level++;
break;
default :
System.out.println("Unknown type!");
}
}
@@ -9,7 +9,6 @@ import org.jetbrains.ether.RW;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.lang.annotation.ElementType;
import java.util.*;
/**
@@ -20,14 +19,15 @@ import java.util.*;
* To change this template use File | Settings | File Templates.
*/
class UsageRepr {
private final static int FIELD_USAGE = 0;
private final static int FIELD_ASSIGN_USAGE = 1;
private final static int METHOD_USAGE = 2;
private final static int CLASS_USAGE = 3;
private final static int CLASS_EXTENDS_USAGE = 4;
private final static int CLASS_NEW_USAGE = 5;
private final static int ANNOTATION_USAGE = 6;
private final static int METAMETHOD_USAGE = 7;
private static final byte FIELD_USAGE = 0x0;
private static final byte FIELD_ASSIGN_USAGE = 0x1;
private static final byte METHOD_USAGE = 0x2;
private static final byte CLASS_USAGE = 0x3;
private static final byte CLASS_EXTENDS_USAGE = 0x4;
private static final byte CLASS_NEW_USAGE = 0x5;
private static final byte ANNOTATION_USAGE = 0x6;
private static final byte METAMETHOD_USAGE = 0x7;
private static final int DEFAULT_SET_CAPACITY = 32;
private static final float DEFAULT_SET_LOAD_FACTOR = 0.98f;
@@ -141,9 +141,9 @@ class UsageRepr {
return owner;
}
private FMUsage(final int n, final int o) {
name = n;
owner = o;
private FMUsage(final int name, final int owner) {
this.name = name;
this.owner = owner;
}
private FMUsage(final DataInput in) {
@@ -156,9 +156,9 @@ class UsageRepr {
}
}
protected void save(final int tag, final DataOutput out) {
protected final void save(final byte tag, final DataOutput out) {
try {
out.writeInt(tag);
out.writeByte(tag);
out.writeInt(name);
out.writeInt(owner);
}
@@ -189,9 +189,9 @@ class UsageRepr {
public static class FieldUsage extends FMUsage {
public final TypeRepr.AbstractType type;
private FieldUsage(final DependencyContext context, final int n, final int o, final int d) {
super(n, o);
type = TypeRepr.getType(context, d);
private FieldUsage(final DependencyContext context, final int name, final int owner, final int descriptor) {
super(name, owner);
type = TypeRepr.getType(context, descriptor);
}
private FieldUsage(final DependencyContext context, final DataInput in) {
@@ -261,10 +261,10 @@ class UsageRepr {
public final TypeRepr.AbstractType[] argumentTypes;
public final TypeRepr.AbstractType returnType;
private MethodUsage(final DependencyContext context, final int n, final int o, final String d) {
super(n, o);
argumentTypes = TypeRepr.getType(context, Type.getArgumentTypes(d));
returnType = TypeRepr.getType(context, Type.getReturnType(d));
private MethodUsage(final DependencyContext context, final int name, final int owner, final String descriptor) {
super(name, owner);
argumentTypes = TypeRepr.getType(context, Type.getArgumentTypes(descriptor));
returnType = TypeRepr.getType(context, Type.getReturnType(descriptor));
}
private MethodUsage(final DependencyContext context, final DataInput in) {
@@ -330,7 +330,7 @@ class UsageRepr {
@Override
public void save(final DataOutput out) {
super.save(METAMETHOD_USAGE, out);
save(METAMETHOD_USAGE, out);
try {
out.writeInt(myArity);
}
@@ -361,20 +361,20 @@ class UsageRepr {
}
public static class ClassUsage extends Usage {
final int className;
final int myClassName;
@Override
public int getOwner() {
return className;
return myClassName;
}
private ClassUsage(final int n) {
className = n;
private ClassUsage(final int className) {
this.myClassName = className;
}
private ClassUsage(final DataInput in) {
try {
className = in.readInt();
myClassName = in.readInt();
}
catch (IOException e) {
throw new RuntimeException(e);
@@ -384,8 +384,8 @@ class UsageRepr {
@Override
public void save(final DataOutput out) {
try {
out.writeInt(CLASS_USAGE);
out.writeInt(className);
out.writeByte(CLASS_USAGE);
out.writeInt(myClassName);
}
catch (IOException e) {
throw new RuntimeException(e);
@@ -399,12 +399,12 @@ class UsageRepr {
final ClassUsage that = (ClassUsage)o;
return className == that.className;
return myClassName == that.myClassName;
}
@Override
public int hashCode() {
return className;
return myClassName;
}
}
@@ -416,8 +416,8 @@ class UsageRepr {
return className;
}
private ClassExtendsUsage(final int n) {
className = n;
private ClassExtendsUsage(final int className) {
this.className = className;
}
private ClassExtendsUsage(final DataInput in) {
@@ -432,7 +432,7 @@ class UsageRepr {
@Override
public void save(final DataOutput out) {
try {
out.writeInt(CLASS_EXTENDS_USAGE);
out.writeByte(CLASS_EXTENDS_USAGE);
out.writeInt(className);
}
catch (IOException e) {
@@ -459,8 +459,8 @@ class UsageRepr {
}
public static class ClassNewUsage extends ClassExtendsUsage {
public ClassNewUsage(int n) {
super(n);
public ClassNewUsage(int className) {
super(className);
}
private ClassNewUsage(final DataInput in) {
@@ -470,7 +470,7 @@ class UsageRepr {
@Override
public void save(final DataOutput out) {
try {
out.writeInt(CLASS_NEW_USAGE);
out.writeByte(CLASS_NEW_USAGE);
out.writeInt(className);
}
catch (IOException e) {
@@ -485,22 +485,27 @@ class UsageRepr {
}
public static class AnnotationUsage extends Usage {
public static final DataExternalizer<ElementType> elementTypeExternalizer = new DataExternalizer<ElementType>() {
public static final DataExternalizer<ElemType> elementTypeExternalizer = new DataExternalizer<ElemType>() {
@Override
public void save(final DataOutput out, final ElementType value) throws IOException {
out.writeUTF(value.toString());
public void save(final DataOutput out, final ElemType value) throws IOException {
out.writeInt(value.ordinal());
}
@Override
public ElementType read(final DataInput in) throws IOException {
final String s = in.readUTF();
return ElementType.valueOf(s);
public ElemType read(final DataInput in) throws IOException {
final int ordinal = in.readInt();
for (ElemType value : ElemType.values()) {
if (value.ordinal() == ordinal) {
return value;
}
}
throw new IOException("Error reading ElementType enum value; unknown ordinal: " + ordinal);
}
};
final TypeRepr.ClassType type;
final TIntHashSet usedArguments;
final Collection<ElementType> usedTargets;
final Set<ElemType> usedTargets;
public boolean satisfies(final Usage usage) {
if (usage instanceof AnnotationUsage) {
@@ -523,7 +528,7 @@ class UsageRepr {
boolean targetsSatisfy = false;
if (usedTargets != null) {
final Collection<ElementType> targets = new HashSet<ElementType>(usedTargets);
final Collection<ElemType> targets = EnumSet.copyOf(usedTargets);
targets.retainAll(annotationUsage.usedTargets);
@@ -536,9 +541,7 @@ class UsageRepr {
return false;
}
private AnnotationUsage(final TypeRepr.ClassType type,
final TIntHashSet usedArguments,
final Collection<ElementType> targets) {
private AnnotationUsage(final TypeRepr.ClassType type, final TIntHashSet usedArguments, final Set<ElemType> targets) {
this.type = type;
this.usedArguments = usedArguments;
this.usedTargets = targets;
@@ -550,7 +553,7 @@ class UsageRepr {
try {
type = (TypeRepr.ClassType)externalizer.read(in);
usedArguments = RW.read(new TIntHashSet(DEFAULT_SET_CAPACITY, DEFAULT_SET_LOAD_FACTOR), in);
usedTargets = RW.read(elementTypeExternalizer, new HashSet<ElementType>(), in);
usedTargets = (EnumSet<ElemType>)RW.read(elementTypeExternalizer, EnumSet.noneOf(ElemType.class), in);
}
catch (IOException e) {
throw new RuntimeException(e);
@@ -560,7 +563,7 @@ class UsageRepr {
@Override
public void save(final DataOutput out) {
try {
out.writeInt(ANNOTATION_USAGE);
out.writeByte(ANNOTATION_USAGE);
type.save(out);
RW.save(usedArguments, out);
RW.save(usedTargets, elementTypeExternalizer, out);
@@ -598,24 +601,15 @@ class UsageRepr {
}
}
public static Usage createFieldUsage(final DependencyContext context,
final int name,
final int owner,
final int descr) {
public static Usage createFieldUsage(final DependencyContext context, final int name, final int owner, final int descr) {
return context.getUsage(new FieldUsage(context, name, owner, descr));
}
public static Usage createFieldAssignUsage(final DependencyContext context,
final int name,
final int owner,
final int descr) {
public static Usage createFieldAssignUsage(final DependencyContext context, final int name, final int owner, final int descr) {
return context.getUsage(new FieldAssignUsage(context, name, owner, descr));
}
public static Usage createMethodUsage(final DependencyContext context,
final int name,
final int owner,
final String descr) {
public static Usage createMethodUsage(final DependencyContext context, final int name, final int owner, final String descr) {
return context.getUsage(new MethodUsage(context, name, owner, descr));
}
@@ -636,7 +630,7 @@ class UsageRepr {
return context.getUsage(new ClassNewUsage(name));
}
public static Usage createAnnotationUsage(final DependencyContext context, final TypeRepr.ClassType type, final TIntHashSet usedArguments, final Collection<ElementType> targets) {
public static Usage createAnnotationUsage(final DependencyContext context, final TypeRepr.ClassType type, final TIntHashSet usedArguments, final Set<ElemType> targets) {
return context.getUsage(new AnnotationUsage(type, usedArguments, targets));
}
@@ -649,7 +643,8 @@ class UsageRepr {
@Override
public Usage read(DataInput in) throws IOException {
switch (in.readInt()) {
final byte tag = in.readByte();
switch (tag) {
case CLASS_USAGE:
return context.getUsage(new ClassUsage(in));
@@ -208,7 +208,7 @@ public class OptimizedFileManager extends DefaultFileManager {
if (callback != null) {
final ClassReader reader = new ClassReader(buffer);
callback.associate(classFileName, Callbacks.getDefaultLookup(sourceFileName), reader);
callback.associate(classFileName, sourceFileName, reader);
}
myWriters.add(new DelayedClassFileWriter() {
@@ -169,7 +169,7 @@ public class GroovyBuilder extends ModuleLevelBuilder {
final String moduleName = moduleAndRoot.module.getName().toLowerCase(Locale.US);
context.getDataManager().getSourceToOutputMap(moduleName, moduleAndRoot.isTestRoot).appendData(sourcePath, outputPath);
}
callback.associate(outputPath, Callbacks.getDefaultLookup(sourcePath), new ClassReader(FileUtil.loadFileBytes(new File(outputPath))));
callback.associate(outputPath, sourcePath, new ClassReader(FileUtil.loadFileBytes(new File(outputPath))));
successfullyCompiledFiles.add(new File(sourcePath));
generatedEvent.add(moduleOutputPath, FileUtil.getRelativePath(moduleOutputPath, outputPath, '/'));