diff options
author | shankha banerjee | 2014-07-16 06:57:51 +0000 |
---|---|---|
committer | ssankaran | 2014-07-16 06:57:51 +0000 |
commit | 62542d77179e2d9d9eae2d205be3f0fefe8aabb4 (patch) | |
tree | dd3f063be08bdf8ad3caca0e5214c77fbaa7cd53 | |
parent | eb98db8467dab9b499bde6848602a31af6a605b6 (diff) | |
download | eclipse.jdt.core-62542d77179e2d9d9eae2d205be3f0fefe8aabb4.tar.gz eclipse.jdt.core-62542d77179e2d9d9eae2d205be3f0fefe8aabb4.tar.xz eclipse.jdt.core-62542d77179e2d9d9eae2d205be3f0fefe8aabb4.zip |
Fixed Bug 438437 - [1.8][compiler] Annotations on enum constants
interpreted only as type annotations if the annotation type specifies
ElementType.TYPE_USE in @Target along with others
Signed-off-by: shankha banerjee <shankhba@in.ibm.com>
3 files changed, 79 insertions, 10 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java index 47ba6f7363..b6400a12e4 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java @@ -11106,4 +11106,72 @@ public void test376977() throws Exception { false, false); } + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=438437 - [1.8][compiler] Annotations +// on enum constants interpreted only as type annotations if the annotation type +// specifies ElementType.TYPE_USE in @Target along with others. +public void test438437() { + if (this.complianceLevel < ClassFileConstants.JDK1_8) + return; + runNegativeTest( + new String[] { + "X.java", + "import java.lang.annotation.ElementType;\n" + + "import java.lang.annotation.Target;\n" + + "@Target({ElementType.TYPE_USE, ElementType.FIELD})\n" + + "@interface TUF {} \n" + + "@Target({ElementType.FIELD})\n" + + "@interface F {} \n" + + "@Target({ElementType.TYPE_USE})\n" + + "@interface TU1 {} \n" + + "@Target({ElementType.LOCAL_VARIABLE})\n" + + "@interface LV {} \n" + + "@Target({ElementType.TYPE_USE})\n" + + "@interface TU2 {} \n" + + "class Y {}\n" + + "public enum X {\n" + + " @TUF E1,\n" + // Error without the fix. + " @F E2,\n" + + " @TU1 E3,\n" + // Error is reported as no type exists for the Enum. + " @LV E4,\n" + + " @TUF @TU1 @F E5,\n" + + " @TUF @TU1 @F @TU2 E6;\n" + + " @TUF Y y11;\n" + + " @F Y y12;\n" + + " @TU1 Y y13;\n" + // No error reported as type exists. + " @LV Y y14;\n" + + "}\n" , + }, + "----------\n" + + "1. ERROR in X.java (at line 17)\n" + + " @TU1 E3,\n" + + " ^^^^\n" + + "Syntax error, type annotations are illegal here\n" + + "----------\n" + + "2. ERROR in X.java (at line 18)\n" + + " @LV E4,\n" + + " ^^^\n" + + "The annotation @LV is disallowed for this location\n" + + "----------\n" + + "3. ERROR in X.java (at line 19)\n" + + " @TUF @TU1 @F E5,\n" + + " ^^^^\n" + + "Syntax error, type annotations are illegal here\n" + + "----------\n" + + "4. ERROR in X.java (at line 20)\n" + + " @TUF @TU1 @F @TU2 E6;\n" + + " ^^^^\n" + + "Syntax error, type annotations are illegal here\n" + + "----------\n" + + "5. ERROR in X.java (at line 20)\n" + + " @TUF @TU1 @F @TU2 E6;\n" + + " ^^^^\n" + + "Syntax error, type annotations are illegal here\n" + + "----------\n" + + "6. ERROR in X.java (at line 24)\n" + + " @LV Y y14;\n" + + " ^^^\n" + + "The annotation @LV is disallowed for this location\n" + + "----------\n"); +} } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java index f6231dda14..9612891912 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java @@ -970,7 +970,7 @@ public abstract class ASTNode implements TypeConstants, TypeIds { } } if (copySE8AnnotationsToType) - copySE8AnnotationsToType(scope, recipient, sourceAnnotations, true); + copySE8AnnotationsToType(scope, recipient, sourceAnnotations, false); return annotations; } @@ -996,7 +996,7 @@ public abstract class ASTNode implements TypeConstants, TypeIds { } // When SE8 annotations feature in SE7 locations, they get attributed to the declared entity. Copy/move these to the type of the declared entity (field, local, argument etc.) - public static void copySE8AnnotationsToType(BlockScope scope, Binding recipient, Annotation[] annotations, boolean isLegalLocation) { + public static void copySE8AnnotationsToType(BlockScope scope, Binding recipient, Annotation[] annotations, boolean annotatingEnumerator) { if (annotations == null || annotations.length == 0 || recipient == null) return; @@ -1020,15 +1020,20 @@ public abstract class ASTNode implements TypeConstants, TypeIds { int se8count = 0; long se8nullBits = 0; Annotation se8NullAnnotation = null; - int firstSE8 = -1, lastSE8 = 0; + int firstSE8 = -1; for (int i = 0, length = annotations.length; i < length; i++) { AnnotationBinding annotation = annotations[i].getCompilerAnnotation(); if (annotation == null) continue; final ReferenceBinding annotationType = annotation.getAnnotationType(); long metaTagBits = annotationType.getAnnotationTagBits(); if ((metaTagBits & TagBits.AnnotationForTypeUse) != 0) { + if (annotatingEnumerator) { + if ((metaTagBits & recipientTargetMask) == 0) { + scope.problemReporter().misplacedTypeAnnotations(annotations[i], annotations[i]); + } + continue; + } if (firstSE8 == -1) firstSE8 = i; - lastSE8 = i; if (se8Annotations == null) { se8Annotations = new AnnotationBinding[] { annotation }; se8count = 1; @@ -1046,10 +1051,6 @@ public abstract class ASTNode implements TypeConstants, TypeIds { } } if (se8Annotations != null) { - if (!isLegalLocation) { - scope.problemReporter().misplacedTypeAnnotations(annotations[firstSE8], annotations[lastSE8]); - return; - } switch (recipient.kind()) { case Binding.LOCAL: LocalVariableBinding local = (LocalVariableBinding) recipient; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java index 9154426efb..31fc2c7010 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java @@ -1732,7 +1732,7 @@ public FieldBinding resolveTypeFor(FieldBinding field) { Annotation [] annotations = fieldDecl.annotations; if (annotations != null && annotations.length != 0) { ASTNode.copySE8AnnotationsToType(initializationScope, field, annotations, - fieldDecl.getKind() != AbstractVariableDeclaration.ENUM_CONSTANT); // type annotation is illegal on enum constant + fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT); // type annotation is illegal on enum constant } Annotation.isTypeUseCompatible(fieldDecl.type, this.scope, annotations); } @@ -1924,7 +1924,7 @@ public MethodBinding resolveTypesFor(MethodBinding method) { if (sourceLevel >= ClassFileConstants.JDK1_8 && !method.isVoidMethod()) { Annotation [] annotations = methodDecl.annotations; if (annotations != null && annotations.length != 0) { - ASTNode.copySE8AnnotationsToType(methodDecl.scope, method, methodDecl.annotations, true); + ASTNode.copySE8AnnotationsToType(methodDecl.scope, method, methodDecl.annotations, false); } Annotation.isTypeUseCompatible(returnType, this.scope, methodDecl.annotations); } |