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