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