diff options
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) |