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