mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
incremental build: recompile usages of annotations containing TYPE_USE target on any target set change (IDEA-180438)
This commit is contained in:
+14
@@ -0,0 +1,14 @@
|
||||
Cleaning output files:
|
||||
out/production/AddAnnotationTargetTypeUse/A.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/A.java
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/AddAnnotationTargetTypeUse/C.class
|
||||
out/production/AddAnnotationTargetTypeUse/C2.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/C.java
|
||||
src/C2.java
|
||||
End of files
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
|
||||
@Target({TYPE, FIELD, METHOD, TYPE_USE})
|
||||
public @interface A {
|
||||
int value() default 3;
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
|
||||
@Target({TYPE, FIELD, TYPE_USE})
|
||||
public @interface A {
|
||||
int value() default 3;
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
@A(10)
|
||||
public class C {
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
public class C2 {
|
||||
|
||||
@A(30)
|
||||
int field;
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
Cleaning output files:
|
||||
out/production/AddTypeUseAnnotationTarget/A.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/A.java
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/AddTypeUseAnnotationTarget/C.class
|
||||
out/production/AddTypeUseAnnotationTarget/C2.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/C.java
|
||||
src/C2.java
|
||||
End of files
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
|
||||
@Target({TYPE, FIELD, TYPE_USE})
|
||||
public @interface A {
|
||||
int value() default 3;
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
|
||||
@Target({TYPE, FIELD})
|
||||
public @interface A {
|
||||
int value() default 3;
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
@A(10)
|
||||
public class C {
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
public class C2 {
|
||||
|
||||
@A(30)
|
||||
int field;
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
Cleaning output files:
|
||||
out/production/RemoveTypeUseAnnotationTarget/A.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/A.java
|
||||
End of files
|
||||
Cleaning output files:
|
||||
out/production/RemoveTypeUseAnnotationTarget/C.class
|
||||
out/production/RemoveTypeUseAnnotationTarget/C2.class
|
||||
End of files
|
||||
Compiling files:
|
||||
src/C.java
|
||||
src/C2.java
|
||||
End of files
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
|
||||
@Target({TYPE, FIELD})
|
||||
public @interface A {
|
||||
int value() default 3;
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
|
||||
@Target({TYPE, FIELD, TYPE_USE})
|
||||
public @interface A {
|
||||
int value() default 3;
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
@A(10)
|
||||
public class C {
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
public class C2 {
|
||||
|
||||
@A(30)
|
||||
int field;
|
||||
}
|
||||
@@ -72,6 +72,11 @@ public class ClassRepr extends ClassFileRepr {
|
||||
return myRetentionPolicy;
|
||||
}
|
||||
|
||||
public Set<ElemType> getAnnotationTargets() {
|
||||
final Set<ElemType> targets = myAnnotationTargets;
|
||||
return targets != null ? Collections.unmodifiableSet(targets) : Collections.emptySet();
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return (access & Opcodes.ACC_INTERFACE) != 0;
|
||||
}
|
||||
@@ -94,6 +99,8 @@ public class ClassRepr extends ClassFileRepr {
|
||||
|
||||
public abstract boolean extendsAdded();
|
||||
|
||||
public abstract boolean targetAttributeCategoryMightChange();
|
||||
|
||||
public boolean no() {
|
||||
return base() == NONE &&
|
||||
interfaces().unchanged() &&
|
||||
@@ -155,6 +162,17 @@ public class ClassRepr extends ClassFileRepr {
|
||||
(myRetentionPolicy == pastClass.myRetentionPolicy));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean targetAttributeCategoryMightChange() {
|
||||
final Specifier<ElemType, Difference> targetsDiff = targets();
|
||||
if (!targetsDiff.unchanged()) {
|
||||
return targetsDiff.added().contains(ElemType.TYPE_USE) ||
|
||||
targetsDiff.removed().contains(ElemType.TYPE_USE) ||
|
||||
pastClass.getAnnotationTargets().contains(ElemType.TYPE_USE);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int base() {
|
||||
return d;
|
||||
|
||||
@@ -1942,6 +1942,10 @@ public class Mappings {
|
||||
debug("Retention policy change detected, adding class usage to affected usages");
|
||||
state.myAffectedUsages.add(changedClass.createUsage());
|
||||
}
|
||||
else if (diff.targetAttributeCategoryMightChange()) {
|
||||
debug("Annotation's attribute category in bytecode might be affected because of TYPE_USE target, adding class usage to affected usages");
|
||||
state.myAffectedUsages.add(changedClass.createUsage());
|
||||
}
|
||||
else {
|
||||
final Collection<ElemType> removedtargets = diff.targets().removed();
|
||||
|
||||
@@ -1955,9 +1959,9 @@ public class Mappings {
|
||||
|
||||
if (!removedtargets.isEmpty()) {
|
||||
debug("Removed some annotation targets, adding annotation query");
|
||||
final UsageRepr.AnnotationUsage annotationUsage = (UsageRepr.AnnotationUsage)UsageRepr
|
||||
.createAnnotationUsage(myContext, TypeRepr.createClassType(myContext, changedClass.name), null, EnumSet.copyOf(removedtargets));
|
||||
state.myAnnotationQuery.add(annotationUsage);
|
||||
state.myAnnotationQuery.add((UsageRepr.AnnotationUsage)UsageRepr.createAnnotationUsage(
|
||||
myContext, TypeRepr.createClassType(myContext, changedClass.name), null, EnumSet.copyOf(removedtargets)
|
||||
));
|
||||
}
|
||||
|
||||
for (final MethodRepr m : diff.methods().added()) {
|
||||
@@ -2186,8 +2190,9 @@ public class Mappings {
|
||||
|
||||
for (UsageRepr.Usage usage : depUsages) {
|
||||
if (usage instanceof UsageRepr.AnnotationUsage) {
|
||||
final UsageRepr.AnnotationUsage annotationUsage = (UsageRepr.AnnotationUsage)usage;
|
||||
for (final UsageRepr.AnnotationUsage query : state.myAnnotationQuery) {
|
||||
if (query.satisfies(usage)) {
|
||||
if (query.satisfies(annotationUsage)) {
|
||||
debug("Added file due to annotation query");
|
||||
myAffectedFiles.add(depFile);
|
||||
return;
|
||||
|
||||
+24
-30
@@ -546,38 +546,32 @@ class UsageRepr {
|
||||
final TIntHashSet myUsedArguments;
|
||||
final Set<ElemType> myUsedTargets;
|
||||
|
||||
public boolean satisfies(final Usage usage) {
|
||||
if (usage instanceof AnnotationUsage) {
|
||||
final AnnotationUsage annotationUsage = (AnnotationUsage)usage;
|
||||
|
||||
if (!myType.equals(annotationUsage.myType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean argumentsSatisfy = false;
|
||||
|
||||
if (myUsedArguments != null) {
|
||||
final TIntHashSet arguments = new TIntHashSet(myUsedArguments.toArray());
|
||||
|
||||
arguments.removeAll(annotationUsage.myUsedArguments.toArray());
|
||||
|
||||
argumentsSatisfy = !arguments.isEmpty();
|
||||
}
|
||||
|
||||
boolean targetsSatisfy = false;
|
||||
|
||||
if (myUsedTargets != null) {
|
||||
final Collection<ElemType> targets = EnumSet.copyOf(myUsedTargets);
|
||||
|
||||
targets.retainAll(annotationUsage.myUsedTargets);
|
||||
|
||||
targetsSatisfy = !targets.isEmpty();
|
||||
}
|
||||
|
||||
return argumentsSatisfy || targetsSatisfy;
|
||||
public boolean satisfies(final AnnotationUsage annotationUsage) {
|
||||
if (!myType.equals(annotationUsage.myType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
boolean argumentsSatisfy = false;
|
||||
|
||||
if (myUsedArguments != null) {
|
||||
final TIntHashSet arguments = new TIntHashSet(myUsedArguments.toArray());
|
||||
|
||||
arguments.removeAll(annotationUsage.myUsedArguments.toArray());
|
||||
|
||||
argumentsSatisfy = !arguments.isEmpty();
|
||||
}
|
||||
|
||||
boolean targetsSatisfy = false;
|
||||
|
||||
if (myUsedTargets != null) {
|
||||
final Collection<ElemType> targets = EnumSet.copyOf(myUsedTargets);
|
||||
|
||||
targets.retainAll(annotationUsage.myUsedTargets);
|
||||
|
||||
targetsSatisfy = !targets.isEmpty();
|
||||
}
|
||||
|
||||
return argumentsSatisfy || targetsSatisfy;
|
||||
}
|
||||
|
||||
private AnnotationUsage(final TypeRepr.ClassType type, final TIntHashSet usedArguments, final Set<ElemType> targets) {
|
||||
|
||||
@@ -28,6 +28,14 @@ public class AnnotationTest extends IncrementalTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testAddAnnotationTargetTypeUse() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testAddTypeUseAnnotationTarget() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testAddAnnotationTypeMemberWithDefaultValue() {
|
||||
doTest();
|
||||
}
|
||||
@@ -97,6 +105,10 @@ public class AnnotationTest extends IncrementalTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testRemoveTypeUseAnnotationTarget() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testRemoveAnnotationTypeMember() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user