Skip to content

Commit

Permalink
ArC - fix AnnotationStore
Browse files Browse the repository at this point in the history
- AnnotationTarget was incorrectly used as a key in a Map
- resolves quarkusio#10593
  • Loading branch information
mkouba committed Jul 10, 2020
1 parent 68e666a commit 7f33d1e
Showing 1 changed file with 68 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@
import java.util.Collections;
import java.util.EnumMap;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.AnnotationTarget.Kind;
import org.jboss.jandex.DotName;
import org.jboss.jandex.FieldInfo;
import org.jboss.jandex.MethodInfo;

/**
* Applies {@link AnnotationsTransformer}s and caches the results of transformations.
Expand All @@ -22,7 +25,7 @@
*/
public final class AnnotationStore {

private final ConcurrentMap<AnnotationTarget, Collection<AnnotationInstance>> transformed;
private final ConcurrentMap<AnnotationTargetKey, Collection<AnnotationInstance>> transformed;

private final EnumMap<Kind, List<AnnotationsTransformer>> transformersMap;

Expand Down Expand Up @@ -50,7 +53,7 @@ public final class AnnotationStore {
*/
public Collection<AnnotationInstance> getAnnotations(AnnotationTarget target) {
if (transformed != null) {
return transformed.computeIfAbsent(target, this::transform);
return transformed.computeIfAbsent(new AnnotationTargetKey(target), this::transform);
}
return getOriginalAnnotations(target);
}
Expand Down Expand Up @@ -88,7 +91,8 @@ public boolean hasAnyAnnotation(AnnotationTarget target, Iterable<DotName> names
return Annotations.containsAny(getAnnotations(target), names);
}

private Collection<AnnotationInstance> transform(AnnotationTarget target) {
private Collection<AnnotationInstance> transform(AnnotationTargetKey key) {
AnnotationTarget target = key.target;
Collection<AnnotationInstance> annotations = getOriginalAnnotations(target);
List<AnnotationsTransformer> transformers = transformersMap.get(target.kind());
if (transformers.isEmpty()) {
Expand Down Expand Up @@ -144,4 +148,65 @@ public Transformation transform() {

}

/**
* We cannot use annotation target directly as a key in a Map. Only {@link MethodInfo} overrides equals/hashCode.
*/
static final class AnnotationTargetKey {

final AnnotationTarget target;

public AnnotationTargetKey(AnnotationTarget target) {
this.target = target;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
AnnotationTargetKey other = (AnnotationTargetKey) obj;
if (target.kind() != other.target.kind()) {
return false;
}
switch (target.kind()) {
case METHOD:
return target.asMethod().equals(other.target);
case FIELD:
FieldInfo field = target.asField();
FieldInfo otherField = other.target.asField();
return Objects.equals(field.name(), otherField.name())
&& Objects.equals(field.declaringClass().name(), otherField.declaringClass().name());
case CLASS:
return target.asClass().name().equals(other.target.asClass().name());
default:
throw unsupportedAnnotationTarget(target);
}
}

@Override
public int hashCode() {
switch (target.kind()) {
case METHOD:
return target.asMethod().hashCode();
case FIELD:
return Objects.hash(target.asField().name(), target.asField().declaringClass().name());
case CLASS:
return target.asClass().name().hashCode();
default:
throw unsupportedAnnotationTarget(target);
}
}

}

private static IllegalArgumentException unsupportedAnnotationTarget(AnnotationTarget target) {
return new IllegalArgumentException("Unsupported annotation target: " + target.kind());
}

}

0 comments on commit 7f33d1e

Please sign in to comment.