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