src/share/classes/com/sun/tools/javac/comp/Annotate.java

Print this page




  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.comp;
  27 
  28 import java.util.HashMap;
  29 import java.util.LinkedHashMap;
  30 import java.util.Map;
  31 

  32 import javax.tools.JavaFileObject;
  33 
  34 import com.sun.tools.javac.util.*;
  35 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  36 import com.sun.tools.javac.code.*;
  37 import com.sun.tools.javac.code.Symbol.*;

  38 import com.sun.tools.javac.tree.*;
  39 import com.sun.tools.javac.tree.JCTree.*;
  40 
  41 import static com.sun.tools.javac.code.Kinds.*;
  42 import static com.sun.tools.javac.code.TypeTag.ARRAY;
  43 import static com.sun.tools.javac.code.TypeTag.CLASS;
  44 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  45 
  46 /** Enter annotations on symbols.  Annotations accumulate in a queue,
  47  *  which is processed at the top level of any set of recursive calls
  48  *  requesting it be processed.
  49  *
  50  *  <p><b>This is NOT part of any supported API.
  51  *  If you write code that depends on this, you do so at your own risk.
  52  *  This code and its internal interfaces are subject to change or
  53  *  deletion without notice.</b>
  54  */
  55 public class Annotate {
  56     protected static final Context.Key<Annotate> annotateKey = new Context.Key<>();
  57 


 248         public List<T> getPlaceholderFor() {
 249             return placeholderFor;
 250         }
 251 
 252         public Annotate.AnnotationContext<T> getRepeatedContext() {
 253             return ctx;
 254         }
 255     }
 256 
 257 
 258 /* ********************************************************************
 259  * Compute an attribute from its annotation.
 260  *********************************************************************/
 261 
 262     /** Process a single compound annotation, returning its
 263      *  Attribute. Used from MemberEnter for attaching the attributes
 264      *  to the annotated symbol.
 265      */
 266     Attribute.Compound enterAnnotation(JCAnnotation a,
 267                                        Type expected,
 268                                        Env<AttrContext> env) {
 269         List<Pair<MethodSymbol,Attribute>> elems =
 270             enterAttributeValues(a, expected, env);
 271         Attribute.Compound ac = new Attribute.Compound(a.type, elems);


 272         a.attribute = ac;
 273 
 274         return ac;
 275     }
 276 
 277     Attribute.TypeCompound enterTypeAnnotation(JCAnnotation a,
 278                                                Type expected,
 279                                                Env<AttrContext> env) {
 280         List<Pair<MethodSymbol,Attribute>> elems =
 281             enterAttributeValues(a, expected, env);

 282 
 283         if (a.attribute == null || !(a.attribute instanceof Attribute.TypeCompound)) {
 284             // Create a new TypeCompound
 285 
 286             Attribute.TypeCompound tc =
 287                 new Attribute.TypeCompound(a.type, elems,
 288                 // TODO: Eventually, we will get rid of this use of
 289                 // unknown, because we'll get a position from
 290                 // MemberEnter (task 8027262).
 291                                            TypeAnnotationPosition.unknown);
 292             a.attribute = tc;
 293             return tc;
 294         } else {
 295             // Use an existing TypeCompound
 296             return (Attribute.TypeCompound)a.attribute;
 297         }
 298     }
 299 
 300     private List<Pair<MethodSymbol,Attribute>>
 301             enterAttributeValues(JCAnnotation a,
 302                                  Type expected,
 303                                  Env<AttrContext> env) {

 304         // The annotation might have had its type attributed (but not
 305         // checked) by attr.attribAnnotationTypes during MemberEnter,
 306         // in which case we do not need to do it again.
 307         Type at = (a.annotationType.type != null ? a.annotationType.type
 308                   : attr.attribType(a.annotationType, env));
 309         a.type = chk.checkType(a.annotationType.pos(), at, expected);
 310         boolean isError = a.type.isErroneous();
 311         if ((a.type.tsym.flags() & Flags.ANNOTATION) == 0 && !isError) {
 312             log.error(a.annotationType.pos(),
 313                       "not.annotation.type", a.type.toString());
 314             isError = true;
 315         }
 316         List<JCExpression> args = a.args;
 317         if (args.length() == 1 && !args.head.hasTag(ASSIGN)) {
 318             // special case: elided "value=" assumed
 319             args.head = make.at(args.head.pos).
 320                 Assign(make.Ident(names.value), args.head);
 321         }
 322         ListBuffer<Pair<MethodSymbol,Attribute>> buf =
 323             new ListBuffer<>();
 324         for (List<JCExpression> tl = args; tl.nonEmpty(); tl = tl.tail) {
 325             JCExpression t = tl.head;
 326             if (!t.hasTag(ASSIGN)) {
 327                 log.error(t.pos(), "annotation.value.must.be.name.value");
 328                 enterAttributeValue(t.type = syms.errType, t, env);
 329                 continue;
 330             }
 331             JCAssign assign = (JCAssign)t;
 332             if (!assign.lhs.hasTag(IDENT)) {
 333                 log.error(t.pos(), "annotation.value.must.be.name.value");
 334                 enterAttributeValue(t.type = syms.errType, t, env);
 335                 continue;
 336             }
 337             JCIdent left = (JCIdent)assign.lhs;
 338             Symbol method = rs.resolveQualifiedMethod(assign.rhs.pos(),
 339                                                           env,
 340                                                           a.type,
 341                                                           left.name,
 342                                                           List.<Type>nil(),
 343                                                           null);
 344             left.sym = method;
 345             left.type = method.type;
 346             if (method.owner != a.type.tsym && !isError)
 347                 log.error(left.pos(), "no.annotation.member", left.name, a.type);
 348             Type result = method.type.getReturnType();
 349             Attribute value = enterAttributeValue(result, assign.rhs, env);
 350             if (!method.type.isErroneous())
 351                 buf.append(new Pair<>((MethodSymbol)method, value));
 352             t.type = result;
 353         }
 354         return buf.toList();
 355     }
 356 
 357     Attribute enterAttributeValue(Type expected,
 358                                   JCExpression tree,
 359                                   Env<AttrContext> env) {

 360         //first, try completing the attribution value sym - if a completion
 361         //error is thrown, we should recover gracefully, and display an
 362         //ordinary resolution diagnostic.
 363         try {
 364             expected.tsym.complete();
 365         } catch(CompletionFailure e) {
 366             log.error(tree.pos(), "cant.resolve", Kinds.kindName(e.sym), e.sym);
 367             expected = syms.errType;
 368         }
 369         if (expected.hasTag(ARRAY)) {
 370             if (!tree.hasTag(NEWARRAY)) {
 371                 tree = make.at(tree.pos).
 372                     NewArray(null, List.<JCExpression>nil(), List.of(tree));
 373             }
 374             JCNewArray na = (JCNewArray)tree;
 375             if (na.elemtype != null) {
 376                 log.error(na.elemtype.pos(), "new.not.allowed.in.annotation");
 377             }
 378             ListBuffer<Attribute> buf = new ListBuffer<>();
 379             for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) {
 380                 buf.append(enterAttributeValue(types.elemtype(expected),
 381                                                l.head,
 382                                                env));
 383             }
 384             na.type = expected;
 385             return new Attribute.
 386                 Array(expected, buf.toArray(new Attribute[buf.length()]));
 387         }
 388         if (tree.hasTag(NEWARRAY)) { //error recovery
 389             if (!expected.isErroneous())
 390                 log.error(tree.pos(), "annotation.value.not.allowable.type");
 391             JCNewArray na = (JCNewArray)tree;
 392             if (na.elemtype != null) {
 393                 log.error(na.elemtype.pos(), "new.not.allowed.in.annotation");
 394             }
 395             for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) {
 396                 enterAttributeValue(syms.errType,
 397                                     l.head,
 398                                     env);
 399             }
 400             return new Attribute.Error(syms.errType);
 401         }
 402         if ((expected.tsym.flags() & Flags.ANNOTATION) != 0) {
 403             if (tree.hasTag(ANNOTATION)) {
 404                 return enterAnnotation((JCAnnotation)tree, expected, env);
 405             } else {
 406                 log.error(tree.pos(), "annotation.value.must.be.annotation");
 407                 expected = syms.errType;
 408             }
 409         }
 410         if (tree.hasTag(ANNOTATION)) { //error recovery
 411             if (!expected.isErroneous())
 412                 log.error(tree.pos(), "annotation.not.valid.for.type", expected);
 413             enterAnnotation((JCAnnotation)tree, syms.errType, env);
 414             return new Attribute.Error(((JCAnnotation)tree).annotationType.type);
 415         }
 416         if (expected.isPrimitive() ||
 417             (types.isSameType(expected, syms.stringType) && !expected.hasTag(TypeTag.ERROR))) {
 418             Type result = attr.attribExpr(tree, env, expected);
 419             if (result.isErroneous())
 420                 return new Attribute.Error(result.getOriginalType());
 421             if (result.constValue() == null) {
 422                 log.error(tree.pos(), "attribute.value.must.be.constant");
 423                 return new Attribute.Error(expected);
 424             }
 425             result = cfolder.coerce(result, expected);
 426             return new Attribute.Constant(expected, result.constValue());
 427         }
 428         if (expected.tsym == syms.classType.tsym) {
 429             Type result = attr.attribExpr(tree, env, expected);
 430             if (result.isErroneous()) {
 431                 // Does it look like an unresolved class literal?
 432                 if (TreeInfo.name(tree) == names._class &&
 433                     ((JCFieldAccess) tree).selected.type.isErroneous()) {


 462             }
 463             VarSymbol enumerator = (VarSymbol) sym;
 464             return new Attribute.Enum(expected, enumerator);
 465         }
 466         //error recovery:
 467         if (!expected.isErroneous())
 468             log.error(tree.pos(), "annotation.value.not.allowable.type");
 469         return new Attribute.Error(attr.attribExpr(tree, env, expected));
 470     }
 471 
 472     /* *********************************
 473      * Support for repeating annotations
 474      ***********************************/
 475 
 476     /* Process repeated annotations. This method returns the
 477      * synthesized container annotation or null IFF all repeating
 478      * annotation are invalid.  This method reports errors/warnings.
 479      */
 480     private <T extends Attribute.Compound> T processRepeatedAnnotations(List<T> annotations,
 481             AnnotationContext<T> ctx,
 482             Symbol on) {

 483         T firstOccurrence = annotations.head;
 484         List<Attribute> repeated = List.nil();
 485         Type origAnnoType = null;
 486         Type arrayOfOrigAnnoType = null;
 487         Type targetContainerType = null;
 488         MethodSymbol containerValueSymbol = null;
 489 
 490         Assert.check(!annotations.isEmpty() &&
 491                      !annotations.tail.isEmpty()); // i.e. size() > 1
 492 
 493         int count = 0;
 494         for (List<T> al = annotations;
 495              !al.isEmpty();
 496              al = al.tail)
 497         {
 498             count++;
 499 
 500             // There must be more than a single anno in the annotation list
 501             Assert.check(count > 1 || !al.tail.isEmpty());
 502 
 503             T currentAnno = al.head;
 504 
 505             origAnnoType = currentAnno.type;
 506             if (arrayOfOrigAnnoType == null) {
 507                 arrayOfOrigAnnoType = types.makeArrayType(origAnnoType);
 508             }
 509 
 510             // Only report errors if this isn't the first occurrence I.E. count > 1
 511             boolean reportError = count > 1;
 512             Type currentContainerType = getContainingType(currentAnno, ctx.pos.get(currentAnno), reportError);
 513             if (currentContainerType == null) {
 514                 continue;
 515             }
 516             // Assert that the target Container is == for all repeated
 517             // annos of the same annotation type, the types should
 518             // come from the same Symbol, i.e. be '=='
 519             Assert.check(targetContainerType == null || currentContainerType == targetContainerType);
 520             targetContainerType = currentContainerType;
 521 
 522             containerValueSymbol = validateContainer(targetContainerType, origAnnoType, ctx.pos.get(currentAnno));
 523 
 524             if (containerValueSymbol == null) { // Check of CA type failed
 525                 // errors are already reported
 526                 continue;
 527             }
 528 
 529             repeated = repeated.prepend(currentAnno);
 530         }
 531 
 532         if (!repeated.isEmpty()) {
 533             repeated = repeated.reverse();
 534             TreeMaker m = make.at(ctx.pos.get(firstOccurrence));
 535             Pair<MethodSymbol, Attribute> p =
 536                     new Pair<MethodSymbol, Attribute>(containerValueSymbol,
 537                                new Attribute.Array(arrayOfOrigAnnoType, repeated));
 538             if (ctx.isTypeCompound) {
 539                 /* TODO: the following code would be cleaner:
 540                 Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p),
 541                         ((Attribute.TypeCompound)annotations.head).position);
 542                 JCTypeAnnotation annoTree = m.TypeAnnotation(at);
 543                 at = enterTypeAnnotation(annoTree, targetContainerType, ctx.env);
 544                 */
 545                 // However, we directly construct the TypeCompound to keep the
 546                 // direct relation to the contained TypeCompounds.
 547                 Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p),
 548                         ((Attribute.TypeCompound)annotations.head).position);
 549 
 550                 // TODO: annotation applicability checks from below?
 551 
 552                 at.setSynthesized(true);
 553 
 554                 @SuppressWarnings("unchecked")
 555                 T x = (T) at;
 556                 return x;
 557             } else {
 558                 Attribute.Compound c = new Attribute.Compound(targetContainerType, List.of(p));


 559                 JCAnnotation annoTree = m.Annotation(c);
 560 
 561                 if (!chk.annotationApplicable(annoTree, on))
 562                     log.error(annoTree.pos(), "invalid.repeatable.annotation.incompatible.target", targetContainerType, origAnnoType);
 563 
 564                 if (!chk.validateAnnotationDeferErrors(annoTree))
 565                     log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType);
 566 
 567                 c = enterAnnotation(annoTree, targetContainerType, ctx.env);
 568                 c.setSynthesized(true);
 569 
 570                 @SuppressWarnings("unchecked")
 571                 T x = (T) c;
 572                 return x;
 573             }
 574         } else {
 575             return null; // errors should have been reported elsewhere
 576         }
 577     }
 578 

 579     /** Fetches the actual Type that should be the containing annotation. */
 580     private Type getContainingType(Attribute.Compound currentAnno,
 581             DiagnosticPosition pos,
 582             boolean reportError)
 583     {
 584         Type origAnnoType = currentAnno.type;
 585         TypeSymbol origAnnoDecl = origAnnoType.tsym;
 586 
 587         // Fetch the Repeatable annotation from the current
 588         // annotation's declaration, or null if it has none
 589         Attribute.Compound ca = origAnnoDecl.attribute(syms.repeatableType.tsym);
 590         if (ca == null) { // has no Repeatable annotation
 591             if (reportError)
 592                 log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.repeatableType);
 593             return null;
 594         }
 595 
 596         return filterSame(extractContainingType(ca, pos, origAnnoDecl),
 597                           origAnnoType);
 598     }


 693                       targetContainerType,
 694                       valueRetType,
 695                       expectedType);
 696             fatalError = true;
 697         }
 698         if (error) {
 699             fatalError = true;
 700         }
 701 
 702         // The conditions for a valid containing annotation are made
 703         // in Check.validateRepeatedAnnotaton();
 704 
 705         return fatalError ? null : containerValueSymbol;
 706     }
 707 
 708     private <T extends Attribute.Compound> AnnotationContext<T>
 709             prepareEnterAnnotations(List<JCAnnotation> annotations,
 710                                     Env<AttrContext> env,
 711                                     Symbol sym,
 712                                     AttributeCreator<T> creator,
 713                                     boolean isTypeCompound) {

 714         Map<TypeSymbol, ListBuffer<T>> annotated = new LinkedHashMap<>();
 715         Map<T, DiagnosticPosition> pos = new HashMap<>();
 716 
 717         for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
 718             JCAnnotation a = al.head;
 719             T c = creator.create(a, syms.annotationType, env);
 720 
 721             Assert.checkNonNull(c, "Failed to create annotation");
 722 
 723             if (annotated.containsKey(a.type.tsym)) {
 724                 if (!allowRepeatedAnnos) {
 725                     log.error(a.pos(), "repeatable.annotations.not.supported.in.source");
 726                     allowRepeatedAnnos = true;
 727                 }
 728                 ListBuffer<T> l = annotated.get(a.type.tsym);
 729                 l = l.append(c);
 730                 annotated.put(a.type.tsym, l);
 731                 pos.put(c, a.pos());
 732             } else {
 733                 annotated.put(a.type.tsym, ListBuffer.of(c));
 734                 pos.put(c, a.pos());
 735             }
 736 
 737             // Note: @Deprecated has no effect on local variables and parameters
 738             if (!c.type.isErroneous()
 739                 && sym.owner.kind != MTH
 740                 && types.isSameType(c.type, syms.deprecatedType)) {
 741                 sym.flags_field |= Flags.DEPRECATED;
 742             }
 743         }
 744 
 745         return new AnnotationContext<>(env, annotated, pos,
 746                                              isTypeCompound);
 747     }
 748 
 749     // Gather up annotations into a map from type symbols to lists of
 750     // Compound attributes, then continue on with repeating
 751     // annotations processing
 752     private <T extends Attribute.Compound>
 753             void attachAttributesLater(final List<JCAnnotation> annotations,
 754                                        final Env<AttrContext> env,
 755                                        final Symbol sym,
 756                                        final boolean isTypeCompound,

 757                                        final AttributeCreator<T> creator,
 758                                        final AttributeAttacher<T> attacher) {
 759         final AnnotationContext<T> ctx =
 760             prepareEnterAnnotations(annotations, env, sym, creator, isTypeCompound);

 761         final Map<Symbol.TypeSymbol, ListBuffer<T>> annotated =
 762             ctx.annotated;
 763         boolean hasRepeated = false;
 764 
 765         List<T> buf = List.<T>nil();
 766         for (ListBuffer<T> lb : annotated.values()) {
 767             if (lb.size() == 1) {
 768                 buf = buf.prepend(lb.first());
 769             } else {
 770                 @SuppressWarnings("unchecked")
 771                 T res = (T) new Placeholder<>(ctx, lb.toList(), sym);
 772                 buf = buf.prepend(res);
 773                 hasRepeated = true;
 774             }
 775         }
 776 
 777         final List<T> attrs = buf.reverse();
 778 
 779         if (!isTypeCompound) {
 780             // Attach declaration attributes early, so
 781             // that @Repeatable and other annotations get attached.
 782             // Since the attacher uses setDeclarationAttributes, this
 783             // will be overwritten later.
 784             attacher.attach(sym, attrs);


 785         }

 786         if (hasRepeated) {












 787             repeated(new Annotate.Worker() {
 788                     @Override
 789                     public String toString() {
 790                         return "repeated annotation pass of: " + sym + " in: " + sym.owner;
 791                     }
 792 
 793                     @Override
 794                     public void run() {
 795                         JavaFileObject oldSource =
 796                             log.useSource(env.toplevel.sourcefile);
 797                         try {
 798                             attacher.attach(sym, replacePlaceholders(attrs, ctx, sym));


 799                         } finally {
 800                             log.useSource(oldSource);
 801                         }
 802                     }
 803                 });



















































































































 804         } else {
 805             attacher.attach(sym, attrs);
 806         }
 807     }
 808 
 809     private interface AttributeAttacher<T extends Attribute.Compound> {
 810         public void attach(Symbol sym, List<T> attrs);

 811     }
 812 
 813     private final AttributeAttacher<Attribute.Compound> declAnnotationsAttacher =
 814         new AttributeAttacher<Attribute.Compound>() {








 815             @Override
 816             public void attach(Symbol sym, List<Attribute.Compound> attrs) {
 817                 sym.resetAnnotations();
 818                 sym.setDeclarationAttributes(attrs);
 819             }
 820         };

 821 
 822     private final AttributeAttacher<Attribute.TypeCompound> typeAnnotationsAttacher =
 823         new AttributeAttacher<Attribute.TypeCompound>() {

 824             @Override
 825             public void attach(Symbol sym, List<Attribute.TypeCompound> attrs) {
 826                 sym.appendUniqueTypeAttributes(attrs);


 827             }
 828         };











































































































 829 
 830     private <T extends Attribute.Compound> List<T>
 831             replacePlaceholders(List<T> buf,
 832                                 Annotate.AnnotationContext<T> ctx,
 833                                 Symbol sym) {
 834         List<T> result = List.nil();
 835         for (T a : buf) {
 836             if (a instanceof Placeholder) {
 837                 @SuppressWarnings("unchecked")
 838                     T replacement = replaceOne((Placeholder<T>) a, ctx, sym);
 839 
 840                 if (null != replacement) {
 841                     result = result.prepend(replacement);
 842                 }
 843             } else {
 844                 result = result.prepend(a);
 845             }
 846         }
 847 
 848         return result.reverse();
 849     }
 850 
 851     private <T extends Attribute.Compound> T replaceOne(Placeholder<T> placeholder,
 852                                                         Annotate.AnnotationContext<T> ctx,
 853                                                         Symbol sym) {
 854         // Process repeated annotations
 855         T validRepeated =
 856             processRepeatedAnnotations(placeholder.getPlaceholderFor(),
 857                                        ctx, sym);
 858 
 859         if (validRepeated != null) {
 860             // Check that the container isn't manually
 861             // present along with repeated instances of
 862             // its contained annotation.
 863             ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym);
 864             if (manualContainer != null) {
 865                 log.error(ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present",
 866                         manualContainer.first().type.tsym);
 867             }
 868         }
 869 
 870         // A null return will delete the Placeholder
 871         return validRepeated;
 872     }
 873 
 874 /* ********************************************************************
 875  * Annotation processing
 876  *********************************************************************/
 877 
 878     /** Queue annotations for later processing. */





 879     void annotateLater(final List<JCAnnotation> annotations,
 880                        final Env<AttrContext> localEnv,
 881                        final Symbol s,
 882                        final DiagnosticPosition deferPos) {



















 883         if (annotations.isEmpty()) {
 884             return;
 885         }
 886         if (s.kind != PCK) {
 887             s.resetAnnotations(); // mark Annotations as incomplete for now
 888         }
 889         normal(new Annotate.Worker() {
 890                 @Override
 891                 public String toString() {
 892                     return "annotate " + annotations + " onto " + s + " in " + s.owner;
 893                 }
 894 
 895                 @Override
 896                 public void run() {

















 897                     Assert.check(s.kind == PCK || s.annotationsPendingCompletion());
 898                     JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
 899                     DiagnosticPosition prevLintPos =
 900                         deferPos != null
 901                         ? deferredLintHandler.setPos(deferPos)
 902                         : deferredLintHandler.immediate();
 903                     Lint prevLint = deferPos != null ? null : chk.setLint(lint);
 904                     try {
 905                         if (s.hasAnnotations() &&
 906                             annotations.nonEmpty())
 907                             log.error(annotations.head.pos,
 908                                       "already.annotated",
 909                                       kindName(s), s);
 910                         actualEnterAnnotations(annotations, localEnv, s);
 911                     } finally {
 912                         if (prevLint != null)
 913                             chk.setLint(prevLint);
 914                         deferredLintHandler.setPos(prevLintPos);
 915                         log.useSource(prev);
 916                     }
 917                 }
 918             });
 919 
 920         validate(new Annotate.Worker() { //validate annotations



 921             @Override
 922             public void run() {
 923                 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
 924                 try {
 925                     chk.validateAnnotations(annotations, s);
 926                 } finally {
 927                     log.useSource(prev);
 928                 }
 929             }
 930         });
















 931     }
 932 
 933     private interface AttributeCreator<T extends Attribute.Compound> {
 934         public T create(JCAnnotation a, Type expected, Env<AttrContext> env);



 935     }
 936 
 937     // TODO: When SE8 features can be used, these can go away and be
 938     // replaced by method refs.
 939     private final AttributeCreator<Attribute.Compound> enterAnnotationsCreator =
 940         new AttributeCreator<Attribute.Compound>() {
 941         @Override
 942         public Attribute.Compound create(JCAnnotation a,
 943                                          Type expected,
 944                                          Env<AttrContext> env) {
 945             return enterAnnotation(a, syms.annotationType, env);

 946         }
 947     };
 948     private final AttributeCreator<Attribute.TypeCompound> enterTypeAnnotationsCreator =
 949         new AttributeCreator<Attribute.TypeCompound>() {
 950         @Override
 951         public Attribute.TypeCompound create(JCAnnotation a,
 952                                              Type expected,
 953                                              Env<AttrContext> env) {
 954             return enterTypeAnnotation(a, syms.annotationType, env);

 955         }
 956     };
 957 
 958     /** Enter a set of annotations. */
 959     private void actualEnterAnnotations(List<JCAnnotation> annotations,
 960                                         Env<AttrContext> env,
 961                                         Symbol s) {
 962         Assert.checkNonNull(s, "Symbol argument to actualEnterAnnotations is null");
 963         attachAttributesLater(annotations, env, s, false,
 964                               enterAnnotationsCreator,
 965                               declAnnotationsAttacher);

 966     }
 967 
 968     /*
 969      * If the symbol is non-null, attach the type annotation to it.
 970      */
 971     private void actualEnterTypeAnnotations(final List<JCAnnotation> annotations,
 972                                             final Env<AttrContext> env,
 973                                             final Symbol s,
 974                                             final DiagnosticPosition deferPos) {
 975         Assert.checkNonNull(s, "Symbol argument to actualEnterTypeAnnotations is nul/");


 976         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
 977         DiagnosticPosition prevLintPos = null;
 978 
 979         if (deferPos != null) {
 980             prevLintPos = deferredLintHandler.setPos(deferPos);
 981         }
 982         try {
 983             attachAttributesLater(annotations, env, s, true,
 984                                   enterTypeAnnotationsCreator,
 985                                   typeAnnotationsAttacher);
 986         } finally {
 987             if (prevLintPos != null)
 988                 deferredLintHandler.setPos(prevLintPos);
 989             log.useSource(prev);
 990         }
 991     }
 992 
 993     public void annotateTypeLater(final JCTree tree,
 994                                   final Env<AttrContext> env,
 995                                   final Symbol sym,
 996                                   final DiagnosticPosition deferPos) {















 997         Assert.checkNonNull(sym);



 998         normal(new Annotate.Worker() {
 999                 @Override
1000                 public String toString() {
1001                     return "type annotate " + tree + " onto " + sym + " in " + sym.owner;
1002                 }
1003                 @Override
1004                 public void run() {
1005                     tree.accept(new TypeAnnotate(env, sym, deferPos));





1006                 }
1007             });
1008     }
1009 
1010     /**
1011      * We need to use a TreeScanner, because it is not enough to visit the top-level
1012      * annotations. We also need to visit type arguments, etc.


1013      */












































































































































































































































































































































