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