mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-158203 Allow JPS plugins to be notified when annotations on method return type or parameter types are changed
This commit is contained in:
@@ -88,13 +88,13 @@ public class ClassRepr extends Proto {
|
||||
}
|
||||
|
||||
public abstract static class Diff extends Difference {
|
||||
public abstract Specifier<TypeRepr.AbstractType> interfaces();
|
||||
public abstract Specifier<TypeRepr.AbstractType, Difference> interfaces();
|
||||
|
||||
public abstract Specifier<FieldRepr> fields();
|
||||
public abstract Specifier<FieldRepr, FieldRepr.Diff> fields();
|
||||
|
||||
public abstract Specifier<MethodRepr> methods();
|
||||
public abstract Specifier<MethodRepr, MethodRepr.Diff> methods();
|
||||
|
||||
public abstract Specifier<ElemType> targets();
|
||||
public abstract Specifier<ElemType, Difference> targets();
|
||||
|
||||
public abstract boolean retentionChanged();
|
||||
|
||||
@@ -150,22 +150,22 @@ public class ClassRepr extends Proto {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Difference.Specifier<TypeRepr.AbstractType> interfaces() {
|
||||
public Difference.Specifier<TypeRepr.AbstractType, Difference> interfaces() {
|
||||
return Difference.make(pastClass.myInterfaces, myInterfaces);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Difference.Specifier<FieldRepr> fields() {
|
||||
public Difference.Specifier<FieldRepr, FieldRepr.Diff> fields() {
|
||||
return Difference.make(pastClass.myFields, myFields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Difference.Specifier<MethodRepr> methods() {
|
||||
public Difference.Specifier<MethodRepr, MethodRepr.Diff> methods() {
|
||||
return Difference.make(pastClass.myMethods, myMethods);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Specifier<ElemType> targets() {
|
||||
public Specifier<ElemType, Difference> targets() {
|
||||
return Difference.make(pastClass.myAnnotationTargets, myAnnotationTargets);
|
||||
}
|
||||
|
||||
|
||||
+7
-4
@@ -29,7 +29,10 @@ import org.jetbrains.org.objectweb.asm.signature.SignatureVisitor;
|
||||
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.*;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author: db
|
||||
@@ -385,7 +388,7 @@ class ClassfileAnalyzer {
|
||||
processSignature(signature);
|
||||
|
||||
return new FieldVisitor(ASM_API_VERSION) {
|
||||
final List<TypeRepr.ClassType> annotations = new SmartList<TypeRepr.ClassType>();
|
||||
final Set<TypeRepr.ClassType> annotations = new THashSet<TypeRepr.ClassType>();
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
|
||||
@@ -413,8 +416,8 @@ class ClassfileAnalyzer {
|
||||
@Override
|
||||
public MethodVisitor visitMethod(final int access, final String n, final String desc, final String signature, final String[] exceptions) {
|
||||
final Ref<Object> defaultValue = Ref.create();
|
||||
final Collection<TypeRepr.ClassType> annotations = new SmartList<TypeRepr.ClassType>();
|
||||
final Collection<ParamAnnotation> paramAnnotations = new SmartList<ParamAnnotation>();
|
||||
final Set<TypeRepr.ClassType> annotations = new THashSet<TypeRepr.ClassType>();
|
||||
final Set<ParamAnnotation> paramAnnotations = new THashSet<ParamAnnotation>();
|
||||
processSignature(signature);
|
||||
|
||||
return new MethodVisitor(ASM_API_VERSION) {
|
||||
|
||||
+12
-10
@@ -43,21 +43,22 @@ abstract class Difference {
|
||||
public static final int SIGNATURE = 8;
|
||||
public static final int SUPERCLASS = 16;
|
||||
public static final int USAGES = 32;
|
||||
public static final int ANNOTATIONS = 64;
|
||||
|
||||
public interface Specifier<T> {
|
||||
public interface Specifier<T, D extends Difference> {
|
||||
Collection<T> added();
|
||||
|
||||
Collection<T> removed();
|
||||
|
||||
Collection<Pair<T, Difference>> changed();
|
||||
Collection<Pair<T, D>> changed();
|
||||
|
||||
boolean unchanged();
|
||||
}
|
||||
|
||||
public static <T> Specifier<T> make(final Set<T> past, final Set<T> now) {
|
||||
public static <T, D extends Difference> Specifier<T, D> make(final Set<T> past, final Set<T> now) {
|
||||
if (past == null) {
|
||||
final Collection<T> _now = Collections.unmodifiableCollection(now);
|
||||
return new Specifier<T>() {
|
||||
return new Specifier<T, D>() {
|
||||
public Collection<T> added() {
|
||||
return _now;
|
||||
}
|
||||
@@ -66,7 +67,7 @@ abstract class Difference {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public Collection<Pair<T, Difference>> changed() {
|
||||
public Collection<Pair<T, D>> changed() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@@ -84,9 +85,9 @@ abstract class Difference {
|
||||
|
||||
removed.removeAll(now);
|
||||
|
||||
final Set<Pair<T, Difference>> changed;
|
||||
final Set<Pair<T, D>> changed;
|
||||
if (canContainChangedElements(past, now)) {
|
||||
changed = new HashSet<Pair<T, Difference>>();
|
||||
changed = new HashSet<Pair<T, D>>();
|
||||
final Set<T> intersect = new HashSet<T>(past);
|
||||
final Map<T, T> nowMap = new HashMap<T, T>();
|
||||
|
||||
@@ -101,7 +102,8 @@ abstract class Difference {
|
||||
for (T x : intersect) {
|
||||
final Proto px = (Proto)x;
|
||||
final Proto py = (Proto)nowMap.get(x);
|
||||
final Difference diff = py.difference(px);
|
||||
//noinspection unchecked
|
||||
final D diff = (D)py.difference(px);
|
||||
|
||||
if (!diff.no()) {
|
||||
changed.add(Pair.create(x, diff));
|
||||
@@ -112,7 +114,7 @@ abstract class Difference {
|
||||
changed = Collections.emptySet();
|
||||
}
|
||||
|
||||
return new Specifier<T>() {
|
||||
return new Specifier<T, D>() {
|
||||
public Collection<T> added() {
|
||||
return added;
|
||||
}
|
||||
@@ -121,7 +123,7 @@ abstract class Difference {
|
||||
return removed;
|
||||
}
|
||||
|
||||
public Collection<Pair<T, Difference>> changed() {
|
||||
public Collection<Pair<T, D>> changed() {
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -39,7 +38,7 @@ class FieldRepr extends ProtoMember {
|
||||
final int descriptor,
|
||||
final int signature,
|
||||
@NotNull
|
||||
final List<TypeRepr.ClassType> annotations, final Object value) {
|
||||
final Set<TypeRepr.ClassType> annotations, final Object value) {
|
||||
super(access, signature, name, TypeRepr.getType(context, descriptor), annotations, value);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.builders.storage.BuildDataCorruptedException;
|
||||
import org.jetbrains.jps.incremental.storage.FileKeyDescriptor;
|
||||
import org.jetbrains.jps.service.JpsServiceManager;
|
||||
import org.jetbrains.org.objectweb.asm.ClassReader;
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||
|
||||
@@ -954,6 +955,9 @@ public class Mappings {
|
||||
|
||||
final boolean myEasyMode; // true means: no need to search for affected files, only preprocess data for integrate
|
||||
|
||||
private final Iterable<MemberAnnotationsChangeTracker> myAnnotationChangeTracker =
|
||||
JpsServiceManager.getInstance().getExtensions(MemberAnnotationsChangeTracker.class);
|
||||
|
||||
private class DelayedWorks {
|
||||
class Triple {
|
||||
final int owner;
|
||||
@@ -1055,9 +1059,9 @@ public class Mappings {
|
||||
final public Set<UsageRepr.AnnotationUsage> myAnnotationQuery = new HashSet<UsageRepr.AnnotationUsage>();
|
||||
final public Map<UsageRepr.Usage, Util.UsageConstraint> myUsageConstraints = new HashMap<UsageRepr.Usage, Util.UsageConstraint>();
|
||||
|
||||
final Difference.Specifier<ClassRepr> myClassDiff;
|
||||
final Difference.Specifier<ClassRepr, ClassRepr.Diff> myClassDiff;
|
||||
|
||||
private DiffState(Difference.Specifier<ClassRepr> classDiff) {
|
||||
private DiffState(Difference.Specifier<ClassRepr, ClassRepr.Diff> classDiff) {
|
||||
this.myClassDiff = classDiff;
|
||||
}
|
||||
}
|
||||
@@ -1395,7 +1399,7 @@ public class Mappings {
|
||||
}
|
||||
|
||||
private void processChangedMethods(final DiffState state, final ClassRepr.Diff diff, final ClassRepr it) {
|
||||
final Collection<Pair<MethodRepr, Difference>> changed = diff.methods().changed();
|
||||
final Collection<Pair<MethodRepr, MethodRepr.Diff>> changed = diff.methods().changed();
|
||||
if (changed.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -1404,9 +1408,9 @@ public class Mappings {
|
||||
assert myFuture != null;
|
||||
assert myAffectedFiles != null;
|
||||
|
||||
for (final Pair<MethodRepr, Difference> mr : changed) {
|
||||
for (final Pair<MethodRepr, MethodRepr.Diff> mr : changed) {
|
||||
final MethodRepr m = mr.first;
|
||||
final MethodRepr.Diff d = (MethodRepr.Diff)mr.second;
|
||||
final MethodRepr.Diff d = mr.second;
|
||||
final boolean throwsChanged = !d.exceptions().unchanged();
|
||||
|
||||
debug("Method: ", m.name);
|
||||
@@ -1427,7 +1431,7 @@ public class Mappings {
|
||||
boolean affected = false;
|
||||
boolean constrained = false;
|
||||
|
||||
final Set<UsageRepr.Usage> usages = new HashSet<UsageRepr.Usage>();
|
||||
final Set<UsageRepr.Usage> usages = new THashSet<UsageRepr.Usage>();
|
||||
|
||||
if (d.packageLocalOn()) {
|
||||
debug("Method became package-private, affecting method usages outside the package");
|
||||
@@ -1463,6 +1467,7 @@ public class Mappings {
|
||||
}
|
||||
|
||||
state.myAffectedUsages.addAll(usages);
|
||||
affected = true;
|
||||
}
|
||||
}
|
||||
else if ((d.base() & Difference.ACCESS) > 0) {
|
||||
@@ -1473,6 +1478,7 @@ public class Mappings {
|
||||
debug("Added static or private specifier or removed static specifier --- affecting method usages");
|
||||
myFuture.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), usages, state.myDependants);
|
||||
state.myAffectedUsages.addAll(usages);
|
||||
affected = true;
|
||||
}
|
||||
|
||||
if ((d.addedModifiers() & Opcodes.ACC_STATIC) > 0) {
|
||||
@@ -1494,15 +1500,38 @@ public class Mappings {
|
||||
if (!affected) {
|
||||
myFuture.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), usages, state.myDependants);
|
||||
state.myAffectedUsages.addAll(usages);
|
||||
affected = true;
|
||||
}
|
||||
|
||||
for (final UsageRepr.Usage usage : usages) {
|
||||
state.myUsageConstraints.put(usage, myFuture.new InheritanceConstraint(it.name));
|
||||
}
|
||||
constrained = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((!affected || constrained) && (d.base() & Difference.ANNOTATIONS) > 0) {
|
||||
final Difference.Specifier<TypeRepr.ClassType, Difference> annotationsDiff = d.annotations();
|
||||
final Difference.Specifier<ParamAnnotation, Difference> paramAnnotationsDiff = d.parameterAnnotations();
|
||||
for (MemberAnnotationsChangeTracker extension : myAnnotationChangeTracker) {
|
||||
final MemberAnnotationsChangeTracker.Action action = extension.methodAnnotationsChanged(m, annotationsDiff, paramAnnotationsDiff);
|
||||
if (action == MemberAnnotationsChangeTracker.Action.RECOMPILE_USAGES) {
|
||||
debug("Extension "+extension.getClass().getName()+" requested recompilation because of changes in annotations list --- affecting method usages");
|
||||
myFuture.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), usages, state.myDependants);
|
||||
state.myAffectedUsages.addAll(usages);
|
||||
if (constrained) {
|
||||
// remove any constraints so that all usages of this method are recompiled
|
||||
for (UsageRepr.Usage usage : usages) {
|
||||
state.myUsageConstraints.remove(usage);
|
||||
}
|
||||
}
|
||||
affected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
debug("End of changed methods processing");
|
||||
@@ -1646,15 +1675,15 @@ public class Mappings {
|
||||
}
|
||||
|
||||
private boolean processChangedFields(final DiffState state, final ClassRepr.Diff diff, final ClassRepr it) {
|
||||
final Collection<Pair<FieldRepr, Difference>> changed = diff.fields().changed();
|
||||
final Collection<Pair<FieldRepr, FieldRepr.Diff>> changed = diff.fields().changed();
|
||||
if (changed.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
debug("Processing changed fields:");
|
||||
assert myFuture != null;
|
||||
|
||||
for (final Pair<FieldRepr, Difference> f : changed) {
|
||||
final Difference d = f.second;
|
||||
for (final Pair<FieldRepr, FieldRepr.Diff> f : changed) {
|
||||
final FieldRepr.Diff d = f.second;
|
||||
final FieldRepr field = f.first;
|
||||
|
||||
debug("Field: ", field.name);
|
||||
@@ -1684,11 +1713,13 @@ public class Mappings {
|
||||
|
||||
if (d.base() != Difference.NONE) {
|
||||
final TIntHashSet propagated = myFuture.propagateFieldAccess(field.name, it.name);
|
||||
boolean affected = false;
|
||||
|
||||
if ((d.base() & Difference.TYPE) > 0 || (d.base() & Difference.SIGNATURE) > 0) {
|
||||
debug("Type or signature changed --- affecting field usages");
|
||||
myFuture
|
||||
.affectFieldUsages(field, propagated, field.createUsage(myContext, it.name), state.myAffectedUsages, state.myDependants);
|
||||
affected = true;
|
||||
}
|
||||
else if ((d.base() & Difference.ACCESS) > 0) {
|
||||
if ((d.addedModifiers() & Opcodes.ACC_STATIC) > 0 ||
|
||||
@@ -1698,10 +1729,10 @@ public class Mappings {
|
||||
debug("Added/removed static modifier or added private/volatile modifier --- affecting field usages");
|
||||
myFuture
|
||||
.affectFieldUsages(field, propagated, field.createUsage(myContext, it.name), state.myAffectedUsages, state.myDependants);
|
||||
affected = true;
|
||||
}
|
||||
else {
|
||||
boolean affected = false;
|
||||
final Set<UsageRepr.Usage> usages = new HashSet<UsageRepr.Usage>();
|
||||
final Set<UsageRepr.Usage> usages = new THashSet<UsageRepr.Usage>();
|
||||
|
||||
if ((d.addedModifiers() & Opcodes.ACC_FINAL) > 0) {
|
||||
debug("Added final modifier --- affecting field assign usages");
|
||||
@@ -1715,6 +1746,7 @@ public class Mappings {
|
||||
if (!affected) {
|
||||
myFuture.affectFieldUsages(field, propagated, field.createUsage(myContext, it.name), usages, state.myDependants);
|
||||
state.myAffectedUsages.addAll(usages);
|
||||
affected = true;
|
||||
}
|
||||
|
||||
for (final UsageRepr.Usage usage : usages) {
|
||||
@@ -1728,6 +1760,26 @@ public class Mappings {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!affected && (d.base() & Difference.ANNOTATIONS) > 0) {
|
||||
final Difference.Specifier<TypeRepr.ClassType, Difference> annotationsDiff = d.annotations();
|
||||
for (MemberAnnotationsChangeTracker extension : myAnnotationChangeTracker) {
|
||||
final MemberAnnotationsChangeTracker.Action action = extension.fieldAnnotationsChanged(field, annotationsDiff);
|
||||
if (action == MemberAnnotationsChangeTracker.Action.RECOMPILE_USAGES) {
|
||||
debug("Extension "+extension.getClass().getName()+" requested recompilation because of changes in annotations list --- affecting field usages");
|
||||
final Set<UsageRepr.Usage> usages = new THashSet<UsageRepr.Usage>();
|
||||
myFuture.affectFieldUsages(field, propagated, field.createUsage(myContext, it.name), usages, state.myDependants);
|
||||
state.myAffectedUsages.addAll(usages);
|
||||
// remove any constraints to ensure all field usages are recompiled
|
||||
for (UsageRepr.Usage usage : usages) {
|
||||
state.myUsageConstraints.remove(usage);
|
||||
}
|
||||
affected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
debug("End of changed fields processing");
|
||||
@@ -1736,7 +1788,7 @@ public class Mappings {
|
||||
}
|
||||
|
||||
private boolean processChangedClasses(final DiffState state) {
|
||||
final Collection<Pair<ClassRepr, Difference>> changedClasses = state.myClassDiff.changed();
|
||||
final Collection<Pair<ClassRepr, ClassRepr.Diff>> changedClasses = state.myClassDiff.changed();
|
||||
if (!changedClasses.isEmpty()) {
|
||||
debug("Processing changed classes:");
|
||||
assert myFuture != null;
|
||||
@@ -1744,9 +1796,9 @@ public class Mappings {
|
||||
|
||||
final Util.FileFilterConstraint fileFilterConstraint = myFilter != null? myPresent.new FileFilterConstraint(myFilter) : null;
|
||||
|
||||
for (final Pair<ClassRepr, Difference> changed : changedClasses) {
|
||||
for (final Pair<ClassRepr, ClassRepr.Diff> changed : changedClasses) {
|
||||
final ClassRepr changedClass = changed.first;
|
||||
final ClassRepr.Diff diff = (ClassRepr.Diff)changed.second;
|
||||
final ClassRepr.Diff diff = changed.second;
|
||||
|
||||
myDelta.addChangedClass(changedClass.name);
|
||||
|
||||
@@ -2154,7 +2206,7 @@ public class Mappings {
|
||||
final File fileName = compiledFile.myFileName;
|
||||
final Set<ClassRepr> classes = compiledFile.myFileClasses;
|
||||
final Set<ClassRepr> pastClasses = (Set<ClassRepr>)mySourceFileToClasses.get(fileName);
|
||||
final DiffState state = new DiffState(Difference.make(pastClasses, classes));
|
||||
final DiffState state = new DiffState(Difference.<ClassRepr, ClassRepr.Diff>make(pastClasses, classes));
|
||||
|
||||
if (!processChangedClasses(state)) {
|
||||
if (!myEasyMode) {
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* 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 org.jetbrains.jps.builders.java.dependencyView;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: 25-Jul-16
|
||||
*/
|
||||
public abstract class MemberAnnotationsChangeTracker {
|
||||
|
||||
public enum Action {
|
||||
NO_ACTION, RECOMPILE_USAGES;
|
||||
}
|
||||
|
||||
public abstract Action methodAnnotationsChanged(
|
||||
MethodRepr method,
|
||||
Difference.Specifier<TypeRepr.ClassType, Difference> annotationsDiff,
|
||||
Difference.Specifier<ParamAnnotation, Difference> paramAnnotationsDiff
|
||||
);
|
||||
|
||||
public abstract Action fieldAnnotationsChanged(FieldRepr field, Difference.Specifier<TypeRepr.ClassType, Difference> annotationsDiff);
|
||||
|
||||
}
|
||||
+35
-16
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.jetbrains.jps.builders.java.dependencyView;
|
||||
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.io.DataExternalizer;
|
||||
import com.intellij.util.io.DataInputOutputUtil;
|
||||
import gnu.trove.THashSet;
|
||||
@@ -27,7 +26,10 @@ import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author: db
|
||||
@@ -39,12 +41,15 @@ class MethodRepr extends ProtoMember {
|
||||
boolean satisfy(MethodRepr m);
|
||||
}
|
||||
|
||||
public final Collection<ParamAnnotation> myParameterAnnotations;
|
||||
public final Set<ParamAnnotation> myParameterAnnotations;
|
||||
public final TypeRepr.AbstractType[] myArgumentTypes;
|
||||
public final Set<TypeRepr.AbstractType> myExceptions;
|
||||
|
||||
public abstract class Diff extends Difference {
|
||||
public abstract Specifier<TypeRepr.AbstractType> exceptions();
|
||||
public static abstract class Diff extends ProtoMember.Diff {
|
||||
|
||||
public abstract Specifier<ParamAnnotation, Difference> parameterAnnotations();
|
||||
|
||||
public abstract Specifier<TypeRepr.AbstractType, Difference> exceptions();
|
||||
|
||||
public abstract boolean defaultAdded();
|
||||
|
||||
@@ -52,11 +57,24 @@ class MethodRepr extends ProtoMember {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Difference difference(final Proto past) {
|
||||
public Diff difference(final Proto past) {
|
||||
final MethodRepr m = (MethodRepr)past;
|
||||
final Difference diff = super.difference(past);
|
||||
final Difference.Specifier<TypeRepr.AbstractType> excs = Difference.make(((MethodRepr)past).myExceptions, myExceptions);
|
||||
final Difference.Specifier<TypeRepr.AbstractType, Difference> excs = Difference.make(m.myExceptions, myExceptions);
|
||||
final Difference.Specifier<TypeRepr.ClassType, Difference> annotations = Difference.make(m.myAnnotations, myAnnotations);
|
||||
final Difference.Specifier<ParamAnnotation, Difference> paramAnnotations = Difference.make(m.myParameterAnnotations, myParameterAnnotations);
|
||||
|
||||
return new Diff() {
|
||||
@Override
|
||||
public Specifier<TypeRepr.ClassType, Difference> annotations() {
|
||||
return annotations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Specifier<ParamAnnotation, Difference> parameterAnnotations() {
|
||||
return paramAnnotations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int addedModifiers() {
|
||||
return diff.addedModifiers();
|
||||
@@ -69,27 +87,28 @@ class MethodRepr extends ProtoMember {
|
||||
|
||||
@Override
|
||||
public boolean no() {
|
||||
return base() == NONE && !defaultAdded() && !defaultRemoved() && excs.unchanged();
|
||||
return base() == NONE && !defaultAdded() && !defaultRemoved() && excs.unchanged() && paramAnnotations.unchanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean defaultAdded() {
|
||||
return hasValue() && !((MethodRepr)past).hasValue();
|
||||
return hasValue() && !m.hasValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean defaultRemoved() {
|
||||
return !hasValue() && ((MethodRepr)past).hasValue();
|
||||
return !hasValue() && m.hasValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Specifier<TypeRepr.AbstractType> exceptions() {
|
||||
public Specifier<TypeRepr.AbstractType, Difference> exceptions() {
|
||||
return excs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int base() {
|
||||
return diff.base();
|
||||
final int base = diff.base();
|
||||
return paramAnnotations.unchanged()? base : base | Difference.ANNOTATIONS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,7 +118,7 @@ class MethodRepr extends ProtoMember {
|
||||
|
||||
@Override
|
||||
public boolean hadValue() {
|
||||
return ((MethodRepr)past).hasValue();
|
||||
return m.hasValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -128,7 +147,7 @@ class MethodRepr extends ProtoMember {
|
||||
final int name,
|
||||
final int signature,
|
||||
final String descriptor,
|
||||
final Collection<TypeRepr.ClassType> annotations, Collection<ParamAnnotation> parameterAnnotations, final String[] exceptions,
|
||||
final Set<TypeRepr.ClassType> annotations, Set<ParamAnnotation> parameterAnnotations, final String[] exceptions,
|
||||
final Object defaultValue) {
|
||||
super(accessFlags, signature, name, TypeRepr.getType(context, Type.getReturnType(descriptor)), annotations, defaultValue);
|
||||
myParameterAnnotations = parameterAnnotations;
|
||||
@@ -149,7 +168,7 @@ class MethodRepr extends ProtoMember {
|
||||
myExceptions = (Set<TypeRepr.AbstractType>)RW.read(externalizer, new THashSet<TypeRepr.AbstractType>(0), in);
|
||||
|
||||
final DataExternalizer<TypeRepr.ClassType> clsTypeExternalizer = TypeRepr.classTypeExternalizer(context);
|
||||
myParameterAnnotations = RW.read(new DataExternalizer<ParamAnnotation>() {
|
||||
myParameterAnnotations = (Set<ParamAnnotation>)RW.read(new DataExternalizer<ParamAnnotation>() {
|
||||
@Override
|
||||
public void save(@NotNull DataOutput out, ParamAnnotation value) throws IOException {
|
||||
value.save(out);
|
||||
@@ -158,7 +177,7 @@ class MethodRepr extends ProtoMember {
|
||||
public ParamAnnotation read(@NotNull DataInput in) throws IOException {
|
||||
return new ParamAnnotation(clsTypeExternalizer, in);
|
||||
}
|
||||
}, new SmartList<ParamAnnotation>(), in);
|
||||
}, new THashSet<ParamAnnotation>(), in);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new BuildDataCorruptedException(e);
|
||||
|
||||
+22
-7
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
package org.jetbrains.jps.builders.java.dependencyView;
|
||||
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.io.DataInputOutputUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.builders.storage.BuildDataCorruptedException;
|
||||
@@ -27,7 +27,7 @@ import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author: db
|
||||
@@ -38,7 +38,7 @@ abstract class ProtoMember extends Proto {
|
||||
@NotNull
|
||||
public final TypeRepr.AbstractType myType;
|
||||
@NotNull
|
||||
public final Collection<TypeRepr.ClassType> myAnnotations;
|
||||
public final Set<TypeRepr.ClassType> myAnnotations;
|
||||
public final Object myValue;
|
||||
|
||||
private static abstract class DataDescriptor<T> {
|
||||
@@ -201,7 +201,7 @@ abstract class ProtoMember extends Proto {
|
||||
@NotNull
|
||||
final TypeRepr.AbstractType t,
|
||||
@NotNull
|
||||
Collection<TypeRepr.ClassType> annotations,
|
||||
Set<TypeRepr.ClassType> annotations,
|
||||
final Object value) {
|
||||
super(access, signature, name);
|
||||
myType = t;
|
||||
@@ -214,7 +214,7 @@ abstract class ProtoMember extends Proto {
|
||||
try {
|
||||
myType = TypeRepr.externalizer(context).read(in);
|
||||
myValue = loadTyped(in);
|
||||
myAnnotations = RW.read(TypeRepr.classTypeExternalizer(context), new SmartList<TypeRepr.ClassType>(), in);
|
||||
myAnnotations = (Set<TypeRepr.ClassType>)RW.read(TypeRepr.classTypeExternalizer(context), new THashSet<TypeRepr.ClassType>(), in);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new BuildDataCorruptedException(e);
|
||||
@@ -278,7 +278,11 @@ abstract class ProtoMember extends Proto {
|
||||
RW.save(myAnnotations, out);
|
||||
}
|
||||
|
||||
public Difference difference(final Proto past) {
|
||||
public abstract static class Diff extends Difference {
|
||||
public abstract Specifier<TypeRepr.ClassType, Difference> annotations();
|
||||
}
|
||||
|
||||
public Diff difference(final Proto past) {
|
||||
final ProtoMember m = (ProtoMember)past;
|
||||
final Difference diff = super.difference(past);
|
||||
int base = diff.base();
|
||||
@@ -287,6 +291,12 @@ abstract class ProtoMember extends Proto {
|
||||
base |= Difference.TYPE;
|
||||
}
|
||||
|
||||
final Difference.Specifier<TypeRepr.ClassType, Difference> annotations = Difference.make(m.myAnnotations, myAnnotations);
|
||||
|
||||
if (!annotations.unchanged()) {
|
||||
base |= Difference.ANNOTATIONS;
|
||||
}
|
||||
|
||||
switch ((myValue == null ? 0 : 1) + (m.myValue == null ? 0 : 2)) {
|
||||
case 3:
|
||||
if (!myValue.equals(m.myValue)) {
|
||||
@@ -308,7 +318,12 @@ abstract class ProtoMember extends Proto {
|
||||
|
||||
final int newBase = base;
|
||||
|
||||
return new Difference() {
|
||||
return new Diff() {
|
||||
@Override
|
||||
public Specifier<TypeRepr.ClassType, Difference> annotations() {
|
||||
return annotations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int base() {
|
||||
return newBase;
|
||||
|
||||
Reference in New Issue
Block a user