8303895: Simplify and clean up LinkFactory code
Reviewed-by: prappo
This commit is contained in:
parent
a00f5d24d3
commit
9f9ab02ff6
@ -72,9 +72,9 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite
|
||||
* @return the type parameters.
|
||||
*/
|
||||
protected Content getTypeParameters(ExecutableElement member) {
|
||||
HtmlLinkInfo linkInfo = new HtmlLinkInfo(configuration, LINK_TYPE_PARAMS_AND_BOUNDS, member);
|
||||
linkInfo.addLineBreaksInTypeParameters = true;
|
||||
linkInfo.showTypeParameterAnnotations = true;
|
||||
HtmlLinkInfo linkInfo = new HtmlLinkInfo(configuration, LINK_TYPE_PARAMS_AND_BOUNDS, member)
|
||||
.addLineBreaksInTypeParameters(true)
|
||||
.showTypeParameterAnnotations(true);
|
||||
return writer.getTypeParameterLinks(linkInfo);
|
||||
}
|
||||
|
||||
@ -121,9 +121,9 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite
|
||||
*/
|
||||
protected void addParam(VariableElement param, TypeMirror paramType, boolean isVarArg,
|
||||
Content target) {
|
||||
HtmlLinkInfo linkInfo = new HtmlLinkInfo(configuration, LINK_TYPE_PARAMS,
|
||||
paramType).varargs(isVarArg);
|
||||
linkInfo.showTypeParameterAnnotations = true;
|
||||
HtmlLinkInfo linkInfo = new HtmlLinkInfo(configuration, LINK_TYPE_PARAMS, paramType)
|
||||
.varargs(isVarArg)
|
||||
.showTypeParameterAnnotations(true);
|
||||
Content link = writer.getLink(linkInfo);
|
||||
target.add(link);
|
||||
if(name(param).length() > 0) {
|
||||
@ -142,8 +142,8 @@ public abstract class AbstractExecutableMemberWriter extends AbstractMemberWrite
|
||||
* @param target the content to which the information will be added.
|
||||
*/
|
||||
protected void addReceiver(ExecutableElement member, TypeMirror rcvrType, Content target) {
|
||||
var info = new HtmlLinkInfo(configuration, SHOW_TYPE_PARAMS_AND_BOUNDS, rcvrType);
|
||||
info.linkToSelf = false;
|
||||
var info = new HtmlLinkInfo(configuration, SHOW_TYPE_PARAMS_AND_BOUNDS, rcvrType)
|
||||
.linkToSelf(false);
|
||||
target.add(writer.getLink(info));
|
||||
target.add(Entity.NO_BREAK_SPACE);
|
||||
if (member.getKind() == ElementKind.CONSTRUCTOR) {
|
||||
|
@ -115,9 +115,8 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
|
||||
div.add(pkgNameDiv);
|
||||
}
|
||||
HtmlLinkInfo linkInfo = new HtmlLinkInfo(configuration,
|
||||
HtmlLinkInfo.Kind.SHOW_TYPE_PARAMS_AND_BOUNDS, typeElement);
|
||||
//Let's not link to ourselves in the header.
|
||||
linkInfo.linkToSelf = false;
|
||||
HtmlLinkInfo.Kind.SHOW_TYPE_PARAMS_AND_BOUNDS, typeElement)
|
||||
.linkToSelf(false); // Let's not link to ourselves in the header
|
||||
var heading = HtmlTree.HEADING_TITLE(Headings.PAGE_TITLE_HEADING,
|
||||
HtmlStyle.title, Text.of(header));
|
||||
heading.add(getTypeParameterLinks(linkInfo));
|
||||
|
@ -1787,7 +1787,7 @@ public class HtmlDocletWriter {
|
||||
ContentBuilder annotation,
|
||||
Map<? extends ExecutableElement, ? extends AnnotationValue> map,
|
||||
boolean linkBreak) {
|
||||
linkInfo.label = Text.of("@" + annotationDoc.getSimpleName());
|
||||
linkInfo.label("@" + annotationDoc.getSimpleName());
|
||||
annotation.add(getLink(linkInfo));
|
||||
if (!map.isEmpty()) {
|
||||
annotation.add("(");
|
||||
@ -1903,7 +1903,7 @@ public class HtmlDocletWriter {
|
||||
String name = utils.isIncluded(t.asElement())
|
||||
? t.asElement().getSimpleName().toString()
|
||||
: utils.getFullyQualifiedName(t.asElement());
|
||||
linkInfo.label = Text.of(name + utils.getDimension(t) + ".class");
|
||||
linkInfo.label(name + utils.getDimension(t) + ".class");
|
||||
return getLink(linkInfo);
|
||||
}
|
||||
@Override
|
||||
|
@ -33,8 +33,13 @@ import java.util.Set;
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.TypeParameterElement;
|
||||
import javax.lang.model.type.ArrayType;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.type.TypeVariable;
|
||||
import javax.lang.model.type.WildcardType;
|
||||
import javax.lang.model.util.SimpleTypeVisitor14;
|
||||
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree;
|
||||
@ -45,59 +50,200 @@ import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Resources;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.Utils;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.Utils.ElementFlag;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.links.LinkFactory;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.links.LinkInfo;
|
||||
|
||||
/**
|
||||
* A factory that returns a link given the information about it.
|
||||
*/
|
||||
public class HtmlLinkFactory extends LinkFactory {
|
||||
public class HtmlLinkFactory {
|
||||
|
||||
private final HtmlDocletWriter m_writer;
|
||||
private final DocPaths docPaths;
|
||||
private final Utils utils;
|
||||
|
||||
/**
|
||||
* Constructs a new link factory.
|
||||
*
|
||||
* @param writer the HTML doclet writer
|
||||
*/
|
||||
public HtmlLinkFactory(HtmlDocletWriter writer) {
|
||||
super(writer.configuration.utils);
|
||||
m_writer = writer;
|
||||
docPaths = writer.configuration.docPaths;
|
||||
utils = writer.configuration.utils;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* {@return a new instance of a content object}
|
||||
*/
|
||||
protected Content newContent() {
|
||||
return new ContentBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Content getClassLink(LinkInfo linkInfo) {
|
||||
/**
|
||||
* Constructs a link from the given link information.
|
||||
*
|
||||
* @param linkInfo the information about the link.
|
||||
* @return the link.
|
||||
*/
|
||||
public Content getLink(HtmlLinkInfo linkInfo) {
|
||||
if (linkInfo.getType() != null) {
|
||||
SimpleTypeVisitor14<Content, HtmlLinkInfo> linkVisitor = new SimpleTypeVisitor14<>() {
|
||||
|
||||
final Content link = newContent();
|
||||
|
||||
// handles primitives, no types and error types
|
||||
@Override
|
||||
protected Content defaultAction(TypeMirror type, HtmlLinkInfo linkInfo) {
|
||||
link.add(utils.getTypeName(type, false));
|
||||
return link;
|
||||
}
|
||||
|
||||
int currentDepth = 0;
|
||||
@Override
|
||||
public Content visitArray(ArrayType type, HtmlLinkInfo linkInfo) {
|
||||
// keep track of the dimension depth and replace the last dimension
|
||||
// specifier with varargs, when the stack is fully unwound.
|
||||
currentDepth++;
|
||||
var componentType = type.getComponentType();
|
||||
visit(componentType, linkInfo.forType(componentType));
|
||||
currentDepth--;
|
||||
if (utils.isAnnotated(type)) {
|
||||
link.add(" ");
|
||||
link.add(getTypeAnnotationLinks(linkInfo));
|
||||
}
|
||||
// use vararg if required
|
||||
if (linkInfo.isVarArg() && currentDepth == 0) {
|
||||
link.add("...");
|
||||
} else {
|
||||
link.add("[]");
|
||||
}
|
||||
return link;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Content visitWildcard(WildcardType type, HtmlLinkInfo linkInfo) {
|
||||
link.add(getTypeAnnotationLinks(linkInfo));
|
||||
link.add("?");
|
||||
TypeMirror extendsBound = type.getExtendsBound();
|
||||
if (extendsBound != null) {
|
||||
link.add(" extends ");
|
||||
link.add(getLink(getBoundsLinkInfo(linkInfo, extendsBound)));
|
||||
}
|
||||
TypeMirror superBound = type.getSuperBound();
|
||||
if (superBound != null) {
|
||||
link.add(" super ");
|
||||
link.add(getLink(getBoundsLinkInfo(linkInfo, superBound)));
|
||||
}
|
||||
return link;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Content visitTypeVariable(TypeVariable type, HtmlLinkInfo linkInfo) {
|
||||
link.add(getTypeAnnotationLinks(linkInfo));
|
||||
TypeVariable typevariable = (utils.isArrayType(type))
|
||||
? (TypeVariable) utils.getComponentType(type)
|
||||
: type;
|
||||
Element owner = typevariable.asElement().getEnclosingElement();
|
||||
if (linkInfo.linkTypeParameters() && utils.isTypeElement(owner)) {
|
||||
linkInfo.setTypeElement((TypeElement) owner);
|
||||
Content label = newContent();
|
||||
label.add(utils.getTypeName(type, false));
|
||||
linkInfo.label(label).skipPreview(true);
|
||||
link.add(getClassLink(linkInfo));
|
||||
} else {
|
||||
// No need to link method type parameters.
|
||||
link.add(utils.getTypeName(typevariable, false));
|
||||
}
|
||||
|
||||
if (linkInfo.showTypeBounds()) {
|
||||
linkInfo.showTypeBounds(false);
|
||||
TypeParameterElement tpe = ((TypeParameterElement) typevariable.asElement());
|
||||
boolean more = false;
|
||||
List<? extends TypeMirror> bounds = utils.getBounds(tpe);
|
||||
for (TypeMirror bound : bounds) {
|
||||
// we get everything as extends java.lang.Object we suppress
|
||||
// all of them except those that have multiple extends
|
||||
if (bounds.size() == 1 &&
|
||||
utils.typeUtils.isSameType(bound, utils.getObjectType()) &&
|
||||
!utils.isAnnotated(bound)) {
|
||||
continue;
|
||||
}
|
||||
link.add(more ? " & " : " extends ");
|
||||
link.add(getLink(getBoundsLinkInfo(linkInfo, bound)));
|
||||
more = true;
|
||||
}
|
||||
}
|
||||
return link;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Content visitDeclared(DeclaredType type, HtmlLinkInfo linkInfo) {
|
||||
TypeMirror enc = type.getEnclosingType();
|
||||
if (enc instanceof DeclaredType dt && utils.isGenericType(dt)) {
|
||||
// If an enclosing type has type parameters render them as separate links as
|
||||
// otherwise this information is lost. On the other hand, plain enclosing types
|
||||
// are not linked separately as they are easy to reach from the nested type.
|
||||
visitDeclared(dt, linkInfo.forType(dt));
|
||||
link.add(".");
|
||||
}
|
||||
link.add(getTypeAnnotationLinks(linkInfo));
|
||||
linkInfo.setTypeElement(utils.asTypeElement(type));
|
||||
link.add(getClassLink(linkInfo));
|
||||
if (linkInfo.showTypeParameters()) {
|
||||
link.add(getTypeParameterLinks(linkInfo));
|
||||
}
|
||||
return link;
|
||||
}
|
||||
};
|
||||
return linkVisitor.visit(linkInfo.getType(), linkInfo);
|
||||
} else if (linkInfo.getTypeElement() != null) {
|
||||
Content link = newContent();
|
||||
link.add(getClassLink(linkInfo));
|
||||
if (linkInfo.showTypeParameters()) {
|
||||
link.add(getTypeParameterLinks(linkInfo));
|
||||
}
|
||||
return link;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a link to the given class.
|
||||
*
|
||||
* @param linkInfo the information about the link to construct
|
||||
* @return the link for the given class.
|
||||
*/
|
||||
protected Content getClassLink(HtmlLinkInfo linkInfo) {
|
||||
BaseConfiguration configuration = m_writer.configuration;
|
||||
HtmlLinkInfo classLinkInfo = (HtmlLinkInfo) linkInfo;
|
||||
TypeElement typeElement = classLinkInfo.typeElement;
|
||||
TypeElement typeElement = linkInfo.getTypeElement();
|
||||
// Create a tool tip if we are linking to a class or interface. Don't
|
||||
// create one if we are linking to a member.
|
||||
String title = "";
|
||||
boolean hasWhere = classLinkInfo.fragment != null && classLinkInfo.fragment.length() != 0;
|
||||
if (!hasWhere) {
|
||||
boolean isTypeLink = classLinkInfo.type != null &&
|
||||
utils.isTypeVariable(utils.getComponentType(classLinkInfo.type));
|
||||
String fragment = linkInfo.getFragment();
|
||||
boolean hasFragment = fragment != null && !fragment.isEmpty();
|
||||
if (!hasFragment) {
|
||||
boolean isTypeLink = linkInfo.getType() != null &&
|
||||
utils.isTypeVariable(utils.getComponentType(linkInfo.getType()));
|
||||
title = getClassToolTip(typeElement, isTypeLink);
|
||||
}
|
||||
Content label = classLinkInfo.getClassLinkLabel(configuration);
|
||||
if (classLinkInfo.context == HtmlLinkInfo.Kind.SHOW_TYPE_PARAMS_IN_LABEL) {
|
||||
Content label = linkInfo.getClassLinkLabel(configuration);
|
||||
if (linkInfo.getContext() == HtmlLinkInfo.Kind.SHOW_TYPE_PARAMS_IN_LABEL) {
|
||||
// For this kind of link, type parameters are included in the link label
|
||||
// (and obviously not added after the link).
|
||||
label.add(getTypeParameterLinks(classLinkInfo));
|
||||
label.add(getTypeParameterLinks(linkInfo));
|
||||
}
|
||||
Set<ElementFlag> flags;
|
||||
Element previewTarget;
|
||||
boolean showPreview = !classLinkInfo.skipPreview;
|
||||
if (!hasWhere && showPreview) {
|
||||
boolean showPreview = !linkInfo.isSkipPreview();
|
||||
if (!hasFragment && showPreview) {
|
||||
flags = utils.elementFlags(typeElement);
|
||||
previewTarget = typeElement;
|
||||
} else if (classLinkInfo.context == HtmlLinkInfo.Kind.SHOW_PREVIEW
|
||||
&& classLinkInfo.targetMember != null && showPreview) {
|
||||
flags = utils.elementFlags(classLinkInfo.targetMember);
|
||||
TypeElement enclosing = utils.getEnclosingTypeElement(classLinkInfo.targetMember);
|
||||
} else if (linkInfo.getContext() == HtmlLinkInfo.Kind.SHOW_PREVIEW
|
||||
&& linkInfo.getTargetMember() != null && showPreview) {
|
||||
flags = utils.elementFlags(linkInfo.getTargetMember());
|
||||
TypeElement enclosing = utils.getEnclosingTypeElement(linkInfo.getTargetMember());
|
||||
Set<ElementFlag> enclosingFlags = utils.elementFlags(enclosing);
|
||||
if (flags.contains(ElementFlag.PREVIEW) && enclosingFlags.contains(ElementFlag.PREVIEW)) {
|
||||
if (enclosing.equals(m_writer.getCurrentPageElement())) {
|
||||
@ -107,7 +253,7 @@ public class HtmlLinkFactory extends LinkFactory {
|
||||
}
|
||||
previewTarget = enclosing;
|
||||
} else {
|
||||
previewTarget = classLinkInfo.targetMember;
|
||||
previewTarget = linkInfo.getTargetMember();
|
||||
}
|
||||
} else {
|
||||
flags = EnumSet.noneOf(ElementFlag.class);
|
||||
@ -117,12 +263,12 @@ public class HtmlLinkFactory extends LinkFactory {
|
||||
Content link = new ContentBuilder();
|
||||
if (utils.isIncluded(typeElement)) {
|
||||
if (configuration.isGeneratedDoc(typeElement) && !utils.hasHiddenTag(typeElement)) {
|
||||
DocPath filename = getPath(classLinkInfo);
|
||||
if (linkInfo.linkToSelf || typeElement != m_writer.getCurrentPageElement()) {
|
||||
DocPath filename = getPath(linkInfo);
|
||||
if (linkInfo.linkToSelf() || typeElement != m_writer.getCurrentPageElement()) {
|
||||
link.add(m_writer.links.createLink(
|
||||
filename.fragment(classLinkInfo.fragment),
|
||||
filename.fragment(linkInfo.getFragment()),
|
||||
label,
|
||||
classLinkInfo.style,
|
||||
linkInfo.getStyle(),
|
||||
title));
|
||||
if (flags.contains(ElementFlag.PREVIEW)) {
|
||||
link.add(HtmlTree.SUP(m_writer.links.createLink(
|
||||
@ -134,8 +280,8 @@ public class HtmlLinkFactory extends LinkFactory {
|
||||
}
|
||||
} else {
|
||||
Content crossLink = m_writer.getCrossClassLink(
|
||||
typeElement, classLinkInfo.fragment,
|
||||
label, classLinkInfo.style, true);
|
||||
typeElement, linkInfo.getFragment(),
|
||||
label, linkInfo.getStyle(), true);
|
||||
if (crossLink != null) {
|
||||
link.add(crossLink);
|
||||
if (flags.contains(ElementFlag.PREVIEW)) {
|
||||
@ -156,21 +302,26 @@ public class HtmlLinkFactory extends LinkFactory {
|
||||
return link;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Content getTypeParameterLinks(LinkInfo linkInfo) {
|
||||
/**
|
||||
* Returns links to the type parameters.
|
||||
*
|
||||
* @param linkInfo the information about the link to construct
|
||||
* @return the links to the type parameters
|
||||
*/
|
||||
protected Content getTypeParameterLinks(HtmlLinkInfo linkInfo) {
|
||||
Content links = newContent();
|
||||
List<TypeMirror> vars = new ArrayList<>();
|
||||
TypeMirror ctype = linkInfo.type != null
|
||||
? utils.getComponentType(linkInfo.type)
|
||||
TypeMirror ctype = linkInfo.getType() != null
|
||||
? utils.getComponentType(linkInfo.getType())
|
||||
: null;
|
||||
if (linkInfo.executableElement != null) {
|
||||
linkInfo.executableElement.getTypeParameters().forEach(t -> vars.add(t.asType()));
|
||||
} else if (linkInfo.type != null && utils.isDeclaredType(linkInfo.type)) {
|
||||
vars.addAll(((DeclaredType) linkInfo.type).getTypeArguments());
|
||||
if (linkInfo.getExecutableElement() != null) {
|
||||
linkInfo.getExecutableElement().getTypeParameters().forEach(t -> vars.add(t.asType()));
|
||||
} else if (linkInfo.getType() != null && utils.isDeclaredType(linkInfo.getType())) {
|
||||
vars.addAll(((DeclaredType) linkInfo.getType()).getTypeArguments());
|
||||
} else if (ctype != null && utils.isDeclaredType(ctype)) {
|
||||
vars.addAll(((DeclaredType) ctype).getTypeArguments());
|
||||
} else if (ctype == null && linkInfo.typeElement != null) {
|
||||
linkInfo.typeElement.getTypeParameters().forEach(t -> vars.add(t.asType()));
|
||||
} else if (ctype == null && linkInfo.getTypeElement() != null) {
|
||||
linkInfo.getTypeElement().getTypeParameters().forEach(t -> vars.add(t.asType()));
|
||||
} else {
|
||||
// Nothing to document.
|
||||
return links;
|
||||
@ -182,11 +333,11 @@ public class HtmlLinkFactory extends LinkFactory {
|
||||
if (many) {
|
||||
links.add(",");
|
||||
links.add(new HtmlTree(TagName.WBR));
|
||||
if (linkInfo.addLineBreaksInTypeParameters) {
|
||||
if (linkInfo.addLineBreaksInTypeParameters()) {
|
||||
links.add(Text.NL);
|
||||
}
|
||||
}
|
||||
links.add(getTypeParameterLink(linkInfo, t));
|
||||
links.add(getLink(linkInfo.forType(t)));
|
||||
many = true;
|
||||
}
|
||||
links.add(">");
|
||||
@ -195,31 +346,18 @@ public class HtmlLinkFactory extends LinkFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a link to the given type parameter.
|
||||
* Returns links to the type annotations.
|
||||
*
|
||||
* @param linkInfo the information about the link to construct
|
||||
* @param typeParam the type parameter to link to
|
||||
* @return the link
|
||||
* @param linkInfo the information about the link to construct
|
||||
* @return the links to the type annotations
|
||||
*/
|
||||
protected Content getTypeParameterLink(LinkInfo linkInfo, TypeMirror typeParam) {
|
||||
HtmlLinkInfo typeLinkInfo = new HtmlLinkInfo(m_writer.configuration,
|
||||
((HtmlLinkInfo) linkInfo).getContext(), typeParam);
|
||||
typeLinkInfo.showTypeBounds = linkInfo.showTypeBounds;
|
||||
typeLinkInfo.linkTypeParameters = linkInfo.linkTypeParameters;
|
||||
typeLinkInfo.linkToSelf = linkInfo.linkToSelf;
|
||||
typeLinkInfo.addLineBreaksInTypeParameters = linkInfo.addLineBreaksInTypeParameters;
|
||||
typeLinkInfo.showTypeParameterAnnotations = linkInfo.showTypeParameterAnnotations;
|
||||
return getLink(typeLinkInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Content getTypeAnnotationLinks(LinkInfo linkInfo) {
|
||||
public Content getTypeAnnotationLinks(HtmlLinkInfo linkInfo) {
|
||||
ContentBuilder links = new ContentBuilder();
|
||||
List<? extends AnnotationMirror> annotations;
|
||||
if (utils.isAnnotated(linkInfo.type)) {
|
||||
annotations = linkInfo.type.getAnnotationMirrors();
|
||||
} else if (utils.isTypeVariable(linkInfo.type) && linkInfo.showTypeParameterAnnotations) {
|
||||
Element element = utils.typeUtils.asElement(linkInfo.type);
|
||||
if (utils.isAnnotated(linkInfo.getType())) {
|
||||
annotations = linkInfo.getType().getAnnotationMirrors();
|
||||
} else if (utils.isTypeVariable(linkInfo.getType()) && linkInfo.showTypeParameterAnnotations()) {
|
||||
Element element = utils.typeUtils.asElement(linkInfo.getType());
|
||||
annotations = element.getAnnotationMirrors();
|
||||
} else {
|
||||
return links;
|
||||
@ -237,6 +375,13 @@ public class HtmlLinkFactory extends LinkFactory {
|
||||
return links;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a link info for a type bounds link.
|
||||
*/
|
||||
private HtmlLinkInfo getBoundsLinkInfo(HtmlLinkInfo linkInfo, TypeMirror bound) {
|
||||
return linkInfo.forType(bound).skipPreview(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a class, return the appropriate tool tip.
|
||||
*
|
||||
@ -272,6 +417,6 @@ public class HtmlLinkFactory extends LinkFactory {
|
||||
* @param linkInfo the information about the link.
|
||||
*/
|
||||
private DocPath getPath(HtmlLinkInfo linkInfo) {
|
||||
return m_writer.pathToRoot.resolve(docPaths.forClass(linkInfo.typeElement));
|
||||
return m_writer.pathToRoot.resolve(docPaths.forClass(linkInfo.getTypeElement()));
|
||||
}
|
||||
}
|
||||
|
@ -28,20 +28,21 @@ package jdk.javadoc.internal.doclets.formats.html;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Text;
|
||||
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.Utils;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.links.LinkInfo;
|
||||
|
||||
|
||||
/**
|
||||
* HTML-specific information about a link.
|
||||
*/
|
||||
public class HtmlLinkInfo extends LinkInfo {
|
||||
public class HtmlLinkInfo {
|
||||
|
||||
/**
|
||||
* Enumeration of different kinds of links.
|
||||
@ -79,29 +80,53 @@ public class HtmlLinkInfo extends LinkInfo {
|
||||
LINK_TYPE_PARAMS_AND_BOUNDS;
|
||||
}
|
||||
|
||||
public final HtmlConfiguration configuration;
|
||||
private final HtmlConfiguration configuration;
|
||||
|
||||
/**
|
||||
* The context of the link.
|
||||
*/
|
||||
public Kind context = Kind.PLAIN;
|
||||
// The context of the link.
|
||||
private Kind context = Kind.PLAIN;
|
||||
|
||||
/**
|
||||
* The fragment of the link.
|
||||
*/
|
||||
public String fragment = "";
|
||||
// The fragment of the link.
|
||||
private String fragment = "";
|
||||
|
||||
/**
|
||||
* The member this link points to (if any).
|
||||
*/
|
||||
public Element targetMember;
|
||||
// The member this link points to (if any).
|
||||
private Element targetMember;
|
||||
|
||||
/**
|
||||
* Optional style for the link.
|
||||
*/
|
||||
public HtmlStyle style = null;
|
||||
// Optional style for the link.
|
||||
private HtmlStyle style = null;
|
||||
|
||||
public final Utils utils;
|
||||
// The class we want to link to. Null if we are not linking to a class.
|
||||
private TypeElement typeElement;
|
||||
|
||||
// The executable element we want to link to. Null if we are not linking to an executable element.
|
||||
private ExecutableElement executableElement;
|
||||
|
||||
// The Type we want to link to. Null if we are not linking to a type.
|
||||
private TypeMirror type;
|
||||
|
||||
// True if this is a link to a VarArg.
|
||||
private boolean isVarArg = false;
|
||||
|
||||
// The label for the link.
|
||||
private Content label;
|
||||
|
||||
// True if we should print the type bounds for the type parameter.
|
||||
private boolean showTypeBounds = true;
|
||||
|
||||
// True if type parameters should be rendered as links.
|
||||
private boolean linkTypeParameters = true;
|
||||
|
||||
// By default, the link can be to the page it's already on. However,
|
||||
// there are cases where we don't want this (e.g. heading of class page).
|
||||
private boolean linkToSelf = true;
|
||||
|
||||
// True iff the preview flags should be skipped for this link.
|
||||
private boolean skipPreview;
|
||||
|
||||
// True if type parameters should be separated by line breaks.
|
||||
private boolean addLineBreaksInTypeParameters = false;
|
||||
|
||||
// True if annotations on type parameters should be shown.
|
||||
private boolean showTypeParameterAnnotations = false;
|
||||
|
||||
/**
|
||||
* Construct a LinkInfo object.
|
||||
@ -112,16 +137,10 @@ public class HtmlLinkInfo extends LinkInfo {
|
||||
*/
|
||||
public HtmlLinkInfo(HtmlConfiguration configuration, Kind context, ExecutableElement ee) {
|
||||
this.configuration = configuration;
|
||||
this.utils = configuration.utils;
|
||||
this.executableElement = ee;
|
||||
setContext(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Content newContent() {
|
||||
return new ContentBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a LinkInfo object.
|
||||
*
|
||||
@ -131,7 +150,6 @@ public class HtmlLinkInfo extends LinkInfo {
|
||||
*/
|
||||
public HtmlLinkInfo(HtmlConfiguration configuration, Kind context, TypeElement typeElement) {
|
||||
this.configuration = configuration;
|
||||
this.utils = configuration.utils;
|
||||
this.typeElement = typeElement;
|
||||
setContext(context);
|
||||
}
|
||||
@ -145,14 +163,63 @@ public class HtmlLinkInfo extends LinkInfo {
|
||||
*/
|
||||
public HtmlLinkInfo(HtmlConfiguration configuration, Kind context, TypeMirror type) {
|
||||
this.configuration = configuration;
|
||||
this.utils = configuration.utils;
|
||||
this.type = type;
|
||||
setContext(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a copy of this HtmlLinkInfo instance with a different TypeMirror.
|
||||
* This is used for contained types such as type parameters or array components.
|
||||
*
|
||||
* @param type the type mirror
|
||||
* @return the new link info
|
||||
*/
|
||||
public HtmlLinkInfo forType(TypeMirror type) {
|
||||
HtmlLinkInfo linkInfo = new HtmlLinkInfo(configuration, context, type);
|
||||
linkInfo.showTypeBounds = showTypeBounds;
|
||||
linkInfo.linkTypeParameters = linkTypeParameters;
|
||||
linkInfo.linkToSelf = linkToSelf;
|
||||
linkInfo.addLineBreaksInTypeParameters = addLineBreaksInTypeParameters;
|
||||
linkInfo.showTypeParameterAnnotations = showTypeParameterAnnotations;
|
||||
linkInfo.skipPreview = skipPreview;
|
||||
return linkInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the typeElement
|
||||
* @param typeElement the new typeElement object
|
||||
*/
|
||||
public void setTypeElement(TypeElement typeElement) {
|
||||
this.typeElement = typeElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* The class we want to link to. Null if we are not linking
|
||||
* to a class.
|
||||
*/
|
||||
public TypeElement getTypeElement() {
|
||||
return typeElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* The executable element we want to link to. Null if we are not linking
|
||||
* to an executable element.
|
||||
*/
|
||||
public ExecutableElement getExecutableElement() {
|
||||
return executableElement;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Type we want to link to. Null if we are not linking to a type.
|
||||
*/
|
||||
public TypeMirror getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the label for the link.
|
||||
* @param label plain-text label for the link
|
||||
* @return this object
|
||||
*/
|
||||
public HtmlLinkInfo label(CharSequence label) {
|
||||
this.label = Text.of(label);
|
||||
@ -161,52 +228,182 @@ public class HtmlLinkInfo extends LinkInfo {
|
||||
|
||||
/**
|
||||
* Set the label for the link.
|
||||
* @param label the new value
|
||||
* @return this object
|
||||
*/
|
||||
public HtmlLinkInfo label(Content label) {
|
||||
this.label = label;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the label for the link}
|
||||
*/
|
||||
public Content getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the style to be used for the link.
|
||||
* @param style the new style value
|
||||
* @return this object
|
||||
*/
|
||||
public HtmlLinkInfo style(HtmlStyle style) {
|
||||
this.style = style;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the optional style for the link}
|
||||
*/
|
||||
public HtmlStyle getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether or not this is a link to a varargs parameter.
|
||||
* @param varargs the new value
|
||||
* @return this object
|
||||
*/
|
||||
public HtmlLinkInfo varargs(boolean varargs) {
|
||||
this.isVarArg = varargs;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return true if this is a link to a vararg member}
|
||||
*/
|
||||
public boolean isVarArg() {
|
||||
return isVarArg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fragment specifier for the link.
|
||||
* @param fragment the new fragment value
|
||||
* @return this object
|
||||
*/
|
||||
public HtmlLinkInfo fragment(String fragment) {
|
||||
this.fragment = fragment;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the fragment of the link}
|
||||
*/
|
||||
public String getFragment() {
|
||||
return fragment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the addLineBreaksInTypeParameters flag for this link.
|
||||
* @param addLineBreaksInTypeParameters the new value
|
||||
* @return this object
|
||||
*/
|
||||
public HtmlLinkInfo addLineBreaksInTypeParameters(boolean addLineBreaksInTypeParameters) {
|
||||
this.addLineBreaksInTypeParameters = addLineBreaksInTypeParameters;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return true if type parameters should be separated by line breaks}
|
||||
*/
|
||||
public boolean addLineBreaksInTypeParameters() {
|
||||
return addLineBreaksInTypeParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the linkToSelf flag for this link.
|
||||
* @param linkToSelf the new value
|
||||
* @return this object
|
||||
*/
|
||||
public HtmlLinkInfo linkToSelf(boolean linkToSelf) {
|
||||
this.linkToSelf = linkToSelf;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return true if we should generate links to the current page}
|
||||
*/
|
||||
public boolean linkToSelf() {
|
||||
return linkToSelf;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return true if type parameters should be rendered as links}
|
||||
*/
|
||||
public boolean linkTypeParameters() {
|
||||
return linkTypeParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the showTypeBounds flag for this link
|
||||
* @param showTypeBounds the new value
|
||||
*/
|
||||
public void showTypeBounds(boolean showTypeBounds) {
|
||||
this.showTypeBounds = showTypeBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return true if we should print the type bounds for the type parameter}
|
||||
*/
|
||||
public boolean showTypeBounds() {
|
||||
return showTypeBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the showTypeParameterAnnotations flag for this link.
|
||||
* @param showTypeParameterAnnotations the new value
|
||||
* @return this object
|
||||
*/
|
||||
public HtmlLinkInfo showTypeParameterAnnotations(boolean showTypeParameterAnnotations) {
|
||||
this.showTypeParameterAnnotations = showTypeParameterAnnotations;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return true if annotations on type parameters should be shown}
|
||||
*/
|
||||
public boolean showTypeParameterAnnotations() {
|
||||
return showTypeParameterAnnotations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the member this link points to (if any).
|
||||
* @param el the new member value
|
||||
* @return this object
|
||||
*/
|
||||
public HtmlLinkInfo targetMember(Element el) {
|
||||
this.targetMember = el;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the member this link points to (if any)}
|
||||
*/
|
||||
public Element getTargetMember() {
|
||||
return targetMember;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether or not the preview flags should be skipped for this link.
|
||||
* @param skipPreview the new value
|
||||
* @return this object
|
||||
*/
|
||||
public HtmlLinkInfo skipPreview(boolean skipPreview) {
|
||||
this.skipPreview = skipPreview;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return true iff the preview flags should be skipped for this link}
|
||||
*/
|
||||
public boolean isSkipPreview() {
|
||||
return skipPreview;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the link context}
|
||||
*/
|
||||
public Kind getContext() {
|
||||
return context;
|
||||
}
|
||||
@ -217,7 +414,7 @@ public class HtmlLinkInfo extends LinkInfo {
|
||||
*
|
||||
* @param c the context id to set.
|
||||
*/
|
||||
public final void setContext(Kind c) {
|
||||
private void setContext(Kind c) {
|
||||
linkTypeParameters = c == Kind.LINK_TYPE_PARAMS || c == Kind.LINK_TYPE_PARAMS_AND_BOUNDS;
|
||||
showTypeBounds = c == Kind.SHOW_TYPE_PARAMS_AND_BOUNDS || c == Kind.LINK_TYPE_PARAMS_AND_BOUNDS;
|
||||
context = c;
|
||||
@ -230,12 +427,15 @@ public class HtmlLinkInfo extends LinkInfo {
|
||||
* @return true if this link is linkable and false if we can't link to the
|
||||
* desired place.
|
||||
*/
|
||||
@Override
|
||||
public boolean isLinkable() {
|
||||
return configuration.utils.isLinkable(typeElement);
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Returns true if links to declared types should include type parameters.
|
||||
*
|
||||
* @return true if type parameter links should be included
|
||||
*/
|
||||
public boolean showTypeParameters() {
|
||||
// Type parameters for these kinds of links are either not desired
|
||||
// or already included in the link label.
|
||||
@ -243,12 +443,52 @@ public class HtmlLinkInfo extends LinkInfo {
|
||||
&& context != Kind.SHOW_TYPE_PARAMS_IN_LABEL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the label for this class link.
|
||||
*
|
||||
* @param configuration the current configuration of the doclet.
|
||||
* @return the label for this class link.
|
||||
*/
|
||||
public Content getClassLinkLabel(BaseConfiguration configuration) {
|
||||
if (label != null && !label.isEmpty()) {
|
||||
return label;
|
||||
} else if (isLinkable()) {
|
||||
Content tlabel = newContent();
|
||||
Utils utils = configuration.utils;
|
||||
tlabel.add(type instanceof DeclaredType dt && utils.isGenericType(dt.getEnclosingType())
|
||||
// If enclosing type is rendered as separate links only use own class name
|
||||
? typeElement.getSimpleName().toString()
|
||||
: configuration.utils.getSimpleName(typeElement));
|
||||
return tlabel;
|
||||
} else {
|
||||
Content tlabel = newContent();
|
||||
tlabel.add(configuration.getClassName(typeElement));
|
||||
return tlabel;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a new instance of a content object}
|
||||
*/
|
||||
protected Content newContent() {
|
||||
return new ContentBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "HtmlLinkInfo{" +
|
||||
"context=" + context +
|
||||
"typeElement=" + typeElement +
|
||||
", executableElement=" + executableElement +
|
||||
", type=" + type +
|
||||
", isVarArg=" + isVarArg +
|
||||
", label=" + label +
|
||||
", showTypeBounds=" + showTypeBounds +
|
||||
", linkTypeParameters=" + linkTypeParameters +
|
||||
", linkToSelf=" + linkToSelf +
|
||||
", addLineBreaksInTypeParameters=" + addLineBreaksInTypeParameters +
|
||||
", showTypeParameterAnnotations=" + showTypeParameterAnnotations +
|
||||
", context=" + context +
|
||||
", fragment=" + fragment +
|
||||
", style=" + style +
|
||||
super.toString() + '}';
|
||||
", style=" + style + '}';
|
||||
}
|
||||
}
|
||||
|
@ -135,10 +135,9 @@ public class Signatures {
|
||||
nameSpan.addStyle(HtmlStyle.typeNameLabel).add(className);
|
||||
}
|
||||
HtmlLinkInfo linkInfo = new HtmlLinkInfo(configuration,
|
||||
HtmlLinkInfo.Kind.SHOW_TYPE_PARAMS_AND_BOUNDS, typeElement);
|
||||
linkInfo.showTypeParameterAnnotations = true;
|
||||
//Let's not link to ourselves in the signature.
|
||||
linkInfo.linkToSelf = false;
|
||||
HtmlLinkInfo.Kind.SHOW_TYPE_PARAMS_AND_BOUNDS, typeElement)
|
||||
.linkToSelf(false) // Let's not link to ourselves in the signature
|
||||
.showTypeParameterAnnotations(true);
|
||||
nameSpan.add(writer.getTypeParameterLinks(linkInfo));
|
||||
content.add(nameSpan);
|
||||
|
||||
|
@ -1,230 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2023, 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.links;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.TypeParameterElement;
|
||||
import javax.lang.model.type.ArrayType;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.type.TypeVariable;
|
||||
import javax.lang.model.type.WildcardType;
|
||||
import javax.lang.model.util.SimpleTypeVisitor14;
|
||||
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.Utils;
|
||||
|
||||
/**
|
||||
* A factory that constructs links from given link information.
|
||||
*/
|
||||
public abstract class LinkFactory {
|
||||
protected final Utils utils;
|
||||
|
||||
protected LinkFactory(Utils utils) {
|
||||
this.utils = utils;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return a new instance of a content object}
|
||||
*/
|
||||
protected abstract Content newContent();
|
||||
|
||||
/**
|
||||
* Constructs a link from the given link information.
|
||||
*
|
||||
* @param linkInfo the information about the link.
|
||||
* @return the link.
|
||||
*/
|
||||
public Content getLink(LinkInfo linkInfo) {
|
||||
if (linkInfo.type != null) {
|
||||
SimpleTypeVisitor14<Content, LinkInfo> linkVisitor = new SimpleTypeVisitor14<>() {
|
||||
|
||||
final Content link = newContent();
|
||||
|
||||
// handles primitives, no types and error types
|
||||
@Override
|
||||
protected Content defaultAction(TypeMirror type, LinkInfo linkInfo) {
|
||||
link.add(utils.getTypeName(type, false));
|
||||
return link;
|
||||
}
|
||||
|
||||
int currentDepth = 0;
|
||||
@Override
|
||||
public Content visitArray(ArrayType type, LinkInfo linkInfo) {
|
||||
// keep track of the dimension depth and replace the last dimension
|
||||
// specifier with varargs, when the stack is fully unwound.
|
||||
currentDepth++;
|
||||
linkInfo.type = type.getComponentType();
|
||||
visit(linkInfo.type, linkInfo);
|
||||
currentDepth--;
|
||||
if (utils.isAnnotated(type)) {
|
||||
linkInfo.type = type;
|
||||
link.add(" ");
|
||||
link.add(getTypeAnnotationLinks(linkInfo));
|
||||
}
|
||||
// use vararg if required
|
||||
if (linkInfo.isVarArg && currentDepth == 0) {
|
||||
link.add("...");
|
||||
} else {
|
||||
link.add("[]");
|
||||
}
|
||||
return link;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Content visitWildcard(WildcardType type, LinkInfo linkInfo) {
|
||||
link.add(getTypeAnnotationLinks(linkInfo));
|
||||
link.add("?");
|
||||
TypeMirror extendsBound = type.getExtendsBound();
|
||||
if (extendsBound != null) {
|
||||
link.add(" extends ");
|
||||
setBoundsLinkInfo(linkInfo, extendsBound);
|
||||
link.add(getLink(linkInfo));
|
||||
}
|
||||
TypeMirror superBound = type.getSuperBound();
|
||||
if (superBound != null) {
|
||||
link.add(" super ");
|
||||
setBoundsLinkInfo(linkInfo, superBound);
|
||||
link.add(getLink(linkInfo));
|
||||
}
|
||||
return link;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Content visitTypeVariable(TypeVariable type, LinkInfo linkInfo) {
|
||||
link.add(getTypeAnnotationLinks(linkInfo));
|
||||
TypeVariable typevariable = (utils.isArrayType(type))
|
||||
? (TypeVariable) utils.getComponentType(type)
|
||||
: type;
|
||||
Element owner = typevariable.asElement().getEnclosingElement();
|
||||
if (linkInfo.linkTypeParameters && utils.isTypeElement(owner)) {
|
||||
linkInfo.typeElement = (TypeElement) owner;
|
||||
Content label = newContent();
|
||||
label.add(utils.getTypeName(type, false));
|
||||
linkInfo.label = label;
|
||||
linkInfo.skipPreview = true;
|
||||
link.add(getClassLink(linkInfo));
|
||||
} else {
|
||||
// No need to link method type parameters.
|
||||
link.add(utils.getTypeName(typevariable, false));
|
||||
}
|
||||
|
||||
if (linkInfo.showTypeBounds) {
|
||||
linkInfo.showTypeBounds = false;
|
||||
TypeParameterElement tpe = ((TypeParameterElement) typevariable.asElement());
|
||||
boolean more = false;
|
||||
List<? extends TypeMirror> bounds = utils.getBounds(tpe);
|
||||
for (TypeMirror bound : bounds) {
|
||||
// we get everything as extends java.lang.Object we suppress
|
||||
// all of them except those that have multiple extends
|
||||
if (bounds.size() == 1 &&
|
||||
utils.typeUtils.isSameType(bound, utils.getObjectType()) &&
|
||||
!utils.isAnnotated(bound)) {
|
||||
continue;
|
||||
}
|
||||
link.add(more ? " & " : " extends ");
|
||||
setBoundsLinkInfo(linkInfo, bound);
|
||||
link.add(getLink(linkInfo));
|
||||
more = true;
|
||||
}
|
||||
}
|
||||
return link;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Content visitDeclared(DeclaredType type, LinkInfo linkInfo) {
|
||||
TypeMirror enc = type.getEnclosingType();
|
||||
if (enc instanceof DeclaredType dt && utils.isGenericType(dt)) {
|
||||
// If an enclosing type has type parameters render them as separate links as
|
||||
// otherwise this information is lost. On the other hand, plain enclosing types
|
||||
// are not linked separately as they are easy to reach from the nested type.
|
||||
setEnclosingTypeLinkInfo(linkInfo, dt);
|
||||
visitDeclared(dt, linkInfo);
|
||||
link.add(".");
|
||||
setEnclosingTypeLinkInfo(linkInfo, type);
|
||||
}
|
||||
link.add(getTypeAnnotationLinks(linkInfo));
|
||||
linkInfo.typeElement = utils.asTypeElement(type);
|
||||
link.add(getClassLink(linkInfo));
|
||||
if (linkInfo.showTypeParameters()) {
|
||||
link.add(getTypeParameterLinks(linkInfo));
|
||||
}
|
||||
return link;
|
||||
}
|
||||
};
|
||||
return linkVisitor.visit(linkInfo.type, linkInfo);
|
||||
} else if (linkInfo.typeElement != null) {
|
||||
Content link = newContent();
|
||||
link.add(getClassLink(linkInfo));
|
||||
if (linkInfo.showTypeParameters()) {
|
||||
link.add(getTypeParameterLinks(linkInfo));
|
||||
}
|
||||
return link;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void setBoundsLinkInfo(LinkInfo linkInfo, TypeMirror bound) {
|
||||
linkInfo.typeElement = null;
|
||||
linkInfo.label = null;
|
||||
linkInfo.type = bound;
|
||||
linkInfo.skipPreview = false;
|
||||
}
|
||||
|
||||
private void setEnclosingTypeLinkInfo(LinkInfo linkinfo, DeclaredType enclosing) {
|
||||
linkinfo.typeElement = null;
|
||||
linkinfo.label = null;
|
||||
linkinfo.type = enclosing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a link to the given class.
|
||||
*
|
||||
* @param linkInfo the information about the link to construct
|
||||
* @return the link for the given class.
|
||||
*/
|
||||
protected abstract Content getClassLink(LinkInfo linkInfo);
|
||||
|
||||
/**
|
||||
* Returns links to the type parameters.
|
||||
*
|
||||
* @param linkInfo the information about the link to construct
|
||||
* @return the links to the type parameters
|
||||
*/
|
||||
protected abstract Content getTypeParameterLinks(LinkInfo linkInfo);
|
||||
|
||||
/**
|
||||
* Returns links to the type annotations.
|
||||
*
|
||||
* @param linkInfo the information about the link to construct
|
||||
* @return the links to the type annotations
|
||||
*/
|
||||
public abstract Content getTypeAnnotationLinks(LinkInfo linkInfo);
|
||||
}
|
@ -1,158 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2023, 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.links;
|
||||
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
|
||||
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.Utils;
|
||||
|
||||
/**
|
||||
* Encapsulates information about a link.
|
||||
*/
|
||||
public abstract class LinkInfo {
|
||||
|
||||
/**
|
||||
* The class we want to link to. Null if we are not linking
|
||||
* to a class.
|
||||
*/
|
||||
public TypeElement typeElement;
|
||||
|
||||
/**
|
||||
* The executable element we want to link to. Null if we are not linking
|
||||
* to an executable element.
|
||||
*/
|
||||
public ExecutableElement executableElement;
|
||||
|
||||
/**
|
||||
* The Type we want to link to. Null if we are not linking to a type.
|
||||
*/
|
||||
public TypeMirror type;
|
||||
|
||||
/**
|
||||
* True if this is a link to a VarArg.
|
||||
*/
|
||||
public boolean isVarArg = false;
|
||||
|
||||
/**
|
||||
* The label for the link.
|
||||
*/
|
||||
public Content label;
|
||||
|
||||
/**
|
||||
* True if we should print the type bounds for the type parameter.
|
||||
*/
|
||||
public boolean showTypeBounds = true;
|
||||
|
||||
/**
|
||||
* True if type parameters should be rendered as links.
|
||||
*/
|
||||
public boolean linkTypeParameters = true;
|
||||
|
||||
/**
|
||||
* By default, the link can be to the page it's already on. However,
|
||||
* there are cases where we don't want this (e.g. heading of class page).
|
||||
*/
|
||||
public boolean linkToSelf = true;
|
||||
|
||||
/**
|
||||
* True iff the preview flags should be skipped for this link.
|
||||
*/
|
||||
public boolean skipPreview;
|
||||
|
||||
/**
|
||||
* True if type parameters should be separated by line breaks.
|
||||
*/
|
||||
public boolean addLineBreaksInTypeParameters = false;
|
||||
|
||||
/**
|
||||
* True if annotations on type parameters should be shown.
|
||||
*/
|
||||
public boolean showTypeParameterAnnotations = false;
|
||||
|
||||
/**
|
||||
* {@return a new instance of a content object}
|
||||
*/
|
||||
protected abstract Content newContent();
|
||||
|
||||
/**
|
||||
* Returns true if this link is linkable and false if we can't link to the
|
||||
* desired place.
|
||||
*
|
||||
* @return true if this link is linkable and false if we can't link to the
|
||||
* desired place.
|
||||
*/
|
||||
public abstract boolean isLinkable();
|
||||
|
||||
/**
|
||||
* Returns true if links to declared types should include type parameters.
|
||||
*
|
||||
* @return true if type parameter links should be included
|
||||
*/
|
||||
public abstract boolean showTypeParameters();
|
||||
|
||||
/**
|
||||
* Return the label for this class link.
|
||||
*
|
||||
* @param configuration the current configuration of the doclet.
|
||||
* @return the label for this class link.
|
||||
*/
|
||||
public Content getClassLinkLabel(BaseConfiguration configuration) {
|
||||
if (label != null && !label.isEmpty()) {
|
||||
return label;
|
||||
} else if (isLinkable()) {
|
||||
Content tlabel = newContent();
|
||||
Utils utils = configuration.utils;
|
||||
tlabel.add(type instanceof DeclaredType dt && utils.isGenericType(dt.getEnclosingType())
|
||||
// If enclosing type is rendered as separate links only use own class name
|
||||
? typeElement.getSimpleName().toString()
|
||||
: configuration.utils.getSimpleName(typeElement));
|
||||
return tlabel;
|
||||
} else {
|
||||
Content tlabel = newContent();
|
||||
tlabel.add(configuration.getClassName(typeElement));
|
||||
return tlabel;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LinkInfo{" + "typeElement=" + typeElement +
|
||||
", executableElement=" + executableElement +
|
||||
", type=" + type +
|
||||
", isVarArg=" + isVarArg +
|
||||
", label=" + label +
|
||||
", showTypeBounds=" + showTypeBounds +
|
||||
", linkTypeParameters=" + linkTypeParameters +
|
||||
", linkToSelf=" + linkToSelf +
|
||||
", addLineBreaksInTypeParameters=" + addLineBreaksInTypeParameters +
|
||||
", showTypeParameterAnnotations=" + showTypeParameterAnnotations + '}';
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides a factory for constructing links.
|
||||
*/
|
||||
package jdk.javadoc.internal.doclets.toolkit.util.links;
|
Loading…
Reference in New Issue
Block a user