8266748: Move modifiers code to Signatures.java

Reviewed-by: jjg
This commit is contained in:
Hannes Wallnöfer 2021-06-08 19:21:21 +00:00
parent 4dd0e7e78a
commit f9b593d668
5 changed files with 138 additions and 143 deletions

View File

@ -85,8 +85,6 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
"java.lang.constant.ConstantDesc",
"java.io.Serializable");
private static final Set<String> previewModifiers = Collections.emptySet();
protected final TypeElement typeElement;
protected final ClassTree classtree;
@ -197,28 +195,9 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
}
@Override
public void addClassSignature(String modifiers, Content classInfoTree) {
ContentBuilder mods = new ContentBuilder();
String sep = null;
for (String modifiersPart : modifiers.split(" ")) {
if (sep != null) {
mods.add(sep);
}
if (previewModifiers.contains(modifiersPart)) {
mods.add(modifiersPart);
mods.add(HtmlTree.SUP(links.createLink(htmlIds.forPreviewSection(typeElement),
contents.previewMark)));
} else {
mods.add(modifiersPart);
}
sep = " ";
}
if (modifiers.endsWith(" ")) {
mods.add(" ");
}
public void addClassSignature(Content classInfoTree) {
classInfoTree.add(new HtmlTree(TagName.HR));
classInfoTree.add(new Signatures.TypeSignature(typeElement, this)
.setModifiers(mods)
.toContent());
}

View File

@ -37,20 +37,29 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants;
import jdk.javadoc.internal.doclets.toolkit.util.Utils;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.RecordComponentElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementKindVisitor14;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.stream.Collectors;
import static javax.lang.model.element.Modifier.ABSTRACT;
import static javax.lang.model.element.Modifier.FINAL;
import static javax.lang.model.element.Modifier.NATIVE;
import static javax.lang.model.element.Modifier.PRIVATE;
import static javax.lang.model.element.Modifier.PROTECTED;
import static javax.lang.model.element.Modifier.PUBLIC;
import static javax.lang.model.element.Modifier.STATIC;
import static javax.lang.model.element.Modifier.STRICTFP;
import static javax.lang.model.element.Modifier.SYNCHRONIZED;
@ -92,17 +101,20 @@ public class Signatures {
static class TypeSignature {
private final TypeElement typeElement;
private final ClassWriterImpl classWriter;
private final HtmlDocletWriter writer;
private final Utils utils;
private final HtmlConfiguration configuration;
private Content modifiers;
TypeSignature(TypeElement typeElement, ClassWriterImpl classWriter) {
this.typeElement = typeElement;
this.classWriter = classWriter;
this.utils = classWriter.utils;
this.configuration = classWriter.configuration;
}
private static final Set<String> previewModifiers = Collections.emptySet();
TypeSignature(TypeElement typeElement, HtmlDocletWriter writer) {
this.typeElement = typeElement;
this.writer = writer;
this.utils = writer.utils;
this.configuration = writer.configuration;
this.modifiers = markPreviewModifiers(getModifiers());
}
public TypeSignature setModifiers(Content modifiers) {
this.modifiers = modifiers;
@ -111,7 +123,7 @@ public class Signatures {
public Content toContent() {
Content content = new ContentBuilder();
Content annotationInfo = classWriter.getAnnotationInfo(typeElement, true);
Content annotationInfo = writer.getAnnotationInfo(typeElement, true);
if (!annotationInfo.isEmpty()) {
content.add(HtmlTree.SPAN(HtmlStyle.annotations, annotationInfo));
}
@ -119,8 +131,8 @@ public class Signatures {
HtmlTree nameSpan = new HtmlTree(TagName.SPAN).setStyle(HtmlStyle.elementName);
Content className = Text.of(utils.getSimpleName(typeElement));
if (classWriter.options.linkSource()) {
classWriter.addSrcLink(typeElement, className, nameSpan);
if (configuration.getOptions().linkSource()) {
writer.addSrcLink(typeElement, className, nameSpan);
} else {
nameSpan.addStyle(HtmlStyle.typeNameLabel).add(className);
}
@ -128,7 +140,7 @@ public class Signatures {
HtmlLinkInfo.Kind.CLASS_SIGNATURE, typeElement);
//Let's not link to ourselves in the signature.
linkInfo.linkToSelf = false;
nameSpan.add(classWriter.getTypeParameterLinks(linkInfo));
nameSpan.add(writer.getTypeParameterLinks(linkInfo));
content.add(nameSpan);
if (utils.isRecord(typeElement)) {
@ -142,7 +154,7 @@ public class Signatures {
if (superclass != null) {
content.add(DocletConstants.NL);
extendsImplements.add("extends ");
Content link = classWriter.getLink(new HtmlLinkInfo(configuration,
Content link = writer.getLink(new HtmlLinkInfo(configuration,
HtmlLinkInfo.Kind.CLASS_SIGNATURE_PARENT_NAME,
superclass));
extendsImplements.add(link);
@ -163,7 +175,7 @@ public class Signatures {
} else {
extendsImplements.add(", ");
}
Content link = classWriter.getLink(new HtmlLinkInfo(configuration,
Content link = writer.getLink(new HtmlLinkInfo(configuration,
HtmlLinkInfo.Kind.CLASS_SIGNATURE_PARENT_NAME,
type));
extendsImplements.add(link);
@ -189,13 +201,13 @@ public class Signatures {
} else {
permitsSpan.add(", ");
}
Content link = classWriter.getLink(new HtmlLinkInfo(configuration,
Content link = writer.getLink(new HtmlLinkInfo(configuration,
HtmlLinkInfo.Kind.PERMITTED_SUBCLASSES,
type));
permitsSpan.add(link);
}
if (linkablePermits.size() < permits.size()) {
Content c = Text.of(classWriter.resources.getText("doclet.not.exhaustive"));
Content c = Text.of(configuration.getDocResources().getText("doclet.not.exhaustive"));
permitsSpan.add(" ");
permitsSpan.add(HtmlTree.SPAN(HtmlStyle.permitsNote, c));
}
@ -210,9 +222,9 @@ public class Signatures {
String sep = "";
for (RecordComponentElement e : typeElement.getRecordComponents()) {
content.add(sep);
classWriter.getAnnotations(e.getAnnotationMirrors(), false)
writer.getAnnotations(e.getAnnotationMirrors(), false)
.forEach(a -> { content.add(a).add(" "); });
Content link = classWriter.getLink(new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.RECORD_COMPONENT,
Content link = writer.getLink(new HtmlLinkInfo(configuration, HtmlLinkInfo.Kind.RECORD_COMPONENT,
e.asType()));
content.add(link);
content.add(Entity.NO_BREAK_SPACE);
@ -222,6 +234,112 @@ public class Signatures {
content.add(")");
return content;
}
private Content markPreviewModifiers(List<String> modifiers) {
Content content = new ContentBuilder();
String sep = null;
for (String modifier : modifiers) {
if (sep != null) {
content.add(sep);
}
content.add(modifier);
if (previewModifiers.contains(modifier)) {
content.add(HtmlTree.SUP(writer.links.createLink(
configuration.htmlIds.forPreviewSection(typeElement),
configuration.contents.previewMark)));
}
sep = " ";
}
content.add(" ");
return content;
}
private List<String> getModifiers() {
SortedSet<Modifier> modifiers = new TreeSet<>(typeElement.getModifiers());
modifiers.remove(NATIVE);
modifiers.remove(STRICTFP);
modifiers.remove(SYNCHRONIZED);
return new ElementKindVisitor14<List<String>, SortedSet<Modifier>>() {
final List<String> list = new ArrayList<>();
void addVisibilityModifier(Set<Modifier> modifiers) {
if (modifiers.contains(PUBLIC)) {
list.add("public");
} else if (modifiers.contains(PROTECTED)) {
list.add("protected");
} else if (modifiers.contains(PRIVATE)) {
list.add("private");
}
}
void addStatic(Set<Modifier> modifiers) {
if (modifiers.contains(STATIC)) {
list.add("static");
}
}
void addSealed(TypeElement e) {
if (e.getModifiers().contains(Modifier.SEALED)) {
list.add("sealed");
} else if (e.getModifiers().contains(Modifier.NON_SEALED)) {
list.add("non-sealed");
}
}
void addModifiers(Set<Modifier> modifiers) {
modifiers.stream()
.map(Modifier::toString)
.forEachOrdered(list::add);
}
@Override
public List<String> visitTypeAsInterface(TypeElement e, SortedSet<Modifier> mods) {
addVisibilityModifier(mods);
addStatic(mods);
addSealed(e);
list.add("interface");
return list;
}
@Override
public List<String> visitTypeAsEnum(TypeElement e, SortedSet<Modifier> mods) {
addVisibilityModifier(mods);
addStatic(mods);
list.add("enum");
return list;
}
@Override
public List<String> visitTypeAsAnnotationType(TypeElement e, SortedSet<Modifier> mods) {
addVisibilityModifier(mods);
addStatic(mods);
list.add("@interface");
return list;
}
@Override
public List<String> visitTypeAsRecord(TypeElement e, SortedSet<Modifier> mods) {
mods.remove(FINAL); // suppress the implicit `final`
return visitTypeAsClass(e, mods);
}
@Override
public List<String> visitTypeAsClass(TypeElement e, SortedSet<Modifier> mods) {
addModifiers(mods);
String keyword = e.getKind() == ElementKind.RECORD ? "record" : "class";
list.add(keyword);
return list;
}
@Override
protected List<String> defaultAction(Element e, SortedSet<Modifier> mods) {
addModifiers(mods);
return list;
}
}.visit(typeElement, modifiers);
}
}
/**

View File

@ -145,10 +145,9 @@ public interface ClassWriter {
/**
* Add the signature of the current class content tree.
*
* @param modifiers the modifiers for the signature
* @param classInfoTree the class content tree to which the signature will be added
*/
void addClassSignature(String modifiers, Content classInfoTree);
void addClassSignature(Content classInfoTree);
/**
* Build the class description.

View File

@ -295,7 +295,7 @@ public class ClassBuilder extends AbstractBuilder {
* @param classInfoTree the content tree to which the documentation will be added
*/
protected void buildClassSignature(Content classInfoTree) {
writer.addClassSignature(utils.modifiersToString(typeElement, true), classInfoTree);
writer.addClassSignature(classInfoTree);
}
/**

View File

@ -34,7 +34,6 @@ import java.text.ParseException;
import java.text.RuleBasedCollator;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
@ -81,7 +80,6 @@ import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.type.WildcardType;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.ElementKindVisitor14;
import javax.lang.model.util.Elements;
import javax.lang.model.util.SimpleAnnotationValueVisitor14;
import javax.lang.model.util.SimpleElementVisitor14;
@ -127,7 +125,6 @@ import jdk.javadoc.internal.doclets.toolkit.taglets.Taglet;
import jdk.javadoc.internal.tool.DocEnvImpl;
import static javax.lang.model.element.ElementKind.*;
import static javax.lang.model.element.Modifier.*;
import static javax.lang.model.type.TypeKind.*;
import static com.sun.source.doctree.DocTree.Kind.*;
@ -491,104 +488,6 @@ public class Utils {
return configuration.workArounds.definesSerializableFields( aclass);
}
public String modifiersToString(Element e, boolean trailingSpace) {
SortedSet<Modifier> modifiers = new TreeSet<>(e.getModifiers());
modifiers.remove(NATIVE);
modifiers.remove(STRICTFP);
modifiers.remove(SYNCHRONIZED);
return new ElementKindVisitor14<String, SortedSet<Modifier>>() {
final StringBuilder sb = new StringBuilder();
void addVisibilityModifier(Set<Modifier> modifiers) {
if (modifiers.contains(PUBLIC)) {
append("public");
} else if (modifiers.contains(PROTECTED)) {
append("protected");
} else if (modifiers.contains(PRIVATE)) {
append("private");
}
}
void addStatic(Set<Modifier> modifiers) {
if (modifiers.contains(STATIC)) {
append("static");
}
}
void addSealed(TypeElement e) {
if (e.getModifiers().contains(Modifier.SEALED)) {
append("sealed");
} else if (e.getModifiers().contains(Modifier.NON_SEALED)) {
append("non-sealed");
}
}
void addModifiers(Set<Modifier> modifiers) {
modifiers.stream()
.map(Modifier::toString)
.forEachOrdered(this::append);
}
void append(String s) {
if (sb.length() > 0) {
sb.append(" ");
}
sb.append(s);
}
String finalString(String s) {
append(s);
if (trailingSpace) {
sb.append(" ");
}
return sb.toString();
}
@Override
public String visitTypeAsInterface(TypeElement e, SortedSet<Modifier> mods) {
addVisibilityModifier(mods);
addStatic(mods);
addSealed(e);
return finalString("interface");
}
@Override
public String visitTypeAsEnum(TypeElement e, SortedSet<Modifier> mods) {
addVisibilityModifier(mods);
addStatic(mods);
return finalString("enum");
}
@Override
public String visitTypeAsAnnotationType(TypeElement e, SortedSet<Modifier> mods) {
addVisibilityModifier(mods);
addStatic(mods);
return finalString("@interface");
}
@Override
public String visitTypeAsRecord(TypeElement e, SortedSet<Modifier> mods) {
mods.remove(FINAL); // suppress the implicit `final`
return visitTypeAsClass(e, mods);
}
@Override
public String visitTypeAsClass(TypeElement e, SortedSet<Modifier> mods) {
addModifiers(mods);
String keyword = e.getKind() == ElementKind.RECORD ? "record" : "class";
return finalString(keyword);
}
@Override
protected String defaultAction(Element e, SortedSet<Modifier> mods) {
addModifiers(mods);
return sb.toString().trim();
}
}.visit(e, modifiers);
}
public boolean isFunctionalInterface(AnnotationMirror amirror) {
return amirror.getAnnotationType().equals(getFunctionalInterface()) &&
configuration.docEnv.getSourceVersion()