changeset 2215:45651f09a242

Automated merge with http://hg.openjdk.java.net/type-annotations/type-annotations/langtools
author wmdietl
date Sun, 17 Feb 2013 20:34:36 -0800
parents cf9bf24b5b84 dbef4179abd8
children e8b1c02dad3b
files src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java src/share/classes/com/sun/tools/javac/comp/Attr.java src/share/classes/com/sun/tools/javac/comp/MemberEnter.java src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java src/share/classes/com/sun/tools/javac/parser/JavacParser.java
diffstat 28 files changed, 493 insertions(+), 151 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/Type.java	Wed Feb 13 14:06:02 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/Type.java	Sun Feb 17 20:34:36 2013 -0800
@@ -706,7 +706,7 @@
                     return s.toString();
                 } else if (sym.name.isEmpty()) {
                     String s;
-                    ClassType norm = (ClassType) tsym.type;
+                    ClassType norm = (ClassType) tsym.type.unannotatedType();
                     if (norm == null) {
                         s = Log.getLocalizedString("anonymous.class", (Object)null);
                     } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
--- a/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Wed Feb 13 14:06:02 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Sun Feb 17 20:34:36 2013 -0800
@@ -49,12 +49,14 @@
 import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind;
 import com.sun.tools.javac.code.TypeTag;
 import com.sun.tools.javac.code.Symbol.VarSymbol;
+import com.sun.tools.javac.comp.Annotate;
 import com.sun.tools.javac.comp.Annotate.Annotator;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.JCBlock;
 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
 import com.sun.tools.javac.tree.JCTree.JCExpression;
 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCNewClass;
 import com.sun.tools.javac.tree.JCTree.JCTypeApply;
 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
 import com.sun.tools.javac.tree.TreeScanner;
@@ -81,17 +83,24 @@
      * determine the correct positions for type annotations.
      * This version only visits types in signatures and should be
      * called from MemberEnter.
-     * The method returns the Annotator object that should be added
-     * to the correct Annotate queue for later processing.
+     * The method takes the Annotate object as parameter and
+     * adds an Annotator to the correct Annotate queue for
+     * later processing.
      */
-    public static Annotator organizeTypeAnnotationsSignatures(final Symtab syms, final Names names,
-            final Log log, final JCClassDecl tree) {
-        return new Annotator() {
+    public static void organizeTypeAnnotationsSignatures(final Symtab syms, final Names names,
+            final Log log, final JCClassDecl tree, Annotate annotate) {
+        if (tree.name == names.empty) {
+            // Nothing to do for anonymous classes; later we will analyze a
+            // NEW_CLASS instead of this CLASS tree.
+            return;
+        }
+
+        annotate.afterRepeated( new Annotator() {
             @Override
             public void enterAnnotation() {
                 new TypeAnnotationPositions(syms, names, log, true).scan(tree);
             }
-        };
+        } );
     }
 
     /**
@@ -102,10 +111,104 @@
         new TypeAnnotationPositions(syms, names, log, false).scan(tree);
     }
 
+    public enum AnnotationType { DECLARATION, TYPE, BOTH };
+
+    /**
+     * Determine whether an annotation is a declaration annotation,
+     * a type annotation, or both.
+     */
+    public static AnnotationType annotationType(Symtab syms, Names names,
+            Attribute.Compound a, Symbol s) {
+        Attribute.Compound atTarget =
+            a.type.tsym.attribute(syms.annotationTargetType.tsym);
+        if (atTarget == null) {
+            return inferTargetMetaInfo(a, s);
+        }
+        Attribute atValue = atTarget.member(names.value);
+        if (!(atValue instanceof Attribute.Array)) {
+            Assert.error("annotationType(): bad @Target argument " + atValue +
+                    " (" + atValue.getClass() + ")");
+            return AnnotationType.DECLARATION; // error recovery
+        }
+        Attribute.Array arr = (Attribute.Array) atValue;
+        boolean isDecl = false, isType = false;
+        for (Attribute app : arr.values) {
+            if (!(app instanceof Attribute.Enum)) {
+                Assert.error("annotationType(): unrecognized Attribute kind " + app +
+                        " (" + app.getClass() + ")");
+                isDecl = true;
+                continue;
+            }
+            Attribute.Enum e = (Attribute.Enum) app;
+            if (e.value.name == names.TYPE) {
+                if (s.kind == Kinds.TYP)
+                    isDecl = true;
+            } else if (e.value.name == names.FIELD) {
+                if (s.kind == Kinds.VAR &&
+                        s.owner.kind != Kinds.MTH)
+                    isDecl = true;
+            } else if (e.value.name == names.METHOD) {
+                if (s.kind == Kinds.MTH &&
+                        !s.isConstructor())
+                    isDecl = true;
+            } else if (e.value.name == names.PARAMETER) {
+                if (s.kind == Kinds.VAR &&
+                        s.owner.kind == Kinds.MTH &&
+                        (s.flags() & Flags.PARAMETER) != 0)
+                    isDecl = true;
+            } else if (e.value.name == names.CONSTRUCTOR) {
+                if (s.kind == Kinds.MTH &&
+                        s.isConstructor())
+                    isDecl = true;
+            } else if (e.value.name == names.LOCAL_VARIABLE) {
+                if (s.kind == Kinds.VAR &&
+                        s.owner.kind == Kinds.MTH &&
+                        (s.flags() & Flags.PARAMETER) == 0)
+                    isDecl = true;
+            } else if (e.value.name == names.ANNOTATION_TYPE) {
+                if (s.kind == Kinds.TYP &&
+                        (s.flags() & Flags.ANNOTATION) != 0)
+                    isDecl = true;
+            } else if (e.value.name == names.PACKAGE) {
+                if (s.kind == Kinds.PCK)
+                    isDecl = true;
+            } else if (e.value.name == names.TYPE_USE) {
+                if (s.kind == Kinds.TYP ||
+                        s.kind == Kinds.VAR ||
+                        (s.kind == Kinds.MTH && !s.isConstructor() &&
+                        !s.type.getReturnType().hasTag(TypeTag.VOID)) ||
+                        (s.kind == Kinds.MTH && s.isConstructor()))
+                    isType = true;
+            } else if (e.value.name == names.TYPE_PARAMETER) {
+                /* Irrelevant in this case */
+                // TYPE_PARAMETER doesn't aid in distinguishing between
+                // Type annotations and declaration annotations on an
+                // Element
+            } else {
+                Assert.error("annotationType(): unrecognized Attribute name " + e.value.name +
+                        " (" + e.value.name.getClass() + ")");
+                isDecl = true;
+            }
+        }
+        if (isDecl && isType) {
+            return AnnotationType.BOTH;
+        } else if (isType) {
+            return AnnotationType.TYPE;
+        } else {
+            return AnnotationType.DECLARATION;
+        }
+    }
+
+    /** Infer the target annotation kind, if none is give.
+     * We only infer declaration annotations.
+     */
+    private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) {
+        return AnnotationType.DECLARATION;
+    }
+
+
     private static class TypeAnnotationPositions extends TreeScanner {
 
-        private enum AnnotationType { DECLARATION, TYPE, BOTH };
-
         private final Symtab syms;
         private final Names names;
         private final Log log;
@@ -154,7 +257,7 @@
             ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<Attribute.TypeCompound>();
 
             for (Attribute.Compound a : annotations) {
-                switch (annotationType(a, sym)) {
+                switch (annotationType(syms, names, a, sym)) {
                 case DECLARATION:
                     declAnnos.append(a);
                     break;
@@ -480,94 +583,6 @@
             return new Attribute.TypeCompound(a, p);
         }
 
-        private AnnotationType annotationType(Attribute.Compound a, Symbol s) {
-            Attribute.Compound atTarget =
-                a.type.tsym.attribute(syms.annotationTargetType.tsym);
-            if (atTarget == null) {
-                return inferTargetMetaInfo(a, s);
-            }
-            Attribute atValue = atTarget.member(names.value);
-            if (!(atValue instanceof Attribute.Array)) {
-                Assert.error("annotationType(): bad @Target argument " + atValue +
-                        " (" + atValue.getClass() + ")");
-                return AnnotationType.DECLARATION; // error recovery
-            }
-            Attribute.Array arr = (Attribute.Array) atValue;
-            boolean isDecl = false, isType = false;
-            for (Attribute app : arr.values) {
-                if (!(app instanceof Attribute.Enum)) {
-                    Assert.error("annotationType(): unrecognized Attribute kind " + app +
-                            " (" + app.getClass() + ")");
-                    isDecl = true;
-                    continue;
-                }
-                Attribute.Enum e = (Attribute.Enum) app;
-                if (e.value.name == names.TYPE) {
-                    if (s.kind == Kinds.TYP)
-                        isDecl = true;
-                } else if (e.value.name == names.FIELD) {
-                    if (s.kind == Kinds.VAR &&
-                            s.owner.kind != Kinds.MTH)
-                        isDecl = true;
-                } else if (e.value.name == names.METHOD) {
-                    if (s.kind == Kinds.MTH &&
-                            !s.isConstructor())
-                        isDecl = true;
-                } else if (e.value.name == names.PARAMETER) {
-                    if (s.kind == Kinds.VAR &&
-                            s.owner.kind == Kinds.MTH &&
-                            (s.flags() & Flags.PARAMETER) != 0)
-                        isDecl = true;
-                } else if (e.value.name == names.CONSTRUCTOR) {
-                    if (s.kind == Kinds.MTH &&
-                            s.isConstructor())
-                        isDecl = true;
-                } else if (e.value.name == names.LOCAL_VARIABLE) {
-                    if (s.kind == Kinds.VAR &&
-                            s.owner.kind == Kinds.MTH &&
-                            (s.flags() & Flags.PARAMETER) == 0)
-                        isDecl = true;
-                } else if (e.value.name == names.ANNOTATION_TYPE) {
-                    if (s.kind == Kinds.TYP &&
-                            (s.flags() & Flags.ANNOTATION) != 0)
-                        isDecl = true;
-                } else if (e.value.name == names.PACKAGE) {
-                    if (s.kind == Kinds.PCK)
-                        isDecl = true;
-                } else if (e.value.name == names.TYPE_USE) {
-                    if (s.kind == Kinds.TYP ||
-                            s.kind == Kinds.VAR ||
-                            (s.kind == Kinds.MTH && !s.isConstructor() &&
-                            !s.type.getReturnType().hasTag(TypeTag.VOID)) ||
-                            (s.kind == Kinds.MTH && s.isConstructor()))
-                        isType = true;
-                } else if (e.value.name == names.TYPE_PARAMETER) {
-                    /* Irrelevant in this case */
-                    // TYPE_PARAMETER doesn't aid in distinguishing between
-                    // Type annotations and declaration annotations on an
-                    // Element
-                } else {
-                    Assert.error("annotationType(): unrecognized Attribute name " + e.value.name +
-                            " (" + e.value.name.getClass() + ")");
-                    isDecl = true;
-                }
-            }
-            if (isDecl && isType) {
-                return AnnotationType.BOTH;
-            } else if (isType) {
-                return AnnotationType.TYPE;
-            } else {
-                return AnnotationType.DECLARATION;
-            }
-        }
-
-        /** Infer the target annotation kind, if none is give.
-         * We only infer declaration annotations.
-         */
-        private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) {
-            return AnnotationType.DECLARATION;
-        }
-
 
         /* This is the beginning of the second part of organizing
          * type annotations: determine the type annotation positions.
@@ -596,7 +611,21 @@
 
                 case NEW_CLASS:
                     JCNewClass frameNewClass = (JCNewClass)frame;
-                    if (frameNewClass.typeargs.contains(tree)) {
+                    if (frameNewClass.def != null) {
+                        // Special handling for anonymous class instantiations
+                        JCClassDecl frameClassDecl = frameNewClass.def;
+                        if (frameClassDecl.extending == tree) {
+                            p.type = TargetType.CLASS_EXTENDS;
+                            p.type_index = -1;
+                        } else if (frameClassDecl.implementing.contains(tree)) {
+                            p.type = TargetType.CLASS_EXTENDS;
+                            p.type_index = frameClassDecl.implementing.indexOf(tree);
+                        } else {
+                            // In contrast to CLASS below, typarams cannot occur here.
+                            Assert.error("Could not determine position of tree " + tree +
+                                    " within frame " + frame);
+                        }
+                    } else if (frameNewClass.typeargs.contains(tree)) {
                         p.type = TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT;
                         p.type_index = frameNewClass.typeargs.indexOf(tree);
                     } else {
@@ -780,6 +809,9 @@
                         default:
                             Assert.error("Found unexpected type annotation for variable: " + v + " with kind: " + v.getKind());
                     }
+                    if (v.getKind() != ElementKind.FIELD) {
+                        v.owner.annotations.appendUniqueTypes(v.getTypeAnnotationMirrors());
+                    }
                     return;
 
                 case ANNOTATED_TYPE: {
@@ -910,7 +942,9 @@
                 return;
             }
             if (sigOnly) {
-                {
+                if (!tree.mods.annotations.isEmpty()) {
+                    // Nothing to do for separateAnnotationsKinds if
+                    // there are no annotations of either kind.
                     TypeAnnotationPosition pos = new TypeAnnotationPosition();
                     pos.type = TargetType.METHOD_RETURN;
                     if (tree.sym.isConstructor()) {
@@ -923,7 +957,10 @@
                                 tree.sym, pos);
                     }
                 }
-                if (tree.recvparam != null && tree.recvparam.sym != null) {
+                if (tree.recvparam != null && tree.recvparam.sym != null &&
+                        !tree.recvparam.mods.annotations.isEmpty()) {
+                    // Nothing to do for separateAnnotationsKinds if
+                    // there are no annotations of either kind.
                     // TODO: make sure there are no declaration annotations.
                     TypeAnnotationPosition pos = new TypeAnnotationPosition();
                     pos.type = TargetType.METHOD_RECEIVER;
@@ -933,11 +970,15 @@
                 }
                 int i = 0;
                 for (JCVariableDecl param : tree.params) {
-                    TypeAnnotationPosition pos = new TypeAnnotationPosition();
-                    pos.type = TargetType.METHOD_FORMAL_PARAMETER;
-                    pos.parameter_index = i;
-                    pos.pos = param.vartype.pos;
-                    separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
+                    if (!param.mods.annotations.isEmpty()) {
+                        // Nothing to do for separateAnnotationsKinds if
+                        // there are no annotations of either kind.
+                        TypeAnnotationPosition pos = new TypeAnnotationPosition();
+                        pos.type = TargetType.METHOD_FORMAL_PARAMETER;
+                        pos.parameter_index = i;
+                        pos.pos = param.vartype.pos;
+                        separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
+                    }
                     ++i;
                 }
             }
@@ -964,7 +1005,10 @@
          */
         @Override
         public void visitVarDef(final JCVariableDecl tree) {
-            if (tree.sym == null) {
+            if (tree.mods.annotations.isEmpty()) {
+                // Nothing to do for separateAnnotationsKinds if
+                // there are no annotations of either kind.
+            } else if (tree.sym == null) {
                 // Something is wrong already. Quietly ignore.
             } else if (tree.sym.getKind() == ElementKind.PARAMETER) {
                 // Parameters are handled in visitMethodDef above.
@@ -1031,6 +1075,24 @@
         }
 
         @Override
+        public void visitNewClass(JCNewClass tree) {
+            if (tree.def != null &&
+                    !tree.def.mods.annotations.isEmpty()) {
+                JCClassDecl classdecl = tree.def;
+                TypeAnnotationPosition pos = new TypeAnnotationPosition();
+                pos.type = TargetType.CLASS_EXTENDS;
+                pos.pos = tree.pos;
+                separateAnnotationsKinds(classdecl, classdecl.sym.type, classdecl.sym, pos);
+            }
+
+            scan(tree.encl);
+            scan(tree.typeargs);
+            scan(tree.clazz);
+            scan(tree.args);
+            scan(tree.def);
+        }
+
+        @Override
         public void visitNewArray(JCNewArray tree) {
             findPosition(tree, tree, tree.annotations);
             int dimAnnosCount = tree.dimAnnotations.size();
--- a/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Wed Feb 13 14:06:02 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Sun Feb 17 20:34:36 2013 -0800
@@ -266,11 +266,10 @@
                            ((MethodSymbol)method, value));
             t.type = result;
         }
-        // TODO: this should be a TypeCompound if "a" is a JCTypeAnnotation.
-        // However, how do we find the correct position?
+        // TODO: this should be a TypeCompound if "a" has Tag.TYPE_ANNOTATION.
+        // Also, see enterTypeAnnotation.
         Attribute.Compound ac = new Attribute.Compound(a.type, buf.toList());
-        // TODO: is this something we want? Who would use it?
-        // a.attribute = ac;
+        a.attribute = ac;
         return ac;
     }
 
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Feb 13 14:06:02 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Sun Feb 17 20:34:36 2013 -0800
@@ -2129,6 +2129,11 @@
                     tree.constructor,
                     localEnv,
                     new ResultInfo(VAL, newMethodTemplate(syms.voidType, argtypes, typeargtypes)));
+            } else {
+                if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
+                    checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations,
+                            tree.clazz.type.tsym);
+                }
             }
 
             if (tree.constructor != null && tree.constructor.kind == MTH)
