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