langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
changeset 25349 7247a4c76872
parent 25348 ae2df33eddfe
parent 25337 31eeda0060a9
child 25365 6db782823853
equal deleted inserted replaced
25348:ae2df33eddfe 25349:7247a4c76872
     1 /*
       
     2  * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package com.sun.tools.javac.code;
       
    27 
       
    28 import javax.lang.model.element.Element;
       
    29 import javax.lang.model.element.ElementKind;
       
    30 import javax.lang.model.type.TypeKind;
       
    31 
       
    32 import javax.tools.JavaFileObject;
       
    33 
       
    34 import com.sun.tools.javac.code.Attribute.TypeCompound;
       
    35 import com.sun.tools.javac.code.Type.ArrayType;
       
    36 import com.sun.tools.javac.code.Type.CapturedType;
       
    37 import com.sun.tools.javac.code.Type.ClassType;
       
    38 import com.sun.tools.javac.code.Type.ErrorType;
       
    39 import com.sun.tools.javac.code.Type.ForAll;
       
    40 import com.sun.tools.javac.code.Type.MethodType;
       
    41 import com.sun.tools.javac.code.Type.PackageType;
       
    42 import com.sun.tools.javac.code.Type.TypeVar;
       
    43 import com.sun.tools.javac.code.Type.UndetVar;
       
    44 import com.sun.tools.javac.code.Type.Visitor;
       
    45 import com.sun.tools.javac.code.Type.WildcardType;
       
    46 import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntry;
       
    47 import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind;
       
    48 import com.sun.tools.javac.code.Symbol.VarSymbol;
       
    49 import com.sun.tools.javac.code.Symbol.MethodSymbol;
       
    50 import com.sun.tools.javac.comp.Annotate;
       
    51 import com.sun.tools.javac.comp.Annotate.Worker;
       
    52 import com.sun.tools.javac.comp.Attr;
       
    53 import com.sun.tools.javac.comp.AttrContext;
       
    54 import com.sun.tools.javac.comp.Env;
       
    55 import com.sun.tools.javac.tree.JCTree;
       
    56 import com.sun.tools.javac.tree.TreeInfo;
       
    57 import com.sun.tools.javac.tree.JCTree.JCBlock;
       
    58 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
       
    59 import com.sun.tools.javac.tree.JCTree.JCExpression;
       
    60 import com.sun.tools.javac.tree.JCTree.JCLambda;
       
    61 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
       
    62 import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
       
    63 import com.sun.tools.javac.tree.JCTree.JCNewClass;
       
    64 import com.sun.tools.javac.tree.JCTree.JCTypeApply;
       
    65 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
       
    66 import com.sun.tools.javac.tree.TreeScanner;
       
    67 import com.sun.tools.javac.tree.JCTree.*;
       
    68 import com.sun.tools.javac.util.Assert;
       
    69 import com.sun.tools.javac.util.Context;
       
    70 import com.sun.tools.javac.util.List;
       
    71 import com.sun.tools.javac.util.ListBuffer;
       
    72 import com.sun.tools.javac.util.Log;
       
    73 import com.sun.tools.javac.util.Names;
       
    74 import com.sun.tools.javac.util.Options;
       
    75 
       
    76 /**
       
    77  * Contains operations specific to processing type annotations.
       
    78  * This class has two functions:
       
    79  * separate declaration from type annotations and insert the type
       
    80  * annotations to their types;
       
    81  * and determine the TypeAnnotationPositions for all type annotations.
       
    82  */
       
    83 public class TypeAnnotations {
       
    84     protected static final Context.Key<TypeAnnotations> typeAnnosKey = new Context.Key<>();
       
    85 
       
    86     public static TypeAnnotations instance(Context context) {
       
    87         TypeAnnotations instance = context.get(typeAnnosKey);
       
    88         if (instance == null)
       
    89             instance = new TypeAnnotations(context);
       
    90         return instance;
       
    91     }
       
    92 
       
    93     final Log log;
       
    94     final Names names;
       
    95     final Symtab syms;
       
    96     final Annotate annotate;
       
    97     final Attr attr;
       
    98 
       
    99     protected TypeAnnotations(Context context) {
       
   100         context.put(typeAnnosKey, this);
       
   101         names = Names.instance(context);
       
   102         log = Log.instance(context);
       
   103         syms = Symtab.instance(context);
       
   104         annotate = Annotate.instance(context);
       
   105         attr = Attr.instance(context);
       
   106         Options options = Options.instance(context);
       
   107     }
       
   108 
       
   109     /**
       
   110      * Separate type annotations from declaration annotations and
       
   111      * determine the correct positions for type annotations.
       
   112      * This version only visits types in signatures and should be
       
   113      * called from MemberEnter.
       
   114      * The method takes the Annotate object as parameter and
       
   115      * adds an Annotate.Worker to the correct Annotate queue for
       
   116      * later processing.
       
   117      */
       
   118     public void organizeTypeAnnotationsSignatures(final Env<AttrContext> env, final JCClassDecl tree) {
       
   119         annotate.afterRepeated( new Worker() {
       
   120             @Override
       
   121             public void run() {
       
   122                 JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
       
   123 
       
   124                 try {
       
   125                     new TypeAnnotationPositions(true).scan(tree);
       
   126                 } finally {
       
   127                     log.useSource(oldSource);
       
   128                 }
       
   129             }
       
   130         } );
       
   131     }
       
   132 
       
   133     public void validateTypeAnnotationsSignatures(final Env<AttrContext> env, final JCClassDecl tree) {
       
   134         annotate.validate(new Worker() { //validate annotations
       
   135             @Override
       
   136             public void run() {
       
   137                 JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
       
   138 
       
   139                 try {
       
   140                     attr.validateTypeAnnotations(tree, true);
       
   141                 } finally {
       
   142                     log.useSource(oldSource);
       
   143                 }
       
   144             }
       
   145         } );
       
   146     }
       
   147 
       
   148     /**
       
   149      * This version only visits types in bodies, that is, field initializers,
       
   150      * top-level blocks, and method bodies, and should be called from Attr.
       
   151      */
       
   152     public void organizeTypeAnnotationsBodies(JCClassDecl tree) {
       
   153         new TypeAnnotationPositions(false).scan(tree);
       
   154     }
       
   155 
       
   156     public enum AnnotationType { DECLARATION, TYPE, BOTH }
       
   157 
       
   158     /**
       
   159      * Determine whether an annotation is a declaration annotation,
       
   160      * a type annotation, or both.
       
   161      */
       
   162     public AnnotationType annotationType(Attribute.Compound a, Symbol s) {
       
   163         Attribute.Compound atTarget =
       
   164             a.type.tsym.attribute(syms.annotationTargetType.tsym);
       
   165         if (atTarget == null) {
       
   166             return inferTargetMetaInfo(a, s);
       
   167         }
       
   168         Attribute atValue = atTarget.member(names.value);
       
   169         if (!(atValue instanceof Attribute.Array)) {
       
   170             Assert.error("annotationType(): bad @Target argument " + atValue +
       
   171                     " (" + atValue.getClass() + ")");
       
   172             return AnnotationType.DECLARATION; // error recovery
       
   173         }
       
   174         Attribute.Array arr = (Attribute.Array) atValue;
       
   175         boolean isDecl = false, isType = false;
       
   176         for (Attribute app : arr.values) {
       
   177             if (!(app instanceof Attribute.Enum)) {
       
   178                 Assert.error("annotationType(): unrecognized Attribute kind " + app +
       
   179                         " (" + app.getClass() + ")");
       
   180                 isDecl = true;
       
   181                 continue;
       
   182             }
       
   183             Attribute.Enum e = (Attribute.Enum) app;
       
   184             if (e.value.name == names.TYPE) {
       
   185                 if (s.kind == Kinds.TYP)
       
   186                     isDecl = true;
       
   187             } else if (e.value.name == names.FIELD) {
       
   188                 if (s.kind == Kinds.VAR &&
       
   189                         s.owner.kind != Kinds.MTH)
       
   190                     isDecl = true;
       
   191             } else if (e.value.name == names.METHOD) {
       
   192                 if (s.kind == Kinds.MTH &&
       
   193                         !s.isConstructor())
       
   194                     isDecl = true;
       
   195             } else if (e.value.name == names.PARAMETER) {
       
   196                 if (s.kind == Kinds.VAR &&
       
   197                         s.owner.kind == Kinds.MTH &&
       
   198                         (s.flags() & Flags.PARAMETER) != 0)
       
   199                     isDecl = true;
       
   200             } else if (e.value.name == names.CONSTRUCTOR) {
       
   201                 if (s.kind == Kinds.MTH &&
       
   202                         s.isConstructor())
       
   203                     isDecl = true;
       
   204             } else if (e.value.name == names.LOCAL_VARIABLE) {
       
   205                 if (s.kind == Kinds.VAR &&
       
   206                         s.owner.kind == Kinds.MTH &&
       
   207                         (s.flags() & Flags.PARAMETER) == 0)
       
   208                     isDecl = true;
       
   209             } else if (e.value.name == names.ANNOTATION_TYPE) {
       
   210                 if (s.kind == Kinds.TYP &&
       
   211                         (s.flags() & Flags.ANNOTATION) != 0)
       
   212                     isDecl = true;
       
   213             } else if (e.value.name == names.PACKAGE) {
       
   214                 if (s.kind == Kinds.PCK)
       
   215                     isDecl = true;
       
   216             } else if (e.value.name == names.TYPE_USE) {
       
   217                 if (s.kind == Kinds.TYP ||
       
   218                         s.kind == Kinds.VAR ||
       
   219                         (s.kind == Kinds.MTH && !s.isConstructor() &&
       
   220                         !s.type.getReturnType().hasTag(TypeTag.VOID)) ||
       
   221                         (s.kind == Kinds.MTH && s.isConstructor()))
       
   222                     isType = true;
       
   223             } else if (e.value.name == names.TYPE_PARAMETER) {
       
   224                 /* Irrelevant in this case */
       
   225                 // TYPE_PARAMETER doesn't aid in distinguishing between
       
   226                 // Type annotations and declaration annotations on an
       
   227                 // Element
       
   228             } else {
       
   229                 Assert.error("annotationType(): unrecognized Attribute name " + e.value.name +
       
   230                         " (" + e.value.name.getClass() + ")");
       
   231                 isDecl = true;
       
   232             }
       
   233         }
       
   234         if (isDecl && isType) {
       
   235             return AnnotationType.BOTH;
       
   236         } else if (isType) {
       
   237             return AnnotationType.TYPE;
       
   238         } else {
       
   239             return AnnotationType.DECLARATION;
       
   240         }
       
   241     }
       
   242 
       
   243     /** Infer the target annotation kind, if none is give.
       
   244      * We only infer declaration annotations.
       
   245      */
       
   246     private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) {
       
   247         return AnnotationType.DECLARATION;
       
   248     }
       
   249 
       
   250 
       
   251     private class TypeAnnotationPositions extends TreeScanner {
       
   252 
       
   253         private final boolean sigOnly;
       
   254 
       
   255         TypeAnnotationPositions(boolean sigOnly) {
       
   256             this.sigOnly = sigOnly;
       
   257         }
       
   258 
       
   259         /*
       
   260          * When traversing the AST we keep the "frames" of visited
       
   261          * trees in order to determine the position of annotations.
       
   262          */
       
   263         private ListBuffer<JCTree> frames = new ListBuffer<>();
       
   264 
       
   265         protected void push(JCTree t) { frames = frames.prepend(t); }
       
   266         protected JCTree pop() { return frames.next(); }
       
   267         // could this be frames.elems.tail.head?
       
   268         private JCTree peek2() { return frames.toList().tail.head; }
       
   269 
       
   270         @Override
       
   271         public void scan(JCTree tree) {
       
   272             push(tree);
       
   273             super.scan(tree);
       
   274             pop();
       
   275         }
       
   276 
       
   277         /**
       
   278          * Separates type annotations from declaration annotations.
       
   279          * This step is needed because in certain locations (where declaration
       
   280          * and type annotations can be mixed, e.g. the type of a field)
       
   281          * we never build an JCAnnotatedType. This step finds these
       
   282          * annotations and marks them as if they were part of the type.
       
   283          */
       
   284         private void separateAnnotationsKinds(JCTree typetree, Type type, Symbol sym,
       
   285                 TypeAnnotationPosition pos) {
       
   286             List<Attribute.Compound> annotations = sym.getRawAttributes();
       
   287             ListBuffer<Attribute.Compound> declAnnos = new ListBuffer<>();
       
   288             ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<>();
       
   289             ListBuffer<Attribute.TypeCompound> onlyTypeAnnos = new ListBuffer<>();
       
   290 
       
   291             for (Attribute.Compound a : annotations) {
       
   292                 switch (annotationType(a, sym)) {
       
   293                 case DECLARATION:
       
   294                     declAnnos.append(a);
       
   295                     break;
       
   296                 case BOTH: {
       
   297                     declAnnos.append(a);
       
   298                     Attribute.TypeCompound ta = toTypeCompound(a, pos);
       
   299                     typeAnnos.append(ta);
       
   300                     break;
       
   301                 }
       
   302                 case TYPE: {
       
   303                     Attribute.TypeCompound ta = toTypeCompound(a, pos);
       
   304                     typeAnnos.append(ta);
       
   305                     // Also keep track which annotations are only type annotations
       
   306                     onlyTypeAnnos.append(ta);
       
   307                     break;
       
   308                 }
       
   309                 }
       
   310             }
       
   311 
       
   312             sym.resetAnnotations();
       
   313             sym.setDeclarationAttributes(declAnnos.toList());
       
   314 
       
   315             if (typeAnnos.isEmpty()) {
       
   316                 return;
       
   317             }
       
   318 
       
   319             List<Attribute.TypeCompound> typeAnnotations = typeAnnos.toList();
       
   320 
       
   321             if (type == null) {
       
   322                 // When type is null, put the type annotations to the symbol.
       
   323                 // This is used for constructor return annotations, for which
       
   324                 // we use the type of the enclosing class.
       
   325                 type = sym.getEnclosingElement().asType();
       
   326 
       
   327                 // Declaration annotations are always allowed on constructor returns.
       
   328                 // Therefore, use typeAnnotations instead of onlyTypeAnnos.
       
   329                 type = typeWithAnnotations(typetree, type, typeAnnotations, typeAnnotations);
       
   330                 // Note that we don't use the result, the call to
       
   331                 // typeWithAnnotations side-effects the type annotation positions.
       
   332                 // This is important for constructors of nested classes.
       
   333                 sym.appendUniqueTypeAttributes(typeAnnotations);
       
   334                 return;
       
   335             }
       
   336 
       
   337             // type is non-null and annotations are added to that type
       
   338             type = typeWithAnnotations(typetree, type, typeAnnotations, onlyTypeAnnos.toList());
       
   339 
       
   340             if (sym.getKind() == ElementKind.METHOD) {
       
   341                 sym.type.asMethodType().restype = type;
       
   342             } else if (sym.getKind() == ElementKind.PARAMETER) {
       
   343                 sym.type = type;
       
   344                 if (sym.getQualifiedName().equals(names._this)) {
       
   345                     sym.owner.type.asMethodType().recvtype = type;
       
   346                     // note that the typeAnnotations will also be added to the owner below.
       
   347                 } else {
       
   348                     MethodType methType = sym.owner.type.asMethodType();
       
   349                     List<VarSymbol> params = ((MethodSymbol)sym.owner).params;
       
   350                     List<Type> oldArgs = methType.argtypes;
       
   351                     ListBuffer<Type> newArgs = new ListBuffer<>();
       
   352                     while (params.nonEmpty()) {
       
   353                         if (params.head == sym) {
       
   354                             newArgs.add(type);
       
   355                         } else {
       
   356                             newArgs.add(oldArgs.head);
       
   357                         }
       
   358                         oldArgs = oldArgs.tail;
       
   359                         params = params.tail;
       
   360                     }
       
   361                     methType.argtypes = newArgs.toList();
       
   362                 }
       
   363             } else {
       
   364                 sym.type = type;
       
   365             }
       
   366 
       
   367             sym.appendUniqueTypeAttributes(typeAnnotations);
       
   368 
       
   369             if (sym.getKind() == ElementKind.PARAMETER ||
       
   370                 sym.getKind() == ElementKind.LOCAL_VARIABLE ||
       
   371                 sym.getKind() == ElementKind.RESOURCE_VARIABLE ||
       
   372                 sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
       
   373                 // Make sure all type annotations from the symbol are also
       
   374                 // on the owner.
       
   375                 sym.owner.appendUniqueTypeAttributes(sym.getRawTypeAttributes());
       
   376             }
       
   377         }
       
   378 
       
   379         // This method has a similar purpose as
       
   380         // {@link com.sun.tools.javac.parser.JavacParser.insertAnnotationsToMostInner(JCExpression, List<JCTypeAnnotation>, boolean)}
       
   381         // We found a type annotation in a declaration annotation position,
       
   382         // for example, on the return type.
       
   383         // Such an annotation is _not_ part of an JCAnnotatedType tree and we therefore
       
   384         // need to set its position explicitly.
       
   385         // The method returns a copy of type that contains these annotations.
       
   386         //
       
   387         // As a side effect the method sets the type annotation position of "annotations".
       
   388         // Note that it is assumed that all annotations share the same position.
       
   389         private Type typeWithAnnotations(final JCTree typetree, final Type type,
       
   390                 final List<Attribute.TypeCompound> annotations,
       
   391                 final List<Attribute.TypeCompound> onlyTypeAnnotations) {
       
   392             //System.err.printf("typeWithAnnotations(typetree: %s, type: %s, annotations: %s, onlyTypeAnnotations: %s)%n",
       
   393             //         typetree, type, annotations, onlyTypeAnnotations);
       
   394             if (annotations.isEmpty()) {
       
   395                 return type;
       
   396             }
       
   397             if (type.hasTag(TypeTag.ARRAY)) {
       
   398                 Type.ArrayType arType = (Type.ArrayType) type;
       
   399                 Type.ArrayType tomodify = new Type.ArrayType(null, arType.tsym,
       
   400                                                              Type.noAnnotations);
       
   401                 Type toreturn;
       
   402                 if (type.isAnnotated()) {
       
   403                     toreturn = tomodify.annotatedType(type.getAnnotationMirrors());
       
   404                 } else {
       
   405                     toreturn = tomodify;
       
   406                 }
       
   407 
       
   408                 JCArrayTypeTree arTree = arrayTypeTree(typetree);
       
   409 
       
   410                 ListBuffer<TypePathEntry> depth = new ListBuffer<>();
       
   411                 depth = depth.append(TypePathEntry.ARRAY);
       
   412                 while (arType.elemtype.hasTag(TypeTag.ARRAY)) {
       
   413                     if (arType.elemtype.isAnnotated()) {
       
   414                         Type aelemtype = arType.elemtype;
       
   415                         arType = (Type.ArrayType) aelemtype;
       
   416                         ArrayType prevToMod = tomodify;
       
   417                         tomodify = new Type.ArrayType(null, arType.tsym,
       
   418                                                       Type.noAnnotations);
       
   419                         prevToMod.elemtype = tomodify.annotatedType(arType.elemtype.getAnnotationMirrors());
       
   420                     } else {
       
   421                         arType = (Type.ArrayType) arType.elemtype;
       
   422                         tomodify.elemtype = new Type.ArrayType(null, arType.tsym,
       
   423                                                                Type.noAnnotations);
       
   424                         tomodify = (Type.ArrayType) tomodify.elemtype;
       
   425                     }
       
   426                     arTree = arrayTypeTree(arTree.elemtype);
       
   427                     depth = depth.append(TypePathEntry.ARRAY);
       
   428                 }
       
   429                 Type arelemType = typeWithAnnotations(arTree.elemtype, arType.elemtype, annotations, onlyTypeAnnotations);
       
   430                 tomodify.elemtype = arelemType;
       
   431                 {
       
   432                     // All annotations share the same position; modify the first one.
       
   433                     Attribute.TypeCompound a = annotations.get(0);
       
   434                     TypeAnnotationPosition p = a.position;
       
   435                     p.location = p.location.prependList(depth.toList());
       
   436                 }
       
   437                 typetree.type = toreturn;
       
   438                 return toreturn;
       
   439             } else if (type.hasTag(TypeTag.TYPEVAR)) {
       
   440                 // Nothing to do for type variables.
       
   441                 return type;
       
   442             } else if (type.getKind() == TypeKind.UNION) {
       
   443                 // There is a TypeKind, but no TypeTag.
       
   444                 JCTypeUnion tutree = (JCTypeUnion) typetree;
       
   445                 JCExpression fst = tutree.alternatives.get(0);
       
   446                 Type res = typeWithAnnotations(fst, fst.type, annotations, onlyTypeAnnotations);
       
   447                 fst.type = res;
       
   448                 // TODO: do we want to set res as first element in uct.alternatives?
       
   449                 // UnionClassType uct = (com.sun.tools.javac.code.Type.UnionClassType)type;
       
   450                 // Return the un-annotated union-type.
       
   451                 return type;
       
   452             } else {
       
   453                 Type enclTy = type;
       
   454                 Element enclEl = type.asElement();
       
   455                 JCTree enclTr = typetree;
       
   456 
       
   457                 while (enclEl != null &&
       
   458                         enclEl.getKind() != ElementKind.PACKAGE &&
       
   459                         enclTy != null &&
       
   460                         enclTy.getKind() != TypeKind.NONE &&
       
   461                         enclTy.getKind() != TypeKind.ERROR &&
       
   462                         (enclTr.getKind() == JCTree.Kind.MEMBER_SELECT ||
       
   463                          enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE ||
       
   464                          enclTr.getKind() == JCTree.Kind.ANNOTATED_TYPE)) {
       
   465                     // Iterate also over the type tree, not just the type: the type is already
       
   466                     // completely resolved and we cannot distinguish where the annotation
       
   467                     // belongs for a nested type.
       
   468                     if (enclTr.getKind() == JCTree.Kind.MEMBER_SELECT) {
       
   469                         // only change encl in this case.
       
   470                         enclTy = enclTy.getEnclosingType();
       
   471                         enclEl = enclEl.getEnclosingElement();
       
   472                         enclTr = ((JCFieldAccess)enclTr).getExpression();
       
   473                     } else if (enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE) {
       
   474                         enclTr = ((JCTypeApply)enclTr).getType();
       
   475                     } else {
       
   476                         // only other option because of while condition
       
   477                         enclTr = ((JCAnnotatedType)enclTr).getUnderlyingType();
       
   478                     }
       
   479                 }
       
   480 
       
   481                 /** We are trying to annotate some enclosing type,
       
   482                  * but nothing more exists.
       
   483                  */
       
   484                 if (enclTy != null &&
       
   485                         enclTy.hasTag(TypeTag.NONE)) {
       
   486                     switch (onlyTypeAnnotations.size()) {
       
   487                     case 0:
       
   488                         // Don't issue an error if all type annotations are
       
   489                         // also declaration annotations.
       
   490                         // If the annotations are also declaration annotations, they are
       
   491                         // illegal as type annotations but might be legal as declaration annotations.
       
   492                         // The normal declaration annotation checks make sure that the use is valid.
       
   493                         break;
       
   494                     case 1:
       
   495                         log.error(typetree.pos(), "cant.type.annotate.scoping.1",
       
   496                                 onlyTypeAnnotations);
       
   497                         break;
       
   498                     default:
       
   499                         log.error(typetree.pos(), "cant.type.annotate.scoping",
       
   500                                 onlyTypeAnnotations);
       
   501                     }
       
   502                     return type;
       
   503                 }
       
   504 
       
   505                 // At this point we have visited the part of the nested
       
   506                 // type that is written in the source code.
       
   507                 // Now count from here to the actual top-level class to determine
       
   508                 // the correct nesting.
       
   509 
       
   510                 // The genericLocation for the annotation.
       
   511                 ListBuffer<TypePathEntry> depth = new ListBuffer<>();
       
   512 
       
   513                 Type topTy = enclTy;
       
   514                 while (enclEl != null &&
       
   515                         enclEl.getKind() != ElementKind.PACKAGE &&
       
   516                         topTy != null &&
       
   517                         topTy.getKind() != TypeKind.NONE &&
       
   518                         topTy.getKind() != TypeKind.ERROR) {
       
   519                     topTy = topTy.getEnclosingType();
       
   520                     enclEl = enclEl.getEnclosingElement();
       
   521 
       
   522                     if (topTy != null && topTy.getKind() != TypeKind.NONE) {
       
   523                         // Only count enclosing types.
       
   524                         depth = depth.append(TypePathEntry.INNER_TYPE);
       
   525                     }
       
   526                 }
       
   527 
       
   528                 if (depth.nonEmpty()) {
       
   529                     // Only need to change the annotation positions
       
   530                     // if they are on an enclosed type.
       
   531                     // All annotations share the same position; modify the first one.
       
   532                     Attribute.TypeCompound a = annotations.get(0);
       
   533                     TypeAnnotationPosition p = a.position;
       
   534                     p.location = p.location.appendList(depth.toList());
       
   535                 }
       
   536 
       
   537                 Type ret = typeWithAnnotations(type, enclTy, annotations);
       
   538                 typetree.type = ret;
       
   539                 return ret;
       
   540             }
       
   541         }
       
   542 
       
   543         private JCArrayTypeTree arrayTypeTree(JCTree typetree) {
       
   544             if (typetree.getKind() == JCTree.Kind.ARRAY_TYPE) {
       
   545                 return (JCArrayTypeTree) typetree;
       
   546             } else if (typetree.getKind() == JCTree.Kind.ANNOTATED_TYPE) {
       
   547                 return (JCArrayTypeTree) ((JCAnnotatedType)typetree).underlyingType;
       
   548             } else {
       
   549                 Assert.error("Could not determine array type from type tree: " + typetree);
       
   550                 return null;
       
   551             }
       
   552         }
       
   553 
       
   554         /** Return a copy of the first type that only differs by
       
   555          * inserting the annotations to the left-most/inner-most type
       
   556          * or the type given by stopAt.
       
   557          *
       
   558          * We need the stopAt parameter to know where on a type to
       
   559          * put the annotations.
       
   560          * If we have nested classes Outer > Middle > Inner, and we
       
   561          * have the source type "@A Middle.Inner", we will invoke
       
   562          * this method with type = Outer.Middle.Inner,
       
   563          * stopAt = Middle.Inner, and annotations = @A.
       
   564          *
       
   565          * @param type The type to copy.
       
   566          * @param stopAt The type to stop at.
       
   567          * @param annotations The annotations to insert.
       
   568          * @return A copy of type that contains the annotations.
       
   569          */
       
   570         private Type typeWithAnnotations(final Type type,
       
   571                 final Type stopAt,
       
   572                 final List<Attribute.TypeCompound> annotations) {
       
   573             //System.err.println("typeWithAnnotations " + type + " " + annotations + " stopAt " + stopAt);
       
   574             Visitor<Type, List<TypeCompound>> visitor =
       
   575                     new Type.Visitor<Type, List<Attribute.TypeCompound>>() {
       
   576                 @Override
       
   577                 public Type visitClassType(ClassType t, List<TypeCompound> s) {
       
   578                     // assert that t.constValue() == null?
       
   579                     if (t == stopAt ||
       
   580                         t.getEnclosingType() == Type.noType) {
       
   581                         return t.annotatedType(s);
       
   582                     } else {
       
   583                         ClassType ret = new ClassType(t.getEnclosingType().accept(this, s),
       
   584                                                       t.typarams_field, t.tsym,
       
   585                                                       t.getAnnotationMirrors());
       
   586                         ret.all_interfaces_field = t.all_interfaces_field;
       
   587                         ret.allparams_field = t.allparams_field;
       
   588                         ret.interfaces_field = t.interfaces_field;
       
   589                         ret.rank_field = t.rank_field;
       
   590                         ret.supertype_field = t.supertype_field;
       
   591                         return ret;
       
   592                     }
       
   593                 }
       
   594 
       
   595                 @Override
       
   596                 public Type visitWildcardType(WildcardType t, List<TypeCompound> s) {
       
   597                     return t.annotatedType(s);
       
   598                 }
       
   599 
       
   600                 @Override
       
   601                 public Type visitArrayType(ArrayType t, List<TypeCompound> s) {
       
   602                     ArrayType ret = new ArrayType(t.elemtype.accept(this, s), t.tsym,
       
   603                                                   t.getAnnotationMirrors());
       
   604                     return ret;
       
   605                 }
       
   606 
       
   607                 @Override
       
   608                 public Type visitMethodType(MethodType t, List<TypeCompound> s) {
       
   609                     // Impossible?
       
   610                     return t;
       
   611                 }
       
   612 
       
   613                 @Override
       
   614                 public Type visitPackageType(PackageType t, List<TypeCompound> s) {
       
   615                     // Impossible?
       
   616                     return t;
       
   617                 }
       
   618 
       
   619                 @Override
       
   620                 public Type visitTypeVar(TypeVar t, List<TypeCompound> s) {
       
   621                     return t.annotatedType(s);
       
   622                 }
       
   623 
       
   624                 @Override
       
   625                 public Type visitCapturedType(CapturedType t, List<TypeCompound> s) {
       
   626                     return t.annotatedType(s);
       
   627                 }
       
   628 
       
   629                 @Override
       
   630                 public Type visitForAll(ForAll t, List<TypeCompound> s) {
       
   631                     // Impossible?
       
   632                     return t;
       
   633                 }
       
   634 
       
   635                 @Override
       
   636                 public Type visitUndetVar(UndetVar t, List<TypeCompound> s) {
       
   637                     // Impossible?
       
   638                     return t;
       
   639                 }
       
   640 
       
   641                 @Override
       
   642                 public Type visitErrorType(ErrorType t, List<TypeCompound> s) {
       
   643                     return t.annotatedType(s);
       
   644                 }
       
   645 
       
   646                 @Override
       
   647                 public Type visitType(Type t, List<TypeCompound> s) {
       
   648                     return t.annotatedType(s);
       
   649                 }
       
   650             };
       
   651 
       
   652             return type.accept(visitor, annotations);
       
   653         }
       
   654 
       
   655         private Attribute.TypeCompound toTypeCompound(Attribute.Compound a, TypeAnnotationPosition p) {
       
   656             // It is safe to alias the position.
       
   657             return new Attribute.TypeCompound(a, p);
       
   658         }
       
   659 
       
   660 
       
   661         /* This is the beginning of the second part of organizing
       
   662          * type annotations: determine the type annotation positions.
       
   663          */
       
   664 
       
   665         // This method is considered deprecated, and will be removed
       
   666         // in the near future.  Don't use it for anything new.
       
   667         private TypeAnnotationPosition
       
   668             resolveFrame(JCTree tree,
       
   669                          JCTree frame,
       
   670                          List<JCTree> path,
       
   671                          JCLambda currentLambda,
       
   672                          int outer_type_index,
       
   673                          ListBuffer<TypePathEntry> location) {
       
   674             /*
       
   675             System.out.println("Resolving tree: " + tree + " kind: " + tree.getKind());
       
   676             System.out.println("    Framing tree: " + frame + " kind: " + frame.getKind());
       
   677             */
       
   678 
       
   679             // Note that p.offset is set in
       
   680             // com.sun.tools.javac.jvm.Gen.setTypeAnnotationPositions(int)
       
   681 
       
   682             switch (frame.getKind()) {
       
   683                 case TYPE_CAST:
       
   684                     return TypeAnnotationPosition.typeCast(location.toList(),
       
   685                                                            currentLambda,
       
   686                                                            outer_type_index,
       
   687                                                            frame.pos);
       
   688 
       
   689                 case INSTANCE_OF:
       
   690                     return TypeAnnotationPosition.instanceOf(location.toList(),
       
   691                                                              currentLambda,
       
   692                                                              frame.pos);
       
   693 
       
   694                 case NEW_CLASS:
       
   695                     final JCNewClass frameNewClass = (JCNewClass) frame;
       
   696                     if (frameNewClass.def != null) {
       
   697                         // Special handling for anonymous class instantiations
       
   698                         final JCClassDecl frameClassDecl = frameNewClass.def;
       
   699                         if (frameClassDecl.extending == tree) {
       
   700                             return TypeAnnotationPosition
       
   701                                 .classExtends(location.toList(), currentLambda,
       
   702                                               frame.pos);
       
   703                         } else if (frameClassDecl.implementing.contains(tree)) {
       
   704                             final int type_index =
       
   705                                 frameClassDecl.implementing.indexOf(tree);
       
   706                             return TypeAnnotationPosition
       
   707                                 .classExtends(location.toList(), currentLambda,
       
   708                                               type_index, frame.pos);
       
   709                         } else {
       
   710                             // In contrast to CLASS below, typarams cannot occur here.
       
   711                             throw new AssertionError("Could not determine position of tree " + tree +
       
   712                                                      " within frame " + frame);
       
   713                         }
       
   714                     } else if (frameNewClass.typeargs.contains(tree)) {
       
   715                         final int type_index =
       
   716                             frameNewClass.typeargs.indexOf(tree);
       
   717                         return TypeAnnotationPosition
       
   718                             .constructorInvocationTypeArg(location.toList(),
       
   719                                                           currentLambda,
       
   720                                                           type_index,
       
   721                                                           frame.pos);
       
   722                     } else {
       
   723                         return TypeAnnotationPosition
       
   724                             .newObj(location.toList(), currentLambda,
       
   725                                     frame.pos);
       
   726                     }
       
   727 
       
   728                 case NEW_ARRAY:
       
   729                     return TypeAnnotationPosition
       
   730                         .newObj(location.toList(), currentLambda, frame.pos);
       
   731 
       
   732                 case ANNOTATION_TYPE:
       
   733                 case CLASS:
       
   734                 case ENUM:
       
   735                 case INTERFACE:
       
   736                     if (((JCClassDecl)frame).extending == tree) {
       
   737                         return TypeAnnotationPosition
       
   738                             .classExtends(location.toList(), currentLambda,
       
   739                                           frame.pos);
       
   740                     } else if (((JCClassDecl)frame).implementing.contains(tree)) {
       
   741                         final int type_index =
       
   742                             ((JCClassDecl)frame).implementing.indexOf(tree);
       
   743                         return TypeAnnotationPosition
       
   744                             .classExtends(location.toList(), currentLambda,
       
   745                                           type_index, frame.pos);
       
   746                     } else if (((JCClassDecl)frame).typarams.contains(tree)) {
       
   747                         final int parameter_index =
       
   748                             ((JCClassDecl)frame).typarams.indexOf(tree);
       
   749                         return TypeAnnotationPosition
       
   750                             .typeParameter(location.toList(), currentLambda,
       
   751                                            parameter_index, frame.pos);
       
   752                     } else {
       
   753                         throw new AssertionError("Could not determine position of tree " +
       
   754                                                  tree + " within frame " + frame);
       
   755                     }
       
   756 
       
   757                 case METHOD: {
       
   758                     final JCMethodDecl frameMethod = (JCMethodDecl) frame;
       
   759                     if (frameMethod.thrown.contains(tree)) {
       
   760                         final int type_index = frameMethod.thrown.indexOf(tree);
       
   761                         return TypeAnnotationPosition
       
   762                             .methodThrows(location.toList(), currentLambda,
       
   763                                           type_index, frame.pos);
       
   764                     } else if (frameMethod.restype == tree) {
       
   765                         return TypeAnnotationPosition
       
   766                             .methodReturn(location.toList(), currentLambda,
       
   767                                           frame.pos);
       
   768                     } else if (frameMethod.typarams.contains(tree)) {
       
   769                         final int parameter_index =
       
   770                             frameMethod.typarams.indexOf(tree);
       
   771                         return TypeAnnotationPosition
       
   772                             .methodTypeParameter(location.toList(),
       
   773                                                  currentLambda,
       
   774                                                  parameter_index, frame.pos);
       
   775                     } else {
       
   776                         throw new AssertionError("Could not determine position of tree " + tree +
       
   777                                                  " within frame " + frame);
       
   778                     }
       
   779                 }
       
   780 
       
   781                 case PARAMETERIZED_TYPE: {
       
   782                     List<JCTree> newPath = path.tail;
       
   783 
       
   784                     if (((JCTypeApply)frame).clazz == tree) {
       
   785                         // generic: RAW; noop
       
   786                     } else if (((JCTypeApply)frame).arguments.contains(tree)) {
       
   787                         JCTypeApply taframe = (JCTypeApply) frame;
       
   788                         int arg = taframe.arguments.indexOf(tree);
       
   789                         location = location.prepend(
       
   790                             new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT,
       
   791                                               arg));
       
   792 
       
   793                         Type typeToUse;
       
   794                         if (newPath.tail != null &&
       
   795                             newPath.tail.head.hasTag(Tag.NEWCLASS)) {
       
   796                             // If we are within an anonymous class
       
   797                             // instantiation, use its type, because it
       
   798                             // contains a correctly nested type.
       
   799                             typeToUse = newPath.tail.head.type;
       
   800                         } else {
       
   801                             typeToUse = taframe.type;
       
   802                         }
       
   803 
       
   804                         location = locateNestedTypes(typeToUse, location);
       
   805                     } else {
       
   806                         throw new AssertionError("Could not determine type argument position of tree " + tree +
       
   807                                                  " within frame " + frame);
       
   808                     }
       
   809 
       
   810                     return resolveFrame(newPath.head, newPath.tail.head,
       
   811                                         newPath, currentLambda,
       
   812                                         outer_type_index, location);
       
   813                 }
       
   814 
       
   815                 case MEMBER_REFERENCE: {
       
   816                     JCMemberReference mrframe = (JCMemberReference) frame;
       
   817 
       
   818                     if (mrframe.expr == tree) {
       
   819                         switch (mrframe.mode) {
       
   820                         case INVOKE:
       
   821                             return TypeAnnotationPosition
       
   822                                 .methodRef(location.toList(), currentLambda,
       
   823                                            frame.pos);
       
   824                         case NEW:
       
   825                             return TypeAnnotationPosition
       
   826                                 .constructorRef(location.toList(),
       
   827                                                 currentLambda,
       
   828                                                 frame.pos);
       
   829                         default:
       
   830                             throw new AssertionError("Unknown method reference mode " + mrframe.mode +
       
   831                                                      " for tree " + tree + " within frame " + frame);
       
   832                         }
       
   833                     } else if (mrframe.typeargs != null &&
       
   834                             mrframe.typeargs.contains(tree)) {
       
   835                         final int type_index = mrframe.typeargs.indexOf(tree);
       
   836                         switch (mrframe.mode) {
       
   837                         case INVOKE:
       
   838                             return TypeAnnotationPosition
       
   839                                 .methodRefTypeArg(location.toList(),
       
   840                                                   currentLambda,
       
   841                                                   type_index, frame.pos);
       
   842                         case NEW:
       
   843                             return TypeAnnotationPosition
       
   844                                 .constructorRefTypeArg(location.toList(),
       
   845                                                        currentLambda,
       
   846                                                        type_index, frame.pos);
       
   847                         default:
       
   848                             throw new AssertionError("Unknown method reference mode " + mrframe.mode +
       
   849                                                    " for tree " + tree + " within frame " + frame);
       
   850                         }
       
   851                     } else {
       
   852                         throw new AssertionError("Could not determine type argument position of tree " + tree +
       
   853                                                " within frame " + frame);
       
   854                     }
       
   855                 }
       
   856 
       
   857                 case ARRAY_TYPE: {
       
   858                     location = location.prepend(TypePathEntry.ARRAY);
       
   859                     List<JCTree> newPath = path.tail;
       
   860                     while (true) {
       
   861                         JCTree npHead = newPath.tail.head;
       
   862                         if (npHead.hasTag(JCTree.Tag.TYPEARRAY)) {
       
   863                             newPath = newPath.tail;
       
   864                             location = location.prepend(TypePathEntry.ARRAY);
       
   865                         } else if (npHead.hasTag(JCTree.Tag.ANNOTATED_TYPE)) {
       
   866                             newPath = newPath.tail;
       
   867                         } else {
       
   868                             break;
       
   869                         }
       
   870                     }
       
   871                     return resolveFrame(newPath.head, newPath.tail.head,
       
   872                                         newPath, currentLambda,
       
   873                                         outer_type_index, location);
       
   874                 }
       
   875 
       
   876                 case TYPE_PARAMETER:
       
   877                     if (path.tail.tail.head.hasTag(JCTree.Tag.CLASSDEF)) {
       
   878                         final JCClassDecl clazz =
       
   879                             (JCClassDecl)path.tail.tail.head;
       
   880                         final int parameter_index =
       
   881                             clazz.typarams.indexOf(path.tail.head);
       
   882                         final int bound_index =
       
   883                             ((JCTypeParameter)frame).bounds.get(0)
       
   884                             .type.isInterface() ?
       
   885                             ((JCTypeParameter)frame).bounds.indexOf(tree) + 1:
       
   886                             ((JCTypeParameter)frame).bounds.indexOf(tree);
       
   887                         return TypeAnnotationPosition
       
   888                             .typeParameterBound(location.toList(),
       
   889                                                 currentLambda,
       
   890                                                 parameter_index, bound_index,
       
   891                                                 frame.pos);
       
   892                     } else if (path.tail.tail.head.hasTag(JCTree.Tag.METHODDEF)) {
       
   893                         final JCMethodDecl method =
       
   894                             (JCMethodDecl)path.tail.tail.head;
       
   895                         final int parameter_index =
       
   896                             method.typarams.indexOf(path.tail.head);
       
   897                         final int bound_index =
       
   898                             ((JCTypeParameter)frame).bounds.get(0)
       
   899                             .type.isInterface() ?
       
   900                             ((JCTypeParameter)frame).bounds.indexOf(tree) + 1:
       
   901                             ((JCTypeParameter)frame).bounds.indexOf(tree);
       
   902                         return TypeAnnotationPosition
       
   903                             .methodTypeParameterBound(location.toList(),
       
   904                                                       currentLambda,
       
   905                                                       parameter_index,
       
   906                                                       bound_index,
       
   907                                                       frame.pos);
       
   908                     } else {
       
   909                         throw new AssertionError("Could not determine position of tree " + tree +
       
   910                                                  " within frame " + frame);
       
   911                     }
       
   912 
       
   913                 case VARIABLE:
       
   914                     VarSymbol v = ((JCVariableDecl)frame).sym;
       
   915                     if (v.getKind() != ElementKind.FIELD) {
       
   916                         v.owner.appendUniqueTypeAttributes(v.getRawTypeAttributes());
       
   917                     }
       
   918                     switch (v.getKind()) {
       
   919                         case LOCAL_VARIABLE:
       
   920                             return TypeAnnotationPosition
       
   921                                 .localVariable(location.toList(), currentLambda,
       
   922                                                frame.pos);
       
   923                         case FIELD:
       
   924                             return TypeAnnotationPosition.field(location.toList(),
       
   925                                                                 currentLambda,
       
   926                                                                 frame.pos);
       
   927                         case PARAMETER:
       
   928                             if (v.getQualifiedName().equals(names._this)) {
       
   929                                 return TypeAnnotationPosition
       
   930                                     .methodReceiver(location.toList(),
       
   931                                                     currentLambda,
       
   932                                                     frame.pos);
       
   933                             } else {
       
   934                                 final int parameter_index =
       
   935                                     methodParamIndex(path, frame);
       
   936                                 return TypeAnnotationPosition
       
   937                                     .methodParameter(location.toList(),
       
   938                                                      currentLambda,
       
   939                                                      parameter_index,
       
   940                                                      frame.pos);
       
   941                             }
       
   942                         case EXCEPTION_PARAMETER:
       
   943                             return TypeAnnotationPosition
       
   944                                 .exceptionParameter(location.toList(),
       
   945                                                     currentLambda,
       
   946                                                     frame.pos);
       
   947                         case RESOURCE_VARIABLE:
       
   948                             return TypeAnnotationPosition
       
   949                                 .resourceVariable(location.toList(),
       
   950                                                   currentLambda,
       
   951                                                   frame.pos);
       
   952                         default:
       
   953                             throw new AssertionError("Found unexpected type annotation for variable: " + v + " with kind: " + v.getKind());
       
   954                     }
       
   955 
       
   956                 case ANNOTATED_TYPE: {
       
   957                     if (frame == tree) {
       
   958                         // This is only true for the first annotated type we see.
       
   959                         // For any other annotated types along the path, we do
       
   960                         // not care about inner types.
       
   961                         JCAnnotatedType atypetree = (JCAnnotatedType) frame;
       
   962                         final Type utype = atypetree.underlyingType.type;
       
   963                         Assert.checkNonNull(utype);
       
   964                         Symbol tsym = utype.tsym;
       
   965                         if (tsym.getKind().equals(ElementKind.TYPE_PARAMETER) ||
       
   966                                 utype.getKind().equals(TypeKind.WILDCARD) ||
       
   967                                 utype.getKind().equals(TypeKind.ARRAY)) {
       
   968                             // Type parameters, wildcards, and arrays have the declaring
       
   969                             // class/method as enclosing elements.
       
   970                             // There is actually nothing to do for them.
       
   971                         } else {
       
   972                             location = locateNestedTypes(utype, location);
       
   973                         }
       
   974                     }
       
   975                     List<JCTree> newPath = path.tail;
       
   976                     return resolveFrame(newPath.head, newPath.tail.head,
       
   977                                         newPath, currentLambda,
       
   978                                         outer_type_index, location);
       
   979                 }
       
   980 
       
   981                 case UNION_TYPE: {
       
   982                     List<JCTree> newPath = path.tail;
       
   983                     return resolveFrame(newPath.head, newPath.tail.head,
       
   984                                         newPath, currentLambda,
       
   985                                         outer_type_index, location);
       
   986                 }
       
   987 
       
   988                 case INTERSECTION_TYPE: {
       
   989                     JCTypeIntersection isect = (JCTypeIntersection)frame;
       
   990                     final List<JCTree> newPath = path.tail;
       
   991                     return resolveFrame(newPath.head, newPath.tail.head,
       
   992                                         newPath, currentLambda,
       
   993                                         isect.bounds.indexOf(tree), location);
       
   994                 }
       
   995 
       
   996                 case METHOD_INVOCATION: {
       
   997                     JCMethodInvocation invocation = (JCMethodInvocation)frame;
       
   998                     if (!invocation.typeargs.contains(tree)) {
       
   999                         throw new AssertionError("{" + tree + "} is not an argument in the invocation: " + invocation);
       
  1000                     }
       
  1001                     MethodSymbol exsym = (MethodSymbol) TreeInfo.symbol(invocation.getMethodSelect());
       
  1002                     final int type_index = invocation.typeargs.indexOf(tree);
       
  1003                     if (exsym == null) {
       
  1004                         throw new AssertionError("could not determine symbol for {" + invocation + "}");
       
  1005                     } else if (exsym.isConstructor()) {
       
  1006                         return TypeAnnotationPosition
       
  1007                             .constructorInvocationTypeArg(location.toList(),
       
  1008                                                           currentLambda,
       
  1009                                                           type_index,
       
  1010                                                           invocation.pos);
       
  1011                     } else {
       
  1012                         return TypeAnnotationPosition
       
  1013                             .methodInvocationTypeArg(location.toList(),
       
  1014                                                      currentLambda,
       
  1015                                                      type_index,
       
  1016                                                      invocation.pos);
       
  1017                     }
       
  1018                 }
       
  1019 
       
  1020                 case EXTENDS_WILDCARD:
       
  1021                 case SUPER_WILDCARD: {
       
  1022                     // Annotations in wildcard bounds
       
  1023                     final List<JCTree> newPath = path.tail;
       
  1024                     return resolveFrame(newPath.head, newPath.tail.head,
       
  1025                                         newPath, currentLambda,
       
  1026                                         outer_type_index,
       
  1027                                         location.prepend(TypePathEntry.WILDCARD));
       
  1028                 }
       
  1029 
       
  1030                 case MEMBER_SELECT: {
       
  1031                     final List<JCTree> newPath = path.tail;
       
  1032                     return resolveFrame(newPath.head, newPath.tail.head,
       
  1033                                         newPath, currentLambda,
       
  1034                                         outer_type_index, location);
       
  1035                 }
       
  1036 
       
  1037                 default:
       
  1038                     throw new AssertionError("Unresolved frame: " + frame +
       
  1039                                              " of kind: " + frame.getKind() +
       
  1040                                              "\n    Looking for tree: " + tree);
       
  1041             }
       
  1042         }
       
  1043 
       
  1044         private ListBuffer<TypePathEntry>
       
  1045             locateNestedTypes(Type type,
       
  1046                               ListBuffer<TypePathEntry> depth) {
       
  1047             Type encl = type.getEnclosingType();
       
  1048             while (encl != null &&
       
  1049                     encl.getKind() != TypeKind.NONE &&
       
  1050                     encl.getKind() != TypeKind.ERROR) {
       
  1051                 depth = depth.prepend(TypePathEntry.INNER_TYPE);
       
  1052                 encl = encl.getEnclosingType();
       
  1053             }
       
  1054             return depth;
       
  1055         }
       
  1056 
       
  1057         private int methodParamIndex(List<JCTree> path, JCTree param) {
       
  1058             List<JCTree> curr = path;
       
  1059             while (curr.head.getTag() != Tag.METHODDEF &&
       
  1060                     curr.head.getTag() != Tag.LAMBDA) {
       
  1061                 curr = curr.tail;
       
  1062             }
       
  1063             if (curr.head.getTag() == Tag.METHODDEF) {
       
  1064                 JCMethodDecl method = (JCMethodDecl)curr.head;
       
  1065                 return method.params.indexOf(param);
       
  1066             } else if (curr.head.getTag() == Tag.LAMBDA) {
       
  1067                 JCLambda lambda = (JCLambda)curr.head;
       
  1068                 return lambda.params.indexOf(param);
       
  1069             } else {
       
  1070                 Assert.error("methodParamIndex expected to find method or lambda for param: " + param);
       
  1071                 return -1;
       
  1072             }
       
  1073         }
       
  1074 
       
  1075         // Each class (including enclosed inner classes) is visited separately.
       
  1076         // This flag is used to prevent from visiting inner classes.
       
  1077         private boolean isInClass = false;
       
  1078 
       
  1079         @Override
       
  1080         public void visitClassDef(JCClassDecl tree) {
       
  1081             if (isInClass)
       
  1082                 return;
       
  1083             isInClass = true;
       
  1084 
       
  1085             if (sigOnly) {
       
  1086                 scan(tree.mods);
       
  1087                 scan(tree.typarams);
       
  1088                 scan(tree.extending);
       
  1089                 scan(tree.implementing);
       
  1090             }
       
  1091             scan(tree.defs);
       
  1092         }
       
  1093 
       
  1094         /**
       
  1095          * Resolve declaration vs. type annotations in methods and
       
  1096          * then determine the positions.
       
  1097          */
       
  1098         @Override
       
  1099         public void visitMethodDef(final JCMethodDecl tree) {
       
  1100             if (tree.sym == null) {
       
  1101                 Assert.error("Visiting tree node before memberEnter");
       
  1102             }
       
  1103             if (sigOnly) {
       
  1104                 if (!tree.mods.annotations.isEmpty()) {
       
  1105                     if (tree.sym.isConstructor()) {
       
  1106                         final TypeAnnotationPosition pos =
       
  1107                             TypeAnnotationPosition.methodReturn(tree.pos);
       
  1108                         // Use null to mark that the annotations go
       
  1109                         // with the symbol.
       
  1110                         separateAnnotationsKinds(tree, null, tree.sym, pos);
       
  1111                     } else {
       
  1112                         final TypeAnnotationPosition pos =
       
  1113                             TypeAnnotationPosition.methodReturn(tree.restype.pos);
       
  1114                         separateAnnotationsKinds(tree.restype,
       
  1115                                                  tree.sym.type.getReturnType(),
       
  1116                                                  tree.sym, pos);
       
  1117                     }
       
  1118                 }
       
  1119                 if (tree.recvparam != null && tree.recvparam.sym != null &&
       
  1120                         !tree.recvparam.mods.annotations.isEmpty()) {
       
  1121                     // Nothing to do for separateAnnotationsKinds if
       
  1122                     // there are no annotations of either kind.
       
  1123                     // TODO: make sure there are no declaration annotations.
       
  1124                     final TypeAnnotationPosition pos =
       
  1125                         TypeAnnotationPosition.methodReceiver(tree.recvparam.vartype.pos);
       
  1126                     separateAnnotationsKinds(tree.recvparam.vartype,
       
  1127                                              tree.recvparam.sym.type,
       
  1128                                              tree.recvparam.sym, pos);
       
  1129                 }
       
  1130                 int i = 0;
       
  1131                 for (JCVariableDecl param : tree.params) {
       
  1132                     if (!param.mods.annotations.isEmpty()) {
       
  1133                         // Nothing to do for separateAnnotationsKinds if
       
  1134                         // there are no annotations of either kind.
       
  1135                         final TypeAnnotationPosition pos =
       
  1136                             TypeAnnotationPosition.methodParameter(i, param.vartype.pos);
       
  1137                         separateAnnotationsKinds(param.vartype,
       
  1138                                                  param.sym.type,
       
  1139                                                  param.sym, pos);
       
  1140                     }
       
  1141                     ++i;
       
  1142                 }
       
  1143             }
       
  1144 
       
  1145             push(tree);
       
  1146             // super.visitMethodDef(tree);
       
  1147             if (sigOnly) {
       
  1148                 scan(tree.mods);
       
  1149                 scan(tree.restype);
       
  1150                 scan(tree.typarams);
       
  1151                 scan(tree.recvparam);
       
  1152                 scan(tree.params);
       
  1153                 scan(tree.thrown);
       
  1154             } else {
       
  1155                 scan(tree.defaultValue);
       
  1156                 scan(tree.body);
       
  1157             }
       
  1158             pop();
       
  1159         }
       
  1160 
       
  1161         /* Store a reference to the current lambda expression, to
       
  1162          * be used by all type annotations within this expression.
       
  1163          */
       
  1164         private JCLambda currentLambda = null;
       
  1165 
       
  1166         public void visitLambda(JCLambda tree) {
       
  1167             JCLambda prevLambda = currentLambda;
       
  1168             try {
       
  1169                 currentLambda = tree;
       
  1170 
       
  1171                 int i = 0;
       
  1172                 for (JCVariableDecl param : tree.params) {
       
  1173                     if (!param.mods.annotations.isEmpty()) {
       
  1174                         // Nothing to do for separateAnnotationsKinds if
       
  1175                         // there are no annotations of either kind.
       
  1176                         final TypeAnnotationPosition pos =
       
  1177                             TypeAnnotationPosition.methodParameter(tree, i,
       
  1178                                                                    param.vartype.pos);
       
  1179                         separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
       
  1180                     }
       
  1181                     ++i;
       
  1182                 }
       
  1183 
       
  1184                 push(tree);
       
  1185                 scan(tree.body);
       
  1186                 scan(tree.params);
       
  1187                 pop();
       
  1188             } finally {
       
  1189                 currentLambda = prevLambda;
       
  1190             }
       
  1191         }
       
  1192 
       
  1193         /**
       
  1194          * Resolve declaration vs. type annotations in variable declarations and
       
  1195          * then determine the positions.
       
  1196          */
       
  1197         @Override
       
  1198         public void visitVarDef(final JCVariableDecl tree) {
       
  1199             if (tree.mods.annotations.isEmpty()) {
       
  1200                 // Nothing to do for separateAnnotationsKinds if
       
  1201                 // there are no annotations of either kind.
       
  1202             } else if (tree.sym == null) {
       
  1203                 Assert.error("Visiting tree node before memberEnter");
       
  1204             } else if (tree.sym.getKind() == ElementKind.PARAMETER) {
       
  1205                 // Parameters are handled in visitMethodDef or visitLambda.
       
  1206             } else if (tree.sym.getKind() == ElementKind.FIELD) {
       
  1207                 if (sigOnly) {
       
  1208                     TypeAnnotationPosition pos =
       
  1209                         TypeAnnotationPosition.field(tree.pos);
       
  1210                     separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
       
  1211                 }
       
  1212             } else if (tree.sym.getKind() == ElementKind.LOCAL_VARIABLE) {
       
  1213                 final TypeAnnotationPosition pos =
       
  1214                     TypeAnnotationPosition.localVariable(currentLambda,
       
  1215                                                          tree.pos);
       
  1216                 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
       
  1217             } else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
       
  1218                 final TypeAnnotationPosition pos =
       
  1219                     TypeAnnotationPosition.exceptionParameter(currentLambda,
       
  1220                                                               tree.pos);
       
  1221                 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
       
  1222             } else if (tree.sym.getKind() == ElementKind.RESOURCE_VARIABLE) {
       
  1223                 final TypeAnnotationPosition pos =
       
  1224                     TypeAnnotationPosition.resourceVariable(currentLambda,
       
  1225                                                             tree.pos);
       
  1226                 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
       
  1227             } else if (tree.sym.getKind() == ElementKind.ENUM_CONSTANT) {
       
  1228                 // No type annotations can occur here.
       
  1229             } else {
       
  1230                 // There is nothing else in a variable declaration that needs separation.
       
  1231                 Assert.error("Unhandled variable kind: " + tree + " of kind: " + tree.sym.getKind());
       
  1232             }
       
  1233 
       
  1234             push(tree);
       
  1235             // super.visitVarDef(tree);
       
  1236             scan(tree.mods);
       
  1237             scan(tree.vartype);
       
  1238             if (!sigOnly) {
       
  1239                 scan(tree.init);
       
  1240             }
       
  1241             pop();
       
  1242         }
       
  1243 
       
  1244         @Override
       
  1245         public void visitBlock(JCBlock tree) {
       
  1246             // Do not descend into top-level blocks when only interested
       
  1247             // in the signature.
       
  1248             if (!sigOnly) {
       
  1249                 scan(tree.stats);
       
  1250             }
       
  1251         }
       
  1252 
       
  1253         @Override
       
  1254         public void visitAnnotatedType(JCAnnotatedType tree) {
       
  1255             push(tree);
       
  1256             findPosition(tree, tree, tree.annotations);
       
  1257             pop();
       
  1258             super.visitAnnotatedType(tree);
       
  1259         }
       
  1260 
       
  1261         @Override
       
  1262         public void visitTypeParameter(JCTypeParameter tree) {
       
  1263             findPosition(tree, peek2(), tree.annotations);
       
  1264             super.visitTypeParameter(tree);
       
  1265         }
       
  1266 
       
  1267         private void copyNewClassAnnotationsToOwner(JCNewClass tree) {
       
  1268             Symbol sym = tree.def.sym;
       
  1269             final TypeAnnotationPosition pos =
       
  1270                 TypeAnnotationPosition.newObj(tree.pos);
       
  1271             ListBuffer<Attribute.TypeCompound> newattrs = new ListBuffer<>();
       
  1272 
       
  1273             for (Attribute.TypeCompound old : sym.getRawTypeAttributes()) {
       
  1274                 newattrs.append(new Attribute.TypeCompound(old.type, old.values,
       
  1275                                                            pos));
       
  1276             }
       
  1277 
       
  1278             sym.owner.appendUniqueTypeAttributes(newattrs.toList());
       
  1279         }
       
  1280 
       
  1281         @Override
       
  1282         public void visitNewClass(JCNewClass tree) {
       
  1283             if (tree.def != null &&
       
  1284                     !tree.def.mods.annotations.isEmpty()) {
       
  1285                 JCClassDecl classdecl = tree.def;
       
  1286                 TypeAnnotationPosition pos;
       
  1287 
       
  1288                 if (classdecl.extending == tree.clazz) {
       
  1289                     pos = TypeAnnotationPosition.classExtends(tree.pos);
       
  1290                 } else if (classdecl.implementing.contains(tree.clazz)) {
       
  1291                     final int index = classdecl.implementing.indexOf(tree.clazz);
       
  1292                     pos = TypeAnnotationPosition.classExtends(index, tree.pos);
       
  1293                 } else {
       
  1294                     // In contrast to CLASS elsewhere, typarams cannot occur here.
       
  1295                     throw new AssertionError("Could not determine position of tree " + tree);
       
  1296                 }
       
  1297                 Type before = classdecl.sym.type;
       
  1298                 separateAnnotationsKinds(classdecl, tree.clazz.type, classdecl.sym, pos);
       
  1299                 copyNewClassAnnotationsToOwner(tree);
       
  1300                 // classdecl.sym.type now contains an annotated type, which
       
  1301                 // is not what we want there.
       
  1302                 // TODO: should we put this type somewhere in the superclass/interface?
       
  1303                 classdecl.sym.type = before;
       
  1304             }
       
  1305 
       
  1306             scan(tree.encl);
       
  1307             scan(tree.typeargs);
       
  1308             scan(tree.clazz);
       
  1309             scan(tree.args);
       
  1310 
       
  1311             // The class body will already be scanned.
       
  1312             // scan(tree.def);
       
  1313         }
       
  1314 
       
  1315         @Override
       
  1316         public void visitNewArray(JCNewArray tree) {
       
  1317             findPosition(tree, tree, tree.annotations);
       
  1318             int dimAnnosCount = tree.dimAnnotations.size();
       
  1319             ListBuffer<TypePathEntry> depth = new ListBuffer<>();
       
  1320 
       
  1321             // handle annotations associated with dimensions
       
  1322             for (int i = 0; i < dimAnnosCount; ++i) {
       
  1323                 ListBuffer<TypePathEntry> location =
       
  1324                     new ListBuffer<TypePathEntry>();
       
  1325                 if (i != 0) {
       
  1326                     depth = depth.append(TypePathEntry.ARRAY);
       
  1327                     location = location.appendList(depth.toList());
       
  1328                 }
       
  1329                 final TypeAnnotationPosition p =
       
  1330                     TypeAnnotationPosition.newObj(location.toList(),
       
  1331                                                   currentLambda,
       
  1332                                                   tree.pos);
       
  1333 
       
  1334                 setTypeAnnotationPos(tree.dimAnnotations.get(i), p);
       
  1335             }
       
  1336 
       
  1337             // handle "free" annotations
       
  1338             // int i = dimAnnosCount == 0 ? 0 : dimAnnosCount - 1;
       
  1339             // TODO: is depth.size == i here?
       
  1340             JCExpression elemType = tree.elemtype;
       
  1341             depth = depth.append(TypePathEntry.ARRAY);
       
  1342             while (elemType != null) {
       
  1343                 if (elemType.hasTag(JCTree.Tag.ANNOTATED_TYPE)) {
       
  1344                     JCAnnotatedType at = (JCAnnotatedType)elemType;
       
  1345                     final ListBuffer<TypePathEntry> locationbuf =
       
  1346                         locateNestedTypes(elemType.type,
       
  1347                                           new ListBuffer<TypePathEntry>());
       
  1348                     final List<TypePathEntry> location =
       
  1349                         locationbuf.toList().prependList(depth.toList());
       
  1350                     final TypeAnnotationPosition p =
       
  1351                         TypeAnnotationPosition.newObj(location, currentLambda,
       
  1352                                                       tree.pos);
       
  1353                     setTypeAnnotationPos(at.annotations, p);
       
  1354                     elemType = at.underlyingType;
       
  1355                 } else if (elemType.hasTag(JCTree.Tag.TYPEARRAY)) {
       
  1356                     depth = depth.append(TypePathEntry.ARRAY);
       
  1357                     elemType = ((JCArrayTypeTree)elemType).elemtype;
       
  1358                 } else if (elemType.hasTag(JCTree.Tag.SELECT)) {
       
  1359                     elemType = ((JCFieldAccess)elemType).selected;
       
  1360                 } else {
       
  1361                     break;
       
  1362                 }
       
  1363             }
       
  1364             scan(tree.elems);
       
  1365         }
       
  1366 
       
  1367         private void findPosition(JCTree tree, JCTree frame, List<JCAnnotation> annotations) {
       
  1368             if (!annotations.isEmpty()) {
       
  1369                 /*
       
  1370                 System.err.println("Finding pos for: " + annotations);
       
  1371                 System.err.println("    tree: " + tree + " kind: " + tree.getKind());
       
  1372                 System.err.println("    frame: " + frame + " kind: " + frame.getKind());
       
  1373                 */
       
  1374                 final TypeAnnotationPosition p =
       
  1375                     resolveFrame(tree, frame, frames.toList(), currentLambda, 0,
       
  1376                                  new ListBuffer<TypePathEntry>());
       
  1377                 setTypeAnnotationPos(annotations, p);
       
  1378             }
       
  1379         }
       
  1380 
       
  1381         private void setTypeAnnotationPos(List<JCAnnotation> annotations,
       
  1382                 TypeAnnotationPosition position) {
       
  1383             for (JCAnnotation anno : annotations) {
       
  1384                 // attribute might be null during DeferredAttr;
       
  1385                 // we will be back later.
       
  1386                 if (anno.attribute != null) {
       
  1387                     ((Attribute.TypeCompound) anno.attribute).position = position;
       
  1388                 }
       
  1389             }
       
  1390         }
       
  1391 
       
  1392         @Override
       
  1393         public String toString() {
       
  1394             return super.toString() + ": sigOnly: " + sigOnly;
       
  1395         }
       
  1396     }
       
  1397 }