1014     private class TypeAnnotate extends TreeScanner {
1015         private final Env<AttrContext> env;








1016         private final Symbol sym;
1017         private DiagnosticPosition deferPos;


1018 
1019         public TypeAnnotate(final Env<AttrContext> env,
1020                             final Symbol sym,
1021                             final DiagnosticPosition deferPos) {
1022 
1023             this.env = env;




1024             this.sym = sym;

1025             this.deferPos = deferPos;












































































































1026         }
1027 
1028         @Override
1029         public void visitAnnotatedType(final JCAnnotatedType tree) {
1030             actualEnterTypeAnnotations(tree.annotations, env, sym, deferPos);
1031             super.visitAnnotatedType(tree);


1032         }
1033 
1034         @Override
1035         public void visitTypeParameter(final JCTypeParameter tree) {
1036             actualEnterTypeAnnotations(tree.annotations, env, sym, deferPos);
1037             super.visitTypeParameter(tree);



















































1038         }
1039 
1040         @Override
1041         public void visitNewArray(final JCNewArray tree) {
1042             actualEnterTypeAnnotations(tree.annotations, env, sym, deferPos);
1043             for (List<JCAnnotation> dimAnnos : tree.dimAnnotations)
1044                 actualEnterTypeAnnotations(dimAnnos, env, sym, deferPos);
1045             super.visitNewArray(tree);
1046         }
1047 
1048         @Override
1049         public void visitMethodDef(final JCMethodDecl tree) {
1050             scan(tree.mods);
1051             scan(tree.restype);
1052             scan(tree.typarams);
1053             scan(tree.recvparam);
1054             scan(tree.params);
1055             scan(tree.thrown);
1056             scan(tree.defaultValue);
1057             // Do not annotate the body, just the signature.
1058             // scan(tree.body);
1059         }
1060 
1061         @Override
1062         public void visitVarDef(final JCVariableDecl tree) {
1063             DiagnosticPosition prevPos = deferPos;
1064             deferPos = tree.pos();
1065             try {
1066                 if (sym != null && sym.kind == Kinds.VAR) {
1067                     // Don't visit a parameter once when the sym is the method
1068                     // and once when the sym is the parameter.
1069                     scan(tree.mods);
1070                     scan(tree.vartype);
1071                 }
1072                 scan(tree.init);
1073             } finally {
1074                 deferPos = prevPos;
1075             }





































1076         }
1077 
1078         @Override
1079         public void visitClassDef(JCClassDecl tree) {
1080             // We can only hit a classdef if it is declared within
1081             // a method. Ignore it - the class will be visited
1082             // separately later.
1083         }
1084 
1085         @Override
1086         public void visitNewClass(JCNewClass tree) {
1087             if (tree.def == null) {
1088                 // For an anonymous class instantiation the class
1089                 // will be visited separately.
1090                 super.visitNewClass(tree);
1091             }
1092         }
















































1093     }
1094 }


  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.comp;
  27 
  28 import java.util.HashMap;
  29 import java.util.LinkedHashMap;
  30 import java.util.Map;
  31 
  32 import javax.lang.model.type.TypeKind;
  33 import javax.tools.JavaFileObject;
  34 
  35 import com.sun.tools.javac.util.*;
  36 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
  37 import com.sun.tools.javac.code.*;
  38 import com.sun.tools.javac.code.Symbol.*;
  39 import com.sun.tools.javac.code.TypeAnnotationPosition.*;
  40 import com.sun.tools.javac.tree.*;
  41 import com.sun.tools.javac.tree.JCTree.*;
  42 
  43 import static com.sun.tools.javac.code.Kinds.*;
  44 import static com.sun.tools.javac.code.TypeTag.ARRAY;
  45 import static com.sun.tools.javac.code.TypeTag.CLASS;
  46 import static com.sun.tools.javac.tree.JCTree.Tag.*;
  47 
  48 /** Enter annotations on symbols.  Annotations accumulate in a queue,
  49  *  which is processed at the top level of any set of recursive calls
  50  *  requesting it be processed.
  51  *
  52  *  <p><b>This is NOT part of any supported API.
  53  *  If you write code that depends on this, you do so at your own risk.
  54  *  This code and its internal interfaces are subject to change or
  55  *  deletion without notice.</b>
  56  */
  57 public class Annotate {
  58     protected static final Context.Key<Annotate> annotateKey = new Context.Key<>();
  59 


 250         public List<T> getPlaceholderFor() {
 251             return placeholderFor;
 252         }
 253 
 254         public Annotate.AnnotationContext<T> getRepeatedContext() {
 255             return ctx;
 256         }
 257     }
 258 
 259 
 260 /* ********************************************************************
 261  * Compute an attribute from its annotation.
 262  *********************************************************************/
 263 
 264     /** Process a single compound annotation, returning its
 265      *  Attribute. Used from MemberEnter for attaching the attributes
 266      *  to the annotated symbol.
 267      */
 268     Attribute.Compound enterAnnotation(JCAnnotation a,
 269                                        Type expected,
 270                                        Env<AttrContext> env,
 271                                        TypeAnnotationPosition position) {
 272         List<Pair<MethodSymbol,Attribute>> buf =
 273             enterAttributeValues(a, expected, env, position);
 274         Attribute.Compound ac =
 275             new Attribute.Compound(a.type, buf, position);
 276         a.attribute = ac;
 277 
 278         return ac;
 279     }
 280 
 281     Attribute.TypeCompound enterTypeAnnotation(JCAnnotation a,
 282                                                Type expected,
 283                                                Env<AttrContext> env,
 284                                                TypeAnnotationPosition position) {
 285         List<Pair<MethodSymbol,Attribute>> buf =
 286             enterAttributeValues(a, expected, env, position);
 287 
 288         if (a.attribute == null || !(a.attribute instanceof Attribute.TypeCompound)) {
 289             // Create a new TypeCompound

 290             Attribute.TypeCompound tc =
 291                 new Attribute.TypeCompound(a.type, buf, position);




 292             a.attribute = tc;
 293             return tc;
 294         } else {
 295             // Use an existing TypeCompound
 296             return (Attribute.TypeCompound)a.attribute;
 297         }
 298     }
 299 
 300     private List<Pair<MethodSymbol,Attribute>>
 301             enterAttributeValues(JCAnnotation a,
 302                                  Type expected,
 303                                  Env<AttrContext> env,
 304                                  TypeAnnotationPosition position) {
 305         // The annotation might have had its type attributed (but not
 306         // checked) by attr.attribAnnotationTypes during MemberEnter,
 307         // in which case we do not need to do it again.
 308         Type at = (a.annotationType.type != null ? a.annotationType.type
 309                   : attr.attribType(a.annotationType, env));
 310         a.type = chk.checkType(a.annotationType.pos(), at, expected);
 311         boolean isError = a.type.isErroneous();
 312         if ((a.type.tsym.flags() & Flags.ANNOTATION) == 0 && !isError) {
 313             log.error(a.annotationType.pos(),
 314                       "not.annotation.type", a.type.toString());
 315             isError = true;
 316         }
 317         List<JCExpression> args = a.args;
 318         if (args.length() == 1 && !args.head.hasTag(ASSIGN)) {
 319             // special case: elided "value=" assumed
 320             args.head = make.at(args.head.pos).
 321                 Assign(make.Ident(names.value), args.head);
 322         }
 323         ListBuffer<Pair<MethodSymbol,Attribute>> buf =
 324             new ListBuffer<>();
 325         for (List<JCExpression> tl = args; tl.nonEmpty(); tl = tl.tail) {
 326             JCExpression t = tl.head;
 327             if (!t.hasTag(ASSIGN)) {
 328                 log.error(t.pos(), "annotation.value.must.be.name.value");
 329                 enterAttributeValue(t.type = syms.errType, t, env, position);
 330                 continue;
 331             }
 332             JCAssign assign = (JCAssign)t;
 333             if (!assign.lhs.hasTag(IDENT)) {
 334                 log.error(t.pos(), "annotation.value.must.be.name.value");
 335                 enterAttributeValue(t.type = syms.errType, t, env, position);
 336                 continue;
 337             }
 338             JCIdent left = (JCIdent)assign.lhs;
 339             Symbol method = rs.resolveQualifiedMethod(assign.rhs.pos(),
 340                                                           env,
 341                                                           a.type,
 342                                                           left.name,
 343                                                           List.<Type>nil(),
 344                                                           null);
 345             left.sym = method;
 346             left.type = method.type;
 347             if (method.owner != a.type.tsym && !isError)
 348                 log.error(left.pos(), "no.annotation.member", left.name, a.type);
 349             Type result = method.type.getReturnType();
 350             Attribute value = enterAttributeValue(result, assign.rhs, env, position);
 351             if (!method.type.isErroneous())
 352                 buf.append(new Pair<>((MethodSymbol)method, value));
 353             t.type = result;
 354         }
 355         return buf.toList();
 356     }
 357 
 358     Attribute enterAttributeValue(Type expected,
 359                                   JCExpression tree,
 360                                   Env<AttrContext> env,
 361                                   TypeAnnotationPosition position) {
 362         //first, try completing the attribution value sym - if a completion
 363         //error is thrown, we should recover gracefully, and display an
 364         //ordinary resolution diagnostic.
 365         try {
 366             expected.tsym.complete();
 367         } catch(CompletionFailure e) {
 368             log.error(tree.pos(), "cant.resolve", Kinds.kindName(e.sym), e.sym);
 369             expected = syms.errType;
 370         }
 371         if (expected.hasTag(ARRAY)) {
 372             if (!tree.hasTag(NEWARRAY)) {
 373                 tree = make.at(tree.pos).
 374                     NewArray(null, List.<JCExpression>nil(), List.of(tree));
 375             }
 376             JCNewArray na = (JCNewArray)tree;
 377             if (na.elemtype != null) {
 378                 log.error(na.elemtype.pos(), "new.not.allowed.in.annotation");
 379             }
 380             ListBuffer<Attribute> buf = new ListBuffer<>();
 381             for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) {
 382                 buf.append(enterAttributeValue(types.elemtype(expected),
 383                                                l.head, env, position));

 384             }
 385             na.type = expected;
 386             return new Attribute.
 387                 Array(expected, buf.toArray(new Attribute[buf.length()]));
 388         }
 389         if (tree.hasTag(NEWARRAY)) { //error recovery
 390             if (!expected.isErroneous())
 391                 log.error(tree.pos(), "annotation.value.not.allowable.type");
 392             JCNewArray na = (JCNewArray)tree;
 393             if (na.elemtype != null) {
 394                 log.error(na.elemtype.pos(), "new.not.allowed.in.annotation");
 395             }
 396             for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) {
 397                 enterAttributeValue(syms.errType, l.head, env, position);


 398             }
 399             return new Attribute.Error(syms.errType);
 400         }
 401         if ((expected.tsym.flags() & Flags.ANNOTATION) != 0) {
 402             if (tree.hasTag(ANNOTATION)) {
 403                 return enterAnnotation((JCAnnotation)tree, expected, env, position);
 404             } else {
 405                 log.error(tree.pos(), "annotation.value.must.be.annotation");
 406                 expected = syms.errType;
 407             }
 408         }
 409         if (tree.hasTag(ANNOTATION)) { //error recovery
 410             if (!expected.isErroneous())
 411                 log.error(tree.pos(), "annotation.not.valid.for.type", expected);
 412             enterAnnotation((JCAnnotation)tree, syms.errType, env, position);
 413             return new Attribute.Error(((JCAnnotation)tree).annotationType.type);
 414         }
 415         if (expected.isPrimitive() ||
 416             (types.isSameType(expected, syms.stringType) && !expected.hasTag(TypeTag.ERROR))) {
 417             Type result = attr.attribExpr(tree, env, expected);
 418             if (result.isErroneous())
 419                 return new Attribute.Error(result.getOriginalType());
 420             if (result.constValue() == null) {
 421                 log.error(tree.pos(), "attribute.value.must.be.constant");
 422                 return new Attribute.Error(expected);
 423             }
 424             result = cfolder.coerce(result, expected);
 425             return new Attribute.Constant(expected, result.constValue());
 426         }
 427         if (expected.tsym == syms.classType.tsym) {
 428             Type result = attr.attribExpr(tree, env, expected);
 429             if (result.isErroneous()) {
 430                 // Does it look like an unresolved class literal?
 431                 if (TreeInfo.name(tree) == names._class &&
 432                     ((JCFieldAccess) tree).selected.type.isErroneous()) {


 461             }
 462             VarSymbol enumerator = (VarSymbol) sym;
 463             return new Attribute.Enum(expected, enumerator);
 464         }
 465         //error recovery:
 466         if (!expected.isErroneous())
 467             log.error(tree.pos(), "annotation.value.not.allowable.type");
 468         return new Attribute.Error(attr.attribExpr(tree, env, expected));
 469     }
 470 
 471     /* *********************************
 472      * Support for repeating annotations
 473      ***********************************/
 474 
 475     /* Process repeated annotations. This method returns the
 476      * synthesized container annotation or null IFF all repeating
 477      * annotation are invalid.  This method reports errors/warnings.
 478      */
 479     private <T extends Attribute.Compound> T processRepeatedAnnotations(List<T> annotations,
 480             AnnotationContext<T> ctx,
 481             Symbol on,
 482             TypeAnnotationPosition position) {
 483         T firstOccurrence = annotations.head;
 484         List<Attribute> repeated = List.nil();
 485         Type origAnnoType = null;
 486         Type arrayOfOrigAnnoType = null;
 487         Type targetContainerType = null;
 488         MethodSymbol containerValueSymbol = null;
 489 
 490         Assert.check(!annotations.isEmpty() &&
 491                      !annotations.tail.isEmpty()); // i.e. size() > 1
 492 
 493         int count = 0;
 494         for (List<T> al = annotations; !al.isEmpty(); al = al.tail) {



 495             count++;

 496             // There must be more than a single anno in the annotation list
 497             Assert.check(count > 1 || !al.tail.isEmpty());
 498 
 499             T currentAnno = al.head;
 500 
 501             origAnnoType = currentAnno.type;
 502             if (arrayOfOrigAnnoType == null) {
 503                 arrayOfOrigAnnoType = types.makeArrayType(origAnnoType);
 504             }
 505 
 506             // Only report errors if this isn't the first occurrence I.E. count > 1
 507             boolean reportError = count > 1;
 508             Type currentContainerType = getContainingType(currentAnno, ctx.pos.get(currentAnno), reportError);
 509             if (currentContainerType == null) {
 510                 continue;
 511             }
 512             // Assert that the target Container is == for all repeated
 513             // annos of the same annotation type, the types should
 514             // come from the same Symbol, i.e. be '=='
 515             Assert.check(targetContainerType == null || currentContainerType == targetContainerType);
 516             targetContainerType = currentContainerType;
 517 
 518             containerValueSymbol = validateContainer(targetContainerType, origAnnoType, ctx.pos.get(currentAnno));
 519 
 520             if (containerValueSymbol == null) { // Check of CA type failed
 521                 // errors are already reported
 522                 continue;
 523             }
 524 
 525             repeated = repeated.prepend(currentAnno);
 526         }
 527 
 528         if (!repeated.isEmpty()) {
 529             repeated = repeated.reverse();
 530             TreeMaker m = make.at(ctx.pos.get(firstOccurrence));
 531             Pair<MethodSymbol, Attribute> p =
 532                     new Pair<MethodSymbol, Attribute>(containerValueSymbol,
 533                                new Attribute.Array(arrayOfOrigAnnoType, repeated));
 534             if (ctx.isTypeCompound) {
 535                 Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p), position);












 536                 at.setSynthesized(true);
 537 
 538                 @SuppressWarnings("unchecked")
 539                 T x = (T) at;
 540                 return x;
 541             } else {
 542                 Attribute.Compound c = new Attribute.Compound(targetContainerType,
 543                                                               List.of(p),
 544                                                               position);
 545                 JCAnnotation annoTree = m.Annotation(c);
 546 
 547                 if (!chk.annotationApplicable(annoTree, on))
 548                     log.error(annoTree.pos(), "invalid.repeatable.annotation.incompatible.target", targetContainerType, origAnnoType);
 549 
 550                 if (!chk.validateAnnotationDeferErrors(annoTree))
 551                     log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType);
 552 
 553                 c = enterAnnotation(annoTree, targetContainerType, ctx.env, position);
 554                 c.setSynthesized(true);
 555 
 556                 @SuppressWarnings("unchecked")
 557                 T x = (T) c;
 558                 return x;
 559             }
 560         } else {
 561             return null; // errors should have been reported elsewhere
 562         }
 563     }
 564 
 565 
 566     /** Fetches the actual Type that should be the containing annotation. */
 567     private Type getContainingType(Attribute.Compound currentAnno,
 568             DiagnosticPosition pos,
 569             boolean reportError)
 570     {
 571         Type origAnnoType = currentAnno.type;
 572         TypeSymbol origAnnoDecl = origAnnoType.tsym;
 573 
 574         // Fetch the Repeatable annotation from the current
 575         // annotation's declaration, or null if it has none
 576         Attribute.Compound ca = origAnnoDecl.attribute(syms.repeatableType.tsym);
 577         if (ca == null) { // has no Repeatable annotation
 578             if (reportError)
 579                 log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.repeatableType);
 580             return null;
 581         }
 582 
 583         return filterSame(extractContainingType(ca, pos, origAnnoDecl),
 584                           origAnnoType);
 585     }


 680                       targetContainerType,
 681                       valueRetType,
 682                       expectedType);
 683             fatalError = true;
 684         }
 685         if (error) {
 686             fatalError = true;
 687         }
 688 
 689         // The conditions for a valid containing annotation are made
 690         // in Check.validateRepeatedAnnotaton();
 691 
 692         return fatalError ? null : containerValueSymbol;
 693     }
 694 
 695     private <T extends Attribute.Compound> AnnotationContext<T>
 696             prepareEnterAnnotations(List<JCAnnotation> annotations,
 697                                     Env<AttrContext> env,
 698                                     Symbol sym,
 699                                     AttributeCreator<T> creator,
 700                                     boolean isTypeCompound,
 701                                     TypeAnnotationPosition position) {
 702         Map<TypeSymbol, ListBuffer<T>> annotated = new LinkedHashMap<>();
 703         Map<T, DiagnosticPosition> pos = new HashMap<>();
 704 
 705         for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
 706             JCAnnotation a = al.head;
 707             T c = creator.create(a, syms.annotationType, env, position);
 708 
 709             Assert.checkNonNull(c, "Failed to create annotation");
 710 
 711             if (annotated.containsKey(a.type.tsym)) {
 712                 if (!allowRepeatedAnnos) {
 713                     log.error(a.pos(), "repeatable.annotations.not.supported.in.source");
 714                     allowRepeatedAnnos = true;
 715                 }
 716                 ListBuffer<T> l = annotated.get(a.type.tsym);
 717                 l = l.append(c);
 718                 annotated.put(a.type.tsym, l);
 719                 pos.put(c, a.pos());
 720             } else {
 721                 annotated.put(a.type.tsym, ListBuffer.of(c));
 722                 pos.put(c, a.pos());
 723             }
 724 
 725             // Note: @Deprecated has no effect on local variables and parameters
 726             if (!c.type.isErroneous()
 727                 && sym.owner.kind != MTH
 728                 && types.isSameType(c.type, syms.deprecatedType)) {
 729                 sym.flags_field |= Flags.DEPRECATED;
 730             }
 731         }
 732 
 733         return new AnnotationContext<>(env, annotated, pos,
 734                                        isTypeCompound);
 735     }
 736 
 737     // Gather up annotations into a map from type symbols to lists of
 738     // Compound attributes, then continue on with repeating
 739     // annotations processing
 740     private <T extends Attribute.Compound>
 741             void attachAttributesLater(final List<JCAnnotation> annotations,
 742                                        final Env<AttrContext> env,
 743                                        final Symbol sym,
 744                                        final boolean isTypeCompound,
 745                                        final TypeAnnotationPosition position,
 746                                        final AttributeCreator<T> creator,
 747                                        final AttributeAttacher<T> attacher) {
 748         final AnnotationContext<T> ctx =
 749             prepareEnterAnnotations(annotations, env, sym, creator,
 750                                     isTypeCompound, position);
 751         final Map<Symbol.TypeSymbol, ListBuffer<T>> annotated =
 752             ctx.annotated;
 753         boolean hasRepeated = false;
 754 
 755         List<T> buf = List.<T>nil();
 756         for (ListBuffer<T> lb : annotated.values()) {
 757             if (lb.size() == 1) {
 758                 buf = buf.prepend(lb.first());
 759             } else {
 760                 @SuppressWarnings("unchecked")
 761                 T res = (T) new Placeholder<>(ctx, lb.toList(), sym);
 762                 buf = buf.prepend(res);
 763                 hasRepeated = true;
 764             }
 765         }
 766 
 767         final List<T> attrs = buf.reverse();
 768 
 769         if (!isTypeCompound) {
 770             // Attach declaration attributes early, so
 771             // that @Repeatable and other annotations get attached.
 772             // Since the attacher uses setDeclarationAttributes, this
 773             // will be overwritten later.
 774             @SuppressWarnings("unchecked")
 775             List<Attribute.Compound> tempattrs = (List<Attribute.Compound>) attrs;
 776             sym.setDeclarationAttributes(tempattrs);
 777         }
 778 
 779         if (hasRepeated) {
 780             replacePlaceholdersAndAttach(attrs, ctx, env, sym, attacher);
 781         } else {
 782             attachAttributesAfterRepeated(attrs, env, attacher);
 783         }
 784     }
 785 
 786     private <T extends Attribute.Compound>
 787             void replacePlaceholdersAndAttach(final List<T> attrs,
 788                                               final AnnotationContext<T> ctx,
 789                                               final Env<AttrContext> env,
 790                                               final Symbol sym,
 791                                               final AttributeAttacher<T> attacher) {
 792         repeated(new Annotate.Worker() {
 793                 @Override
 794                 public String toString() {
 795                     return "repeated annotation pass of: " + sym + " in: " + sym.owner;
 796                 }
 797 
 798                 @Override
 799                 public void run() {
 800                     JavaFileObject oldSource =
 801                         log.useSource(env.toplevel.sourcefile);
 802                     try {
 803                         final List<T> replaced =
 804                             replacePlaceholders(attrs, ctx, sym);
 805                         attachAttributesAfterRepeated(replaced, env, attacher);
 806                     } finally {
 807                         log.useSource(oldSource);
 808                     }
 809                 }
 810             });
 811     }
 812 
 813     private <T extends Attribute.Compound>
 814             void attachAttributesAfterRepeated(final List<T> attrs,
 815                                                final Env<AttrContext> env,
 816                                                final AttributeAttacher<T> attacher) {
 817         afterRepeated(new Worker() {
 818                 @Override
 819                 public String toString() {
 820                     return "attach pass for: " + attrs;
 821                 }
 822 
 823                 @Override
 824                 public void run() {
 825                     JavaFileObject oldSource =
 826                         log.useSource(env.toplevel.sourcefile);
 827                     try {
 828                         attacher.attach(attrs);
 829                     } finally {
 830                         log.useSource(oldSource);
 831                     }
 832                 }
 833             });
 834     }
 835 
 836     public interface AttributeAttacher<T extends Attribute.Compound> {
 837         public void attach(List<T> attrs);
 838     }
 839 
 840     public interface Reporter<T extends Attribute.Compound> {
 841         public void report(List<T> attrs);
 842     }
 843 
 844     public enum AnnotationType { DECLARATION, TYPE, BOTH }
 845 
 846     /**
 847      * Determine whether an annotation is a declaration annotation,
 848      * a type annotation, or both.
 849      */
 850     public AnnotationType annotationType(Attribute.Compound a, Symbol s) {
 851         Attribute.Compound atTarget =
 852             a.type.tsym.attribute(syms.annotationTargetType.tsym);
 853         if (atTarget == null) {
 854             return inferTargetMetaInfo(a, s);
 855         }
 856         Attribute atValue = atTarget.member(names.value);
 857         if (!(atValue instanceof Attribute.Array)) {
 858             Assert.error("annotationType(): bad @Target argument " + atValue +
 859                     " (" + atValue.getClass() + ")");
 860             return AnnotationType.DECLARATION; // error recovery
 861         }
 862         Attribute.Array arr = (Attribute.Array) atValue;
 863         boolean isDecl = false, isType = false;
 864         for (Attribute app : arr.values) {
 865             if (!(app instanceof Attribute.Enum)) {
 866                 Assert.error("annotationType(): unrecognized Attribute kind " + app +
 867                         " (" + app.getClass() + ")");
 868                 isDecl = true;
 869                 continue;
 870             }
 871             Attribute.Enum e = (Attribute.Enum) app;
 872             if (e.value.name == names.TYPE) {
 873                 if (s.kind == Kinds.TYP)
 874                     isDecl = true;
 875             } else if (e.value.name == names.FIELD) {
 876                 if (s.kind == Kinds.VAR &&
 877                         s.owner.kind != Kinds.MTH)
 878                     isDecl = true;
 879             } else if (e.value.name == names.METHOD) {
 880                 if (s.kind == Kinds.MTH &&
 881                         !s.isConstructor())
 882                     isDecl = true;
 883             } else if (e.value.name == names.PARAMETER) {
 884                 if (s.kind == Kinds.VAR &&
 885                         s.owner.kind == Kinds.MTH &&
 886                         (s.flags() & Flags.PARAMETER) != 0)
 887                     isDecl = true;
 888             } else if (e.value.name == names.CONSTRUCTOR) {
 889                 if (s.kind == Kinds.MTH &&
 890                         s.isConstructor())
 891                     isDecl = true;
 892             } else if (e.value.name == names.LOCAL_VARIABLE) {
 893                 if (s.kind == Kinds.VAR &&
 894                         s.owner.kind == Kinds.MTH &&
 895                         (s.flags() & Flags.PARAMETER) == 0)
 896                     isDecl = true;
 897             } else if (e.value.name == names.ANNOTATION_TYPE) {
 898                 if (s.kind == Kinds.TYP &&
 899                         (s.flags() & Flags.ANNOTATION) != 0)
 900                     isDecl = true;
 901             } else if (e.value.name == names.PACKAGE) {
 902                 if (s.kind == Kinds.PCK)
 903                     isDecl = true;
 904             } else if (e.value.name == names.TYPE_USE) {
 905                 if (s.kind == Kinds.TYP ||
 906                     s.kind == Kinds.VAR ||
 907                     (s.kind == Kinds.MTH && !s.isConstructor() &&
 908                      !s.type.getReturnType().hasTag(TypeTag.VOID)) ||
 909                     (s.kind == Kinds.MTH && s.isConstructor()))
 910                     isType = true;
 911             } else if (e.value.name == names.TYPE_PARAMETER) {
 912                 /* Irrelevant in this case */
 913                 // TYPE_PARAMETER doesn't aid in distinguishing between
 914                 // Type annotations and declaration annotations on an
 915                 // Element
 916             } else {
 917                 Assert.error("annotationType(): unrecognized Attribute name " + e.value.name +
 918                         " (" + e.value.name.getClass() + ")");
 919                 isDecl = true;
 920             }
 921         }
 922         if (isDecl && isType) {
 923             return AnnotationType.BOTH;
 924         } else if (isType) {
 925             return AnnotationType.TYPE;
 926         } else {
 927             return AnnotationType.DECLARATION;
 928         }
 929     }
 930 
 931     private Attribute.TypeCompound toTypeCompound(Attribute.Compound a) {
 932         // It is safe to alias the position.
 933         return new Attribute.TypeCompound(a, a.position);
 934     }
 935 
 936     /** Infer the target annotation kind, if none is given.
 937      * We only infer declaration annotations.
 938      */
 939     private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) {
 940         return AnnotationType.DECLARATION;
 941     }
 942 
 943     private AttributeAttacher<Attribute.Compound>
 944             declAnnotationsAttacher(final Symbol sym) {
 945         return new AttributeAttacher<Attribute.Compound>() {
 946             @Override
 947             public void attach(List<Attribute.Compound> attrs) {
 948                 sym.resetAnnotations();
 949                 sym.setDeclarationAttributes(attrs);
 950             }
 951         };
 952     }
 953 
 954     private AttributeAttacher<Attribute.TypeCompound>
 955             typeAnnotationsAttacher(final Symbol sym) {
 956         return new AttributeAttacher<Attribute.TypeCompound>() {
 957             @Override
 958             public void attach(List<Attribute.TypeCompound> attrs) {
 959                 if (!attrs.isEmpty()) {
 960                     attachTypeAnnotations(sym, attrs);
 961                 }
 962             }
 963         };
 964     }
 965 
 966     private void reportIllegalScoping(List<Attribute.TypeCompound> attrs,
 967                                       int pos) {
 968         switch (attrs.size()) {
 969         case 0:
 970             // Don't issue an error if all type annotations are
 971             // also declaration annotations.
 972             // If the annotations are also declaration annotations, they are
 973             // illegal as type annotations but might be legal as declaration annotations.
 974             // The normal declaration annotation checks make sure that the use is valid.
 975             break;
 976         case 1:
 977             //System.err.println("Reporting illegal scoping");
 978             log.error(pos, "cant.type.annotate.scoping.1", attrs);
 979             break;
 980         default:
 981             //System.err.println("Reporting illegal scoping");
 982             log.error(pos, "cant.type.annotate.scoping", attrs);
 983         }
 984     }
 985 
 986     private Reporter<Attribute.TypeCompound>
 987             illegalScopingReporter(final int pos) {
 988         return new Reporter<Attribute.TypeCompound>() {
 989             @Override
 990             public void report(List<Attribute.TypeCompound> attrs) {
 991                 reportIllegalScoping(attrs, pos);
 992             }
 993         };
 994     }
 995 
 996     private AttributeAttacher<Attribute.Compound>
 997             classifyingAttacher(final Symbol sym) {
 998         return classifyingAttacher(sym, declAnnotationsAttacher(sym),
 999                                    typeAnnotationsAttacher(sym),
1000                                    null);
1001     }
1002 
1003 
1004     private AttributeAttacher<Attribute.Compound>
1005             classifyingAttacher(final Symbol sym,
1006                                 final AttributeAttacher<Attribute.Compound> declAttacher,
1007                                 final AttributeAttacher<Attribute.TypeCompound> typeAttacher,
1008                                 final Reporter<Attribute.TypeCompound> reporter) {
1009         return new AttributeAttacher<Attribute.Compound>() {
1010             @Override
1011             public void attach(List<Attribute.Compound> attrs) {
1012                 ListBuffer<Attribute.Compound> declAnnos = new ListBuffer<>();
1013                 ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<>();
1014                 ListBuffer<Attribute.TypeCompound> onlyTypeAnnos = new ListBuffer<>();
1015 
1016                 for (Attribute.Compound a : attrs) {
1017                     Assert.check(!(a instanceof Placeholder),
1018                                  "Placeholders found in annotations being attached!");
1019                     switch (annotationType(a, sym)) {
1020                     case DECLARATION:
1021                         declAnnos.append(a);
1022                         break;
1023                     case BOTH: {
1024                         declAnnos.append(a);
1025                         Attribute.TypeCompound ta = toTypeCompound(a);
1026                         Assert.checkNonNull(ta.position);
1027                         typeAnnos.append(ta);
1028                         break;
1029                     }
1030                     case TYPE: {
1031                         Attribute.TypeCompound ta = toTypeCompound(a);
1032                         Assert.checkNonNull(ta.position);
1033                         typeAnnos.append(ta);
1034                         // Also keep track which annotations are only type annotations
1035                         onlyTypeAnnos.append(ta);
1036                         break;
1037                     }
1038                     default:
1039                         throw new AssertionError("Unknown annotation type");
1040                     }
1041                 }
1042 
1043                 if (declAttacher != null)
1044                     declAttacher.attach(declAnnos.toList());
1045 
1046                 if (typeAttacher != null)
1047                     typeAttacher.attach(typeAnnos.toList());
1048 
1049                 if (reporter != null)
1050                     reporter.report(onlyTypeAnnos.toList());
1051             }
1052         };
1053     }
1054 
1055     public void attachTypeAnnotations(Symbol sym, List<Attribute.TypeCompound> attrs) {
1056         sym.appendUniqueTypeAttributes(attrs);
1057 
1058         // For type annotations on variables in methods, make
1059         // sure they are attached to the owner too.
1060         switch(sym.getKind()) {
1061         case PARAMETER:
1062         case LOCAL_VARIABLE:
1063         case RESOURCE_VARIABLE:
1064         case EXCEPTION_PARAMETER:
1065             // Make sure all type annotations from the symbol are also
1066             // on the owner.
1067             sym.owner.appendUniqueTypeAttributes(attrs);
1068             break;
1069         }
1070     }
1071 
1072     private <T extends Attribute.Compound> List<T>
1073             replacePlaceholders(List<T> buf,
1074                                 Annotate.AnnotationContext<T> ctx,
1075                                 Symbol sym) {
1076         List<T> result = List.nil();
1077         for (T a : buf) {
1078             if (a instanceof Placeholder) {
1079                 @SuppressWarnings("unchecked")
1080                 T replacement = replaceOne((Placeholder<T>) a, ctx, sym);
1081 
1082                 if (null != replacement) {
1083                     result = result.prepend(replacement);
1084                 }
1085             } else {
1086                 result = result.prepend(a);
1087             }
1088         }
1089 
1090         return result.reverse();
1091     }
1092 
1093     private <T extends Attribute.Compound> T replaceOne(Placeholder<T> placeholder,
1094                                                         Annotate.AnnotationContext<T> ctx,
1095                                                         Symbol sym) {
1096         // Process repeated annotations
1097         T validRepeated =
1098             processRepeatedAnnotations(placeholder.getPlaceholderFor(),
1099                                        ctx, sym, placeholder.position);
1100 
1101         if (validRepeated != null) {
1102             // Check that the container isn't manually
1103             // present along with repeated instances of
1104             // its contained annotation.
1105             ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym);
1106             if (manualContainer != null) {
1107                 log.error(ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present",
1108                         manualContainer.first().type.tsym);
1109             }
1110         }
1111 
1112         // A null return will delete the Placeholder
1113         return validRepeated;
1114     }
1115 
1116 /* ********************************************************************
1117  * Annotation processing
1118  *********************************************************************/
1119 
1120     void annotateLater(final List<JCAnnotation> annotations,
1121                        final Env<AttrContext> localEnv,
1122                        final Symbol s) {
1123         annotateLater(annotations, localEnv, s, null);
1124     }
1125 
1126     void annotateLater(final List<JCAnnotation> annotations,
1127                        final Env<AttrContext> localEnv,
1128                        final Symbol s,
1129                        final DiagnosticPosition deferPos) {
1130         annotateLater(annotations, localEnv, s, deferPos, null,
1131                       declAnnotationsAttacher(s));
1132     }
1133 
1134     void annotateLater(final List<JCAnnotation> annotations,
1135                        final Env<AttrContext> localEnv,
1136                        final Symbol s,
1137                        final DiagnosticPosition deferPos,
1138                        final TypeAnnotationPosition tapos) {
1139         annotateLater(annotations, localEnv, s, deferPos, tapos,
1140                       classifyingAttacher(s));
1141     }
1142 
1143     void annotateLater(final List<JCAnnotation> annotations,
1144                        final Env<AttrContext> localEnv,
1145                        final Symbol s,
1146                        final DiagnosticPosition deferPos,
1147                        final TypeAnnotationPosition tapos,
1148                        final AttributeAttacher<Attribute.Compound> attacher) {
1149         if (annotations.isEmpty()) {
1150             return;
1151         }
1152         if (s.kind != PCK) {
1153             s.resetAnnotations(); // mark Annotations as incomplete for now
1154         }
1155         normal(new Annotate.Worker() {
1156                 @Override
1157                 public String toString() {
1158                     return "annotate " + annotations + " onto " + s + " in " + s.owner;
1159                 }
1160 
1161                 @Override
1162                 public void run() {
1163                     annotateNow(annotations, localEnv, s, deferPos,
1164                                 tapos, attacher);
1165                 }
1166             });
1167 
1168         validate(annotationValidator(annotations, localEnv, s));
1169     }
1170 
1171     private void annotateNow(final List<JCAnnotation> annotations,
1172                              final Env<AttrContext> localEnv,
1173                              final Symbol s,
1174                              final DiagnosticPosition deferPos,
1175                              final TypeAnnotationPosition position,
1176                              final AttributeAttacher<Attribute.Compound> attacher) {
1177         if (annotations.isEmpty()) {
1178             return;
1179         }
1180         Assert.check(s.kind == PCK || s.annotationsPendingCompletion());
1181         JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
1182         DiagnosticPosition prevLintPos = deferPos != null ?
1183             deferredLintHandler.setPos(deferPos) :
1184             deferredLintHandler.immediate();

1185         Lint prevLint = deferPos != null ? null : chk.setLint(lint);
1186         try {
1187             if (s.hasAnnotations() &&
1188                 annotations.nonEmpty())
1189                 log.error(annotations.head.pos,
1190                           "already.annotated",
1191                           kindName(s), s);
1192             actualEnterAnnotations(annotations, localEnv, s, position, attacher);
1193         } finally {
1194             if (prevLint != null)
1195                 chk.setLint(prevLint);
1196             deferredLintHandler.setPos(prevLintPos);
1197             log.useSource(prev);
1198         }
1199     }

