diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/PackageScopeTests.java b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/PackageScopeTests.java
index 30b516337a..7c606dcf8b 100644
--- a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/PackageScopeTests.java
+++ b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/PackageScopeTests.java
@@ -270,4 +270,16 @@ public void testPackageScope8() {
method = findMethod(getCUDeclFor("Foo.groovy"), "method4");
assertTrue("Expected protected but was: " + Modifier.toString(method.modifiers), Modifier.isProtected(method.modifiers));
}
+
+ @Test // https://issues.apache.org/jira/browse/GROOVY-8940
+ public void testPackageScope9() {
+ String[] sources = {
+ "Tag.groovy",
+ "@groovy.transform.PackageScope\n" +
+ "@interface Tag {\n" +
+ "}\n",
+ };
+
+ runNegativeTest(sources, "");
+ }
}
diff --git a/base/org.codehaus.groovy24/.checkstyle b/base/org.codehaus.groovy24/.checkstyle
index fa7b9f67d2..4ba524fc8f 100644
--- a/base/org.codehaus.groovy24/.checkstyle
+++ b/base/org.codehaus.groovy24/.checkstyle
@@ -16,6 +16,7 @@
+
diff --git a/base/org.codehaus.groovy24/src/org/codehaus/groovy/ast/AnnotationNode.java b/base/org.codehaus.groovy24/src/org/codehaus/groovy/ast/AnnotationNode.java
new file mode 100644
index 0000000000..52ba8377f6
--- /dev/null
+++ b/base/org.codehaus.groovy24/src/org/codehaus/groovy/ast/AnnotationNode.java
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.codehaus.groovy.ast;
+
+import org.codehaus.groovy.GroovyBugError;
+import org.codehaus.groovy.ast.expr.Expression;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Represents an annotation which can be attached to interfaces, classes, methods and fields.
+ *
+ * @author James Strachan
+ * @author Alex Popescu
+ */
+public class AnnotationNode extends ASTNode {
+ /* GRECLIPSE edit
+ public static final int TYPE_TARGET = 1;
+ */
+ public static final int CONSTRUCTOR_TARGET = 1 << 1;
+ public static final int METHOD_TARGET = 1 << 2;
+ public static final int FIELD_TARGET = 1 << 3;
+ public static final int PARAMETER_TARGET = 1 << 4;
+ public static final int LOCAL_VARIABLE_TARGET = 1 << 5;
+ public static final int ANNOTATION_TARGET = 1 << 6;
+ public static final int PACKAGE_TARGET = 1 << 7;
+ // GRECLIPSE add -- GROOVY-7151 and GROOVY-8940
+ public static final int TYPE_TARGET = 1 | ANNOTATION_TARGET;
+ // GRECLIPSE end
+ private static final int ALL_TARGETS = TYPE_TARGET | CONSTRUCTOR_TARGET | METHOD_TARGET
+ | FIELD_TARGET | PARAMETER_TARGET | LOCAL_VARIABLE_TARGET | PACKAGE_TARGET;
+
+ private final ClassNode classNode;
+ private Map members;
+ private boolean runtimeRetention= false, sourceRetention= false, classRetention = false;
+ private int allowedTargets = ALL_TARGETS;
+
+ public AnnotationNode(ClassNode classNode) {
+ this.classNode = classNode;
+ }
+
+ public ClassNode getClassNode() {
+ return classNode;
+ }
+
+ public Map getMembers() {
+ if (members == null) {
+ return Collections.emptyMap();
+ }
+ return members;
+ }
+
+ public Expression getMember(String name) {
+ if (members == null) {
+ return null;
+ }
+ return members.get(name);
+ }
+
+ private void assertMembers() {
+ if (members == null) {
+ members = new LinkedHashMap();
+ }
+ }
+
+ public void addMember(String name, Expression value) {
+ assertMembers();
+ Expression oldValue = members.get(name);
+ if (oldValue == null) {
+ members.put(name, value);
+ }
+ else {
+ throw new GroovyBugError(String.format("Annotation member %s has already been added", name));
+ }
+ }
+
+ public void setMember(String name, Expression value) {
+ assertMembers();
+ members.put(name, value);
+ }
+
+ public boolean isBuiltIn(){
+ return false;
+ }
+
+ /**
+ * Flag corresponding to RetentionPolicy
.
+ * @return true if the annotation should be visible at runtime,
+ * false otherwise
+ */
+ public boolean hasRuntimeRetention() {
+ return this.runtimeRetention;
+ }
+
+ /**
+ * Sets the internal flag of this annotation runtime retention policy.
+ * If the current annotation has
+ * RetentionPolicy.RUNTIME
or if false
+ * if the RetentionPolicy.CLASS
.
+ * @param flag if true then current annotation is marked as having
+ * RetentionPolicy.RUNTIME
. If false then
+ * the annotation has RetentionPolicy.CLASS
.
+ */
+ public void setRuntimeRetention(boolean flag) {
+ this.runtimeRetention = flag;
+ }
+
+ /**
+ * Flag corresponding to RetentionPolicy.SOURCE
.
+ * @return true if the annotation is only allowed in sources
+ * false otherwise
+ */
+ public boolean hasSourceRetention() {
+ if (!runtimeRetention && !classRetention) return true;
+ return this.sourceRetention;
+ }
+
+ /** Sets the internal flag if the current annotation has
+ * RetentionPolicy.SOURCE
.
+ */
+ public void setSourceRetention(boolean flag) {
+ this.sourceRetention = flag;
+ }
+
+ /**
+ * Flag corresponding to RetentionPolicy.CLASS
.
+ * @return true if the annotation is recorded by the compiler,
+ * but not visible at runtime
+ * false otherwise
+ */
+ public boolean hasClassRetention() {
+ return this.classRetention;
+ }
+
+ /** Sets the internal flag if the current annotation has
+ * RetentionPolicy.CLASS
.
+ */
+ public void setClassRetention(boolean flag) {
+ this.classRetention = flag;
+ }
+
+ public void setAllowedTargets(int bitmap) {
+ this.allowedTargets = bitmap;
+ }
+
+ public boolean isTargetAllowed(int target) {
+ return (this.allowedTargets & target) == target;
+ }
+
+ public static String targetToName(int target) {
+ switch(target) {
+ case TYPE_TARGET:
+ return "TYPE";
+ case CONSTRUCTOR_TARGET:
+ return "CONSTRUCTOR";
+ case METHOD_TARGET:
+ return "METHOD";
+ case FIELD_TARGET:
+ return "FIELD";
+ case PARAMETER_TARGET:
+ return "PARAMETER";
+ case LOCAL_VARIABLE_TARGET:
+ return "LOCAL_VARIABLE";
+ case ANNOTATION_TARGET:
+ return "ANNOTATION";
+ case PACKAGE_TARGET:
+ return "PACKAGE";
+ default:
+ return "unknown target";
+ }
+ }
+}
diff --git a/base/org.codehaus.groovy24/src/org/codehaus/groovy/classgen/ExtendedVerifier.java b/base/org.codehaus.groovy24/src/org/codehaus/groovy/classgen/ExtendedVerifier.java
index 57918362c0..25feb92fd5 100644
--- a/base/org.codehaus.groovy24/src/org/codehaus/groovy/classgen/ExtendedVerifier.java
+++ b/base/org.codehaus.groovy24/src/org/codehaus/groovy/classgen/ExtendedVerifier.java
@@ -321,7 +321,7 @@ protected boolean isAnnotationCompatible() {
}
protected void addError(String msg, ASTNode expr) {
- // GRECLIPSE: start: use new form of error message that has an end column
+ // GRECLIPSE add -- use new form of error message that has an end column
if (expr instanceof AnnotationNode) {
AnnotationNode aNode = (AnnotationNode) expr;
this.source.getErrorCollector().addErrorAndContinue(
diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/ExtendedVerifier.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/ExtendedVerifier.java
index 25b9ef9ae9..97f84477cb 100644
--- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/ExtendedVerifier.java
+++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/ExtendedVerifier.java
@@ -282,7 +282,7 @@ private static boolean isOverrideMethod(MethodNode method) {
}
ClassNode superClass = next.getUnresolvedSuperClass();
if (superClass != null) {
- next = correctToGenericsSpecRecurse(updatedGenericsSpec, superClass);
+ next = correctToGenericsSpecRecurse(updatedGenericsSpec, superClass);
} else {
next = null;
}
@@ -291,7 +291,7 @@ private static boolean isOverrideMethod(MethodNode method) {
}
private static MethodNode getDeclaredMethodCorrected(Map genericsSpec, MethodNode mn, ClassNode correctedNext) {
- for (MethodNode orig : correctedNext.getDeclaredMethods(mn.getName())) {
+ for (MethodNode orig : correctedNext.getDeclaredMethods(mn.getName())) {
MethodNode method = correctToGenericsSpec(genericsSpec, orig);
if (ParameterUtils.parametersEqual(method.getParameters(), mn.getParameters())) {
return method;
@@ -324,7 +324,7 @@ protected boolean isAnnotationCompatible() {
}
public void addError(String msg, ASTNode expr) {
- // GRECLIPSE: start: use new form of error message that has an end column
+ // GRECLIPSE add -- use new form of error message that has an end column
if (expr instanceof AnnotationNode) {
AnnotationNode aNode = (AnnotationNode) expr;
this.source.getErrorCollector().addErrorAndContinue(
diff --git a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/ExtendedVerifier.java b/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/ExtendedVerifier.java
index 25b9ef9ae9..97f84477cb 100644
--- a/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/ExtendedVerifier.java
+++ b/base/org.codehaus.groovy26/src/org/codehaus/groovy/classgen/ExtendedVerifier.java
@@ -282,7 +282,7 @@ private static boolean isOverrideMethod(MethodNode method) {
}
ClassNode superClass = next.getUnresolvedSuperClass();
if (superClass != null) {
- next = correctToGenericsSpecRecurse(updatedGenericsSpec, superClass);
+ next = correctToGenericsSpecRecurse(updatedGenericsSpec, superClass);
} else {
next = null;
}
@@ -291,7 +291,7 @@ private static boolean isOverrideMethod(MethodNode method) {
}
private static MethodNode getDeclaredMethodCorrected(Map genericsSpec, MethodNode mn, ClassNode correctedNext) {
- for (MethodNode orig : correctedNext.getDeclaredMethods(mn.getName())) {
+ for (MethodNode orig : correctedNext.getDeclaredMethods(mn.getName())) {
MethodNode method = correctToGenericsSpec(genericsSpec, orig);
if (ParameterUtils.parametersEqual(method.getParameters(), mn.getParameters())) {
return method;
@@ -324,7 +324,7 @@ protected boolean isAnnotationCompatible() {
}
public void addError(String msg, ASTNode expr) {
- // GRECLIPSE: start: use new form of error message that has an end column
+ // GRECLIPSE add -- use new form of error message that has an end column
if (expr instanceof AnnotationNode) {
AnnotationNode aNode = (AnnotationNode) expr;
this.source.getErrorCollector().addErrorAndContinue(
diff --git a/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/wizards/NewTypeWizard.java b/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/wizards/NewTypeWizard.java
index cbb59cc733..e58c012425 100644
--- a/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/wizards/NewTypeWizard.java
+++ b/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/wizards/NewTypeWizard.java
@@ -582,7 +582,7 @@ private void createAnnotationControls(Composite parent) {
Map modifiers = new LinkedHashMap<>();
modifiers.put(NewWizardMessages.NewTypeWizardPage_modifiers_public, Flags.AccPublic);
- //modifiers.put(NewWizardMessages.NewTypeWizardPage_modifiers_default, Flags.AccDefault);
+ modifiers.put(NewWizardMessages.NewTypeWizardPage_modifiers_default, Flags.AccDefault);
modifiers.put(NewWizardMessages.NewTypeWizardPage_modifiers_private, Flags.AccPrivate);
modifiers.put(NewWizardMessages.NewTypeWizardPage_modifiers_protected, Flags.AccProtected);