@@ -2190,6 +2195,20 @@
                 }
             }
 
+    private void checkForDeclarationAnnotations(List<? extends JCAnnotation> annotations,
+            Symbol sym) {
+        // Ensure that no declaration annotations are present.
+        // Note that a tree type might be an AnnotatedType with
+        // empty annotations, if only declaration annotations were given.
+        // This method will raise an error for such a type.
+        for (JCAnnotation ai : annotations) {
+            if (TypeAnnotations.annotationType(syms, names, ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) {
+                log.error(ai.pos(), "annotation.type.not.applicable");
+            }
+        }
+    }
+
+
     /** Make an attributed null check tree.
      */
     public JCExpression makeNullCheck(JCExpression arg) {
@@ -2216,6 +2235,10 @@
                 attribExpr(l.head, localEnv, syms.intType);
                 owntype = new ArrayType(owntype, syms.arrayClass);
             }
+            if (tree.elemtype.hasTag(ANNOTATED_TYPE)) {
+                checkForDeclarationAnnotations(((JCAnnotatedType) tree.elemtype).annotations,
+                        tree.elemtype.type.tsym);
+            }
         } else {
             // we are seeing an untyped aggregate { ... }
             // this is allowed only if the prototype is an array
@@ -3858,7 +3881,14 @@
 
         ListBuffer<Attribute.TypeCompound> buf = ListBuffer.lb();
         for (JCAnnotation anno : annotations) {
-            buf.append((Attribute.TypeCompound) anno.attribute);
+            if (anno.attribute != null) {
+                // TODO: this null-check is only needed for an obscure
+                // ordering issue, where annotate.flush is called when
+                // the attribute is not set yet. For an example failure
+                // try the referenceinfos/NestedTypes.java test.
+                // Any better solutions?
+                buf.append((Attribute.TypeCompound) anno.attribute);
+            }
         }
         return buf.toList();
     }
