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