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