8023682: Incorrect attributes emitted for anonymous class declaration
authoremc
Thu, 24 Oct 2013 01:27:10 -0400
changeset 21499 203cfd174518
parent 21498 58c2486db8d0
child 21500 475e59d3b40c
8023682: Incorrect attributes emitted for anonymous class declaration Summary: Cause javac to emit type annotations on new instruction as well as anonymous class supertype for annotated anonymous classes. Reviewed-by: jjg, jfranck
langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeOnAnonClass.java
langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeOnAnonClass.out
langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.out
langtools/test/tools/javac/annotations/typeAnnotations/newlocations/AnonymousClass.java
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Wed Oct 23 23:20:32 2013 -0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Thu Oct 24 01:27:10 2013 -0400
@@ -370,9 +370,9 @@
             sym.appendUniqueTypeAttributes(typeAnnotations);
 
             if (sym.getKind() == ElementKind.PARAMETER ||
-                    sym.getKind() == ElementKind.LOCAL_VARIABLE ||
-                    sym.getKind() == ElementKind.RESOURCE_VARIABLE ||
-                    sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
+                sym.getKind() == ElementKind.LOCAL_VARIABLE ||
+                sym.getKind() == ElementKind.RESOURCE_VARIABLE ||
+                sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
                 // Make sure all type annotations from the symbol are also
                 // on the owner.
                 sym.owner.appendUniqueTypeAttributes(sym.getRawTypeAttributes());
@@ -1221,6 +1221,22 @@
             super.visitTypeParameter(tree);
         }
 
+        private void copyNewClassAnnotationsToOwner(JCNewClass tree) {
+            Symbol sym = tree.def.sym;
+            TypeAnnotationPosition pos = new TypeAnnotationPosition();
+            ListBuffer<Attribute.TypeCompound> newattrs =
+                new ListBuffer<Attribute.TypeCompound>();
+
+            for (Attribute.TypeCompound old : sym.getRawTypeAttributes()) {
+                newattrs.append(new Attribute.TypeCompound(old.type, old.values,
+                                                           pos));
+            }
+
+            pos.type = TargetType.NEW;
+            pos.pos = tree.pos;
+            sym.owner.appendUniqueTypeAttributes(newattrs.toList());
+        }
+
         @Override
         public void visitNewClass(JCNewClass tree) {
             if (tree.def != null &&
@@ -1239,7 +1255,7 @@
                 }
                 Type before = classdecl.sym.type;
                 separateAnnotationsKinds(classdecl, tree.clazz.type, classdecl.sym, pos);
-
+                copyNewClassAnnotationsToOwner(tree);
                 // classdecl.sym.type now contains an annotated type, which
                 // is not what we want there.
                 // TODO: should we put this type somewhere in the superclass/interface?
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Wed Oct 23 23:20:32 2013 -0400
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java	Thu Oct 24 01:27:10 2013 -0400
@@ -3011,7 +3011,6 @@
     boolean annotationApplicable(JCAnnotation a, Symbol s) {
         Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym);
         Name[] targets;
-
         if (arr == null) {
             targets = defaultTargetMetaInfo(a, s);
         } else {
@@ -3028,7 +3027,7 @@
         }
         for (Name target : targets) {
             if (target == names.TYPE)
-                { if (s.kind == TYP) return true; }
+                { if (s.kind == TYP && !s.isAnonymous()) return true; }
             else if (target == names.FIELD)
                 { if (s.kind == VAR && s.owner.kind != MTH) return true; }
             else if (target == names.METHOD)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeOnAnonClass.java	Thu Oct 24 01:27:10 2013 -0400
@@ -0,0 +1,13 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8023682
+ * @summary Cannot annotate an anonymous class with a target type of TYPE
+ * @compile/fail/ref=TypeOnAnonClass.out -XDrawDiagnostics TypeOnAnonClass.java
+ */
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@interface X {}
+interface Foo {}
+class TypeOnAnonClass { void m() { new @X Foo() {}; } }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/TypeOnAnonClass.out	Thu Oct 24 01:27:10 2013 -0400
@@ -0,0 +1,2 @@
+TypeOnAnonClass.java:13:40: compiler.err.annotation.type.not.applicable
+1 error
--- a/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.out	Wed Oct 23 23:20:32 2013 -0400
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.out	Thu Oct 24 01:27:10 2013 -0400
@@ -1,4 +1,5 @@
 DeclarationAnnotation.java:10:21: compiler.err.annotation.type.not.applicable
 DeclarationAnnotation.java:11:21: compiler.err.annotation.type.not.applicable
 DeclarationAnnotation.java:12:21: compiler.err.annotation.type.not.applicable
-3 errors
\ No newline at end of file
+DeclarationAnnotation.java:16:21: compiler.err.annotation.type.not.applicable
+4 errors
--- a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/AnonymousClass.java	Wed Oct 23 23:20:32 2013 -0400
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/AnonymousClass.java	Thu Oct 24 01:27:10 2013 -0400
@@ -32,12 +32,9 @@
  */
 class AnonymousClass {
     Object o1 = new @TA Object() { };
-    // Declaration annotations are also allowed.
-    Object o2 = new @TA @DA Object() { };
+    Object o2 = new @TA Object() { };
 }
 
-@interface DA { }
-
 @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
 @interface TA { }