1200 
1201     private Annotate.Worker annotationValidator(final List<JCAnnotation> annotations,
1202                                                 final Env<AttrContext> localEnv,
1203                                                 final Symbol s) {
1204         return new Annotate.Worker() { //validate annotations
1205             @Override
1206             public void run() {
1207                 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
1208                 try {
1209                     chk.validateAnnotations(annotations, s);
1210                 } finally {
1211                     log.useSource(prev);
1212                 }
1213             }
1214         };
1215     }
1216 
1217     private Annotate.Worker typeAnnotationValidator(final List<JCAnnotation> annotations,
1218                                                     final Env<AttrContext> localEnv,
1219                                                     final boolean isTypeParameter) {
1220         return new Annotate.Worker() { //validate annotations
1221             @Override
1222             public void run() {
1223                 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
1224                 try {
1225                     chk.validateTypeAnnotations(annotations, isTypeParameter);
1226                 } finally {
1227                     log.useSource(prev);
1228                 }
1229             }
1230         };
1231     }
1232 
1233     private interface AttributeCreator<T extends Attribute.Compound> {
1234         public T create(JCAnnotation a,
1235                         Type expected,
1236                         Env<AttrContext> env,
1237                         TypeAnnotationPosition position);
1238     }
1239 
1240     // TODO: When SE8 features can be used, these can go away and be
1241     // replaced by method refs.
1242     private final AttributeCreator<Attribute.Compound> enterAnnotationsCreator =
1243         new AttributeCreator<Attribute.Compound>() {
1244         @Override
1245         public Attribute.Compound create(JCAnnotation a,
1246                                          Type expected,
1247                                          Env<AttrContext> env,
1248                                          TypeAnnotationPosition position) {
1249             return enterAnnotation(a, syms.annotationType, env, position);
1250         }
1251     };
1252     private final AttributeCreator<Attribute.TypeCompound> enterTypeAnnotationsCreator =
1253         new AttributeCreator<Attribute.TypeCompound>() {
1254         @Override
1255         public Attribute.TypeCompound create(JCAnnotation a,
1256                                              Type expected,
1257                                              Env<AttrContext> env,
1258                                              TypeAnnotationPosition position) {
1259             return enterTypeAnnotation(a, syms.annotationType, env, position);
1260         }
1261     };
1262 
1263     /** Enter a set of annotations. */
1264     private void actualEnterAnnotations(List<JCAnnotation> annotations,
1265                                         Env<AttrContext> env,
1266                                         Symbol s,
1267                                         TypeAnnotationPosition position,
1268                                         AttributeAttacher<Attribute.Compound> attacher) {
1269         Assert.checkNonNull(s);
1270         attachAttributesLater(annotations, env, s, false, position,
1271                               enterAnnotationsCreator, attacher);
1272     }
1273 
1274     /*
1275      * If the symbol is non-null, attach the type annotation to it.
1276      */
1277     private void actualEnterTypeAnnotations(final List<JCAnnotation> annotations,
1278                                             final Env<AttrContext> env,
1279                                             final Symbol s,
1280                                             final DiagnosticPosition deferPos,
1281                                             final TypeAnnotationPosition position,
1282                                             final AttributeAttacher<Attribute.TypeCompound> attacher) {
1283         Assert.checkNonNull(s);
1284         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
1285         DiagnosticPosition prevLintPos = null;
1286 
1287         if (deferPos != null) {
1288             prevLintPos = deferredLintHandler.setPos(deferPos);
1289         }
1290         try {
1291             attachAttributesLater(annotations, env, s, true, position,
1292                                   enterTypeAnnotationsCreator, attacher);

1293         } finally {
1294             if (prevLintPos != null)
1295                 deferredLintHandler.setPos(prevLintPos);
1296             log.useSource(prev);
1297         }
1298     }
1299 
1300     public void annotateTypeLater(final JCTree tree,
1301                                   final Env<AttrContext> env,
1302                                   final Symbol sym,
1303                                   final DiagnosticPosition deferPos,
1304                                   final JCLambda currentLambda,
1305                                   final PositionCreator creator,
1306                                   final boolean speculative) {
1307         annotateTypeLater(tree, List.<JCAnnotation>nil(), env, sym,
1308                           deferPos, currentLambda, creator, speculative);
1309     }
1310 
1311     public void annotateTypeLater(final JCTree tree,
1312                                   final List<JCAnnotation> declAnnos,
1313                                   final Env<AttrContext> env,
1314                                   final Symbol sym,
1315                                   final DiagnosticPosition deferPos,
1316                                   final JCLambda currentLambda,
1317                                   final PositionCreator creator,
1318                                   final boolean speculative) {
1319         Assert.checkNonNull(sym);
1320         Assert.checkNonNull(declAnnos);
1321         Assert.checkNonNull(creator);
1322 
1323         normal(new Annotate.Worker() {
1324                 @Override
1325                 public String toString() {
1326                     return "type annotate " + tree + " onto " + sym + " in " + sym.owner;
1327                 }
1328                 @Override
1329                 public void run() {
1330                     if (!declAnnos.isEmpty()) {
1331                         sym.resetAnnotations(); // mark Annotations as incomplete for now
1332                     }
1333 
1334                     tree.accept(typeAnnotater(declAnnos, sym, env, deferPos,
1335                                               currentLambda, creator, speculative));
1336                 }
1337             });
1338     }
1339 
1340     /**
1341      * A client passed into various visitors that takes a type path as
1342      * an argument and performs an action (typically creating a
1343      * TypeAnnotationPosition and then creating a {@code Worker} and
1344      * adding it to a queue.
1345      */
1346     public abstract class PositionCreator {
1347         public TypeAnnotationPosition create() {
1348             return create(List.<TypePathEntry>nil(), null, 0);
1349         }
1350 
1351         public TypeAnnotationPosition createNonNull(List<TypePathEntry> path,
1352                                                     JCLambda lambda,
1353                                                     int typeIndex) {
1354             final TypeAnnotationPosition out = create(path, lambda, typeIndex);
1355 
1356             if (out != null)
1357                 return out;
1358             else
1359                 throw new AssertionError("No annotation creator registered");
1360         }
1361 
1362         public abstract TypeAnnotationPosition create(List<TypePathEntry> path,
1363                                                       JCLambda lambda,
1364                                                       int typeIndex);
1365     }
1366 
1367     // For when we don't have a creator.  Creates null.
1368     public final PositionCreator noCreator =
1369         new PositionCreator() {
1370             @Override
1371             public TypeAnnotationPosition create(List<TypePathEntry> path,
1372                                                  JCLambda lambda,
1373                                                  int typeIndex) {
1374                 return null;
1375             }
1376         };
1377 
1378     // Create class extension positions
1379     public final PositionCreator extendsCreator =
1380         new PositionCreator() {
1381             @Override
1382             public TypeAnnotationPosition create(List<TypePathEntry> path,
1383                                                  JCLambda lambda,
1384                                                  int typeIndex) {
1385                 return TypeAnnotationPosition.classExtends(path, lambda, -1);
1386             }
1387         };
1388 
1389     // Create interface implementation positions
1390     public PositionCreator implementsCreator(final int idx) {
1391         return new PositionCreator() {
1392             @Override
1393             public TypeAnnotationPosition create(List<TypePathEntry> path,
1394                                                  JCLambda lambda,
1395                                                  int typeIndex) {
1396                 return TypeAnnotationPosition.classExtends(path, lambda, idx, -1);
1397             }
1398         };
1399     }
1400 
1401     // Create method parameter positions
1402     public final PositionCreator paramCreator(final int idx) {
1403         return new PositionCreator() {
1404             @Override
1405             public TypeAnnotationPosition create(List<TypePathEntry> path,
1406                                                  JCLambda lambda,
1407                                                  int typeIndex) {
1408                 return TypeAnnotationPosition.methodParameter(path, lambda, idx, -1);
1409             }
1410         };
1411     }
1412 
1413     // Create class type parameter positions
1414     public PositionCreator typeParamCreator(final int idx) {
1415         return new PositionCreator() {
1416             @Override
1417             public TypeAnnotationPosition create(List<TypePathEntry> path,
1418                                                  JCLambda lambda,
1419                                                  int typeIndex) {
1420                 return TypeAnnotationPosition.typeParameter(path, lambda, idx, -1);
1421             }
1422         };
1423     }
1424 
1425     public PositionCreator typeParamBoundCreator(final JCTypeParameter typaram,
1426                                                  final int param_idx,
1427                                                  final int bound_idx) {
1428         return new PositionCreator() {
1429             @Override
1430             public TypeAnnotationPosition create(List<TypePathEntry> path,
1431                                                  JCLambda lambda,
1432                                                  int typeIndex) {
1433                 final int real_bound_idx =
1434                     typaram.bounds.head.type.isInterface() ? bound_idx + 1 : bound_idx;
1435                 return TypeAnnotationPosition
1436                     .typeParameterBound(path, lambda, param_idx, real_bound_idx, -1);
1437             }
1438         };
1439     }
1440 
1441     // Create field positions
1442     public final PositionCreator fieldCreator = 
1443         new PositionCreator() {
1444             @Override
1445             public TypeAnnotationPosition create(List<TypePathEntry> path,
1446                                                  JCLambda lambda,
1447                                                  int typeIndex) {
1448                 return TypeAnnotationPosition.field(path, lambda, -1);
1449             }
1450         };
1451 
1452     // Create local variable positions
1453     public PositionCreator localVarCreator(final int pos) {
1454         return new PositionCreator() {
1455             @Override
1456             public TypeAnnotationPosition create(List<TypePathEntry> path,
1457                                                  JCLambda lambda,
1458                                                  int typeIndex) {
1459                 return TypeAnnotationPosition.localVariable(path, lambda, pos);
1460             }
1461         };
1462     }
1463 
1464     public PositionCreator resourceVarCreator(final int pos) {
1465         return new PositionCreator() {
1466             @Override
1467             public TypeAnnotationPosition create(List<TypePathEntry> path,
1468                                                  JCLambda lambda,
1469                                                  int typeIndex) {
1470                 return TypeAnnotationPosition.resourceVariable(path, lambda, pos);
1471             }
1472         };
1473     }
1474 
1475     public PositionCreator exceptionParamCreator(final int pos) {
1476         return new PositionCreator() {
1477             @Override
1478             public TypeAnnotationPosition create(List<TypePathEntry> path,
1479                                                  JCLambda lambda,
1480                                                  int typeIndex) {
1481                 return TypeAnnotationPosition.exceptionParameter(path, lambda,
1482                                                                  typeIndex, pos);
1483             }
1484         };
1485     }
1486 
1487     public PositionCreator methodTypeParamCreator(final int idx) {
1488         return new PositionCreator() {
1489             @Override
1490             public TypeAnnotationPosition create(List<TypePathEntry> path,
1491                                                  JCLambda lambda,
1492                                                  int typeIndex) {
1493                 return TypeAnnotationPosition.methodTypeParameter(path, lambda, idx, -1);
1494             }
1495         };
1496     }
1497 
1498     public PositionCreator methodRefTypeArgCreator(final int idx,
1499                                                    final int pos) {
1500         return new PositionCreator() {
1501             @Override
1502             public TypeAnnotationPosition create(List<TypePathEntry> path,
1503                                                  JCLambda lambda,
1504                                                  int typeIndex) {
1505                 return TypeAnnotationPosition.methodRefTypeArg(path, lambda, idx, pos);
1506             }
1507         };
1508     }
1509 
1510     public PositionCreator constructorRefTypeArgCreator(final int idx,
1511                                                         final int pos) {
1512         return new PositionCreator() {
1513             @Override
1514             public TypeAnnotationPosition create(List<TypePathEntry> path,
1515                                                  JCLambda lambda,
1516                                                  int typeIndex) {
1517                 return TypeAnnotationPosition
1518                     .constructorRefTypeArg(path, lambda, idx, pos);
1519             }
1520         };
1521     }
1522 
1523     public PositionCreator methodInvokeTypeArgCreator(final int idx,
1524                                                       final int pos) {
1525         return new PositionCreator() {
1526             @Override
1527             public TypeAnnotationPosition create(List<TypePathEntry> path,
1528                                                  JCLambda lambda,
1529                                                  int typeIndex) {
1530                 return TypeAnnotationPosition.methodInvocationTypeArg(path, lambda, idx, pos);
1531             }
1532         };
1533     }
1534 
1535     public PositionCreator constructorInvokeTypeArgCreator(final int idx,
1536                                                            final int pos) {
1537         return new PositionCreator() {
1538             @Override
1539             public TypeAnnotationPosition create(List<TypePathEntry> path,
1540                                                  JCLambda lambda,
1541                                                  int typeIndex) {
1542                 return TypeAnnotationPosition.constructorInvocationTypeArg(path, lambda, idx, pos);
1543             }
1544         };
1545     }
1546 
1547     public PositionCreator methodTypeParamBoundCreator(final JCTypeParameter typaram,
1548                                                        final int param_idx,
1549                                                        final int bound_idx) {
1550         return new PositionCreator() {
1551             @Override
1552             public TypeAnnotationPosition create(List<TypePathEntry> path,
1553                                                  JCLambda lambda,
1554                                                  int typeIndex) {
1555                 final int real_bound_idx =
1556                     typaram.bounds.head.type.isInterface() ? bound_idx + 1 : bound_idx;
1557                 return TypeAnnotationPosition
1558                     .methodTypeParameterBound(path, lambda, param_idx, real_bound_idx, -1);
1559             }
1560         };
1561     }
1562 
1563     public PositionCreator throwCreator(final int idx) {
1564         return new PositionCreator() {
1565             @Override
1566             public TypeAnnotationPosition create(List<TypePathEntry> path,
1567                                                  JCLambda lambda,
1568                                                  int typeIndex) {
1569                 return TypeAnnotationPosition.methodThrows(path, lambda, idx, -1);
1570             }
1571         };
1572     }
1573 
1574     public final PositionCreator returnCreator =
1575         new PositionCreator() {
1576             @Override
1577             public TypeAnnotationPosition create(List<TypePathEntry> path,
1578                                                  JCLambda lambda,
1579                                                  int typeIndex) {
1580                 return TypeAnnotationPosition.methodReturn(path, lambda, -1);
1581             }
1582         };
1583 
1584     public PositionCreator receiverCreator =
1585         new PositionCreator() {
1586             @Override
1587             public TypeAnnotationPosition create(List<TypePathEntry> path,
1588                                                  JCLambda lambda,
1589                                                  int typeIndex) {
1590                 return TypeAnnotationPosition.methodReceiver(path, lambda, -1);
1591             }
1592         };
1593 
1594     public PositionCreator methodRefCreator(final int pos) {
1595         return new PositionCreator() {
1596             @Override
1597             public TypeAnnotationPosition create(List<TypePathEntry> path,
1598                                                  JCLambda lambda,
1599                                                  int typeIndex) {
1600                 return TypeAnnotationPosition.methodRef(path, lambda, pos);
1601             }
1602         };
1603     }
1604 
1605     public PositionCreator constructorRefCreator(final int pos) {
1606         return new PositionCreator() {
1607             @Override
1608             public TypeAnnotationPosition create(List<TypePathEntry> path,
1609                                                  JCLambda lambda,
1610                                                  int typeIndex) {
1611                 return TypeAnnotationPosition.constructorRef(path, lambda, pos);
1612             }
1613         };
1614     }
1615 
1616     public PositionCreator instanceOfCreator(final int pos) {
1617         return new PositionCreator() {
1618             @Override
1619             public TypeAnnotationPosition create(List<TypePathEntry> path,
1620                                                  JCLambda lambda,
1621                                                  int typeIndex) {
1622                 return TypeAnnotationPosition.instanceOf(path, lambda, pos);
1623             }
1624         };
1625     }
1626 
1627     public PositionCreator newObjCreator(final int pos) {
1628         return new PositionCreator() {
1629             @Override
1630             public TypeAnnotationPosition create(List<TypePathEntry> path,
1631                                                  JCLambda lambda,
1632                                                  int typeIndex) {
1633                 return TypeAnnotationPosition.newObj(path, lambda, pos);
1634             }
1635         };
1636     }
1637 
1638     public PositionCreator castCreator(final int pos) {
1639         return new PositionCreator() {
1640             @Override
1641             public TypeAnnotationPosition create(List<TypePathEntry> path,
1642                                                  JCLambda lambda,
1643                                                  int typeIndex) {
1644                 return TypeAnnotationPosition.typeCast(path, lambda, typeIndex, pos);
1645             }
1646         };
1647     }
1648 
1649     private static List<TypePathEntry> addInners(Type type,
1650                                                  List<TypePathEntry> typepath) {
1651         Type encl = type.getEnclosingType();
1652         while (encl != null && encl.getKind() != TypeKind.NONE &&
1653                encl.getKind() != TypeKind.ERROR) {
1654             typepath = typepath.append(TypePathEntry.INNER_TYPE);
1655             encl = encl.getEnclosingType();
1656         }
1657         return typepath;
1658     }
1659 
1660     public TypeAnnotate typeAnnotater(final List<JCAnnotation> declAnnos,
1661                                       final Symbol sym,
1662                                       final Env<AttrContext> env,
1663                                       final DiagnosticPosition deferPos,
1664                                       final JCLambda currentLambda,
1665                                       final PositionCreator creator,
1666                                       final boolean speculative) {
1667         if (!speculative) {
1668             return new TypeAnnotate(declAnnos, sym, env, deferPos,
1669                                     currentLambda, creator,
1670                                     declAnnotationsAttacher(sym),
1671                                     typeAnnotationsAttacher(sym));
1672         } else {
1673             return new TypeAnnotate(declAnnos, sym, env, deferPos,
1674                                     currentLambda, creator, null, null);
1675         }
1676     }
1677 
1678     private class TypeAnnotate extends TreeScanner {
1679         protected PositionCreator creator;
1680         private List<TypePathEntry> typepath = List.nil();
1681         private JCLambda currentLambda;
1682         private int type_index = 0;
1683         private boolean innermost;
1684         // These attachers are for declaration annotations
1685         private AttributeAttacher<Attribute.Compound> declAttacher;
1686         private AttributeAttacher<Attribute.TypeCompound> typeAttacher;
1687         private Reporter<Attribute.TypeCompound> reporter;
1688         private final Symbol sym;
1689         private final DiagnosticPosition deferPos;
1690         private final Env<AttrContext> env;
1691         private final List<JCAnnotation> declAnnos;
1692 
1693         public TypeAnnotate(final List<JCAnnotation> declAnnos,
1694                             final Symbol sym,
1695                             final Env<AttrContext> env,
1696                             final DiagnosticPosition deferPos,
1697                             final JCLambda currentLambda,
1698                             final PositionCreator creator,
1699                             final AttributeAttacher<Attribute.Compound> declAttacher,
1700                             final AttributeAttacher<Attribute.TypeCompound> typeAttacher) {
1701             this.declAnnos = declAnnos;
1702             this.sym = sym;
1703             this.env = env;
1704             this.deferPos = deferPos;
1705             this.currentLambda = currentLambda;
1706             this.creator = creator;
1707             this.innermost = true;
1708             this.declAttacher = declAttacher;
1709             this.typeAttacher = typeAttacher;
1710             this.reporter = null;
1711         }
1712 
1713         private void doDeclAnnos() {
1714             if (!declAnnos.isEmpty()) {
1715                 final TypeAnnotationPosition tapos =
1716                     creator.createNonNull(typepath, currentLambda, type_index);
1717                 annotateNow(declAnnos, env, sym, deferPos, tapos,
1718                             classifyingAttacher(sym, declAttacher,
1719                                                 typeAttacher, reporter));
1720                 validate(annotationValidator(declAnnos, env, sym));
1721             }
1722         }
1723 
1724         private void doTypeAnnos(List<JCAnnotation> annos,
1725                                  boolean isTypeParameter) {
1726             if (!annos.isEmpty()) {
1727                 final AttributeAttacher<Attribute.TypeCompound> currTypeAttacher = typeAttacher;
1728                 final Reporter<Attribute.TypeCompound> currReporter = reporter;
1729                 final AttributeAttacher<Attribute.TypeCompound> attacher =
1730                     new AttributeAttacher<Attribute.TypeCompound>() {
1731                     @Override
1732                     public void attach(List<Attribute.TypeCompound> attrs) {
1733                         if (currTypeAttacher != null)
1734                             currTypeAttacher.attach(attrs);
1735                         if (currReporter != null)
1736                             currReporter.report(attrs);
1737                     }
1738                 };
1739                 final TypeAnnotationPosition tapos =
1740                     creator.createNonNull(typepath, currentLambda, type_index);
1741                 actualEnterTypeAnnotations(annos, env, sym, deferPos, tapos,
1742                                            attacher);
1743                 validate(typeAnnotationValidator(annos, env, isTypeParameter));
1744             }
1745         }
1746 
1747         @Override
1748         public void visitTypeIdent(final JCPrimitiveTypeTree tree) {
1749             if (innermost) {
1750                 final AttributeAttacher<Attribute.TypeCompound> oldTypeAttacher = typeAttacher;
1751                 typeAttacher =
1752                     new AttributeAttacher<Attribute.TypeCompound>() {
1753                         @Override
1754                         public void attach(List<Attribute.TypeCompound> attrs) {
1755                             if (null != oldTypeAttacher)
1756                                 oldTypeAttacher.attach(attrs);
1757 
1758                             if (!attrs.isEmpty()) {
1759                                 tree.type = tree.type.annotatedType(attrs);
1760                             }
1761                         }
1762                     };
1763                 doDeclAnnos();
1764                 typeAttacher = oldTypeAttacher;
1765             }
1766         }
1767 
1768         @Override
1769         public void visitIdent(final JCIdent tree) {
1770             if (innermost) {
1771                 final AttributeAttacher<Attribute.TypeCompound> oldTypeAttacher = typeAttacher;
1772                 final Reporter<Attribute.TypeCompound> oldReporter = reporter;
1773                 typeAttacher =
1774                     new AttributeAttacher<Attribute.TypeCompound>() {
1775                         @Override
1776                         public void attach(List<Attribute.TypeCompound> attrs) {
1777                             if (null != oldTypeAttacher)
1778                                 oldTypeAttacher.attach(attrs);
1779 
1780                             if (!attrs.isEmpty() &&
1781                                 !tree.type.hasTag(TypeTag.PACKAGE)) {
1782                                 tree.type = tree.type.annotatedType(attrs);
1783                             }
1784                         }
1785                     };
1786                 if (tree.type != null) {
1787                     final List<TypePathEntry> oldpath = typepath;
1788                     typepath = addInners(tree.type, typepath);
1789                     doDeclAnnos();
1790                     typepath = oldpath;
1791                 } else {
1792                     doDeclAnnos();
1793                 }
1794                 reporter = oldReporter;
1795                 typeAttacher = oldTypeAttacher;
1796             }
1797         }
1798 
1799         @Override
1800         public void visitAnnotatedType(JCAnnotatedType tree) {
1801             Assert.checkNonNull(tree.getUnderlyingType().type);
1802             final boolean oldinnermost = innermost;
1803             innermost = false;
1804             scan(tree.annotations);
1805             innermost = oldinnermost;
1806             scan(tree.underlyingType);
1807             final Reporter<Attribute.TypeCompound> oldReporter = reporter;
1808             final List<TypePathEntry> oldpath = typepath;
1809             typepath = addInners(tree.getUnderlyingType().type, typepath);
1810             doTypeAnnos(tree.annotations, false);
1811             typepath = oldpath;
1812             reporter = oldReporter;
1813         }
1814 
1815         @Override
1816         public void visitTypeArray(JCArrayTypeTree tree) {
1817             final List<TypePathEntry> oldpath = typepath;
1818             typepath = typepath.append(TypePathEntry.ARRAY);
1819             super.visitTypeArray(tree);
1820             typepath = oldpath;
1821         }
1822 
1823         @Override
1824         public void visitTypeApply(JCTypeApply tree) {
1825             Assert.checkNonNull(tree.getType().type);
1826             final List<TypePathEntry> oldpath = typepath;
1827             scan(tree.clazz);
1828 
1829 
1830             if (tree.getType() != null && tree.getType().type != null) {
1831                 typepath = addInners(tree.getType().type, typepath);
1832             }
1833             final boolean oldinnermost = innermost;
1834             innermost = false;
1835             int i = 0;
1836             for (List<JCExpression> l = tree.arguments; l.nonEmpty();
1837                  l = l.tail, i++) {
1838                 final JCExpression arg = l.head;
1839                 final List<TypePathEntry> noargpath = typepath;
1840                 typepath = typepath.append(new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, i));
1841                 scan(arg);
1842                 typepath = noargpath;
1843             }
1844             typepath = oldpath;
1845             innermost = oldinnermost;
1846         }
1847 
1848         @Override
1849         public void visitNewArray(JCNewArray tree) {
1850             final List<TypePathEntry> oldpath = typepath;
1851             final PositionCreator oldcreator = creator;
1852             creator = newObjCreator(tree.pos);
1853             doTypeAnnos(tree.annotations, false);
1854 
1855             for (int i = 0; i < tree.dimAnnotations.size(); i++) {
1856                 final List<JCAnnotation> dimAnnos = tree.dimAnnotations.get(i);
1857                 doTypeAnnos(dimAnnos, false);
1858                 // This is right.  As per the type annotations spec,
1859                 // the first array dimension has no arrays in the type
1860                 // path, the second has one, and so on, and the
1861                 // element type has n for n dimensions.
1862                 typepath = typepath.append(TypePathEntry.ARRAY);
1863             }
1864 
1865             // The element type is sometimes null, in the case of
1866             // array literals.
1867             scan(tree.elemtype);
1868             typepath = oldpath;
1869             creator = oldcreator;
1870         }
1871 
1872         @Override
1873         public void visitWildcard(JCWildcard tree) {
1874             final List<TypePathEntry> oldpath = typepath;
1875             typepath = typepath.append(TypePathEntry.WILDCARD);
1876             super.visitWildcard(tree);
1877             typepath = oldpath;
1878         }
1879 
1880         @Override
1881         public void visitTypeParameter(JCTypeParameter tree) {
1882             scan(tree.annotations);
1883             Assert.checkNonNull(tree.type);
1884             doTypeAnnos(tree.annotations, true);

1885         }
1886 
1887         @Override
1888         public void visitLambda(JCLambda tree) {
1889             final JCLambda oldLambda = currentLambda;
1890             currentLambda = tree;
1891             scan(tree.body);

1892             scan(tree.params);
1893             currentLambda = oldLambda;
1894             


1895         }
1896 
1897         @Override
1898         public void visitTypeIntersection(JCTypeIntersection tree) {
1899             final boolean oldinnermost = innermost;
1900             for (List<JCExpression> l = tree.bounds; l.nonEmpty();
1901                  l = l.tail, type_index++) {
1902                 scan(l.head);
1903                 // Set innermost to false after the first element
1904                 innermost = false;


1905             }
1906             innermost = oldinnermost;


1907         }
1908 
1909         @Override
1910         public void visitTypeUnion(JCTypeUnion tree) {
1911             final boolean oldinnermost = innermost;
1912             for (List<JCExpression> l = tree.alternatives; l.nonEmpty();
1913                  l = l.tail, type_index++) {
1914                 scan(l.head);
1915                 // Set innermost to false after the first element
1916                 innermost = false;
1917             }
1918             innermost = oldinnermost;
1919         }
1920 
1921         @Override
1922         public void visitSelect(JCFieldAccess tree) {
1923             Symbol sym = tree.sym;
1924             //System.err.println("visitSelect " + tree);
1925             final AttributeAttacher<Attribute.TypeCompound> oldTypeAttacher = typeAttacher;
1926             final Reporter<Attribute.TypeCompound> oldReporter = reporter;
1927             // If we're selecting from an interface or a static class,
1928             // set up attachers that will only attach declaration
1929             // annotations and will report type annotations as errors.
1930             Type selectedTy = tree.selected.type;
1931             if (sym != null && (sym.isStatic() || sym.isInterface() ||
1932                                 selectedTy.hasTag(TypeTag.PACKAGE))) {
1933                 typeAttacher = null;
1934                 reporter = illegalScopingReporter(tree.pos);
1935             }
1936             super.visitSelect(tree);
1937             typeAttacher = oldTypeAttacher;
1938             reporter = oldReporter;
1939         }
1940 
1941         // These methods stop the visitor from continuing on when it
1942         // sees a definition.
1943         @Override
1944         public void visitVarDef(final JCVariableDecl tree) {
1945         }
1946 
1947         @Override
1948         public void visitClassDef(JCClassDecl tree) {
1949             // We can only hit a classdef if it is declared within
1950             // a method. Ignore it - the class will be visited
1951             // separately later.
1952         }
1953 
1954         @Override
1955         public void visitNewClass(JCNewClass tree) {
1956             // This will be visited by Attr later, so don't do
1957             // anything.


1958         }
1959     }
1960 
1961     private class TypeAnnotateExpr extends TypeAnnotate {
1962         public TypeAnnotateExpr(final Symbol sym,
1963                                 final Env<AttrContext> env,
1964                                 final DiagnosticPosition deferPos,
1965                                 final JCLambda currentLambda,
1966                                 final PositionCreator creator) {
1967             super(List.<JCAnnotation>nil(), sym, env, deferPos,
1968                   currentLambda, creator, null, null);
1969         }
1970 
1971         @Override
1972         public void visitTypeCast(final JCTypeCast tree) {
1973             final PositionCreator oldcreator = creator;
1974             creator = castCreator(tree.pos);
1975             super.visitTypeCast(tree);
1976             creator = oldcreator;
1977         }
1978 
1979         @Override
1980         public void visitTypeTest(JCInstanceOf tree) {
1981             final PositionCreator oldcreator = creator;
1982             creator = instanceOfCreator(tree.pos);
1983             super.visitTypeTest(tree);
1984             creator = oldcreator;
1985         }
1986     }
1987 
1988     public void typeAnnotateExprLater(final JCTree tree,
1989                                       final Env<AttrContext> env,
1990                                       final Symbol sym,
1991                                       final DiagnosticPosition deferPos,
1992                                       final JCLambda currentLambda,
1993                                       final PositionCreator creator) {
1994         Assert.checkNonNull(sym);
1995         Assert.checkNonNull(creator);
1996 
1997         normal(new Annotate.Worker() {
1998                 @Override
1999                 public String toString() {
2000                     return "type annotate " + tree + " onto " + sym + " in " + sym.owner;
2001                 }
2002                 @Override
2003                 public void run() {
2004                     tree.accept(new TypeAnnotateExpr(sym, env, deferPos,
2005                                                      currentLambda, creator));
2006                 }
2007             });
2008     }
2009 }