src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java

changeset 1570
f91144b7da75
parent 1521
71f35e4b93a5
child 1563
bc456436c613
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Mon Feb 04 18:08:53 2013 -0500
     1.3 @@ -0,0 +1,1037 @@
     1.4 +/*
     1.5 + * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.  Oracle designates this
    1.11 + * particular file as subject to the "Classpath" exception as provided
    1.12 + * by Oracle in the LICENSE file that accompanied this code.
    1.13 + *
    1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.17 + * version 2 for more details (a copy is included in the LICENSE file that
    1.18 + * accompanied this code).
    1.19 + *
    1.20 + * You should have received a copy of the GNU General Public License version
    1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.23 + *
    1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.25 + * or visit www.oracle.com if you need additional information or have any
    1.26 + * questions.
    1.27 + */
    1.28 +
    1.29 +package com.sun.tools.javac.code;
    1.30 +
    1.31 +import javax.lang.model.element.Element;
    1.32 +import javax.lang.model.element.ElementKind;
    1.33 +import javax.lang.model.type.TypeKind;
    1.34 +
    1.35 +import com.sun.tools.javac.code.Attribute;
    1.36 +import com.sun.tools.javac.code.Attribute.TypeCompound;
    1.37 +import com.sun.tools.javac.code.Flags;
    1.38 +import com.sun.tools.javac.code.Kinds;
    1.39 +import com.sun.tools.javac.code.Type.AnnotatedType;
    1.40 +import com.sun.tools.javac.code.Type.ArrayType;
    1.41 +import com.sun.tools.javac.code.Type.CapturedType;
    1.42 +import com.sun.tools.javac.code.Type.ClassType;
    1.43 +import com.sun.tools.javac.code.Type.ErrorType;
    1.44 +import com.sun.tools.javac.code.Type.ForAll;
    1.45 +import com.sun.tools.javac.code.Type.MethodType;
    1.46 +import com.sun.tools.javac.code.Type.PackageType;
    1.47 +import com.sun.tools.javac.code.Type.TypeVar;
    1.48 +import com.sun.tools.javac.code.Type.UndetVar;
    1.49 +import com.sun.tools.javac.code.Type.Visitor;
    1.50 +import com.sun.tools.javac.code.Type.WildcardType;
    1.51 +import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntry;
    1.52 +import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind;
    1.53 +import com.sun.tools.javac.code.TypeTag;
    1.54 +import com.sun.tools.javac.code.Symbol.VarSymbol;
    1.55 +import com.sun.tools.javac.comp.Annotate.Annotator;
    1.56 +import com.sun.tools.javac.tree.JCTree;
    1.57 +import com.sun.tools.javac.tree.JCTree.JCBlock;
    1.58 +import com.sun.tools.javac.tree.JCTree.JCClassDecl;
    1.59 +import com.sun.tools.javac.tree.JCTree.JCExpression;
    1.60 +import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
    1.61 +import com.sun.tools.javac.tree.JCTree.JCTypeApply;
    1.62 +import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
    1.63 +import com.sun.tools.javac.tree.TreeScanner;
    1.64 +import com.sun.tools.javac.tree.JCTree.*;
    1.65 +import com.sun.tools.javac.util.Assert;
    1.66 +import com.sun.tools.javac.util.List;
    1.67 +import com.sun.tools.javac.util.ListBuffer;
    1.68 +import com.sun.tools.javac.util.Log;
    1.69 +import com.sun.tools.javac.util.Names;
    1.70 +
    1.71 +/**
    1.72 + * Contains operations specific to processing type annotations.
    1.73 + * This class has two functions:
    1.74 + * separate declaration from type annotations and insert the type
    1.75 + * annotations to their types;
    1.76 + * and determine the TypeAnnotationPositions for all type annotations.
    1.77 + */
    1.78 +public class TypeAnnotations {
    1.79 +    // Class cannot be instantiated.
    1.80 +    private TypeAnnotations() {}
    1.81 +
    1.82 +    /**
    1.83 +     * Separate type annotations from declaration annotations and
    1.84 +     * determine the correct positions for type annotations.
    1.85 +     * This version only visits types in signatures and should be
    1.86 +     * called from MemberEnter.
    1.87 +     * The method returns the Annotator object that should be added
    1.88 +     * to the correct Annotate queue for later processing.
    1.89 +     */
    1.90 +    public static Annotator organizeTypeAnnotationsSignatures(final Symtab syms, final Names names,
    1.91 +            final Log log, final JCClassDecl tree) {
    1.92 +        return new Annotator() {
    1.93 +            @Override
    1.94 +            public void enterAnnotation() {
    1.95 +                new TypeAnnotationPositions(syms, names, log, true).scan(tree);
    1.96 +            }
    1.97 +        };
    1.98 +    }
    1.99 +
   1.100 +    /**
   1.101 +     * This version only visits types in bodies, that is, field initializers,
   1.102 +     * top-level blocks, and method bodies, and should be called from Attr.
   1.103 +     */
   1.104 +    public static void organizeTypeAnnotationsBodies(Symtab syms, Names names, Log log, JCClassDecl tree) {
   1.105 +        new TypeAnnotationPositions(syms, names, log, false).scan(tree);
   1.106 +    }
   1.107 +
   1.108 +    private static class TypeAnnotationPositions extends TreeScanner {
   1.109 +
   1.110 +        private enum AnnotationType { DECLARATION, TYPE, BOTH };
   1.111 +
   1.112 +        private final Symtab syms;
   1.113 +        private final Names names;
   1.114 +        private final Log log;
   1.115 +        private final boolean sigOnly;
   1.116 +
   1.117 +        private TypeAnnotationPositions(Symtab syms, Names names, Log log, boolean sigOnly) {
   1.118 +            this.syms = syms;
   1.119 +            this.names = names;
   1.120 +            this.log = log;
   1.121 +            this.sigOnly = sigOnly;
   1.122 +        }
   1.123 +
   1.124 +        /*
   1.125 +         * When traversing the AST we keep the "frames" of visited
   1.126 +         * trees in order to determine the position of annotations.
   1.127 +         */
   1.128 +        private ListBuffer<JCTree> frames = ListBuffer.lb();
   1.129 +
   1.130 +        protected void push(JCTree t) { frames = frames.prepend(t); }
   1.131 +        protected JCTree pop() { return frames.next(); }
   1.132 +        // could this be frames.elems.tail.head?
   1.133 +        private JCTree peek2() { return frames.toList().tail.head; }
   1.134 +
   1.135 +        @Override
   1.136 +        public void scan(JCTree tree) {
   1.137 +            push(tree);
   1.138 +            super.scan(tree);
   1.139 +            pop();
   1.140 +        }
   1.141 +
   1.142 +        /**
   1.143 +         * Separates type annotations from declaration annotations.
   1.144 +         * This step is needed because in certain locations (where declaration
   1.145 +         * and type annotations can be mixed, e.g. the type of a field)
   1.146 +         * we never build an JCAnnotatedType. This step finds these
   1.147 +         * annotations and marks them as if they were part of the type.
   1.148 +         */
   1.149 +        private void separateAnnotationsKinds(JCTree typetree, Type type, Symbol sym,
   1.150 +                TypeAnnotationPosition pos) {
   1.151 +            /*
   1.152 +            System.out.printf("separateAnnotationsKinds(typetree: %s, type: %s, symbol: %s, pos: %s%n",
   1.153 +                    typetree, type, sym, pos);
   1.154 +            */
   1.155 +            List<Attribute.Compound> annotations = sym.getRawAttributes();
   1.156 +            ListBuffer<Attribute.Compound> declAnnos = new ListBuffer<Attribute.Compound>();
   1.157 +            ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<Attribute.TypeCompound>();
   1.158 +
   1.159 +            for (Attribute.Compound a : annotations) {
   1.160 +                switch (annotationType(a, sym)) {
   1.161 +                case DECLARATION:
   1.162 +                    declAnnos.append(a);
   1.163 +                    break;
   1.164 +                case BOTH: {
   1.165 +                    declAnnos.append(a);
   1.166 +                    Attribute.TypeCompound ta = toTypeCompound(a, pos);
   1.167 +                    typeAnnos.append(ta);
   1.168 +                    break;
   1.169 +                }
   1.170 +                case TYPE: {
   1.171 +                    Attribute.TypeCompound ta = toTypeCompound(a, pos);
   1.172 +                    typeAnnos.append(ta);
   1.173 +                    break;
   1.174 +                }
   1.175 +                }
   1.176 +            }
   1.177 +
   1.178 +            sym.annotations.reset();
   1.179 +            sym.annotations.setDeclarationAttributes(declAnnos.toList());
   1.180 +
   1.181 +            List<Attribute.TypeCompound> typeAnnotations = typeAnnos.toList();
   1.182 +
   1.183 +            if (type == null) {
   1.184 +                // When type is null, put the type annotations to the symbol.
   1.185 +                // This is used for constructor return annotations, for which
   1.186 +                // no appropriate type exists.
   1.187 +                sym.annotations.appendUniqueTypes(typeAnnotations);
   1.188 +                return;
   1.189 +            }
   1.190 +
   1.191 +            // type is non-null and annotations are added to that type
   1.192 +            type = typeWithAnnotations(typetree, type, typeAnnotations, log);
   1.193 +
   1.194 +            if (sym.getKind() == ElementKind.METHOD) {
   1.195 +                sym.type.asMethodType().restype = type;
   1.196 +            } else {
   1.197 +                sym.type = type;
   1.198 +            }
   1.199 +
   1.200 +            sym.annotations.appendUniqueTypes(typeAnnotations);
   1.201 +            if (sym.getKind() == ElementKind.PARAMETER &&
   1.202 +                    sym.getQualifiedName().equals(names._this)) {
   1.203 +                sym.owner.type.asMethodType().recvtype = type;
   1.204 +                // note that the typeAnnotations will also be added to the owner below.
   1.205 +            }
   1.206 +            if (sym.getKind() == ElementKind.PARAMETER ||
   1.207 +                    sym.getKind() == ElementKind.LOCAL_VARIABLE ||
   1.208 +                    sym.getKind() == ElementKind.RESOURCE_VARIABLE ||
   1.209 +                    sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
   1.210 +                // Make sure all type annotations from the symbol are also
   1.211 +                // on the owner.
   1.212 +                sym.owner.annotations.appendUniqueTypes(sym.getTypeAnnotationMirrors());
   1.213 +            }
   1.214 +        }
   1.215 +
   1.216 +        // This method has a similar purpose as
   1.217 +        // {@link com.sun.tools.javac.parser.JavacParser.insertAnnotationsToMostInner(JCExpression, List<JCTypeAnnotation>, boolean)}
   1.218 +        // We found a type annotation in a declaration annotation position,
   1.219 +        // for example, on the return type.
   1.220 +        // Such an annotation is _not_ part of an JCAnnotatedType tree and we therefore
   1.221 +        // need to set its position explicitly.
   1.222 +        // The method returns a copy of type that contains these annotations.
   1.223 +        private static Type typeWithAnnotations(final JCTree typetree, final Type type,
   1.224 +                final List<Attribute.TypeCompound> annotations, Log log) {
   1.225 +            // System.out.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s)%n",
   1.226 +            //         typetree, type, annotations);
   1.227 +            if (annotations.isEmpty()) {
   1.228 +                return type;
   1.229 +            }
   1.230 +            if (type.hasTag(TypeTag.ARRAY)) {
   1.231 +                Type toreturn;
   1.232 +                Type.ArrayType tomodify;
   1.233 +                Type.ArrayType arType;
   1.234 +                {
   1.235 +                    Type touse = type;
   1.236 +                    if (type.getKind() == TypeKind.ANNOTATED) {
   1.237 +                        Type.AnnotatedType atype = (Type.AnnotatedType)type;
   1.238 +                        toreturn = new Type.AnnotatedType(atype.underlyingType);
   1.239 +                        ((Type.AnnotatedType)toreturn).typeAnnotations = atype.typeAnnotations;
   1.240 +                        touse = atype.underlyingType;
   1.241 +                        arType = (Type.ArrayType) touse;
   1.242 +                        tomodify = new Type.ArrayType(null, arType.tsym);
   1.243 +                        ((Type.AnnotatedType)toreturn).underlyingType = tomodify;
   1.244 +                    } else {
   1.245 +                        arType = (Type.ArrayType) touse;
   1.246 +                        tomodify = new Type.ArrayType(null, arType.tsym);
   1.247 +                        toreturn = tomodify;
   1.248 +                    }
   1.249 +                }
   1.250 +                JCArrayTypeTree arTree = arrayTypeTree(typetree);
   1.251 +
   1.252 +                ListBuffer<TypePathEntry> depth = ListBuffer.lb();
   1.253 +                depth = depth.append(TypePathEntry.ARRAY);
   1.254 +                while (arType.elemtype.hasTag(TypeTag.ARRAY)) {
   1.255 +                    if (arType.elemtype.getKind() == TypeKind.ANNOTATED) {
   1.256 +                        Type.AnnotatedType aelemtype = (Type.AnnotatedType) arType.elemtype;
   1.257 +                        Type.AnnotatedType newAT = new Type.AnnotatedType(aelemtype.underlyingType);
   1.258 +                        tomodify.elemtype = newAT;
   1.259 +                        newAT.typeAnnotations = aelemtype.typeAnnotations;
   1.260 +                        arType = (Type.ArrayType) aelemtype.underlyingType;
   1.261 +                        tomodify = new Type.ArrayType(null, arType.tsym);
   1.262 +                        newAT.underlyingType = tomodify;
   1.263 +                    } else {
   1.264 +                        arType = (Type.ArrayType) arType.elemtype;
   1.265 +                        tomodify.elemtype = new Type.ArrayType(null, arType.tsym);
   1.266 +                        tomodify = (Type.ArrayType) tomodify.elemtype;
   1.267 +                    }
   1.268 +                    arTree = arrayTypeTree(arTree.elemtype);
   1.269 +                    depth = depth.append(TypePathEntry.ARRAY);
   1.270 +                }
   1.271 +                Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations, log);
   1.272 +                tomodify.elemtype = arelemType;
   1.273 +                for (Attribute.TypeCompound a : annotations) {
   1.274 +                    TypeAnnotationPosition p = a.position;
   1.275 +                    p.location = p.location.prependList(depth.toList());
   1.276 +                }
   1.277 +                return toreturn;
   1.278 +            } else if (type.hasTag(TypeTag.TYPEVAR)) {
   1.279 +                // Nothing to do for type variables.
   1.280 +                return type;
   1.281 +            } else {
   1.282 +                Type enclTy = type;
   1.283 +                Element enclEl = type.asElement();
   1.284 +                JCTree enclTr = typetree;
   1.285 +
   1.286 +                while (enclEl != null &&
   1.287 +                        enclEl.getKind() != ElementKind.PACKAGE &&
   1.288 +                        enclTy != null &&
   1.289 +                        enclTy.getKind() != TypeKind.NONE &&
   1.290 +                        enclTy.getKind() != TypeKind.ERROR &&
   1.291 +                        (enclTr.getKind() == JCTree.Kind.MEMBER_SELECT ||
   1.292 +                         enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE ||
   1.293 +                         enclTr.getKind() == JCTree.Kind.ANNOTATED_TYPE)) {
   1.294 +                    // Iterate also over the type tree, not just the type: the type is already
   1.295 +                    // completely resolved and we cannot distinguish where the annotation
   1.296 +                    // belongs for a nested type.
   1.297 +                    if (enclTr.getKind() == JCTree.Kind.MEMBER_SELECT) {
   1.298 +                        // only change encl in this case.
   1.299 +                        enclTy = enclTy.getEnclosingType();
   1.300 +                        enclEl = enclEl.getEnclosingElement();
   1.301 +                        enclTr = ((JCFieldAccess)enclTr).getExpression();
   1.302 +                    } else if (enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE) {
   1.303 +                        enclTr = ((JCTypeApply)enclTr).getType();
   1.304 +                    } else {
   1.305 +                        // only other option because of while condition
   1.306 +                        enclTr = ((JCAnnotatedType)enclTr).getUnderlyingType();
   1.307 +                    }
   1.308 +                }
   1.309 +
   1.310 +                /** We are trying to annotate some enclosing type,
   1.311 +                 * but nothing more exists.
   1.312 +                 */
   1.313 +                if (enclTy != null &&
   1.314 +                        enclTy.getKind() == TypeKind.NONE &&
   1.315 +                        (enclTr.getKind() == JCTree.Kind.IDENTIFIER ||
   1.316 +                         enclTr.getKind() == JCTree.Kind.MEMBER_SELECT ||
   1.317 +                         enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE ||
   1.318 +                         enclTr.getKind() == JCTree.Kind.ANNOTATED_TYPE)) {
   1.319 +                    // TODO: also if it's "java. @A lang.Object", that is,
   1.320 +                    // if it's on a package?
   1.321 +                    log.error(enclTr.pos(), "cant.annotate.nested.type", enclTr.toString());
   1.322 +                    return type;
   1.323 +                }
   1.324 +
   1.325 +                // At this point we have visited the part of the nested
   1.326 +                // type that is written in the source code.
   1.327 +                // Now count from here to the actual top-level class to determine
   1.328 +                // the correct nesting.
   1.329 +
   1.330 +                // The genericLocation for the annotation.
   1.331 +                ListBuffer<TypePathEntry> depth = ListBuffer.lb();
   1.332 +
   1.333 +                Type topTy = enclTy;
   1.334 +                while (enclEl != null &&
   1.335 +                        enclEl.getKind() != ElementKind.PACKAGE &&
   1.336 +                        topTy != null &&
   1.337 +                        topTy.getKind() != TypeKind.NONE &&
   1.338 +                        topTy.getKind() != TypeKind.ERROR) {
   1.339 +                    topTy = topTy.getEnclosingType();
   1.340 +                    enclEl = enclEl.getEnclosingElement();
   1.341 +
   1.342 +                    if (topTy != null && topTy.getKind() != TypeKind.NONE) {
   1.343 +                        // Only count enclosing types.
   1.344 +                        depth = depth.append(TypePathEntry.INNER_TYPE);
   1.345 +                    }
   1.346 +                }
   1.347 +
   1.348 +                if (depth.nonEmpty()) {
   1.349 +                    // Only need to change the annotation positions
   1.350 +                    // if they are on an enclosed type.
   1.351 +                    for (Attribute.TypeCompound a : annotations) {
   1.352 +                        TypeAnnotationPosition p = a.position;
   1.353 +                        p.location = p.location.appendList(depth.toList());
   1.354 +                    }
   1.355 +                }
   1.356 +
   1.357 +                Type ret = typeWithAnnotations(type, enclTy, annotations);
   1.358 +                return ret;
   1.359 +            }
   1.360 +        }
   1.361 +
   1.362 +        private static JCArrayTypeTree arrayTypeTree(JCTree typetree) {
   1.363 +            if (typetree.getKind() == JCTree.Kind.ARRAY_TYPE) {
   1.364 +                return (JCArrayTypeTree) typetree;
   1.365 +            } else if (typetree.getKind() == JCTree.Kind.ANNOTATED_TYPE) {
   1.366 +                return (JCArrayTypeTree) ((JCAnnotatedType)typetree).underlyingType;
   1.367 +            } else {
   1.368 +                Assert.error("Could not determine array type from type tree: " + typetree);
   1.369 +                return null;
   1.370 +            }
   1.371 +        }
   1.372 +
   1.373 +        /** Return a copy of the first type that only differs by
   1.374 +         * inserting the annotations to the left-most/inner-most type
   1.375 +         * or the type given by stopAt.
   1.376 +         *
   1.377 +         * We need the stopAt parameter to know where on a type to
   1.378 +         * put the annotations.
   1.379 +         * If we have nested classes Outer > Middle > Inner, and we
   1.380 +         * have the source type "@A Middle.Inner", we will invoke
   1.381 +         * this method with type = Outer.Middle.Inner,
   1.382 +         * stopAt = Middle.Inner, and annotations = @A.
   1.383 +         *
   1.384 +         * @param type The type to copy.
   1.385 +         * @param stopAt The type to stop at.
   1.386 +         * @param annotations The annotations to insert.
   1.387 +         * @return A copy of type that contains the annotations.
   1.388 +         */
   1.389 +        private static Type typeWithAnnotations(final Type type,
   1.390 +                final Type stopAt,
   1.391 +                final List<Attribute.TypeCompound> annotations) {
   1.392 +            Visitor<Type, List<TypeCompound>> visitor =
   1.393 +                    new Type.Visitor<Type, List<Attribute.TypeCompound>>() {
   1.394 +                @Override
   1.395 +                public Type visitClassType(ClassType t, List<TypeCompound> s) {
   1.396 +                    // assert that t.constValue() == null?
   1.397 +                    if (t == stopAt ||
   1.398 +                        t.getEnclosingType() == Type.noType) {
   1.399 +                        return new AnnotatedType(s, t);
   1.400 +                    } else {
   1.401 +                        ClassType ret = new ClassType(t.getEnclosingType().accept(this, s),
   1.402 +                                t.typarams_field, t.tsym);
   1.403 +                        ret.all_interfaces_field = t.all_interfaces_field;
   1.404 +                        ret.allparams_field = t.allparams_field;
   1.405 +                        ret.interfaces_field = t.interfaces_field;
   1.406 +                        ret.rank_field = t.rank_field;
   1.407 +                        ret.supertype_field = t.supertype_field;
   1.408 +                        return ret;
   1.409 +                    }
   1.410 +                }
   1.411 +
   1.412 +                @Override
   1.413 +                public Type visitAnnotatedType(AnnotatedType t, List<TypeCompound> s) {
   1.414 +                    return new AnnotatedType(t.typeAnnotations, t.underlyingType.accept(this, s));
   1.415 +                }
   1.416 +
   1.417 +                @Override
   1.418 +                public Type visitWildcardType(WildcardType t, List<TypeCompound> s) {
   1.419 +                    return new AnnotatedType(s, t);
   1.420 +                }
   1.421 +
   1.422 +                @Override
   1.423 +                public Type visitArrayType(ArrayType t, List<TypeCompound> s) {
   1.424 +                    ArrayType ret = new ArrayType(t.elemtype.accept(this, s), t.tsym);
   1.425 +                    return ret;
   1.426 +                }
   1.427 +
   1.428 +                @Override
   1.429 +                public Type visitMethodType(MethodType t, List<TypeCompound> s) {
   1.430 +                    // Impossible?
   1.431 +                    return t;
   1.432 +                }
   1.433 +
   1.434 +                @Override
   1.435 +                public Type visitPackageType(PackageType t, List<TypeCompound> s) {
   1.436 +                    // Impossible?
   1.437 +                    return t;
   1.438 +                }
   1.439 +
   1.440 +                @Override
   1.441 +                public Type visitTypeVar(TypeVar t, List<TypeCompound> s) {
   1.442 +                    return new AnnotatedType(s, t);
   1.443 +                }
   1.444 +
   1.445 +                @Override
   1.446 +                public Type visitCapturedType(CapturedType t, List<TypeCompound> s) {
   1.447 +                    return new AnnotatedType(s, t);
   1.448 +                }
   1.449 +
   1.450 +                @Override
   1.451 +                public Type visitForAll(ForAll t, List<TypeCompound> s) {
   1.452 +                    // Impossible?
   1.453 +                    return t;
   1.454 +                }
   1.455 +
   1.456 +                @Override
   1.457 +                public Type visitUndetVar(UndetVar t, List<TypeCompound> s) {
   1.458 +                    // Impossible?
   1.459 +                    return t;
   1.460 +                }
   1.461 +
   1.462 +                @Override
   1.463 +                public Type visitErrorType(ErrorType t, List<TypeCompound> s) {
   1.464 +                    return new AnnotatedType(s, t);
   1.465 +                }
   1.466 +
   1.467 +                @Override
   1.468 +                public Type visitType(Type t, List<TypeCompound> s) {
   1.469 +                    // Error?
   1.470 +                    return t;
   1.471 +                }
   1.472 +            };
   1.473 +
   1.474 +            return type.accept(visitor, annotations);
   1.475 +        }
   1.476 +
   1.477 +        private static Attribute.TypeCompound toTypeCompound(Attribute.Compound a, TypeAnnotationPosition p) {
   1.478 +            // It is safe to alias the position.
   1.479 +            return new Attribute.TypeCompound(a, p);
   1.480 +        }
   1.481 +
   1.482 +        private AnnotationType annotationType(Attribute.Compound a, Symbol s) {
   1.483 +            Attribute.Compound atTarget =
   1.484 +                a.type.tsym.attribute(syms.annotationTargetType.tsym);
   1.485 +            if (atTarget == null) {
   1.486 +                return inferTargetMetaInfo(a, s);
   1.487 +            }
   1.488 +            Attribute atValue = atTarget.member(names.value);
   1.489 +            if (!(atValue instanceof Attribute.Array)) {
   1.490 +                Assert.error("annotationType(): bad @Target argument " + atValue +
   1.491 +                        " (" + atValue.getClass() + ")");
   1.492 +                return AnnotationType.DECLARATION; // error recovery
   1.493 +            }
   1.494 +            Attribute.Array arr = (Attribute.Array) atValue;
   1.495 +            boolean isDecl = false, isType = false;
   1.496 +            for (Attribute app : arr.values) {
   1.497 +                if (!(app instanceof Attribute.Enum)) {
   1.498 +                    Assert.error("annotationType(): unrecognized Attribute kind " + app +
   1.499 +                            " (" + app.getClass() + ")");
   1.500 +                    isDecl = true;
   1.501 +                    continue;
   1.502 +                }
   1.503 +                Attribute.Enum e = (Attribute.Enum) app;
   1.504 +                if (e.value.name == names.TYPE) {
   1.505 +                    if (s.kind == Kinds.TYP)
   1.506 +                        isDecl = true;
   1.507 +                } else if (e.value.name == names.FIELD) {
   1.508 +                    if (s.kind == Kinds.VAR &&
   1.509 +                            s.owner.kind != Kinds.MTH)
   1.510 +                        isDecl = true;
   1.511 +                } else if (e.value.name == names.METHOD) {
   1.512 +                    if (s.kind == Kinds.MTH &&
   1.513 +                            !s.isConstructor())
   1.514 +                        isDecl = true;
   1.515 +                } else if (e.value.name == names.PARAMETER) {
   1.516 +                    if (s.kind == Kinds.VAR &&
   1.517 +                            s.owner.kind == Kinds.MTH &&
   1.518 +                            (s.flags() & Flags.PARAMETER) != 0)
   1.519 +                        isDecl = true;
   1.520 +                } else if (e.value.name == names.CONSTRUCTOR) {
   1.521 +                    if (s.kind == Kinds.MTH &&
   1.522 +                            s.isConstructor())
   1.523 +                        isDecl = true;
   1.524 +                } else if (e.value.name == names.LOCAL_VARIABLE) {
   1.525 +                    if (s.kind == Kinds.VAR &&
   1.526 +                            s.owner.kind == Kinds.MTH &&
   1.527 +                            (s.flags() & Flags.PARAMETER) == 0)
   1.528 +                        isDecl = true;
   1.529 +                } else if (e.value.name == names.ANNOTATION_TYPE) {
   1.530 +                    if (s.kind == Kinds.TYP &&
   1.531 +                            (s.flags() & Flags.ANNOTATION) != 0)
   1.532 +                        isDecl = true;
   1.533 +                } else if (e.value.name == names.PACKAGE) {
   1.534 +                    if (s.kind == Kinds.PCK)
   1.535 +                        isDecl = true;
   1.536 +                } else if (e.value.name == names.TYPE_USE) {
   1.537 +                    if (s.kind == Kinds.TYP ||
   1.538 +                            s.kind == Kinds.VAR ||
   1.539 +                            (s.kind == Kinds.MTH && !s.isConstructor() &&
   1.540 +                            !s.type.getReturnType().hasTag(TypeTag.VOID)) ||
   1.541 +                            (s.kind == Kinds.MTH && s.isConstructor()))
   1.542 +                        isType = true;
   1.543 +                } else if (e.value.name == names.TYPE_PARAMETER) {
   1.544 +                    /* Irrelevant in this case */
   1.545 +                    // TYPE_PARAMETER doesn't aid in distinguishing between
   1.546 +                    // Type annotations and declaration annotations on an
   1.547 +                    // Element
   1.548 +                } else {
   1.549 +                    Assert.error("annotationType(): unrecognized Attribute name " + e.value.name +
   1.550 +                            " (" + e.value.name.getClass() + ")");
   1.551 +                    isDecl = true;
   1.552 +                }
   1.553 +            }
   1.554 +            if (isDecl && isType) {
   1.555 +                return AnnotationType.BOTH;
   1.556 +            } else if (isType) {
   1.557 +                return AnnotationType.TYPE;
   1.558 +            } else {
   1.559 +                return AnnotationType.DECLARATION;
   1.560 +            }
   1.561 +        }
   1.562 +
   1.563 +        /** Infer the target annotation kind, if none is give.
   1.564 +         * We only infer declaration annotations.
   1.565 +         */
   1.566 +        private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) {
   1.567 +            return AnnotationType.DECLARATION;
   1.568 +        }
   1.569 +
   1.570 +
   1.571 +        /* This is the beginning of the second part of organizing
   1.572 +         * type annotations: determine the type annotation positions.
   1.573 +         */
   1.574 +
   1.575 +        private void resolveFrame(JCTree tree, JCTree frame,
   1.576 +                List<JCTree> path, TypeAnnotationPosition p) {
   1.577 +            /*
   1.578 +            System.out.println("Resolving tree: " + tree + " kind: " + tree.getKind());
   1.579 +            System.out.println("    Framing tree: " + frame + " kind: " + frame.getKind());
   1.580 +            */
   1.581 +            switch (frame.getKind()) {
   1.582 +                case TYPE_CAST:
   1.583 +                    p.type = TargetType.CAST;
   1.584 +                    p.pos = frame.pos;
   1.585 +                    return;
   1.586 +
   1.587 +                case INSTANCE_OF:
   1.588 +                    p.type = TargetType.INSTANCEOF;
   1.589 +                    p.pos = frame.pos;
   1.590 +                    return;
   1.591 +
   1.592 +                case NEW_CLASS:
   1.593 +                    JCNewClass frameNewClass = (JCNewClass)frame;
   1.594 +                    if (frameNewClass.typeargs.contains(tree)) {
   1.595 +                        p.type = TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT;
   1.596 +                        p.type_index = frameNewClass.typeargs.indexOf(tree);
   1.597 +                    } else {
   1.598 +                        p.type = TargetType.NEW;
   1.599 +                    }
   1.600 +                    p.pos = frame.pos;
   1.601 +                    return;
   1.602 +
   1.603 +                case NEW_ARRAY:
   1.604 +                    p.type = TargetType.NEW;
   1.605 +                    p.pos = frame.pos;
   1.606 +                    return;
   1.607 +
   1.608 +                case ANNOTATION_TYPE:
   1.609 +                case CLASS:
   1.610 +                case ENUM:
   1.611 +                case INTERFACE:
   1.612 +                    p.pos = frame.pos;
   1.613 +                    if (((JCClassDecl)frame).extending == tree) {
   1.614 +                        p.type = TargetType.CLASS_EXTENDS;
   1.615 +                        p.type_index = -1;
   1.616 +                    } else if (((JCClassDecl)frame).implementing.contains(tree)) {
   1.617 +                        p.type = TargetType.CLASS_EXTENDS;
   1.618 +                        p.type_index = ((JCClassDecl)frame).implementing.indexOf(tree);
   1.619 +                    } else if (((JCClassDecl)frame).typarams.contains(tree)) {
   1.620 +                        p.type = TargetType.CLASS_TYPE_PARAMETER;
   1.621 +                        p.parameter_index = ((JCClassDecl)frame).typarams.indexOf(tree);
   1.622 +                    } else {
   1.623 +                        Assert.error("Could not determine position of tree " + tree +
   1.624 +                                " within frame " + frame);
   1.625 +                    }
   1.626 +                    return;
   1.627 +
   1.628 +                case METHOD: {
   1.629 +                    JCMethodDecl frameMethod = (JCMethodDecl) frame;
   1.630 +                    p.pos = frame.pos;
   1.631 +                    if (frameMethod.thrown.contains(tree)) {
   1.632 +                        p.type = TargetType.THROWS;
   1.633 +                        p.type_index = frameMethod.thrown.indexOf(tree);
   1.634 +                    } else if (frameMethod.restype == tree) {
   1.635 +                        p.type = TargetType.METHOD_RETURN;
   1.636 +                    } else if (frameMethod.typarams.contains(tree)) {
   1.637 +                        p.type = TargetType.METHOD_TYPE_PARAMETER;
   1.638 +                        p.parameter_index = frameMethod.typarams.indexOf(tree);
   1.639 +                    } else {
   1.640 +                        Assert.error("Could not determine position of tree " + tree +
   1.641 +                                " within frame " + frame);
   1.642 +                    }
   1.643 +                    return;
   1.644 +                }
   1.645 +
   1.646 +                case PARAMETERIZED_TYPE: {
   1.647 +                    if (((JCTypeApply)frame).clazz == tree) {
   1.648 +                        // generic: RAW; noop
   1.649 +                    } else if (((JCTypeApply)frame).arguments.contains(tree)) {
   1.650 +                        JCTypeApply taframe = (JCTypeApply) frame;
   1.651 +                        int arg = taframe.arguments.indexOf(tree);
   1.652 +                        p.location = p.location.prepend(new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg));
   1.653 +
   1.654 +                        locateNestedTypes(taframe.type, p);
   1.655 +                    } else {
   1.656 +                        Assert.error("Could not determine type argument position of tree " + tree +
   1.657 +                                " within frame " + frame);
   1.658 +                    }
   1.659 +
   1.660 +                    List<JCTree> newPath = path.tail;
   1.661 +                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
   1.662 +                    return;
   1.663 +                }
   1.664 +
   1.665 +                case ARRAY_TYPE: {
   1.666 +                    ListBuffer<TypePathEntry> index = ListBuffer.lb();
   1.667 +                    index = index.append(TypePathEntry.ARRAY);
   1.668 +                    List<JCTree> newPath = path.tail;
   1.669 +                    while (true) {
   1.670 +                        JCTree npHead = newPath.tail.head;
   1.671 +                        if (npHead.hasTag(JCTree.Tag.TYPEARRAY)) {
   1.672 +                            newPath = newPath.tail;
   1.673 +                            index = index.append(TypePathEntry.ARRAY);
   1.674 +                        } else if (npHead.hasTag(JCTree.Tag.ANNOTATED_TYPE)) {
   1.675 +                            newPath = newPath.tail;
   1.676 +                        } else {
   1.677 +                            break;
   1.678 +                        }
   1.679 +                    }
   1.680 +                    p.location = p.location.prependList(index.toList());
   1.681 +                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
   1.682 +                    return;
   1.683 +                }
   1.684 +
   1.685 +                case TYPE_PARAMETER:
   1.686 +                    if (path.tail.tail.head.hasTag(JCTree.Tag.CLASSDEF)) {
   1.687 +                        JCClassDecl clazz = (JCClassDecl)path.tail.tail.head;
   1.688 +                        p.type = TargetType.CLASS_TYPE_PARAMETER_BOUND;
   1.689 +                        p.parameter_index = clazz.typarams.indexOf(path.tail.head);
   1.690 +                        p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree);
   1.691 +                        if (((JCTypeParameter)frame).bounds.get(0).type.isInterface()) {
   1.692 +                            // Account for an implicit Object as bound 0
   1.693 +                            p.bound_index += 1;
   1.694 +                        }
   1.695 +                    } else if (path.tail.tail.head.hasTag(JCTree.Tag.METHODDEF)) {
   1.696 +                        JCMethodDecl method = (JCMethodDecl)path.tail.tail.head;
   1.697 +                        p.type = TargetType.METHOD_TYPE_PARAMETER_BOUND;
   1.698 +                        p.parameter_index = method.typarams.indexOf(path.tail.head);
   1.699 +                        p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree);
   1.700 +                        if (((JCTypeParameter)frame).bounds.get(0).type.isInterface()) {
   1.701 +                            // Account for an implicit Object as bound 0
   1.702 +                            p.bound_index += 1;
   1.703 +                        }
   1.704 +                    } else {
   1.705 +                        Assert.error("Could not determine position of tree " + tree +
   1.706 +                                " within frame " + frame);
   1.707 +                    }
   1.708 +                    p.pos = frame.pos;
   1.709 +                    return;
   1.710 +
   1.711 +                case VARIABLE:
   1.712 +                    VarSymbol v = ((JCVariableDecl)frame).sym;
   1.713 +                    p.pos = frame.pos;
   1.714 +                    switch (v.getKind()) {
   1.715 +                        case LOCAL_VARIABLE:
   1.716 +                            p.type = TargetType.LOCAL_VARIABLE;
   1.717 +                            break;
   1.718 +                        case FIELD:
   1.719 +                            p.type = TargetType.FIELD;
   1.720 +                            break;
   1.721 +                        case PARAMETER:
   1.722 +                            if (v.getQualifiedName().equals(names._this)) {
   1.723 +                                // TODO: Intro a separate ElementKind?
   1.724 +                                p.type = TargetType.METHOD_RECEIVER;
   1.725 +                            } else {
   1.726 +                                p.type = TargetType.METHOD_FORMAL_PARAMETER;
   1.727 +                                p.parameter_index = methodParamIndex(path, frame);
   1.728 +                            }
   1.729 +                            break;
   1.730 +                        case EXCEPTION_PARAMETER:
   1.731 +                            p.type = TargetType.EXCEPTION_PARAMETER;
   1.732 +                            break;
   1.733 +                        case RESOURCE_VARIABLE:
   1.734 +                            p.type = TargetType.RESOURCE_VARIABLE;
   1.735 +                            break;
   1.736 +                        default:
   1.737 +                            Assert.error("Found unexpected type annotation for variable: " + v + " with kind: " + v.getKind());
   1.738 +                    }
   1.739 +                    return;
   1.740 +
   1.741 +                case ANNOTATED_TYPE: {
   1.742 +                    if (frame == tree) {
   1.743 +                        // This is only true for the first annotated type we see.
   1.744 +                        // For any other annotated types along the path, we do
   1.745 +                        // not care about inner types.
   1.746 +                        JCAnnotatedType atypetree = (JCAnnotatedType) frame;
   1.747 +                        final Type utype = atypetree.underlyingType.type;
   1.748 +                        Symbol tsym = utype.tsym;
   1.749 +                        if (tsym.getKind().equals(ElementKind.TYPE_PARAMETER) ||
   1.750 +                                utype.getKind().equals(TypeKind.WILDCARD) ||
   1.751 +                                utype.getKind().equals(TypeKind.ARRAY)) {
   1.752 +                            // Type parameters, wildcards, and arrays have the declaring
   1.753 +                            // class/method as enclosing elements.
   1.754 +                            // There is actually nothing to do for them.
   1.755 +                        } else {
   1.756 +                            locateNestedTypes(utype, p);
   1.757 +                        }
   1.758 +                    }
   1.759 +                    List<JCTree> newPath = path.tail;
   1.760 +                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
   1.761 +                    return;
   1.762 +                }
   1.763 +
   1.764 +                case UNION_TYPE: {
   1.765 +                    // TODO: can we store any information here to help in
   1.766 +                    // determining the final position?
   1.767 +                    List<JCTree> newPath = path.tail;
   1.768 +                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
   1.769 +                    return;
   1.770 +                }
   1.771 +
   1.772 +                case METHOD_INVOCATION: {
   1.773 +                    JCMethodInvocation invocation = (JCMethodInvocation)frame;
   1.774 +                    if (!invocation.typeargs.contains(tree)) {
   1.775 +                        Assert.error("{" + tree + "} is not an argument in the invocation: " + invocation);
   1.776 +                    }
   1.777 +                    p.type = TargetType.METHOD_INVOCATION_TYPE_ARGUMENT;
   1.778 +                    p.pos = invocation.pos;
   1.779 +                    p.type_index = invocation.typeargs.indexOf(tree);
   1.780 +                    return;
   1.781 +                }
   1.782 +
   1.783 +                case EXTENDS_WILDCARD:
   1.784 +                case SUPER_WILDCARD: {
   1.785 +                    // Annotations in wildcard bounds
   1.786 +                    p.location = p.location.prepend(TypePathEntry.WILDCARD);
   1.787 +                    List<JCTree> newPath = path.tail;
   1.788 +                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
   1.789 +                    return;
   1.790 +                }
   1.791 +
   1.792 +                case MEMBER_SELECT: {
   1.793 +                    List<JCTree> newPath = path.tail;
   1.794 +                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
   1.795 +                    return;
   1.796 +                }
   1.797 +
   1.798 +                default:
   1.799 +                    Assert.error("Unresolved frame: " + frame + " of kind: " + frame.getKind() +
   1.800 +                            "\n    Looking for tree: " + tree);
   1.801 +                    return;
   1.802 +            }
   1.803 +        }
   1.804 +
   1.805 +        private static void locateNestedTypes(Type type, TypeAnnotationPosition p) {
   1.806 +            // The number of "steps" to get from the full type to the
   1.807 +            // left-most outer type.
   1.808 +            ListBuffer<TypePathEntry> depth = ListBuffer.lb();
   1.809 +
   1.810 +            Type encl = type.getEnclosingType();
   1.811 +            while (encl != null &&
   1.812 +                    encl.getKind() != TypeKind.NONE &&
   1.813 +                    encl.getKind() != TypeKind.ERROR) {
   1.814 +                depth = depth.append(TypePathEntry.INNER_TYPE);
   1.815 +                encl = encl.getEnclosingType();
   1.816 +            }
   1.817 +            if (depth.nonEmpty()) {
   1.818 +                p.location = p.location.prependList(depth.toList());
   1.819 +            }
   1.820 +        }
   1.821 +
   1.822 +        private static int methodParamIndex(List<JCTree> path, JCTree param) {
   1.823 +            List<JCTree> curr = path;
   1.824 +            while (curr.head.getTag() != Tag.METHODDEF) {
   1.825 +                curr = curr.tail;
   1.826 +            }
   1.827 +            JCMethodDecl method = (JCMethodDecl)curr.head;
   1.828 +            return method.params.indexOf(param);
   1.829 +        }
   1.830 +
   1.831 +        // Each class (including enclosed inner classes) is visited separately.
   1.832 +        // This flag is used to prevent from visiting inner classes.
   1.833 +        private boolean isInClass = false;
   1.834 +
   1.835 +        @Override
   1.836 +        public void visitClassDef(JCClassDecl tree) {
   1.837 +            if (isInClass)
   1.838 +                return;
   1.839 +            isInClass = true;
   1.840 +            if (sigOnly) {
   1.841 +                scan(tree.mods);
   1.842 +                scan(tree.typarams);
   1.843 +                scan(tree.extending);
   1.844 +                scan(tree.implementing);
   1.845 +            }
   1.846 +            scan(tree.defs);
   1.847 +        }
   1.848 +
   1.849 +        /**
   1.850 +         * Resolve declaration vs. type annotations in methods and
   1.851 +         * then determine the positions.
   1.852 +         */
   1.853 +        @Override
   1.854 +        public void visitMethodDef(final JCMethodDecl tree) {
   1.855 +            if (tree.sym == null) {
   1.856 +                // Something most be wrong, e.g. a class not found.
   1.857 +                // Quietly ignore. (See test FailOver15.java)
   1.858 +                return;
   1.859 +            }
   1.860 +            if (sigOnly) {
   1.861 +                {
   1.862 +                    TypeAnnotationPosition pos = new TypeAnnotationPosition();
   1.863 +                    pos.type = TargetType.METHOD_RETURN;
   1.864 +                    if (tree.sym.isConstructor()) {
   1.865 +                        pos.pos = tree.pos;
   1.866 +                        // Use null to mark that the annotations go with the symbol.
   1.867 +                        separateAnnotationsKinds(tree, null, tree.sym, pos);
   1.868 +                    } else {
   1.869 +                        pos.pos = tree.restype.pos;
   1.870 +                        separateAnnotationsKinds(tree.restype, tree.sym.type.getReturnType(),
   1.871 +                                tree.sym, pos);
   1.872 +                    }
   1.873 +                }
   1.874 +                if (tree.recvparam != null && tree.recvparam.sym != null) {
   1.875 +                    // TODO: make sure there are no declaration annotations.
   1.876 +                    TypeAnnotationPosition pos = new TypeAnnotationPosition();
   1.877 +                    pos.type = TargetType.METHOD_RECEIVER;
   1.878 +                    pos.pos = tree.recvparam.vartype.pos;
   1.879 +                    separateAnnotationsKinds(tree.recvparam.vartype, tree.recvparam.sym.type,
   1.880 +                            tree.recvparam.sym, pos);
   1.881 +                }
   1.882 +                int i = 0;
   1.883 +                for (JCVariableDecl param : tree.params) {
   1.884 +                    TypeAnnotationPosition pos = new TypeAnnotationPosition();
   1.885 +                    pos.type = TargetType.METHOD_FORMAL_PARAMETER;
   1.886 +                    pos.parameter_index = i;
   1.887 +                    pos.pos = param.vartype.pos;
   1.888 +                    separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
   1.889 +                    ++i;
   1.890 +                }
   1.891 +            }
   1.892 +
   1.893 +            push(tree);
   1.894 +            // super.visitMethodDef(tree);
   1.895 +            if (sigOnly) {
   1.896 +                scan(tree.mods);
   1.897 +                scan(tree.restype);
   1.898 +                scan(tree.typarams);
   1.899 +                scan(tree.recvparam);
   1.900 +                scan(tree.params);
   1.901 +                scan(tree.thrown);
   1.902 +            } else {
   1.903 +                scan(tree.defaultValue);
   1.904 +                scan(tree.body);
   1.905 +            }
   1.906 +            pop();
   1.907 +        }
   1.908 +
   1.909 +        /**
   1.910 +         * Resolve declaration vs. type annotations in variable declarations and
   1.911 +         * then determine the positions.
   1.912 +         */
   1.913 +        @Override
   1.914 +        public void visitVarDef(final JCVariableDecl tree) {
   1.915 +            if (tree.sym == null) {
   1.916 +                // Something is wrong already. Quietly ignore.
   1.917 +            } else if (tree.sym.getKind() == ElementKind.FIELD) {
   1.918 +                if (sigOnly) {
   1.919 +                    TypeAnnotationPosition pos = new TypeAnnotationPosition();
   1.920 +                    pos.type = TargetType.FIELD;
   1.921 +                    pos.pos = tree.pos;
   1.922 +                    separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
   1.923 +                }
   1.924 +            } else if (tree.sym.getKind() == ElementKind.LOCAL_VARIABLE) {
   1.925 +                TypeAnnotationPosition pos = new TypeAnnotationPosition();
   1.926 +                pos.type = TargetType.LOCAL_VARIABLE;
   1.927 +                pos.pos = tree.pos;
   1.928 +                separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
   1.929 +            } else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
   1.930 +                // System.out.println("Found exception param: " + tree);
   1.931 +                TypeAnnotationPosition pos = new TypeAnnotationPosition();
   1.932 +                pos.type = TargetType.EXCEPTION_PARAMETER;
   1.933 +                pos.pos = tree.pos;
   1.934 +                separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
   1.935 +            } else if (tree.sym.getKind() == ElementKind.RESOURCE_VARIABLE) {
   1.936 +                TypeAnnotationPosition pos = new TypeAnnotationPosition();
   1.937 +                pos.type = TargetType.RESOURCE_VARIABLE;
   1.938 +                pos.pos = tree.pos;
   1.939 +                separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
   1.940 +            } else {
   1.941 +                // There is nothing else in a variable declaration that needs separation.
   1.942 +                // System.out.println("We found a: " + tree);
   1.943 +            }
   1.944 +
   1.945 +            push(tree);
   1.946 +            // super.visitVarDef(tree);
   1.947 +            scan(tree.mods);
   1.948 +            scan(tree.vartype);
   1.949 +            if (!sigOnly) {
   1.950 +                scan(tree.init);
   1.951 +            }
   1.952 +            pop();
   1.953 +        }
   1.954 +
   1.955 +        @Override
   1.956 +        public void visitBlock(JCBlock tree) {
   1.957 +            // Do not descend into top-level blocks when only interested
   1.958 +            // in the signature.
   1.959 +            if (!sigOnly) {
   1.960 +                scan(tree.stats);
   1.961 +            }
   1.962 +        }
   1.963 +
   1.964 +        @Override
   1.965 +        public void visitAnnotatedType(JCAnnotatedType tree) {
   1.966 +            push(tree);
   1.967 +            findPosition(tree, tree, tree.annotations);
   1.968 +            pop();
   1.969 +            super.visitAnnotatedType(tree);
   1.970 +        }
   1.971 +
   1.972 +        @Override
   1.973 +        public void visitTypeParameter(JCTypeParameter tree) {
   1.974 +            findPosition(tree, peek2(), tree.annotations);
   1.975 +            super.visitTypeParameter(tree);
   1.976 +        }
   1.977 +
   1.978 +        @Override
   1.979 +        public void visitNewArray(JCNewArray tree) {
   1.980 +            findPosition(tree, tree, tree.annotations);
   1.981 +            int dimAnnosCount = tree.dimAnnotations.size();
   1.982 +            ListBuffer<TypePathEntry> depth = ListBuffer.lb();
   1.983 +
   1.984 +            // handle annotations associated with dimensions
   1.985 +            for (int i = 0; i < dimAnnosCount; ++i) {
   1.986 +                TypeAnnotationPosition p = new TypeAnnotationPosition();
   1.987 +                p.pos = tree.pos;
   1.988 +                p.type = TargetType.NEW;
   1.989 +                if (i != 0) {
   1.990 +                    depth = depth.append(TypePathEntry.ARRAY);
   1.991 +                    p.location = p.location.appendList(depth.toList());
   1.992 +                }
   1.993 +
   1.994 +                setTypeAnnotationPos(tree.dimAnnotations.get(i), p);
   1.995 +            }
   1.996 +
   1.997 +            // handle "free" annotations
   1.998 +            // int i = dimAnnosCount == 0 ? 0 : dimAnnosCount - 1;
   1.999 +            // TODO: is depth.size == i here?
  1.1000 +            JCExpression elemType = tree.elemtype;
  1.1001 +            while (elemType != null) {
  1.1002 +                if (elemType.hasTag(JCTree.Tag.ANNOTATED_TYPE)) {
  1.1003 +                    JCAnnotatedType at = (JCAnnotatedType)elemType;
  1.1004 +                    TypeAnnotationPosition p = new TypeAnnotationPosition();
  1.1005 +                    p.type = TargetType.NEW;
  1.1006 +                    p.pos = tree.pos;
  1.1007 +                    p.location = p.location.appendList(depth.toList());
  1.1008 +                    setTypeAnnotationPos(at.annotations, p);
  1.1009 +                    elemType = at.underlyingType;
  1.1010 +                } else if (elemType.hasTag(JCTree.Tag.TYPEARRAY)) {
  1.1011 +                    depth = depth.append(TypePathEntry.ARRAY);
  1.1012 +                    elemType = ((JCArrayTypeTree)elemType).elemtype;
  1.1013 +                } else {
  1.1014 +                    break;
  1.1015 +                }
  1.1016 +            }
  1.1017 +            scan(tree.elems);
  1.1018 +        }
  1.1019 +
  1.1020 +        private void findPosition(JCTree tree, JCTree frame, List<JCAnnotation> annotations) {
  1.1021 +            if (!annotations.isEmpty()) {
  1.1022 +                /*
  1.1023 +                System.out.println("Finding pos for: " + annotations);
  1.1024 +                System.out.println("    tree: " + tree);
  1.1025 +                System.out.println("    frame: " + frame);
  1.1026 +                */
  1.1027 +                TypeAnnotationPosition p = new TypeAnnotationPosition();
  1.1028 +                resolveFrame(tree, frame, frames.toList(), p);
  1.1029 +                setTypeAnnotationPos(annotations, p);
  1.1030 +            }
  1.1031 +        }
  1.1032 +
  1.1033 +        private static void setTypeAnnotationPos(List<JCAnnotation> annotations,
  1.1034 +                TypeAnnotationPosition position) {
  1.1035 +            for (JCAnnotation anno : annotations) {
  1.1036 +                ((Attribute.TypeCompound) anno.attribute).position = position;
  1.1037 +            }
  1.1038 +        }
  1.1039 +    }
  1.1040 +}

mercurial