1 /* 2 * Copyright (c) 1998, 2018, 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 package jdk.javadoc.internal.doclets.toolkit.util; 26 27 import java.util.*; 28 29 import javax.lang.model.element.AnnotationMirror; 30 import javax.lang.model.element.Element; 31 import javax.lang.model.element.ExecutableElement; 32 import javax.lang.model.element.PackageElement; 33 import javax.lang.model.element.TypeElement; 34 import javax.lang.model.element.TypeParameterElement; 35 import javax.lang.model.element.VariableElement; 36 import javax.lang.model.type.ArrayType; 37 import javax.lang.model.type.DeclaredType; 38 import javax.lang.model.type.ErrorType; 39 import javax.lang.model.type.TypeMirror; 40 import javax.lang.model.type.TypeVariable; 41 import javax.lang.model.type.WildcardType; 42 import javax.lang.model.util.ElementFilter; 43 import javax.lang.model.util.Elements; 44 import javax.lang.model.util.SimpleElementVisitor14; 45 import javax.lang.model.util.SimpleTypeVisitor9; 46 import javax.lang.model.util.Types; 47 48 import jdk.javadoc.doclet.DocletEnvironment; 49 import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration; 50 51 import static jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberTable.Kind.*; 52 53 /** 54 * Map all class uses for a given class. 55 * 56 * <p> 57 * <b>This is NOT part of any supported API. If you write code that depends on this, you do so at 58 * your own risk. This code and its internal interfaces are subject to change or deletion without 59 * notice.</b> 60 * 61 * @author Robert G. Field 62 */ 63 public class ClassUseMapper { 64 65 private final ClassTree classtree; 66 67 /** 68 * Mapping of TypeElements to set of PackageElements used by that class. 69 */ 70 public final Map<TypeElement, Set<PackageElement>> classToPackage; 71 72 /** 73 * Mapping of TypeElements representing annotations to a set of PackageElements that use the annotation. 74 */ 75 public final Map<TypeElement, List<PackageElement>> classToPackageAnnotations = new HashMap<>(); 76 77 /** 78 * Mapping of TypeElements to a set of TypeElements used by that class. 79 */ 80 public final Map<TypeElement, Set<TypeElement>> classToClass = new HashMap<>(); 81 82 /** 83 * Mapping of TypeElements to a list of TypeElements which are direct or indirect subClasses of 84 * that class. 85 */ 86 public final Map<TypeElement, List<TypeElement>> classToSubclass = new HashMap<>(); 87 88 /** 89 * Mapping of TypeElements to list of TypeElements which are direct or indirect subInterfaces of 90 * that interface. 91 */ 92 public final Map<TypeElement, List<TypeElement>> classToSubinterface = new HashMap<>(); 93 94 /** 95 * Mapping of TypeElements to list of TypeElements which implement this interface. 96 */ 97 public Map<TypeElement, List<TypeElement>> classToImplementingClass = new HashMap<>(); 98 99 /** 100 * Mapping of TypeElements to list of VariableElements declared as that class. 101 */ 102 public final Map<TypeElement, List<VariableElement>> classToField = new HashMap<>(); 103 104 /** 105 * Mapping of TypeElements to list of ExecutableElements returning that class. 106 */ 107 public final Map<TypeElement, List<ExecutableElement>> classToMethodReturn = new HashMap<>(); 108 109 /** 110 * Mapping of TypeElements to list of ExecutableElements having that class as an arg. 111 */ 112 public final Map<TypeElement, List<ExecutableElement>> classToMethodArgs = new HashMap<>(); 113 114 /** 115 * Mapping of TypeElements to list of ExecutableElements which throws that class. 116 */ 117 public final Map<TypeElement, List<ExecutableElement>> classToMethodThrows = new HashMap<>(); 118 119 /** 120 * Mapping of TypeElements to list of ExecutableElements (constructors) having that 121 * class as an arg. 122 */ 123 public final Map<TypeElement, List<ExecutableElement>> classToConstructorArgs = new HashMap<>(); 124 125 /** 126 * Mapping of TypeElements to list of constructors which throws that class. 127 */ 128 public final Map<TypeElement, List<ExecutableElement>> classToConstructorThrows = new HashMap<>(); 129 130 /** 131 * The mapping of TypeElements representing annotations to constructors that use them. 132 */ 133 public final Map<TypeElement, List<ExecutableElement>> classToConstructorAnnotations = new HashMap<>(); 134 135 /** 136 * The mapping of TypeElement representing annotations to constructor parameters that use them. 137 */ 138 public final Map<TypeElement, List<ExecutableElement>> classToConstructorParamAnnotation = new HashMap<>(); 139 140 /** 141 * The mapping of TypeElements to constructor arguments that use them as type parameters. 142 */ 143 public final Map<TypeElement, List<ExecutableElement>> classToConstructorArgTypeParam = new HashMap<>(); 144 145 /** 146 * The mapping of TypeElement to TypeElement that use them as type parameters. 147 */ 148 public final Map<TypeElement, List<TypeElement>> classToClassTypeParam = new HashMap<>(); 149 150 /** 151 * The mapping of TypeElement representing annotation to TypeElements that use them. 152 */ 153 public final Map<TypeElement, List<TypeElement>> classToClassAnnotations = new HashMap<>(); 154 155 /** 156 * The mapping of TypeElement to methods that use them as type parameters. 157 */ 158 public final Map<TypeElement, List<ExecutableElement>> classToMethodTypeParam = new HashMap<>(); 159 160 /** 161 * The mapping of TypeElement to method arguments that use them as type parameters. 162 */ 163 public final Map<TypeElement, List<ExecutableElement>> classToMethodArgTypeParam = new HashMap<>(); 164 165 /** 166 * The mapping of TypeElement representing annotation to methods that use them. 167 */ 168 public final Map<TypeElement, List<ExecutableElement>> classToMethodAnnotations = new HashMap<>(); 169 170 /** 171 * The mapping of TypeElements to methods that have return type with type parameters 172 * of that class. 173 */ 174 public final Map<TypeElement, List<ExecutableElement>> classToMethodReturnTypeParam = new HashMap<>(); 175 176 /** 177 * The mapping of TypeElements representing annotations to method parameters that use them. 178 */ 179 public final Map<TypeElement, List<ExecutableElement>> classToMethodParamAnnotation = new HashMap<>(); 180 181 /** 182 * The mapping of TypeElements to fields that use them as type parameters. 183 */ 184 public final Map<TypeElement, List<VariableElement>> classToFieldTypeParam = new HashMap<>(); 185 186 /** 187 * The mapping of TypeElements representing annotation to fields that use them. 188 */ 189 public final Map<TypeElement, List<VariableElement>> annotationToField = new HashMap<>(); 190 191 private final DocletEnvironment docEnv; 192 private final Elements elementUtils; 193 private final Types typeUtils; 194 private final Utils utils; 195 196 public ClassUseMapper(BaseConfiguration configuration, ClassTree classtree) { 197 docEnv = configuration.docEnv; 198 elementUtils = docEnv.getElementUtils(); 199 typeUtils = docEnv.getTypeUtils(); 200 utils = configuration.utils; 201 this.classtree = classtree; 202 classToPackage = new TreeMap<>(utils.makeClassUseComparator()); 203 // Map subclassing, subinterfacing implementing, ... 204 for (TypeElement te : classtree.baseClasses()) { 205 subclasses(te); 206 } 207 for (TypeElement intfc : classtree.baseInterfaces()) { 208 // does subinterfacing as side-effect 209 implementingClasses(intfc); 210 } 211 // Map methods, fields, constructors using a class. 212 Set<TypeElement> classes = configuration.getIncludedTypeElements(); 213 for (TypeElement aClass : classes) { 214 PackageElement pkg = elementUtils.getPackageOf(aClass); 215 mapAnnotations(classToPackageAnnotations, pkg, pkg); 216 mapTypeParameters(classToClassTypeParam, aClass, aClass); 217 mapAnnotations(classToClassAnnotations, aClass, aClass); 218 VisibleMemberTable vmt = configuration.getVisibleMemberTable(aClass); 219 220 List<VariableElement> fields = ElementFilter.fieldsIn(vmt.getVisibleMembers(FIELDS)); 221 for (VariableElement fd : fields) { 222 mapTypeParameters(classToFieldTypeParam, fd, fd); 223 mapAnnotations(annotationToField, fd, fd); 224 SimpleTypeVisitor9<Void, VariableElement> stv = new SimpleTypeVisitor9<Void, VariableElement>() { 225 @Override 226 public Void visitArray(ArrayType t, VariableElement p) { 227 return visit(t.getComponentType(), p); 228 } 229 230 @Override 231 public Void visitDeclared(DeclaredType t, VariableElement p) { 232 add(classToField, (TypeElement) t.asElement(), p); 233 return null; 234 } 235 @Override 236 public Void visitTypeVariable(TypeVariable t, VariableElement p) { 237 return visit(typeUtils.erasure(t), p); 238 } 239 }; 240 stv.visit(fd.asType(), fd); 241 } 242 243 List<ExecutableElement> ctors = ElementFilter.constructorsIn(vmt.getMembers(CONSTRUCTORS)); 244 for (ExecutableElement ctor : ctors) { 245 mapAnnotations(classToConstructorAnnotations, ctor, ctor); 246 mapExecutable(ctor); 247 } 248 249 List<ExecutableElement> methods = ElementFilter.methodsIn(vmt.getMembers(METHODS)); 250 251 for (ExecutableElement method : methods) { 252 mapExecutable(method); 253 mapTypeParameters(classToMethodTypeParam, method, method); 254 mapAnnotations(classToMethodAnnotations, method, method); 255 SimpleTypeVisitor9<Void, ExecutableElement> stv = new SimpleTypeVisitor9<Void, ExecutableElement>() { 256 @Override 257 public Void visitArray(ArrayType t, ExecutableElement p) { 258 TypeMirror componentType = t.getComponentType(); 259 return visit(utils.isTypeVariable(componentType) 260 ? typeUtils.erasure(componentType) 261 : componentType, p); 262 } 263 264 @Override 265 public Void visitDeclared(DeclaredType t, ExecutableElement p) { 266 mapTypeParameters(classToMethodReturnTypeParam, t, p); 267 add(classToMethodReturn, (TypeElement) t.asElement(), p); 268 return null; 269 } 270 271 @Override 272 protected Void defaultAction(TypeMirror e, ExecutableElement p) { 273 return null; 274 } 275 }; 276 stv.visit(method.getReturnType(), method); 277 } 278 } 279 } 280 281 /** 282 * Return all subClasses of a class AND fill-in classToSubclass map. 283 */ 284 private Collection<TypeElement> subclasses(TypeElement te) { 285 Collection<TypeElement> ret = classToSubclass.get(te); 286 if (ret == null) { 287 ret = new TreeSet<>(utils.makeClassUseComparator()); 288 Set<TypeElement> subs = classtree.subClasses(te); 289 if (subs != null) { 290 ret.addAll(subs); 291 for (TypeElement sub : subs) { 292 ret.addAll(subclasses(sub)); 293 } 294 } 295 addAll(classToSubclass, te, ret); 296 } 297 return ret; 298 } 299 300 /** 301 * Return all subInterfaces of an interface AND fill-in classToSubinterface map. 302 */ 303 private Collection<TypeElement> subinterfaces(TypeElement te) { 304 Collection<TypeElement> ret = classToSubinterface.get(te); 305 if (ret == null) { 306 ret = new TreeSet<>(utils.makeClassUseComparator()); 307 Set<TypeElement> subs = classtree.subInterfaces(te); 308 if (subs != null) { 309 ret.addAll(subs); 310 for (TypeElement sub : subs) { 311 ret.addAll(subinterfaces(sub)); 312 } 313 } 314 addAll(classToSubinterface, te, ret); 315 } 316 return ret; 317 } 318 319 /** 320 * Return all implementing classes of an interface (including all subClasses of implementing 321 * classes and all classes implementing subInterfaces) AND fill-in both classToImplementingClass 322 * and classToSubinterface maps. 323 */ 324 private Collection<TypeElement> implementingClasses(TypeElement te) { 325 Collection<TypeElement> ret = classToImplementingClass.get(te); 326 if (ret == null) { 327 ret = new TreeSet<>(utils.makeClassUseComparator()); 328 Set<TypeElement> impl = classtree.implementingClasses(te); 329 if (impl != null) { 330 ret.addAll(impl); 331 for (TypeElement anImpl : impl) { 332 ret.addAll(subclasses(anImpl)); 333 } 334 } 335 for (TypeElement intfc : subinterfaces(te)) { 336 ret.addAll(implementingClasses(intfc)); 337 } 338 addAll(classToImplementingClass, te, ret); 339 } 340 return ret; 341 } 342 343 /** 344 * Determine classes used by a method or constructor, so they can be inverse mapped. 345 */ 346 private void mapExecutable(ExecutableElement ee) { 347 final boolean isConstructor = utils.isConstructor(ee); 348 Set<TypeMirror> classArgs = new TreeSet<>(utils.makeTypeMirrorClassUseComparator()); 349 for (VariableElement param : ee.getParameters()) { 350 TypeMirror pType = param.asType(); 351 // primitives don't get mapped and type variables are mapped elsewhere 352 if (!pType.getKind().isPrimitive() && !utils.isTypeVariable(pType)) { 353 // no duplicates please 354 if (classArgs.add(pType)) { 355 new SimpleTypeVisitor9<Void, ExecutableElement>() { 356 @Override 357 public Void visitArray(ArrayType t, ExecutableElement p) { 358 return visit(t.getComponentType(), p); 359 } 360 361 @Override 362 public Void visitDeclared(DeclaredType t, ExecutableElement p) { 363 add(isConstructor 364 ? classToConstructorArgs 365 : classToMethodArgs, 366 (TypeElement) t.asElement(), p); 367 return null; 368 } 369 @Override 370 public Void visitTypeVariable(TypeVariable t, ExecutableElement p) { 371 visit(typeUtils.erasure(t), p); 372 return null; 373 } 374 }.visit(pType, ee); 375 mapTypeParameters(isConstructor 376 ? classToConstructorArgTypeParam 377 : classToMethodArgTypeParam, 378 pType, ee); 379 } 380 } 381 mapAnnotations(isConstructor 382 ? classToConstructorParamAnnotation 383 : classToMethodParamAnnotation, 384 param, ee); 385 386 } 387 for (TypeMirror anException : ee.getThrownTypes()) { 388 SimpleTypeVisitor9<Void, ExecutableElement> stv = new SimpleTypeVisitor9<Void, ExecutableElement>() { 389 390 @Override 391 public Void visitArray(ArrayType t, ExecutableElement p) { 392 super.visit(t.getComponentType(), p); 393 return null; 394 } 395 396 @Override 397 public Void visitDeclared(DeclaredType t, ExecutableElement p) { 398 add(isConstructor ? classToConstructorThrows : classToMethodThrows, 399 (TypeElement) t.asElement(), p); 400 return null; 401 } 402 403 @Override 404 public Void visitError(ErrorType t, ExecutableElement p) { 405 add(isConstructor ? classToConstructorThrows : classToMethodThrows, 406 (TypeElement) t.asElement(), p); 407 return null; 408 } 409 410 @Override 411 protected Void defaultAction(TypeMirror e, ExecutableElement p) { 412 throw new AssertionError("this should not happen"); 413 } 414 }; 415 416 stv.visit(typeUtils.erasure(anException), ee); 417 } 418 } 419 420 private <T> List<T> refList(Map<TypeElement, List<T>> map, TypeElement element) { 421 List<T> list = map.get(element); 422 if (list == null) { 423 list = new ArrayList<>(); 424 map.put(element, list); 425 } 426 return list; 427 } 428 429 private Set<PackageElement> packageSet(TypeElement te) { 430 Set<PackageElement> pkgSet = classToPackage.get(te); 431 if (pkgSet == null) { 432 pkgSet = new TreeSet<>(utils.makeClassUseComparator()); 433 classToPackage.put(te, pkgSet); 434 } 435 return pkgSet; 436 } 437 438 private Set<TypeElement> classSet(TypeElement te) { 439 Set<TypeElement> clsSet = classToClass.get(te); 440 if (clsSet == null) { 441 clsSet = new TreeSet<>(utils.makeClassUseComparator()); 442 classToClass.put(te, clsSet); 443 } 444 return clsSet; 445 } 446 447 private <T extends Element> void add(Map<TypeElement, List<T>> map, TypeElement te, T ref) { 448 // add to specified map 449 refList(map, te).add(ref); 450 // add ref's package to package map and class map 451 packageSet(te).add(elementUtils.getPackageOf(ref)); 452 TypeElement entry = (utils.isField((Element) ref) 453 || utils.isConstructor((Element) ref) 454 || utils.isMethod((Element) ref)) 455 ? (TypeElement) ref.getEnclosingElement() 456 : (TypeElement) ref; 457 classSet(te).add(entry); 458 } 459 460 private void addAll(Map<TypeElement, List<TypeElement>> map, TypeElement te, Collection<TypeElement> refs) { 461 if (refs == null) { 462 return; 463 } 464 // add to specified map 465 refList(map, te).addAll(refs); 466 467 Set<PackageElement> pkgSet = packageSet(te); 468 Set<TypeElement> clsSet = classSet(te); 469 // add ref's package to package map and class map 470 for (TypeElement cls : refs) { 471 pkgSet.add(utils.containingPackage(cls)); 472 clsSet.add(cls); 473 } 474 } 475 476 /** 477 * Map the TypeElements to the members that use them as type parameters. 478 * 479 * @param map the map the insert the information into. 480 * @param element the te whose type parameters are being checked. 481 * @param holder the holder that owns the type parameters. 482 */ 483 private <T extends Element> void mapTypeParameters(final Map<TypeElement, List<T>> map, 484 Element element, final T holder) { 485 486 @SuppressWarnings("preview") 487 SimpleElementVisitor14<Void, Void> elementVisitor 488 = new SimpleElementVisitor14<Void, Void>() { 489 490 private void addParameters(TypeParameterElement e) { 491 for (TypeMirror type : utils.getBounds(e)) { 492 addTypeParameterToMap(map, type, holder); 493 } 494 } 495 496 @Override 497 public Void visitType(TypeElement e, Void p) { 498 for (TypeParameterElement param : e.getTypeParameters()) { 499 addParameters(param); 500 } 501 return null; 502 } 503 504 @Override 505 public Void visitExecutable(ExecutableElement e, Void p) { 506 for (TypeParameterElement param : e.getTypeParameters()) { 507 addParameters(param); 508 } 509 return null; 510 } 511 512 @Override 513 protected Void defaultAction(Element e, Void p) { 514 mapTypeParameters(map, e.asType(), holder); 515 return null; 516 } 517 518 @Override 519 public Void visitTypeParameter(TypeParameterElement e, Void p) { 520 addParameters(e); 521 return null; 522 } 523 }; 524 elementVisitor.visit(element); 525 } 526 527 private <T extends Element> void mapTypeParameters(final Map<TypeElement, List<T>> map, 528 TypeMirror aType, final T holder) { 529 530 SimpleTypeVisitor9<Void, Void> tv = new SimpleTypeVisitor9<Void, Void>() { 531 532 @Override 533 public Void visitWildcard(WildcardType t, Void p) { 534 TypeMirror bound = t.getExtendsBound(); 535 if (bound != null) { 536 addTypeParameterToMap(map, bound, holder); 537 } 538 bound = t.getSuperBound(); 539 if (bound != null) { 540 addTypeParameterToMap(map, bound, holder); 541 } 542 return null; 543 } 544 545 // ParameterizedType 546 @Override 547 public Void visitDeclared(DeclaredType t, Void p) { 548 for (TypeMirror targ : t.getTypeArguments()) { 549 addTypeParameterToMap(map, targ, holder); 550 } 551 return null; 552 } 553 }; 554 tv.visit(aType); 555 } 556 557 /** 558 * Map the AnnotationType to the members that use them as type parameters. 559 * 560 * @param map the map the insert the information into. 561 * @param e whose type parameters are being checked. 562 * @param holder owning the type parameters. 563 */ 564 @SuppressWarnings("preview") 565 private <T extends Element> void mapAnnotations(final Map<TypeElement, List<T>> map, 566 Element e, final T holder) { 567 new SimpleElementVisitor14<Void, Void>() { 568 569 void addAnnotations(Element e) { 570 for (AnnotationMirror a : e.getAnnotationMirrors()) { 571 add(map, (TypeElement) a.getAnnotationType().asElement(), holder); 572 } 573 } 574 575 @Override 576 public Void visitPackage(PackageElement e, Void p) { 577 for (AnnotationMirror a : e.getAnnotationMirrors()) { 578 refList(map, (TypeElement) a.getAnnotationType().asElement()).add(holder); 579 } 580 return null; 581 } 582 583 @Override 584 protected Void defaultAction(Element e, Void p) { 585 addAnnotations(e); 586 return null; 587 } 588 }.visit(e); 589 } 590 591 private <T extends Element> void addTypeParameterToMap(final Map<TypeElement, List<T>> map, 592 TypeMirror type, final T holder) { 593 new SimpleTypeVisitor9<Void, Void>() { 594 595 @Override 596 protected Void defaultAction(TypeMirror e, Void p) { 597 return super.defaultAction(e, p); 598 } 599 600 @Override 601 public Void visitDeclared(DeclaredType t, Void p) { 602 add(map, (TypeElement) t.asElement(), holder); 603 return null; 604 } 605 606 }.visit(type); 607 mapTypeParameters(map, type, holder); 608 } 609 }