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