TypeAnnotations.java revision 3070:b3ed4ac7cd91
1/* 2 * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.tools.javac.code; 27 28import javax.lang.model.element.Element; 29import javax.lang.model.element.ElementKind; 30import javax.lang.model.type.TypeKind; 31import javax.tools.JavaFileObject; 32 33import com.sun.tools.javac.code.Attribute.Array; 34import com.sun.tools.javac.code.Attribute.TypeCompound; 35import com.sun.tools.javac.code.Symbol.TypeSymbol; 36import com.sun.tools.javac.code.Type.ArrayType; 37import com.sun.tools.javac.code.Type.CapturedType; 38import com.sun.tools.javac.code.Type.ClassType; 39import com.sun.tools.javac.code.Type.ErrorType; 40import com.sun.tools.javac.code.Type.ForAll; 41import com.sun.tools.javac.code.Type.MethodType; 42import com.sun.tools.javac.code.Type.PackageType; 43import com.sun.tools.javac.code.Type.TypeVar; 44import com.sun.tools.javac.code.Type.UndetVar; 45import com.sun.tools.javac.code.Type.Visitor; 46import com.sun.tools.javac.code.Type.WildcardType; 47import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntry; 48import com.sun.tools.javac.code.TypeAnnotationPosition.TypePathEntryKind; 49import com.sun.tools.javac.code.Symbol.VarSymbol; 50import com.sun.tools.javac.code.Symbol.MethodSymbol; 51import com.sun.tools.javac.code.TypeMetadata.Entry.Kind; 52import com.sun.tools.javac.comp.Annotate; 53import com.sun.tools.javac.comp.Attr; 54import com.sun.tools.javac.comp.AttrContext; 55import com.sun.tools.javac.comp.Env; 56import com.sun.tools.javac.tree.JCTree; 57import com.sun.tools.javac.tree.TreeInfo; 58import com.sun.tools.javac.tree.JCTree.JCBlock; 59import com.sun.tools.javac.tree.JCTree.JCClassDecl; 60import com.sun.tools.javac.tree.JCTree.JCExpression; 61import com.sun.tools.javac.tree.JCTree.JCLambda; 62import com.sun.tools.javac.tree.JCTree.JCMethodDecl; 63import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; 64import com.sun.tools.javac.tree.JCTree.JCNewClass; 65import com.sun.tools.javac.tree.JCTree.JCTypeApply; 66import com.sun.tools.javac.tree.JCTree.JCVariableDecl; 67import com.sun.tools.javac.tree.TreeScanner; 68import com.sun.tools.javac.tree.JCTree.*; 69import com.sun.tools.javac.util.Assert; 70import com.sun.tools.javac.util.Context; 71import com.sun.tools.javac.util.List; 72import com.sun.tools.javac.util.ListBuffer; 73import com.sun.tools.javac.util.Log; 74import com.sun.tools.javac.util.Names; 75 76import static com.sun.tools.javac.code.Kinds.Kind.*; 77 78/** 79 * Contains operations specific to processing type annotations. 80 * This class has two functions: 81 * separate declaration from type annotations and insert the type 82 * annotations to their types; 83 * and determine the TypeAnnotationPositions for all type annotations. 84 */ 85public class TypeAnnotations { 86 protected static final Context.Key<TypeAnnotations> typeAnnosKey = new Context.Key<>(); 87 88 public static TypeAnnotations instance(Context context) { 89 TypeAnnotations instance = context.get(typeAnnosKey); 90 if (instance == null) 91 instance = new TypeAnnotations(context); 92 return instance; 93 } 94 95 final Log log; 96 final Names names; 97 final Symtab syms; 98 final Annotate annotate; 99 final Attr attr; 100 101 protected TypeAnnotations(Context context) { 102 context.put(typeAnnosKey, this); 103 names = Names.instance(context); 104 log = Log.instance(context); 105 syms = Symtab.instance(context); 106 annotate = Annotate.instance(context); 107 attr = Attr.instance(context); 108 } 109 110 /** 111 * Separate type annotations from declaration annotations and 112 * determine the correct positions for type annotations. 113 * This version only visits types in signatures and should be 114 * called from MemberEnter. 115 */ 116 public void organizeTypeAnnotationsSignatures(final Env<AttrContext> env, final JCClassDecl tree) { 117 annotate.afterTypes(new Runnable() { 118 @Override 119 public void run() { 120 JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile); 121 122 try { 123 new TypeAnnotationPositions(true).scan(tree); 124 } finally { 125 log.useSource(oldSource); 126 } 127 } 128 }); 129 } 130 131 public void validateTypeAnnotationsSignatures(final Env<AttrContext> env, final JCClassDecl tree) { 132 annotate.validate(new Runnable() { //validate annotations 133 @Override 134 public void run() { 135 JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile); 136 137 try { 138 attr.validateTypeAnnotations(tree, true); 139 } finally { 140 log.useSource(oldSource); 141 } 142 } 143 }); 144 } 145 146 /** 147 * This version only visits types in bodies, that is, field initializers, 148 * top-level blocks, and method bodies, and should be called from Attr. 149 */ 150 public void organizeTypeAnnotationsBodies(JCClassDecl tree) { 151 new TypeAnnotationPositions(false).scan(tree); 152 } 153 154 public enum AnnotationType { DECLARATION, TYPE, NONE, BOTH } 155 156 public List<Attribute> annotationTargets(TypeSymbol tsym) { 157 Attribute.Compound atTarget = tsym.getAnnotationTypeMetadata().getTarget(); 158 if (atTarget == null) { 159 return null; 160 } 161 162 Attribute atValue = atTarget.member(names.value); 163 if (!(atValue instanceof Attribute.Array)) { 164 return null; 165 } 166 167 List<Attribute> targets = ((Array)atValue).getValue(); 168 if (targets.stream().anyMatch(a -> !(a instanceof Attribute.Enum))) { 169 return null; 170 } 171 172 return targets; 173 } 174 175 /** 176 * Determine whether an annotation is a declaration annotation, 177 * a type annotation, or both. 178 */ 179 public AnnotationType annotationTargetType(Attribute.Compound a, Symbol s) { 180 List<Attribute> targets = annotationTargets(a.type.tsym); 181 return (targets == null) ? 182 AnnotationType.DECLARATION : 183 targets.stream() 184 .map(attr -> targetToAnnotationType(attr, s)) 185 .reduce(AnnotationType.NONE, this::combineAnnotationType); 186 } 187 188 private AnnotationType combineAnnotationType(AnnotationType at1, AnnotationType at2) { 189 if (at1 == AnnotationType.NONE) { 190 return at2; 191 } else if (at2 == AnnotationType.NONE) { 192 return at1; 193 } else if (at1 != at2) { 194 return AnnotationType.BOTH; 195 } else { 196 return at1; 197 } 198 } 199 200 private AnnotationType targetToAnnotationType(Attribute a, Symbol s) { 201 Attribute.Enum e = (Attribute.Enum)a; 202 if (e.value.name == names.TYPE) { 203 if (s.kind == TYP) 204 return AnnotationType.DECLARATION; 205 } else if (e.value.name == names.FIELD) { 206 if (s.kind == VAR && 207 s.owner.kind != MTH) 208 return AnnotationType.DECLARATION; 209 } else if (e.value.name == names.METHOD) { 210 if (s.kind == MTH && 211 !s.isConstructor()) 212 return AnnotationType.DECLARATION; 213 } else if (e.value.name == names.PARAMETER) { 214 if (s.kind == VAR && 215 s.owner.kind == MTH && 216 (s.flags() & Flags.PARAMETER) != 0) 217 return AnnotationType.DECLARATION; 218 } else if (e.value.name == names.CONSTRUCTOR) { 219 if (s.kind == MTH && 220 s.isConstructor()) 221 return AnnotationType.DECLARATION; 222 } else if (e.value.name == names.LOCAL_VARIABLE) { 223 if (s.kind == VAR && 224 s.owner.kind == MTH && 225 (s.flags() & Flags.PARAMETER) == 0) 226 return AnnotationType.DECLARATION; 227 } else if (e.value.name == names.ANNOTATION_TYPE) { 228 if (s.kind == TYP && 229 (s.flags() & Flags.ANNOTATION) != 0) 230 return AnnotationType.DECLARATION; 231 } else if (e.value.name == names.PACKAGE) { 232 if (s.kind == PCK) 233 return AnnotationType.DECLARATION; 234 } else if (e.value.name == names.TYPE_USE) { 235 if (s.kind == TYP || 236 s.kind == VAR || 237 (s.kind == MTH && !s.isConstructor() && 238 !s.type.getReturnType().hasTag(TypeTag.VOID)) || 239 (s.kind == MTH && s.isConstructor())) 240 return AnnotationType.TYPE; 241 } else if (e.value.name == names.TYPE_PARAMETER) { 242 /* Irrelevant in this case */ 243 // TYPE_PARAMETER doesn't aid in distinguishing between 244 // Type annotations and declaration annotations on an 245 // Element 246 } else { 247 Assert.error("annotationTargetType(): unrecognized Attribute name " + e.value.name + 248 " (" + e.value.name.getClass() + ")"); 249 return AnnotationType.DECLARATION; 250 } 251 return AnnotationType.NONE; 252 } 253 254 private class TypeAnnotationPositions extends TreeScanner { 255 256 private final boolean sigOnly; 257 258 TypeAnnotationPositions(boolean sigOnly) { 259 this.sigOnly = sigOnly; 260 } 261 262 /* 263 * When traversing the AST we keep the "frames" of visited 264 * trees in order to determine the position of annotations. 265 */ 266 private List<JCTree> frames = List.nil(); 267 268 protected void push(JCTree t) { 269 frames = frames.prepend(t); 270 } 271 protected JCTree pop() { 272 JCTree t = frames.head; 273 frames = frames.tail; 274 return t; 275 } 276 // could this be frames.elems.tail.head? 277 private JCTree peek2() { 278 return frames.tail.head; 279 } 280 281 @Override 282 public void scan(JCTree tree) { 283 push(tree); 284 try { 285 super.scan(tree); 286 } finally { 287 pop(); 288 } 289 } 290 291 /** 292 * Separates type annotations from declaration annotations. 293 * This step is needed because in certain locations (where declaration 294 * and type annotations can be mixed, e.g. the type of a field) 295 * we never build an JCAnnotatedType. This step finds these 296 * annotations and marks them as if they were part of the type. 297 */ 298 private void separateAnnotationsKinds(JCTree typetree, Type type, 299 Symbol sym, TypeAnnotationPosition pos) 300 { 301 List<Attribute.Compound> allAnnotations = sym.getRawAttributes(); 302 ListBuffer<Attribute.Compound> declAnnos = new ListBuffer<>(); 303 ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<>(); 304 ListBuffer<Attribute.TypeCompound> onlyTypeAnnos = new ListBuffer<>(); 305 306 for (Attribute.Compound a : allAnnotations) { 307 switch (annotationTargetType(a, sym)) { 308 case DECLARATION: 309 declAnnos.append(a); 310 break; 311 case BOTH: { 312 declAnnos.append(a); 313 Attribute.TypeCompound ta = toTypeCompound(a, pos); 314 typeAnnos.append(ta); 315 break; 316 } 317 case TYPE: { 318 Attribute.TypeCompound ta = toTypeCompound(a, pos); 319 typeAnnos.append(ta); 320 // Also keep track which annotations are only type annotations 321 onlyTypeAnnos.append(ta); 322 break; 323 } 324 } 325 } 326 327 // If we have no type annotations we are done for this Symbol 328 if (typeAnnos.isEmpty()) { 329 return; 330 } 331 332 // Reset decl annotations to the set {all - type only} 333 sym.resetAnnotations(); 334 sym.setDeclarationAttributes(declAnnos.toList()); 335 336 List<Attribute.TypeCompound> typeAnnotations = typeAnnos.toList(); 337 338 if (type == null) { 339 // When type is null, put the type annotations to the symbol. 340 // This is used for constructor return annotations, for which 341 // we use the type of the enclosing class. 342 type = sym.getEnclosingElement().asType(); 343 344 // Declaration annotations are always allowed on constructor returns. 345 // Therefore, use typeAnnotations instead of onlyTypeAnnos. 346 typeWithAnnotations(typetree, type, typeAnnotations, typeAnnotations, pos); 347 // Note that we don't use the result, the call to 348 // typeWithAnnotations side-effects the type annotation positions. 349 // This is important for constructors of nested classes. 350 sym.appendUniqueTypeAttributes(typeAnnotations); 351 return; 352 } 353 354 // type is non-null, add type annotations from declaration context to the type 355 type = typeWithAnnotations(typetree, type, typeAnnotations, onlyTypeAnnos.toList(), pos); 356 357 if (sym.getKind() == ElementKind.METHOD) { 358 sym.type.asMethodType().restype = type; 359 } else if (sym.getKind() == ElementKind.PARAMETER && currentLambda == null) { 360 sym.type = type; 361 if (sym.getQualifiedName().equals(names._this)) { 362 sym.owner.type.asMethodType().recvtype = type; 363 // note that the typeAnnotations will also be added to the owner below. 364 } else { 365 MethodType methType = sym.owner.type.asMethodType(); 366 List<VarSymbol> params = ((MethodSymbol)sym.owner).params; 367 List<Type> oldArgs = methType.argtypes; 368 ListBuffer<Type> newArgs = new ListBuffer<>(); 369 while (params.nonEmpty()) { 370 if (params.head == sym) { 371 newArgs.add(type); 372 } else { 373 newArgs.add(oldArgs.head); 374 } 375 oldArgs = oldArgs.tail; 376 params = params.tail; 377 } 378 methType.argtypes = newArgs.toList(); 379 } 380 } else { 381 sym.type = type; 382 } 383 384 sym.appendUniqueTypeAttributes(typeAnnotations); 385 386 if (sym.getKind() == ElementKind.PARAMETER || 387 sym.getKind() == ElementKind.LOCAL_VARIABLE || 388 sym.getKind() == ElementKind.RESOURCE_VARIABLE || 389 sym.getKind() == ElementKind.EXCEPTION_PARAMETER) { 390 // Make sure all type annotations from the symbol are also 391 // on the owner. 392 sym.owner.appendUniqueTypeAttributes(sym.getRawTypeAttributes()); 393 } 394 } 395 396 // This method has a similar purpose as 397 // {@link com.sun.tools.javac.parser.JavacParser.insertAnnotationsToMostInner(JCExpression, List<JCTypeAnnotation>, boolean)} 398 // We found a type annotation in a declaration annotation position, 399 // for example, on the return type. 400 // Such an annotation is _not_ part of an JCAnnotatedType tree and we therefore 401 // need to set its position explicitly. 402 // The method returns a copy of type that contains these annotations. 403 // 404 // As a side effect the method sets the type annotation position of "annotations". 405 // Note that it is assumed that all annotations share the same position. 406 private Type typeWithAnnotations(final JCTree typetree, final Type type, 407 final List<Attribute.TypeCompound> annotations, 408 final List<Attribute.TypeCompound> onlyTypeAnnotations, 409 final TypeAnnotationPosition pos) 410 { 411 if (annotations.isEmpty()) { 412 return type; 413 } 414 415 if (type.hasTag(TypeTag.ARRAY)) 416 return rewriteArrayType((ArrayType)type, annotations, pos); 417 418 if (type.hasTag(TypeTag.TYPEVAR)) { 419 return type.annotatedType(onlyTypeAnnotations); 420 } else if (type.getKind() == TypeKind.UNION) { 421 // There is a TypeKind, but no TypeTag. 422 JCTypeUnion tutree = (JCTypeUnion)typetree; 423 JCExpression fst = tutree.alternatives.get(0); 424 Type res = typeWithAnnotations(fst, fst.type, annotations, onlyTypeAnnotations, pos); 425 fst.type = res; 426 // TODO: do we want to set res as first element in uct.alternatives? 427 // UnionClassType uct = (com.sun.tools.javac.code.Type.UnionClassType)type; 428 // Return the un-annotated union-type. 429 return type; 430 } else { 431 Type enclTy = type; 432 Element enclEl = type.asElement(); 433 JCTree enclTr = typetree; 434 435 while (enclEl != null && 436 enclEl.getKind() != ElementKind.PACKAGE && 437 enclTy != null && 438 enclTy.getKind() != TypeKind.NONE && 439 enclTy.getKind() != TypeKind.ERROR && 440 (enclTr.getKind() == JCTree.Kind.MEMBER_SELECT || 441 enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE || 442 enclTr.getKind() == JCTree.Kind.ANNOTATED_TYPE)) { 443 // Iterate also over the type tree, not just the type: the type is already 444 // completely resolved and we cannot distinguish where the annotation 445 // belongs for a nested type. 446 if (enclTr.getKind() == JCTree.Kind.MEMBER_SELECT) { 447 // only change encl in this case. 448 enclTy = enclTy.getEnclosingType(); 449 enclEl = enclEl.getEnclosingElement(); 450 enclTr = ((JCFieldAccess)enclTr).getExpression(); 451 } else if (enclTr.getKind() == JCTree.Kind.PARAMETERIZED_TYPE) { 452 enclTr = ((JCTypeApply)enclTr).getType(); 453 } else { 454 // only other option because of while condition 455 enclTr = ((JCAnnotatedType)enclTr).getUnderlyingType(); 456 } 457 } 458 459 /** We are trying to annotate some enclosing type, 460 * but nothing more exists. 461 */ 462 if (enclTy != null && 463 enclTy.hasTag(TypeTag.NONE)) { 464 switch (onlyTypeAnnotations.size()) { 465 case 0: 466 // Don't issue an error if all type annotations are 467 // also declaration annotations. 468 // If the annotations are also declaration annotations, they are 469 // illegal as type annotations but might be legal as declaration annotations. 470 // The normal declaration annotation checks make sure that the use is valid. 471 break; 472 case 1: 473 log.error(typetree.pos(), "cant.type.annotate.scoping.1", 474 onlyTypeAnnotations); 475 break; 476 default: 477 log.error(typetree.pos(), "cant.type.annotate.scoping", 478 onlyTypeAnnotations); 479 } 480 return type; 481 } 482 483 // At this point we have visited the part of the nested 484 // type that is written in the source code. 485 // Now count from here to the actual top-level class to determine 486 // the correct nesting. 487 488 // The genericLocation for the annotation. 489 ListBuffer<TypePathEntry> depth = new ListBuffer<>(); 490 491 Type topTy = enclTy; 492 while (enclEl != null && 493 enclEl.getKind() != ElementKind.PACKAGE && 494 topTy != null && 495 topTy.getKind() != TypeKind.NONE && 496 topTy.getKind() != TypeKind.ERROR) { 497 topTy = topTy.getEnclosingType(); 498 enclEl = enclEl.getEnclosingElement(); 499 500 if (topTy != null && topTy.getKind() != TypeKind.NONE) { 501 // Only count enclosing types. 502 depth = depth.append(TypePathEntry.INNER_TYPE); 503 } 504 } 505 506 if (depth.nonEmpty()) { 507 // Only need to change the annotation positions 508 // if they are on an enclosed type. 509 // All annotations share the same position; modify the first one. 510 Attribute.TypeCompound a = annotations.get(0); 511 TypeAnnotationPosition p = a.position; 512 p.location = p.location.appendList(depth.toList()); 513 } 514 515 Type ret = typeWithAnnotations(type, enclTy, annotations); 516 typetree.type = ret; 517 return ret; 518 } 519 } 520 521 /** 522 * Create a copy of the {@code Type type} with the help of the Tree for a type 523 * {@code JCTree typetree} inserting all type annotations in {@code annotations} to the 524 * innermost array component type. 525 * 526 * SIDE EFFECT: Update position for the annotations to be {@code pos}. 527 */ 528 private Type rewriteArrayType(ArrayType type, List<TypeCompound> annotations, TypeAnnotationPosition pos) { 529 ArrayType tomodify = new ArrayType(type); 530 ArrayType res = tomodify; 531 532 List<TypePathEntry> loc = List.nil(); 533 534 // peel one and update loc 535 Type tmpType = type.elemtype; 536 loc = loc.prepend(TypePathEntry.ARRAY); 537 538 while (tmpType.hasTag(TypeTag.ARRAY)) { 539 ArrayType arr = (ArrayType)tmpType; 540 541 // Update last type with new element type 542 ArrayType tmp = new ArrayType(arr); 543 tomodify.elemtype = tmp; 544 tomodify = tmp; 545 546 tmpType = arr.elemtype; 547 loc = loc.prepend(TypePathEntry.ARRAY); 548 } 549 550 // Fix innermost element type 551 Type elemType; 552 if (tmpType.getMetadata() != null) { 553 List<TypeCompound> tcs; 554 if (tmpType.getAnnotationMirrors().isEmpty()) { 555 tcs = annotations; 556 } else { 557 // Special case, lets prepend 558 tcs = annotations.appendList(tmpType.getAnnotationMirrors()); 559 } 560 elemType = tmpType.cloneWithMetadata(tmpType 561 .getMetadata() 562 .without(Kind.ANNOTATIONS) 563 .combine(new TypeMetadata.Annotations(tcs))); 564 } else { 565 elemType = tmpType.cloneWithMetadata(new TypeMetadata(new TypeMetadata.Annotations(annotations))); 566 } 567 tomodify.elemtype = elemType; 568 569 // Update positions 570 for (TypeCompound tc : annotations) { 571 if (tc.position == null) 572 tc.position = pos; 573 tc.position.location = loc; 574 } 575 576 return res; 577 } 578 579 /** Return a copy of the first type that only differs by 580 * inserting the annotations to the left-most/inner-most type 581 * or the type given by stopAt. 582 * 583 * We need the stopAt parameter to know where on a type to 584 * put the annotations. 585 * If we have nested classes Outer > Middle > Inner, and we 586 * have the source type "@A Middle.Inner", we will invoke 587 * this method with type = Outer.Middle.Inner, 588 * stopAt = Middle.Inner, and annotations = @A. 589 * 590 * @param type The type to copy. 591 * @param stopAt The type to stop at. 592 * @param annotations The annotations to insert. 593 * @return A copy of type that contains the annotations. 594 */ 595 private Type typeWithAnnotations(final Type type, 596 final Type stopAt, 597 final List<Attribute.TypeCompound> annotations) { 598 Visitor<Type, List<TypeCompound>> visitor = 599 new Type.Visitor<Type, List<Attribute.TypeCompound>>() { 600 @Override 601 public Type visitClassType(ClassType t, List<TypeCompound> s) { 602 // assert that t.constValue() == null? 603 if (t == stopAt || 604 t.getEnclosingType() == Type.noType) { 605 return t.annotatedType(s); 606 } else { 607 ClassType ret = new ClassType(t.getEnclosingType().accept(this, s), 608 t.typarams_field, t.tsym, 609 t.getMetadata()); 610 ret.all_interfaces_field = t.all_interfaces_field; 611 ret.allparams_field = t.allparams_field; 612 ret.interfaces_field = t.interfaces_field; 613 ret.rank_field = t.rank_field; 614 ret.supertype_field = t.supertype_field; 615 return ret; 616 } 617 } 618 619 @Override 620 public Type visitWildcardType(WildcardType t, List<TypeCompound> s) { 621 return t.annotatedType(s); 622 } 623 624 @Override 625 public Type visitArrayType(ArrayType t, List<TypeCompound> s) { 626 ArrayType ret = new ArrayType(t.elemtype.accept(this, s), t.tsym, 627 t.getMetadata()); 628 return ret; 629 } 630 631 @Override 632 public Type visitMethodType(MethodType t, List<TypeCompound> s) { 633 // Impossible? 634 return t; 635 } 636 637 @Override 638 public Type visitPackageType(PackageType t, List<TypeCompound> s) { 639 // Impossible? 640 return t; 641 } 642 643 @Override 644 public Type visitTypeVar(TypeVar t, List<TypeCompound> s) { 645 return t.annotatedType(s); 646 } 647 648 @Override 649 public Type visitCapturedType(CapturedType t, List<TypeCompound> s) { 650 return t.annotatedType(s); 651 } 652 653 @Override 654 public Type visitForAll(ForAll t, List<TypeCompound> s) { 655 // Impossible? 656 return t; 657 } 658 659 @Override 660 public Type visitUndetVar(UndetVar t, List<TypeCompound> s) { 661 // Impossible? 662 return t; 663 } 664 665 @Override 666 public Type visitErrorType(ErrorType t, List<TypeCompound> s) { 667 return t.annotatedType(s); 668 } 669 670 @Override 671 public Type visitType(Type t, List<TypeCompound> s) { 672 return t.annotatedType(s); 673 } 674 }; 675 676 return type.accept(visitor, annotations); 677 } 678 679 private Attribute.TypeCompound toTypeCompound(Attribute.Compound a, TypeAnnotationPosition p) { 680 // It is safe to alias the position. 681 return new Attribute.TypeCompound(a, p); 682 } 683 684 685 /* This is the beginning of the second part of organizing 686 * type annotations: determine the type annotation positions. 687 */ 688 private TypeAnnotationPosition 689 resolveFrame(JCTree tree, 690 JCTree frame, 691 List<JCTree> path, 692 JCLambda currentLambda, 693 int outer_type_index, 694 ListBuffer<TypePathEntry> location) 695 { 696 697 // Note that p.offset is set in 698 // com.sun.tools.javac.jvm.Gen.setTypeAnnotationPositions(int) 699 700 switch (frame.getKind()) { 701 case TYPE_CAST: 702 return TypeAnnotationPosition.typeCast(location.toList(), 703 currentLambda, 704 outer_type_index, 705 frame.pos); 706 707 case INSTANCE_OF: 708 return TypeAnnotationPosition.instanceOf(location.toList(), 709 currentLambda, 710 frame.pos); 711 712 case NEW_CLASS: 713 final JCNewClass frameNewClass = (JCNewClass) frame; 714 if (frameNewClass.def != null) { 715 // Special handling for anonymous class instantiations 716 final JCClassDecl frameClassDecl = frameNewClass.def; 717 if (frameClassDecl.implementing.contains(tree)) { 718 final int type_index = 719 frameClassDecl.implementing.indexOf(tree); 720 return TypeAnnotationPosition 721 .classExtends(location.toList(), currentLambda, 722 type_index, frame.pos); 723 } else { 724 //for encl.new @TA Clazz(), tree may be different from frameClassDecl.extending 725 return TypeAnnotationPosition 726 .classExtends(location.toList(), currentLambda, 727 frame.pos); 728 } 729 } else if (frameNewClass.typeargs.contains(tree)) { 730 final int type_index = 731 frameNewClass.typeargs.indexOf(tree); 732 return TypeAnnotationPosition 733 .constructorInvocationTypeArg(location.toList(), 734 currentLambda, 735 type_index, 736 frame.pos); 737 } else { 738 return TypeAnnotationPosition 739 .newObj(location.toList(), currentLambda, 740 frame.pos); 741 } 742 743 case NEW_ARRAY: 744 return TypeAnnotationPosition 745 .newObj(location.toList(), currentLambda, frame.pos); 746 747 case ANNOTATION_TYPE: 748 case CLASS: 749 case ENUM: 750 case INTERFACE: 751 if (((JCClassDecl)frame).extending == tree) { 752 return TypeAnnotationPosition 753 .classExtends(location.toList(), currentLambda, 754 frame.pos); 755 } else if (((JCClassDecl)frame).implementing.contains(tree)) { 756 final int type_index = 757 ((JCClassDecl)frame).implementing.indexOf(tree); 758 return TypeAnnotationPosition 759 .classExtends(location.toList(), currentLambda, 760 type_index, frame.pos); 761 } else if (((JCClassDecl)frame).typarams.contains(tree)) { 762 final int parameter_index = 763 ((JCClassDecl)frame).typarams.indexOf(tree); 764 return TypeAnnotationPosition 765 .typeParameter(location.toList(), currentLambda, 766 parameter_index, frame.pos); 767 } else { 768 throw new AssertionError("Could not determine position of tree " + 769 tree + " within frame " + frame); 770 } 771 772 case METHOD: { 773 final JCMethodDecl frameMethod = (JCMethodDecl) frame; 774 if (frameMethod.thrown.contains(tree)) { 775 final int type_index = frameMethod.thrown.indexOf(tree); 776 return TypeAnnotationPosition 777 .methodThrows(location.toList(), currentLambda, 778 type_index, frame.pos); 779 } else if (frameMethod.restype == tree) { 780 return TypeAnnotationPosition 781 .methodReturn(location.toList(), currentLambda, 782 frame.pos); 783 } else if (frameMethod.typarams.contains(tree)) { 784 final int parameter_index = 785 frameMethod.typarams.indexOf(tree); 786 return TypeAnnotationPosition 787 .methodTypeParameter(location.toList(), 788 currentLambda, 789 parameter_index, frame.pos); 790 } else { 791 throw new AssertionError("Could not determine position of tree " + tree + 792 " within frame " + frame); 793 } 794 } 795 796 case PARAMETERIZED_TYPE: { 797 List<JCTree> newPath = path.tail; 798 799 if (((JCTypeApply)frame).clazz == tree) { 800 // generic: RAW; noop 801 } else if (((JCTypeApply)frame).arguments.contains(tree)) { 802 JCTypeApply taframe = (JCTypeApply) frame; 803 int arg = taframe.arguments.indexOf(tree); 804 location = location.prepend( 805 new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, 806 arg)); 807 808 Type typeToUse; 809 if (newPath.tail != null && 810 newPath.tail.head.hasTag(Tag.NEWCLASS)) { 811 // If we are within an anonymous class 812 // instantiation, use its type, because it 813 // contains a correctly nested type. 814 typeToUse = newPath.tail.head.type; 815 } else { 816 typeToUse = taframe.type; 817 } 818 819 location = locateNestedTypes(typeToUse, location); 820 } else { 821 throw new AssertionError("Could not determine type argument position of tree " + tree + 822 " within frame " + frame); 823 } 824 825 return resolveFrame(newPath.head, newPath.tail.head, 826 newPath, currentLambda, 827 outer_type_index, location); 828 } 829 830 case MEMBER_REFERENCE: { 831 JCMemberReference mrframe = (JCMemberReference) frame; 832 833 if (mrframe.expr == tree) { 834 switch (mrframe.mode) { 835 case INVOKE: 836 return TypeAnnotationPosition 837 .methodRef(location.toList(), currentLambda, 838 frame.pos); 839 case NEW: 840 return TypeAnnotationPosition 841 .constructorRef(location.toList(), 842 currentLambda, 843 frame.pos); 844 default: 845 throw new AssertionError("Unknown method reference mode " + mrframe.mode + 846 " for tree " + tree + " within frame " + frame); 847 } 848 } else if (mrframe.typeargs != null && 849 mrframe.typeargs.contains(tree)) { 850 final int type_index = mrframe.typeargs.indexOf(tree); 851 switch (mrframe.mode) { 852 case INVOKE: 853 return TypeAnnotationPosition 854 .methodRefTypeArg(location.toList(), 855 currentLambda, 856 type_index, frame.pos); 857 case NEW: 858 return TypeAnnotationPosition 859 .constructorRefTypeArg(location.toList(), 860 currentLambda, 861 type_index, frame.pos); 862 default: 863 throw new AssertionError("Unknown method reference mode " + mrframe.mode + 864 " for tree " + tree + " within frame " + frame); 865 } 866 } else { 867 throw new AssertionError("Could not determine type argument position of tree " + tree + 868 " within frame " + frame); 869 } 870 } 871 872 case ARRAY_TYPE: { 873 location = location.prepend(TypePathEntry.ARRAY); 874 List<JCTree> newPath = path.tail; 875 while (true) { 876 JCTree npHead = newPath.tail.head; 877 if (npHead.hasTag(JCTree.Tag.TYPEARRAY)) { 878 newPath = newPath.tail; 879 location = location.prepend(TypePathEntry.ARRAY); 880 } else if (npHead.hasTag(JCTree.Tag.ANNOTATED_TYPE)) { 881 newPath = newPath.tail; 882 } else { 883 break; 884 } 885 } 886 return resolveFrame(newPath.head, newPath.tail.head, 887 newPath, currentLambda, 888 outer_type_index, location); 889 } 890 891 case TYPE_PARAMETER: 892 if (path.tail.tail.head.hasTag(JCTree.Tag.CLASSDEF)) { 893 final JCClassDecl clazz = 894 (JCClassDecl)path.tail.tail.head; 895 final int parameter_index = 896 clazz.typarams.indexOf(path.tail.head); 897 final int bound_index = 898 ((JCTypeParameter)frame).bounds.get(0) 899 .type.isInterface() ? 900 ((JCTypeParameter)frame).bounds.indexOf(tree) + 1: 901 ((JCTypeParameter)frame).bounds.indexOf(tree); 902 return TypeAnnotationPosition 903 .typeParameterBound(location.toList(), 904 currentLambda, 905 parameter_index, bound_index, 906 frame.pos); 907 } else if (path.tail.tail.head.hasTag(JCTree.Tag.METHODDEF)) { 908 final JCMethodDecl method = 909 (JCMethodDecl)path.tail.tail.head; 910 final int parameter_index = 911 method.typarams.indexOf(path.tail.head); 912 final int bound_index = 913 ((JCTypeParameter)frame).bounds.get(0) 914 .type.isInterface() ? 915 ((JCTypeParameter)frame).bounds.indexOf(tree) + 1: 916 ((JCTypeParameter)frame).bounds.indexOf(tree); 917 return TypeAnnotationPosition 918 .methodTypeParameterBound(location.toList(), 919 currentLambda, 920 parameter_index, 921 bound_index, 922 frame.pos); 923 } else { 924 throw new AssertionError("Could not determine position of tree " + tree + 925 " within frame " + frame); 926 } 927 928 case VARIABLE: 929 VarSymbol v = ((JCVariableDecl)frame).sym; 930 if (v.getKind() != ElementKind.FIELD) { 931 v.owner.appendUniqueTypeAttributes(v.getRawTypeAttributes()); 932 } 933 switch (v.getKind()) { 934 case LOCAL_VARIABLE: 935 return TypeAnnotationPosition 936 .localVariable(location.toList(), currentLambda, 937 frame.pos); 938 case FIELD: 939 return TypeAnnotationPosition.field(location.toList(), 940 currentLambda, 941 frame.pos); 942 case PARAMETER: 943 if (v.getQualifiedName().equals(names._this)) { 944 return TypeAnnotationPosition 945 .methodReceiver(location.toList(), 946 currentLambda, 947 frame.pos); 948 } else { 949 final int parameter_index = 950 methodParamIndex(path, frame); 951 return TypeAnnotationPosition 952 .methodParameter(location.toList(), 953 currentLambda, 954 parameter_index, 955 frame.pos); 956 } 957 case EXCEPTION_PARAMETER: 958 return TypeAnnotationPosition 959 .exceptionParameter(location.toList(), 960 currentLambda, 961 frame.pos); 962 case RESOURCE_VARIABLE: 963 return TypeAnnotationPosition 964 .resourceVariable(location.toList(), 965 currentLambda, 966 frame.pos); 967 default: 968 throw new AssertionError("Found unexpected type annotation for variable: " + v + " with kind: " + v.getKind()); 969 } 970 971 case ANNOTATED_TYPE: { 972 if (frame == tree) { 973 // This is only true for the first annotated type we see. 974 // For any other annotated types along the path, we do 975 // not care about inner types. 976 JCAnnotatedType atypetree = (JCAnnotatedType) frame; 977 final Type utype = atypetree.underlyingType.type; 978 Assert.checkNonNull(utype); 979 Symbol tsym = utype.tsym; 980 if (tsym.getKind().equals(ElementKind.TYPE_PARAMETER) || 981 utype.getKind().equals(TypeKind.WILDCARD) || 982 utype.getKind().equals(TypeKind.ARRAY)) { 983 // Type parameters, wildcards, and arrays have the declaring 984 // class/method as enclosing elements. 985 // There is actually nothing to do for them. 986 } else { 987 location = locateNestedTypes(utype, location); 988 } 989 } 990 List<JCTree> newPath = path.tail; 991 return resolveFrame(newPath.head, newPath.tail.head, 992 newPath, currentLambda, 993 outer_type_index, location); 994 } 995 996 case UNION_TYPE: { 997 List<JCTree> newPath = path.tail; 998 return resolveFrame(newPath.head, newPath.tail.head, 999 newPath, currentLambda, 1000 outer_type_index, location); 1001 } 1002 1003 case INTERSECTION_TYPE: { 1004 JCTypeIntersection isect = (JCTypeIntersection)frame; 1005 final List<JCTree> newPath = path.tail; 1006 return resolveFrame(newPath.head, newPath.tail.head, 1007 newPath, currentLambda, 1008 isect.bounds.indexOf(tree), location); 1009 } 1010 1011 case METHOD_INVOCATION: { 1012 JCMethodInvocation invocation = (JCMethodInvocation)frame; 1013 if (!invocation.typeargs.contains(tree)) { 1014 throw new AssertionError("{" + tree + "} is not an argument in the invocation: " + invocation); 1015 } 1016 MethodSymbol exsym = (MethodSymbol) TreeInfo.symbol(invocation.getMethodSelect()); 1017 final int type_index = invocation.typeargs.indexOf(tree); 1018 if (exsym == null) { 1019 throw new AssertionError("could not determine symbol for {" + invocation + "}"); 1020 } else if (exsym.isConstructor()) { 1021 return TypeAnnotationPosition 1022 .constructorInvocationTypeArg(location.toList(), 1023 currentLambda, 1024 type_index, 1025 invocation.pos); 1026 } else { 1027 return TypeAnnotationPosition 1028 .methodInvocationTypeArg(location.toList(), 1029 currentLambda, 1030 type_index, 1031 invocation.pos); 1032 } 1033 } 1034 1035 case EXTENDS_WILDCARD: 1036 case SUPER_WILDCARD: { 1037 // Annotations in wildcard bounds 1038 final List<JCTree> newPath = path.tail; 1039 return resolveFrame(newPath.head, newPath.tail.head, 1040 newPath, currentLambda, 1041 outer_type_index, 1042 location.prepend(TypePathEntry.WILDCARD)); 1043 } 1044 1045 case MEMBER_SELECT: { 1046 final List<JCTree> newPath = path.tail; 1047 return resolveFrame(newPath.head, newPath.tail.head, 1048 newPath, currentLambda, 1049 outer_type_index, location); 1050 } 1051 1052 default: 1053 throw new AssertionError("Unresolved frame: " + frame + 1054 " of kind: " + frame.getKind() + 1055 "\n Looking for tree: " + tree); 1056 } 1057 } 1058 1059 private ListBuffer<TypePathEntry> 1060 locateNestedTypes(Type type, 1061 ListBuffer<TypePathEntry> depth) { 1062 Type encl = type.getEnclosingType(); 1063 while (encl != null && 1064 encl.getKind() != TypeKind.NONE && 1065 encl.getKind() != TypeKind.ERROR) { 1066 depth = depth.prepend(TypePathEntry.INNER_TYPE); 1067 encl = encl.getEnclosingType(); 1068 } 1069 return depth; 1070 } 1071 1072 private int methodParamIndex(List<JCTree> path, JCTree param) { 1073 List<JCTree> curr = path; 1074 while (curr.head.getTag() != Tag.METHODDEF && 1075 curr.head.getTag() != Tag.LAMBDA) { 1076 curr = curr.tail; 1077 } 1078 if (curr.head.getTag() == Tag.METHODDEF) { 1079 JCMethodDecl method = (JCMethodDecl)curr.head; 1080 return method.params.indexOf(param); 1081 } else if (curr.head.getTag() == Tag.LAMBDA) { 1082 JCLambda lambda = (JCLambda)curr.head; 1083 return lambda.params.indexOf(param); 1084 } else { 1085 Assert.error("methodParamIndex expected to find method or lambda for param: " + param); 1086 return -1; 1087 } 1088 } 1089 1090 // Each class (including enclosed inner classes) is visited separately. 1091 // This flag is used to prevent from visiting inner classes. 1092 private boolean isInClass = false; 1093 1094 @Override 1095 public void visitClassDef(JCClassDecl tree) { 1096 if (isInClass) 1097 return; 1098 isInClass = true; 1099 1100 if (sigOnly) { 1101 scan(tree.mods); 1102 scan(tree.typarams); 1103 scan(tree.extending); 1104 scan(tree.implementing); 1105 } 1106 scan(tree.defs); 1107 } 1108 1109 /** 1110 * Resolve declaration vs. type annotations in methods and 1111 * then determine the positions. 1112 */ 1113 @Override 1114 public void visitMethodDef(final JCMethodDecl tree) { 1115 if (tree.sym == null) { 1116 Assert.error("Visiting tree node before memberEnter"); 1117 } 1118 if (sigOnly) { 1119 if (!tree.mods.annotations.isEmpty()) { 1120 if (tree.sym.isConstructor()) { 1121 final TypeAnnotationPosition pos = 1122 TypeAnnotationPosition.methodReturn(tree.pos); 1123 // Use null to mark that the annotations go 1124 // with the symbol. 1125 separateAnnotationsKinds(tree, null, tree.sym, pos); 1126 } else { 1127 final TypeAnnotationPosition pos = 1128 TypeAnnotationPosition.methodReturn(tree.restype.pos); 1129 separateAnnotationsKinds(tree.restype, 1130 tree.sym.type.getReturnType(), 1131 tree.sym, pos); 1132 } 1133 } 1134 if (tree.recvparam != null && tree.recvparam.sym != null && 1135 !tree.recvparam.mods.annotations.isEmpty()) { 1136 // Nothing to do for separateAnnotationsKinds if 1137 // there are no annotations of either kind. 1138 // TODO: make sure there are no declaration annotations. 1139 final TypeAnnotationPosition pos = TypeAnnotationPosition.methodReceiver(tree.recvparam.vartype.pos); 1140 push(tree.recvparam); 1141 try { 1142 separateAnnotationsKinds(tree.recvparam.vartype, tree.recvparam.sym.type, tree.recvparam.sym, pos); 1143 } finally { 1144 pop(); 1145 } 1146 } 1147 int i = 0; 1148 for (JCVariableDecl param : tree.params) { 1149 if (!param.mods.annotations.isEmpty()) { 1150 // Nothing to do for separateAnnotationsKinds if 1151 // there are no annotations of either kind. 1152 final TypeAnnotationPosition pos = TypeAnnotationPosition.methodParameter(i, param.vartype.pos); 1153 push(param); 1154 try { 1155 separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos); 1156 } finally { 1157 pop(); 1158 } 1159 } 1160 ++i; 1161 } 1162 } 1163 1164 if (sigOnly) { 1165 scan(tree.mods); 1166 scan(tree.restype); 1167 scan(tree.typarams); 1168 scan(tree.recvparam); 1169 scan(tree.params); 1170 scan(tree.thrown); 1171 } else { 1172 scan(tree.defaultValue); 1173 scan(tree.body); 1174 } 1175 } 1176 1177 /* Store a reference to the current lambda expression, to 1178 * be used by all type annotations within this expression. 1179 */ 1180 private JCLambda currentLambda = null; 1181 1182 public void visitLambda(JCLambda tree) { 1183 JCLambda prevLambda = currentLambda; 1184 try { 1185 currentLambda = tree; 1186 1187 int i = 0; 1188 for (JCVariableDecl param : tree.params) { 1189 if (!param.mods.annotations.isEmpty()) { 1190 // Nothing to do for separateAnnotationsKinds if 1191 // there are no annotations of either kind. 1192 final TypeAnnotationPosition pos = TypeAnnotationPosition 1193 .methodParameter(tree, i, param.vartype.pos); 1194 push(param); 1195 try { 1196 separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos); 1197 } finally { 1198 pop(); 1199 } 1200 } 1201 ++i; 1202 } 1203 1204 scan(tree.body); 1205 scan(tree.params); 1206 } finally { 1207 currentLambda = prevLambda; 1208 } 1209 } 1210 1211 /** 1212 * Resolve declaration vs. type annotations in variable declarations and 1213 * then determine the positions. 1214 */ 1215 @Override 1216 public void visitVarDef(final JCVariableDecl tree) { 1217 if (tree.mods.annotations.isEmpty()) { 1218 // Nothing to do for separateAnnotationsKinds if 1219 // there are no annotations of either kind. 1220 } else if (tree.sym == null) { 1221 Assert.error("Visiting tree node before memberEnter"); 1222 } else if (tree.sym.getKind() == ElementKind.PARAMETER) { 1223 // Parameters are handled in visitMethodDef or visitLambda. 1224 } else if (tree.sym.getKind() == ElementKind.FIELD) { 1225 if (sigOnly) { 1226 TypeAnnotationPosition pos = 1227 TypeAnnotationPosition.field(tree.pos); 1228 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos); 1229 } 1230 } else if (tree.sym.getKind() == ElementKind.LOCAL_VARIABLE) { 1231 final TypeAnnotationPosition pos = 1232 TypeAnnotationPosition.localVariable(currentLambda, 1233 tree.pos); 1234 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos); 1235 } else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) { 1236 final TypeAnnotationPosition pos = 1237 TypeAnnotationPosition.exceptionParameter(currentLambda, 1238 tree.pos); 1239 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos); 1240 } else if (tree.sym.getKind() == ElementKind.RESOURCE_VARIABLE) { 1241 final TypeAnnotationPosition pos = 1242 TypeAnnotationPosition.resourceVariable(currentLambda, 1243 tree.pos); 1244 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos); 1245 } else if (tree.sym.getKind() == ElementKind.ENUM_CONSTANT) { 1246 // No type annotations can occur here. 1247 } else { 1248 // There is nothing else in a variable declaration that needs separation. 1249 Assert.error("Unhandled variable kind"); 1250 } 1251 1252 scan(tree.mods); 1253 scan(tree.vartype); 1254 if (!sigOnly) { 1255 scan(tree.init); 1256 } 1257 } 1258 1259 @Override 1260 public void visitBlock(JCBlock tree) { 1261 // Do not descend into top-level blocks when only interested 1262 // in the signature. 1263 if (!sigOnly) { 1264 scan(tree.stats); 1265 } 1266 } 1267 1268 @Override 1269 public void visitAnnotatedType(JCAnnotatedType tree) { 1270 push(tree); 1271 findPosition(tree, tree, tree.annotations); 1272 pop(); 1273 super.visitAnnotatedType(tree); 1274 } 1275 1276 @Override 1277 public void visitTypeParameter(JCTypeParameter tree) { 1278 findPosition(tree, peek2(), tree.annotations); 1279 super.visitTypeParameter(tree); 1280 } 1281 1282 private void copyNewClassAnnotationsToOwner(JCNewClass tree) { 1283 Symbol sym = tree.def.sym; 1284 final TypeAnnotationPosition pos = 1285 TypeAnnotationPosition.newObj(tree.pos); 1286 ListBuffer<Attribute.TypeCompound> newattrs = new ListBuffer<>(); 1287 1288 for (Attribute.TypeCompound old : sym.getRawTypeAttributes()) { 1289 newattrs.append(new Attribute.TypeCompound(old.type, old.values, 1290 pos)); 1291 } 1292 1293 sym.owner.appendUniqueTypeAttributes(newattrs.toList()); 1294 } 1295 1296 @Override 1297 public void visitNewClass(JCNewClass tree) { 1298 if (tree.def != null && 1299 !tree.def.mods.annotations.isEmpty()) { 1300 JCClassDecl classdecl = tree.def; 1301 TypeAnnotationPosition pos; 1302 1303 if (classdecl.extending == tree.clazz) { 1304 pos = TypeAnnotationPosition.classExtends(tree.pos); 1305 } else if (classdecl.implementing.contains(tree.clazz)) { 1306 final int index = classdecl.implementing.indexOf(tree.clazz); 1307 pos = TypeAnnotationPosition.classExtends(index, tree.pos); 1308 } else { 1309 // In contrast to CLASS elsewhere, typarams cannot occur here. 1310 throw new AssertionError("Could not determine position of tree " + tree); 1311 } 1312 Type before = classdecl.sym.type; 1313 separateAnnotationsKinds(classdecl, tree.clazz.type, classdecl.sym, pos); 1314 copyNewClassAnnotationsToOwner(tree); 1315 // classdecl.sym.type now contains an annotated type, which 1316 // is not what we want there. 1317 // TODO: should we put this type somewhere in the superclass/interface? 1318 classdecl.sym.type = before; 1319 } 1320 1321 scan(tree.encl); 1322 scan(tree.typeargs); 1323 scan(tree.clazz); 1324 scan(tree.args); 1325 1326 // The class body will already be scanned. 1327 // scan(tree.def); 1328 } 1329 1330 @Override 1331 public void visitNewArray(JCNewArray tree) { 1332 findPosition(tree, tree, tree.annotations); 1333 int dimAnnosCount = tree.dimAnnotations.size(); 1334 ListBuffer<TypePathEntry> depth = new ListBuffer<>(); 1335 1336 // handle annotations associated with dimensions 1337 for (int i = 0; i < dimAnnosCount; ++i) { 1338 ListBuffer<TypePathEntry> location = 1339 new ListBuffer<TypePathEntry>(); 1340 if (i != 0) { 1341 depth = depth.append(TypePathEntry.ARRAY); 1342 location = location.appendList(depth.toList()); 1343 } 1344 final TypeAnnotationPosition p = 1345 TypeAnnotationPosition.newObj(location.toList(), 1346 currentLambda, 1347 tree.pos); 1348 1349 setTypeAnnotationPos(tree.dimAnnotations.get(i), p); 1350 } 1351 1352 // handle "free" annotations 1353 // int i = dimAnnosCount == 0 ? 0 : dimAnnosCount - 1; 1354 // TODO: is depth.size == i here? 1355 JCExpression elemType = tree.elemtype; 1356 depth = depth.append(TypePathEntry.ARRAY); 1357 while (elemType != null) { 1358 if (elemType.hasTag(JCTree.Tag.ANNOTATED_TYPE)) { 1359 JCAnnotatedType at = (JCAnnotatedType)elemType; 1360 final ListBuffer<TypePathEntry> locationbuf = 1361 locateNestedTypes(elemType.type, 1362 new ListBuffer<TypePathEntry>()); 1363 final List<TypePathEntry> location = 1364 locationbuf.toList().prependList(depth.toList()); 1365 final TypeAnnotationPosition p = 1366 TypeAnnotationPosition.newObj(location, currentLambda, 1367 tree.pos); 1368 setTypeAnnotationPos(at.annotations, p); 1369 elemType = at.underlyingType; 1370 } else if (elemType.hasTag(JCTree.Tag.TYPEARRAY)) { 1371 depth = depth.append(TypePathEntry.ARRAY); 1372 elemType = ((JCArrayTypeTree)elemType).elemtype; 1373 } else if (elemType.hasTag(JCTree.Tag.SELECT)) { 1374 elemType = ((JCFieldAccess)elemType).selected; 1375 } else { 1376 break; 1377 } 1378 } 1379 scan(tree.elems); 1380 } 1381 1382 1383 private void findTypeCompoundPosition(JCTree tree, JCTree frame, List<Attribute.TypeCompound> annotations) { 1384 if (!annotations.isEmpty()) { 1385 final TypeAnnotationPosition p = 1386 resolveFrame(tree, frame, frames, currentLambda, 0, new ListBuffer<>()); 1387 for (TypeCompound tc : annotations) 1388 tc.position = p; 1389 } 1390 } 1391 1392 private void findPosition(JCTree tree, JCTree frame, List<JCAnnotation> annotations) { 1393 if (!annotations.isEmpty()) 1394 { 1395 final TypeAnnotationPosition p = 1396 resolveFrame(tree, frame, frames, currentLambda, 0, new ListBuffer<>()); 1397 1398 setTypeAnnotationPos(annotations, p); 1399 } 1400 } 1401 1402 private void setTypeAnnotationPos(List<JCAnnotation> annotations, TypeAnnotationPosition position) 1403 { 1404 // attribute might be null during DeferredAttr; 1405 // we will be back later. 1406 for (JCAnnotation anno : annotations) { 1407 if (anno.attribute != null) 1408 ((Attribute.TypeCompound) anno.attribute).position = position; 1409 } 1410 } 1411 1412 1413 @Override 1414 public String toString() { 1415 return super.toString() + ": sigOnly: " + sigOnly; 1416 } 1417 } 1418} 1419