# HG changeset patch # User emc # Date 1382592430 14400 # Node ID 119747cd9f2565faa6e76d9bf3e1a5364d4ca386 # Parent d2fa3f7e964ebba80facf5f7b9eec25a31718a9b 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 diff -r d2fa3f7e964e -r 119747cd9f25 src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java --- a/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java Wed Oct 23 23:20:32 2013 -0400 +++ b/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 newattrs = + new ListBuffer(); + + 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? diff -r d2fa3f7e964e -r 119747cd9f25 src/share/classes/com/sun/tools/javac/comp/Check.java --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Oct 23 23:20:32 2013 -0400 +++ b/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) diff -r d2fa3f7e964e -r 119747cd9f25 test/tools/javac/annotations/typeAnnotations/failures/TypeOnAnonClass.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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() {}; } } diff -r d2fa3f7e964e -r 119747cd9f25 test/tools/javac/annotations/typeAnnotations/failures/TypeOnAnonClass.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 diff -r d2fa3f7e964e -r 119747cd9f25 test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.out --- a/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.out Wed Oct 23 23:20:32 2013 -0400 +++ b/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 diff -r d2fa3f7e964e -r 119747cd9f25 test/tools/javac/annotations/typeAnnotations/newlocations/AnonymousClass.java --- a/test/tools/javac/annotations/typeAnnotations/newlocations/AnonymousClass.java Wed Oct 23 23:20:32 2013 -0400 +++ b/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 { }