8237383: Members inherited from non-public types are not included in index

Reviewed-by: jjg
This commit is contained in:
Hannes Wallnöfer 2020-04-08 21:28:14 +02:00
parent 64957a1770
commit cdb379e5b4
35 changed files with 1021 additions and 895 deletions

View File

@ -90,7 +90,7 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite
deprecatedLinkContent.add(".");
deprecatedLinkContent.add(member.getSimpleName());
}
String signature = utils.flatSignature((ExecutableElement) member);
String signature = utils.flatSignature((ExecutableElement) member, typeElement);
if (signature.length() > 2) {
deprecatedLinkContent.add(Entity.ZERO_WIDTH_SPACE);
}

View File

@ -27,7 +27,6 @@ package jdk.javadoc.internal.doclets.formats.html;
import java.io.IOException;
import java.io.Writer;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@ -35,11 +34,11 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.SimpleElementVisitor14;
import com.sun.source.doctree.DocTree;
import jdk.javadoc.internal.doclets.formats.html.SearchIndexItem.Category;
@ -55,6 +54,7 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
import jdk.javadoc.internal.doclets.toolkit.util.IndexBuilder;
import jdk.javadoc.internal.doclets.toolkit.util.IndexItem;
/**
* Generate Index for all the Member Names with Indexing in
@ -96,80 +96,17 @@ public class AbstractIndexWriter extends HtmlDocletWriter {
this.navBar = new Navigation(null, configuration, PageMode.INDEX, path);
Stream<SearchIndexItem> items =
searchItems.itemsOfCategories(Category.INDEX, Category.SYSTEM_PROPERTY)
.sorted(utils.makeGenericSearchIndexComparator());
.sorted(comparators.makeGenericSearchIndexComparator());
this.tagSearchIndexMap = buildSearchTagIndex(items);
}
/**
* Add the member information for the unicode character along with the
* list of the members.
*
* @param uc Unicode for which member list information to be generated
* @param memberlist List of members for the unicode character
* @param contentTree the content tree to which the information will be added
*/
protected void addContents(Character uc, Collection<? extends Element> memberlist,
protected void addContents(Character uc, List<IndexItem> memberlist,
Content contentTree) {
addHeading(uc, contentTree);
// Display the list only if there are elements to be displayed.
if (!memberlist.isEmpty()) {
HtmlTree dl = HtmlTree.DL(HtmlStyle.index);
for (Element element : memberlist) {
addDescription(dl, element);
}
contentTree.add(dl);
}
}
protected void addSearchContents(Character uc, List<SearchIndexItem> searchList,
Content contentTree) {
addHeading(uc, contentTree);
// Display the list only if there are elements to be displayed.
if (!searchList.isEmpty()) {
HtmlTree dl = HtmlTree.DL(HtmlStyle.index);
for (SearchIndexItem sii : searchList) {
addDescription(sii, dl);
}
contentTree.add(dl);
}
}
protected void addContents(Character uc, List<? extends Element> memberlist,
List<SearchIndexItem> searchList, Content contentTree) {
addHeading(uc, contentTree);
int memberListSize = memberlist.size();
int searchListSize = searchList.size();
int i = 0;
int j = 0;
HtmlTree dl = HtmlTree.DL(HtmlStyle.index);
while (i < memberListSize && j < searchListSize) {
Element elem = memberlist.get(i);
String name = (utils.isModule(elem))
? utils.getFullyQualifiedName(elem) : utils.getSimpleName(elem);
if (name.compareTo(searchList.get(j).getLabel()) < 0) {
addDescription(dl, memberlist.get(i));
i++;
} else if (name.compareTo(searchList.get(j).getLabel()) > 0) {
addDescription(searchList.get(j), dl);
j++;
} else {
addDescription(dl, memberlist.get(i));
addDescription(searchList.get(j), dl);
j++;
i++;
}
}
if (i >= memberListSize) {
while (j < searchListSize) {
addDescription(searchList.get(j), dl);
j++;
}
}
if (j >= searchListSize) {
while (i < memberListSize) {
addDescription(dl, memberlist.get(i));
i++;
}
for (IndexItem indexItem : memberlist) {
addDescription(indexItem, dl);
}
contentTree.add(dl);
}
@ -183,109 +120,78 @@ public class AbstractIndexWriter extends HtmlDocletWriter {
contentTree.add(heading);
}
@SuppressWarnings("preview")
protected void addDescription(Content dl, Element element) {
SearchIndexItem si = new SearchIndexItem();
new SimpleElementVisitor14<Void, Void>() {
@Override
public Void visitModule(ModuleElement e, Void p) {
if (configuration.showModules) {
addDescription(e, dl, si);
searchItems.add(si);
}
return null;
}
@Override
public Void visitPackage(PackageElement e, Void p) {
addDescription(e, dl, si);
searchItems.add(si);
return null;
}
@Override
public Void visitType(TypeElement e, Void p) {
addDescription(e, dl, si);
searchItems.add(si);
return null;
}
@Override
protected Void defaultAction(Element e, Void p) {
addDescription(e, dl, si);
searchItems.add(si);
return null;
}
}.visit(element);
protected void addDescription(IndexItem indexItem, Content dl) {
SearchIndexItem si = indexItem.getSearchTag();
if (si != null) {
addDescription(si, dl);
} else {
si = new SearchIndexItem();
si.setLabel(indexItem.getLabel());
addElementDescription(indexItem, dl, si);
searchItems.add(si);
}
}
/**
* Add one line summary comment for the module.
* Add one line summary comment for the element.
*
* @param mdle the module to be documented
* @param indexItem the element to be documented
* @param dlTree the content tree to which the description will be added
* @param si the search index item
*/
protected void addDescription(ModuleElement mdle, Content dlTree, SearchIndexItem si) {
String moduleName = utils.getFullyQualifiedName(mdle);
Content link = getModuleLink(mdle, new StringContent(moduleName));
si.setLabel(moduleName);
si.setCategory(Category.MODULES);
Content dt = HtmlTree.DT(link);
dt.add(" - ");
dt.add(contents.module_);
dt.add(" " + moduleName);
dlTree.add(dt);
Content dd = new HtmlTree(TagName.DD);
addSummaryComment(mdle, dd);
dlTree.add(dd);
}
/**
* Add one line summary comment for the package.
*
* @param pkg the package to be documented
* @param dlTree the content tree to which the description will be added
* @param si the search index item to be updated
*/
protected void addDescription(PackageElement pkg, Content dlTree, SearchIndexItem si) {
Content link = getPackageLink(pkg, new StringContent(utils.getPackageName(pkg)));
if (configuration.showModules) {
si.setContainingModule(utils.getFullyQualifiedName(utils.containingModule(pkg)));
protected void addElementDescription(IndexItem indexItem, Content dlTree, SearchIndexItem si) {
Content dt;
Element element = indexItem.getElement();
String label = indexItem.getLabel();
switch (element.getKind()) {
case MODULE:
dt = HtmlTree.DT(getModuleLink((ModuleElement)element, new StringContent(label)));
si.setCategory(Category.MODULES);
dt.add(" - ").add(contents.module_).add(" " + label);
break;
case PACKAGE:
dt = HtmlTree.DT(getPackageLink((PackageElement)element, new StringContent(label)));
if (configuration.showModules) {
si.setContainingModule(utils.getFullyQualifiedName(utils.containingModule(element)));
}
si.setCategory(Category.PACKAGES);
dt.add(" - ").add(contents.package_).add(" " + label);
break;
case CLASS:
case ENUM:
case ANNOTATION_TYPE:
case INTERFACE:
dt = HtmlTree.DT(getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.Kind.INDEX, (TypeElement)element).strong(true)));
si.setContainingPackage(utils.getPackageName(utils.containingPackage(element)));
si.setCategory(Category.TYPES);
dt.add(" - ");
addClassInfo((TypeElement)element, dt);
break;
default:
TypeElement containingType = indexItem.getTypeElement();
dt = HtmlTree.DT(HtmlTree.SPAN(HtmlStyle.memberNameLink,
getDocLink(LinkInfoImpl.Kind.INDEX, containingType, element, new StringContent(label))));
si.setContainingPackage(utils.getPackageName(utils.containingPackage(element)));
si.setContainingClass(utils.getSimpleName(containingType));
if (utils.isExecutableElement(element)) {
String url = HtmlTree.encodeURL(links.getName(getAnchor((ExecutableElement)element)));
if (!label.equals(url)) {
si.setUrl(url);
}
}
si.setCategory(Category.MEMBERS);
dt.add(" - ");
addMemberDesc(element, containingType, dt);
break;
}
si.setLabel(utils.getPackageName(pkg));
si.setCategory(Category.PACKAGES);
Content dt = HtmlTree.DT(link);
dt.add(" - ");
dt.add(contents.package_);
dt.add(" " + utils.getPackageName(pkg));
dlTree.add(dt);
Content dd = new HtmlTree(TagName.DD);
addSummaryComment(pkg, dd);
dlTree.add(dd);
}
/**
* Add one line summary comment for the class.
*
* @param typeElement the class being documented
* @param dlTree the content tree to which the description will be added
* @param si the search index item to be updated
*/
protected void addDescription(TypeElement typeElement, Content dlTree, SearchIndexItem si) {
Content link = getLink(new LinkInfoImpl(configuration,
LinkInfoImpl.Kind.INDEX, typeElement).strong(true));
si.setContainingPackage(utils.getPackageName(utils.containingPackage(typeElement)));
si.setLabel(utils.getSimpleName(typeElement));
si.setCategory(Category.TYPES);
Content dt = HtmlTree.DT(link);
dt.add(" - ");
addClassInfo(typeElement, dt);
dlTree.add(dt);
Content dd = new HtmlTree(TagName.DD);
addComment(typeElement, dd);
if (element.getKind() == ElementKind.MODULE || element.getKind() == ElementKind.PACKAGE) {
addSummaryComment(element, dd);
} else {
addComment(element, dd);
}
dlTree.add(dd);
}
@ -304,41 +210,6 @@ public class AbstractIndexWriter extends HtmlDocletWriter {
));
}
/**
* Add description for Class, Field, Method or Constructor.
*
* @param member the member of the Class Kind
* @param dlTree the content tree to which the description will be added
* @param si search index item
*/
protected void addDescription(Element member, Content dlTree, SearchIndexItem si) {
si.setContainingPackage(utils.getPackageName(utils.containingPackage(member)));
si.setContainingClass(utils.getSimpleName(utils.getEnclosingTypeElement(member)));
String name = utils.getSimpleName(member);
if (utils.isExecutableElement(member)) {
ExecutableElement ee = (ExecutableElement)member;
name = name + utils.flatSignature(ee);
si.setLabel(name);
String url = HtmlTree.encodeURL(links.getName(getAnchor(ee)));
if (!name.equals(url)) {
si.setUrl(url);
}
} else {
si.setLabel(name);
}
si.setCategory(Category.MEMBERS);
Content span = HtmlTree.SPAN(HtmlStyle.memberNameLink,
getDocLink(LinkInfoImpl.Kind.INDEX, member, name));
Content dt = HtmlTree.DT(span);
dt.add(" - ");
addMemberDesc(member, dt);
dlTree.add(dt);
Content dd = new HtmlTree(TagName.DD);
addComment(member, dd);
dlTree.add(dd);
}
protected void addDescription(SearchIndexItem sii, Content dlTree) {
String siiPath = pathToRoot.isEmpty() ? "" : pathToRoot.getPath() + "/";
siiPath += sii.getUrl();
@ -394,12 +265,12 @@ public class AbstractIndexWriter extends HtmlDocletWriter {
* Add description about the Static Variable/Method/Constructor for a
* member.
*
* @param member MemberDoc for the member within the Class Kind
* @param member element for the member
* @param enclosing the enclosing type element
* @param contentTree the content tree to which the member description will be added
*/
protected void addMemberDesc(Element member, Content contentTree) {
TypeElement containing = utils.getEnclosingTypeElement(member);
String classdesc = utils.getTypeElementName(containing, true) + " ";
protected void addMemberDesc(Element member, TypeElement enclosing, Content contentTree) {
String classdesc = utils.getTypeElementName(enclosing, true) + " ";
if (utils.isField(member)) {
Content resource = contents.getContent(utils.isStatic(member)
? "doclet.Static_variable_in"
@ -414,7 +285,7 @@ public class AbstractIndexWriter extends HtmlDocletWriter {
: "doclet.Method_in", classdesc);
contentTree.add(resource);
}
addPreQualifiedClassLink(LinkInfoImpl.Kind.INDEX, containing,
addPreQualifiedClassLink(LinkInfoImpl.Kind.INDEX, enclosing,
false, contentTree);
}

View File

@ -135,7 +135,7 @@ public abstract class AbstractTreeWriter extends HtmlDocletWriter {
TypeElement typeElement,
Content contentTree)
{
SortedSet<TypeElement> interfaces = new TreeSet<>(utils.makeGeneralPurposeComparator());
SortedSet<TypeElement> interfaces = new TreeSet<>(comparators.makeGeneralPurposeComparator());
typeElement.getInterfaces().forEach(t -> interfaces.add(utils.asTypeElement(t)));
if (interfaces.size() > (utils.isInterface(typeElement) ? 1 : 0)) {
boolean isFirst = true;

View File

@ -22,12 +22,12 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.javadoc.internal.doclets.formats.html;
import java.util.ArrayList;
import java.util.List;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import com.sun.source.doctree.DocTree;
@ -43,6 +43,7 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
import jdk.javadoc.internal.doclets.toolkit.util.IndexBuilder;
import jdk.javadoc.internal.doclets.toolkit.util.IndexItem;
/**
* Generate the file with list of all the classes in this run.
@ -132,9 +133,9 @@ public class AllClassesIndexWriter extends HtmlDocletWriter {
.addTab(resources.annotationTypeSummary, utils::isAnnotationType)
.setTabScript(i -> "show(" + i + ");");
for (Character unicode : indexBuilder.keys()) {
for (Element element : indexBuilder.getMemberList(unicode)) {
TypeElement typeElement = (TypeElement) element;
if (!utils.isCoreClass(typeElement)) {
for (IndexItem indexItem : indexBuilder.getMemberList(unicode)) {
TypeElement typeElement = (TypeElement) indexItem.getElement();
if (typeElement == null || !utils.isCoreClass(typeElement)) {
continue;
}
addTableRow(table, typeElement);

View File

@ -109,7 +109,7 @@ public class AnnotationTypeRequiredMemberWriterImpl extends AbstractMemberWriter
new StringContent(simpleName));
annotationDocTree.add(heading);
return HtmlTree.SECTION(HtmlStyle.detail, annotationDocTree)
.setId(simpleName + utils.signature((ExecutableElement) member));
.setId(simpleName + utils.signature((ExecutableElement) member, typeElement));
}
@Override

View File

@ -107,11 +107,11 @@ public class ClassUseWriter extends SubWriterHolderWriter {
super(configuration, filename);
this.typeElement = typeElement;
if (mapper.classToPackageAnnotations.containsKey(typeElement)) {
pkgToPackageAnnotations = new TreeSet<>(utils.makeClassUseComparator());
pkgToPackageAnnotations = new TreeSet<>(comparators.makeClassUseComparator());
pkgToPackageAnnotations.addAll(mapper.classToPackageAnnotations.get(typeElement));
}
configuration.currentTypeElement = typeElement;
this.pkgSet = new TreeSet<>(utils.makePackageComparator());
this.pkgSet = new TreeSet<>(comparators.makePackageComparator());
this.pkgToClassTypeParameter = pkgDivide(mapper.classToClassTypeParam);
this.pkgToClassAnnotations = pkgDivide(mapper.classToClassAnnotations);
this.pkgToMethodTypeParameter = pkgDivide(mapper.classToMethodTypeParam);
@ -181,7 +181,7 @@ public class ClassUseWriter extends SubWriterHolderWriter {
Map<PackageElement, List<Element>> map = new HashMap<>();
List<? extends Element> elements = (List<? extends Element>) classMap.get(typeElement);
if (elements != null) {
Collections.sort(elements, utils.makeClassUseComparator());
Collections.sort(elements, comparators.makeClassUseComparator());
for (Element e : elements) {
PackageElement pkg = utils.containingPackage(e);
pkgSet.add(pkg);

View File

@ -409,7 +409,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
@Override
public void addImplementedInterfacesInfo(Content classInfoTree) {
SortedSet<TypeMirror> interfaces = new TreeSet<>(utils.makeTypeMirrorClassUseComparator());
SortedSet<TypeMirror> interfaces = new TreeSet<>(comparators.makeTypeMirrorClassUseComparator());
interfaces.addAll(utils.getAllInterfaces(typeElement));
if (utils.isClass(typeElement) && !interfaces.isEmpty()) {
HtmlTree dl = HtmlTree.DL(HtmlStyle.notes);
@ -422,7 +422,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
@Override
public void addSuperInterfacesInfo(Content classInfoTree) {
SortedSet<TypeMirror> interfaces =
new TreeSet<>(utils.makeTypeMirrorIndexUseComparator());
new TreeSet<>(comparators.makeTypeMirrorIndexUseComparator());
interfaces.addAll(utils.getAllInterfaces(typeElement));
if (utils.isInterface(typeElement) && !interfaces.isEmpty()) {

View File

@ -77,7 +77,6 @@ import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
import jdk.javadoc.internal.doclets.formats.html.markup.Entity;
import jdk.javadoc.internal.doclets.formats.html.markup.FixedStringContent;
import jdk.javadoc.internal.doclets.formats.html.markup.Head;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlAttr;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlDocument;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
import jdk.javadoc.internal.doclets.formats.html.markup.TagName;
@ -94,6 +93,7 @@ import jdk.javadoc.internal.doclets.toolkit.PackageSummaryWriter;
import jdk.javadoc.internal.doclets.toolkit.Resources;
import jdk.javadoc.internal.doclets.toolkit.taglets.DocRootTaglet;
import jdk.javadoc.internal.doclets.toolkit.taglets.TagletWriter;
import jdk.javadoc.internal.doclets.toolkit.util.Comparators;
import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
import jdk.javadoc.internal.doclets.toolkit.util.DocFile;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
@ -168,6 +168,8 @@ public class HtmlDocletWriter {
protected final DocPaths docPaths;
protected final Comparators comparators;
/**
* To check whether annotation heading is printed or not.
*/
@ -218,6 +220,7 @@ public class HtmlDocletWriter {
this.resources = configuration.docResources;
this.links = new Links(path);
this.utils = configuration.utils;
this.comparators = utils.comparators;
this.path = path;
this.pathToRoot = path.parent().invert();
this.filename = path.basename();
@ -990,7 +993,7 @@ public class HtmlDocletWriter {
return executableElement.getSimpleName().toString();
}
String member = anchorName(executableElement);
String erasedSignature = utils.makeSignature(executableElement, true, true);
String erasedSignature = utils.makeSignature(executableElement, null, true, true);
return member + erasedSignature;
}
@ -1119,7 +1122,7 @@ public class HtmlDocletWriter {
}
if (utils.isExecutableElement(refMem)) {
if (refMemName.indexOf('(') < 0) {
refMemName += utils.makeSignature((ExecutableElement)refMem, true);
refMemName += utils.makeSignature((ExecutableElement) refMem, null, true);
}
if (overriddenMethod != null) {
// The method to actually link.

View File

@ -314,7 +314,7 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter
VisibleMemberTable vmt = writer.configuration
.getVisibleMemberTable(utils.getEnclosingTypeElement(method));
SortedSet<ExecutableElement> implementedMethods =
new TreeSet<>(utils.makeOverrideUseComparator());
new TreeSet<>(utils.comparators.makeOverrideUseComparator());
implementedMethods.addAll(vmt.getImplementedMethods(method));
for (ExecutableElement implementedMeth : implementedMethods) {
TypeMirror intfac = vmt.getImplementedMethodHolder(method, implementedMeth);

View File

@ -84,13 +84,13 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
* Map of module elements and modifiers required by this module.
*/
private final Map<ModuleElement, Content> requires
= new TreeMap<>(utils.makeModuleComparator());
= new TreeMap<>(comparators.makeModuleComparator());
/**
* Map of indirect modules and modifiers, transitive closure, required by this module.
*/
private final Map<ModuleElement, Content> indirectModules
= new TreeMap<>(utils.makeModuleComparator());
= new TreeMap<>(comparators.makeModuleComparator());
/**
* Details about a package in a module.
@ -120,44 +120,44 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
/**
* Map of packages of this module, and details of whether they are exported or opened.
*/
private final Map<PackageElement, PackageEntry> packages = new TreeMap<>(utils.makePackageComparator());
private final Map<PackageElement, PackageEntry> packages = new TreeMap<>(utils.comparators.makePackageComparator());
/**
* Map of indirect modules (transitive closure) and their exported packages.
*/
private final Map<ModuleElement, SortedSet<PackageElement>> indirectPackages
= new TreeMap<>(utils.makeModuleComparator());
= new TreeMap<>(comparators.makeModuleComparator());
/**
* Map of indirect modules (transitive closure) and their open packages.
*/
private final Map<ModuleElement, SortedSet<PackageElement>> indirectOpenPackages
= new TreeMap<>(utils.makeModuleComparator());
= new TreeMap<>(comparators.makeModuleComparator());
/**
* Set of services used by the module.
*/
private final SortedSet<TypeElement> uses
= new TreeSet<>(utils.makeAllClassesComparator());
= new TreeSet<>(comparators.makeAllClassesComparator());
/**
* Map of services used by the module and specified using @uses javadoc tag, and description.
*/
private final Map<TypeElement, Content> usesTrees
= new TreeMap<>(utils.makeAllClassesComparator());
= new TreeMap<>(comparators.makeAllClassesComparator());
/**
* Map of services provided by this module, and set of its implementations.
*/
private final Map<TypeElement, SortedSet<TypeElement>> provides
= new TreeMap<>(utils.makeAllClassesComparator());
= new TreeMap<>(comparators.makeAllClassesComparator());
/**
* Map of services provided by the module and specified using @provides javadoc tag, and
* description.
*/
private final Map<TypeElement, Content> providesTrees
= new TreeMap<>(utils.makeAllClassesComparator());
= new TreeMap<>(comparators.makeAllClassesComparator());
private final Navigation navBar;
@ -288,7 +288,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
// Include package if in details mode, or exported to all (i.e. targetModules == null)
if (moduleMode == ModuleMode.ALL || targetMdles == null) {
PackageEntry packageEntry = packages.computeIfAbsent(p, pkg -> new PackageEntry());
SortedSet<ModuleElement> mdleList = new TreeSet<>(utils.makeModuleComparator());
SortedSet<ModuleElement> mdleList = new TreeSet<>(utils.comparators.makeModuleComparator());
if (targetMdles != null) {
mdleList.addAll(targetMdles);
}
@ -306,7 +306,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
// Include package if in details mode, or opened to all (i.e. targetModules == null)
if (moduleMode == ModuleMode.ALL || targetMdles == null) {
PackageEntry packageEntry = packages.computeIfAbsent(p, pkg -> new PackageEntry());
SortedSet<ModuleElement> mdleList = new TreeSet<>(utils.makeModuleComparator());
SortedSet<ModuleElement> mdleList = new TreeSet<>(utils.comparators.makeModuleComparator());
if (targetMdles != null) {
mdleList.addAll(targetMdles);
}
@ -318,7 +318,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
// Get all the exported and opened packages, for the transitive closure of the module, to be displayed in
// the indirect packages tables.
dependentModules.forEach((module, mod) -> {
SortedSet<PackageElement> exportedPackages = new TreeSet<>(utils.makePackageComparator());
SortedSet<PackageElement> exportedPackages = new TreeSet<>(utils.comparators.makePackageComparator());
ElementFilter.exportsIn(module.getDirectives()).forEach(directive -> {
PackageElement pkg = directive.getPackage();
if (shouldDocument(pkg)) {
@ -333,7 +333,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
if (!exportedPackages.isEmpty()) {
indirectPackages.put(module, exportedPackages);
}
SortedSet<PackageElement> openPackages = new TreeSet<>(utils.makePackageComparator());
SortedSet<PackageElement> openPackages = new TreeSet<>(utils.comparators.makePackageComparator());
if (module.isOpen()) {
openPackages.addAll(utils.getModulePackageMap().getOrDefault(module, Collections.emptySet()));
} else {
@ -365,7 +365,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
TypeElement u = directive.getService();
if (shouldDocument(u)) {
List<? extends TypeElement> implList = directive.getImplementations();
SortedSet<TypeElement> implSet = new TreeSet<>(utils.makeAllClassesComparator());
SortedSet<TypeElement> implSet = new TreeSet<>(utils.comparators.makeAllClassesComparator());
implSet.addAll(implList);
provides.put(u, implSet);
}

View File

@ -88,7 +88,7 @@ public class PackageUseWriter extends SubWriterHolderWriter {
Set<TypeElement> usedClasses = usingPackageToUsedClasses
.get(utils.getPackageName(usingPackage));
if (usedClasses == null) {
usedClasses = new TreeSet<>(utils.makeGeneralPurposeComparator());
usedClasses = new TreeSet<>(comparators.makeGeneralPurposeComparator());
usingPackageToUsedClasses.put(utils.getPackageName(usingPackage),
usedClasses);
}

View File

@ -69,9 +69,9 @@ public final class SearchIndexItems {
private Set<SearchIndexItem> newSetForCategory(Category category) {
final Comparator<SearchIndexItem> cmp;
if (category == Category.TYPES) {
cmp = utils.makeTypeSearchIndexComparator();
cmp = utils.comparators.makeTypeSearchIndexComparator();
} else {
cmp = utils.makeGenericSearchIndexComparator();
cmp = utils.comparators.makeGenericSearchIndexComparator();
}
return new TreeSet<>(cmp);
}

View File

@ -105,14 +105,10 @@ public class SingleIndexWriter extends AbstractIndexWriter {
elements.addAll(tagSearchIndexMap.keySet());
addLinksForIndexes(mainContent);
for (Character unicode : elements) {
if (tagSearchIndexMap.get(unicode) == null) {
addContents(unicode, indexBuilder.getMemberList(unicode), mainContent);
} else if (indexBuilder.getMemberList(unicode) == null) {
addSearchContents(unicode, tagSearchIndexMap.get(unicode), mainContent);
} else {
addContents(unicode, indexBuilder.getMemberList(unicode),
tagSearchIndexMap.get(unicode), mainContent);
if (tagSearchIndexMap.get(unicode) != null) {
indexBuilder.addSearchTags(unicode, tagSearchIndexMap.get(unicode));
}
addContents(unicode, indexBuilder.getMemberList(unicode), mainContent);
}
addLinksForIndexes(mainContent);
HtmlTree footer = HtmlTree.FOOTER();

View File

@ -135,14 +135,10 @@ public class SplitIndexWriter extends AbstractIndexWriter {
contents.getContent("doclet.Index"))));
Content mainContent = new ContentBuilder();
addLinksForIndexes(mainContent);
if (tagSearchIndexMap.get(unicode) == null) {
addContents(unicode, indexBuilder.getMemberList(unicode), mainContent);
} else if (indexBuilder.getMemberList(unicode) == null) {
addSearchContents(unicode, tagSearchIndexMap.get(unicode), mainContent);
} else {
addContents(unicode, indexBuilder.getMemberList(unicode),
tagSearchIndexMap.get(unicode), mainContent);
if (tagSearchIndexMap.get(unicode) != null) {
indexBuilder.addSearchTags(unicode, tagSearchIndexMap.get(unicode));
}
addContents(unicode, indexBuilder.getMemberList(unicode), mainContent);
addLinksForIndexes(mainContent);
main.add(mainContent);
HtmlTree footer = HtmlTree.FOOTER();

View File

@ -432,7 +432,8 @@ public class TagletWriterImpl extends TagletWriter {
@Override
public Void visitExecutable(ExecutableElement e, Void p) {
si.setHolder(utils.getFullyQualifiedName(utils.getEnclosingTypeElement(e))
+ "." + utils.getSimpleName(e) + utils.flatSignature(e));
+ "." + utils.getSimpleName(e)
+ utils.flatSignature(e, htmlWriter.getCurrentPageElement()));
return null;
}

View File

@ -265,7 +265,7 @@ public abstract class AbstractDoclet implements Doclet {
protected void generateClassFiles(DocletEnvironment docEnv, ClassTree classtree)
throws DocletException {
generateClassFiles(classtree);
SortedSet<PackageElement> packages = new TreeSet<>(utils.makePackageComparator());
SortedSet<PackageElement> packages = new TreeSet<>(utils.comparators.makePackageComparator());
packages.addAll(configuration.getSpecifiedPackageElements());
configuration.modulePackages.values().stream().forEach(packages::addAll);
for (PackageElement pkg : packages) {

View File

@ -47,6 +47,7 @@ import jdk.javadoc.doclet.Taglet;
import jdk.javadoc.internal.doclets.formats.html.HtmlDoclet;
import jdk.javadoc.internal.doclets.toolkit.builders.BuilderFactory;
import jdk.javadoc.internal.doclets.toolkit.taglets.TagletManager;
import jdk.javadoc.internal.doclets.toolkit.util.Comparators;
import jdk.javadoc.internal.doclets.toolkit.util.DocFile;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileFactory;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
@ -308,16 +309,17 @@ public abstract class BaseConfiguration {
}
private void initModules() {
Comparators comparators = utils.comparators;
// Build the modules structure used by the doclet
modules = new TreeSet<>(utils.makeModuleComparator());
modules = new TreeSet<>(comparators.makeModuleComparator());
modules.addAll(getSpecifiedModuleElements());
modulePackages = new TreeMap<>(utils.makeModuleComparator());
modulePackages = new TreeMap<>(comparators.makeModuleComparator());
for (PackageElement p : packages) {
ModuleElement mdle = docEnv.getElementUtils().getModuleOf(p);
if (mdle != null && !mdle.isUnnamed()) {
Set<PackageElement> s = modulePackages
.computeIfAbsent(mdle, m -> new TreeSet<>(utils.makePackageComparator()));
.computeIfAbsent(mdle, m -> new TreeSet<>(comparators.makePackageComparator()));
s.add(p);
}
}
@ -326,7 +328,7 @@ public abstract class BaseConfiguration {
ModuleElement mdle = docEnv.getElementUtils().getModuleOf(p);
if (mdle != null && !mdle.isUnnamed()) {
Set<PackageElement> s = modulePackages
.computeIfAbsent(mdle, m -> new TreeSet<>(utils.makePackageComparator()));
.computeIfAbsent(mdle, m -> new TreeSet<>(comparators.makePackageComparator()));
s.add(p);
}
}
@ -342,7 +344,7 @@ public abstract class BaseConfiguration {
}
private void initPackages() {
packages = new TreeSet<>(utils.makePackageComparator());
packages = new TreeSet<>(utils.comparators.makePackageComparator());
// add all the included packages
packages.addAll(includedPackageElements);
}

View File

@ -445,8 +445,8 @@ public class WorkArounds {
NewSerializedForm(Utils utils, Elements elements, TypeElement te) {
this.utils = utils;
this.elements = elements;
methods = new TreeSet<>(utils.makeGeneralPurposeComparator());
fields = new TreeSet<>(utils.makeGeneralPurposeComparator());
methods = new TreeSet<>(utils.comparators.makeGeneralPurposeComparator());
fields = new TreeSet<>(utils.comparators.makeGeneralPurposeComparator());
if (utils.isExternalizable(te)) {
/* look up required public accessible methods,
* writeExternal and readExternal.

View File

@ -96,7 +96,7 @@ public class ConstantsSummaryBuilder extends AbstractBuilder {
super(context);
this.writer = writer;
this.typeElementsWithConstFields = new HashSet<>();
this.printedPackageHeaders = new TreeSet<>(utils.makePackageComparator());
this.printedPackageHeaders = new TreeSet<>(utils.comparators.makePackageComparator());
}
/**
@ -315,7 +315,7 @@ public class ConstantsSummaryBuilder extends AbstractBuilder {
members.addAll(vmt.getVisibleMembers(FIELDS));
members.addAll(vmt.getVisibleMembers(ENUM_CONSTANTS));
SortedSet<VariableElement> includes =
new TreeSet<>(utils.makeGeneralPurposeComparator());
new TreeSet<>(utils.comparators.makeGeneralPurposeComparator());
for (Element element : members) {
VariableElement member = (VariableElement)element;
if (member.getConstantValue() != null) {

View File

@ -84,7 +84,7 @@ public abstract class MemberSummaryBuilder extends AbstractMemberBuilder {
private MemberSummaryBuilder(Context context, TypeElement typeElement) {
super(context, typeElement);
memberSummaryWriters = new EnumMap<>(VisibleMemberTable.Kind.class);
comparator = utils.makeIndexUseComparator();
comparator = utils.comparators.makeIndexElementComparator();
pHelper = new PropertyHelper(this);
}

View File

@ -117,7 +117,7 @@ public class SerializedFormBuilder extends AbstractBuilder {
*/
@Override
public void build() throws DocletException {
SortedSet<TypeElement> rootclasses = new TreeSet<>(utils.makeGeneralPurposeComparator());
SortedSet<TypeElement> rootclasses = new TreeSet<>(utils.comparators.makeGeneralPurposeComparator());
rootclasses.addAll(configuration.getIncludedTypeElements());
if (!serialClassFoundToDocument(rootclasses)) {
//Nothing to document.
@ -470,7 +470,7 @@ public class SerializedFormBuilder extends AbstractBuilder {
// ObjectStreamFields. Print a member for each serialField tag.
// (There should be one serialField tag per ObjectStreamField
// element.)
SortedSet<SerialFieldTree> tags = new TreeSet<>(utils.makeSerialFieldTreeComparator());
SortedSet<SerialFieldTree> tags = new TreeSet<>(utils.comparators.makeSerialFieldTreeComparator());
// sort the elements
for (DocTree dt : utils.getSerialFieldTrees(field)) {
SerialFieldTree st = (SerialFieldTree) dt;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2020, 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
@ -84,7 +84,7 @@ public class InheritDocTaglet extends BaseTaglet {
!(inheritableTaglet instanceof InheritableTaglet)) {
String message = utils.getSimpleName(e) +
((utils.isExecutableElement(e))
? utils.flatSignature((ExecutableElement)e)
? utils.flatSignature((ExecutableElement)e, writer.getCurrentPageElement())
: "");
//This tag does not support inheritance.
messages.warning(e, "doclet.noInheritedDoc", message);
@ -103,7 +103,7 @@ public class InheritDocTaglet extends BaseTaglet {
} else {
String message = utils.getSimpleName(e) +
((utils.isExecutableElement(e))
? utils.flatSignature((ExecutableElement)e)
? utils.flatSignature((ExecutableElement)e, writer.getCurrentPageElement())
: "");
messages.warning(e, "doclet.noInheritedDoc", message);
}

View File

@ -111,7 +111,7 @@ public class ClassTree {
Messages messages = configuration.getMessages();
messages.notice("doclet.Building_Tree");
comparator = utils.makeClassUseComparator();
comparator = utils.comparators.makeClassUseComparator();
baseAnnotationTypes = new TreeSet<>(comparator);
baseEnums = new TreeSet<>(comparator);
baseClasses = new TreeSet<>(comparator);
@ -128,7 +128,7 @@ public class ClassTree {
public ClassTree(DocletEnvironment docEnv, BaseConfiguration configuration) {
this.configuration = configuration;
this.utils = configuration.utils;
comparator = utils.makeClassUseComparator();
comparator = utils.comparators.makeClassUseComparator();
baseAnnotationTypes = new TreeSet<>(comparator);
baseEnums = new TreeSet<>(comparator);
baseClasses = new TreeSet<>(comparator);
@ -145,7 +145,7 @@ public class ClassTree {
public ClassTree(SortedSet<TypeElement>classesSet, BaseConfiguration configuration) {
this.configuration = configuration;
this.utils = configuration.utils;
comparator = utils.makeClassUseComparator();
comparator = utils.comparators.makeClassUseComparator();
baseAnnotationTypes = new TreeSet<>(comparator);
baseEnums = new TreeSet<>(comparator);
baseClasses = new TreeSet<>(comparator);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2020, 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
@ -190,14 +190,16 @@ public class ClassUseMapper {
private final Elements elementUtils;
private final Types typeUtils;
private final Utils utils;
private final Comparators comparators;
public ClassUseMapper(BaseConfiguration configuration, ClassTree classtree) {
docEnv = configuration.docEnv;
elementUtils = docEnv.getElementUtils();
typeUtils = docEnv.getTypeUtils();
utils = configuration.utils;
comparators = utils.comparators;
this.classtree = classtree;
classToPackage = new TreeMap<>(utils.makeClassUseComparator());
classToPackage = new TreeMap<>(comparators.makeClassUseComparator());
// Map subclassing, subinterfacing implementing, ...
for (TypeElement te : classtree.baseClasses()) {
subclasses(te);
@ -282,7 +284,7 @@ public class ClassUseMapper {
private Collection<TypeElement> subclasses(TypeElement te) {
Collection<TypeElement> ret = classToSubclass.get(te);
if (ret == null) {
ret = new TreeSet<>(utils.makeClassUseComparator());
ret = new TreeSet<>(comparators.makeClassUseComparator());
Set<TypeElement> subs = classtree.subClasses(te);
if (subs != null) {
ret.addAll(subs);
@ -301,7 +303,7 @@ public class ClassUseMapper {
private Collection<TypeElement> subinterfaces(TypeElement te) {
Collection<TypeElement> ret = classToSubinterface.get(te);
if (ret == null) {
ret = new TreeSet<>(utils.makeClassUseComparator());
ret = new TreeSet<>(comparators.makeClassUseComparator());
Set<TypeElement> subs = classtree.subInterfaces(te);
if (subs != null) {
ret.addAll(subs);
@ -322,7 +324,7 @@ public class ClassUseMapper {
private Collection<TypeElement> implementingClasses(TypeElement te) {
Collection<TypeElement> ret = classToImplementingClass.get(te);
if (ret == null) {
ret = new TreeSet<>(utils.makeClassUseComparator());
ret = new TreeSet<>(comparators.makeClassUseComparator());
Set<TypeElement> impl = classtree.implementingClasses(te);
if (impl != null) {
ret.addAll(impl);
@ -343,7 +345,7 @@ public class ClassUseMapper {
*/
private void mapExecutable(ExecutableElement ee) {
final boolean isConstructor = utils.isConstructor(ee);
Set<TypeMirror> classArgs = new TreeSet<>(utils.makeTypeMirrorClassUseComparator());
Set<TypeMirror> classArgs = new TreeSet<>(comparators.makeTypeMirrorClassUseComparator());
for (VariableElement param : ee.getParameters()) {
TypeMirror pType = param.asType();
// primitives don't get mapped and type variables are mapped elsewhere
@ -427,7 +429,7 @@ public class ClassUseMapper {
private Set<PackageElement> packageSet(TypeElement te) {
Set<PackageElement> pkgSet = classToPackage.get(te);
if (pkgSet == null) {
pkgSet = new TreeSet<>(utils.makeClassUseComparator());
pkgSet = new TreeSet<>(comparators.makeClassUseComparator());
classToPackage.put(te, pkgSet);
}
return pkgSet;
@ -436,7 +438,7 @@ public class ClassUseMapper {
private Set<TypeElement> classSet(TypeElement te) {
Set<TypeElement> clsSet = classToClass.get(te);
if (clsSet == null) {
clsSet = new TreeSet<>(utils.makeClassUseComparator());
clsSet = new TreeSet<>(comparators.makeClassUseComparator());
classToClass.put(te, clsSet);
}
return clsSet;

View File

@ -405,16 +405,6 @@ public class CommentHelper {
return (n == -1) ? null : s.substring(n + 1);
}
public String getReferencedMemberName(Element e) {
if (e == null) {
return null;
}
Utils utils = configuration.utils;
return utils.isExecutableElement(e)
? utils.getSimpleName(e) + utils.makeSignature((ExecutableElement) e, true, true)
: utils.getSimpleName(e);
}
public PackageElement getReferencedPackage(DocTree dtree) {
Element e = getReferencedElement(dtree);
if (e != null) {

View File

@ -0,0 +1,589 @@
/*
* Copyright (c) 2020, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.javadoc.internal.doclets.toolkit.util;
import com.sun.source.doctree.SerialFieldTree;
import jdk.javadoc.internal.doclets.formats.html.SearchIndexItem;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.SimpleElementVisitor14;
import javax.lang.model.util.SimpleTypeVisitor9;
import java.util.Comparator;
import java.util.List;
/**
* A collection of {@code Comparator} factory methods.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class Comparators {
private final Utils utils;
Comparators(Utils utils) {
this.utils = utils;
}
private Comparator<Element> moduleComparator = null;
/**
* Comparator for ModuleElements, simply compares the fully qualified names
* @return a Comparator
*/
public Comparator<Element> makeModuleComparator() {
if (moduleComparator == null) {
moduleComparator = new ElementComparator() {
@Override
public int compare(Element mod1, Element mod2) {
return compareFullyQualifiedNames(mod1, mod2);
}
};
}
return moduleComparator;
}
private Comparator<Element> allClassesComparator = null;
/**
* Returns a Comparator for all classes, compares the simple names of
* TypeElement, if equal then the fully qualified names.
*
* @return Comparator
*/
public Comparator<Element> makeAllClassesComparator() {
if (allClassesComparator == null) {
allClassesComparator = new ElementComparator() {
@Override
public int compare(Element e1, Element e2) {
int result = compareNames(e1, e2);
if (result == 0)
result = compareFullyQualifiedNames(e1, e2);
return result;
}
};
}
return allClassesComparator;
}
private Comparator<Element> packageComparator = null;
/**
* Returns a Comparator for packages, by comparing the fully qualified names.
*
* @return a Comparator
*/
public Comparator<Element> makePackageComparator() {
if (packageComparator == null) {
packageComparator = new ElementComparator() {
@Override
public int compare(Element pkg1, Element pkg2) {
return compareFullyQualifiedNames(pkg1, pkg2);
}
};
}
return packageComparator;
}
private Comparator<Element> deprecatedComparator = null;
/**
* Returns a Comparator for deprecated items listed on deprecated list page, by comparing the
* fully qualified names.
*
* @return a Comparator
*/
public Comparator<Element> makeDeprecatedComparator() {
if (deprecatedComparator == null) {
deprecatedComparator = new ElementComparator() {
@Override
public int compare(Element e1, Element e2) {
return compareFullyQualifiedNames(e1, e2);
}
};
}
return deprecatedComparator;
}
private Comparator<SerialFieldTree> serialFieldTreeComparator = null;
/**
* Returns a Comparator for SerialFieldTree.
* @return a Comparator
*/
public Comparator<SerialFieldTree> makeSerialFieldTreeComparator() {
if (serialFieldTreeComparator == null) {
serialFieldTreeComparator = (SerialFieldTree o1, SerialFieldTree o2) -> {
String s1 = o1.getName().toString();
String s2 = o2.getName().toString();
return s1.compareTo(s2);
};
}
return serialFieldTreeComparator;
}
/**
* Returns a general purpose comparator.
* @return a Comparator
*/
public Comparator<Element> makeGeneralPurposeComparator() {
return makeClassUseComparator();
}
private Comparator<Element> overrideUseComparator = null;
/**
* Returns a Comparator for overrides and implements,
* used primarily on methods, compares the name first,
* then compares the simple names of the enclosing
* TypeElement and the fully qualified name of the enclosing TypeElement.
* @return a Comparator
*/
public Comparator<Element> makeOverrideUseComparator() {
if (overrideUseComparator == null) {
overrideUseComparator = new ElementComparator() {
@Override
public int compare(Element o1, Element o2) {
int result = utils.compareStrings(utils.getSimpleName(o1), utils.getSimpleName(o2));
if (result != 0) {
return result;
}
if (!utils.isTypeElement(o1) && !utils.isTypeElement(o2) && !utils.isPackage(o1) && !utils.isPackage(o2)) {
TypeElement t1 = utils.getEnclosingTypeElement(o1);
TypeElement t2 = utils.getEnclosingTypeElement(o2);
result = utils.compareStrings(utils.getSimpleName(t1), utils.getSimpleName(t2));
if (result != 0)
return result;
}
result = utils.compareStrings(utils.getFullyQualifiedName(o1), utils.getFullyQualifiedName(o2));
if (result != 0)
return result;
return compareElementKinds(o1, o2);
}
};
}
return overrideUseComparator;
}
private Comparator<Element> indexUseComparator = null;
/**
* Returns an {@code Element} Comparator for index file presentations, and are sorted as follows.
* If comparing modules and/or packages then simply compare the qualified names,
* if comparing a module or a package with a type/member then compare the
* FullyQualifiedName of the module or a package with the SimpleName of the entity,
* otherwise:
* 1. compare the ElementKind ex: Module, Package, Interface etc.
* 2a. if equal and if the type is of ExecutableElement(Constructor, Methods),
* a case insensitive comparison of parameter the type signatures
* 2b. if equal, case sensitive comparison of the type signatures
* 3. finally, if equal, compare the FQNs of the entities
* @return an element comparator for index file use
*/
public Comparator<Element> makeIndexElementComparator() {
if (indexUseComparator == null) {
indexUseComparator = new ElementComparator() {
/**
* Compares two elements.
*
* @param e1 - an element.
* @param e2 - an element.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
@Override
public int compare(Element e1, Element e2) {
int result;
// first, compare names as appropriate
if ((utils.isModule(e1) || utils.isPackage(e1)) && (utils.isModule(e2) || utils.isPackage(e2))) {
result = compareFullyQualifiedNames(e1, e2);
} else if (utils.isModule(e1) || utils.isPackage(e1)) {
result = utils.compareStrings(utils.getFullyQualifiedName(e1), utils.getSimpleName(e2));
} else if (utils.isModule(e2) || utils.isPackage(e2)) {
result = utils.compareStrings(utils.getSimpleName(e1), utils.getFullyQualifiedName(e2));
} else {
result = compareNames(e1, e2);
}
if (result != 0) {
return result;
}
// if names are the same, compare element kinds
result = compareElementKinds(e1, e2);
if (result != 0) {
return result;
}
// if element kinds are the same, and are methods,
// compare the method parameters
if (hasParameters(e1)) {
List<? extends VariableElement> parameters1 = ((ExecutableElement)e1).getParameters();
List<? extends VariableElement> parameters2 = ((ExecutableElement)e2).getParameters();
result = compareParameters(false, parameters1, parameters2);
if (result != 0) {
return result;
}
result = compareParameters(true, parameters1, parameters2);
if (result != 0) {
return result;
}
}
// else fall back on fully qualified names
return compareFullyQualifiedNames(e1, e2);
}
};
}
return indexUseComparator;
}
/**
* Returns a comparator for the {@code IndexItem}s in the index page. This is a composite
* comparator that must be able to compare all kinds {@code Element}s as well as
* {@code SearchIndexItem}s.
*
* @return a comparator for index page items.
*/
public Comparator<IndexItem> makeIndexComparator(boolean classesOnly) {
Comparator<Element> elementComparator = classesOnly
? makeAllClassesComparator()
: makeIndexElementComparator();
Comparator<SearchIndexItem> searchTagComparator =
makeGenericSearchIndexComparator();
return (o1, o2) -> {
// Compare two elements
if (o1.getElement() != null && o2.getElement() != null) {
return elementComparator.compare(o1.getElement(), o2.getElement());
}
// Compare two search tags
if (o1.getSearchTag() != null && o2.getSearchTag() != null) {
return searchTagComparator.compare(o1.getSearchTag(), o2.getSearchTag());
}
// Compare an element with a search tag.
// Compares labels, if those are equal put the search tag first.
int d = utils.compareStrings(o1.getLabel(), o2.getLabel());
if (d == 0) {
d = o1.getElement() == null ? 1 : -1;
}
return d;
};
}
private Comparator<TypeMirror> typeMirrorClassUseComparator = null;
/**
* Compares the FullyQualifiedNames of two TypeMirrors
* @return
*/
public Comparator<TypeMirror> makeTypeMirrorClassUseComparator() {
if (typeMirrorClassUseComparator == null) {
typeMirrorClassUseComparator = (TypeMirror type1, TypeMirror type2) -> {
String s1 = utils.getQualifiedTypeName(type1);
String s2 = utils.getQualifiedTypeName(type2);
return utils.compareStrings(s1, s2);
};
}
return typeMirrorClassUseComparator;
}
private Comparator<TypeMirror> typeMirrorIndexUseComparator = null;
/**
* Compares the SimpleNames of TypeMirrors if equal then the
* FullyQualifiedNames of TypeMirrors.
*
* @return
*/
public Comparator<TypeMirror> makeTypeMirrorIndexUseComparator() {
if (typeMirrorIndexUseComparator == null) {
typeMirrorIndexUseComparator = (TypeMirror t1, TypeMirror t2) -> {
int result = utils.compareStrings(utils.getTypeName(t1, false), utils.getTypeName(t2, false));
if (result != 0)
return result;
return utils.compareStrings(utils.getQualifiedTypeName(t1), utils.getQualifiedTypeName(t2));
};
}
return typeMirrorIndexUseComparator;
}
private Comparator<Element> classUseComparator = null;
/**
* Comparator for ClassUse presentations, and sorts as follows:
* 1. member names
* 2. then fully qualified member names
* 3. then parameter types if applicable
* 4. finally the element kinds ie. package, class, interface etc.
* @return a comparator to sort classes and members for class use
*/
public Comparator<Element> makeClassUseComparator() {
if (classUseComparator == null) {
classUseComparator = new ElementComparator() {
/**
* Compares two Elements.
*
* @param e1 - an element.
* @param e2 - an element.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
@Override
public int compare(Element e1, Element e2) {
int result = compareNames(e1, e2);
if (result != 0) {
return result;
}
result = compareFullyQualifiedNames(e1, e2);
if (result != 0) {
return result;
}
if (hasParameters(e1) && hasParameters(e2)) {
List<? extends VariableElement> parameters1 = ((ExecutableElement)e1).getParameters();
List<? extends VariableElement> parameters2 = ((ExecutableElement)e2).getParameters();
result = compareParameters(false, parameters1, parameters2);
if (result != 0) {
return result;
}
result = compareParameters(true, parameters1, parameters2);
}
if (result != 0) {
return result;
}
return compareElementKinds(e1, e2);
}
};
}
return classUseComparator;
}
/**
* A general purpose comparator to sort Element entities, basically provides the building blocks
* for creating specific comparators for an use-case.
*/
private abstract class ElementComparator implements Comparator<Element> {
public ElementComparator() { }
/**
* compares two parameter arrays by first comparing the length of the arrays, and
* then each Type of the parameter in the array.
* @param params1 the first parameter array.
* @param params2 the first parameter array.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
protected int compareParameters(boolean caseSensitive, List<? extends VariableElement> params1,
List<? extends VariableElement> params2) {
return utils.compareStrings(caseSensitive, getParametersAsString(params1),
getParametersAsString(params2));
}
String getParametersAsString(List<? extends VariableElement> params) {
StringBuilder sb = new StringBuilder();
for (VariableElement param : params) {
TypeMirror t = param.asType();
// prefix P for primitive and R for reference types, thus items will
// be ordered lexically and correctly.
sb.append(getTypeCode(t)).append("-").append(t).append("-");
}
return sb.toString();
}
private String getTypeCode(TypeMirror t) {
return new SimpleTypeVisitor9<String, Void>() {
@Override
public String visitPrimitive(PrimitiveType t, Void p) {
return "P";
}
@Override
public String visitArray(ArrayType t, Void p) {
return visit(t.getComponentType());
}
@Override
protected String defaultAction(TypeMirror e, Void p) {
return "R";
}
}.visit(t);
}
/**
* Compares two Elements, typically the name of a method,
* field or constructor.
* @param e1 the first Element.
* @param e2 the second Element.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
protected int compareNames(Element e1, Element e2) {
return utils.compareStrings(utils.getSimpleName(e1), utils.getSimpleName(e2));
}
/**
* Compares the fully qualified names of the entities
* @param e1 the first Element.
* @param e2 the first Element.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
protected int compareFullyQualifiedNames(Element e1, Element e2) {
// add simplename to be compatible
String thisElement = getFullyQualifiedName(e1);
String thatElement = getFullyQualifiedName(e2);
return utils.compareStrings(thisElement, thatElement);
}
protected int compareElementKinds(Element e1, Element e2) {
return Integer.compare(getKindIndex(e1), getKindIndex(e2));
}
private int getKindIndex(Element e) {
switch (e.getKind()) {
case MODULE: return 0;
case PACKAGE: return 1;
case CLASS: return 2;
case ENUM: return 3;
case ENUM_CONSTANT: return 4;
case RECORD: return 5;
case INTERFACE: return 6;
case ANNOTATION_TYPE: return 7;
case FIELD: return 8;
case CONSTRUCTOR: return 9;
case METHOD: return 10;
default: throw new IllegalArgumentException(e.getKind().toString());
}
}
@SuppressWarnings("preview")
boolean hasParameters(Element e) {
return new SimpleElementVisitor14<Boolean, Void>() {
@Override
public Boolean visitExecutable(ExecutableElement e, Void p) {
return true;
}
@Override
protected Boolean defaultAction(Element e, Void p) {
return false;
}
}.visit(e);
}
/**
* The fully qualified names of the entities, used solely by the comparator.
*
* @return a negative integer, zero, or a positive integer as the first argument is less
* than, equal to, or greater than the second.
*/
@SuppressWarnings("preview")
private String getFullyQualifiedName(Element e) {
return new SimpleElementVisitor14<String, Void>() {
@Override
public String visitModule(ModuleElement e, Void p) {
return e.getQualifiedName().toString();
}
@Override
public String visitPackage(PackageElement e, Void p) {
return e.getQualifiedName().toString();
}
@Override
public String visitExecutable(ExecutableElement e, Void p) {
// For backward compatibility
return getFullyQualifiedName(e.getEnclosingElement())
+ "." + e.getSimpleName().toString();
}
@Override
public String visitType(TypeElement e, Void p) {
return e.getQualifiedName().toString();
}
@Override
protected String defaultAction(Element e, Void p) {
return utils.getEnclosingTypeElement(e).getQualifiedName().toString()
+ "." + e.getSimpleName().toString();
}
}.visit(e);
}
}
/**
* Returns a Comparator for SearchIndexItems representing types. Items are
* compared by short name, or full string representation if names are equal.
*
* @return a Comparator
*/
public Comparator<SearchIndexItem> makeTypeSearchIndexComparator() {
return (SearchIndexItem sii1, SearchIndexItem sii2) -> {
int result = utils.compareStrings(sii1.getSimpleName(), sii2.getSimpleName());
if (result == 0) {
// TreeSet needs this to be consistent with equal so we do
// a plain comparison of string representations as fallback.
result = sii1.toString().compareTo(sii2.toString());
}
return result;
};
}
private Comparator<SearchIndexItem> genericSearchIndexComparator = null;
/**
* Returns a Comparator for SearchIndexItems representing modules, packages, or members.
* Items are compared by label (member name plus signature for members, package name for
* packages, and module name for modules). If labels are equal then full string
* representation is compared.
*
* @return a Comparator
*/
public Comparator<SearchIndexItem> makeGenericSearchIndexComparator() {
if (genericSearchIndexComparator == null) {
genericSearchIndexComparator = (SearchIndexItem sii1, SearchIndexItem sii2) -> {
int result = utils.compareStrings(sii1.getLabel(), sii2.getLabel());
if (result == 0) {
// TreeSet needs this to be consistent with equal so we do
// a plain comparison of string representations as fallback.
result = sii1.toString().compareTo(sii2.toString());
}
return result;
};
}
return genericSearchIndexComparator;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2020, 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
@ -76,7 +76,7 @@ public class DeprecatedAPIListBuilder {
deprecatedMap = new EnumMap<>(DeprElementKind.class);
for (DeprElementKind kind : DeprElementKind.values()) {
deprecatedMap.put(kind,
new TreeSet<>(utils.makeDeprecatedComparator()));
new TreeSet<>(utils.comparators.makeDeprecatedComparator()));
}
buildDeprecatedAPIInfo();
}
@ -85,8 +85,6 @@ public class DeprecatedAPIListBuilder {
* Build the sorted list of all the deprecated APIs in this run.
* Build separate lists for deprecated modules, packages, classes, constructors,
* methods and fields.
*
* @param configuration the current configuration of the doclet.
*/
private void buildDeprecatedAPIInfo() {
SortedSet<Element> rset = deprecatedMap.get(DeprElementKind.REMOVAL);
@ -165,7 +163,6 @@ public class DeprecatedAPIListBuilder {
*
* @param rset set of elements deprecated for removal.
* @param sset set of deprecated elements.
* @param list List of all the particular deprecated members, e.g. methods.
* @param members members to be added in the list.
*/
private void composeDeprecatedList(SortedSet<Element> rset, SortedSet<Element> sset, List<? extends Element> members) {

View File

@ -331,7 +331,7 @@ public class Group {
*/
SortedSet<PackageElement> getPkgList(Map<String, SortedSet<PackageElement>> map,
String groupname) {
return map.computeIfAbsent(groupname, g -> new TreeSet<>(configuration.utils.makePackageComparator()));
return map.computeIfAbsent(groupname, g -> new TreeSet<>(configuration.utils.comparators.makePackageComparator()));
}
/**
@ -343,7 +343,7 @@ public class Group {
*/
SortedSet<ModuleElement> getModuleList(Map<String, SortedSet<ModuleElement>> map,
String groupname) {
return map.computeIfAbsent(groupname, g -> new TreeSet<>(configuration.utils.makeModuleComparator()));
return map.computeIfAbsent(groupname, g -> new TreeSet<>(configuration.utils.comparators.makeModuleComparator()));
}
/**

View File

@ -33,6 +33,7 @@ import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import jdk.javadoc.internal.doclets.formats.html.SearchIndexItem;
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
import jdk.javadoc.internal.doclets.toolkit.Messages;
@ -52,7 +53,7 @@ public class IndexBuilder {
* Sets of elements keyed by the first character of the names of the
* elements in those sets.
*/
private final Map<Character, SortedSet<Element>> indexMap;
private final Map<Character, SortedSet<IndexItem>> indexMap;
/**
* Don't generate deprecated information if true.
@ -66,7 +67,7 @@ public class IndexBuilder {
private final BaseConfiguration configuration;
private final Utils utils;
private final Comparator<Element> comparator;
private final Comparator<IndexItem> comparator;
/**
* Creates a new {@code IndexBuilder}.
@ -106,9 +107,7 @@ public class IndexBuilder {
this.noDeprecated = noDeprecated;
this.classesOnly = classesOnly;
this.indexMap = new TreeMap<>();
comparator = classesOnly
? utils.makeAllClassesComparator()
: utils.makeIndexUseComparator();
comparator = utils.comparators.makeIndexComparator(classesOnly);
buildIndex();
}
@ -117,7 +116,7 @@ public class IndexBuilder {
*/
private void buildIndex() {
Set<TypeElement> classes = configuration.getIncludedTypeElements();
indexElements(classes);
indexTypeElements(classes);
if (classesOnly) {
return;
}
@ -129,7 +128,7 @@ public class IndexBuilder {
.filter(_package -> _package != null && !_package.isUnnamed())
.collect(Collectors.toSet());
}
indexElements(packages);
packages.forEach(this::indexPackage);
classes.stream()
.filter(this::shouldIndex)
.forEach(this::indexMembers);
@ -147,12 +146,12 @@ public class IndexBuilder {
*/
private void indexMembers(TypeElement te) {
VisibleMemberTable vmt = configuration.getVisibleMemberTable(te);
indexElements(vmt.getMembers(FIELDS));
indexElements(vmt.getMembers(ANNOTATION_TYPE_MEMBER_OPTIONAL));
indexElements(vmt.getMembers(ANNOTATION_TYPE_MEMBER_REQUIRED));
indexElements(vmt.getMembers(METHODS));
indexElements(vmt.getMembers(CONSTRUCTORS));
indexElements(vmt.getMembers(ENUM_CONSTANTS));
indexElements(vmt.getVisibleMembers(FIELDS), te);
indexElements(vmt.getVisibleMembers(ANNOTATION_TYPE_MEMBER_OPTIONAL), te);
indexElements(vmt.getVisibleMembers(ANNOTATION_TYPE_MEMBER_REQUIRED), te);
indexElements(vmt.getVisibleMembers(METHODS), te);
indexElements(vmt.getVisibleMembers(CONSTRUCTORS), te);
indexElements(vmt.getVisibleMembers(ENUM_CONSTANTS), te);
}
/**
@ -160,15 +159,29 @@ public class IndexBuilder {
*
* @param elements a collection of elements
*/
private void indexElements(Iterable<? extends Element> elements) {
private void indexElements(Iterable<? extends Element> elements, TypeElement typeElement) {
for (Element element : elements) {
if (shouldIndex(element)) {
String name = utils.isPackage(element)
? utils.getPackageName((PackageElement) element)
: utils.getSimpleName(element);
String name = utils.getSimpleName(element);
Character ch = keyCharacter(name);
SortedSet<Element> set = indexMap.computeIfAbsent(ch, c -> new TreeSet<>(comparator));
set.add(element);
SortedSet<IndexItem> set = indexMap.computeIfAbsent(ch, c -> new TreeSet<>(comparator));
set.add(new IndexItem(element, typeElement, configuration.utils));
}
}
}
/**
* Index the given type elements.
*
* @param elements type elements
*/
private void indexTypeElements(Iterable<TypeElement> elements) {
for (TypeElement typeElement : elements) {
if (shouldIndex(typeElement)) {
String name = utils.getSimpleName(typeElement);
Character ch = keyCharacter(name);
SortedSet<IndexItem> set = indexMap.computeIfAbsent(ch, c -> new TreeSet<>(comparator));
set.add(new IndexItem(typeElement, configuration.utils));
}
}
}
@ -183,8 +196,21 @@ public class IndexBuilder {
private void indexModules() {
for (ModuleElement m : configuration.modules) {
Character ch = keyCharacter(m.getQualifiedName().toString());
SortedSet<Element> set = indexMap.computeIfAbsent(ch, c -> new TreeSet<>(comparator));
set.add(m);
SortedSet<IndexItem> set = indexMap.computeIfAbsent(ch, c -> new TreeSet<>(comparator));
set.add(new IndexItem(m, configuration.utils));
}
}
/**
* Index the given package element.
*
* @param packageElement the package element
*/
private void indexPackage(PackageElement packageElement) {
if (shouldIndex(packageElement)) {
Character ch = keyCharacter(utils.getPackageName(packageElement));
SortedSet<IndexItem> set = indexMap.computeIfAbsent(ch, c -> new TreeSet<>(comparator));
set.add(new IndexItem(packageElement, configuration.utils));
}
}
@ -215,7 +241,7 @@ public class IndexBuilder {
*
* @return map
*/
public Map<Character, SortedSet<Element>> asMap() {
public Map<Character, SortedSet<IndexItem>> asMap() {
return indexMap;
}
@ -226,8 +252,8 @@ public class IndexBuilder {
* @param key index key
* @return list of elements keyed by the provided character
*/
public List<? extends Element> getMemberList(Character key) {
SortedSet<Element> set = indexMap.get(key);
public List<IndexItem> getMemberList(Character key) {
SortedSet<IndexItem> set = indexMap.get(key);
if (set == null) {
return null;
}
@ -240,4 +266,18 @@ public class IndexBuilder {
public List<Character> keys() {
return new ArrayList<>(indexMap.keySet());
}
/**
* Add search tags for the key {@code key}.
*
* @param key the index key
* @param searchTags the search tags
*/
public void addSearchTags(char key, List<SearchIndexItem> searchTags) {
searchTags.forEach(searchTag -> {
SortedSet<IndexItem> set = indexMap.computeIfAbsent(key, c -> new TreeSet<>(comparator));
set.add(new IndexItem(searchTag));
});
}
}

View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2020, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.javadoc.internal.doclets.toolkit.util;
import jdk.javadoc.internal.doclets.formats.html.SearchIndexItem;
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
/**
* A holder for an indexed {@link Element} or {@link SearchIndexItem}.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class IndexItem {
private final Element element;
private final SearchIndexItem searchTag;
private String label;
private TypeElement typeElement;
public IndexItem(SearchIndexItem searchTag) {
this.element = null;
this.searchTag = searchTag;
this.label = searchTag.getLabel();
}
private IndexItem(Element element) {
this.element = element;
this.searchTag = null;
}
public IndexItem(TypeElement typeElement, Utils utils) {
this(typeElement);
this.label = utils.getSimpleName(typeElement);
}
public IndexItem(ModuleElement moduleElement, Utils utils) {
this(moduleElement);
this.label = utils.getFullyQualifiedName(moduleElement);
}
public IndexItem(PackageElement packageElement, Utils utils) {
this(packageElement);
this.label = utils.getPackageName(packageElement);
}
public IndexItem(Element member, TypeElement typeElement, Utils utils) {
this(member);
this.typeElement = typeElement;
String name = utils.getSimpleName(member);
if (utils.isExecutableElement(member)) {
ExecutableElement ee = (ExecutableElement)member;
name += utils.flatSignature(ee, typeElement);
}
this.label = name;
}
public String getLabel() {
return label;
}
public Element getElement() {
return element;
}
public SearchIndexItem getSearchTag() {
return searchTag;
}
public TypeElement getTypeElement() {
return typeElement;
}
}

View File

@ -114,7 +114,7 @@ public class TypeElementCatalog {
public TypeElementCatalog(BaseConfiguration config) {
this.configuration = config;
this.utils = config.utils;
comparator = utils.makeGeneralPurposeComparator();
comparator = utils.comparators.makeGeneralPurposeComparator();
allClasses = new HashMap<>();
ordinaryClasses = new HashMap<>();
exceptions = new HashMap<>();

View File

@ -37,7 +37,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Deque;
import java.util.EnumSet;
import java.util.HashMap;
@ -97,7 +96,6 @@ import com.sun.source.doctree.DocTree;
import com.sun.source.doctree.DocTree.Kind;
import com.sun.source.doctree.EndElementTree;
import com.sun.source.doctree.ParamTree;
import com.sun.source.doctree.SerialFieldTree;
import com.sun.source.doctree.StartElementTree;
import com.sun.source.doctree.TextTree;
import com.sun.source.doctree.UnknownBlockTagTree;
@ -107,11 +105,9 @@ import com.sun.source.util.DocSourcePositions;
import com.sun.source.util.DocTrees;
import com.sun.source.util.TreePath;
import com.sun.tools.javac.model.JavacTypes;
import jdk.javadoc.internal.doclets.formats.html.SearchIndexItem;
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
import jdk.javadoc.internal.doclets.toolkit.BaseOptions;
import jdk.javadoc.internal.doclets.toolkit.CommentUtils.DocCommentDuo;
import jdk.javadoc.internal.doclets.toolkit.Messages;
import jdk.javadoc.internal.doclets.toolkit.Resources;
import jdk.javadoc.internal.doclets.toolkit.WorkArounds;
import jdk.javadoc.internal.doclets.toolkit.taglets.BaseTaglet;
@ -136,22 +132,22 @@ import static jdk.javadoc.internal.doclets.toolkit.builders.ConstantsSummaryBuil
public class Utils {
public final BaseConfiguration configuration;
private final BaseOptions options;
private final Messages messages;
private final Resources resources;
public final DocTrees docTrees;
public final Elements elementUtils;
public final Types typeUtils;
public final Comparators comparators;
private final JavaScriptScanner javaScriptScanner;
public Utils(BaseConfiguration c) {
configuration = c;
options = configuration.getOptions();
messages = configuration.getMessages();
resources = configuration.getDocResources();
elementUtils = c.docEnv.getElementUtils();
typeUtils = c.docEnv.getTypeUtils();
docTrees = c.docEnv.getDocTrees();
javaScriptScanner = c.isAllowScriptInComments() ? null : new JavaScriptScanner();
comparators = new Comparators(this);
}
// our own little symbol table
@ -219,7 +215,7 @@ public class Utils {
public List<Element> excludeDeprecatedMembers(List<? extends Element> members) {
return members.stream()
.filter(member -> !isDeprecated(member))
.sorted(makeGeneralPurposeComparator())
.sorted(comparators.makeGeneralPurposeComparator())
.collect(Collectors.toCollection(ArrayList::new));
}
@ -664,39 +660,44 @@ public class Utils {
}
/**
* Get the signature. It is the parameter list, type is qualified.
* Get the signature of an executable element with qualified parameter types
* in the context of type element {@code site}.
* For instance, for a method {@code mymethod(String x, int y)},
* it will return {@code (java.lang.String,int)}.
*
* @param e
* @return String
* @param e the executable element
* @param site the contextual site
* @return String signature with qualified parameter types
*/
public String signature(ExecutableElement e) {
return makeSignature(e, true);
public String signature(ExecutableElement e, TypeElement site) {
return makeSignature(e, site, true);
}
/**
* Get flat signature. All types are not qualified.
* Return a String, which is the flat signature of this member.
* It is the parameter list, type is not qualified.
* Get the flat signature of an executable element with simple (unqualified)
* parameter types in the context of type element {@code site}.
* For instance, for a method {@code mymethod(String x, int y)},
* it will return {@code (String, int)}.
*
* @param e the executable element
* @param site the contextual site
* @return String signature with simple (unqualified) parameter types
*/
public String flatSignature(ExecutableElement e) {
return makeSignature(e, false);
public String flatSignature(ExecutableElement e, TypeElement site) {
return makeSignature(e, site, false);
}
public String makeSignature(ExecutableElement e, boolean full) {
return makeSignature(e, full, false);
public String makeSignature(ExecutableElement e, TypeElement site, boolean full) {
return makeSignature(e, site, full, false);
}
public String makeSignature(ExecutableElement e, boolean full, boolean ignoreTypeParameters) {
public String makeSignature(ExecutableElement e, TypeElement site, boolean full, boolean ignoreTypeParameters) {
StringBuilder result = new StringBuilder();
result.append("(");
Iterator<? extends VariableElement> iterator = e.getParameters().iterator();
ExecutableType executableType = asInstantiatedMethodType(site, e);
Iterator<? extends TypeMirror> iterator = executableType.getParameterTypes().iterator();
while (iterator.hasNext()) {
VariableElement next = iterator.next();
TypeMirror type = next.asType();
TypeMirror type = iterator.next();
result.append(getTypeSignature(type, full, ignoreTypeParameters));
if (iterator.hasNext()) {
result.append(", ");
@ -929,7 +930,7 @@ public class Utils {
}
public SortedSet<TypeElement> getTypeElementsAsSortedSet(Iterable<TypeElement> typeElements) {
SortedSet<TypeElement> set = new TreeSet<>(makeGeneralPurposeComparator());
SortedSet<TypeElement> set = new TreeSet<>(comparators.makeGeneralPurposeComparator());
typeElements.forEach(set::add);
return set;
}
@ -1577,7 +1578,7 @@ public class Utils {
public SortedSet<TypeElement> filterOutPrivateClasses(Iterable<TypeElement> classlist,
boolean javafx) {
SortedSet<TypeElement> filteredOutClasses =
new TreeSet<>(makeGeneralPurposeComparator());
new TreeSet<>(comparators.makeGeneralPurposeComparator());
if (!javafx) {
for (Element te : classlist) {
if (!hasHiddenTag(te)) {
@ -1644,7 +1645,7 @@ public class Utils {
private DocCollator tertiaryCollator = null;
private DocCollator secondaryCollator = null;
private int compareStrings(boolean caseSensitive, String s1, String s2) {
int compareStrings(boolean caseSensitive, String s1, String s2) {
if (caseSensitive) {
if (tertiaryCollator == null) {
tertiaryCollator = new DocCollator(configuration.locale, Collator.TERTIARY);
@ -1732,245 +1733,6 @@ public class Utils {
}
}
private Comparator<Element> moduleComparator = null;
/**
* Comparator for ModuleElements, simply compares the fully qualified names
* @return a Comparator
*/
public Comparator<Element> makeModuleComparator() {
if (moduleComparator == null) {
moduleComparator = new Utils.ElementComparator() {
@Override
public int compare(Element mod1, Element mod2) {
return compareFullyQualifiedNames(mod1, mod2);
}
};
}
return moduleComparator;
}
private Comparator<Element> allClassesComparator = null;
/**
* Returns a Comparator for all classes, compares the simple names of
* TypeElement, if equal then the fully qualified names.
*
* @return Comparator
*/
public Comparator<Element> makeAllClassesComparator() {
if (allClassesComparator == null) {
allClassesComparator = new Utils.ElementComparator() {
@Override
public int compare(Element e1, Element e2) {
int result = compareNames(e1, e2);
if (result == 0)
result = compareFullyQualifiedNames(e1, e2);
return result;
}
};
}
return allClassesComparator;
}
private Comparator<Element> packageComparator = null;
/**
* Returns a Comparator for packages, by comparing the fully qualified names.
*
* @return a Comparator
*/
public Comparator<Element> makePackageComparator() {
if (packageComparator == null) {
packageComparator = new Utils.ElementComparator() {
@Override
public int compare(Element pkg1, Element pkg2) {
return compareFullyQualifiedNames(pkg1, pkg2);
}
};
}
return packageComparator;
}
private Comparator<Element> deprecatedComparator = null;
/**
* Returns a Comparator for deprecated items listed on deprecated list page, by comparing the
* fully qualified names.
*
* @return a Comparator
*/
public Comparator<Element> makeDeprecatedComparator() {
if (deprecatedComparator == null) {
deprecatedComparator = new Utils.ElementComparator() {
@Override
public int compare(Element e1, Element e2) {
return compareFullyQualifiedNames(e1, e2);
}
};
}
return deprecatedComparator;
}
private Comparator<SerialFieldTree> serialFieldTreeComparator = null;
/**
* Returns a Comparator for SerialFieldTree.
* @return a Comparator
*/
public Comparator<SerialFieldTree> makeSerialFieldTreeComparator() {
if (serialFieldTreeComparator == null) {
serialFieldTreeComparator = (SerialFieldTree o1, SerialFieldTree o2) -> {
String s1 = o1.getName().toString();
String s2 = o2.getName().toString();
return s1.compareTo(s2);
};
}
return serialFieldTreeComparator;
}
/**
* Returns a general purpose comparator.
* @return a Comparator
*/
public Comparator<Element> makeGeneralPurposeComparator() {
return makeClassUseComparator();
}
private Comparator<Element> overrideUseComparator = null;
/**
* Returns a Comparator for overrides and implements,
* used primarily on methods, compares the name first,
* then compares the simple names of the enclosing
* TypeElement and the fully qualified name of the enclosing TypeElement.
* @return a Comparator
*/
public Comparator<Element> makeOverrideUseComparator() {
if (overrideUseComparator == null) {
overrideUseComparator = new Utils.ElementComparator() {
@Override
public int compare(Element o1, Element o2) {
int result = compareStrings(getSimpleName(o1), getSimpleName(o2));
if (result != 0) {
return result;
}
if (!isTypeElement(o1) && !isTypeElement(o2) && !isPackage(o1) && !isPackage(o2)) {
TypeElement t1 = getEnclosingTypeElement(o1);
TypeElement t2 = getEnclosingTypeElement(o2);
result = compareStrings(getSimpleName(t1), getSimpleName(t2));
if (result != 0)
return result;
}
result = compareStrings(getFullyQualifiedName(o1), getFullyQualifiedName(o2));
if (result != 0)
return result;
return compareElementKinds(o1, o2);
}
};
}
return overrideUseComparator;
}
private Comparator<Element> indexUseComparator = null;
/**
* Returns a Comparator for index file presentations, and are sorted as follows.
* If comparing modules and/or packages then simply compare the qualified names,
* if comparing a module or a package with a type/member then compare the
* FullyQualifiedName of the module or a package with the SimpleName of the entity,
* otherwise:
* 1. compare the ElementKind ex: Module, Package, Interface etc.
* 2a. if equal and if the type is of ExecutableElement(Constructor, Methods),
* a case insensitive comparison of parameter the type signatures
* 2b. if equal, case sensitive comparison of the type signatures
* 3. finally, if equal, compare the FQNs of the entities
* @return a comparator for index file use
*/
public Comparator<Element> makeIndexUseComparator() {
if (indexUseComparator == null) {
indexUseComparator = new Utils.ElementComparator() {
/**
* Compares two elements.
*
* @param e1 - an element.
* @param e2 - an element.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
@Override
public int compare(Element e1, Element e2) {
int result;
// first, compare names as appropriate
if ((isModule(e1) || isPackage(e1)) && (isModule(e2) || isPackage(e2))) {
result = compareFullyQualifiedNames(e1, e2);
} else if (isModule(e1) || isPackage(e1)) {
result = compareStrings(getFullyQualifiedName(e1), getSimpleName(e2));
} else if (isModule(e2) || isPackage(e2)) {
result = compareStrings(getSimpleName(e1), getFullyQualifiedName(e2));
} else {
result = compareNames(e1, e2);
}
if (result != 0) {
return result;
}
// if names are the same, compare element kinds
result = compareElementKinds(e1, e2);
if (result != 0) {
return result;
}
// if element kinds are the same, and are methods,
// compare the method parameters
if (hasParameters(e1)) {
List<? extends VariableElement> parameters1 = ((ExecutableElement)e1).getParameters();
List<? extends VariableElement> parameters2 = ((ExecutableElement)e2).getParameters();
result = compareParameters(false, parameters1, parameters2);
if (result != 0) {
return result;
}
result = compareParameters(true, parameters1, parameters2);
if (result != 0) {
return result;
}
}
// else fall back on fully qualified names
return compareFullyQualifiedNames(e1, e2);
}
};
}
return indexUseComparator;
}
private Comparator<TypeMirror> typeMirrorClassUseComparator = null;
/**
* Compares the FullyQualifiedNames of two TypeMirrors
* @return
*/
public Comparator<TypeMirror> makeTypeMirrorClassUseComparator() {
if (typeMirrorClassUseComparator == null) {
typeMirrorClassUseComparator = (TypeMirror type1, TypeMirror type2) -> {
String s1 = getQualifiedTypeName(type1);
String s2 = getQualifiedTypeName(type2);
return compareStrings(s1, s2);
};
}
return typeMirrorClassUseComparator;
}
private Comparator<TypeMirror> typeMirrorIndexUseComparator = null;
/**
* Compares the SimpleNames of TypeMirrors if equal then the
* FullyQualifiedNames of TypeMirrors.
*
* @return
*/
public Comparator<TypeMirror> makeTypeMirrorIndexUseComparator() {
if (typeMirrorIndexUseComparator == null) {
typeMirrorIndexUseComparator = (TypeMirror t1, TypeMirror t2) -> {
int result = compareStrings(getTypeName(t1, false), getTypeName(t2, false));
if (result != 0)
return result;
return compareStrings(getQualifiedTypeName(t1), getQualifiedTypeName(t2));
};
}
return typeMirrorIndexUseComparator;
}
/**
* Get the qualified type name of a TypeMirror compatible with the Element's
* getQualified name, returns the qualified name of the Reference type
@ -2043,252 +1805,6 @@ public class Utils {
}.visit(e);
}
private Comparator<Element> classUseComparator = null;
/**
* Comparator for ClassUse presentations, and sorts as follows:
* 1. member names
* 2. then fully qualified member names
* 3. then parameter types if applicable
* 4. finally the element kinds ie. package, class, interface etc.
* @return a comparator to sort classes and members for class use
*/
public Comparator<Element> makeClassUseComparator() {
if (classUseComparator == null) {
classUseComparator = new Utils.ElementComparator() {
/**
* Compares two Elements.
*
* @param e1 - an element.
* @param e2 - an element.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
@Override
public int compare(Element e1, Element e2) {
int result = compareNames(e1, e2);
if (result != 0) {
return result;
}
result = compareFullyQualifiedNames(e1, e2);
if (result != 0) {
return result;
}
if (hasParameters(e1) && hasParameters(e2)) {
List<? extends VariableElement> parameters1 = ((ExecutableElement)e1).getParameters();
List<? extends VariableElement> parameters2 = ((ExecutableElement)e2).getParameters();
result = compareParameters(false, parameters1, parameters2);
if (result != 0) {
return result;
}
result = compareParameters(true, parameters1, parameters2);
}
if (result != 0) {
return result;
}
return compareElementKinds(e1, e2);
}
};
}
return classUseComparator;
}
/**
* A general purpose comparator to sort Element entities, basically provides the building blocks
* for creating specific comparators for an use-case.
*/
private abstract class ElementComparator implements Comparator<Element> {
public ElementComparator() { }
/**
* compares two parameter arrays by first comparing the length of the arrays, and
* then each Type of the parameter in the array.
* @param params1 the first parameter array.
* @param params2 the first parameter array.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
protected int compareParameters(boolean caseSensitive, List<? extends VariableElement> params1,
List<? extends VariableElement> params2) {
return compareStrings(caseSensitive, getParametersAsString(params1),
getParametersAsString(params2));
}
String getParametersAsString(List<? extends VariableElement> params) {
StringBuilder sb = new StringBuilder();
for (VariableElement param : params) {
TypeMirror t = param.asType();
// prefix P for primitive and R for reference types, thus items will
// be ordered lexically and correctly.
sb.append(getTypeCode(t)).append("-").append(t).append("-");
}
return sb.toString();
}
private String getTypeCode(TypeMirror t) {
return new SimpleTypeVisitor9<String, Void>() {
@Override
public String visitPrimitive(PrimitiveType t, Void p) {
return "P";
}
@Override
public String visitArray(ArrayType t, Void p) {
return visit(t.getComponentType());
}
@Override
protected String defaultAction(TypeMirror e, Void p) {
return "R";
}
}.visit(t);
}
/**
* Compares two Elements, typically the name of a method,
* field or constructor.
* @param e1 the first Element.
* @param e2 the second Element.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
protected int compareNames(Element e1, Element e2) {
return compareStrings(getSimpleName(e1), getSimpleName(e2));
}
/**
* Compares the fully qualified names of the entities
* @param e1 the first Element.
* @param e2 the first Element.
* @return a negative integer, zero, or a positive integer as the first
* argument is less than, equal to, or greater than the second.
*/
protected int compareFullyQualifiedNames(Element e1, Element e2) {
// add simplename to be compatible
String thisElement = getFullyQualifiedName(e1);
String thatElement = getFullyQualifiedName(e2);
return compareStrings(thisElement, thatElement);
}
protected int compareElementKinds(Element e1, Element e2) {
return Integer.compare(getKindIndex(e1), getKindIndex(e2));
}
private int getKindIndex(Element e) {
switch (e.getKind()) {
case MODULE: return 0;
case PACKAGE: return 1;
case CLASS: return 2;
case ENUM: return 3;
case ENUM_CONSTANT: return 4;
case RECORD: return 5;
case INTERFACE: return 6;
case ANNOTATION_TYPE: return 7;
case FIELD: return 8;
case CONSTRUCTOR: return 9;
case METHOD: return 10;
default: throw new IllegalArgumentException(e.getKind().toString());
}
}
@SuppressWarnings("preview")
boolean hasParameters(Element e) {
return new SimpleElementVisitor14<Boolean, Void>() {
@Override
public Boolean visitExecutable(ExecutableElement e, Void p) {
return true;
}
@Override
protected Boolean defaultAction(Element e, Void p) {
return false;
}
}.visit(e);
}
/**
* The fully qualified names of the entities, used solely by the comparator.
*
* @return a negative integer, zero, or a positive integer as the first argument is less
* than, equal to, or greater than the second.
*/
@SuppressWarnings("preview")
private String getFullyQualifiedName(Element e) {
return new SimpleElementVisitor14<String, Void>() {
@Override
public String visitModule(ModuleElement e, Void p) {
return e.getQualifiedName().toString();
}
@Override
public String visitPackage(PackageElement e, Void p) {
return e.getQualifiedName().toString();
}
@Override
public String visitExecutable(ExecutableElement e, Void p) {
// For backward compatibility
return getFullyQualifiedName(e.getEnclosingElement())
+ "." + e.getSimpleName().toString();
}
@Override
public String visitType(TypeElement e, Void p) {
return e.getQualifiedName().toString();
}
@Override
protected String defaultAction(Element e, Void p) {
return getEnclosingTypeElement(e).getQualifiedName().toString()
+ "." + e.getSimpleName().toString();
}
}.visit(e);
}
}
/**
* Returns a Comparator for SearchIndexItems representing types. Items are
* compared by short name, or full string representation if names are equal.
*
* @return a Comparator
*/
public Comparator<SearchIndexItem> makeTypeSearchIndexComparator() {
return (SearchIndexItem sii1, SearchIndexItem sii2) -> {
int result = compareStrings(sii1.getSimpleName(), sii2.getSimpleName());
if (result == 0) {
// TreeSet needs this to be consistent with equal so we do
// a plain comparison of string representations as fallback.
result = sii1.toString().compareTo(sii2.toString());
}
return result;
};
}
private Comparator<SearchIndexItem> genericSearchIndexComparator = null;
/**
* Returns a Comparator for SearchIndexItems representing modules, packages, or members.
* Items are compared by label (member name plus signature for members, package name for
* packages, and module name for modules). If labels are equal then full string
* representation is compared.
*
* @return a Comparator
*/
public Comparator<SearchIndexItem> makeGenericSearchIndexComparator() {
if (genericSearchIndexComparator == null) {
genericSearchIndexComparator = (SearchIndexItem sii1, SearchIndexItem sii2) -> {
int result = compareStrings(sii1.getLabel(), sii2.getLabel());
if (result == 0) {
// TreeSet needs this to be consistent with equal so we do
// a plain comparison of string representations as fallback.
result = sii1.toString().compareTo(sii2.toString());
}
return result;
};
}
return genericSearchIndexComparator;
}
public Iterable<TypeElement> getEnclosedTypeElements(PackageElement pkg) {
List<TypeElement> out = getInterfaces(pkg);
@ -2385,7 +1901,7 @@ public class Utils {
}
public Map<ModuleElement, String> getDependentModules(ModuleElement mdle) {
Map<ModuleElement, String> result = new TreeMap<>(makeModuleComparator());
Map<ModuleElement, String> result = new TreeMap<>(comparators.makeModuleComparator());
Deque<ModuleElement> queue = new ArrayDeque<>();
// get all the requires for the element in question
for (RequiresDirective rd : ElementFilter.requiresIn(mdle.getDirectives())) {
@ -2491,7 +2007,7 @@ public class Utils {
clist.addAll(getInterfacesUnfiltered(e));
clist.addAll(getAnnotationTypesUnfiltered(e));
clist.addAll(getRecordsUnfiltered(e));
SortedSet<TypeElement> oset = new TreeSet<>(makeGeneralPurposeComparator());
SortedSet<TypeElement> oset = new TreeSet<>(comparators.makeGeneralPurposeComparator());
oset.addAll(clist);
return oset;
}
@ -2512,7 +2028,7 @@ public class Utils {
clist.addAll(getAnnotationTypes(e));
clist.addAll(getEnums(e));
clist.addAll(getRecords(e));
oset = new TreeSet<>(makeGeneralPurposeComparator());
oset = new TreeSet<>(comparators.makeGeneralPurposeComparator());
oset.addAll(clist);
cachedClasses.put(e, oset);
return oset;

View File

@ -114,8 +114,6 @@ public class VisibleMemberTable {
private List<VisibleMemberTable> allSuperinterfaces;
private List<VisibleMemberTable> parents;
private Map<Kind, List<Element>> extraMembers = new EnumMap<>(Kind.class);
private Map<Kind, List<Element>> visibleMembers = null;
private Map<ExecutableElement, PropertyMembers> propertyMap = new HashMap<>();
@ -148,11 +146,6 @@ public class VisibleMemberTable {
computeVisibleMembers();
}
List<? extends Element> getExtraMembers(Kind kind) {
ensureInitialized();
return visibleMembers.getOrDefault(kind, Collections.emptyList());
}
List<VisibleMemberTable> getAllSuperclasses() {
ensureInitialized();
return allSuperclasses;
@ -286,7 +279,7 @@ public class VisibleMemberTable {
// ... and finally the sorted super interfaces.
allSuperinterfaces.stream()
.map(vmt -> vmt.te)
.sorted(utils.makeGeneralPurposeComparator())
.sorted(utils.comparators.makeGeneralPurposeComparator())
.forEach(result::add);
return result;
@ -383,21 +376,12 @@ public class VisibleMemberTable {
LocalMemberTable lmt = new LocalMemberTable();
for (Kind k : Kind.values()) {
computeLeafMembers(lmt, k);
computeVisibleMembers(lmt, k);
}
// All members have been computed, compute properties.
computeVisibleProperties(lmt);
}
private void computeLeafMembers(LocalMemberTable lmt, Kind kind) {
List<Element> list = new ArrayList<>();
if (utils.isUndocumentedEnclosure(te)) {
list.addAll(lmt.getOrderedMembers(kind));
}
parents.forEach(pvmt -> list.addAll(pvmt.getExtraMembers(kind)));
extraMembers.put(kind, Collections.unmodifiableList(list));
}
void computeVisibleMembers(LocalMemberTable lmt, Kind kind) {
switch (kind) {
@ -457,7 +441,6 @@ public class VisibleMemberTable {
private void computeVisibleFieldsAndInnerClasses(LocalMemberTable lmt, Kind kind) {
Set<Element> result = new LinkedHashSet<>();
for (VisibleMemberTable pvmt : parents) {
result.addAll(pvmt.getExtraMembers(kind));
result.addAll(pvmt.getAllVisibleMembers(kind));
}
@ -492,32 +475,6 @@ public class VisibleMemberTable {
}
});
inheritedMethods.addAll(pvmt.getAllVisibleMembers(Kind.METHODS));
// Copy the extra members (if any) from the lineage.
if (!utils.shouldDocument(pvmt.te)) {
List<? extends Element> extraMethods = pvmt.getExtraMembers(Kind.METHODS);
if (lmt.getOrderedMembers(Kind.METHODS).isEmpty()) {
inheritedMethods.addAll(extraMethods);
continue;
}
// Check if an extra-method ought to percolate through.
for (Element extraMethod : extraMethods) {
boolean found = false;
List<Element> lmethods = lmt.getMembers(extraMethod, Kind.METHODS);
for (Element lmethod : lmethods) {
ExecutableElement method = (ExecutableElement)lmethod;
found = utils.elementUtils.overrides(method,
(ExecutableElement)extraMethod, te);
if (found)
break;
}
if (!found)
inheritedMethods.add(extraMethod);
}
}
}
// Filter out inherited methods that:
@ -536,15 +493,14 @@ public class VisibleMemberTable {
OverridingMethodInfo p = overriddenMethodTable.getOrDefault(m, null);
return p == null || !p.simpleOverride;
};
List<Element> mlist = lmt.getOrderedMembers(Kind.METHODS);
List<Element> llist = mlist.stream()
List<Element> localList = lmt.getOrderedMembers(Kind.METHODS)
.stream()
.map(m -> (ExecutableElement)m)
.filter(isVisible)
.collect(Collectors.toList());
// Merge the above lists, making sure the local methods precede
// the others
list.addAll(0, llist);
// Merge the above lists, making sure the local methods precede the others
list.addAll(0, localList);
// Final filtration of elements
list = list.stream()
@ -897,12 +853,9 @@ public class VisibleMemberTable {
private final Map<ExecutableElement, TypeMirror> interfaces = new HashMap<>();
private final List<ExecutableElement> methlist = new ArrayList<>();
private final TypeElement typeElement;
private final ExecutableElement method;
public ImplementedMethods(ExecutableElement method) {
this.method = method;
typeElement = utils.getEnclosingTypeElement(method);
TypeElement typeElement = utils.getEnclosingTypeElement(method);
Set<TypeMirror> intfacs = utils.getAllInterfaces(typeElement);
/*
* Search for the method in the list of interfaces. If found check if it is

View File

@ -24,7 +24,7 @@
/*
* @test
* @bug 4638588 4635809 6256068 6270645 8025633 8026567 8162363 8175200
* 8192850 8182765 8220217 8224052
* 8192850 8182765 8220217 8224052 8237383
* @summary Test to make sure that members are inherited properly in the Javadoc.
* Verify that inheritance labels are correct.
* @library ../../lib
@ -116,7 +116,7 @@ public class TestMemberInheritance extends JavadocTester {
+ "<th class=\"col-second\" scope=\"row\"><code><span class=\"member-name-link\">"
+ "<a href=\"#parentMethod(T)\">parentMethod</a></span>&#8203;(java.lang.String&nbsp;t)</code></th>\n"
+ "<td class=\"col-last\">\n"
+ "<div class=\"block\">Returns some value.</div>\n"
+ "<div class=\"block\">Returns some value with an inherited search tag.</div>\n"
+ "</td>\n");
checkOutput("pkg2/DocumentedNonGenericChild.html", true,
@ -129,7 +129,9 @@ public class TestMemberInheritance extends JavadocTester {
+ " "
+ "throws <span class=\"exceptions\">java.lang.IllegalArgumentException,\n"
+ "java.lang.InterruptedException,\n"
+ "java.lang.IllegalStateException</span></div>");
+ "java.lang.IllegalStateException</span></div>\n"
+ "<div class=\"block\">Returns some value with an <span id=\"inheritedsearchtag\" "
+ "class=\"search-tag-result\">inherited search tag</span>.</div>");
checkOutput("pkg2/DocumentedNonGenericChild.html", true,
"<dt>Throws:</dt>\n"
@ -140,13 +142,13 @@ public class TestMemberInheritance extends JavadocTester {
checkOutput("pkg2/DocumentedNonGenericChild.html", true,
"<td class=\"col-first\"><code>java.lang.String</code></td>\n"
+ "<th class=\"col-second\" scope=\"row\"><code><span class=\"member-name-link\">"
+ "<a href=\"#f\">f</a></span></code></th>\n"
+ "<a href=\"#parentField\">parentField</a></span></code></th>\n"
+ "<td class=\"col-last\">\n"
+ "<div class=\"block\">A field.</div>",
"<section class=\"detail\" id=\"f\">\n"
+ "<h3>f</h3>\n"
"<section class=\"detail\" id=\"parentField\">\n"
+ "<h3>parentField</h3>\n"
+ "<div class=\"member-signature\"><span class=\"modifiers\">public</span>&nbsp;"
+ "<span class=\"return-type\">java.lang.String</span>&nbsp;<span class=\"member-name\">f</span></div>\n"
+ "<span class=\"return-type\">java.lang.String</span>&nbsp;<span class=\"member-name\">parentField</span></div>\n"
+ "<div class=\"block\">A field.</div>\n"
+ "</section>");
@ -161,5 +163,68 @@ public class TestMemberInheritance extends JavadocTester {
+ "<span class=\"member-name\">method</span>&#8203;(<span class=\"parameters\">"
+ "java.lang.String&nbsp;t)</span></div>\n"
+ "</section>");
checkOutput("index-all.html", true,
"<dt><span class=\"member-name-link\"><a href=\"pkg2/DocumentedNonGenericChild.html#parentField\">"
+ "parentField</a></span> - Variable in class pkg2.<a href=\"pkg2/DocumentedNonGenericChild.html\" "
+ "title=\"class in pkg2\">DocumentedNonGenericChild</a></dt>\n"
+ "<dd>\n<div class=\"block\">A field.</div>\n"
+ "</dd>\n",
"<dt><span class=\"member-name-link\"><a href=\"pkg2/DocumentedNonGenericChild.html#parentMethod(T)\">"
+ "parentMethod(String)</a></span> - Method in class pkg2.<a "
+ "href=\"pkg2/DocumentedNonGenericChild.html\" title=\"class in pkg2\">DocumentedNonGenericChild</a></dt>\n"
+ "<dd>\n<div class=\"block\">Returns some value with an inherited search tag.</div>\n"
+ "</dd>");
checkOutput("member-search-index.js", true,
"{\"p\":\"pkg2\",\"c\":\"DocumentedNonGenericChild\",\"l\":\"parentField\"}",
"{\"p\":\"pkg2\",\"c\":\"DocumentedNonGenericChild\",\"l\":\"parentMethod(String)"
+ "\",\"u\":\"parentMethod(T)\"}");
checkOutput("tag-search-index.js", true,
"{\"l\":\"inherited search tag\",\"h\":\"pkg2.UndocumentedGenericParent.parentMethod(String)\","
+ "\"u\":\"pkg2/DocumentedNonGenericChild.html#inheritedsearchtag\"}");
}
@Test
public void testSplitIndex() {
javadoc("-d", "out-split",
"-splitindex",
"-sourcepath", testSrc,
"pkg", "diamond", "inheritDist", "pkg1", "pkg2", "pkg3");
checkExit(Exit.OK);
checkOutput("pkg2/DocumentedNonGenericChild.html", true,
"<section class=\"detail\" id=\"parentMethod(T)\">\n"
+ "<h3 id=\"parentMethod(java.lang.Object)\">parentMethod</h3>\n"
+ "<div class=\"member-signature\"><span class=\"modifiers\">protected abstract</span>"
+ "&nbsp;<span class=\"return-type\">java.lang.String</span>&nbsp;"
+ "<span class=\"member-name\">parentMethod</span>&#8203;"
+ "(<span class=\"parameters\">java.lang.String&nbsp;t)</span>\n"
+ " "
+ "throws <span class=\"exceptions\">java.lang.IllegalArgumentException,\n"
+ "java.lang.InterruptedException,\n"
+ "java.lang.IllegalStateException</span></div>\n"
+ "<div class=\"block\">Returns some value with an <span id=\"inheritedsearchtag\" "
+ "class=\"search-tag-result\">inherited search tag</span>.</div>");
checkOutput("index-files/index-9.html", true,
"<dt><span class=\"member-name-link\"><a href=\"../pkg2/DocumentedNonGenericChild.html#parentField\">"
+ "parentField</a></span> - Variable in class pkg2.<a href=\"../pkg2/DocumentedNonGenericChild.html\" "
+ "title=\"class in pkg2\">DocumentedNonGenericChild</a></dt>\n"
+ "<dd>\n<div class=\"block\">A field.</div>\n"
+ "</dd>\n",
"<dt><span class=\"member-name-link\"><a href=\"../pkg2/DocumentedNonGenericChild.html#parentMethod(T)\">"
+ "parentMethod(String)</a></span> - Method in class pkg2.<a "
+ "href=\"../pkg2/DocumentedNonGenericChild.html\" title=\"class in pkg2\">DocumentedNonGenericChild</a></dt>\n"
+ "<dd>\n<div class=\"block\">Returns some value with an inherited search tag.</div>\n"
+ "</dd>");
checkOutput("member-search-index.js", true,
"{\"p\":\"pkg2\",\"c\":\"DocumentedNonGenericChild\",\"l\":\"parentField\"}",
"{\"p\":\"pkg2\",\"c\":\"DocumentedNonGenericChild\",\"l\":\"parentMethod(String)"
+ "\",\"u\":\"parentMethod(T)\"}");
checkOutput("tag-search-index.js", true,
"{\"l\":\"inherited search tag\",\"h\":\"pkg2.UndocumentedGenericParent.parentMethod(String)\","
+ "\"u\":\"pkg2/DocumentedNonGenericChild.html#inheritedsearchtag\"}");
}
}

View File

@ -27,10 +27,10 @@ abstract class UndocumentedGenericParent<T, E extends Throwable, F extends Throw
/**
* A field.
*/
public T f;
public T parentField;
/**
* Returns some value.
* Returns some value with an {@index "inherited search tag"}.
*
* @param t a parameter
* @return some value