Annotate.java revision 2571:10fc81ac75b4
1/* 2 * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.tools.javac.comp; 27 28import java.util.HashMap; 29import java.util.LinkedHashMap; 30import java.util.Map; 31 32import javax.lang.model.element.ElementKind; 33import javax.lang.model.type.TypeKind; 34import javax.tools.JavaFileObject; 35 36import com.sun.tools.javac.util.*; 37import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 38import com.sun.tools.javac.code.*; 39import com.sun.tools.javac.code.Symbol.*; 40import com.sun.tools.javac.code.TypeAnnotationPosition.*; 41import com.sun.tools.javac.tree.*; 42import com.sun.tools.javac.tree.JCTree.*; 43 44import static com.sun.tools.javac.code.Kinds.*; 45import static com.sun.tools.javac.code.TypeTag.ARRAY; 46import static com.sun.tools.javac.code.TypeTag.CLASS; 47import static com.sun.tools.javac.tree.JCTree.Tag.*; 48 49/** Enter annotations on symbols. Annotations accumulate in a queue, 50 * which is processed at the top level of any set of recursive calls 51 * requesting it be processed. 52 * 53 * <p><b>This is NOT part of any supported API. 54 * If you write code that depends on this, you do so at your own risk. 55 * This code and its internal interfaces are subject to change or 56 * deletion without notice.</b> 57 */ 58public class Annotate { 59 protected static final Context.Key<Annotate> annotateKey = new Context.Key<>(); 60 61 public static Annotate instance(Context context) { 62 Annotate instance = context.get(annotateKey); 63 if (instance == null) 64 instance = new Annotate(context); 65 return instance; 66 } 67 68 private final Attr attr; 69 private final TreeMaker make; 70 private final Log log; 71 private final Symtab syms; 72 private final Names names; 73 private final Resolve rs; 74 private final Types types; 75 private final ConstFold cfolder; 76 private final Check chk; 77 private final Lint lint; 78 private final DeferredLintHandler deferredLintHandler; 79 private final Source source; 80 81 private boolean allowTypeAnnos; 82 private boolean allowRepeatedAnnos; 83 84 protected Annotate(Context context) { 85 context.put(annotateKey, this); 86 attr = Attr.instance(context); 87 make = TreeMaker.instance(context); 88 log = Log.instance(context); 89 syms = Symtab.instance(context); 90 names = Names.instance(context); 91 rs = Resolve.instance(context); 92 types = Types.instance(context); 93 cfolder = ConstFold.instance(context); 94 chk = Check.instance(context); 95 source = Source.instance(context); 96 lint = Lint.instance(context); 97 deferredLintHandler = DeferredLintHandler.instance(context); 98 allowRepeatedAnnos = source.allowRepeatedAnnotations(); 99 allowTypeAnnos = source.allowTypeAnnotations(); 100 } 101 102/* ******************************************************************** 103 * Queue maintenance 104 *********************************************************************/ 105 106 private int enterCount = 0; 107 108 ListBuffer<Worker> q = new ListBuffer<>(); 109 ListBuffer<Worker> typesQ = new ListBuffer<>(); 110 ListBuffer<Worker> repeatedQ = new ListBuffer<>(); 111 ListBuffer<Worker> afterRepeatedQ = new ListBuffer<>(); 112 ListBuffer<Worker> validateQ = new ListBuffer<>(); 113 114 public void earlier(Worker a) { 115 q.prepend(a); 116 } 117 118 public void normal(Worker a) { 119 q.append(a); 120 } 121 122 public void typeAnnotation(Worker a) { 123 typesQ.append(a); 124 } 125 126 public void repeated(Worker a) { 127 repeatedQ.append(a); 128 } 129 130 public void afterRepeated(Worker a) { 131 afterRepeatedQ.append(a); 132 } 133 134 public void validate(Worker a) { 135 validateQ.append(a); 136 } 137 138 /** Called when the Enter phase starts. */ 139 public void enterStart() { 140 enterCount++; 141 } 142 143 /** Called after the Enter phase completes. */ 144 public void enterDone() { 145 enterCount--; 146 flush(); 147 } 148 149 /** Variant which allows for a delayed flush of annotations. 150 * Needed by ClassReader */ 151 public void enterDoneWithoutFlush() { 152 enterCount--; 153 } 154 155 public void flush() { 156 if (enterCount != 0) return; 157 enterCount++; 158 try { 159 while (q.nonEmpty()) { 160 q.next().run(); 161 } 162 while (typesQ.nonEmpty()) { 163 typesQ.next().run(); 164 } 165 while (repeatedQ.nonEmpty()) { 166 repeatedQ.next().run(); 167 } 168 while (afterRepeatedQ.nonEmpty()) { 169 afterRepeatedQ.next().run(); 170 } 171 while (validateQ.nonEmpty()) { 172 validateQ.next().run(); 173 } 174 } finally { 175 enterCount--; 176 } 177 } 178 179 /** A client that needs to run during {@link #flush()} registers an worker 180 * into one of the queues defined in this class. The queues are: {@link #earlier(Worker)}, 181 * {@link #normal(Worker)}, {@link #typeAnnotation(Worker)}, {@link #repeated(Worker)}, 182 * {@link #afterRepeated(Worker)}, {@link #validate(Worker)}. 183 * The {@link Worker#run()} method will called inside the {@link #flush()} 184 * call. Queues are empties in the abovementioned order. 185 */ 186 public interface Worker { 187 void run(); 188 String toString(); 189 } 190 191 /** 192 * This context contains all the information needed to synthesize new 193 * annotations trees by the completer for repeating annotations. 194 */ 195 private class AnnotationContext<T extends Attribute.Compound> { 196 public final Env<AttrContext> env; 197 public final Map<Symbol.TypeSymbol, ListBuffer<T>> annotated; 198 public final Map<T, JCDiagnostic.DiagnosticPosition> pos; 199 public final boolean isTypeCompound; 200 201 public AnnotationContext(Env<AttrContext> env, 202 Map<Symbol.TypeSymbol, ListBuffer<T>> annotated, 203 Map<T, JCDiagnostic.DiagnosticPosition> pos, 204 boolean isTypeCompound) { 205 Assert.checkNonNull(env); 206 Assert.checkNonNull(annotated); 207 Assert.checkNonNull(pos); 208 209 this.env = env; 210 this.annotated = annotated; 211 this.pos = pos; 212 this.isTypeCompound = isTypeCompound; 213 } 214 215 public String toString() { 216 StringBuilder sb = new StringBuilder(); 217 sb.append("RepeatedContext["); 218 for (Map.Entry<Symbol.TypeSymbol, ListBuffer<T>> entry : 219 annotated.entrySet()) { 220 sb.append(" "); 221 sb.append(entry.getKey()); 222 sb.append(" = { "); 223 sb.append(entry.getValue()); 224 sb.append(" }"); 225 } 226 sb.append(" ]"); 227 return sb.toString(); 228 } 229 } 230 231 private static class Placeholder<T extends Attribute.Compound> extends Attribute.Compound { 232 233 private final Annotate.AnnotationContext<T> ctx; 234 private final List<T> placeholderFor; 235 private final Symbol on; 236 237 public Placeholder(Annotate.AnnotationContext<T> ctx, 238 List<T> placeholderFor, Symbol on) { 239 super(on.type, List.<Pair<Symbol.MethodSymbol, Attribute>>nil(), 240 placeholderFor.head.position); 241 this.ctx = ctx; 242 this.placeholderFor = placeholderFor; 243 this.on = on; 244 } 245 246 @Override 247 public String toString() { 248 return "<placeholder: " + placeholderFor + " on: " + on + ">"; 249 } 250 251 public List<T> getPlaceholderFor() { 252 return placeholderFor; 253 } 254 255 public Annotate.AnnotationContext<T> getRepeatedContext() { 256 return ctx; 257 } 258 } 259 260 261/* ******************************************************************** 262 * Compute an attribute from its annotation. 263 *********************************************************************/ 264 265 /** 266 * Enter (and attribute) a single regular annotation, returning 267 * its Attribute. We give these annotations a position in case we 268 * end up creating a type annotation from using toTypeCompound. 269 * 270 * In some cases, namely on annotations that can never be type 271 * annotations (like package annotations), the position can be 272 * null; however, if this annotation is in a place where it might 273 * possibly denote a type annotation, it will have a non-null 274 * position. 275 * 276 * @param a Annotation to attribute. 277 * @param expected Expected annotation type. 278 * @param env The environment. 279 * @param position The type annotation position this will have if 280 * it's converted to a type annotation. 281 * @return The Attribute.Compound representing this annotation. 282 */ 283 Attribute.Compound enterAnnotation(JCAnnotation a, 284 Type expected, 285 Env<AttrContext> env, 286 TypeAnnotationPosition position) { 287 List<Pair<MethodSymbol,Attribute>> buf = 288 enterAttributeValues(a, expected, env, position); 289 Attribute.Compound ac = 290 new Attribute.Compound(a.type, buf, position); 291 a.attribute = ac; 292 293 return ac; 294 } 295 296 /** 297 * Enter (and attribute) a single type annotation, returning its 298 * Attribute. 299 * 300 * Things are a bit complicated, though, because a single source 301 * annotation (JCAnnotation) might give rise to several bytecode 302 * annotations (Attribute.TypeCompound), but we can only associate 303 * a source annotation with one bytecode annotation. Thus, we 304 * have to distinguish between the "primary" (which will be stored 305 * to the JCAnnotation) and "secondary" (which won't) annotations. 306 * The primary place this gets used is for anonymous classes. 307 * 308 * The annotations we generate for the new instruction are the 309 * primary, and the ones we generate for the class are the 310 * secondaries. (Note: this choice is arbitrary, and it does not 311 * appear to cause any problems if these roles are reversed) 312 * 313 * @param a The annotation to attribute. 314 * @param expected The expected annotation type. 315 * @param env The environment. 316 * @param position The type annotation position to give the type 317 * annotation. 318 * @param secondaryAttr Whether or not this is a secondary (ie 319 * will ignore the .attribute field on a). 320 * @return The Attribute.TypeCompound representing the annotation. 321 */ 322 Attribute.TypeCompound enterTypeAnnotation(JCAnnotation a, 323 Type expected, 324 Env<AttrContext> env, 325 TypeAnnotationPosition position, 326 boolean secondaryAttr) { 327 List<Pair<MethodSymbol,Attribute>> buf = 328 enterAttributeValues(a, expected, env, position); 329 330 // Secondary attr means we do not set the .attribute field of 331 // the JCAnnotation, nor do we pay attention to it. 332 if (!secondaryAttr || a.attribute == null || 333 !(a.attribute instanceof Attribute.TypeCompound)) { 334 // Create a new TypeCompound 335 Attribute.TypeCompound tc = 336 new Attribute.TypeCompound(a.type, buf, position); 337 a.attribute = tc; 338 return tc; 339 } else { 340 // Use an existing TypeCompound 341 return (Attribute.TypeCompound)a.attribute; 342 } 343 } 344 345 // Attribute all the annotation's values. 346 private List<Pair<MethodSymbol,Attribute>> 347 enterAttributeValues(JCAnnotation a, 348 Type expected, 349 Env<AttrContext> env, 350 TypeAnnotationPosition position) { 351 // The annotation might have had its type attributed (but not 352 // checked) by attr.attribAnnotationTypes during MemberEnter, 353 // in which case we do not need to do it again. 354 Type at = (a.annotationType.type != null ? a.annotationType.type 355 : attr.attribType(a.annotationType, env)); 356 a.type = chk.checkType(a.annotationType.pos(), at, expected); 357 boolean isError = a.type.isErroneous(); 358 if ((a.type.tsym.flags() & Flags.ANNOTATION) == 0 && !isError) { 359 log.error(a.annotationType.pos(), 360 "not.annotation.type", a.type.toString()); 361 isError = true; 362 } 363 List<JCExpression> args = a.args; 364 if (args.length() == 1 && !args.head.hasTag(ASSIGN)) { 365 // special case: elided "value=" assumed 366 args.head = make.at(args.head.pos). 367 Assign(make.Ident(names.value), args.head); 368 } 369 ListBuffer<Pair<MethodSymbol,Attribute>> buf = 370 new ListBuffer<>(); 371 for (List<JCExpression> tl = args; tl.nonEmpty(); tl = tl.tail) { 372 JCExpression t = tl.head; 373 if (!t.hasTag(ASSIGN)) { 374 log.error(t.pos(), "annotation.value.must.be.name.value"); 375 enterAttributeValue(t.type = syms.errType, t, env, position); 376 continue; 377 } 378 JCAssign assign = (JCAssign)t; 379 if (!assign.lhs.hasTag(IDENT)) { 380 log.error(t.pos(), "annotation.value.must.be.name.value"); 381 enterAttributeValue(t.type = syms.errType, t, env, position); 382 continue; 383 } 384 JCIdent left = (JCIdent)assign.lhs; 385 Symbol method = rs.resolveQualifiedMethod(assign.rhs.pos(), 386 env, 387 a.type, 388 left.name, 389 List.<Type>nil(), 390 null); 391 left.sym = method; 392 left.type = method.type; 393 if (method.owner != a.type.tsym && !isError) 394 log.error(left.pos(), "no.annotation.member", left.name, a.type); 395 Type result = method.type.getReturnType(); 396 Attribute value = enterAttributeValue(result, assign.rhs, env, position); 397 if (!method.type.isErroneous()) 398 buf.append(new Pair<>((MethodSymbol)method, value)); 399 t.type = result; 400 } 401 return buf.toList(); 402 } 403 404 Attribute enterAttributeValue(Type expected, 405 JCExpression tree, 406 Env<AttrContext> env) { 407 return enterAttributeValue(expected, tree, env, null); 408 } 409 410 Attribute enterAttributeValue(Type expected, 411 JCExpression tree, 412 Env<AttrContext> env, 413 TypeAnnotationPosition position) { 414 //first, try completing the attribution value sym - if a completion 415 //error is thrown, we should recover gracefully, and display an 416 //ordinary resolution diagnostic. 417 try { 418 expected.tsym.complete(); 419 } catch(CompletionFailure e) { 420 log.error(tree.pos(), "cant.resolve", Kinds.kindName(e.sym), e.sym); 421 expected = syms.errType; 422 } 423 if (expected.hasTag(ARRAY)) { 424 if (!tree.hasTag(NEWARRAY)) { 425 tree = make.at(tree.pos). 426 NewArray(null, List.<JCExpression>nil(), List.of(tree)); 427 } 428 JCNewArray na = (JCNewArray)tree; 429 if (na.elemtype != null) { 430 log.error(na.elemtype.pos(), "new.not.allowed.in.annotation"); 431 } 432 ListBuffer<Attribute> buf = new ListBuffer<>(); 433 for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) { 434 buf.append(enterAttributeValue(types.elemtype(expected), 435 l.head, env, position)); 436 } 437 na.type = expected; 438 return new Attribute. 439 Array(expected, buf.toArray(new Attribute[buf.length()])); 440 } 441 if (tree.hasTag(NEWARRAY)) { //error recovery 442 if (!expected.isErroneous()) 443 log.error(tree.pos(), "annotation.value.not.allowable.type"); 444 JCNewArray na = (JCNewArray)tree; 445 if (na.elemtype != null) { 446 log.error(na.elemtype.pos(), "new.not.allowed.in.annotation"); 447 } 448 for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) { 449 enterAttributeValue(syms.errType, l.head, env, position); 450 } 451 return new Attribute.Error(syms.errType); 452 } 453 if ((expected.tsym.flags() & Flags.ANNOTATION) != 0) { 454 if (tree.hasTag(ANNOTATION)) { 455 return enterAnnotation((JCAnnotation)tree, expected, env, position); 456 } else { 457 log.error(tree.pos(), "annotation.value.must.be.annotation"); 458 expected = syms.errType; 459 } 460 } 461 if (tree.hasTag(ANNOTATION)) { //error recovery 462 if (!expected.isErroneous()) 463 log.error(tree.pos(), "annotation.not.valid.for.type", expected); 464 enterAnnotation((JCAnnotation)tree, syms.errType, env, position); 465 return new Attribute.Error(((JCAnnotation)tree).annotationType.type); 466 } 467 if (expected.isPrimitive() || 468 (types.isSameType(expected, syms.stringType) && !expected.hasTag(TypeTag.ERROR))) { 469 Type result = attr.attribExpr(tree, env, expected); 470 if (result.isErroneous()) 471 return new Attribute.Error(result.getOriginalType()); 472 if (result.constValue() == null) { 473 log.error(tree.pos(), "attribute.value.must.be.constant"); 474 return new Attribute.Error(expected); 475 } 476 result = cfolder.coerce(result, expected); 477 return new Attribute.Constant(expected, result.constValue()); 478 } 479 if (expected.tsym == syms.classType.tsym) { 480 Type result = attr.attribExpr(tree, env, expected); 481 if (result.isErroneous()) { 482 // Does it look like an unresolved class literal? 483 if (TreeInfo.name(tree) == names._class && 484 ((JCFieldAccess) tree).selected.type.isErroneous()) { 485 Name n = (((JCFieldAccess) tree).selected).type.tsym.flatName(); 486 return new Attribute.UnresolvedClass(expected, 487 types.createErrorType(n, 488 syms.unknownSymbol, syms.classType)); 489 } else { 490 return new Attribute.Error(result.getOriginalType()); 491 } 492 } 493 494 // Class literals look like field accesses of a field named class 495 // at the tree level 496 if (TreeInfo.name(tree) != names._class) { 497 log.error(tree.pos(), "annotation.value.must.be.class.literal"); 498 return new Attribute.Error(syms.errType); 499 } 500 return new Attribute.Class(types, 501 (((JCFieldAccess) tree).selected).type); 502 } 503 if (expected.hasTag(CLASS) && 504 (expected.tsym.flags() & Flags.ENUM) != 0) { 505 Type result = attr.attribExpr(tree, env, expected); 506 Symbol sym = TreeInfo.symbol(tree); 507 if (sym == null || 508 TreeInfo.nonstaticSelect(tree) || 509 sym.kind != Kinds.VAR || 510 (sym.flags() & Flags.ENUM) == 0) { 511 log.error(tree.pos(), "enum.annotation.must.be.enum.constant"); 512 return new Attribute.Error(result.getOriginalType()); 513 } 514 VarSymbol enumerator = (VarSymbol) sym; 515 return new Attribute.Enum(expected, enumerator); 516 } 517 //error recovery: 518 if (!expected.isErroneous()) 519 log.error(tree.pos(), "annotation.value.not.allowable.type"); 520 return new Attribute.Error(attr.attribExpr(tree, env, expected)); 521 } 522 523 /* ********************************* 524 * Support for repeating annotations 525 ***********************************/ 526 527 /* Process repeated annotations. This method returns the 528 * synthesized container annotation or null IFF all repeating 529 * annotation are invalid. This method reports errors/warnings. 530 */ 531 private <T extends Attribute.Compound> T processRepeatedAnnotations( 532 List<T> annotations, 533 AnnotationContext<T> ctx, 534 Symbol on, 535 TypeAnnotationPosition position) { 536 T firstOccurrence = annotations.head; 537 List<Attribute> repeated = List.nil(); 538 Type origAnnoType = null; 539 Type arrayOfOrigAnnoType = null; 540 Type targetContainerType = null; 541 MethodSymbol containerValueSymbol = null; 542 543 Assert.check(!annotations.isEmpty() && 544 !annotations.tail.isEmpty()); // i.e. size() > 1 545 546 int count = 0; 547 for (List<T> al = annotations; !al.isEmpty(); al = al.tail) { 548 count++; 549 // There must be more than a single anno in the annotation list 550 Assert.check(count > 1 || !al.tail.isEmpty()); 551 552 T currentAnno = al.head; 553 554 origAnnoType = currentAnno.type; 555 if (arrayOfOrigAnnoType == null) { 556 arrayOfOrigAnnoType = types.makeArrayType(origAnnoType); 557 } 558 559 // Only report errors if this isn't the first occurrence I.E. count > 1 560 boolean reportError = count > 1; 561 Type currentContainerType = getContainingType(currentAnno, ctx.pos.get(currentAnno), reportError); 562 if (currentContainerType == null) { 563 continue; 564 } 565 // Assert that the target Container is == for all repeated 566 // annos of the same annotation type, the types should 567 // come from the same Symbol, i.e. be '==' 568 Assert.check(targetContainerType == null || currentContainerType == targetContainerType); 569 targetContainerType = currentContainerType; 570 571 containerValueSymbol = validateContainer(targetContainerType, origAnnoType, ctx.pos.get(currentAnno)); 572 573 if (containerValueSymbol == null) { // Check of CA type failed 574 // errors are already reported 575 continue; 576 } 577 578 repeated = repeated.prepend(currentAnno); 579 } 580 581 if (!repeated.isEmpty()) { 582 repeated = repeated.reverse(); 583 TreeMaker m = make.at(ctx.pos.get(firstOccurrence)); 584 Pair<MethodSymbol, Attribute> p = 585 new Pair<MethodSymbol, Attribute>(containerValueSymbol, 586 new Attribute.Array(arrayOfOrigAnnoType, repeated)); 587 if (ctx.isTypeCompound) { 588 Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p), position); 589 at.setSynthesized(true); 590 591 @SuppressWarnings("unchecked") 592 T x = (T) at; 593 return x; 594 } else { 595 Attribute.Compound c = new Attribute.Compound(targetContainerType, 596 List.of(p), 597 position); 598 JCAnnotation annoTree = m.Annotation(c); 599 600 if (!chk.annotationApplicable(annoTree, on)) 601 log.error(annoTree.pos(), "invalid.repeatable.annotation.incompatible.target", targetContainerType, origAnnoType); 602 603 if (!chk.validateAnnotationDeferErrors(annoTree)) 604 log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType); 605 606 c = enterAnnotation(annoTree, targetContainerType, ctx.env, position); 607 c.setSynthesized(true); 608 609 @SuppressWarnings("unchecked") 610 T x = (T) c; 611 return x; 612 } 613 } else { 614 return null; // errors should have been reported elsewhere 615 } 616 } 617 618 619 /** Fetches the actual Type that should be the containing annotation. */ 620 private Type getContainingType(Attribute.Compound currentAnno, 621 DiagnosticPosition pos, 622 boolean reportError) 623 { 624 Type origAnnoType = currentAnno.type; 625 TypeSymbol origAnnoDecl = origAnnoType.tsym; 626 627 // Fetch the Repeatable annotation from the current 628 // annotation's declaration, or null if it has none 629 Attribute.Compound ca = origAnnoDecl.attribute(syms.repeatableType.tsym); 630 if (ca == null) { // has no Repeatable annotation 631 if (reportError) 632 log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.repeatableType); 633 return null; 634 } 635 636 return filterSame(extractContainingType(ca, pos, origAnnoDecl), 637 origAnnoType); 638 } 639 640 // returns null if t is same as 's', returns 't' otherwise 641 private Type filterSame(Type t, Type s) { 642 if (t == null || s == null) { 643 return t; 644 } 645 646 return types.isSameType(t, s) ? null : t; 647 } 648 649 /** Extract the actual Type to be used for a containing annotation. */ 650 private Type extractContainingType(Attribute.Compound ca, 651 DiagnosticPosition pos, 652 TypeSymbol annoDecl) 653 { 654 // The next three checks check that the Repeatable annotation 655 // on the declaration of the annotation type that is repeating is 656 // valid. 657 658 // Repeatable must have at least one element 659 if (ca.values.isEmpty()) { 660 log.error(pos, "invalid.repeatable.annotation", annoDecl); 661 return null; 662 } 663 Pair<MethodSymbol,Attribute> p = ca.values.head; 664 Name name = p.fst.name; 665 if (name != names.value) { // should contain only one element, named "value" 666 log.error(pos, "invalid.repeatable.annotation", annoDecl); 667 return null; 668 } 669 if (!(p.snd instanceof Attribute.Class)) { // check that the value of "value" is an Attribute.Class 670 log.error(pos, "invalid.repeatable.annotation", annoDecl); 671 return null; 672 } 673 674 return ((Attribute.Class)p.snd).getValue(); 675 } 676 677 /* Validate that the suggested targetContainerType Type is a valid 678 * container type for repeated instances of originalAnnoType 679 * annotations. Return null and report errors if this is not the 680 * case, return the MethodSymbol of the value element in 681 * targetContainerType if it is suitable (this is needed to 682 * synthesize the container). */ 683 private MethodSymbol validateContainer(Type targetContainerType, 684 Type originalAnnoType, 685 DiagnosticPosition pos) { 686 MethodSymbol containerValueSymbol = null; 687 boolean fatalError = false; 688 689 // Validate that there is a (and only 1) value method 690 Scope scope = targetContainerType.tsym.members(); 691 int nr_value_elems = 0; 692 boolean error = false; 693 for(Symbol elm : scope.getSymbolsByName(names.value)) { 694 nr_value_elems++; 695 696 if (nr_value_elems == 1 && 697 elm.kind == Kinds.MTH) { 698 containerValueSymbol = (MethodSymbol)elm; 699 } else { 700 error = true; 701 } 702 } 703 if (error) { 704 log.error(pos, 705 "invalid.repeatable.annotation.multiple.values", 706 targetContainerType, 707 nr_value_elems); 708 return null; 709 } else if (nr_value_elems == 0) { 710 log.error(pos, 711 "invalid.repeatable.annotation.no.value", 712 targetContainerType); 713 return null; 714 } 715 716 // validate that the 'value' element is a method 717 // probably "impossible" to fail this 718 if (containerValueSymbol.kind != Kinds.MTH) { 719 log.error(pos, 720 "invalid.repeatable.annotation.invalid.value", 721 targetContainerType); 722 fatalError = true; 723 } 724 725 // validate that the 'value' element has the correct return type 726 // i.e. array of original anno 727 Type valueRetType = containerValueSymbol.type.getReturnType(); 728 Type expectedType = types.makeArrayType(originalAnnoType); 729 if (!(types.isArray(valueRetType) && 730 types.isSameType(expectedType, valueRetType))) { 731 log.error(pos, 732 "invalid.repeatable.annotation.value.return", 733 targetContainerType, 734 valueRetType, 735 expectedType); 736 fatalError = true; 737 } 738 if (error) { 739 fatalError = true; 740 } 741 742 // The conditions for a valid containing annotation are made 743 // in Check.validateRepeatedAnnotaton(); 744 745 return fatalError ? null : containerValueSymbol; 746 } 747 748 /** 749 * First step of repeating annotations handling: go through a list 750 * of annotations, and gather up all the repeated ones into a map, 751 * which we use to build an AnnotationContext. 752 * 753 * Because we do this, we need to get all the annotations for a 754 * given AST node at once (ie. if we have "@A @B @A int foo;", we 755 * have to get "@A @B @A" at the same time). 756 * 757 * @param annotations The annotations being attached. 758 * @param env The environment. 759 * @param sym The symbol to which the annotations will be attached. 760 * @param creator The attribute creator used to enter the annotations. 761 * @param position The position for any type annotations. 762 * @return The AnnotaionContext for use in the next phase. 763 */ 764 private <T extends Attribute.Compound> AnnotationContext<T> 765 prepareEnterAnnotations(List<JCAnnotation> annotations, 766 Env<AttrContext> env, 767 Symbol sym, 768 AttributeCreator<T> creator, 769 TypeAnnotationPosition position) { 770 Map<TypeSymbol, ListBuffer<T>> annotated = new LinkedHashMap<>(); 771 Map<T, DiagnosticPosition> pos = new HashMap<>(); 772 773 // Go through the annotation list, build up a map from 774 // annotation types to lists of annotations. 775 for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) { 776 JCAnnotation a = al.head; 777 T c = creator.create(a, syms.annotationType, env, position); 778 779 Assert.checkNonNull(c, "Failed to create annotation"); 780 781 if (annotated.containsKey(a.type.tsym)) { 782 // Make sure we even allow repeating annotations. 783 if (!allowRepeatedAnnos) { 784 log.error(a.pos(), "repeatable.annotations.not.supported.in.source"); 785 allowRepeatedAnnos = true; 786 } 787 // Append the annotation to the list for this kind of 788 // annotation. 789 ListBuffer<T> l = annotated.get(a.type.tsym); 790 l = l.append(c); 791 annotated.put(a.type.tsym, l); 792 pos.put(c, a.pos()); 793 } else { 794 // We are seeing the first annotation of this kind. 795 annotated.put(a.type.tsym, ListBuffer.of(c)); 796 pos.put(c, a.pos()); 797 } 798 799 // Note: @Deprecated has no effect on local variables and parameters 800 if (!c.type.isErroneous() 801 && sym.owner.kind != MTH 802 && types.isSameType(c.type, syms.deprecatedType)) { 803 sym.flags_field |= Flags.DEPRECATED; 804 } 805 } 806 807 return new AnnotationContext<>(env, annotated, pos, 808 creator.createsTypeCompound()); 809 } 810 811 /** 812 * Entry-point for repeating annotations handling. At this point, 813 * we should know the type annotation position, and we should have 814 * all the annotations for a given source location. 815 * 816 * We first gather up all the repeated annotations and build an 817 * AnnotationContext. Then create Placeholder's for any repeated 818 * annotations and send them further down the pipeline. 819 * 820 * Something to keep in mind here is that even if we are handling 821 * "declaration" annotations, it is still possible that those 822 * might turn into type annotations (consider "@A @B int foo;", 823 * for example). 824 * 825 * The pipeline uses a sort of continuation-passing like style, 826 * with creator and attacher. This allows two things. First, it 827 * allows for a single pipeline for repeating annotations, 828 * regardless of what eventually happens to the annotations. 829 * Second, it allows us to avoid some unsafe casts we would 830 * otherwise have to make. 831 * 832 * @param annotations The annotations to handle. 833 * @param env The environment. 834 * @param sym The symbol to which to attach annotations. 835 * @param position The position for type annotations. 836 * @param creator The creator to use to enter annotations. 837 * @param attacher The attacher to use to attach annotations. 838 */ 839 private <T extends Attribute.Compound> 840 void attachAttributesLater(final List<JCAnnotation> annotations, 841 final Env<AttrContext> env, 842 final Symbol sym, 843 final TypeAnnotationPosition position, 844 final AttributeCreator<T> creator, 845 final AttributeAttacher<T> attacher) { 846 // First, gather up all the repeated annotations. 847 final AnnotationContext<T> ctx = 848 prepareEnterAnnotations(annotations, env, sym, creator, position); 849 final Map<Symbol.TypeSymbol, ListBuffer<T>> annotated = 850 ctx.annotated; 851 boolean hasRepeated = false; 852 853 // Now run through all the annotation types in the 854 // AnnotationContext. If there are any that have more than 855 // one entry, then we set up a Placeholder for them. 856 List<T> buf = List.<T>nil(); 857 for (ListBuffer<T> lb : annotated.values()) { 858 if (lb.size() == 1) { 859 buf = buf.prepend(lb.first()); 860 } else { 861 @SuppressWarnings("unchecked") 862 T res = (T) new Placeholder<>(ctx, lb.toList(), sym); 863 buf = buf.prepend(res); 864 hasRepeated = true; 865 } 866 } 867 868 final List<T> attrs = buf.reverse(); 869 870 if (!creator.createsTypeCompound()) { 871 // Attach declaration attributes early, so 872 // that @Repeatable and other annotations get attached. 873 // Since the attacher uses setDeclarationAttributes, this 874 // will be overwritten later. 875 // 876 // The root cause of this is that annotations are 877 // themselves defined using annotations. However, it is 878 // never the case that a type annotation affects the 879 // definition of an annotation, so we don't have to do 880 // this. 881 // 882 // We really should find a better way to do this. 883 @SuppressWarnings("unchecked") 884 List<Attribute.Compound> tempattrs = (List<Attribute.Compound>) attrs; 885 sym.setDeclarationAttributes(tempattrs); 886 } 887 888 if (hasRepeated) { 889 // If we have repeated annotations, then we go to the next 890 // pipeline step, which replaces all the placeholders. 891 replacePlaceholdersAndAttach(attrs, ctx, env, sym, attacher); 892 } else { 893 // If we don't have repeated annotations, then we still 894 // have to run the annotations through the rest of the 895 // pipeline. 896 // 897 // For type annotations, we might have error-reporting to 898 // do, and the attacher might end up attaching the 899 // annotation to the symbol's owner as well. 900 // 901 // For regular annotations, we might have a 902 // classifyingAttacher, in which case we have to pull the 903 // annotations off the symbol, classify them, and then put 904 // them in the right place. 905 attachAttributesAfterRepeated(attrs, env, attacher); 906 } 907 } 908 909 /** 910 * Next pipeline step for repeated annotations: replate all the 911 * placeholders, and then send the result further down the pipe. 912 * 913 * @param attrs The Attributes representing the annotations. 914 * @param ctx The AnnotationContext being used. 915 * @param env The environment. 916 * @param sym The symbol to which to attach annotations. 917 * @param attacher The attacher to use to attach annotations. 918 */ 919 private <T extends Attribute.Compound> 920 void replacePlaceholdersAndAttach(final List<T> attrs, 921 final AnnotationContext<T> ctx, 922 final Env<AttrContext> env, 923 final Symbol sym, 924 final AttributeAttacher<T> attacher) { 925 // Set up a Worker. 926 repeated(new Annotate.Worker() { 927 @Override 928 public String toString() { 929 return "repeated annotation pass of: " + sym + " in: " + sym.owner; 930 } 931 932 @Override 933 public void run() { 934 JavaFileObject oldSource = 935 log.useSource(env.toplevel.sourcefile); 936 try { 937 // Replace placeholders 938 final List<T> replaced = 939 replacePlaceholders(attrs, ctx, sym); 940 // Then send the result to the final pipeline stage. 941 attachAttributesAfterRepeated(replaced, env, attacher); 942 } finally { 943 log.useSource(oldSource); 944 } 945 } 946 }); 947 } 948 949 /** 950 * Final pipeline stage. Simply use the attacher to deal with the 951 * annotations however we want to deal with them. Note that 952 * attachers may do a number of things, like attach annotations to 953 * other symbols (as is the case with some type annotations, which 954 * get attached to their symbol's owner as well), report errors, 955 * or even create copies (as is the case with classifyingAttacher) 956 * 957 * At this point, we have to be able to guarantee that we don't 958 * see any Placeholders. 959 * 960 * @param attrs The Attributes representing the annotations. 961 * @param env The environment. 962 * @param attacher The attacher we use to finish handling the 963 * annotations. 964 */ 965 private <T extends Attribute.Compound> 966 void attachAttributesAfterRepeated(final List<T> attrs, 967 final Env<AttrContext> env, 968 final AttributeAttacher<T> attacher) { 969 // Set up a Worker that just calls the attacher. 970 afterRepeated(new Worker() { 971 @Override 972 public String toString() { 973 return "attach pass for: " + attrs; 974 } 975 976 @Override 977 public void run() { 978 JavaFileObject oldSource = 979 log.useSource(env.toplevel.sourcefile); 980 try { 981 attacher.attach(attrs); 982 } finally { 983 log.useSource(oldSource); 984 } 985 } 986 }); 987 } 988 989 /** 990 * AttributeAttachers are similar to continuations. That contains 991 * the behavior of the final stage of the annotation pipeline, 992 * when we've creted Attributes (which have a type annotation 993 * position), and we've dealt with repeating annotations. Once we 994 * have done all that, we simply hand off the list of attributes 995 * to the attacher and let it do its work. 996 * 997 * If we didn't have the multiple deferred steps, we could 998 * implement this by returning a list of Attributes from a 999 * top-level method representing the entire repeating annotations 1000 * pipeline. Since we have to handle annotations in multiple 1001 * steps, we can't do that. Therefore, in this light, we can 1002 * think of an attacher as being essentially a return 1003 * continuation. 1004 * 1005 * We also have ways to "build" more complex attachers out of 1006 * simple ones, such as classifyingAttacher. This allows us 1007 * considerable flexibility in how we deal with annotations at the 1008 * end of the pipeline (which is necessary, because there are a 1009 * lot of cases). 1010 */ 1011 public interface AttributeAttacher<T extends Attribute.Compound> { 1012 public void attach(List<T> attrs); 1013 } 1014 1015 /** 1016 * An interface for describing error reporting behaviors for 1017 * type-only annotations. Sometimes, we need to report errors if 1018 * any annotations wind up being type-only annotations (the best 1019 * example being for illegal scoping). But at the point where we 1020 * know this, we don't always know if a given annotation will be a 1021 * type-only annotation, a regular annotation, or both. So we 1022 * have to defer the error-reporting until we do know. 1023 */ 1024 public interface Reporter<T extends Attribute.Compound> { 1025 public void report(List<T> attrs); 1026 } 1027 1028 public enum AnnotationKind { DECLARATION, TYPE, BOTH } 1029 1030 public Attribute[] getTargetTypes(Attribute.Compound a) { 1031 Attribute.Compound atTarget = 1032 a.type.tsym.attribute(syms.annotationTargetType.tsym); 1033 if (atTarget == null) { 1034 return null; 1035 } 1036 Attribute atValue = atTarget.member(names.value); 1037 Assert.check(atValue instanceof Attribute.Array); 1038 return ((Attribute.Array) atValue).values; 1039 } 1040 1041 public boolean hasTypeUseTarget(Attribute.Compound a, 1042 boolean isTypeParameter) { 1043 Attribute[] targets = getTargetTypes(a); 1044 if (targets != null) { 1045 for (Attribute app : targets) { 1046 Assert.check(app instanceof Attribute.Enum); 1047 Attribute.Enum e = (Attribute.Enum) app; 1048 if (e.value.name == names.TYPE_USE || 1049 (isTypeParameter && e.value.name == names.TYPE_PARAMETER)) { 1050 return true; 1051 } 1052 } 1053 } 1054 return false; 1055 } 1056 1057 /** 1058 * Determine whether an annotation is a declaration annotation, 1059 * a type annotation, or both. 1060 */ 1061 public AnnotationKind annotationKind(Attribute.Compound a, Symbol s) { 1062 Attribute[] targets = getTargetTypes(a); 1063 if (targets == null) { 1064 return AnnotationKind.DECLARATION; 1065 } 1066 boolean isDecl = false, isType = false; 1067 for (Attribute app : targets) { 1068 Assert.check(app instanceof Attribute.Enum); 1069 Attribute.Enum e = (Attribute.Enum) app; 1070 if (e.value.name == names.TYPE) { 1071 if (s.kind == Kinds.TYP) { 1072 ElementKind skind = s.getKind(); 1073 // The only symbols we should see here correspond 1074 // to definitions. 1075 Assert.check(skind == ElementKind.ANNOTATION_TYPE || 1076 skind == ElementKind.INTERFACE || 1077 skind == ElementKind.ENUM || 1078 skind == ElementKind.CLASS); 1079 isDecl = true; 1080 } 1081 } else if (e.value.name == names.FIELD) { 1082 if (s.kind == Kinds.VAR && 1083 s.owner.kind != Kinds.MTH) 1084 isDecl = true; 1085 } else if (e.value.name == names.METHOD) { 1086 if (s.kind == Kinds.MTH && 1087 !s.isConstructor()) 1088 isDecl = true; 1089 } else if (e.value.name == names.PARAMETER) { 1090 if (s.kind == Kinds.VAR && 1091 s.owner.kind == Kinds.MTH && 1092 (s.flags() & Flags.PARAMETER) != 0) 1093 isDecl = true; 1094 } else if (e.value.name == names.CONSTRUCTOR) { 1095 if (s.kind == Kinds.MTH && 1096 s.isConstructor()) 1097 isDecl = true; 1098 } else if (e.value.name == names.LOCAL_VARIABLE) { 1099 if (s.kind == Kinds.VAR && 1100 s.owner.kind == Kinds.MTH && 1101 (s.flags() & Flags.PARAMETER) == 0) 1102 isDecl = true; 1103 } else if (e.value.name == names.ANNOTATION_TYPE) { 1104 if (s.kind == Kinds.TYP && 1105 (s.flags() & Flags.ANNOTATION) != 0) 1106 isDecl = true; 1107 } else if (e.value.name == names.PACKAGE) { 1108 if (s.kind == Kinds.PCK) 1109 isDecl = true; 1110 } else if (e.value.name == names.TYPE_USE) { 1111 if (s.kind == Kinds.TYP || 1112 s.kind == Kinds.VAR || 1113 (s.kind == Kinds.MTH && !s.isConstructor() && 1114 !s.type.getReturnType().hasTag(TypeTag.VOID)) || 1115 (s.kind == Kinds.MTH && s.isConstructor())) 1116 isType = true; 1117 } else if (e.value.name == names.TYPE_PARAMETER) { 1118 /* Irrelevant in this case: we will never see symbols 1119 * that are type parameters, as we never attach 1120 * declaration annotations to them. */ 1121 Assert.check(s.getKind() != ElementKind.TYPE_PARAMETER); 1122 } else { 1123 Assert.error("annotationKind(): unrecognized Attribute name " + e.value.name + 1124 " (" + e.value.name.getClass() + ")"); 1125 } 1126 } 1127 if (isDecl && isType) { 1128 return AnnotationKind.BOTH; 1129 } else if (isType) { 1130 return AnnotationKind.TYPE; 1131 } else { 1132 return AnnotationKind.DECLARATION; 1133 } 1134 } 1135 1136 /** 1137 * An attacher that just attaches annotations as declaration 1138 * annotations. This is used in places where we know for a fact 1139 * that type annotations cannot occur. 1140 */ 1141 private AttributeAttacher<Attribute.Compound> 1142 declAnnotationsAttacher(final Symbol sym) { 1143 return new AttributeAttacher<Attribute.Compound>() { 1144 @Override 1145 public String toString() { 1146 return "Attacher for strictly declaration annotations, for " + 1147 sym; 1148 } 1149 1150 @Override 1151 public void attach(List<Attribute.Compound> attrs) { 1152 sym.resetAnnotations(); 1153 sym.setDeclarationAttributes(attrs); 1154 } 1155 }; 1156 } 1157 1158 /** 1159 * An attacher that just attaches annotations as type annotations. 1160 * We use this in places where only type annotations can occur. 1161 * The most common use for this is any annotation where we have to 1162 * "parse" a type (arrays, inner classes, type arguments, bounds, 1163 * etc.). We also use this for base types for non-declarations 1164 * (ie. casts, instanceofs, etc). A more subtle case is for 1165 * anonymous classes and receiver parameters, both of which cannot 1166 * have regular annotations. 1167 */ 1168 private AttributeAttacher<Attribute.TypeCompound> 1169 typeAnnotationsAttacher(final Symbol sym) { 1170 return new AttributeAttacher<Attribute.TypeCompound>() { 1171 @Override 1172 public String toString() { 1173 return "Attacher for strictly type annotations, for " + sym; 1174 } 1175 1176 @Override 1177 public void attach(List<Attribute.TypeCompound> attrs) { 1178 if (!attrs.isEmpty()) { 1179 attachTypeAnnotations(sym, attrs); 1180 } 1181 } 1182 }; 1183 } 1184 1185 /** 1186 * Attach type-only annotations using an attacher, and run a 1187 * reporter. Either the reporter or the attacher may be null, in 1188 * which case we skip that step. 1189 */ 1190 private AttributeAttacher<Attribute.TypeCompound> 1191 reportingTypeAnnotationsAttacher(final AttributeAttacher<Attribute.TypeCompound> attacher, 1192 final Reporter<Attribute.TypeCompound> reporter) { 1193 return new AttributeAttacher<Attribute.TypeCompound>() { 1194 @Override 1195 public String toString() { 1196 return "Error-reporting type annotation, attacher is: " + attacher + 1197 "\n reporter is: " + reporter; 1198 } 1199 1200 @Override 1201 public void attach(List<Attribute.TypeCompound> attrs) { 1202 if (attacher != null) 1203 attacher.attach(attrs); 1204 1205 if (reporter != null) 1206 reporter.report(attrs); 1207 } 1208 }; 1209 } 1210 1211 /** 1212 * Attach type-only annotations to a symbol and also update the 1213 * .type field on a tree (unless it is a package type). This is 1214 * used to put annotations on to a type as well as a symbol. 1215 */ 1216 private AttributeAttacher<Attribute.TypeCompound> 1217 typeUpdatingTypeAnnotationsAttacher(final AttributeAttacher<Attribute.TypeCompound> attacher, 1218 final JCTree tree) { 1219 return new AttributeAttacher<Attribute.TypeCompound>() { 1220 @Override 1221 public String toString() { 1222 return "Type-updating type annotation attacher, attacher is: " + attacher + 1223 "\n tree is: " + tree; 1224 } 1225 1226 @Override 1227 public void attach(List<Attribute.TypeCompound> attrs) { 1228 if (null != attacher) 1229 attacher.attach(attrs); 1230 1231 if (!attrs.isEmpty() && !tree.type.hasTag(TypeTag.PACKAGE)) { 1232 tree.type = tree.type.annotatedType(attrs); 1233 } 1234 } 1235 }; 1236 } 1237 1238 /** 1239 * A Reporter for illegal scoping. We set one of these up in 1240 * TypeAnnotate whenever we are in a place that corresponds to a 1241 * package or static class that cannot be annotated. 1242 */ 1243 private void reportIllegalScoping(List<Attribute.TypeCompound> attrs, 1244 int pos) { 1245 switch (attrs.size()) { 1246 case 0: 1247 // Don't issue an error if all type annotations are 1248 // also declaration annotations. 1249 // If the annotations are also declaration annotations, they are 1250 // illegal as type annotations but might be legal as declaration annotations. 1251 // The normal declaration annotation checks make sure that the use is valid. 1252 break; 1253 case 1: 1254 log.error(pos, "cant.type.annotate.scoping.1", attrs); 1255 break; 1256 default: 1257 log.error(pos, "cant.type.annotate.scoping", attrs); 1258 } 1259 } 1260 1261 private Reporter<Attribute.TypeCompound> 1262 illegalScopingReporter(final int pos) { 1263 return new Reporter<Attribute.TypeCompound>() { 1264 @Override 1265 public String toString() { 1266 return "Illegal scoping reporter at position " + pos; 1267 } 1268 1269 @Override 1270 public void report(List<Attribute.TypeCompound> attrs) { 1271 reportIllegalScoping(attrs, pos); 1272 } 1273 }; 1274 } 1275 1276 // Create the "simple case": just attach type and regular 1277 // annotations, no reporting. 1278 private AttributeAttacher<Attribute.Compound> 1279 classifyingAttacher(final Symbol sym) { 1280 return classifyingAttacher(sym, declAnnotationsAttacher(sym), 1281 typeAnnotationsAttacher(sym), 1282 null); 1283 } 1284 1285 1286 /** 1287 * Build an attacher for handling the case where we have 1288 * annotations, but we don't know for sure whether they are 1289 * declaration annotations, type annotations, or both. 1290 * 1291 * We do this by taking an attacher for declaration annotations, 1292 * another one for type annotations, and (possibly) a reporter for 1293 * type-only annotations. We then use the logic from 1294 * annotationKind to figure out what kind each annotation is and 1295 * deal with it accordingly. 1296 * 1297 * Any of the declAttacher, the typeAttacher, or the Reporter can 1298 * be null, in which case we skip it. 1299 * 1300 * We have to have the reporter *separate* from the type 1301 * annotation attacher, because we might be attaching type 1302 * annotations that are also declaration annotations. But the 1303 * semantics of reporters are that they get called for type-only 1304 * annotations. For an example of where this matters, consider 1305 * "@A java.lang.Object foo;", where @A can annotate packages and 1306 * type uses. We would create the classifyingAttacher with null 1307 * for the type attacher and an illegal scoping reporter. Both 1308 * attachers would end up getting called on @A (which, we'd skip 1309 * the type attacher, because it's null), the result being that @A 1310 * goes on foo as a declaration annotation. The reporter would 1311 * not get called, because there are no type-only annotations. 1312 * However, if @A can only annotate type uses, then it's a 1313 * type-only annotation, and we report an illegal scoping error. 1314 * 1315 * Note: there is a case where we want both attachers to be null: 1316 * speculative attribution. 1317 * 1318 * @param sym The symbol to which to attach annotations. 1319 * @param declAttacher The attacher to use for declaration (and 1320 * both) annotations, or null. 1321 * @param typeAttacher The attacher to use for type (and both) 1322 * annotations, or null. 1323 * @param reporter The reporter to use for type-only annotations, or null. 1324 * @return The created attacher. 1325 */ 1326 private AttributeAttacher<Attribute.Compound> 1327 classifyingAttacher(final Symbol sym, 1328 final AttributeAttacher<Attribute.Compound> declAttacher, 1329 final AttributeAttacher<Attribute.TypeCompound> typeAttacher, 1330 final Reporter<Attribute.TypeCompound> reporter) { 1331 return new AttributeAttacher<Attribute.Compound>() { 1332 @Override 1333 public String toString() { 1334 return "Classifying attacher, attaching to " + sym + 1335 "\n declaration annotation attacher is: " + declAttacher + 1336 "\n type annotation attacher is: " + typeAttacher + 1337 "\n reporter for strictly type annotations is: " + reporter; 1338 } 1339 1340 @Override 1341 public void attach(List<Attribute.Compound> attrs) { 1342 // We sort annotations into "buckets" based on what 1343 // kind they are. 1344 ListBuffer<Attribute.Compound> declAnnos = new ListBuffer<>(); 1345 ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<>(); 1346 // We also need to keep track of the type-only 1347 // annotations, in case we have a reporting action. 1348 ListBuffer<Attribute.TypeCompound> onlyTypeAnnos = new ListBuffer<>(); 1349 1350 for (Attribute.Compound a : attrs) { 1351 Assert.check(!(a instanceof Placeholder), 1352 "Placeholders found in annotations being attached!"); 1353 switch (annotationKind(a, sym)) { 1354 case DECLARATION: 1355 declAnnos.append(a); 1356 break; 1357 case BOTH: { 1358 declAnnos.append(a); 1359 Attribute.TypeCompound ta = a.toTypeCompound(); 1360 Assert.checkNonNull(ta.position); 1361 typeAnnos.append(ta); 1362 break; 1363 } 1364 case TYPE: { 1365 Attribute.TypeCompound ta = a.toTypeCompound(); 1366 Assert.checkNonNull(ta.position); 1367 typeAnnos.append(ta); 1368 // Also keep track which annotations are only type annotations 1369 onlyTypeAnnos.append(ta); 1370 break; 1371 } 1372 default: 1373 throw new AssertionError("Unknown annotation type"); 1374 } 1375 } 1376 1377 if (declAttacher != null) 1378 declAttacher.attach(declAnnos.toList()); 1379 1380 if (typeAttacher != null) 1381 typeAttacher.attach(typeAnnos.toList()); 1382 1383 if (reporter != null) 1384 reporter.report(onlyTypeAnnos.toList()); 1385 } 1386 }; 1387 } 1388 1389 /** 1390 * Actually attach a list of type annotations to a symbol. For 1391 * variables defined in methods, we need to attach to both the 1392 * variable symbol, as well as the method symbol. This takes care 1393 * of that. 1394 * 1395 * @param sym The symbol to which to attach. 1396 * @param attrs The annotations to attach. 1397 */ 1398 public void attachTypeAnnotations(Symbol sym, List<Attribute.TypeCompound> attrs) { 1399 sym.appendUniqueTypeAttributes(attrs); 1400 1401 // For type annotations on variables in methods, make 1402 // sure they are attached to the owner too. 1403 switch(sym.getKind()) { 1404 case PARAMETER: 1405 case LOCAL_VARIABLE: 1406 case RESOURCE_VARIABLE: 1407 case EXCEPTION_PARAMETER: 1408 // Make sure all type annotations from the symbol are also 1409 // on the owner. 1410 sym.owner.appendUniqueTypeAttributes(attrs); 1411 break; 1412 } 1413 } 1414 1415 /** 1416 * Final task for repeating annotations: go through a list of 1417 * Attributes and replace all the placeholders with containers. 1418 * 1419 * @param buf The list of Attributes. 1420 * @param ctx The AnnotationContext. 1421 * @param sym The symbol to which we are attaching. 1422 * @return The list of attributes with all placeholders replaced. 1423 */ 1424 private <T extends Attribute.Compound> List<T> 1425 replacePlaceholders(List<T> buf, 1426 Annotate.AnnotationContext<T> ctx, 1427 Symbol sym) { 1428 List<T> result = List.nil(); 1429 for (T a : buf) { 1430 if (a instanceof Placeholder) { 1431 @SuppressWarnings("unchecked") 1432 T replacement = replaceOne((Placeholder<T>) a, ctx, sym); 1433 1434 if (null != replacement) { 1435 result = result.prepend(replacement); 1436 } 1437 } else { 1438 result = result.prepend(a); 1439 } 1440 } 1441 1442 return result.reverse(); 1443 } 1444 1445 /** 1446 * Replace one placeholder with a container. 1447 */ 1448 private <T extends Attribute.Compound> T replaceOne(Placeholder<T> placeholder, 1449 Annotate.AnnotationContext<T> ctx, 1450 Symbol sym) { 1451 // Process repeated annotations 1452 T validRepeated = 1453 processRepeatedAnnotations(placeholder.getPlaceholderFor(), 1454 ctx, sym, placeholder.position); 1455 1456 if (validRepeated != null) { 1457 // Check that the container isn't manually 1458 // present along with repeated instances of 1459 // its contained annotation. 1460 ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym); 1461 if (manualContainer != null) { 1462 log.error(ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present", 1463 manualContainer.first().type.tsym); 1464 } 1465 } 1466 1467 // A null return will delete the Placeholder 1468 return validRepeated; 1469 } 1470 1471/* ******************************************************************** 1472 * Annotation processing 1473 *********************************************************************/ 1474 1475 /** 1476 * Run a list of annotations through the repeating annotations 1477 * pipeline, and attach them. We don't have any diagnostic 1478 * position. 1479 */ 1480 void annotateLater(final List<JCAnnotation> annotations, 1481 final Env<AttrContext> localEnv, 1482 final Symbol s) { 1483 annotateLater(annotations, localEnv, s, null); 1484 } 1485 1486 /** 1487 * Run a list of annotations through the repeating annotations 1488 * pipeline and attach them. This is for when we have annotations 1489 * that cannot possibly be type annotations (thus, we have no type 1490 * annotation position). 1491 */ 1492 void annotateLater(final List<JCAnnotation> annotations, 1493 final Env<AttrContext> localEnv, 1494 final Symbol s, 1495 final DiagnosticPosition deferPos) { 1496 // Only attach declaration annotations. 1497 doAnnotateLater(annotations, localEnv, s, deferPos, null, 1498 declAnnotationsAttacher(s)); 1499 } 1500 1501 /** 1502 * Run a list of annotations through the repeating annotation 1503 * pipeline, and then classify and attach them. This is used 1504 * whenever we have annotations that might be regular annotations, 1505 * type annotations, or both. 1506 */ 1507 void annotateWithClassifyLater(final List<JCAnnotation> annotations, 1508 final Env<AttrContext> localEnv, 1509 final Symbol s, 1510 final DiagnosticPosition deferPos, 1511 final TypeAnnotationPosition tapos) { 1512 // Set up just the basic classifying attacher. 1513 doAnnotateLater(annotations, localEnv, s, deferPos, tapos, 1514 classifyingAttacher(s)); 1515 } 1516 1517 /** 1518 * Set up a worker for handling annotations without parsing a type tree. 1519 */ 1520 private void doAnnotateLater(final List<JCAnnotation> annotations, 1521 final Env<AttrContext> localEnv, 1522 final Symbol s, 1523 final DiagnosticPosition deferPos, 1524 final TypeAnnotationPosition tapos, 1525 final AttributeAttacher<Attribute.Compound> attacher) { 1526 if (annotations.isEmpty()) { 1527 return; 1528 } 1529 // Mark annotations as incomplete for now. 1530 // 1531 // This should probably get redesigned at some point. 1532 if (s.kind != PCK) { 1533 s.resetAnnotations(); 1534 } 1535 normal(new Annotate.Worker() { 1536 @Override 1537 public String toString() { 1538 return "annotate " + annotations + " onto " + s + " in " + s.owner; 1539 } 1540 1541 @Override 1542 public void run() { 1543 annotateNow(annotations, localEnv, s, deferPos, 1544 tapos, attacher); 1545 } 1546 }); 1547 1548 validate(annotationValidator(annotations, localEnv, s)); 1549 } 1550 1551 /** 1552 * Run a list of declaration (meaning they are in a declaration 1553 * position) annotations through the repeating annotations 1554 * pipeline. 1555 * 1556 * Note that in some cases, these annotations might end up being 1557 * type annotations, or both declaration and type annotations. 1558 * 1559 * @param annotations The annotations to handle. 1560 * @param localEnv the environment. 1561 * @param s The symbol to which to attach. 1562 * @param deferPos The diagnostic position to use. 1563 * @param position The type annotation position to use if some of 1564 * the annotations end up being type annotations. 1565 * @param attacher The attacher to use. 1566 */ 1567 private void annotateNow(final List<JCAnnotation> annotations, 1568 final Env<AttrContext> localEnv, 1569 final Symbol s, 1570 final DiagnosticPosition deferPos, 1571 final TypeAnnotationPosition position, 1572 final AttributeAttacher<Attribute.Compound> attacher) { 1573 if (annotations.isEmpty()) { 1574 return; 1575 } 1576 Assert.check(s.kind == PCK || s.annotationsPendingCompletion()); 1577 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); 1578 DiagnosticPosition prevLintPos = deferPos != null ? 1579 deferredLintHandler.setPos(deferPos) : 1580 deferredLintHandler.immediate(); 1581 Lint prevLint = deferPos != null ? null : chk.setLint(lint); 1582 try { 1583 if (s.hasAnnotations() && 1584 annotations.nonEmpty()) 1585 log.error(annotations.head.pos, 1586 "already.annotated", 1587 kindName(s), s); 1588 actualEnterAnnotations(annotations, localEnv, s, position, attacher); 1589 } finally { 1590 if (prevLint != null) 1591 chk.setLint(prevLint); 1592 deferredLintHandler.setPos(prevLintPos); 1593 log.useSource(prev); 1594 } 1595 } 1596 1597 // Set up a validator to enforce some rules on regular annotations. 1598 private Annotate.Worker annotationValidator(final List<JCAnnotation> annotations, 1599 final Env<AttrContext> localEnv, 1600 final Symbol s) { 1601 return new Annotate.Worker() { //validate annotations 1602 @Override 1603 public void run() { 1604 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); 1605 try { 1606 chk.validateAnnotations(annotations, s); 1607 } finally { 1608 log.useSource(prev); 1609 } 1610 } 1611 }; 1612 } 1613 1614 private void checkForDeclarationAnnotations(List<? extends JCAnnotation> annotations, 1615 boolean isTypeParameter) { 1616 // Ensure that no declaration annotations are present. 1617 // Note that a tree type might be an AnnotatedType with 1618 // empty annotations, if only declaration annotations were given. 1619 // This method will raise an error for such a type. 1620 for (JCAnnotation ai : annotations) { 1621 Assert.checkNonNull(ai.type); 1622 Assert.checkNonNull(ai.attribute); 1623 1624 if (!ai.type.isErroneous() && 1625 !hasTypeUseTarget(ai.attribute, isTypeParameter)) { 1626 log.error(ai.pos(), "annotation.type.not.applicable"); 1627 } 1628 } 1629 } 1630 1631 // Set up a validator to enforce some rules on type annotations. 1632 // In addition to those enforced by Check.validateTypeAnnotations, 1633 // this enforces that declaration annotations cannot occur on type 1634 // parameters. 1635 private Annotate.Worker typeAnnotationValidator(final List<JCAnnotation> annotations, 1636 final Env<AttrContext> localEnv, 1637 final boolean isTypeParameter) { 1638 return new Annotate.Worker() { //validate annotations 1639 @Override 1640 public void run() { 1641 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); 1642 try { 1643 checkForDeclarationAnnotations(annotations, isTypeParameter); 1644 chk.validateTypeAnnotations(annotations, isTypeParameter); 1645 } finally { 1646 log.useSource(prev); 1647 } 1648 } 1649 }; 1650 } 1651 1652 /** 1653 * This is an interface that wraps up the functionality of 1654 * enterAnnotations and enterTypeAnnotations. This allows some 1655 * code duplication to be removed from the original repeating 1656 * annotations pipeline. It also allows for some unsafe casts to 1657 * be eliminated. 1658 * 1659 * Note: when Lambdas can be used in the compiler, we can just use 1660 * method refs for enterAnnotations and enterTypeAnnotations. 1661 */ 1662 private interface AttributeCreator<T extends Attribute.Compound> { 1663 public T create(JCAnnotation a, 1664 Type expected, 1665 Env<AttrContext> env, 1666 TypeAnnotationPosition position); 1667 public abstract boolean createsTypeCompound(); 1668 } 1669 1670 // Note: try to avoid doing anything that makes these any more 1671 // than just the equivalent of method refs in a pre-lambda 1672 // setting. That way, they can go away when we are allowed to use 1673 // lambda. 1674 private final AttributeCreator<Attribute.Compound> enterAnnotationsCreator = 1675 new AttributeCreator<Attribute.Compound>() { 1676 @Override 1677 public String toString() { 1678 return "Attribute creator for regular declaration annotations"; 1679 } 1680 1681 @Override 1682 public Attribute.Compound create(JCAnnotation a, 1683 Type expected, 1684 Env<AttrContext> env, 1685 TypeAnnotationPosition position) { 1686 return enterAnnotation(a, syms.annotationType, env, position); 1687 } 1688 1689 @Override 1690 public boolean createsTypeCompound() { return false; } 1691 }; 1692 1693 private AttributeCreator<Attribute.TypeCompound> 1694 enterTypeAnnotationsCreator(final boolean secondaryAttr) { 1695 return new AttributeCreator<Attribute.TypeCompound>() { 1696 @Override 1697 public String toString() { 1698 if (!secondaryAttr) { 1699 return "Attribute creator for regular type annotations"; 1700 } else { 1701 return "Attribute creator for regular type annotations, ignores cached attributes"; 1702 } 1703 } 1704 1705 @Override 1706 public Attribute.TypeCompound create(JCAnnotation a, 1707 Type expected, 1708 Env<AttrContext> env, 1709 TypeAnnotationPosition position) { 1710 return enterTypeAnnotation(a, syms.annotationType, 1711 env, position, secondaryAttr); 1712 } 1713 1714 @Override 1715 public boolean createsTypeCompound() { return true; } 1716 }; 1717 } 1718 1719 /** 1720 * Send a list of annotations (which occurred in a declaration 1721 * position) into the repeating annotations pipeline. 1722 */ 1723 private void actualEnterAnnotations(List<JCAnnotation> annotations, 1724 Env<AttrContext> env, 1725 Symbol s, 1726 TypeAnnotationPosition position, 1727 AttributeAttacher<Attribute.Compound> attacher) { 1728 Assert.checkNonNull(s); 1729 attachAttributesLater(annotations, env, s, position, 1730 enterAnnotationsCreator, attacher); 1731 } 1732 1733 /** 1734 * Send a list of annotations (which occurred in a type-use 1735 * position) into the repeating annotations pipeline. 1736 */ 1737 private void actualEnterTypeAnnotations(final List<JCAnnotation> annotations, 1738 final Env<AttrContext> env, 1739 final Symbol s, 1740 final DiagnosticPosition deferPos, 1741 final boolean secondaryAttr, 1742 final TypeAnnotationPosition position, 1743 final AttributeAttacher<Attribute.TypeCompound> attacher) { 1744 Assert.checkNonNull(s); 1745 JavaFileObject prev = log.useSource(env.toplevel.sourcefile); 1746 DiagnosticPosition prevLintPos = null; 1747 1748 if (deferPos != null) { 1749 prevLintPos = deferredLintHandler.setPos(deferPos); 1750 } 1751 try { 1752 attachAttributesLater(annotations, env, s, position, 1753 enterTypeAnnotationsCreator(secondaryAttr), 1754 attacher); 1755 } finally { 1756 if (prevLintPos != null) 1757 deferredLintHandler.setPos(prevLintPos); 1758 log.useSource(prev); 1759 } 1760 } 1761 1762 /** 1763 * Given a type tree, walk down it and handle any annotations we 1764 * find. 1765 * 1766 * @param tree The type tree to scan. 1767 * @param env The environment. 1768 * @param sym The symbol to which to attach any annotations we 1769 * might find. 1770 * @param deferPos The diagnostic position to use. 1771 * @param creator The creator to use for making positions. 1772 */ 1773 public void annotateTypeLater(final JCTree tree, 1774 final Env<AttrContext> env, 1775 final Symbol sym, 1776 final DiagnosticPosition deferPos, 1777 final PositionCreator creator) { 1778 doAnnotateTypeLater(tree, List.<JCAnnotation>nil(), env, 1779 sym, deferPos, creator, false, false); 1780 } 1781 1782 /** 1783 * Given a type tree, walk down it and handle any annotations we 1784 * find. We also have a set of base-type annotations (which 1785 * occurred in a declaration position in source), which may either 1786 * be declaration annotations or annotations on the base type. 1787 * For an example, in "@A int @B []", we would have the type tree 1788 * "int @B []" with base-type annotations "@A". 1789 * 1790 * @param tree The type tree to scan. 1791 * @param baseTypeAnnos The base-type annotations. 1792 * @param env The environment. 1793 * @param sym The symbol to which to attach any annotations we 1794 * might find. 1795 * @param deferPos The diagnostic position to use. 1796 * @param creator The creator to use for making positions. 1797 */ 1798 public void annotateTypeLater(final JCTree tree, 1799 final List<JCAnnotation> baseTypeAnnos, 1800 final Env<AttrContext> env, 1801 final Symbol sym, 1802 final DiagnosticPosition deferPos, 1803 final PositionCreator creator) { 1804 doAnnotateTypeLater(tree, baseTypeAnnos, env, sym, deferPos, 1805 creator, false, false); 1806 } 1807 1808 /** 1809 * Given a type tree, walk down it and handle any annotations we 1810 * find. We also have a set of base-type annotations (which 1811 * occurred in a declaration position in source), which must be 1812 * type annotations on the base type. 1813 * 1814 * @param tree The type tree to scan. 1815 * @param baseTypeAnnos The base-type annotations. 1816 * @param env The environment. 1817 * @param sym The symbol to which to attach any annotations we 1818 * might find. 1819 * @param deferPos The diagnostic position to use. 1820 * @param creator The creator to use for making positions. 1821 */ 1822 public void annotateStrictTypeLater(final JCTree tree, 1823 final List<JCAnnotation> baseTypeAnnos, 1824 final Env<AttrContext> env, 1825 final Symbol sym, 1826 final DiagnosticPosition deferPos, 1827 final PositionCreator creator) { 1828 doAnnotateTypeLater(tree, baseTypeAnnos, env, sym, deferPos, 1829 creator, true, false); 1830 } 1831 1832 /** 1833 * Given a type tree representing an anonymous class' supertype, 1834 * walk down it and handle any annotations we find. We also have 1835 * a set of base-type annotations (which occurred in a declaration 1836 * position in source), which must be type annotations on the base 1837 * type. 1838 * 1839 * @param tree The type tree to scan. 1840 * @param baseTypeAnnos The base-type annotations. 1841 * @param env The environment. 1842 * @param sym The symbol to which to attach any annotations we 1843 * might find. 1844 * @param deferPos The diagnostic position to use. 1845 * @param creator The creator to use for making positions. 1846 */ 1847 public void annotateAnonClassDefLater(final JCTree tree, 1848 final List<JCAnnotation> baseTypeAnnos, 1849 final Env<AttrContext> env, 1850 final Symbol sym, 1851 final DiagnosticPosition deferPos, 1852 final PositionCreator creator) { 1853 doAnnotateTypeLater(tree, baseTypeAnnos, env, sym, deferPos, 1854 creator, true, true); 1855 } 1856 1857 // The combined worker function for the annotateTypeLater family. 1858 public void doAnnotateTypeLater(final JCTree tree, 1859 final List<JCAnnotation> baseTypeAnnos, 1860 final Env<AttrContext> env, 1861 final Symbol sym, 1862 final DiagnosticPosition deferPos, 1863 final PositionCreator creator, 1864 final boolean onlyTypeAnnos, 1865 final boolean secondaryAttr) { 1866 Assert.checkNonNull(sym); 1867 Assert.checkNonNull(baseTypeAnnos); 1868 Assert.checkNonNull(creator); 1869 1870 normal(new Annotate.Worker() { 1871 @Override 1872 public String toString() { 1873 return "type annotate " + tree + " onto " + sym + " in " + sym.owner; 1874 } 1875 @Override 1876 public void run() { 1877 if (!baseTypeAnnos.isEmpty()) { 1878 sym.resetAnnotations(); // mark Annotations as incomplete for now 1879 } 1880 1881 tree.accept(typeAnnotator(baseTypeAnnos, sym, env, deferPos, 1882 creator, onlyTypeAnnos, 1883 secondaryAttr)); 1884 } 1885 }); 1886 } 1887 1888 /** 1889 * A client passed into various visitors that takes a type path as 1890 * an argument and performs an action (typically creating a 1891 * TypeAnnotationPosition and then creating a {@code Worker} and 1892 * adding it to a queue. 1893 */ 1894 public abstract class PositionCreator { 1895 public abstract TypeAnnotationPosition create(List<TypePathEntry> path, 1896 JCLambda lambda, 1897 int typeIndex); 1898 } 1899 1900 // For when we don't have a creator. Throws an exception. 1901 public final PositionCreator noCreator = 1902 new PositionCreator() { 1903 @Override 1904 public String toString() { 1905 return "Sentinel null position creator"; 1906 } 1907 1908 @Override 1909 public TypeAnnotationPosition create(List<TypePathEntry> path, 1910 JCLambda lambda, 1911 int typeIndex) { 1912 throw new AssertionError("No annotation position creator registered"); 1913 } 1914 }; 1915 1916 // For when we are creating annotations that will inevitably 1917 // trigger errors. Creates null. 1918 public final PositionCreator errorCreator = 1919 new PositionCreator() { 1920 @Override 1921 public String toString() { 1922 return "Position creator for annotations that represent errors"; 1923 } 1924 1925 @Override 1926 public TypeAnnotationPosition create(List<TypePathEntry> path, 1927 JCLambda lambda, 1928 int typeIndex) { 1929 return null; 1930 } 1931 }; 1932 1933 // Create class extension positions 1934 public final PositionCreator extendsCreator = 1935 new PositionCreator() { 1936 @Override 1937 public String toString() { 1938 return "Position creator for extends"; 1939 } 1940 1941 @Override 1942 public TypeAnnotationPosition create(List<TypePathEntry> path, 1943 JCLambda lambda, 1944 int typeIndex) { 1945 return TypeAnnotationPosition.classExtends(path, lambda, -1); 1946 } 1947 }; 1948 1949 // Create interface implementation positions 1950 public PositionCreator implementsCreator(final int idx) { 1951 return new PositionCreator() { 1952 @Override 1953 public String toString() { 1954 return "Position creator for implements, index " + idx; 1955 } 1956 1957 @Override 1958 public TypeAnnotationPosition create(List<TypePathEntry> path, 1959 JCLambda lambda, 1960 int typeIndex) { 1961 return TypeAnnotationPosition.classExtends(path, lambda, idx, -1); 1962 } 1963 }; 1964 } 1965 1966 // Create method parameter positions 1967 public final PositionCreator paramCreator(final int idx) { 1968 return new PositionCreator() { 1969 @Override 1970 public String toString() { 1971 return "Position creator for parameter " + idx; 1972 } 1973 1974 @Override 1975 public TypeAnnotationPosition create(List<TypePathEntry> path, 1976 JCLambda lambda, 1977 int typeIndex) { 1978 return TypeAnnotationPosition.methodParameter(path, lambda, idx, -1); 1979 } 1980 }; 1981 } 1982 1983 // Create class type parameter positions 1984 public PositionCreator typeParamCreator(final int idx) { 1985 return new PositionCreator() { 1986 @Override 1987 public String toString() { 1988 return "Position creator for class type parameter " + idx; 1989 } 1990 1991 @Override 1992 public TypeAnnotationPosition create(List<TypePathEntry> path, 1993 JCLambda lambda, 1994 int typeIndex) { 1995 return TypeAnnotationPosition.typeParameter(path, lambda, idx, -1); 1996 } 1997 }; 1998 } 1999 2000 public PositionCreator typeParamBoundCreator(final JCTypeParameter typaram, 2001 final int param_idx, 2002 final int bound_idx) { 2003 return new PositionCreator() { 2004 @Override 2005 public String toString() { 2006 return "Position creator for class type parameter " + param_idx + 2007 ", bound " + bound_idx; 2008 } 2009 2010 @Override 2011 public TypeAnnotationPosition create(List<TypePathEntry> path, 2012 JCLambda lambda, 2013 int typeIndex) { 2014 final int real_bound_idx = 2015 typaram.bounds.head.type.isInterface() ? bound_idx + 1 : bound_idx; 2016 return TypeAnnotationPosition 2017 .typeParameterBound(path, lambda, param_idx, real_bound_idx, -1); 2018 } 2019 }; 2020 } 2021 2022 // Create field positions 2023 public final PositionCreator fieldCreator = 2024 new PositionCreator() { 2025 @Override 2026 public String toString() { 2027 return "Position creator for field declaration"; 2028 } 2029 2030 @Override 2031 public TypeAnnotationPosition create(List<TypePathEntry> path, 2032 JCLambda lambda, 2033 int typeIndex) { 2034 return TypeAnnotationPosition.field(path, lambda, -1); 2035 } 2036 }; 2037 2038 // Create local variable positions 2039 public PositionCreator localVarCreator(final int pos) { 2040 return new PositionCreator() { 2041 @Override 2042 public String toString() { 2043 return "Position creator for local variable declaration at " + 2044 pos; 2045 } 2046 2047 @Override 2048 public TypeAnnotationPosition create(List<TypePathEntry> path, 2049 JCLambda lambda, 2050 int typeIndex) { 2051 return TypeAnnotationPosition.localVariable(path, lambda, pos); 2052 } 2053 }; 2054 } 2055 2056 // Create resource variable positions. 2057 public PositionCreator resourceVarCreator(final int pos) { 2058 return new PositionCreator() { 2059 @Override 2060 public String toString() { 2061 return "Position creator for resource variable declaration at " + 2062 pos; 2063 } 2064 2065 @Override 2066 public TypeAnnotationPosition create(List<TypePathEntry> path, 2067 JCLambda lambda, 2068 int typeIndex) { 2069 return TypeAnnotationPosition.resourceVariable(path, lambda, pos); 2070 } 2071 }; 2072 } 2073 2074 // Create exception parameter positions. 2075 public PositionCreator exceptionParamCreator(final int pos) { 2076 return new PositionCreator() { 2077 @Override 2078 public String toString() { 2079 return "Position creator for exception param declaration at " + 2080 pos; 2081 } 2082 2083 @Override 2084 public TypeAnnotationPosition create(List<TypePathEntry> path, 2085 JCLambda lambda, 2086 int typeIndex) { 2087 return TypeAnnotationPosition.exceptionParameter(path, lambda, 2088 typeIndex, pos); 2089 } 2090 }; 2091 } 2092 2093 // Create constructor reference type argument positions. 2094 public PositionCreator constructorRefTypeArgCreator(final int idx, 2095 final int pos) { 2096 return new PositionCreator() { 2097 @Override 2098 public String toString() { 2099 return "Position creator for constructor reference type argument " + idx + 2100 " at " + pos; 2101 } 2102 2103 @Override 2104 public TypeAnnotationPosition create(List<TypePathEntry> path, 2105 JCLambda lambda, 2106 int typeIndex) { 2107 return TypeAnnotationPosition 2108 .constructorRefTypeArg(path, lambda, idx, pos); 2109 } 2110 }; 2111 } 2112 2113 public PositionCreator methodInvokeTypeArgCreator(final int idx, 2114 final int pos) { 2115 return new PositionCreator() { 2116 @Override 2117 public String toString() { 2118 return "Position creator for method invoke type argument " + idx + 2119 " at " + pos; 2120 } 2121 2122 @Override 2123 public TypeAnnotationPosition create(List<TypePathEntry> path, 2124 JCLambda lambda, 2125 int typeIndex) { 2126 return TypeAnnotationPosition.methodInvocationTypeArg(path, lambda, idx, pos); 2127 } 2128 }; 2129 } 2130 2131 public PositionCreator methodTypeParamCreator(final int idx) { 2132 return new PositionCreator() { 2133 @Override 2134 public String toString() { 2135 return "Position creator for method type parameter " + idx; 2136 } 2137 2138 @Override 2139 public TypeAnnotationPosition create(List<TypePathEntry> path, 2140 JCLambda lambda, 2141 int typeIndex) { 2142 return TypeAnnotationPosition.methodTypeParameter(path, lambda, idx, -1); 2143 } 2144 }; 2145 } 2146 2147 public PositionCreator methodTypeParamBoundCreator(final JCTypeParameter typaram, 2148 final int param_idx, 2149 final int bound_idx) { 2150 return new PositionCreator() { 2151 @Override 2152 public String toString() { 2153 return "Position creator for method type parameter " + param_idx + 2154 " bound " + bound_idx; 2155 } 2156 2157 @Override 2158 public TypeAnnotationPosition create(List<TypePathEntry> path, 2159 JCLambda lambda, 2160 int typeIndex) { 2161 final int real_bound_idx = 2162 typaram.bounds.head.type.isInterface() ? bound_idx + 1 : bound_idx; 2163 return TypeAnnotationPosition 2164 .methodTypeParameterBound(path, lambda, param_idx, real_bound_idx, -1); 2165 } 2166 }; 2167 } 2168 2169 public PositionCreator throwCreator(final int idx) { 2170 return new PositionCreator() { 2171 @Override 2172 public String toString() { 2173 return "Position creator for throw, type index " + idx; 2174 } 2175 2176 @Override 2177 public TypeAnnotationPosition create(List<TypePathEntry> path, 2178 JCLambda lambda, 2179 int typeIndex) { 2180 return TypeAnnotationPosition.methodThrows(path, lambda, idx, -1); 2181 } 2182 }; 2183 } 2184 2185 public final PositionCreator returnCreator = 2186 new PositionCreator() { 2187 @Override 2188 public String toString() { 2189 return "Position creator for method return type"; 2190 } 2191 2192 @Override 2193 public TypeAnnotationPosition create(List<TypePathEntry> path, 2194 JCLambda lambda, 2195 int typeIndex) { 2196 return TypeAnnotationPosition.methodReturn(path, lambda, -1); 2197 } 2198 }; 2199 2200 public PositionCreator receiverCreator = 2201 new PositionCreator() { 2202 @Override 2203 public String toString() { 2204 return "Position creator for method receiver parameter type"; 2205 } 2206 2207 @Override 2208 public TypeAnnotationPosition create(List<TypePathEntry> path, 2209 JCLambda lambda, 2210 int typeIndex) { 2211 return TypeAnnotationPosition.methodReceiver(path, lambda, -1); 2212 } 2213 }; 2214 2215 public PositionCreator methodRefCreator(final int pos) { 2216 return new PositionCreator() { 2217 @Override 2218 public String toString() { 2219 return "Position creator for method reference at " + pos; 2220 } 2221 2222 @Override 2223 public TypeAnnotationPosition create(List<TypePathEntry> path, 2224 JCLambda lambda, 2225 int typeIndex) { 2226 return TypeAnnotationPosition.methodRef(path, lambda, pos); 2227 } 2228 }; 2229 } 2230 2231 public PositionCreator methodRefTypeArgCreator(final int idx, 2232 final int pos) { 2233 return new PositionCreator() { 2234 @Override 2235 public String toString() { 2236 return "Position creator for method reference type argument " + idx + 2237 " at " + pos; 2238 } 2239 2240 @Override 2241 public TypeAnnotationPosition create(List<TypePathEntry> path, 2242 JCLambda lambda, 2243 int typeIndex) { 2244 return TypeAnnotationPosition.methodRefTypeArg(path, lambda, idx, pos); 2245 } 2246 }; 2247 } 2248 2249 public PositionCreator constructorRefCreator(final int pos) { 2250 return new PositionCreator() { 2251 @Override 2252 public String toString() { 2253 return "Position creator for constructor reference at " + pos; 2254 } 2255 2256 @Override 2257 public TypeAnnotationPosition create(List<TypePathEntry> path, 2258 JCLambda lambda, 2259 int typeIndex) { 2260 return TypeAnnotationPosition.constructorRef(path, lambda, pos); 2261 } 2262 }; 2263 } 2264 2265 public PositionCreator constructorInvokeTypeArgCreator(final int idx, 2266 final int pos) { 2267 return new PositionCreator() { 2268 @Override 2269 public String toString() { 2270 return "Position creator for constructor invoke type argument " + idx + 2271 " at " + pos; 2272 } 2273 2274 @Override 2275 public TypeAnnotationPosition create(List<TypePathEntry> path, 2276 JCLambda lambda, 2277 int typeIndex) { 2278 return TypeAnnotationPosition.constructorInvocationTypeArg(path, lambda, idx, pos); 2279 } 2280 }; 2281 } 2282 2283 public PositionCreator instanceOfCreator(final int pos) { 2284 return new PositionCreator() { 2285 @Override 2286 public String toString() { 2287 return "Position creator for instanceof at " + pos; 2288 } 2289 2290 @Override 2291 public TypeAnnotationPosition create(List<TypePathEntry> path, 2292 JCLambda lambda, 2293 int typeIndex) { 2294 return TypeAnnotationPosition.instanceOf(path, lambda, pos); 2295 } 2296 }; 2297 } 2298 2299 public PositionCreator newObjCreator(final int pos) { 2300 return new PositionCreator() { 2301 @Override 2302 public String toString() { 2303 return "Position creator for new at " + pos; 2304 } 2305 2306 @Override 2307 public TypeAnnotationPosition create(List<TypePathEntry> path, 2308 JCLambda lambda, 2309 int typeIndex) { 2310 return TypeAnnotationPosition.newObj(path, lambda, pos); 2311 } 2312 }; 2313 } 2314 2315 public PositionCreator castCreator(final int pos) { 2316 return new PositionCreator() { 2317 @Override 2318 public String toString() { 2319 return "Position creator for cast at " + pos; 2320 } 2321 2322 @Override 2323 public TypeAnnotationPosition create(List<TypePathEntry> path, 2324 JCLambda lambda, 2325 int typeIndex) { 2326 return TypeAnnotationPosition.typeCast(path, lambda, typeIndex, pos); 2327 } 2328 }; 2329 } 2330 2331 public static List<TypePathEntry> makeInners(Type type) { 2332 return addInners(type, List.<TypePathEntry>nil()); 2333 } 2334 2335 private static List<TypePathEntry> addInners(Type type, 2336 List<TypePathEntry> typepath) { 2337 Type encl = type.getEnclosingType(); 2338 while (encl != null && encl.getKind() != TypeKind.NONE && 2339 encl.getKind() != TypeKind.ERROR) { 2340 typepath = typepath.append(TypePathEntry.INNER_TYPE); 2341 encl = encl.getEnclosingType(); 2342 } 2343 return typepath; 2344 } 2345 2346 /** 2347 * Set up the visitor to scan the type tree and handle any 2348 * annotations we find. If we are in speculative attribution, we 2349 * will not actually attach anything, we will just enter the 2350 * annotations and run them through the pipeline to pick up any 2351 * errors that might occur. 2352 * 2353 * @param baseTypeAnnos Annotations on the base type, which need 2354 * to be classified if onlyTypeAnnos is false. 2355 * @param sym The symbol to which to attach. 2356 * @param env The environment. 2357 * @param creator The position creator to use. 2358 * @param onlyTypeAnnos Whether or not baseTypeAnnos can represent 2359 * declaration annotations. 2360 * @param secondaryAttr Whether or not we are creating secondary 2361 * attributes (see enterTypeAnnotations). 2362 */ 2363 public TypeAnnotate typeAnnotator(final List<JCAnnotation> baseTypeAnnos, 2364 final Symbol sym, 2365 final Env<AttrContext> env, 2366 final DiagnosticPosition deferPos, 2367 final PositionCreator creator, 2368 final boolean onlyTypeAnnos, 2369 final boolean secondaryAttr) { 2370 if (!env.info.isSpeculative) { 2371 return new TypeAnnotate(baseTypeAnnos, sym, env, deferPos, creator, 2372 declAnnotationsAttacher(sym), 2373 typeAnnotationsAttacher(sym), 2374 onlyTypeAnnos, secondaryAttr); 2375 } else { 2376 return new TypeAnnotate(baseTypeAnnos, sym, env, deferPos, creator, 2377 null, null, onlyTypeAnnos, secondaryAttr); 2378 } 2379 } 2380 2381 /** 2382 * A visitor that scans a type tree and handles an annotations it finds. 2383 * 2384 */ 2385 private class TypeAnnotate extends TreeScanner { 2386 // The creator we use to create positions. 2387 protected PositionCreator creator; 2388 // The current type path 2389 private List<TypePathEntry> typepath = List.nil(); 2390 // The current innermost lambda 2391 private JCLambda currentLambda; 2392 // The current type index, if we are looking at an 2393 // intersection type. 2394 private int type_index = 0; 2395 // Whether or not we are looking at the innermost type. This 2396 // gets used to figure out where to attach base type 2397 // annotations. 2398 private boolean innermost; 2399 // The attachers and reporter we use. 2400 private AttributeAttacher<Attribute.Compound> declAttacher; 2401 private AttributeAttacher<Attribute.TypeCompound> typeAttacher; 2402 private Reporter<Attribute.TypeCompound> reporter; 2403 // The symbol to which we are attaching. 2404 private final Symbol sym; 2405 // The diagnostic position we use. 2406 private final DiagnosticPosition deferPos; 2407 // The environment 2408 private final Env<AttrContext> env; 2409 private final List<JCAnnotation> baseTypeAnnos; 2410 // Whether or not baseTypeAnnos can be declaration 2411 // annotations, or just strictly type annotations. 2412 private final boolean onlyTypeAnnos; 2413 // Whether or not we are creating secondary attributes (see 2414 // enterTypeAnnotations). 2415 private final boolean secondaryAttr; 2416 2417 public TypeAnnotate(final List<JCAnnotation> baseTypeAnnos, 2418 final Symbol sym, 2419 final Env<AttrContext> env, 2420 final DiagnosticPosition deferPos, 2421 final PositionCreator creator, 2422 final AttributeAttacher<Attribute.Compound> declAttacher, 2423 final AttributeAttacher<Attribute.TypeCompound> typeAttacher, 2424 final boolean onlyTypeAnnos, 2425 final boolean secondaryAttr) { 2426 this.baseTypeAnnos = baseTypeAnnos; 2427 this.sym = sym; 2428 this.env = env; 2429 this.deferPos = deferPos; 2430 this.currentLambda = env.getLambda(); 2431 this.creator = creator; 2432 this.innermost = true; 2433 this.declAttacher = declAttacher; 2434 this.typeAttacher = typeAttacher; 2435 this.reporter = null; 2436 this.onlyTypeAnnos = onlyTypeAnnos; 2437 this.secondaryAttr = secondaryAttr; 2438 } 2439 2440 // Deal with the base-type annotations. This should only get 2441 // called when we are at the inner-most type. 2442 private void doBaseTypeAnnos() { 2443 if (onlyTypeAnnos) { 2444 // If the base type annotations can only be type 2445 // annotations, then handle them as such. 2446 doTypeAnnos(baseTypeAnnos, false); 2447 } else if (!baseTypeAnnos.isEmpty()) { 2448 // Otherwise, send them into the repeating annotations 2449 // pipeline with a classifying attacher we build based 2450 // on the current state. 2451 final TypeAnnotationPosition tapos = 2452 creator.create(typepath, currentLambda, type_index); 2453 annotateNow(baseTypeAnnos, env, sym, deferPos, tapos, 2454 classifyingAttacher(sym, declAttacher, 2455 typeAttacher, reporter)); 2456 // Also set up a validator. 2457 validate(annotationValidator(baseTypeAnnos, env, sym)); 2458 } 2459 } 2460 2461 // Deal with type annotations we found while scanning the tree. 2462 private void doTypeAnnos(List<JCAnnotation> annos, 2463 boolean isTypeParameter) { 2464 if (!annos.isEmpty()) { 2465 // Grab the reporter and the type attacher (which, 2466 // it's ok for either to be null), and combine them 2467 // into a reporting attacher. 2468 final AttributeAttacher<Attribute.TypeCompound> attacher = 2469 reportingTypeAnnotationsAttacher(typeAttacher, reporter); 2470 // Create the position using the current type path and 2471 // type index. 2472 final TypeAnnotationPosition tapos = 2473 creator.create(typepath, currentLambda, type_index); 2474 // Send the annotations into the repeating annotations 2475 // pipeline, and set up a validator. 2476 actualEnterTypeAnnotations(annos, env, sym, deferPos, secondaryAttr, 2477 tapos, attacher); 2478 validate(typeAnnotationValidator(annos, env, isTypeParameter)); 2479 } 2480 } 2481 2482 @Override 2483 public void visitTypeIdent(final JCPrimitiveTypeTree tree) { 2484 // This is one place that can represent the base type. 2485 // But we need to make sure we're actually in the 2486 // innermost type (ie not a type argument or something). 2487 if (innermost) { 2488 final AttributeAttacher<Attribute.TypeCompound> oldTypeAttacher = typeAttacher; 2489 // We want to update the Type to have annotations. 2490 typeAttacher = typeUpdatingTypeAnnotationsAttacher(oldTypeAttacher, 2491 tree); 2492 // We can't possibly have any INNER_TYPE type path 2493 // elements, because these are all primitives. 2494 doBaseTypeAnnos(); 2495 typeAttacher = oldTypeAttacher; 2496 } 2497 } 2498 2499 @Override 2500 public void visitIdent(final JCIdent tree) { 2501 // This is one place that can represent the base type. 2502 // But we need to make sure we're actually in the 2503 // innermost type (ie not a type argument or something). 2504 if (innermost) { 2505 final AttributeAttacher<Attribute.TypeCompound> oldTypeAttacher = typeAttacher; 2506 // Set up an attacher that updates the Type, so we get 2507 // the annotations. 2508 typeAttacher = typeUpdatingTypeAnnotationsAttacher(oldTypeAttacher, 2509 tree); 2510 // Add any INNER_TYPE type path elements we might need. 2511 if (tree.type != null) { 2512 final List<TypePathEntry> oldpath = typepath; 2513 typepath = addInners(tree.type, typepath); 2514 doBaseTypeAnnos(); 2515 typepath = oldpath; 2516 } else { 2517 doBaseTypeAnnos(); 2518 } 2519 typeAttacher = oldTypeAttacher; 2520 } 2521 } 2522 2523 @Override 2524 public void visitAnnotatedType(JCAnnotatedType tree) { 2525 // This is one place where we run into pure type 2526 // annotations. 2527 Assert.checkNonNull(tree.getUnderlyingType().type); 2528 final boolean oldinnermost = innermost; 2529 // Make sure we don't consider ourselves "innermost" when 2530 // scanning the annotations. 2531 innermost = false; 2532 scan(tree.annotations); 2533 innermost = oldinnermost; 2534 scan(tree.underlyingType); 2535 final List<TypePathEntry> oldpath = typepath; 2536 typepath = addInners(tree.getUnderlyingType().type, typepath); 2537 doTypeAnnos(tree.annotations, false); 2538 typepath = oldpath; 2539 } 2540 2541 @Override 2542 public void visitTypeArray(JCArrayTypeTree tree) { 2543 // This case is simple: just add an ARRAY to the type path. 2544 final List<TypePathEntry> oldpath = typepath; 2545 typepath = typepath.append(TypePathEntry.ARRAY); 2546 super.visitTypeArray(tree); 2547 typepath = oldpath; 2548 } 2549 2550 @Override 2551 public void visitTypeApply(JCTypeApply tree) { 2552 // Handle type arguments 2553 Assert.checkNonNull(tree.getType().type); 2554 final List<TypePathEntry> oldpath = typepath; 2555 // First, look at the base type. 2556 scan(tree.clazz); 2557 2558 // Add any INNER_TYPE path elements we need first 2559 if (tree.getType() != null && tree.getType().type != null) { 2560 typepath = addInners(tree.getType().type, typepath); 2561 } 2562 // Make sure we're not considering ourselves innermost 2563 // when looking at type arguments. 2564 final boolean oldinnermost = innermost; 2565 innermost = false; 2566 // For each type argument, add a TYPE_ARGUMENT path 2567 // element for the right index. 2568 int i = 0; 2569 for (List<JCExpression> l = tree.arguments; l.nonEmpty(); 2570 l = l.tail, i++) { 2571 final JCExpression arg = l.head; 2572 final List<TypePathEntry> noargpath = typepath; 2573 typepath = typepath.append(new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, i)); 2574 scan(arg); 2575 typepath = noargpath; 2576 } 2577 typepath = oldpath; 2578 innermost = oldinnermost; 2579 } 2580 2581 @Override 2582 public void visitNewArray(JCNewArray tree) { 2583 // We can also run into type annotations here, on dimAnnos. 2584 final List<TypePathEntry> oldpath = typepath; 2585 final PositionCreator oldcreator = creator; 2586 creator = newObjCreator(tree.pos); 2587 doTypeAnnos(tree.annotations, false); 2588 2589 // Go through the dimensions, set up the type path, and 2590 // handle any annetations we find. 2591 for (int i = 0; i < tree.dimAnnotations.size(); i++) { 2592 final List<JCAnnotation> dimAnnos = tree.dimAnnotations.get(i); 2593 doTypeAnnos(dimAnnos, false); 2594 // This is right. As per the type annotations spec, 2595 // the first array dimension has no arrays in the type 2596 // path, the second has one, and so on, and the 2597 // element type has n for n dimensions. 2598 typepath = typepath.append(TypePathEntry.ARRAY); 2599 } 2600 2601 // The element type is sometimes null, in the case of 2602 // array literals. 2603 scan(tree.elemtype); 2604 typepath = oldpath; 2605 creator = oldcreator; 2606 } 2607 2608 @Override 2609 public void visitWildcard(JCWildcard tree) { 2610 // Simple: add a WILDCARD type path element and continue. 2611 final List<TypePathEntry> oldpath = typepath; 2612 typepath = typepath.append(TypePathEntry.WILDCARD); 2613 super.visitWildcard(tree); 2614 typepath = oldpath; 2615 } 2616 2617 @Override 2618 public void visitTypeParameter(JCTypeParameter tree) { 2619 // This is another place where we can run into pure type 2620 // annotations. 2621 scan(tree.annotations); 2622 Assert.checkNonNull(tree.type); 2623 doTypeAnnos(tree.annotations, true); 2624 } 2625 2626 @Override 2627 public void visitLambda(JCLambda tree) { 2628 // If we run into a lambda, set the current lambda to it. 2629 final JCLambda oldLambda = currentLambda; 2630 currentLambda = tree; 2631 scan(tree.body); 2632 scan(tree.params); 2633 currentLambda = oldLambda; 2634 } 2635 2636 @Override 2637 public void visitTypeIntersection(JCTypeIntersection tree) { 2638 final boolean oldinnermost = innermost; 2639 // Run through the options, and update the type_index 2640 // accordingly. 2641 for (List<JCExpression> l = tree.bounds; l.nonEmpty(); 2642 l = l.tail, type_index++) { 2643 scan(l.head); 2644 // Set innermost to false after the first element 2645 innermost = false; 2646 } 2647 innermost = oldinnermost; 2648 } 2649 2650 @Override 2651 public void visitTypeUnion(JCTypeUnion tree) { 2652 final boolean oldinnermost = innermost; 2653 // Run through the options, and update the type_index 2654 // accordingly. 2655 for (List<JCExpression> l = tree.alternatives; l.nonEmpty(); 2656 l = l.tail, type_index++) { 2657 scan(l.head); 2658 // Set innermost to false after the first element 2659 innermost = false; 2660 } 2661 innermost = oldinnermost; 2662 } 2663 2664 @Override 2665 public void visitSelect(JCFieldAccess tree) { 2666 // In this case, we need to possibly set up an 2667 // illegalScopingReporter, if the selected type cannot be 2668 // annotated. 2669 Symbol sym = tree.sym; 2670 final AttributeAttacher<Attribute.TypeCompound> oldTypeAttacher = typeAttacher; 2671 final Reporter<Attribute.TypeCompound> oldReporter = reporter; 2672 // If we're selecting from an interface or a static class, 2673 // set up attachers that will only attach declaration 2674 // annotations and will report type annotations as errors. 2675 Type selectedTy = tree.selected.type; 2676 if ((sym != null && (sym.isStatic() || sym.isInterface() || 2677 selectedTy.hasTag(TypeTag.PACKAGE))) || 2678 tree.name == names._class) { 2679 typeAttacher = null; 2680 reporter = illegalScopingReporter(tree.pos); 2681 } 2682 super.visitSelect(tree); 2683 typeAttacher = oldTypeAttacher; 2684 reporter = oldReporter; 2685 } 2686 2687 // These methods stop the visitor from continuing on when it 2688 // sees a definition. 2689 @Override 2690 public void visitVarDef(final JCVariableDecl tree) { 2691 } 2692 2693 @Override 2694 public void visitClassDef(JCClassDecl tree) { 2695 } 2696 2697 @Override 2698 public void visitNewClass(JCNewClass tree) { 2699 2700 } 2701 } 2702 2703 // A derived TypeAnnotate visitor that also scans expressions 2704 // within Deferred attribution. 2705 private class TypeAnnotateExpr extends TypeAnnotate { 2706 // This constructor creates an instance suitable for deferred 2707 // attribution. 2708 public TypeAnnotateExpr(final Symbol sym, 2709 final Env<AttrContext> env, 2710 final DiagnosticPosition deferPos, 2711 final PositionCreator creator) { 2712 super(List.<JCAnnotation>nil(), sym, env, deferPos, 2713 creator, null, null, false, false); 2714 } 2715 2716 @Override 2717 public void visitTypeCast(final JCTypeCast tree) { 2718 final PositionCreator oldcreator = creator; 2719 creator = castCreator(tree.pos); 2720 super.visitTypeCast(tree); 2721 creator = oldcreator; 2722 } 2723 2724 @Override 2725 public void visitTypeTest(JCInstanceOf tree) { 2726 final PositionCreator oldcreator = creator; 2727 creator = instanceOfCreator(tree.pos); 2728 super.visitTypeTest(tree); 2729 creator = oldcreator; 2730 } 2731 2732 @Override 2733 public void visitReference(JCMemberReference that) { 2734 final boolean isConstructor = that.getName() == names.init; 2735 final PositionCreator oldcreator = creator; 2736 creator = isConstructor ? constructorRefCreator(that.pos) : 2737 methodRefCreator(that.pos); 2738 scan(that.expr); 2739 2740 if (null != that.typeargs) { 2741 int i = 0; 2742 for (List<JCExpression> l = that.typeargs; 2743 l.nonEmpty(); l = l.tail, i++) { 2744 final Annotate.PositionCreator typeArgCreator = 2745 isConstructor ? constructorRefTypeArgCreator(i, that.pos) : 2746 methodRefTypeArgCreator(i, that.pos); 2747 final JCExpression arg = l.head; 2748 scan(that.expr); 2749 } 2750 } 2751 2752 creator = oldcreator; 2753 } 2754 2755 @Override 2756 public void visitNewClass(JCNewClass tree) { 2757 // This will be visited by Attr later, so don't do 2758 // anything. 2759 } 2760 } 2761 2762 /** 2763 * Set up a visitor to scan an expression and handle any type 2764 * annotations it finds, within a deferred attribution context. 2765 */ 2766 public void typeAnnotateExprLater(final JCTree tree, 2767 final Env<AttrContext> env, 2768 final Symbol sym, 2769 final DiagnosticPosition deferPos, 2770 final PositionCreator creator) { 2771 Assert.checkNonNull(sym); 2772 Assert.checkNonNull(creator); 2773 2774 normal(new Annotate.Worker() { 2775 @Override 2776 public String toString() { 2777 return "type annotate " + tree + " onto " + sym + " in " + sym.owner; 2778 } 2779 @Override 2780 public void run() { 2781 tree.accept(new TypeAnnotateExpr(sym, env, deferPos, creator)); 2782 } 2783 }); 2784 } 2785} 2786