Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions src/main/java/org/codehaus/groovy/ast/AnnotationNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,11 @@ public class AnnotationNode extends ASTNode {
public static final int IMPORT_TARGET = 1 << 12;
public static final int TYPE_TARGET = ANNOTATION_TARGET | 1; // GROOVY-7151

private static final int UNINITIALIZED = -1;

private final ClassNode classNode;
private Map<String, Expression> members;
private int allowedTargets = UNINITIALIZED;

public AnnotationNode(final ClassNode type) {
classNode = requireNonNull(type);
Expand Down Expand Up @@ -88,7 +91,8 @@ private void ensureMembers() {
}

@Deprecated(since = "6.0.0")
public void setAllowedTargets(final int ignored) {
public void setAllowedTargets(final int bitmap) {
allowedTargets = bitmap;
}

@Deprecated(since = "6.0.0")
Expand Down Expand Up @@ -129,11 +133,20 @@ public boolean isBuiltIn() {
}

public boolean isTargetAllowed(final int target) {
int cached = allowedTargets;
if (cached == UNINITIALIZED) {
cached = computeAllowedTargets();
allowedTargets = cached;
}
return (target & cached) == target;
}

private int computeAllowedTargets() {
if (!(classNode.isPrimaryClassNode() || classNode.isResolved()))
throw new IllegalStateException("cannot check target at this time");

// GROOVY-6526: check class for @Target
int allowedTargets = classNode.redirect().getNodeMetaData(Target.class, (k) -> {
int targets = classNode.redirect().getNodeMetaData(Target.class, (k) -> {
for (AnnotationNode an : classNode.getAnnotations()) {
if ("java.lang.annotation.Target".equals(an.getClassNode().getName())
&& an.getMember("value") instanceof ListExpression list) {
Expand Down Expand Up @@ -165,7 +178,7 @@ public boolean isTargetAllowed(final int target) {
});

// check @ExtendedTarget for Groovy-specific element types
allowedTargets |= classNode.redirect().getNodeMetaData(ExtendedTarget.class, (k) -> {
targets |= classNode.redirect().getNodeMetaData(ExtendedTarget.class, (k) -> {
for (AnnotationNode an : classNode.getAnnotations()) {
if ("groovy.lang.annotation.ExtendedTarget".equals(an.getClassNode().getName())) {
Expression member = an.getMember("value");
Expand All @@ -183,7 +196,7 @@ public boolean isTargetAllowed(final int target) {
return 0;
});

return (target & allowedTargets) == target;
return targets;
}

private static int extendedElementTypeBits(final Expression e) {
Expand Down
Loading