1 /*
   2  * Copyright (c) 2003, 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 java.util.Iterator;
  29 
  30 import com.sun.tools.javac.tree.JCTree.JCLambda;
  31 import com.sun.tools.javac.util.*;
  32 
  33 /** A type annotation position.
  34 *
  35 *  <p><b>This is NOT part of any supported API.
  36 *  If you write code that depends on this, you do so at your own risk.
  37 *  This code and its internal interfaces are subject to change or
  38 *  deletion without notice.</b>
  39 */
  40 // Code duplicated in com.sun.tools.classfile.TypeAnnotation.Position
  41 public class TypeAnnotationPosition {
  42 
  43     public enum TypePathEntryKind {
  44         ARRAY(0),
  45         INNER_TYPE(1),
  46         WILDCARD(2),
  47         TYPE_ARGUMENT(3);
  48 
  49         public final int tag;
  50 
  51         private TypePathEntryKind(int tag) {
  52             this.tag = tag;
  53         }
  54     }
  55 
  56     public static class TypePathEntry {
  57         /** The fixed number of bytes per TypePathEntry. */
  58         public static final int bytesPerEntry = 2;
  59 
  60         public final TypePathEntryKind tag;
  61         public final int arg;
  62 
  63         public static final TypePathEntry ARRAY = new TypePathEntry(TypePathEntryKind.ARRAY);
  64         public static final TypePathEntry INNER_TYPE = new TypePathEntry(TypePathEntryKind.INNER_TYPE);
  65         public static final TypePathEntry WILDCARD = new TypePathEntry(TypePathEntryKind.WILDCARD);
  66 
  67         private TypePathEntry(TypePathEntryKind tag) {
  68             Assert.check(tag == TypePathEntryKind.ARRAY ||
  69                     tag == TypePathEntryKind.INNER_TYPE ||
  70                     tag == TypePathEntryKind.WILDCARD,
  71                     "Invalid TypePathEntryKind: " + tag);
  72             this.tag = tag;
  73             this.arg = 0;
  74         }
  75 
  76         public TypePathEntry(TypePathEntryKind tag, int arg) {
  77             Assert.check(tag == TypePathEntryKind.TYPE_ARGUMENT,
  78                     "Invalid TypePathEntryKind: " + tag);
  79             this.tag = tag;
  80             this.arg = arg;
  81         }
  82 
  83         public static TypePathEntry fromBinary(int tag, int arg) {
  84             Assert.check(arg == 0 || tag == TypePathEntryKind.TYPE_ARGUMENT.tag,
  85                     "Invalid TypePathEntry tag/arg: " + tag + "/" + arg);
  86             switch (tag) {
  87             case 0:
  88                 return ARRAY;
  89             case 1:
  90                 return INNER_TYPE;
  91             case 2:
  92                 return WILDCARD;
  93             case 3:
  94                 return new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg);
  95             default:
  96                 Assert.error("Invalid TypePathEntryKind tag: " + tag);
  97                 return null;
  98             }
  99         }
 100 
 101         @Override
 102         public String toString() {
 103             return tag.toString() +
 104                     (tag == TypePathEntryKind.TYPE_ARGUMENT ? ("(" + arg + ")") : "");
 105         }
 106 
 107         @Override
 108         public boolean equals(Object other) {
 109             if (! (other instanceof TypePathEntry)) {
 110                 return false;
 111             }
 112             TypePathEntry tpe = (TypePathEntry) other;
 113             return this.tag == tpe.tag && this.arg == tpe.arg;
 114         }
 115 
 116         @Override
 117         public int hashCode() {
 118             return this.tag.hashCode() * 17 + this.arg;
 119         }
 120     }
 121 
 122     public static final List<TypePathEntry> emptyPath = List.nil();
 123 
 124     // NOTE: All of these will be converted to final fields eventually.
 125 
 126     public final TargetType type;
 127 
 128     // For generic/array types.
 129 
 130     // This field is in the process of being made final.  Do not
 131     // introduce new mutations.
 132     public List<TypePathEntry> location;
 133 
 134     // Tree position.
 135     public final int pos;
 136 
 137     // For type casts, type tests, new, locals (as start_pc),
 138     // and method and constructor reference type arguments.
 139     public boolean isValidOffset = false;
 140     public int offset = -1;
 141 
 142     // For locals. arrays same length
 143     public int[] lvarOffset = null;
 144     public int[] lvarLength = null;
 145     public int[] lvarIndex = null;
 146 
 147     // For type parameter bound
 148     public final int bound_index;
 149 
 150     // For type parameter and method parameter
 151     public final int parameter_index;
 152 
 153     // For class extends, implements, and throws clauses
 154     public final int type_index;
 155 
 156     // For exception parameters, index into exception table.  In
 157     // com.sun.tools.javac.jvm.Gen.genCatch, we first use this to hold
 158     // the catch type index.  Then in
 159     // com.sun.tools.javac.jvm.Code.fillExceptionParameterPositions we
 160     // use that value to determine the exception table index.
 161     private int exception_index = Integer.MIN_VALUE;
 162 
 163     // If this type annotation is within a lambda expression,
 164     // store a pointer to the lambda expression tree in order
 165     // to allow a later translation to the right method.
 166     public final JCLambda onLambda;
 167 
 168     // NOTE: This constructor will eventually go away, and be replaced
 169     // by static builder methods.
 170 
 171     @Override
 172     public String toString() {
 173         StringBuilder sb = new StringBuilder();
 174         sb.append('[');
 175         sb.append(type);
 176 
 177         switch (type) {
 178         // instanceof
 179         case INSTANCEOF:
 180         // new expression
 181         case NEW:
 182         // constructor/method reference receiver
 183         case CONSTRUCTOR_REFERENCE:
 184         case METHOD_REFERENCE:
 185             sb.append(", offset = ");
 186             sb.append(offset);
 187             break;
 188         // local variable
 189         case LOCAL_VARIABLE:
 190         // resource variable
 191         case RESOURCE_VARIABLE:
 192             if (lvarOffset == null) {
 193                 sb.append(", lvarOffset is null!");
 194                 break;
 195             }
 196             sb.append(", {");
 197             for (int i = 0; i < lvarOffset.length; ++i) {
 198                 if (i != 0) sb.append("; ");
 199                 sb.append("start_pc = ");
 200                 sb.append(lvarOffset[i]);
 201                 sb.append(", length = ");
 202                 sb.append(lvarLength[i]);
 203                 sb.append(", index = ");
 204                 sb.append(lvarIndex[i]);
 205             }
 206             sb.append("}");
 207             break;
 208         // method receiver
 209         case METHOD_RECEIVER:
 210             // Do nothing
 211             break;
 212         // type parameter
 213         case CLASS_TYPE_PARAMETER:
 214         case METHOD_TYPE_PARAMETER:
 215             sb.append(", param_index = ");
 216             sb.append(parameter_index);
 217             break;
 218         // type parameter bound
 219         case CLASS_TYPE_PARAMETER_BOUND:
 220         case METHOD_TYPE_PARAMETER_BOUND:
 221             sb.append(", param_index = ");
 222             sb.append(parameter_index);
 223             sb.append(", bound_index = ");
 224             sb.append(bound_index);
 225             break;
 226         // class extends or implements clause
 227         case CLASS_EXTENDS:
 228             sb.append(", type_index = ");
 229             sb.append(type_index);
 230             break;
 231         // throws
 232         case THROWS:
 233             sb.append(", type_index = ");
 234             sb.append(type_index);
 235             break;
 236         // exception parameter
 237         case EXCEPTION_PARAMETER:
 238             sb.append(", exception_index = ");
 239             sb.append(exception_index);
 240             break;
 241         // method parameter
 242         case METHOD_FORMAL_PARAMETER:
 243             sb.append(", param_index = ");
 244             sb.append(parameter_index);
 245             break;
 246         // type cast
 247         case CAST:
 248         // method/constructor/reference type argument
 249         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
 250         case METHOD_INVOCATION_TYPE_ARGUMENT:
 251         case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
 252         case METHOD_REFERENCE_TYPE_ARGUMENT:
 253             sb.append(", offset = ");
 254             sb.append(offset);
 255             sb.append(", type_index = ");
 256             sb.append(type_index);
 257             break;
 258         // We don't need to worry about these
 259         case METHOD_RETURN:
 260         case FIELD:
 261             break;
 262         case UNKNOWN:
 263             sb.append(", position UNKNOWN!");
 264             break;
 265         default:
 266             Assert.error("Unknown target type: " + type);
 267         }
 268 
 269         // Append location data for generics/arrays.
 270         if (!location.isEmpty()) {
 271             sb.append(", location = (");
 272             sb.append(location);
 273             sb.append(")");
 274         }
 275 
 276         sb.append(", pos = ");
 277         sb.append(pos);
 278 
 279         if (onLambda != null) {
 280             sb.append(", onLambda hash = ");
 281             sb.append(onLambda.hashCode());
 282         }
 283 
 284         sb.append(']');
 285         return sb.toString();
 286     }
 287 
 288     /**
 289      * Indicates whether the target tree of the annotation has been optimized
 290      * away from classfile or not.
 291      * @return true if the target has not been optimized away
 292      */
 293     public boolean emitToClassfile() {
 294         return !type.isLocal() || isValidOffset;
 295     }
 296 
 297 
 298     public boolean matchesPos(int pos) {
 299         return this.pos == pos;
 300     }
 301 
 302     public void updatePosOffset(int to) {
 303         offset = to;
 304         lvarOffset = new int[]{to};
 305         isValidOffset = true;
 306     }
 307 
 308     public boolean hasExceptionIndex() {
 309         return exception_index >= 0;
 310     }
 311 
 312     public int getExceptionIndex() {
 313         Assert.check(exception_index >= 0, "exception_index does not contain a bytecode offset");
 314         return exception_index;
 315     }
 316 
 317     public void setExceptionIndex(final int exception_index) {
 318         Assert.check(hasCatchType(), "exception_index already contains a bytecode offset");
 319         Assert.check(exception_index >= 0, "Expected a valid bytecode offset");
 320         this.exception_index = exception_index;
 321     }
 322 
 323     public boolean hasCatchType() {
 324         return exception_index < 0 && exception_index != Integer.MIN_VALUE;
 325     }
 326 
 327     public int getCatchType() {
 328         Assert.check(hasCatchType(),
 329                      "exception_index does not contain valid catch info");
 330         return ((-this.exception_index) - 1) & 0xff ;
 331     }
 332 
 333     public int getStartPos() {
 334         Assert.check(hasCatchType(),
 335                      "exception_index does not contain valid catch info");
 336         return ((-this.exception_index) - 1) >> 8 ;
 337     }
 338 
 339     public void setCatchInfo(final int catchType, final int startPos) {
 340         Assert.check(this.exception_index < 0,
 341                      "exception_index already contains a bytecode index");
 342         Assert.check(catchType >= 0, "Expected a valid catch type");
 343         this.exception_index = -((catchType | startPos << 8) + 1);
 344     }
 345 
 346     /**
 347      * Decode the binary representation for a type path and set
 348      * the {@code location} field.
 349      *
 350      * @param list The bytecode representation of the type path.
 351      */
 352     public static List<TypePathEntry> getTypePathFromBinary(java.util.List<Integer> list) {
 353         ListBuffer<TypePathEntry> loc = new ListBuffer<>();
 354         Iterator<Integer> iter = list.iterator();
 355         while (iter.hasNext()) {
 356             Integer fst = iter.next();
 357             Assert.check(iter.hasNext(), "Could not decode type path: " + list);
 358             Integer snd = iter.next();
 359             loc = loc.append(TypePathEntry.fromBinary(fst, snd));
 360         }
 361         return loc.toList();
 362     }
 363 
 364     public static List<Integer> getBinaryFromTypePath(java.util.List<TypePathEntry> locs) {
 365         ListBuffer<Integer> loc = new ListBuffer<>();
 366         for (TypePathEntry tpe : locs) {
 367             loc = loc.append(tpe.tag.tag);
 368             loc = loc.append(tpe.arg);
 369         }
 370         return loc.toList();
 371     }
 372 
 373     // These methods are the new preferred way to create
 374     // TypeAnnotationPositions
 375 
 376     // Never make this a public constructor without creating a builder.
 377     private TypeAnnotationPosition(final TargetType ttype,
 378                                    final int pos,
 379                                    final int parameter_index,
 380                                    final JCLambda onLambda,
 381                                    final int type_index,
 382                                    final int bound_index,
 383                                    final List<TypePathEntry> location) {
 384         Assert.checkNonNull(location);
 385         this.type = ttype;
 386         this.pos = pos;
 387         this.parameter_index = parameter_index;
 388         this.onLambda = onLambda;
 389         this.type_index = type_index;
 390         this.bound_index = bound_index;
 391         this.location = location;
 392     }
 393 
 394     /**
 395      * Create a {@code TypeAnnotationPosition} for a method return.
 396      *
 397      * @param location The type path.
 398      * @param onLambda The lambda for this parameter.
 399      * @param pos The position from the associated tree node.
 400      */
 401     public static TypeAnnotationPosition
 402         methodReturn(final List<TypePathEntry> location,
 403                      final JCLambda onLambda,
 404                      final int pos) {
 405         return new TypeAnnotationPosition(TargetType.METHOD_RETURN, pos,
 406                                           Integer.MIN_VALUE, onLambda,
 407                                           Integer.MIN_VALUE, Integer.MIN_VALUE,
 408                                           location);
 409     }
 410 
 411     /**
 412      * Create a {@code TypeAnnotationPosition} for a method return.
 413      *
 414      * @param location The type path.
 415      */
 416     public static TypeAnnotationPosition
 417         methodReturn(final List<TypePathEntry> location) {
 418         return methodReturn(location, null, -1);
 419     }
 420 
 421     /**
 422      * Create a {@code TypeAnnotationPosition} for a method return.
 423      *
 424      * @param pos The position from the associated tree node.
 425      */
 426     public static TypeAnnotationPosition methodReturn(final int pos) {
 427         return methodReturn(emptyPath, null, pos);
 428     }
 429 
 430     /**
 431      * Create a {@code TypeAnnotationPosition} for a method receiver.
 432      *
 433      * @param location The type path.
 434      * @param onLambda The lambda for this parameter.
 435      * @param pos The position from the associated tree node.
 436      */
 437     public static TypeAnnotationPosition
 438         methodReceiver(final List<TypePathEntry> location,
 439                      final JCLambda onLambda,
 440                      final int pos) {
 441         return new TypeAnnotationPosition(TargetType.METHOD_RECEIVER, pos,
 442                                           Integer.MIN_VALUE, onLambda,
 443                                           Integer.MIN_VALUE, Integer.MIN_VALUE,
 444                                           location);
 445     }
 446 
 447     /**
 448      * Create a {@code TypeAnnotationPosition} for a method receiver.
 449      *
 450      * @param location The type path.
 451      */
 452     public static TypeAnnotationPosition
 453         methodReceiver(final List<TypePathEntry> location) {
 454         return methodReceiver(location, null, -1);
 455     }
 456 
 457     /**
 458      * Create a {@code TypeAnnotationPosition} for a method receiver.
 459      *
 460      * @param pos The position from the associated tree node.
 461      */
 462     public static TypeAnnotationPosition methodReceiver(final int pos) {
 463         return methodReceiver(emptyPath, null, pos);
 464     }
 465 
 466     /**
 467      * Create a {@code TypeAnnotationPosition} for a method formal parameter.
 468      *
 469      * @param location The type path.
 470      * @param onLambda The lambda for this parameter.
 471      * @param index The index of the parameter.
 472      * @param pos The position from the associated tree node.
 473      */
 474     public static TypeAnnotationPosition
 475         methodParameter(final List<TypePathEntry> location,
 476                         final JCLambda onLambda,
 477                         final int parameter_index,
 478                         final int pos) {
 479         return new TypeAnnotationPosition(TargetType.METHOD_FORMAL_PARAMETER,
 480                                           pos, parameter_index, onLambda,
 481                                           Integer.MIN_VALUE, Integer.MIN_VALUE,
 482                                           location);
 483     }
 484 
 485     /**
 486      * Create a {@code TypeAnnotationPosition} for a method formal parameter.
 487      *
 488      * @param onLambda The lambda for this parameter.
 489      * @param index The index of the parameter.
 490      * @param pos The position from the associated tree node.
 491      */
 492     public static TypeAnnotationPosition
 493         methodParameter(final JCLambda onLambda,
 494                         final int parameter_index,
 495                         final int pos) {
 496         return methodParameter(emptyPath, onLambda,
 497                                parameter_index, pos);
 498     }
 499 
 500     /**
 501      * Create a {@code TypeAnnotationPosition} for a method formal parameter.
 502      *
 503      * @param index The index of the parameter.
 504      * @param pos The position from the associated tree node.
 505      */
 506     public static TypeAnnotationPosition
 507         methodParameter(final int parameter_index,
 508                         final int pos) {
 509         return methodParameter(null, parameter_index, pos);
 510     }
 511 
 512     /**
 513      * Create a {@code TypeAnnotationPosition} for a method formal parameter.
 514      *
 515      * @param location The type path.
 516      * @param index The index of the parameter.
 517      */
 518     public static TypeAnnotationPosition
 519         methodParameter(final List<TypePathEntry> location,
 520                         final int parameter_index) {
 521         return methodParameter(location, null, parameter_index, -1);
 522     }
 523 
 524     /**
 525      * Create a {@code TypeAnnotationPosition} for a method reference.
 526      *
 527      * @param location The type path.
 528      * @param onLambda The lambda for this method reference.
 529      * @param pos The position from the associated tree node.
 530      */
 531     public static TypeAnnotationPosition
 532         methodRef(final List<TypePathEntry> location,
 533                   final JCLambda onLambda,
 534                   final int pos) {
 535         return new TypeAnnotationPosition(TargetType.METHOD_REFERENCE, pos,
 536                                           Integer.MIN_VALUE, onLambda,
 537                                           Integer.MIN_VALUE, Integer.MIN_VALUE,
 538                                           location);
 539     }
 540 
 541     /**
 542      * Create a {@code TypeAnnotationPosition} for a method reference.
 543      *
 544      * @param location The type path.
 545      * @param onLambda The lambda for this method reference.
 546      * @param pos The position from the associated tree node.
 547      */
 548     public static TypeAnnotationPosition
 549         methodRef(final List<TypePathEntry> location) {
 550         return methodRef(location, null, -1);
 551     }
 552 
 553     /**
 554      * Create a {@code TypeAnnotationPosition} for a constructor reference.
 555      *
 556      * @param location The type path.
 557      * @param onLambda The lambda for this constructor reference.
 558      * @param pos The position from the associated tree node.
 559      */
 560     public static TypeAnnotationPosition
 561         constructorRef(final List<TypePathEntry> location,
 562                        final JCLambda onLambda,
 563                        final int pos) {
 564         return new TypeAnnotationPosition(TargetType.CONSTRUCTOR_REFERENCE, pos,
 565                                           Integer.MIN_VALUE, onLambda,
 566                                           Integer.MIN_VALUE, Integer.MIN_VALUE,
 567                                           location);
 568     }
 569 
 570     /**
 571      * Create a {@code TypeAnnotationPosition} for a constructor reference.
 572      *
 573      * @param location The type path.
 574      * @param onLambda The lambda for this constructor reference.
 575      * @param pos The position from the associated tree node.
 576      */
 577     public static TypeAnnotationPosition
 578         constructorRef(final List<TypePathEntry> location) {
 579         return constructorRef(location, null, -1);
 580     }
 581 
 582     /**
 583      * Create a {@code TypeAnnotationPosition} for a field.
 584      *
 585      * @param location The type path.
 586      * @param onLambda The lambda for this variable.
 587      * @param pos The position from the associated tree node.
 588      */
 589     public static TypeAnnotationPosition
 590         field(final List<TypePathEntry> location,
 591               final JCLambda onLambda,
 592               final int pos) {
 593         return new TypeAnnotationPosition(TargetType.FIELD, pos,
 594                                           Integer.MIN_VALUE, onLambda,
 595                                           Integer.MIN_VALUE, Integer.MIN_VALUE,
 596                                           location);
 597     }
 598 
 599     /**
 600      * Create a {@code TypeAnnotationPosition} for a field.
 601      *
 602      * @param location The type path.
 603      */
 604     public static TypeAnnotationPosition
 605         field(final List<TypePathEntry> location) {
 606         return field(location, null, -1);
 607     }
 608 
 609     /**
 610      * Create a {@code TypeAnnotationPosition} for a field.
 611      *
 612      * @param pos The position from the associated tree node.
 613      */
 614     public static TypeAnnotationPosition field(final int pos) {
 615         return field(emptyPath, null, pos);
 616     }
 617 
 618     /**
 619      * Create a {@code TypeAnnotationPosition} for a local variable.
 620      *
 621      * @param location The type path.
 622      * @param onLambda The lambda for this variable.
 623      * @param pos The position from the associated tree node.
 624      */
 625     public static TypeAnnotationPosition
 626         localVariable(final List<TypePathEntry> location,
 627                       final JCLambda onLambda,
 628                       final int pos) {
 629         return new TypeAnnotationPosition(TargetType.LOCAL_VARIABLE, pos,
 630                                           Integer.MIN_VALUE, onLambda,
 631                                           Integer.MIN_VALUE, Integer.MIN_VALUE,
 632                                           location);
 633     }
 634 
 635     /**
 636      * Create a {@code TypeAnnotationPosition} for a local variable.
 637      *
 638      * @param onLambda The lambda for this variable.
 639      * @param pos The position from the associated tree node.
 640      */
 641     public static TypeAnnotationPosition
 642         localVariable(final JCLambda onLambda,
 643                       final int pos) {
 644         return localVariable(emptyPath, onLambda, pos);
 645     }
 646 
 647     /**
 648      * Create a {@code TypeAnnotationPosition} for a local variable.
 649      *
 650      * @param location The type path.
 651      */
 652     public static TypeAnnotationPosition
 653         localVariable(final List<TypePathEntry> location) {
 654         return localVariable(location, null, -1);
 655     }
 656 
 657     /**
 658      * Create a {@code TypeAnnotationPosition} for an exception parameter.
 659      *
 660      * @param location The type path.
 661      * @param onLambda The lambda for this parameter.
 662      * @param pos The position from the associated tree node.
 663      */
 664     public static TypeAnnotationPosition
 665         exceptionParameter(final List<TypePathEntry> location,
 666                            final JCLambda onLambda,
 667                            final int pos) {
 668         return new TypeAnnotationPosition(TargetType.EXCEPTION_PARAMETER, pos,
 669                                           Integer.MIN_VALUE, onLambda,
 670                                           Integer.MIN_VALUE, Integer.MIN_VALUE,
 671                                           location);
 672     }
 673 
 674     /**
 675      * Create a {@code TypeAnnotationPosition} for an exception parameter.
 676      *
 677      * @param onLambda The lambda for this parameter.
 678      * @param pos The position from the associated tree node.
 679      */
 680     public static TypeAnnotationPosition
 681         exceptionParameter(final JCLambda onLambda,
 682                            final int pos) {
 683         return exceptionParameter(emptyPath, onLambda, pos);
 684     }
 685 
 686     /**
 687      * Create a {@code TypeAnnotationPosition} for an exception parameter.
 688      *
 689      * @param location The type path.
 690      */
 691     public static TypeAnnotationPosition
 692         exceptionParameter(final List<TypePathEntry> location) {
 693         return exceptionParameter(location, null, -1);
 694     }
 695 
 696 
 697     /**
 698      * Create a {@code TypeAnnotationPosition} for a resource variable.
 699      *
 700      * @param location The type path.
 701      * @param onLambda The lambda for this variable.
 702      * @param pos The position from the associated tree node.
 703      */
 704     public static TypeAnnotationPosition
 705         resourceVariable(final List<TypePathEntry> location,
 706                          final JCLambda onLambda,
 707                          final int pos) {
 708         return new TypeAnnotationPosition(TargetType.RESOURCE_VARIABLE, pos,
 709                                           Integer.MIN_VALUE, onLambda,
 710                                           Integer.MIN_VALUE, Integer.MIN_VALUE,
 711                                           location);
 712     }
 713 
 714     /**
 715      * Create a {@code TypeAnnotationPosition} for a resource variable.
 716      *
 717      * @param onLambda The lambda for this variable.
 718      * @param pos The position from the associated tree node.
 719      */
 720     public static TypeAnnotationPosition
 721         resourceVariable(final JCLambda onLambda,
 722                          final int pos) {
 723         return resourceVariable(emptyPath, onLambda, pos);
 724     }
 725 
 726     /**
 727      * Create a {@code TypeAnnotationPosition} for a resource variable.
 728      *
 729      * @param location The type path.
 730      * @param onLambda The lambda for this variable.
 731      * @param pos The position from the associated tree node.
 732      */
 733     public static TypeAnnotationPosition
 734         resourceVariable(final List<TypePathEntry> location) {
 735         return resourceVariable(location, null, -1);
 736     }
 737 
 738     /**
 739      * Create a {@code TypeAnnotationPosition} for a new.
 740      *
 741      * @param location The type path.
 742      * @param onLambda The lambda for this variable.
 743      * @param pos The position from the associated tree node.
 744      */
 745     public static TypeAnnotationPosition
 746         newObj(final List<TypePathEntry> location,
 747                final JCLambda onLambda,
 748                final int pos) {
 749         return new TypeAnnotationPosition(TargetType.NEW, pos,
 750                                           Integer.MIN_VALUE, onLambda,
 751                                           Integer.MIN_VALUE, Integer.MIN_VALUE,
 752                                           location);
 753     }
 754 
 755     /**
 756      * Create a {@code TypeAnnotationPosition} for a new.
 757      *
 758      * @param location The type path.
 759      * @param onLambda The lambda for this variable.
 760      * @param pos The position from the associated tree node.
 761      */
 762     public static TypeAnnotationPosition newObj(final int pos) {
 763         return newObj(emptyPath, null, pos);
 764     }
 765 
 766     /**
 767      * Create a {@code TypeAnnotationPosition} for a new.
 768      *
 769      * @param location The type path.
 770      * @param onLambda The lambda for this variable.
 771      * @param pos The position from the associated tree node.
 772      */
 773     public static TypeAnnotationPosition
 774         newObj(final List<TypePathEntry> location) {
 775         return newObj(location, null, -1);
 776     }
 777 
 778     /**
 779      * Create a {@code TypeAnnotationPosition} for a class extension.
 780      *
 781      * @param location The type path.
 782      * @param onLambda The lambda for this variable.
 783      * @param type_index The index of the interface.
 784      * @param pos The position from the associated tree node.
 785      */
 786     public static TypeAnnotationPosition
 787         classExtends(final List<TypePathEntry> location,
 788                      final JCLambda onLambda,
 789                      final int type_index,
 790                      final int pos) {
 791         return new TypeAnnotationPosition(TargetType.CLASS_EXTENDS, pos,
 792                                           Integer.MIN_VALUE, onLambda,
 793                                           type_index, Integer.MIN_VALUE,
 794                                           location);
 795     }
 796 
 797     /**
 798      * Create a {@code TypeAnnotationPosition} for a class extension.
 799      *
 800      * @param location The type path.
 801      * @param onLambda The lambda for this variable.
 802      * @param type_index The index of the interface.
 803      * @param pos The position from the associated tree node.
 804      */
 805     public static TypeAnnotationPosition
 806         classExtends(final List<TypePathEntry> location,
 807                      final JCLambda onLambda,
 808                      final int pos) {
 809         return classExtends(location, onLambda, -1, pos);
 810     }
 811 
 812     /**
 813      * Create a {@code TypeAnnotationPosition} for a class extension.
 814      *
 815      * @param location The type path.
 816      * @param type_index The index of the interface.
 817      */
 818     public static TypeAnnotationPosition
 819         classExtends(final List<TypePathEntry> location,
 820                      final int type_index) {
 821         return classExtends(location, null, type_index, -1);
 822     }
 823 
 824     /**
 825      * Create a {@code TypeAnnotationPosition} for a class extension.
 826      *
 827      * @param type_index The index of the interface.
 828      * @param pos The position from the associated tree node.
 829      */
 830     public static TypeAnnotationPosition classExtends(final int type_index,
 831                                                       final int pos) {
 832         return classExtends(emptyPath, null, type_index, pos);
 833     }
 834 
 835     /**
 836      * Create a {@code TypeAnnotationPosition} for a class extension.
 837      *
 838      * @param pos The position from the associated tree node.
 839      */
 840     public static TypeAnnotationPosition classExtends(final int pos) {
 841         return classExtends(-1, pos);
 842     }
 843 
 844     /**
 845      * Create a {@code TypeAnnotationPosition} for an instanceof.
 846      *
 847      * @param location The type path.
 848      * @param onLambda The lambda for this variable.
 849      * @param pos The position from the associated tree node.
 850      */
 851     public static TypeAnnotationPosition
 852         instanceOf(final List<TypePathEntry> location,
 853                    final JCLambda onLambda,
 854                    final int pos) {
 855         return new TypeAnnotationPosition(TargetType.INSTANCEOF, pos,
 856                                           Integer.MIN_VALUE, onLambda,
 857                                           Integer.MIN_VALUE, Integer.MIN_VALUE,
 858                                           location);
 859     }
 860     /**
 861      * Create a {@code TypeAnnotationPosition} for an instanceof.
 862      *
 863      * @param location The type path.
 864      * @param onLambda The lambda for this variable.
 865      * @param pos The position from the associated tree node.
 866      */
 867     public static TypeAnnotationPosition
 868         instanceOf(final List<TypePathEntry> location) {
 869         return instanceOf(location, null, -1);
 870     }
 871 
 872     /**
 873      * Create a {@code TypeAnnotationPosition} for a type cast.
 874      *
 875      * @param location The type path.
 876      * @param onLambda The lambda for this variable.
 877      * @param type_index The index into an intersection type.
 878      * @param pos The position from the associated tree node.
 879      */
 880     public static TypeAnnotationPosition
 881         typeCast(final List<TypePathEntry> location,
 882                  final JCLambda onLambda,
 883                  final int type_index,
 884                  final int pos) {
 885         return new TypeAnnotationPosition(TargetType.CAST, pos,
 886                                           Integer.MIN_VALUE, onLambda,
 887                                           type_index, Integer.MIN_VALUE,
 888                                           location);
 889     }
 890 
 891     /**
 892      * Create a {@code TypeAnnotationPosition} for a type cast.
 893      *
 894      * @param location The type path.
 895      * @param onLambda The lambda for this variable.
 896      * @param type_index The index into an intersection type.
 897      * @param pos The position from the associated tree node.
 898      */
 899     public static TypeAnnotationPosition
 900         typeCast(final List<TypePathEntry> location,
 901                  final int type_index) {
 902         return typeCast(location, null, type_index, -1);
 903     }
 904 
 905     /**
 906      * Create a {@code TypeAnnotationPosition} for a method
 907      * invocation type argument.
 908      *
 909      * @param location The type path.
 910      * @param onLambda The lambda for this variable.
 911      * @param type_index The index of the type argument.
 912      * @param pos The position from the associated tree node.
 913      */
 914     public static TypeAnnotationPosition
 915         methodInvocationTypeArg(final List<TypePathEntry> location,
 916                                 final JCLambda onLambda,
 917                                 final int type_index,
 918                                 final int pos) {
 919         return new TypeAnnotationPosition(TargetType.METHOD_INVOCATION_TYPE_ARGUMENT,
 920                                           pos, Integer.MIN_VALUE, onLambda,
 921                                           type_index, Integer.MIN_VALUE,
 922                                           location);
 923     }
 924 
 925     /**
 926      * Create a {@code TypeAnnotationPosition} for a method
 927      * invocation type argument.
 928      *
 929      * @param location The type path.
 930      * @param type_index The index of the type argument.
 931      */
 932     public static TypeAnnotationPosition
 933         methodInvocationTypeArg(final List<TypePathEntry> location,
 934                                 final int type_index) {
 935         return methodInvocationTypeArg(location, null, type_index, -1);
 936     }
 937 
 938     /**
 939      * Create a {@code TypeAnnotationPosition} for a constructor
 940      * invocation type argument.
 941      *
 942      * @param location The type path.
 943      * @param onLambda The lambda for this variable.
 944      * @param type_index The index of the type argument.
 945      * @param pos The position from the associated tree node.
 946      */
 947     public static TypeAnnotationPosition
 948         constructorInvocationTypeArg(final List<TypePathEntry> location,
 949                                      final JCLambda onLambda,
 950                                      final int type_index,
 951                                      final int pos) {
 952         return new TypeAnnotationPosition(TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT,
 953                                           pos, Integer.MIN_VALUE, onLambda,
 954                                           type_index, Integer.MIN_VALUE,
 955                                           location);
 956     }
 957 
 958     /**
 959      * Create a {@code TypeAnnotationPosition} for a constructor
 960      * invocation type argument.
 961      *
 962      * @param location The type path.
 963      * @param type_index The index of the type argument.
 964      */
 965     public static TypeAnnotationPosition
 966         constructorInvocationTypeArg(final List<TypePathEntry> location,
 967                                      final int type_index) {
 968         return constructorInvocationTypeArg(location, null, type_index, -1);
 969     }
 970 
 971     /**
 972      * Create a {@code TypeAnnotationPosition} for a type parameter.
 973      *
 974      * @param location The type path.
 975      * @param onLambda The lambda for this variable.
 976      * @param parameter_index The index of the type parameter.
 977      * @param pos The position from the associated tree node.
 978      */
 979     public static TypeAnnotationPosition
 980         typeParameter(final List<TypePathEntry> location,
 981                       final JCLambda onLambda,
 982                       final int parameter_index,
 983                       final int pos) {
 984         return new TypeAnnotationPosition(TargetType.CLASS_TYPE_PARAMETER, pos,
 985                                           parameter_index, onLambda,
 986                                           Integer.MIN_VALUE, Integer.MIN_VALUE,
 987                                           location);
 988     }
 989 
 990     /**
 991      * Create a {@code TypeAnnotationPosition} for a type parameter.
 992      *
 993      * @param location The type path.
 994      * @param onLambda The lambda for this variable.
 995      * @param parameter_index The index of the type parameter.
 996      * @param pos The position from the associated tree node.
 997      */
 998     public static TypeAnnotationPosition
 999         typeParameter(final List<TypePathEntry> location,
1000                       final int parameter_index) {
1001         return typeParameter(location, null, parameter_index, -1);
1002     }
1003 
1004     /**
1005      * Create a {@code TypeAnnotationPosition} for a method type parameter.
1006      *
1007      * @param location The type path.
1008      * @param onLambda The lambda for this variable.
1009      * @param parameter_index The index of the type parameter.
1010      * @param pos The position from the associated tree node.
1011      */
1012     public static TypeAnnotationPosition
1013         methodTypeParameter(final List<TypePathEntry> location,
1014                             final JCLambda onLambda,
1015                             final int parameter_index,
1016                             final int pos) {
1017         return new TypeAnnotationPosition(TargetType.METHOD_TYPE_PARAMETER,
1018                                           pos, parameter_index, onLambda,
1019                                           Integer.MIN_VALUE, Integer.MIN_VALUE,
1020                                           location);
1021     }
1022 
1023     /**
1024      * Create a {@code TypeAnnotationPosition} for a method type parameter.
1025      *
1026      * @param location The type path.
1027      * @param parameter_index The index of the type parameter.
1028      */
1029     public static TypeAnnotationPosition
1030         methodTypeParameter(final List<TypePathEntry> location,
1031                             final int parameter_index) {
1032         return methodTypeParameter(location, null, parameter_index, -1);
1033     }
1034 
1035     /**
1036      * Create a {@code TypeAnnotationPosition} for a throws clause.
1037      *
1038      * @param location The type path.
1039      * @param onLambda The lambda for this variable.
1040      * @param type_index The index of the exception.
1041      * @param pos The position from the associated tree node.
1042      */
1043     public static TypeAnnotationPosition
1044         methodThrows(final List<TypePathEntry> location,
1045                      final JCLambda onLambda,
1046                      final int type_index,
1047                      final int pos) {
1048         return new TypeAnnotationPosition(TargetType.THROWS, pos,
1049                                           Integer.MIN_VALUE, onLambda,
1050                                           type_index, Integer.MIN_VALUE,
1051                                           location);
1052     }
1053 
1054     /**
1055      * Create a {@code TypeAnnotationPosition} for a throws clause.
1056      *
1057      * @param location The type path.
1058      * @param type_index The index of the exception.
1059      */
1060     public static TypeAnnotationPosition
1061         methodThrows(final List<TypePathEntry> location,
1062                      final int type_index) {
1063         return methodThrows(location, null, type_index, -1);
1064     }
1065 
1066     /**
1067      * Create a {@code TypeAnnotationPosition} for a method reference
1068      * type argument.
1069      *
1070      * @param location The type path.
1071      * @param onLambda The lambda for this variable.
1072      * @param parameter_index The index of the type argument.
1073      * @param pos The position from the associated tree node.
1074      */
1075     public static TypeAnnotationPosition
1076         methodRefTypeArg(final List<TypePathEntry> location,
1077                          final JCLambda onLambda,
1078                          final int type_index,
1079                          final int pos) {
1080         return new TypeAnnotationPosition(TargetType.METHOD_REFERENCE_TYPE_ARGUMENT,
1081                                           pos, Integer.MIN_VALUE, onLambda,
1082                                           type_index, Integer.MIN_VALUE,
1083                                           location);
1084     }
1085 
1086     /**
1087      * Create a {@code TypeAnnotationPosition} for a method reference
1088      * type argument.
1089      *
1090      * @param location The type path.
1091      * @param onLambda The lambda for this variable.
1092      * @param parameter_index The index of the type argument.
1093      * @param pos The position from the associated tree node.
1094      */
1095     public static TypeAnnotationPosition
1096         methodRefTypeArg(final List<TypePathEntry> location,
1097                          final int type_index) {
1098         return methodRefTypeArg(location, null, type_index, -1);
1099     }
1100 
1101     /**
1102      * Create a {@code TypeAnnotationPosition} for a constructor reference
1103      * type argument.
1104      *
1105      * @param location The type path.
1106      * @param onLambda The lambda for this variable.
1107      * @param parameter_index The index of the type argument.
1108      * @param pos The position from the associated tree node.
1109      */
1110     public static TypeAnnotationPosition
1111         constructorRefTypeArg(final List<TypePathEntry> location,
1112                               final JCLambda onLambda,
1113                               final int type_index,
1114                               final int pos) {
1115         return new TypeAnnotationPosition(TargetType.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
1116                                           pos, Integer.MIN_VALUE, onLambda,
1117                                           type_index, Integer.MIN_VALUE,
1118                                           location);
1119     }
1120 
1121     /**
1122      * Create a {@code TypeAnnotationPosition} for a constructor reference
1123      * type argument.
1124      *
1125      * @param location The type path.
1126      * @param parameter_index The index of the type argument.
1127      */
1128     public static TypeAnnotationPosition
1129         constructorRefTypeArg(final List<TypePathEntry> location,
1130                               final int type_index) {
1131         return constructorRefTypeArg(location, null, type_index, -1);
1132     }
1133 
1134     /**
1135      * Create a {@code TypeAnnotationPosition} for a type parameter bound.
1136      *
1137      * @param location The type path.
1138      * @param onLambda The lambda for this variable.
1139      * @param parameter_index The index of the type parameter.
1140      * @param bound_index The index of the type parameter bound.
1141      * @param pos The position from the associated tree node.
1142      */
1143     public static TypeAnnotationPosition
1144         typeParameterBound(final List<TypePathEntry> location,
1145                            final JCLambda onLambda,
1146                            final int parameter_index,
1147                            final int bound_index,
1148                            final int pos) {
1149         return new TypeAnnotationPosition(TargetType.CLASS_TYPE_PARAMETER_BOUND,
1150                                           pos, parameter_index, onLambda,
1151                                           Integer.MIN_VALUE, bound_index,
1152                                           location);
1153     }
1154 
1155     /**
1156      * Create a {@code TypeAnnotationPosition} for a type parameter bound.
1157      *
1158      * @param location The type path.
1159      * @param parameter_index The index of the type parameter.
1160      * @param bound_index The index of the type parameter bound.
1161      */
1162     public static TypeAnnotationPosition
1163         typeParameterBound(final List<TypePathEntry> location,
1164                            final int parameter_index,
1165                            final int bound_index) {
1166         return typeParameterBound(location, null, parameter_index,
1167                                   bound_index, -1);
1168     }
1169 
1170     /**
1171      * Create a {@code TypeAnnotationPosition} for a method type
1172      * parameter bound.
1173      *
1174      * @param location The type path.
1175      * @param onLambda The lambda for this variable.
1176      * @param parameter_index The index of the type parameter.
1177      * @param bound_index The index of the type parameter bound.
1178      * @param pos The position from the associated tree node.
1179      */
1180     public static TypeAnnotationPosition
1181         methodTypeParameterBound(final List<TypePathEntry> location,
1182                                  final JCLambda onLambda,
1183                                  final int parameter_index,
1184                                  final int bound_index,
1185                                  final int pos) {
1186         return new TypeAnnotationPosition(TargetType.METHOD_TYPE_PARAMETER_BOUND,
1187                                           pos, parameter_index, onLambda,
1188                                           Integer.MIN_VALUE, bound_index,
1189                                           location);
1190     }
1191 
1192     /**
1193      * Create a {@code TypeAnnotationPosition} for a method type
1194      * parameter bound.
1195      *
1196      * @param location The type path.
1197      * @param parameter_index The index of the type parameter.
1198      * @param bound_index The index of the type parameter bound.
1199      */
1200     public static TypeAnnotationPosition
1201         methodTypeParameterBound(final List<TypePathEntry> location,
1202                                  final int parameter_index,
1203                                  final int bound_index) {
1204         return methodTypeParameterBound(location, null, parameter_index,
1205                                         bound_index, -1);
1206     }
1207 
1208     // Consider this deprecated on arrival.  We eventually want to get
1209     // rid of this value altogether.  Do not use it for anything new.
1210     public static final TypeAnnotationPosition unknown =
1211         new TypeAnnotationPosition(TargetType.UNKNOWN, -1,
1212                                    Integer.MIN_VALUE, null,
1213                                    Integer.MIN_VALUE, Integer.MIN_VALUE,
1214                                    emptyPath);
1215 }