mirror of
https://github.com/openjdk/jdk.git
synced 2026-07-31 13:15:26 +00:00
8285939: javadoc java.lang.Record should not have "Direct Known Subclasses:" section
Reviewed-by: prappo, hannesw
This commit is contained in:
parent
f5bbade9e4
commit
8fc201e5bb
@ -25,17 +25,19 @@
|
||||
|
||||
package jdk.javadoc.internal.doclets.formats.html;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.lang.model.element.TypeElement;
|
||||
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.TagName;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.TagName;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.ClassTree.Hierarchy;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
|
||||
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import java.util.Collection;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract class to print the class hierarchy page for all the Classes. This
|
||||
@ -48,20 +50,19 @@ public abstract class AbstractTreeWriter extends HtmlDocletWriter {
|
||||
/**
|
||||
* The class and interface tree built by using {@link ClassTree}
|
||||
*/
|
||||
protected final ClassTree classtree;
|
||||
protected final ClassTree classTree;
|
||||
|
||||
/**
|
||||
* Constructor initializes classtree variable. This constructor will be used
|
||||
* while generating global tree file "overview-tree.html".
|
||||
* Constructor. This constructor will be used while generating global tree file "overview-tree.html".
|
||||
*
|
||||
* @param configuration The current configuration
|
||||
* @param filename File to be generated.
|
||||
* @param classtree Tree built by {@link ClassTree}.
|
||||
* @param classTree Tree built by {@link ClassTree}.
|
||||
*/
|
||||
protected AbstractTreeWriter(HtmlConfiguration configuration,
|
||||
DocPath filename, ClassTree classtree) {
|
||||
DocPath filename, ClassTree classTree) {
|
||||
super(configuration, filename);
|
||||
this.classtree = classtree;
|
||||
this.classTree = classTree;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,11 +72,11 @@ public abstract class AbstractTreeWriter extends HtmlDocletWriter {
|
||||
*
|
||||
* @param parent the superclass or superinterface of the sset
|
||||
* @param collection a collection of the sub-classes at this level
|
||||
* @param isEnum true if we are generating a tree for enums
|
||||
* @param hierarchy the hierarchy for which we are generating a tree
|
||||
* @param content the content to which the level information will be added
|
||||
*/
|
||||
protected void addLevelInfo(TypeElement parent, Collection<TypeElement> collection,
|
||||
boolean isEnum, Content content) {
|
||||
Hierarchy hierarchy, Content content) {
|
||||
if (!collection.isEmpty()) {
|
||||
var ul = new HtmlTree(TagName.UL);
|
||||
for (TypeElement local : collection) {
|
||||
@ -83,8 +84,7 @@ public abstract class AbstractTreeWriter extends HtmlDocletWriter {
|
||||
li.setStyle(HtmlStyle.circle);
|
||||
addPartialInfo(local, li);
|
||||
addExtendsImplements(parent, local, li);
|
||||
addLevelInfo(local, classtree.directSubClasses(local, isEnum),
|
||||
isEnum, li); // Recurse
|
||||
addLevelInfo(local, hierarchy.subtypes(local), hierarchy, li); // Recurse
|
||||
ul.add(li);
|
||||
}
|
||||
content.add(ul);
|
||||
@ -92,35 +92,28 @@ public abstract class AbstractTreeWriter extends HtmlDocletWriter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the heading for the tree depending upon tree type if it's a
|
||||
* Class Tree or Interface tree.
|
||||
* Adds a class or interface hierarchy with a given heading to given content.
|
||||
*
|
||||
* @param sset classes which are at the most base level, all the
|
||||
* other classes in this run will derive from these classes
|
||||
* @param heading heading for the tree
|
||||
* @param content the content to which the tree will be added
|
||||
* @param hierarchy the hierarchy to add
|
||||
* @param heading the heading
|
||||
* @param content the content to which to add the hierarchy
|
||||
*/
|
||||
protected void addTree(SortedSet<TypeElement> sset, String heading, Content content) {
|
||||
addTree(sset, heading, content, false);
|
||||
}
|
||||
|
||||
protected void addTree(SortedSet<TypeElement> sset, String heading,
|
||||
Content content, boolean isEnums) {
|
||||
if (!sset.isEmpty()) {
|
||||
TypeElement firstTypeElement = sset.first();
|
||||
protected void addTree(Hierarchy hierarchy, String heading, Content content) {
|
||||
SortedSet<TypeElement> roots = hierarchy.roots();
|
||||
if (!roots.isEmpty()) {
|
||||
TypeElement firstTypeElement = roots.first();
|
||||
Content headingContent = contents.getContent(heading);
|
||||
var sectionHeading = HtmlTree.HEADING_TITLE(Headings.CONTENT_HEADING,
|
||||
headingContent);
|
||||
var section = HtmlTree.SECTION(HtmlStyle.hierarchy, sectionHeading);
|
||||
addLevelInfo(!utils.isPlainInterface(firstTypeElement) ? firstTypeElement : null,
|
||||
sset, isEnums, section);
|
||||
roots, hierarchy, section);
|
||||
content.add(section);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add information regarding the classes which this class extends or
|
||||
* implements.
|
||||
* Add information regarding the classes which this class extends or implements.
|
||||
*
|
||||
* @param parent the parent class of the class being documented
|
||||
* @param typeElement the TypeElement under consideration
|
||||
|
||||
@ -143,11 +143,11 @@ public class ClassUseWriter extends SubWriterHolderWriter {
|
||||
* Write out class use pages.
|
||||
*
|
||||
* @param configuration the configuration for this doclet
|
||||
* @param classtree the class tree hierarchy
|
||||
* @param classTree the class tree hierarchy
|
||||
* @throws DocFileIOException if there is an error while generating the documentation
|
||||
*/
|
||||
public static void generate(HtmlConfiguration configuration, ClassTree classtree) throws DocFileIOException {
|
||||
ClassUseMapper mapper = new ClassUseMapper(configuration, classtree);
|
||||
public static void generate(HtmlConfiguration configuration, ClassTree classTree) throws DocFileIOException {
|
||||
ClassUseMapper mapper = new ClassUseMapper(configuration, classTree);
|
||||
boolean nodeprecated = configuration.getOptions().noDeprecated();
|
||||
Utils utils = configuration.utils;
|
||||
for (TypeElement aClass : configuration.getIncludedTypeElements()) {
|
||||
|
||||
@ -77,7 +77,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
|
||||
|
||||
protected final TypeElement typeElement;
|
||||
|
||||
protected final ClassTree classtree;
|
||||
protected final ClassTree classTree;
|
||||
|
||||
/**
|
||||
* @param configuration the configuration data for the doclet
|
||||
@ -89,7 +89,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
|
||||
super(configuration, configuration.docPaths.forClass(typeElement));
|
||||
this.typeElement = typeElement;
|
||||
configuration.currentTypeElement = typeElement;
|
||||
this.classtree = classTree;
|
||||
this.classTree = classTree;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -285,7 +285,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
|
||||
return; // Don't generate the list, too huge
|
||||
}
|
||||
}
|
||||
Set<TypeElement> subclasses = classtree.directSubClasses(typeElement, false);
|
||||
Set<TypeElement> subclasses = classTree.hierarchy(typeElement).subtypes(typeElement);
|
||||
if (!subclasses.isEmpty()) {
|
||||
var dl = HtmlTree.DL(HtmlStyle.notes);
|
||||
dl.add(HtmlTree.DT(contents.subclassesLabel));
|
||||
@ -298,7 +298,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
|
||||
@Override
|
||||
public void addSubInterfacesInfo(Content target) {
|
||||
if (utils.isPlainInterface(typeElement)) {
|
||||
Set<TypeElement> subInterfaces = classtree.allSubClasses(typeElement, false);
|
||||
Set<TypeElement> subInterfaces = classTree.hierarchy(typeElement).allSubtypes(typeElement);
|
||||
if (!subInterfaces.isEmpty()) {
|
||||
var dl = HtmlTree.DL(HtmlStyle.notes);
|
||||
dl.add(HtmlTree.DT(contents.subinterfacesLabel));
|
||||
@ -318,7 +318,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
|
||||
return; // Don't generate the list, too huge
|
||||
}
|
||||
}
|
||||
Set<TypeElement> implcl = classtree.implementingClasses(typeElement);
|
||||
Set<TypeElement> implcl = classTree.implementingClasses(typeElement);
|
||||
if (!implcl.isEmpty()) {
|
||||
var dl = HtmlTree.DL(HtmlStyle.notes);
|
||||
dl.add(HtmlTree.DT(contents.implementingClassesLabel));
|
||||
|
||||
@ -203,9 +203,9 @@ public class HtmlDoclet extends AbstractDoclet {
|
||||
* @throws DocletException if there is a problem while writing the other files
|
||||
*/
|
||||
@Override // defined by AbstractDoclet
|
||||
protected void generateOtherFiles(ClassTree classtree)
|
||||
protected void generateOtherFiles(ClassTree classTree)
|
||||
throws DocletException {
|
||||
super.generateOtherFiles(classtree);
|
||||
super.generateOtherFiles(classTree);
|
||||
HtmlOptions options = configuration.getOptions();
|
||||
if (options.linkSource()) {
|
||||
SourceToHTMLConverter.convertRoot(configuration, DocPaths.SOURCE_OUTPUT);
|
||||
@ -228,11 +228,11 @@ public class HtmlDoclet extends AbstractDoclet {
|
||||
}
|
||||
// do early to reduce memory footprint
|
||||
if (options.classUse()) {
|
||||
ClassUseWriter.generate(configuration, classtree);
|
||||
ClassUseWriter.generate(configuration, classTree);
|
||||
}
|
||||
|
||||
if (options.createTree()) {
|
||||
TreeWriter.generate(configuration, classtree);
|
||||
TreeWriter.generate(configuration, classTree);
|
||||
}
|
||||
|
||||
if (configuration.conditionalPages.contains((HtmlConfiguration.ConditionalPage.DEPRECATED))) {
|
||||
@ -392,7 +392,7 @@ public class HtmlDoclet extends AbstractDoclet {
|
||||
}
|
||||
|
||||
@Override // defined by AbstractDoclet
|
||||
protected void generatePackageFiles(ClassTree classtree) throws DocletException {
|
||||
protected void generatePackageFiles(ClassTree classTree) throws DocletException {
|
||||
HtmlOptions options = configuration.getOptions();
|
||||
Set<PackageElement> packages = configuration.packages;
|
||||
List<PackageElement> pList = new ArrayList<>(packages);
|
||||
|
||||
@ -31,7 +31,6 @@ import javax.lang.model.element.PackageElement;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.BodyContents;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.TagName;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.Navigation.PageMode;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
@ -103,10 +102,11 @@ public class PackageTreeWriter extends AbstractTreeWriter {
|
||||
addLinkToAllPackages(div);
|
||||
}
|
||||
mainContent.add(div);
|
||||
addTree(classtree.baseClasses(), "doclet.Class_Hierarchy", mainContent);
|
||||
addTree(classtree.baseInterfaces(), "doclet.Interface_Hierarchy", mainContent);
|
||||
addTree(classtree.baseAnnotationTypes(), "doclet.Annotation_Type_Hierarchy", mainContent);
|
||||
addTree(classtree.baseEnums(), "doclet.Enum_Hierarchy", mainContent, true);
|
||||
addTree(classTree.classes(), "doclet.Class_Hierarchy", mainContent);
|
||||
addTree(classTree.interfaces(), "doclet.Interface_Hierarchy", mainContent);
|
||||
addTree(classTree.annotationInterfaces(), "doclet.Annotation_Type_Hierarchy", mainContent);
|
||||
addTree(classTree.enumClasses(), "doclet.Enum_Hierarchy", mainContent);
|
||||
addTree(classTree.recordClasses(), "doclet.Record_Class_Hierarchy", mainContent);
|
||||
bodyContents.addMainContent(mainContent);
|
||||
bodyContents.setFooter(getFooter());
|
||||
body.add(bodyContents);
|
||||
|
||||
@ -66,10 +66,10 @@ public class TreeWriter extends AbstractTreeWriter {
|
||||
*
|
||||
* @param configuration the current configuration of the doclet.
|
||||
* @param filename String filename
|
||||
* @param classtree the tree being built.
|
||||
* @param classTree the tree being built.
|
||||
*/
|
||||
public TreeWriter(HtmlConfiguration configuration, DocPath filename, ClassTree classtree) {
|
||||
super(configuration, filename, classtree);
|
||||
public TreeWriter(HtmlConfiguration configuration, DocPath filename, ClassTree classTree) {
|
||||
super(configuration, filename, classTree);
|
||||
packages = configuration.packages;
|
||||
classesOnly = packages.isEmpty();
|
||||
this.bodyContents = new BodyContents();
|
||||
@ -80,13 +80,13 @@ public class TreeWriter extends AbstractTreeWriter {
|
||||
* "overview-tree.html" file.
|
||||
*
|
||||
* @param configuration the configuration for this doclet
|
||||
* @param classtree the class tree being documented.
|
||||
* @param classTree the class tree being documented.
|
||||
* @throws DocFileIOException if there is a problem generating the overview tree page
|
||||
*/
|
||||
public static void generate(HtmlConfiguration configuration,
|
||||
ClassTree classtree) throws DocFileIOException {
|
||||
ClassTree classTree) throws DocFileIOException {
|
||||
DocPath filename = DocPaths.OVERVIEW_TREE;
|
||||
TreeWriter treegen = new TreeWriter(configuration, filename, classtree);
|
||||
TreeWriter treegen = new TreeWriter(configuration, filename, classTree);
|
||||
treegen.generateTreeFile();
|
||||
}
|
||||
|
||||
@ -104,10 +104,11 @@ public class TreeWriter extends AbstractTreeWriter {
|
||||
addPackageTreeLinks(div);
|
||||
Content mainContent = new ContentBuilder();
|
||||
mainContent.add(div);
|
||||
addTree(classtree.baseClasses(), "doclet.Class_Hierarchy", mainContent);
|
||||
addTree(classtree.baseInterfaces(), "doclet.Interface_Hierarchy", mainContent);
|
||||
addTree(classtree.baseAnnotationTypes(), "doclet.Annotation_Type_Hierarchy", mainContent);
|
||||
addTree(classtree.baseEnums(), "doclet.Enum_Hierarchy", mainContent, true);
|
||||
addTree(classTree.classes(), "doclet.Class_Hierarchy", mainContent);
|
||||
addTree(classTree.interfaces(), "doclet.Interface_Hierarchy", mainContent);
|
||||
addTree(classTree.annotationInterfaces(), "doclet.Annotation_Type_Hierarchy", mainContent);
|
||||
addTree(classTree.enumClasses(), "doclet.Enum_Hierarchy", mainContent);
|
||||
addTree(classTree.recordClasses(), "doclet.Record_Class_Hierarchy", mainContent);
|
||||
body.add(bodyContents
|
||||
.addMainContent(mainContent)
|
||||
.setFooter(getFooter()));
|
||||
|
||||
@ -41,6 +41,7 @@ doclet.Window_Class_Hierarchy=Class Hierarchy
|
||||
doclet.Interface_Hierarchy=Interface Hierarchy
|
||||
doclet.Enum_Hierarchy=Enum Hierarchy
|
||||
doclet.Enum_Class_Hierarchy=Enum Class Hierarchy
|
||||
doclet.Record_Class_Hierarchy=Record Class Hierarchy
|
||||
doclet.Annotation_Type_Hierarchy=Annotation Type Hierarchy
|
||||
doclet.Annotation_Interface_Hierarchy=Annotation Interface Hierarchy
|
||||
doclet.Href_Class_Title=class in {0}
|
||||
|
||||
@ -202,25 +202,25 @@ public abstract class AbstractDoclet implements Doclet {
|
||||
}
|
||||
messages.notice("doclet.build_version",
|
||||
configuration.getDocletVersion());
|
||||
ClassTree classtree = new ClassTree(configuration, configuration.getOptions().noDeprecated());
|
||||
ClassTree classTree = new ClassTree(configuration);
|
||||
|
||||
generateClassFiles(classtree);
|
||||
generateClassFiles(classTree);
|
||||
|
||||
ElementListWriter.generate(configuration);
|
||||
generatePackageFiles(classtree);
|
||||
generatePackageFiles(classTree);
|
||||
generateModuleFiles();
|
||||
|
||||
generateOtherFiles(classtree);
|
||||
generateOtherFiles(classTree);
|
||||
configuration.tagletManager.printReport();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate additional documentation that is added to the API documentation.
|
||||
*
|
||||
* @param classtree the data structure representing the class tree
|
||||
* @param classTree the data structure representing the class tree
|
||||
* @throws DocletException if there is a problem while generating the documentation
|
||||
*/
|
||||
protected void generateOtherFiles(ClassTree classtree) throws DocletException {
|
||||
protected void generateOtherFiles(ClassTree classTree) throws DocletException {
|
||||
BuilderFactory builderFactory = configuration.getBuilderFactory();
|
||||
AbstractBuilder constantsSummaryBuilder = builderFactory.getConstantsSummaryBuilder();
|
||||
constantsSummaryBuilder.build();
|
||||
@ -239,28 +239,28 @@ public abstract class AbstractDoclet implements Doclet {
|
||||
/**
|
||||
* Generate the package documentation.
|
||||
*
|
||||
* @param classtree the data structure representing the class tree
|
||||
* @param classTree the data structure representing the class tree
|
||||
* @throws DocletException if there is a problem while generating the documentation
|
||||
*/
|
||||
protected abstract void generatePackageFiles(ClassTree classtree) throws DocletException;
|
||||
protected abstract void generatePackageFiles(ClassTree classTree) throws DocletException;
|
||||
|
||||
/**
|
||||
* Generate the class documentation.
|
||||
*
|
||||
* @param arr the set of types to be documented
|
||||
* @param classtree the data structure representing the class tree
|
||||
* @param classTree the data structure representing the class tree
|
||||
* @throws DocletException if there is a problem while generating the documentation
|
||||
*/
|
||||
protected abstract void generateClassFiles(SortedSet<TypeElement> arr, ClassTree classtree)
|
||||
protected abstract void generateClassFiles(SortedSet<TypeElement> arr, ClassTree classTree)
|
||||
throws DocletException;
|
||||
|
||||
/**
|
||||
* Iterate through all classes and construct documentation for them.
|
||||
*
|
||||
* @param classtree the data structure representing the class tree
|
||||
* @param classTree the data structure representing the class tree
|
||||
* @throws DocletException if there is a problem while generating the documentation
|
||||
*/
|
||||
protected void generateClassFiles(ClassTree classtree)
|
||||
protected void generateClassFiles(ClassTree classTree)
|
||||
throws DocletException {
|
||||
|
||||
SortedSet<TypeElement> classes = new TreeSet<>(utils.comparators.makeGeneralPurposeComparator());
|
||||
@ -278,6 +278,6 @@ public abstract class AbstractDoclet implements Doclet {
|
||||
classes.addAll(utils.getAllClasses(pkg));
|
||||
}
|
||||
|
||||
generateClassFiles(classes, classtree);
|
||||
generateClassFiles(classes, classTree);
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,11 +27,10 @@ package jdk.javadoc.internal.doclets.toolkit.util;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -42,242 +41,276 @@ import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
|
||||
import jdk.javadoc.doclet.DocletEnvironment;
|
||||
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Messages;
|
||||
|
||||
/**
|
||||
* Build Class Hierarchy for all the Classes. This class builds the Class
|
||||
* Tree and the Interface Tree separately.
|
||||
* Class and interface hierarchies.
|
||||
*/
|
||||
public class ClassTree {
|
||||
|
||||
/**
|
||||
* List of base classes. Used to get the mapped listing of sub-classes.
|
||||
* The kind of hierarchy.
|
||||
* Currently, the kinds correspond to the kinds of declared types,
|
||||
* although other partitions could be possible.
|
||||
*/
|
||||
private final SortedSet<TypeElement> baseClasses;
|
||||
private enum HierarchyKind {
|
||||
CLASSES, ENUM_CLASSES, RECORD_CLASSES, INTERFACES, ANNOTATION_INTERFACES
|
||||
}
|
||||
|
||||
/**
|
||||
* Mapping for each Class with their sub classes
|
||||
* A "hierarchy" provides the subtypes of all the supertypes of a set of leaf elements,
|
||||
* together with the root supertype(s).
|
||||
*/
|
||||
private final Map<TypeElement, SortedSet<TypeElement>> subClasses = new HashMap<>();
|
||||
public static class Hierarchy {
|
||||
private final SortedSet<TypeElement> roots;
|
||||
private final SubtypeMap subtypes;
|
||||
private final Comparator<Element> comparator;
|
||||
|
||||
Hierarchy(Comparator<Element> comparator) {
|
||||
this.comparator = comparator;
|
||||
roots = new TreeSet<>(comparator);
|
||||
subtypes = new SubtypeMap(comparator);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the roots of the hierarchy}
|
||||
* Each root is a class or interface with no superclass or superinterfaces.
|
||||
* If the hierarchy just contains classes, the root will be {@code java.lang.Object}.
|
||||
*/
|
||||
public SortedSet<TypeElement> roots() {
|
||||
return roots;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the immediate subtypes of the given type element, or an empty set if there are none}
|
||||
* @param typeElement the type element
|
||||
*/
|
||||
public SortedSet<TypeElement> subtypes(TypeElement typeElement) {
|
||||
return subtypes.getOrDefault(typeElement, Collections.emptySortedSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the set of all subtypes of the given type element, or an empty set if there are none}
|
||||
*
|
||||
* The set of all subtypes is the transitive closure of the {@linkplain #subtypes(TypeElement) immediate subtypes}
|
||||
* of the given type element.
|
||||
*
|
||||
* @param typeElement the type element
|
||||
*/
|
||||
public SortedSet<TypeElement> allSubtypes(TypeElement typeElement) {
|
||||
// new entries added to the collection are searched as well;
|
||||
// this is really a work queue.
|
||||
List<TypeElement> list = new ArrayList<>(subtypes(typeElement));
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
var subtypes = subtypes(list.get(i));
|
||||
for (var subtype : subtypes) {
|
||||
if (!list.contains(subtype)) {
|
||||
list.add(subtype);
|
||||
}
|
||||
}
|
||||
}
|
||||
SortedSet<TypeElement> out = new TreeSet<>(comparator);
|
||||
out.addAll(list);
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List of base-interfaces. Contains set of all the interfaces who do not
|
||||
* have super-interfaces. Can be used to get the mapped listing of
|
||||
* sub-interfaces.
|
||||
* A map giving the subtypes for each of a collection of type elements.
|
||||
* The subtypes may be subclasses or subinterfaces, depending on the context.
|
||||
*
|
||||
* The subtypes are recorded by calling {@link SubtypeMap#addSubtype(TypeElement, TypeElement) addSubtype}.
|
||||
*/
|
||||
private final SortedSet<TypeElement> baseInterfaces;
|
||||
@SuppressWarnings("serial")
|
||||
private static class SubtypeMap extends HashMap<TypeElement, SortedSet<TypeElement>> {
|
||||
private final Comparator<Element> comparator;
|
||||
|
||||
/**
|
||||
* Creates a map to provide the subtypes of a type element,
|
||||
* sorted according to a given comparator.
|
||||
*
|
||||
* An alternate implementation would be to store the subtypes unsorted,
|
||||
* and to lazily sort them when needed, such as when generating documentation.
|
||||
*
|
||||
* @param comparator the comparator
|
||||
*/
|
||||
SubtypeMap(Comparator<Element> comparator) {
|
||||
this.comparator = comparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the subtypes for a type element, or an empty set if there are none}
|
||||
*
|
||||
* @param typeElement the type element
|
||||
*/
|
||||
SortedSet<TypeElement> getSubtypes(TypeElement typeElement) {
|
||||
return computeIfAbsent(typeElement, te -> new TreeSet<>(comparator));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a subtype into the set of subtypes for a type element
|
||||
*
|
||||
* @param typeElement the type element
|
||||
* @param subtype the subtype
|
||||
* @return {@code true} if this set did not already contain the specified element
|
||||
*/
|
||||
boolean addSubtype(TypeElement typeElement, TypeElement subtype) {
|
||||
return getSubtypes(typeElement).add(subtype);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The collection of hierarchies, indexed by kind.
|
||||
*/
|
||||
private final Map<HierarchyKind, Hierarchy> hierarchies;
|
||||
|
||||
/**
|
||||
* Mapping for each Interface with their SubInterfaces
|
||||
* Mapping for each interface with classes that implement it.
|
||||
*/
|
||||
private final Map<TypeElement, SortedSet<TypeElement>> subInterfaces = new HashMap<>();
|
||||
|
||||
private final SortedSet<TypeElement> baseEnums;
|
||||
private final Map<TypeElement, SortedSet<TypeElement>> subEnums = new HashMap<>();
|
||||
|
||||
private final SortedSet<TypeElement> baseAnnotationTypes;
|
||||
private final Map<TypeElement, SortedSet<TypeElement>> subAnnotationTypes = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Mapping for each Interface with classes who implement it.
|
||||
*/
|
||||
private final Map<TypeElement, SortedSet<TypeElement>> implementingClasses = new HashMap<>();
|
||||
private final SubtypeMap implementingClasses;
|
||||
|
||||
private final BaseConfiguration configuration;
|
||||
private final Utils utils;
|
||||
private final Comparator<Element> comparator;
|
||||
|
||||
/**
|
||||
* Constructor. Build the Tree using the Root of this Javadoc run.
|
||||
* Constructor. Build the tree for all the included type elements.
|
||||
*
|
||||
* @param configuration the configuration of the doclet.
|
||||
* @param noDeprecated Don't add deprecated classes in the class tree, if
|
||||
* true.
|
||||
* @param configuration the configuration of the doclet
|
||||
*/
|
||||
public ClassTree(BaseConfiguration configuration, boolean noDeprecated) {
|
||||
public ClassTree(BaseConfiguration configuration) {
|
||||
this.configuration = configuration;
|
||||
this.utils = configuration.utils;
|
||||
|
||||
Messages messages = configuration.getMessages();
|
||||
messages.notice("doclet.Building_Tree");
|
||||
|
||||
comparator = utils.comparators.makeClassUseComparator();
|
||||
baseAnnotationTypes = new TreeSet<>(comparator);
|
||||
baseEnums = new TreeSet<>(comparator);
|
||||
baseClasses = new TreeSet<>(comparator);
|
||||
baseInterfaces = new TreeSet<>(comparator);
|
||||
Comparator<Element> comparator = utils.comparators.makeClassUseComparator();
|
||||
|
||||
hierarchies = new EnumMap<>(HierarchyKind.class);
|
||||
for (var hk : HierarchyKind.values()) {
|
||||
hierarchies.put(hk, new Hierarchy(comparator));
|
||||
}
|
||||
implementingClasses = new SubtypeMap(comparator);
|
||||
|
||||
buildTree(configuration.getIncludedTypeElements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. Build the Tree using the Root of this Javadoc run.
|
||||
*
|
||||
* @param docEnv the DocletEnvironment.
|
||||
* @param configuration The current configuration of the doclet.
|
||||
*/
|
||||
public ClassTree(DocletEnvironment docEnv, BaseConfiguration configuration) {
|
||||
this.configuration = configuration;
|
||||
this.utils = configuration.utils;
|
||||
comparator = utils.comparators.makeClassUseComparator();
|
||||
baseAnnotationTypes = new TreeSet<>(comparator);
|
||||
baseEnums = new TreeSet<>(comparator);
|
||||
baseClasses = new TreeSet<>(comparator);
|
||||
baseInterfaces = new TreeSet<>(comparator);
|
||||
buildTree(configuration.getIncludedTypeElements());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. Build the tree for the given array of classes.
|
||||
* Constructor. Build the tree for the given collection of classes.
|
||||
*
|
||||
* @param classesSet a set of classes
|
||||
* @param configuration The current configuration of the doclet.
|
||||
*/
|
||||
public ClassTree(SortedSet<TypeElement>classesSet, BaseConfiguration configuration) {
|
||||
public ClassTree(SortedSet<TypeElement> classesSet, BaseConfiguration configuration) {
|
||||
this.configuration = configuration;
|
||||
this.utils = configuration.utils;
|
||||
comparator = utils.comparators.makeClassUseComparator();
|
||||
baseAnnotationTypes = new TreeSet<>(comparator);
|
||||
baseEnums = new TreeSet<>(comparator);
|
||||
baseClasses = new TreeSet<>(comparator);
|
||||
baseInterfaces = new TreeSet<>(comparator);
|
||||
|
||||
Comparator<Element> comparator = utils.comparators.makeClassUseComparator();
|
||||
|
||||
hierarchies = new EnumMap<>(HierarchyKind.class);
|
||||
for (var hk : HierarchyKind.values()) {
|
||||
hierarchies.put(hk, new Hierarchy(comparator));
|
||||
}
|
||||
implementingClasses = new SubtypeMap(comparator);
|
||||
|
||||
buildTree(classesSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate mapping for the sub-classes for every class in this run.
|
||||
* Return the sub-class set for java.lang.Object which will be having
|
||||
* sub-class listing for itself and also for each sub-class itself will
|
||||
* have their own sub-class lists.
|
||||
* Generate the hierarchies for the given type elements.
|
||||
*
|
||||
* @param classes all the classes in this run.
|
||||
* @param typeElements the type elements
|
||||
*/
|
||||
private void buildTree(Iterable<TypeElement> classes) {
|
||||
for (TypeElement aClass : classes) {
|
||||
private void buildTree(Iterable<TypeElement> typeElements) {
|
||||
for (TypeElement te : typeElements) {
|
||||
// In the tree page (e.g overview-tree.html) do not include
|
||||
// information of classes which are deprecated or are a part of a
|
||||
// deprecated package.
|
||||
if (configuration.getOptions().noDeprecated() &&
|
||||
(utils.isDeprecated(aClass) ||
|
||||
utils.isDeprecated(utils.containingPackage(aClass)))) {
|
||||
(utils.isDeprecated(te) ||
|
||||
utils.isDeprecated(utils.containingPackage(te)))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (utils.hasHiddenTag(aClass)) {
|
||||
if (utils.hasHiddenTag(te)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (utils.isEnum(aClass)) {
|
||||
processType(aClass, configuration, baseEnums, subEnums);
|
||||
} else if (utils.isClass(aClass)) {
|
||||
processType(aClass, configuration, baseClasses, subClasses);
|
||||
} else if (utils.isPlainInterface(aClass)) {
|
||||
processInterface(aClass);
|
||||
} else if (utils.isAnnotationInterface(aClass)) {
|
||||
processType(aClass, configuration, baseAnnotationTypes,
|
||||
subAnnotationTypes);
|
||||
if (utils.isEnum(te)) {
|
||||
processType(te, hierarchies.get(HierarchyKind.ENUM_CLASSES));
|
||||
} else if (utils.isRecord(te)) {
|
||||
processType(te, hierarchies.get(HierarchyKind.RECORD_CLASSES));
|
||||
} else if (utils.isClass(te)) {
|
||||
processType(te, hierarchies.get(HierarchyKind.CLASSES));
|
||||
} else if (utils.isPlainInterface(te)) {
|
||||
processInterface(te);
|
||||
} else if (utils.isAnnotationInterface(te)) {
|
||||
processType(te, hierarchies.get(HierarchyKind.ANNOTATION_INTERFACES));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For the class passed map it to its own sub-class listing.
|
||||
* For the Class passed, get the super class,
|
||||
* if superclass is non null, (it is not "java.lang.Object")
|
||||
* get the "value" from the hashmap for this key Class
|
||||
* if entry not found create one and get that.
|
||||
* add this Class as a sub class in the set
|
||||
* Recurse till hits java.lang.Object Null SuperClass.
|
||||
* Adds details for a type element into a given hierarchy.
|
||||
*
|
||||
* @param typeElement for which sub class mapping is to be generated.
|
||||
* @param configuration the current configuration of the doclet.
|
||||
* The subtypes are updated for the transitive closure of all supertypes of this type element.
|
||||
* If this type element has no superclass or superinterfaces, it is marked as a root.
|
||||
*
|
||||
* @param typeElement for which the hierarchy is to be generated
|
||||
* @param hierarchy the hierarchy
|
||||
*/
|
||||
private void processType(TypeElement typeElement, BaseConfiguration configuration,
|
||||
Collection<TypeElement> bases, Map<TypeElement, SortedSet<TypeElement>> subs) {
|
||||
private void processType(TypeElement typeElement, Hierarchy hierarchy) {
|
||||
TypeElement superclass = utils.getFirstVisibleSuperClassAsTypeElement(typeElement);
|
||||
if (superclass != null) {
|
||||
if (!add(subs, superclass, typeElement)) {
|
||||
if (!hierarchy.subtypes.addSubtype(superclass, typeElement)) {
|
||||
return;
|
||||
} else {
|
||||
processType(superclass, configuration, bases, subs);
|
||||
processType(superclass, hierarchy);
|
||||
}
|
||||
} else { // typeElement is java.lang.Object, add it once to the set
|
||||
if (!bases.contains(typeElement)) {
|
||||
bases.add(typeElement);
|
||||
}
|
||||
hierarchy.roots.add(typeElement);
|
||||
}
|
||||
Set<TypeMirror> intfacs = utils.getAllInterfaces(typeElement);
|
||||
for (TypeMirror intfac : intfacs) {
|
||||
add(implementingClasses, utils.asTypeElement(intfac), typeElement);
|
||||
|
||||
Set<TypeMirror> interfaces = utils.getAllInterfaces(typeElement);
|
||||
for (TypeMirror t : interfaces) {
|
||||
implementingClasses.addSubtype(utils.asTypeElement(t), typeElement);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For the interface passed get the interfaces which it extends, and then
|
||||
* put this interface in the sub-interface set of those interfaces. Do it
|
||||
* recursively. If a interface doesn't have super-interface just attach
|
||||
* recursively. If an interface doesn't have super-interface just attach
|
||||
* that interface in the set of all the baseInterfaces.
|
||||
*
|
||||
* @param typeElement Interface under consideration.
|
||||
*/
|
||||
private void processInterface(TypeElement typeElement) {
|
||||
List<? extends TypeMirror> intfacs = typeElement.getInterfaces();
|
||||
if (!intfacs.isEmpty()) {
|
||||
for (TypeMirror intfac : intfacs) {
|
||||
if (!add(subInterfaces, utils.asTypeElement(intfac), typeElement)) {
|
||||
Hierarchy interfacesHierarchy = hierarchies.get(HierarchyKind.INTERFACES);
|
||||
List<? extends TypeMirror> interfaces = typeElement.getInterfaces();
|
||||
if (!interfaces.isEmpty()) {
|
||||
for (TypeMirror t : interfaces) {
|
||||
if (!interfacesHierarchy.subtypes.addSubtype(utils.asTypeElement(t), typeElement)) {
|
||||
return;
|
||||
} else {
|
||||
processInterface(utils.asTypeElement(intfac)); // Recurse
|
||||
processInterface(utils.asTypeElement(t)); // Recurse
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// we need to add all the interfaces who do not have
|
||||
// super-interfaces to baseInterfaces set to traverse them
|
||||
if (!baseInterfaces.contains(typeElement)) {
|
||||
baseInterfaces.add(typeElement);
|
||||
}
|
||||
// super-interfaces to the root set to traverse them
|
||||
interfacesHierarchy.roots.add(typeElement);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust the Class Tree. Add the class interface in to it's super classes
|
||||
* or super interface's sub-interface set.
|
||||
*
|
||||
* @param map the entire map.
|
||||
* @param superclass java.lang.Object or the super-interface.
|
||||
* @param typeElement sub-interface to be mapped.
|
||||
* @return true if class added, false if class already processed.
|
||||
*/
|
||||
private boolean add(Map<TypeElement, SortedSet<TypeElement>> map, TypeElement superclass, TypeElement typeElement) {
|
||||
SortedSet<TypeElement> sset = map.computeIfAbsent(superclass, s -> new TreeSet<>(comparator));
|
||||
if (sset.contains(typeElement)) {
|
||||
return false;
|
||||
} else {
|
||||
sset.add(typeElement);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* From the map return the set of sub-classes or sub-interfaces. If set
|
||||
* is null create a new one and return it.
|
||||
*
|
||||
* @param map The entire map.
|
||||
* @param typeElement class for which the sub-class set is requested.
|
||||
* @return a set of sub classes.
|
||||
*/
|
||||
private SortedSet<TypeElement> get(Map<TypeElement, SortedSet<TypeElement>> map, TypeElement typeElement) {
|
||||
return map.computeIfAbsent(typeElement, t -> new TreeSet<>(comparator));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the sub-class set for the class passed.
|
||||
*
|
||||
* @param typeElement class whose sub-class set is required.
|
||||
*/
|
||||
public SortedSet<TypeElement> subClasses(TypeElement typeElement) {
|
||||
return get(subClasses, typeElement);
|
||||
return hierarchies.get(HierarchyKind.CLASSES).subtypes(typeElement);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -286,7 +319,7 @@ public class ClassTree {
|
||||
* @param typeElement interface whose sub-interface set is required.
|
||||
*/
|
||||
public SortedSet<TypeElement> subInterfaces(TypeElement typeElement) {
|
||||
return get(subInterfaces, typeElement);
|
||||
return hierarchies.get(HierarchyKind.INTERFACES).subtypes(typeElement);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -295,106 +328,61 @@ public class ClassTree {
|
||||
* @param typeElement interface whose implementing-classes set is required.
|
||||
*/
|
||||
public SortedSet<TypeElement> implementingClasses(TypeElement typeElement) {
|
||||
SortedSet<TypeElement> result = get(implementingClasses, typeElement);
|
||||
SortedSet<TypeElement> intfcs = allSubClasses(typeElement, false);
|
||||
SortedSet<TypeElement> result = implementingClasses.getSubtypes(typeElement);
|
||||
SortedSet<TypeElement> interfaces = hierarchy(typeElement).allSubtypes(typeElement);
|
||||
|
||||
// If class x implements a subinterface of typeElement, then it follows
|
||||
// that class x implements typeElement.
|
||||
Iterator<TypeElement> subInterfacesIter = intfcs.iterator();
|
||||
while (subInterfacesIter.hasNext()) {
|
||||
Iterator<TypeElement> implementingClassesIter
|
||||
= implementingClasses(subInterfacesIter.next()).iterator();
|
||||
while (implementingClassesIter.hasNext()) {
|
||||
TypeElement c = implementingClassesIter.next();
|
||||
if (!result.contains(c)) {
|
||||
result.add(c);
|
||||
}
|
||||
}
|
||||
for (TypeElement te : interfaces) {
|
||||
result.addAll(implementingClasses(te));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the sub-class/interface set for the class/interface passed.
|
||||
*
|
||||
* @param typeElement class/interface whose sub-class/interface set is required.
|
||||
* @param isEnum true if the subClasses should be forced to come from the
|
||||
* enum tree.
|
||||
*/
|
||||
public SortedSet<TypeElement> directSubClasses(TypeElement typeElement, boolean isEnum) {
|
||||
return directSubClasses0(typeElement, isEnum);
|
||||
}
|
||||
|
||||
private SortedSet<TypeElement> directSubClasses0(TypeElement typeElement, boolean isEnum) {
|
||||
if (isEnum) {
|
||||
return get(subEnums, typeElement);
|
||||
} else if (utils.isAnnotationInterface(typeElement)) {
|
||||
return get(subAnnotationTypes, typeElement);
|
||||
} else if (utils.isPlainInterface(typeElement)) {
|
||||
return get(subInterfaces, typeElement);
|
||||
} else if (utils.isClass(typeElement)) {
|
||||
return get(subClasses, typeElement);
|
||||
} else {
|
||||
return Collections.emptySortedSet();
|
||||
}
|
||||
public Hierarchy hierarchy(TypeElement typeElement) {
|
||||
HierarchyKind hk = switch (typeElement.getKind()) {
|
||||
case CLASS -> HierarchyKind.CLASSES;
|
||||
case ENUM -> HierarchyKind.ENUM_CLASSES;
|
||||
case RECORD -> HierarchyKind.RECORD_CLASSES;
|
||||
case INTERFACE -> HierarchyKind.INTERFACES;
|
||||
case ANNOTATION_TYPE -> HierarchyKind.ANNOTATION_INTERFACES;
|
||||
default -> throw new IllegalArgumentException(typeElement.getKind().name() + " " + typeElement.getQualifiedName());
|
||||
};
|
||||
return hierarchies.get(hk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a set of all direct or indirect, sub-classes and subInterfaces
|
||||
* of the TypeElement argument.
|
||||
*
|
||||
* @param typeElement TypeElement whose sub-classes or sub-interfaces are requested.
|
||||
* @param isEnum true if the subClasses should be forced to come from the
|
||||
* enum tree.
|
||||
* {@return the hierarchy for which the leaf nodes are plain classes}
|
||||
*/
|
||||
public SortedSet<TypeElement> allSubClasses(TypeElement typeElement, boolean isEnum) {
|
||||
// new entries added to the set are searched as well, this is
|
||||
// really a work queue.
|
||||
List<TypeElement> list = new ArrayList<>(directSubClasses(typeElement, isEnum));
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
TypeElement te = list.get(i);
|
||||
SortedSet<TypeElement> tset = directSubClasses0(te, isEnum);
|
||||
for (TypeElement tte : tset) {
|
||||
if (!list.contains(tte)) {
|
||||
list.add(tte);
|
||||
}
|
||||
}
|
||||
}
|
||||
SortedSet<TypeElement> out = new TreeSet<>(comparator);
|
||||
out.addAll(list);
|
||||
return out;
|
||||
public Hierarchy classes() {
|
||||
return hierarchies.get(HierarchyKind.CLASSES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a set of base classes. This will have only one element namely
|
||||
* the TypeElement for java.lang.Object, since this is the base class for all
|
||||
* classes.
|
||||
* {@return the hierarchy for which the leaf nodes are enum classes}
|
||||
*/
|
||||
public SortedSet<TypeElement> baseClasses() {
|
||||
return baseClasses;
|
||||
public Hierarchy enumClasses() {
|
||||
return hierarchies.get(HierarchyKind.ENUM_CLASSES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the set of base interfaces. This is the set of interfaces
|
||||
* which do not have super-interface.
|
||||
* {@return the hierarchy for which the leaf nodes are record classes}
|
||||
*/
|
||||
public SortedSet<TypeElement> baseInterfaces() {
|
||||
return baseInterfaces;
|
||||
public Hierarchy recordClasses() {
|
||||
return hierarchies.get(HierarchyKind.RECORD_CLASSES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the set of base enums. This is the set of enums
|
||||
* which do not have super-enums.
|
||||
* {@return the hierarchy for which the leaf nodes are plain interfaces}
|
||||
*/
|
||||
public SortedSet<TypeElement> baseEnums() {
|
||||
return baseEnums;
|
||||
public Hierarchy interfaces() {
|
||||
return hierarchies.get(HierarchyKind.INTERFACES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the set of base annotation types. This is the set
|
||||
* of annotation types which do not have super-annotation types.
|
||||
* {@return the hierarchy for which the leaf nodes are annotation interfaces}
|
||||
*/
|
||||
public SortedSet<TypeElement> baseAnnotationTypes() {
|
||||
return baseAnnotationTypes;
|
||||
public Hierarchy annotationInterfaces() {
|
||||
return hierarchies.get(HierarchyKind.ANNOTATION_INTERFACES);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -60,7 +60,7 @@ import static jdk.javadoc.internal.doclets.toolkit.util.VisibleMemberTable.Kind.
|
||||
*/
|
||||
public class ClassUseMapper {
|
||||
|
||||
private final ClassTree classtree;
|
||||
private final ClassTree classTree;
|
||||
|
||||
/**
|
||||
* Mapping of TypeElements to set of PackageElements used by that class.
|
||||
@ -192,19 +192,19 @@ public class ClassUseMapper {
|
||||
private final Utils utils;
|
||||
private final Comparators comparators;
|
||||
|
||||
public ClassUseMapper(BaseConfiguration configuration, ClassTree classtree) {
|
||||
public ClassUseMapper(BaseConfiguration configuration, ClassTree classTree) {
|
||||
docEnv = configuration.docEnv;
|
||||
elementUtils = docEnv.getElementUtils();
|
||||
typeUtils = docEnv.getTypeUtils();
|
||||
utils = configuration.utils;
|
||||
comparators = utils.comparators;
|
||||
this.classtree = classtree;
|
||||
this.classTree = classTree;
|
||||
classToPackage = new TreeMap<>(comparators.makeClassUseComparator());
|
||||
// Map subclassing, subinterfacing implementing, ...
|
||||
for (TypeElement te : classtree.baseClasses()) {
|
||||
for (TypeElement te : classTree.classes().roots()) {
|
||||
subclasses(te);
|
||||
}
|
||||
for (TypeElement intfc : classtree.baseInterfaces()) {
|
||||
for (TypeElement intfc : classTree.interfaces().roots()) {
|
||||
// does subinterfacing as a side-effect
|
||||
implementingClasses(intfc);
|
||||
}
|
||||
@ -286,7 +286,7 @@ public class ClassUseMapper {
|
||||
Collection<TypeElement> ret = classToSubclass.get(te);
|
||||
if (ret == null) {
|
||||
ret = new TreeSet<>(comparators.makeClassUseComparator());
|
||||
Set<TypeElement> subs = classtree.subClasses(te);
|
||||
Set<TypeElement> subs = classTree.subClasses(te);
|
||||
if (subs != null) {
|
||||
ret.addAll(subs);
|
||||
for (TypeElement sub : subs) {
|
||||
@ -305,7 +305,7 @@ public class ClassUseMapper {
|
||||
Collection<TypeElement> ret = classToSubinterface.get(te);
|
||||
if (ret == null) {
|
||||
ret = new TreeSet<>(comparators.makeClassUseComparator());
|
||||
Set<TypeElement> subs = classtree.subInterfaces(te);
|
||||
Set<TypeElement> subs = classTree.subInterfaces(te);
|
||||
if (subs != null) {
|
||||
ret.addAll(subs);
|
||||
for (TypeElement sub : subs) {
|
||||
@ -326,7 +326,7 @@ public class ClassUseMapper {
|
||||
Collection<TypeElement> ret = classToImplementingClass.get(te);
|
||||
if (ret == null) {
|
||||
ret = new TreeSet<>(comparators.makeClassUseComparator());
|
||||
Set<TypeElement> impl = classtree.implementingClasses(te);
|
||||
Set<TypeElement> impl = classTree.implementingClasses(te);
|
||||
if (impl != null) {
|
||||
ret.addAll(impl);
|
||||
for (TypeElement anImpl : impl) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8225055 8239804 8246774 8258338 8261976 8275199
|
||||
* @bug 8225055 8239804 8246774 8258338 8261976 8275199 8285939
|
||||
* @summary Record types
|
||||
* @library /tools/lib ../../lib
|
||||
* @modules jdk.javadoc/jdk.javadoc.internal.tool
|
||||
@ -605,4 +605,41 @@ public class TestRecordTypes extends JavadocTester {
|
||||
</ul>
|
||||
</section>""");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPackageTree(Path base) throws IOException {
|
||||
Path src = base.resolve("src");
|
||||
tb.writeJavaFiles(src,
|
||||
"""
|
||||
package p;
|
||||
/**
|
||||
* A point.
|
||||
* @param x the x coord
|
||||
* @param y the y coord
|
||||
*/
|
||||
public record Point(int x, int y) { }""");
|
||||
|
||||
javadoc("-d", base.resolve("out").toString(),
|
||||
"-quiet", "-noindex", "--no-platform-links",
|
||||
"-sourcepath", src.toString(),
|
||||
"p");
|
||||
checkExit(Exit.OK);
|
||||
|
||||
checkOutput("p/package-tree.html", true,
|
||||
"""
|
||||
<section class="hierarchy">
|
||||
<h2 title="Record Class Hierarchy">Record Class Hierarchy</h2>
|
||||
<ul>
|
||||
<li class="circle">java.lang.Object
|
||||
<ul>
|
||||
<li class="circle">java.lang.Record
|
||||
<ul>
|
||||
<li class="circle">p.<a href="Point.html" class="type-name-link" title="class in p">Point</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</section>""");
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user