@@ -4163,15 +4193,12 @@
         tree.accept(typeAnnotationsValidator);
     }
     //where
-    private final JCTree.Visitor typeAnnotationsValidator =
-        new TreeScanner() {
+    private final JCTree.Visitor typeAnnotationsValidator = new TreeScanner() {
+
+        private boolean checkAllAnnotations = false;
+
         public void visitAnnotation(JCAnnotation tree) {
-            if (tree.hasTag(TYPE_ANNOTATION)) {
-                // TODO: It seems to WMD as if the annotation in
-                // parameters, in particular also the recvparam, are never
-                // of type JCTypeAnnotation and therefore never checked!
-                // Luckily this check doesn't really do anything that isn't
-                // also done elsewhere.
+            if (tree.hasTag(TYPE_ANNOTATION) || checkAllAnnotations) {
                 chk.validateTypeAnnotation(tree, false);
             }
             super.visitAnnotation(tree);
@@ -4191,10 +4218,14 @@
             // I would say it's safe to skip.
             if (tree.sym != null && (tree.sym.flags() & Flags.STATIC) != 0) {
                 if (tree.recvparam != null) {
-                    // TODO: better error message. Is the pos good?
-                    log.error(tree.recvparam.pos(), "annotation.type.not.applicable");
+                    log.error(tree.recvparam.pos(), "receiver.parameter.not.applicable");
                 }
             }
+            if (tree.recvparam != null &&
+                    tree.recvparam.vartype.type.getKind() != TypeKind.ERROR) {
+                checkForDeclarationAnnotations(tree.recvparam.mods.annotations,
+                        tree.recvparam.vartype.type.tsym);
+            }
             if (tree.restype != null && tree.restype.type != null) {
                 validateAnnotatedType(tree.restype, tree.restype.type);
             }
@@ -4215,9 +4246,30 @@
                 validateAnnotatedType(tree.clazz, tree.clazz.type);
             super.visitTypeTest(tree);
         }
-        // TODO: what else do we need?
-        // public void visitNewClass(JCNewClass tree) {
-        // public void visitNewArray(JCNewArray tree) {
+        public void visitNewClass(JCNewClass tree) {
+            if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
+                boolean prevCheck = this.checkAllAnnotations;
+                try {
+                    this.checkAllAnnotations = true;
+                    scan(((JCAnnotatedType)tree.clazz).annotations);
+                } finally {
+                    this.checkAllAnnotations = prevCheck;
+                }
+            }
+            super.visitNewClass(tree);
+        }
+        public void visitNewArray(JCNewArray tree) {
+            if (tree.elemtype != null && tree.elemtype.hasTag(ANNOTATED_TYPE)) {
+                boolean prevCheck = this.checkAllAnnotations;
+                try {
+                    this.checkAllAnnotations = true;
+                    scan(((JCAnnotatedType)tree.elemtype).annotations);
+                } finally {
+                    this.checkAllAnnotations = prevCheck;
+                }
+            }
+            super.visitNewArray(tree);
+        }
 
         /* I would want to model this after
          * com.sun.tools.javac.comp.Check.Validator.visitSelectInternal(JCFieldAccess)
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Wed Feb 13 14:06:02 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Sun Feb 17 20:34:36 2013 -0800
@@ -1202,7 +1202,7 @@
 
     /** Validate a type expression. That is,
      *  check that all type arguments of a parametric type are within
-     *  their bounds. This must be done in a second phase after type attributon
+     *  their bounds. This must be done in a second phase after type attribution
      *  since a class might have a subclass as type parameter bound. E.g:
      *
      *  <pre>{@code
--- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Wed Feb 13 14:06:02 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Sun Feb 17 20:34:36 2013 -0800
@@ -1088,7 +1088,7 @@
                 isFirst = true;
             }
         }
-        annotate.afterRepeated(TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree));
+        TypeAnnotations.organizeTypeAnnotationsSignatures(syms, names, log, tree, annotate);
     }
 
     private void actualEnterTypeAnnotations(final List<JCAnnotation> annotations,
@@ -1198,6 +1198,26 @@
             // Do not annotate the body, just the signature.
             // scan(tree.body);
         }
+
+        @Override
+        public void visitVarDef(final JCVariableDecl tree) {
+            if (sym.kind == Kinds.VAR) {
+                // Don't visit a parameter once when the sym is the method
+                // and once when the sym is the parameter.
+                scan(tree.mods);
+                scan(tree.vartype);
+            }
+            scan(tree.init);
+        }
+
+        @Override
+        public void visitNewClass(JCNewClass tree) {
+            if (tree.def == null) {
+                // For an anonymous class instantiation the class
+                // will be visited separately.
+                super.visitNewClass(tree);
+            }
+        }
     }
 
 
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Wed Feb 13 14:06:02 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Sun Feb 17 20:34:36 2013 -0800
@@ -881,7 +881,8 @@
                     // For method parameters we get the annotation twice! Once with
                     // a valid position, once unknown.
                     // TODO: find a cleaner solution.
-                    // System.err.println("ClassWriter: Position UNKNOWN in type annotation: " + tc);
+                    PrintWriter pw = log.getWriter(Log.WriterKind.ERROR);
+                    pw.println("ClassWriter: Position UNKNOWN in type annotation: " + tc);
                     continue;
                 }
             }
--- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Wed Feb 13 14:06:02 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Sun Feb 17 20:34:36 2013 -0800
@@ -2013,7 +2013,7 @@
     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
      */
     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
-        List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
+        List<JCAnnotation> newAnnotations = annotationsOpt(Tag.ANNOTATION);
 
         switch (token.kind) {
         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
@@ -2030,11 +2030,6 @@
         }
         JCExpression t = qualident(true);
 
-        // handle type annotations for non primitive arrays
-        if (newAnnotations.nonEmpty()) {
-            t = insertAnnotationsToMostInner(t, newAnnotations, false);
-        }
-
         int oldmode = mode;
         mode = TYPE;
         boolean diamondFound = false;
@@ -2068,6 +2063,11 @@
         }
         mode = oldmode;
         if (token.kind == LBRACKET || token.kind == MONKEYS_AT) {
+            // handle type annotations for non primitive arrays
+            if (newAnnotations.nonEmpty()) {
+                t = insertAnnotationsToMostInner(t, newAnnotations, false);
+            }
+
             JCExpression e = arrayCreatorRest(newpos, t);
             if (diamondFound) {
                 reportSyntaxError(lastTypeargsPos, "cannot.create.array.with.diamond");
@@ -2092,8 +2092,18 @@
             if (newClass.def != null) {
                 assert newClass.def.mods.annotations.isEmpty();
                 if (newAnnotations.nonEmpty()) {
+                    // Add type and declaration annotations to the new class;
+                    // com.sun.tools.javac.code.TypeAnnotations.TypeAnnotationPositions.visitNewClass(JCNewClass)
+                    // will later remove all type annotations and only leave the
+                    // declaration annotations.
                     newClass.def.mods.pos = earlier(newClass.def.mods.pos, newAnnotations.head.pos);
-                    newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations);
+                    newClass.def.mods.annotations = newAnnotations;
+                }
+            } else {
+                // handle type annotations for instantiations
+                if (newAnnotations.nonEmpty()) {
+                    t = insertAnnotationsToMostInner(t, newAnnotations, false);
+                    newClass.clazz = t;
                 }
             }
             return newClass;
--- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Wed Feb 13 14:06:02 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Sun Feb 17 20:34:36 2013 -0800
@@ -2157,6 +2157,10 @@
     as of release 8, ''this'' is allowed as the parameter name for the receiver type only, which has to be the first parameter
 
 # TODO 308: make a better error message
+compiler.err.receiver.parameter.not.applicable=\
+    receiver parameter not applicable
+
+# TODO 308: make a better error message
 compiler.err.cant.annotate.static.class=\
     enclosing static nested class cannot be annotated
 # TODO 308: make a better error message
--- a/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Wed Feb 13 14:06:02 2013 -0800
+++ b/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Sun Feb 17 20:34:36 2013 -0800
@@ -918,6 +918,9 @@
                 printExprs(tree.typeargs);
                 print(">");
             }
+            if (tree.def != null && tree.def.mods.annotations.nonEmpty()) {
+                printTypeAnnotations(tree.def.mods.annotations);
+            }
             printExpr(tree.clazz);
             print("(");
             printExprs(tree.args);
--- a/test/tools/javac/annotations/typeAnnotations/attribution/Scopes.java	Wed Feb 13 14:06:02 2013 -0800
+++ b/test/tools/javac/annotations/typeAnnotations/attribution/Scopes.java	Sun Feb 17 20:34:36 2013 -0800
@@ -28,11 +28,17 @@
  * @author Mahmood Ali
  * @compile Scopes.java
  */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
 class Scopes {
 
   void test(@A(VALUE) Scopes this) { }
   void test1(@A(value=VALUE) Scopes this) { }
 
   private static final int VALUE = 1;
+
+  @Target(ElementType.TYPE_USE)
   @interface A { int value(); }
 }
--- a/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.java	Wed Feb 13 14:06:02 2013 -0800
+++ b/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.java	Sun Feb 17 20:34:36 2013 -0800
@@ -6,7 +6,7 @@
  * @compile/fail/ref=StaticMethods.out -XDrawDiagnostics StaticMethods.java
  */
 class StaticMethods {
-  static void main(@A StaticMethods this) { }
+  static void main(StaticMethods this) { }
 }
 
 @interface A { }
--- a/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.out	Wed Feb 13 14:06:02 2013 -0800
+++ b/test/tools/javac/annotations/typeAnnotations/failures/StaticMethods.out	Sun Feb 17 20:34:36 2013 -0800
@@ -1,2 +1,2 @@
-StaticMethods.java:9:37: compiler.err.annotation.type.not.applicable
-1 error
+StaticMethods.java:9:34: compiler.err.receiver.parameter.not.applicable
+1 error
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.java	Sun Feb 17 20:34:36 2013 -0800
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 1234567
+ * @summary ensure that declaration annotations are not allowed on
+ *   new array expressions
+ * @author Werner Dietl
+ * @compile/fail/ref=DeclarationAnnotation.out -XDrawDiagnostics DeclarationAnnotation.java
+ */
+class DeclarationAnnotation {
+    Object e1 = new @DA int[5];
+    Object e2 = new @DA String[42];
+    Object e3 = new @DA Object();
+
+    // The declaration annotation is only allowed for
+    // an anonymous class creation.
+    Object ok = new @DA Object() { };
+}
+
+@interface DA { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/typeAnnotations/failures/common/arrays/DeclarationAnnotation.out	Sun Feb 17 20:34:36 2013 -0800
@@ -0,0 +1,4 @@
+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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DeclarationAnnotation.java	Sun Feb 17 20:34:36 2013 -0800
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 1234567
+ * @summary ensure that declaration annotations are not allowed on
+ *   method receiver types
+ * @author Werner Dietl
+ * @compile/fail/ref=DeclarationAnnotation.out -XDrawDiagnostics DeclarationAnnotation.java
+ */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+class DeclarationAnnotation {
+    void bad(@DA DeclarationAnnotation this) {}
+    void good(@TA DeclarationAnnotation this) {}
+}
+
+@interface DA { }
+
+@Target(ElementType.TYPE_USE)
+@interface TA { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/DeclarationAnnotation.out	Sun Feb 17 20:34:36 2013 -0800
@@ -0,0 +1,2 @@
+DeclarationAnnotation.java:14:14: compiler.err.annotation.type.not.applicable
+1 error
--- a/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/Nesting.java	Wed Feb 13 14:06:02 2013 -0800
+++ b/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/Nesting.java	Sun Feb 17 20:34:36 2013 -0800
@@ -28,6 +28,11 @@
  * @author Werner Dietl
  * @compile Nesting.java
  */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE_USE)
 @interface A { }
 
 class Nesting {
--- a/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.out	Wed Feb 13 14:06:02 2013 -0800
+++ b/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/StaticThings.out	Sun Feb 17 20:34:36 2013 -0800
@@ -1,5 +1,5 @@
-StaticThings.java:52:32: compiler.err.annotation.type.not.applicable
-StaticThings.java:54:37: compiler.err.annotation.type.not.applicable
-StaticThings.java:33:26: compiler.err.annotation.type.not.applicable
-StaticThings.java:36:28: compiler.err.annotation.type.not.applicable
+StaticThings.java:52:32: compiler.err.receiver.parameter.not.applicable
+StaticThings.java:54:37: compiler.err.receiver.parameter.not.applicable
+StaticThings.java:33:26: compiler.err.receiver.parameter.not.applicable
+StaticThings.java:36:28: compiler.err.receiver.parameter.not.applicable
 4 errors
\ No newline at end of file
--- a/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.java	Wed Feb 13 14:06:02 2013 -0800
+++ b/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.java	Sun Feb 17 20:34:36 2013 -0800
@@ -29,6 +29,10 @@
  * @compile/fail/ref=WrongType.out -XDrawDiagnostics WrongType.java
  */
 
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE_USE)
 @interface A {}
 
 class WrongType {
--- a/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.out	Wed Feb 13 14:06:02 2013 -0800
+++ b/test/tools/javac/annotations/typeAnnotations/failures/common/receiver/WrongType.out	Sun Feb 17 20:34:36 2013 -0800
@@ -1,9 +1,9 @@
-WrongType.java:51:15: compiler.err.cant.resolve.location: kindname.class, XYZ, , , (compiler.misc.location: kindname.class, WrongType, null)
-WrongType.java:61:27: compiler.err.doesnt.exist: Outer
-WrongType.java:62:31: compiler.err.cant.resolve.location: kindname.class, XY, , , (compiler.misc.location: kindname.class, WrongType, null)
-WrongType.java:44:23: compiler.err.incorrect.receiver.type
-WrongType.java:46:23: compiler.err.incorrect.receiver.type
-WrongType.java:59:33: compiler.err.incorrect.receiver.type
-WrongType.java:60:31: compiler.err.incorrect.receiver.type
-WrongType.java:66:28: compiler.err.incorrect.receiver.type
+WrongType.java:55:15: compiler.err.cant.resolve.location: kindname.class, XYZ, , , (compiler.misc.location: kindname.class, WrongType, null)
+WrongType.java:65:27: compiler.err.doesnt.exist: Outer
+WrongType.java:66:31: compiler.err.cant.resolve.location: kindname.class, XY, , , (compiler.misc.location: kindname.class, WrongType, null)
+WrongType.java:48:23: compiler.err.incorrect.receiver.type
+WrongType.java:50:23: compiler.err.incorrect.receiver.type
+WrongType.java:63:33: compiler.err.incorrect.receiver.type
+WrongType.java:64:31: compiler.err.incorrect.receiver.type
+WrongType.java:70:28: compiler.err.incorrect.receiver.type
 8 errors
\ No newline at end of file
--- a/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.java	Wed Feb 13 14:06:02 2013 -0800
+++ b/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.java	Sun Feb 17 20:34:36 2013 -0800
@@ -5,10 +5,15 @@
  * @author Mahmood Ali
  * @compile/fail/ref=MissingAnnotationValue.out -XDrawDiagnostics MissingAnnotationValue.java
  */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
 class MissingAnnotationValue {
   void test() {
     new @A String();
   }
 }
 
+@Target(ElementType.TYPE_USE)
 @interface A { int field(); }
--- a/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.out	Wed Feb 13 14:06:02 2013 -0800
+++ b/test/tools/javac/annotations/typeAnnotations/failures/common/rest/MissingAnnotationValue.out	Sun Feb 17 20:34:36 2013 -0800
@@ -1,2 +1,2 @@
-MissingAnnotationValue.java:10:9: compiler.err.annotation.missing.default.value: A, field
+MissingAnnotationValue.java:14:9: compiler.err.annotation.missing.default.value: A, field
 1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DeclarationAnnotation.java	Sun Feb 17 20:34:36 2013 -0800
@@ -0,0 +1,22 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 1234567
+ * @summary ensure that declaration annotations are not allowed on
+ *   wildcards
+ * @author Werner Dietl
+ * @compile/fail/ref=DeclarationAnnotation.out -XDrawDiagnostics DeclarationAnnotation.java
+ */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.util.List;
+
+class DeclarationAnnotation {
+    List<@DA ? extends Object> bad;
+    List<@TA ? extends Object> good;
+}
+
+@interface DA { }
+
+@Target(ElementType.TYPE_USE)
+@interface TA { }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/typeAnnotations/failures/common/wildcards/DeclarationAnnotation.out	Sun Feb 17 20:34:36 2013 -0800
@@ -0,0 +1,2 @@
+DeclarationAnnotation.java:15:10: compiler.err.annotation.type.not.applicable
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/typeAnnotations/newlocations/AnonymousClass.java	Sun Feb 17 20:34:36 2013 -0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+
+/*
+ * @test
+ * @bug 1234567
+ * @summary new type annotation location: anonymous class creation
+ * @author Werner Dietl
+ * @compile AnonymousClass.java
+ */
+class AnonymousClass {
+    Object o1 = new @TA Object() { };
+    // Declaration annotations are also allowed.
+    Object o2 = new @TA @DA Object() { };
+}
+
+@interface DA { }
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TA { }
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+@interface TB { }
--- a/test/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java	Wed Feb 13 14:06:02 2013 -0800
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/NestedTypes.java	Sun Feb 17 20:34:36 2013 -0800
@@ -831,4 +831,27 @@
                 "  }\n" +
                 "}}\n";
     }
+
+    @TADescriptions({
+        @TADescription(annotation = "TA", type = CLASS_EXTENDS,
+                genericLocation = {}, typeIndex = -1),
+        @TADescription(annotation = "TB", type = CLASS_EXTENDS,
+                genericLocation = {3, 0}, typeIndex = -1),
+        @TADescription(annotation = "TC", type = CLASS_EXTENDS,
+                genericLocation = {3, 1}, typeIndex = -1),
+        @TADescription(annotation = "TD", type = CLASS_EXTENDS,
+                genericLocation = {1, 0}, typeIndex = -1),
+        @TADescription(annotation = "TE", type = CLASS_EXTENDS,
+                genericLocation = {1, 0, 3, 0}, typeIndex = -1),
+        @TADescription(annotation = "TF", type = CLASS_EXTENDS,
+                genericLocation = {1, 0, 3, 1}, typeIndex = -1)
+    })
+    @TestClass("GOuter$GInner$Test")
+    public String testExtends1() {
+        return "class GOuter<A, B> {\n" +
+                "  class GInner<X, Y> {\n" +
+                "    class Test extends @TA GOuter<@TB String, @TC String>.@TD GInner<@TE String, @TF String> {}" +
+                "  }" +
+                "}";
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/annotations/typeAnnotations/referenceinfos/Test.java	Sun Feb 17 20:34:36 2013 -0800
@@ -0,0 +1,33 @@
+
+import java.util.*;
+import java.lang.annotation.*;
+
+class Test<K> { GOuter<@TC Object, String> entrySet() { return null; } }
+
+@interface A {}
+@interface B {}
+@interface C {}
+@interface D {}
+@interface E {}
+@interface F {}
+
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TA {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TB {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TC {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TD {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TE {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TF {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TG {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TH {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TI {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TJ {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TK {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TL {}
+@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface TM {}
+
+@Repeatable(RTAs.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTA {}
+@Repeatable(RTBs.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTB {}
+@ContainerFor(RTA.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTAs { RTA[] value(); }
+@ContainerFor(RTB.class) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) @interface RTBs { RTB[] value(); }
+@Target(value={ElementType.TYPE,ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER,ElementType.CONSTRUCTOR,ElementType.LOCAL_VARIABLE})
+@interface Decl {}