Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java137
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java6
3 files changed, 142 insertions, 5 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java
index dd090e5b9b..523cfafef8 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TypeAnnotationTest.java
@@ -19,7 +19,7 @@ import junit.framework.Test;
public class TypeAnnotationTest extends AbstractRegressionTest {
static {
-// TESTS_NUMBERS = new int [] { 36 };
+// TESTS_NUMBERS = new int [] { 40 };
}
public static Class testClass() {
return TypeAnnotationTest.class;
@@ -2150,4 +2150,139 @@ public class TypeAnnotationTest extends AbstractRegressionTest {
" )\n";
checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
}
+ // make sure annotation without target appears twice when set on a method declaration
+ public void test037() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.lang.annotation.Target;\r\n" +
+ "import static java.lang.annotation.ElementType.*;\r\n" +
+ "\r\n" +
+ "@Target(METHOD)\r\n" +
+ "@interface Annot {\r\n" +
+ " int value() default 0;\r\n" +
+ "}\r\n" +
+ "public class X {\r\n" +
+ " @Annot(4)\r\n" +
+ " public void foo() {\r\n" +
+ " }\r\n" +
+ "}",
+ },
+ "");
+ String expectedOutput =
+ " public void foo();\n" +
+ " 0 return\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 11]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 1] local: this index: 0 type: X\n" +
+ " RuntimeInvisibleAnnotations: \n" +
+ " #16 @Annot(\n" +
+ " #17 value=(int) 4 (constant type)\n" +
+ " )\n" +
+ "}";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+ // make sure annotation without target appears twice when set on a method declaration
+ public void test038() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "@interface Annot {\r\n" +
+ " int value() default 0;\r\n" +
+ "}\r\n" +
+ "public class X {\r\n" +
+ " @Annot(4)\r\n" +
+ " public void foo() {\r\n" +
+ " }\r\n" +
+ "}",
+ },
+ "");
+ String expectedOutput =
+ " // Method descriptor #6 ()V\n" +
+ " // Stack: 0, Locals: 1\n" +
+ " public void foo();\n" +
+ " 0 return\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 7]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 1] local: this index: 0 type: X\n" +
+ " RuntimeInvisibleAnnotations: \n" +
+ " #16 @Annot(\n" +
+ " #17 value=(int) 4 (constant type)\n" +
+ " )\n" +
+ "}";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+ // make sure annotation without target appears twice when set on a method declaration
+ public void test039() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "@interface Annot {\r\n" +
+ " int value() default 0;\r\n" +
+ "}\r\n" +
+ "public class X {\r\n" +
+ " @Annot(4)\r\n" +
+ " public int foo() {\r\n" +
+ " return 0;\r\n" +
+ " }\r\n" +
+ "}",
+ },
+ "");
+ String expectedOutput =
+ " public int foo();\n" +
+ " 0 iconst_0\n" +
+ " 1 ireturn\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 7]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 2] local: this index: 0 type: X\n" +
+ " RuntimeInvisibleAnnotations: \n" +
+ " #17 @Annot(\n" +
+ " #18 value=(int) 4 (constant type)\n" +
+ " )\n" +
+ " RuntimeInvisibleTypeAnnotations: \n" +
+ " #17 @Annot(\n" +
+ " #18 value=(int) 4 (constant type)\n" +
+ " target type = 0xa METHOD_RETURN_TYPE\n" +
+ " )\n" +
+ "}";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
+ // make sure annotation without target appears twice when set on a method declaration
+ public void test040() throws Exception {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "import java.lang.annotation.Target;\r\n" +
+ "import static java.lang.annotation.ElementType.*;\r\n" +
+ "\r\n" +
+ "@Target(METHOD)\r\n" +
+ "@interface Annot {\r\n" +
+ " int value() default 0;\r\n" +
+ "}\r\n" +
+ "public class X {\r\n" +
+ " @Annot(4)\r\n" +
+ " public int foo() {\r\n" +
+ " return 0;\r\n" +
+ " }\r\n" +
+ "}",
+ },
+ "");
+ String expectedOutput =
+ " public int foo();\n" +
+ " 0 iconst_0\n" +
+ " 1 ireturn\n" +
+ " Line numbers:\n" +
+ " [pc: 0, line: 11]\n" +
+ " Local variable table:\n" +
+ " [pc: 0, pc: 2] local: this index: 0 type: X\n" +
+ " RuntimeInvisibleAnnotations: \n" +
+ " #17 @Annot(\n" +
+ " #18 value=(int) 4 (constant type)\n" +
+ " )\n" +
+ "}";
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput, ClassFileBytesDisassembler.SYSTEM);
+ }
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
index b57d0971fc..120536584f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
@@ -1975,10 +1975,10 @@ public class ClassFile implements TypeConstants, TypeIds {
}
}
Annotation[] annotations = methodDeclaration.annotations;
- if (annotations != null) {
+ if (annotations != null && binding.returnType.id != T_void) {
methodDeclaration.getAllAnnotationContexts(AnnotationTargetTypeConstants.METHOD_RETURN_TYPE, allTypeAnnotationContexts);
}
- if (!methodDeclaration.isConstructor() && !methodDeclaration.isClinit()) {
+ if (!methodDeclaration.isConstructor() && !methodDeclaration.isClinit() && binding.returnType.id != T_void) {
MethodDeclaration declaration = (MethodDeclaration) methodDeclaration;
TypeReference typeReference = declaration.returnType;
if ((typeReference.bits & ASTNode.HasTypeAnnotations) != 0) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
index 0c23a3f258..594474d7a1 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Annotation.java
@@ -519,7 +519,8 @@ public abstract class Annotation extends Expression {
long metaTagBits = annotationBinding.getAnnotationTagBits(); // could be forward reference
// jsr 308
// we need to filter out type use and type parameter annotations
- if ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) == 0) {
+ if ((metaTagBits & (TagBits.AnnotationTargetMASK)) != 0
+ && ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) == 0)) {
return false;
}
@@ -535,7 +536,8 @@ public abstract class Annotation extends Expression {
return false;
}
long metaTagBits = annotationBinding.getAnnotationTagBits();
- if ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) == 0) {
+ if ((metaTagBits & (TagBits.AnnotationTargetMASK)) != 0
+ && ((metaTagBits & (TagBits.AnnotationForTypeParameter | TagBits.AnnotationForTypeUse)) == 0)) {
return false;
}
if ((metaTagBits & TagBits.AnnotationRetentionMASK) == 0)

Back to the top