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.lang.constant.ConstantDesc",
"java.io.Serializable"); "java.io.Serializable");
private static final Set<String> previewModifiers = Collections.emptySet();
protected final TypeElement typeElement; protected final TypeElement typeElement;
protected final ClassTree classtree; protected final ClassTree classtree;
@ -197,28 +195,9 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
} }
@Override @Override
public void addClassSignature(String modifiers, Content classInfoTree) { public void addClassSignature(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(" ");
}
classInfoTree.add(new HtmlTree(TagName.HR)); classInfoTree.add(new HtmlTree(TagName.HR));
classInfoTree.add(new Signatures.TypeSignature(typeElement, this) classInfoTree.add(new Signatures.TypeSignature(typeElement, this)
.setModifiers(mods)
.toContent()); .toContent());
} }

View File

@ -37,20 +37,29 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants;
import jdk.javadoc.internal.doclets.toolkit.util.Utils; import jdk.javadoc.internal.doclets.toolkit.util.Utils;
import javax.lang.model.element.Element; import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Modifier; import javax.lang.model.element.Modifier;
import javax.lang.model.element.ModuleElement; import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement; import javax.lang.model.element.PackageElement;
import javax.lang.model.element.RecordComponentElement; import javax.lang.model.element.RecordComponentElement;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror; 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.List;
import java.util.Set; import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static javax.lang.model.element.Modifier.ABSTRACT; 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.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.PUBLIC;
import static javax.lang.model.element.Modifier.STATIC;
import static javax.lang.model.element.Modifier.STRICTFP; import static javax.lang.model.element.Modifier.STRICTFP;
import static javax.lang.model.element.Modifier.SYNCHRONIZED; import static javax.lang.model.element.Modifier.SYNCHRONIZED;
@ -92,17 +101,20 @@ public class Signatures {
static class TypeSignature { static class TypeSignature {
private final TypeElement typeElement; private final TypeElement typeElement;
private final ClassWriterImpl classWriter; private final HtmlDocletWriter writer;
private final Utils utils; private final Utils utils;
private final HtmlConfiguration configuration; private final HtmlConfiguration configuration;
private Content modifiers; private Content modifiers;
TypeSignature(TypeElement typeElement, ClassWriterImpl classWriter) { private static final Set<String> previewModifiers = Collections.emptySet();
this.typeElement = typeElement;
this.classWriter = classWriter; TypeSignature(TypeElement typeElement, HtmlDocletWriter writer) {
this.utils = classWriter.utils; this.typeElement = typeElement;
this.configuration = classWriter.configuration; this.writer = writer;
} this.utils = writer.utils;
this.configuration = writer.configuration;
this.modifiers = markPreviewModifiers(getModifiers());
}
public TypeSignature setModifiers(Content modifiers) { public TypeSignature setModifiers(Content modifiers) {
this.modifiers = modifiers; this.modifiers = modifiers;
@ -111,7 +123,7 @@ public class Signatures {
public Content toContent() { public Content toContent() {
Content content = new ContentBuilder(); Content content = new ContentBuilder();
Content annotationInfo = classWriter.getAnnotationInfo(typeElement, true); Content annotationInfo = writer.getAnnotationInfo(typeElement, true);
if (!annotationInfo.isEmpty()) { if (!annotationInfo.isEmpty()) {
content.add(HtmlTree.SPAN(HtmlStyle.annotations, annotationInfo)); content.add(HtmlTree.SPAN(HtmlStyle.annotations, annotationInfo));
} }
@ -119,8 +131,8 @@ public class Signatures {
HtmlTree nameSpan = new HtmlTree(TagName.SPAN).setStyle(HtmlStyle.elementName); HtmlTree nameSpan = new HtmlTree(TagName.SPAN).setStyle(HtmlStyle.elementName);
Content className = Text.of(utils.getSimpleName(typeElement)); Content className = Text.of(utils.getSimpleName(typeElement));
if (classWriter.options.linkSource()) { if (configuration.getOptions().linkSource()) {
classWriter.addSrcLink(typeElement, className, nameSpan); writer.addSrcLink(typeElement, className, nameSpan);
} else { } else {
nameSpan.addStyle(HtmlStyle.typeNameLabel).add(className); nameSpan.addStyle(HtmlStyle.typeNameLabel).add(className);
} }
@ -128,7 +140,7 @@ public class Signatures {
HtmlLinkInfo.Kind.CLASS_SIGNATURE, typeElement); HtmlLinkInfo.Kind.CLASS_SIGNATURE, typeElement);
//Let's not link to ourselves in the signature. //Let's not link to ourselves in the signature.
linkInfo.linkToSelf = false; linkInfo.linkToSelf = false;
nameSpan.add(classWriter.getTypeParameterLinks(linkInfo)); nameSpan.add(writer.getTypeParameterLinks(linkInfo));
content.add(nameSpan); content.add(nameSpan);
if (utils.isRecord(typeElement)) { if (utils.isRecord(typeElement)) {
@ -142,7 +154,7 @@ public class Signatures {
if (superclass != null) { if (superclass != null) {
content.add(DocletConstants.NL); content.add(DocletConstants.NL);
extendsImplements.add("extends "); extendsImplements.add("extends ");
Content link = classWriter.getLink(new HtmlLinkInfo(configuration, Content link = writer.getLink(new HtmlLinkInfo(configuration,
HtmlLinkInfo.Kind.CLASS_SIGNATURE_PARENT_NAME, HtmlLinkInfo.Kind.CLASS_SIGNATURE_PARENT_NAME,
superclass)); superclass));
extendsImplements.add(link); extendsImplements.add(link);
@ -163,7 +175,7 @@ public class Signatures {
} else { } else {
extendsImplements.add(", "); extendsImplements.add(", ");
} }
Content link = classWriter.getLink(new HtmlLinkInfo(configuration, Content link = writer.getLink(new HtmlLinkInfo(configuration,
HtmlLinkInfo.Kind.CLASS_SIGNATURE_PARENT_NAME, HtmlLinkInfo.Kind.CLASS_SIGNATURE_PARENT_NAME,
type)); type));
extendsImplements.add(link); extendsImplements.add(link);
@ -189,13 +201,13 @@ public class Signatures {
} else { } else {
permitsSpan.add(", "); permitsSpan.add(", ");
} }
Content link = classWriter.getLink(new HtmlLinkInfo(configuration, Content link = writer.getLink(new HtmlLinkInfo(configuration,
HtmlLinkInfo.Kind.PERMITTED_SUBCLASSES, HtmlLinkInfo.Kind.PERMITTED_SUBCLASSES,
type)); type));
permitsSpan.add(link); permitsSpan.add(link);
} }
if (linkablePermits.size() < permits.size()) { 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(" ");
permitsSpan.add(HtmlTree.SPAN(HtmlStyle.permitsNote, c)); permitsSpan.add(HtmlTree.SPAN(HtmlStyle.permitsNote, c));
} }
@ -210,9 +222,9 @@ public class Signatures {
String sep = ""; String sep = "";
for (RecordComponentElement e : typeElement.getRecordComponents()) { for (RecordComponentElement e : typeElement.getRecordComponents()) {
content.add(sep); content.add(sep);
classWriter.getAnnotations(e.getAnnotationMirrors(), false) writer.getAnnotations(e.getAnnotationMirrors(), false)
.forEach(a -> { content.add(a).add(" "); }); .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())); e.asType()));
content.add(link); content.add(link);
content.add(Entity.NO_BREAK_SPACE); content.add(Entity.NO_BREAK_SPACE);
@ -222,6 +234,112 @@ public class Signatures {
content.add(")"); content.add(")");
return content; 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. * 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 * @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. * 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 * @param classInfoTree the content tree to which the documentation will be added
*/ */
protected void buildClassSignature(Content classInfoTree) { 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.text.RuleBasedCollator;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Deque; 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.TypeVariable;
import javax.lang.model.type.WildcardType; import javax.lang.model.type.WildcardType;
import javax.lang.model.util.ElementFilter; import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.ElementKindVisitor14;
import javax.lang.model.util.Elements; import javax.lang.model.util.Elements;
import javax.lang.model.util.SimpleAnnotationValueVisitor14; import javax.lang.model.util.SimpleAnnotationValueVisitor14;
import javax.lang.model.util.SimpleElementVisitor14; 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 jdk.javadoc.internal.tool.DocEnvImpl;
import static javax.lang.model.element.ElementKind.*; import static javax.lang.model.element.ElementKind.*;
import static javax.lang.model.element.Modifier.*;
import static javax.lang.model.type.TypeKind.*; import static javax.lang.model.type.TypeKind.*;
import static com.sun.source.doctree.DocTree.Kind.*; import static com.sun.source.doctree.DocTree.Kind.*;
@ -491,104 +488,6 @@ public class Utils {
return configuration.workArounds.definesSerializableFields( aclass); 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) { public boolean isFunctionalInterface(AnnotationMirror amirror) {
return amirror.getAnnotationType().equals(getFunctionalInterface()) && return amirror.getAnnotationType().equals(getFunctionalInterface()) &&
configuration.docEnv.getSourceVersion() configuration.docEnv.getSourceVersion()