mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8225054: Compiler implementation for records
8225052: javax.lang.model support for records 8225053: Preview APIs support for records 8225055: Javadoc for records 8226314: com.sun.source support for records 8227113: Specification for java.lang.Record 8233526: JVM support for records Implement records in the compiler and the JVM, including serialization, reflection and APIs support Co-authored-by: Brian Goetz <brian.goetz@oracle.com> Co-authored-by: Maurizio Cimadamore <maurizio.cimadamore@oracle.com> Co-authored-by: Harold Seigel <harold.seigel@oracle.com> Co-authored-by: Joe Darcy <joe.darcy@oracle.com> Co-authored-by: Jonathan Gibbons <jonathan.gibbons@oracle.com> Co-authored-by: Chris Hegarty <chris.hegarty@oracle.com> Co-authored-by: Jan Lahoda <jan.lahoda@oracle.com> Reviewed-by: mcimadamore, briangoetz, alanb, darcy, chegar, jrose, jlahoda, coleenp, dholmes, lfoltan, mchung, sadayapalam, hannesw, sspitsyn
This commit is contained in:
parent
0a375cfa2d
commit
827e5e3226
351 changed files with 24958 additions and 6395 deletions
|
@ -38,7 +38,7 @@ 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.SimpleElementVisitor9;
|
||||
import javax.lang.model.util.SimpleElementVisitor14;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.Entity;
|
||||
|
@ -178,9 +178,10 @@ public class AbstractIndexWriter extends HtmlDocletWriter {
|
|||
contentTree.add(heading);
|
||||
}
|
||||
|
||||
@SuppressWarnings("preview")
|
||||
protected void addDescription(Content dl, Element element) {
|
||||
SearchIndexItem si = new SearchIndexItem();
|
||||
new SimpleElementVisitor9<Void, Void>() {
|
||||
new SimpleElementVisitor14<Void, Void>() {
|
||||
|
||||
@Override
|
||||
public Void visitModule(ModuleElement e, Void p) {
|
||||
|
|
|
@ -35,6 +35,7 @@ import javax.lang.model.element.AnnotationMirror;
|
|||
import javax.lang.model.element.Element;
|
||||
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.SimpleElementVisitor8;
|
||||
|
@ -210,7 +211,7 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Override @SuppressWarnings("preview")
|
||||
public void addClassSignature(String modifiers, Content classInfoTree) {
|
||||
Content hr = new HtmlTree(HtmlTag.HR);
|
||||
classInfoTree.add(hr);
|
||||
|
@ -231,6 +232,9 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
|
|||
span.add(parameterLinks);
|
||||
pre.add(span);
|
||||
}
|
||||
if (utils.isRecord(typeElement)) {
|
||||
pre.add(getRecordComponents(typeElement));
|
||||
}
|
||||
if (!utils.isInterface(typeElement)) {
|
||||
TypeMirror superclass = utils.getFirstVisibleSuperClass(typeElement);
|
||||
if (superclass != null) {
|
||||
|
@ -266,6 +270,26 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
|
|||
classInfoTree.add(pre);
|
||||
}
|
||||
|
||||
@SuppressWarnings("preview")
|
||||
private Content getRecordComponents(TypeElement typeElem) {
|
||||
Content content = new ContentBuilder();
|
||||
content.add("(");
|
||||
String sep = "";
|
||||
for (RecordComponentElement e : typeElement.getRecordComponents()) {
|
||||
content.add(sep);
|
||||
getAnnotations(e.getAnnotationMirrors(), false).stream()
|
||||
.forEach(a -> { content.add(a); content.add(" "); });
|
||||
Content link = getLink(new LinkInfoImpl(configuration, LinkInfoImpl.Kind.RECORD_COMPONENT,
|
||||
e.asType()));
|
||||
content.add(link);
|
||||
content.add(Entity.NO_BREAK_SPACE);
|
||||
content.add(e.getSimpleName());
|
||||
sep = ", ";
|
||||
}
|
||||
content.add(")");
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -294,9 +318,9 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
|
|||
* Get the class hierarchy tree for the given class.
|
||||
*
|
||||
* @param type the class to print the hierarchy for
|
||||
* @return a content tree for class inheritence
|
||||
* @return a content tree for class inheritance
|
||||
*/
|
||||
private Content getClassInheritenceTree(TypeMirror type) {
|
||||
private Content getClassInheritanceTree(TypeMirror type) {
|
||||
TypeMirror sup;
|
||||
HtmlTree classTree = null;
|
||||
do {
|
||||
|
@ -347,19 +371,20 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite
|
|||
if (!utils.isClass(typeElement)) {
|
||||
return;
|
||||
}
|
||||
classContentTree.add(getClassInheritenceTree(typeElement.asType()));
|
||||
classContentTree.add(getClassInheritanceTree(typeElement.asType()));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void addTypeParamInfo(Content classInfoTree) {
|
||||
if (!utils.getTypeParamTrees(typeElement).isEmpty()) {
|
||||
Content typeParam = (new ParamTaglet()).getTagletOutput(typeElement,
|
||||
public void addParamInfo(Content classInfoTree) {
|
||||
if (utils.hasBlockTag(typeElement, DocTree.Kind.PARAM)) {
|
||||
Content paramInfo = (new ParamTaglet()).getTagletOutput(typeElement,
|
||||
getTagletWriterInstance(false));
|
||||
Content dl = HtmlTree.DL(typeParam);
|
||||
classInfoTree.add(dl);
|
||||
if (!paramInfo.isEmpty()) {
|
||||
classInfoTree.add(HtmlTree.DL(paramInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -155,6 +155,7 @@ public class Contents {
|
|||
public final Content propertyLabel;
|
||||
public final Content propertyDetailsLabel;
|
||||
public final Content propertySummaryLabel;
|
||||
public final Content record;
|
||||
public final Content seeLabel;
|
||||
public final Content serializedForm;
|
||||
public final Content servicesLabel;
|
||||
|
@ -282,6 +283,7 @@ public class Contents {
|
|||
propertyLabel = getContent("doclet.Property");
|
||||
propertyDetailsLabel = getContent("doclet.Property_Detail");
|
||||
propertySummaryLabel = getContent("doclet.Property_Summary");
|
||||
record = getContent("doclet.Record");
|
||||
seeLabel = getContent("doclet.See");
|
||||
serializedForm = getContent("doclet.Serialized_Form");
|
||||
servicesLabel = getContent("doclet.Services");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2019, 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
|
||||
|
@ -236,22 +236,21 @@ public class HtmlDoclet extends AbstractDoclet {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override // defined by AbstractDoclet
|
||||
protected void generateClassFiles(SortedSet<TypeElement> arr, ClassTree classtree)
|
||||
protected void generateClassFiles(SortedSet<TypeElement> typeElems, ClassTree classTree)
|
||||
throws DocletException {
|
||||
List<TypeElement> list = new ArrayList<>(arr);
|
||||
for (TypeElement klass : list) {
|
||||
if (utils.hasHiddenTag(klass) ||
|
||||
!(configuration.isGeneratedDoc(klass) && utils.isIncluded(klass))) {
|
||||
for (TypeElement te : typeElems) {
|
||||
if (utils.hasHiddenTag(te) ||
|
||||
!(configuration.isGeneratedDoc(te) && utils.isIncluded(te))) {
|
||||
continue;
|
||||
}
|
||||
if (utils.isAnnotationType(klass)) {
|
||||
if (utils.isAnnotationType(te)) {
|
||||
AbstractBuilder annotationTypeBuilder =
|
||||
configuration.getBuilderFactory()
|
||||
.getAnnotationTypeBuilder(klass);
|
||||
.getAnnotationTypeBuilder(te);
|
||||
annotationTypeBuilder.build();
|
||||
} else {
|
||||
AbstractBuilder classBuilder =
|
||||
configuration.getBuilderFactory().getClassBuilder(klass, classtree);
|
||||
configuration.getBuilderFactory().getClassBuilder(te, classTree);
|
||||
classBuilder.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ import javax.lang.model.element.VariableElement;
|
|||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.util.SimpleAnnotationValueVisitor9;
|
||||
import javax.lang.model.util.SimpleElementVisitor9;
|
||||
import javax.lang.model.util.SimpleElementVisitor14;
|
||||
import javax.lang.model.util.SimpleTypeVisitor9;
|
||||
|
||||
import com.sun.source.doctree.AttributeTree;
|
||||
|
@ -1510,7 +1510,8 @@ public class HtmlDocletWriter {
|
|||
@Override
|
||||
public Boolean visitLink(LinkTree node, Content c) {
|
||||
// we need to pass the DocTreeImpl here, so ignore node
|
||||
result.add(seeTagToContent(element, tag));
|
||||
Content content = seeTagToContent(element, tag);
|
||||
result.add(content);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1658,13 +1659,14 @@ public class HtmlDocletWriter {
|
|||
*
|
||||
* @return the text, with all the relative links redirected to work.
|
||||
*/
|
||||
@SuppressWarnings("preview")
|
||||
private String redirectRelativeLinks(Element element, TextTree tt) {
|
||||
String text = tt.getBody();
|
||||
if (element == null || utils.isOverviewElement(element) || shouldNotRedirectRelativeLinks()) {
|
||||
return text;
|
||||
}
|
||||
|
||||
DocPath redirectPathFromRoot = new SimpleElementVisitor9<DocPath, Void>() {
|
||||
DocPath redirectPathFromRoot = new SimpleElementVisitor14<DocPath, Void>() {
|
||||
@Override
|
||||
public DocPath visitType(TypeElement e, Void p) {
|
||||
return docPaths.forPackage(utils.containingPackage(e));
|
||||
|
@ -1747,22 +1749,22 @@ public class HtmlDocletWriter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Add the annotatation types for the given element and parameter.
|
||||
* Add the annotation types for the given element and parameter.
|
||||
*
|
||||
* @param param the parameter to write annotations for.
|
||||
* @param tree the content tree to which the annotation types will be added
|
||||
*/
|
||||
public boolean addAnnotationInfo(VariableElement param, Content tree) {
|
||||
Content annotaionInfo = getAnnotationInfo(param.getAnnotationMirrors(), false);
|
||||
if (annotaionInfo.isEmpty()) {
|
||||
Content annotationInfo = getAnnotationInfo(param.getAnnotationMirrors(), false);
|
||||
if (annotationInfo.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
tree.add(annotaionInfo);
|
||||
tree.add(annotationInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the annotatation types for the given Element.
|
||||
* Adds the annotation types for the given Element.
|
||||
*
|
||||
* @param descList a list of annotation mirrors.
|
||||
* @param htmltree the documentation tree to which the annotation info will be
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2019, 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
|
||||
|
@ -215,7 +215,12 @@ public class LinkInfoImpl extends LinkInfo {
|
|||
/**
|
||||
* A receiver type
|
||||
*/
|
||||
RECEIVER_TYPE
|
||||
RECEIVER_TYPE,
|
||||
|
||||
/**
|
||||
* A record component within a class signature
|
||||
*/
|
||||
RECORD_COMPONENT
|
||||
}
|
||||
|
||||
public final HtmlConfiguration configuration;
|
||||
|
|
|
@ -208,6 +208,15 @@ public class PackageWriterImpl extends HtmlDocletWriter
|
|||
addClassesSummary(enums, resources.enumSummary, tableHeader, summaryContentTree);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void addRecordSummary(SortedSet<TypeElement> records, Content summaryContentTree) {
|
||||
TableHeader tableHeader= new TableHeader(contents.record, contents.descriptionLabel);
|
||||
addClassesSummary(records, resources.recordSummary, tableHeader, summaryContentTree);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
@ -28,13 +28,15 @@ package jdk.javadoc.internal.doclets.formats.html;
|
|||
import java.util.List;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.util.SimpleElementVisitor9;
|
||||
import javax.lang.model.util.SimpleElementVisitor14;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import com.sun.source.doctree.IndexTree;
|
||||
import com.sun.source.doctree.ParamTree;
|
||||
import com.sun.source.doctree.SystemPropertyTree;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
|
||||
|
@ -190,15 +192,19 @@ public class TagletWriterImpl extends TagletWriter {
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@SuppressWarnings("preview")
|
||||
public Content paramTagOutput(Element element, DocTree paramTag, String paramName) {
|
||||
ContentBuilder body = new ContentBuilder();
|
||||
CommentHelper ch = utils.getCommentHelper(element);
|
||||
body.add(HtmlTree.CODE(new RawHtml(paramName)));
|
||||
// define id attributes for state components so that generated descriptions may refer to them
|
||||
boolean defineID = (element.getKind() == ElementKind.RECORD)
|
||||
&& (paramTag instanceof ParamTree) && !((ParamTree) paramTag).isTypeParameter();
|
||||
Content nameTree = new StringContent(paramName);
|
||||
body.add(HtmlTree.CODE(defineID ? HtmlTree.A_ID("param-" + paramName, nameTree) : nameTree));
|
||||
body.add(" - ");
|
||||
List<? extends DocTree> description = ch.getDescription(configuration, paramTag);
|
||||
body.add(htmlWriter.commentTagsToContent(paramTag, element, description, false, inSummary));
|
||||
HtmlTree result = HtmlTree.DD(body);
|
||||
return result;
|
||||
return HtmlTree.DD(body);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -409,6 +415,7 @@ public class TagletWriterImpl extends TagletWriter {
|
|||
return configuration;
|
||||
}
|
||||
|
||||
@SuppressWarnings("preview")
|
||||
private Content createAnchorAndSearchIndex(Element element, String tagText, String desc){
|
||||
Content result = null;
|
||||
if (isFirstSentence && inSummary) {
|
||||
|
@ -427,7 +434,7 @@ public class TagletWriterImpl extends TagletWriter {
|
|||
si.setDescription(desc);
|
||||
si.setUrl(htmlWriter.path.getPath() + "#" + anchorName);
|
||||
DocPaths docPaths = configuration.docPaths;
|
||||
new SimpleElementVisitor9<Void, Void>() {
|
||||
new SimpleElementVisitor14<Void, Void>() {
|
||||
@Override
|
||||
public Void visitVariable(VariableElement e, Void p) {
|
||||
TypeElement te = utils.getEnclosingTypeElement(e);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2019, 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
|
||||
|
@ -26,13 +26,14 @@
|
|||
package jdk.javadoc.internal.doclets.toolkit;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.ref.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ModuleElement;
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.util.SimpleElementVisitor9;
|
||||
import javax.lang.model.util.SimpleElementVisitor14;
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
|
@ -1222,6 +1223,7 @@ public abstract class BaseConfiguration {
|
|||
* Splits the elements in a collection to its individual
|
||||
* collection.
|
||||
*/
|
||||
@SuppressWarnings("preview")
|
||||
static private class Splitter {
|
||||
|
||||
final Set<ModuleElement> mset = new LinkedHashSet<>();
|
||||
|
@ -1235,7 +1237,7 @@ public abstract class BaseConfiguration {
|
|||
: docEnv.getSpecifiedElements();
|
||||
|
||||
for (Element e : inset) {
|
||||
new SimpleElementVisitor9<Void, Void>() {
|
||||
new SimpleElementVisitor14<Void, Void>() {
|
||||
@Override
|
||||
@DefinedBy(Api.LANGUAGE_MODEL)
|
||||
public Void visitModule(ModuleElement e, Void p) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2019, 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
|
||||
|
@ -73,11 +73,11 @@ public interface ClassWriter {
|
|||
public Content getClassInfoTreeHeader();
|
||||
|
||||
/**
|
||||
* Add the type parameter information.
|
||||
* Add the type parameter and state component information.
|
||||
*
|
||||
* @param classInfoTree content tree to which the documentation will be added
|
||||
*/
|
||||
public void addTypeParamInfo(Content classInfoTree);
|
||||
public void addParamInfo(Content classInfoTree);
|
||||
|
||||
/**
|
||||
* Add all super interfaces if this is an interface.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2019, 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
|
||||
|
@ -38,20 +38,26 @@ import java.net.URI;
|
|||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.Name;
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.lang.model.element.RecordComponentElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.SimpleJavaFileObject;
|
||||
|
||||
import com.sun.source.doctree.AttributeTree;
|
||||
import com.sun.source.doctree.DocCommentTree;
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import com.sun.source.doctree.IdentifierTree;
|
||||
import com.sun.source.doctree.ParamTree;
|
||||
import com.sun.source.doctree.ReferenceTree;
|
||||
import com.sun.source.doctree.TextTree;
|
||||
import com.sun.source.util.DocTreeFactory;
|
||||
|
@ -65,6 +71,7 @@ import jdk.javadoc.internal.doclets.toolkit.util.Utils;
|
|||
public class CommentUtils {
|
||||
|
||||
final BaseConfiguration configuration;
|
||||
final Utils utils;
|
||||
final Resources resources;
|
||||
final DocTreeFactory treeFactory;
|
||||
final HashMap<Element, DocCommentDuo> dcTreesMap = new HashMap<>();
|
||||
|
@ -73,6 +80,7 @@ public class CommentUtils {
|
|||
|
||||
protected CommentUtils(BaseConfiguration configuration) {
|
||||
this.configuration = configuration;
|
||||
utils = configuration.utils;
|
||||
resources = configuration.getResources();
|
||||
trees = configuration.docEnv.getDocTrees();
|
||||
treeFactory = trees.getDocTreeFactory();
|
||||
|
@ -107,17 +115,17 @@ public class CommentUtils {
|
|||
return treeFactory.newSeeTree(list);
|
||||
}
|
||||
|
||||
public DocTree makeTextTree(String content) {
|
||||
TextTree text = treeFactory.newTextTree(content);
|
||||
return (DocTree) text;
|
||||
public TextTree makeTextTree(String content) {
|
||||
return treeFactory.newTextTree(content);
|
||||
}
|
||||
|
||||
public void setEnumValuesTree(Element e) {
|
||||
Utils utils = configuration.utils;
|
||||
String klassName = utils.getSimpleName(utils.getEnclosingTypeElement(e));
|
||||
public TextTree makeTextTreeForResource(String key) {
|
||||
return treeFactory.newTextTree(resources.getText(key));
|
||||
}
|
||||
|
||||
public void setEnumValuesTree(ExecutableElement ee) {
|
||||
List<DocTree> fullBody = new ArrayList<>();
|
||||
fullBody.add(treeFactory.newTextTree(resources.getText("doclet.enum_values_doc.fullbody", klassName)));
|
||||
fullBody.add(treeFactory.newTextTree(resources.getText("doclet.enum_values_doc.fullbody")));
|
||||
|
||||
List<DocTree> descriptions = new ArrayList<>();
|
||||
descriptions.add(treeFactory.newTextTree(resources.getText("doclet.enum_values_doc.return")));
|
||||
|
@ -125,11 +133,10 @@ public class CommentUtils {
|
|||
List<DocTree> tags = new ArrayList<>();
|
||||
tags.add(treeFactory.newReturnTree(descriptions));
|
||||
DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, tags);
|
||||
dcTreesMap.put(e, new DocCommentDuo(null, docTree));
|
||||
dcTreesMap.put(ee, new DocCommentDuo(null, docTree));
|
||||
}
|
||||
|
||||
public void setEnumValueOfTree(Element e) {
|
||||
|
||||
public void setEnumValueOfTree(ExecutableElement ee) {
|
||||
List<DocTree> fullBody = new ArrayList<>();
|
||||
fullBody.add(treeFactory.newTextTree(resources.getText("doclet.enum_valueof_doc.fullbody")));
|
||||
|
||||
|
@ -137,7 +144,6 @@ public class CommentUtils {
|
|||
|
||||
List<DocTree> paramDescs = new ArrayList<>();
|
||||
paramDescs.add(treeFactory.newTextTree(resources.getText("doclet.enum_valueof_doc.param_name")));
|
||||
ExecutableElement ee = (ExecutableElement) e;
|
||||
java.util.List<? extends VariableElement> parameters = ee.getParameters();
|
||||
VariableElement param = parameters.get(0);
|
||||
IdentifierTree id = treeFactory.newIdentifierTree(elementUtils.getName(param.getSimpleName().toString()));
|
||||
|
@ -161,7 +167,231 @@ public class CommentUtils {
|
|||
|
||||
DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, tags);
|
||||
|
||||
dcTreesMap.put(e, new DocCommentDuo(null, docTree));
|
||||
dcTreesMap.put(ee, new DocCommentDuo(null, docTree));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the description for the canonical constructor for a record.
|
||||
* @param ee the constructor
|
||||
*/
|
||||
public void setRecordConstructorTree(ExecutableElement ee) {
|
||||
TypeElement te = utils.getEnclosingTypeElement(ee);
|
||||
|
||||
List<DocTree> fullBody =
|
||||
makeDescriptionWithName("doclet.record_constructor_doc.fullbody", te.getSimpleName());
|
||||
|
||||
List<DocTree> tags = new ArrayList<>();
|
||||
java.util.List<? extends VariableElement> parameters = ee.getParameters();
|
||||
for (VariableElement param : ee.getParameters()) {
|
||||
Name name = param.getSimpleName();
|
||||
IdentifierTree id = treeFactory.newIdentifierTree(name);
|
||||
tags.add(treeFactory.newParamTree(false, id,
|
||||
makeDescriptionWithComponent("doclet.record_constructor_doc.param_name", te, name)));
|
||||
}
|
||||
|
||||
DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, tags);
|
||||
dcTreesMap.put(ee, new DocCommentDuo(null, docTree));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the description for the standard {@code equals} method for a record.
|
||||
* @param ee the {@code equals} method
|
||||
*/
|
||||
@SuppressWarnings("preview")
|
||||
public void setRecordEqualsTree(ExecutableElement ee) {
|
||||
List<DocTree> fullBody = new ArrayList<>();
|
||||
add(fullBody, "doclet.record_equals_doc.fullbody.head");
|
||||
fullBody.add(treeFactory.newTextTree(" "));
|
||||
|
||||
List<? extends RecordComponentElement> comps = ((TypeElement) ee.getEnclosingElement()).getRecordComponents();
|
||||
boolean hasPrimitiveComponents =
|
||||
comps.stream().anyMatch(e -> e.asType().getKind().isPrimitive());
|
||||
boolean hasReferenceComponents =
|
||||
comps.stream().anyMatch(e -> !e.asType().getKind().isPrimitive());
|
||||
if (hasPrimitiveComponents && hasReferenceComponents) {
|
||||
add(fullBody, "doclet.record_equals_doc.fullbody.tail.both");
|
||||
} else if (hasPrimitiveComponents) {
|
||||
add(fullBody, "doclet.record_equals_doc.fullbody.tail.primitive");
|
||||
} else if (hasReferenceComponents) {
|
||||
add(fullBody, "doclet.record_equals_doc.fullbody.tail.reference");
|
||||
}
|
||||
Name paramName = ee.getParameters().get(0).getSimpleName();
|
||||
IdentifierTree id = treeFactory.newIdentifierTree(paramName);
|
||||
List<DocTree> paramDesc =
|
||||
makeDescriptionWithName("doclet.record_equals_doc.param_name", paramName);
|
||||
DocTree paramTree = treeFactory.newParamTree(false, id, paramDesc);
|
||||
|
||||
DocTree returnTree = treeFactory.newReturnTree(
|
||||
makeDescriptionWithName("doclet.record_equals_doc.return", paramName));
|
||||
|
||||
TreePath treePath = utils.getTreePath(ee.getEnclosingElement());
|
||||
DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, List.of(paramTree, returnTree));
|
||||
dcTreesMap.put(ee, new DocCommentDuo(treePath, docTree));
|
||||
}
|
||||
|
||||
private void add(List<DocTree> contents, String resourceKey) {
|
||||
// Special case to allow '{@link ...}' to appear in the string.
|
||||
// A less general case would be to detect literal use of Object.equals
|
||||
// A more general case would be to allow access to DocCommentParser somehow
|
||||
String body = resources.getText(resourceKey);
|
||||
Pattern p = Pattern.compile("\\{@link (\\S*)(.*)}");
|
||||
Matcher m = p.matcher(body);
|
||||
int start = 0;
|
||||
while (m.find(start)) {
|
||||
if (m.start() > start) {
|
||||
contents.add(treeFactory.newTextTree(body.substring(start, m.start())));
|
||||
}
|
||||
ReferenceTree refTree = treeFactory.newReferenceTree(m.group(1));
|
||||
List<DocTree> descr = List.of(treeFactory.newTextTree(m.group(2).trim())) ;
|
||||
contents.add(treeFactory.newLinkTree(refTree, descr));
|
||||
start = m.end();
|
||||
}
|
||||
if (start < body.length()) {
|
||||
contents.add(treeFactory.newTextTree(body.substring(start)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the description for the standard {@code hashCode} method for a record.
|
||||
* @param ee the {@code hashCode} method
|
||||
*/
|
||||
public void setRecordHashCodeTree(ExecutableElement ee) {
|
||||
List<DocTree> fullBody = List.of(makeTextTreeForResource("doclet.record_hashCode_doc.fullbody"));
|
||||
|
||||
DocTree returnTree = treeFactory.newReturnTree(
|
||||
List.of(makeTextTreeForResource("doclet.record_hashCode_doc.return")));
|
||||
|
||||
DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, List.of(returnTree));
|
||||
dcTreesMap.put(ee, new DocCommentDuo(null, docTree));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the description for the standard {@code toString} method for a record.
|
||||
* @param ee the {@code toString} method
|
||||
*/
|
||||
public void setRecordToStringTree(ExecutableElement ee) {
|
||||
List<DocTree> fullBody = List.of(
|
||||
treeFactory.newTextTree(resources.getText("doclet.record_toString_doc.fullbody")));
|
||||
|
||||
DocTree returnTree = treeFactory.newReturnTree(List.of(
|
||||
treeFactory.newTextTree(resources.getText("doclet.record_toString_doc.return"))));
|
||||
|
||||
DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, List.of(returnTree));
|
||||
dcTreesMap.put(ee, new DocCommentDuo(null, docTree));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the description for the accessor method for a state component of a record.
|
||||
* @param ee the accessor method
|
||||
*/
|
||||
public void setRecordAccessorTree(ExecutableElement ee) {
|
||||
TypeElement te = utils.getEnclosingTypeElement(ee);
|
||||
|
||||
List<DocTree> fullBody =
|
||||
makeDescriptionWithComponent("doclet.record_accessor_doc.fullbody", te, ee.getSimpleName());
|
||||
|
||||
DocTree returnTree = treeFactory.newReturnTree(
|
||||
makeDescriptionWithComponent("doclet.record_accessor_doc.return", te, ee.getSimpleName()));
|
||||
|
||||
DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, List.of(returnTree));
|
||||
dcTreesMap.put(ee, new DocCommentDuo(null, docTree));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the description for the field for a state component of a record.
|
||||
* @param ve the field
|
||||
*/
|
||||
public void setRecordFieldTree(VariableElement ve) {
|
||||
TypeElement te = utils.getEnclosingTypeElement(ve);
|
||||
|
||||
List<DocTree> fullBody =
|
||||
makeDescriptionWithComponent("doclet.record_field_doc.fullbody", te, ve.getSimpleName());
|
||||
|
||||
DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, List.of());
|
||||
dcTreesMap.put(ve, new DocCommentDuo(null, docTree));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a description that contains a reference to a state component of a record.
|
||||
* The description is looked up as a resource, and should contain {@code {0}} where the
|
||||
* reference to the component is to be inserted. The reference will be a link if the
|
||||
* doc comment for the record has a {@code @param} tag for the component.
|
||||
* @param key the resource key for the description
|
||||
* @param elem the record element
|
||||
* @param component the name of the component
|
||||
* @return the description
|
||||
*/
|
||||
private List<DocTree> makeDescriptionWithComponent(String key, TypeElement elem, Name component) {
|
||||
List<DocTree> result = new ArrayList<>();
|
||||
String text = resources.getText(key);
|
||||
int index = text.indexOf("{0}");
|
||||
result.add(treeFactory.newTextTree(text.substring(0, index)));
|
||||
Name A = elementUtils.getName("a");
|
||||
Name CODE = elementUtils.getName("code");
|
||||
Name HREF = elementUtils.getName("href");
|
||||
List<DocTree> code = List.of(
|
||||
treeFactory.newStartElementTree(CODE, List.of(), false),
|
||||
treeFactory.newTextTree(component.toString()),
|
||||
treeFactory.newEndElementTree(CODE));
|
||||
if (hasParamForComponent(elem, component)) {
|
||||
DocTree href = treeFactory.newAttributeTree(HREF,
|
||||
AttributeTree.ValueKind.DOUBLE,
|
||||
List.of(treeFactory.newTextTree("#param-" + component)));
|
||||
result.add(treeFactory.newStartElementTree(A, List.of(href), false));
|
||||
result.addAll(code);
|
||||
result.add(treeFactory.newEndElementTree(A));
|
||||
} else {
|
||||
result.addAll(code);
|
||||
}
|
||||
result.add(treeFactory.newTextTree(text.substring(index + 3)));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the doc comment for a record contains an {@code @param}}
|
||||
* for a state component of the record.
|
||||
* @param elem the record element
|
||||
* @param component the name of the component
|
||||
* @return whether or not there is a {@code @param}} for the component
|
||||
*/
|
||||
private boolean hasParamForComponent(TypeElement elem, Name component) {
|
||||
DocCommentTree elemComment = utils.getDocCommentTree(elem);
|
||||
if (elemComment == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (DocTree t : elemComment.getBlockTags()) {
|
||||
if (t instanceof ParamTree && ((ParamTree) t).getName().getName() == component) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a description that contains the simple name of a program element
|
||||
* The description is looked up as a resource, and should contain {@code {0}} where the
|
||||
* name is to be inserted.
|
||||
* @param key the resource key for the description
|
||||
* @param name the name
|
||||
* @return the description
|
||||
*/
|
||||
private List<DocTree> makeDescriptionWithName(String key, Name name) {
|
||||
String text = resources.getText(key);
|
||||
int index = text.indexOf("{0}");
|
||||
if (index == -1) {
|
||||
return List.of(treeFactory.newTextTree(text));
|
||||
} else {
|
||||
Name CODE = elementUtils.getName("code");
|
||||
return List.of(
|
||||
treeFactory.newTextTree(text.substring(0, index)),
|
||||
treeFactory.newStartElementTree(CODE, List.of(), false),
|
||||
treeFactory.newTextTree(name.toString()),
|
||||
treeFactory.newEndElementTree(CODE),
|
||||
treeFactory.newTextTree(text.substring(index + 3))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -215,7 +445,7 @@ public class CommentUtils {
|
|||
}
|
||||
|
||||
public void setDocCommentTree(Element element, List<? extends DocTree> fullBody,
|
||||
List<? extends DocTree> blockTags, Utils utils) {
|
||||
List<? extends DocTree> blockTags) {
|
||||
DocCommentTree docTree = treeFactory.newDocCommentTree(fullBody, blockTags);
|
||||
dcTreesMap.put(element, new DocCommentDuo(null, docTree));
|
||||
// A method having null comment (no comment) that might need to be replaced
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2019, 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
|
||||
|
@ -94,6 +94,15 @@ public interface PackageSummaryWriter {
|
|||
public abstract void addEnumSummary(SortedSet<TypeElement> enums,
|
||||
Content summaryContentTree);
|
||||
|
||||
/**
|
||||
* Adds the table of records to the documentation tree.
|
||||
*
|
||||
* @param records the records to document.
|
||||
* @param summaryContentTree the content tree to which the summaries will be added
|
||||
*/
|
||||
public abstract void addRecordSummary(SortedSet<TypeElement> records,
|
||||
Content summaryContentTree);
|
||||
|
||||
/**
|
||||
* Adds the table of exceptions to the documentation tree.
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2019, 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
|
||||
|
@ -49,6 +49,7 @@ public class Resources {
|
|||
public final String exceptionSummary;
|
||||
public final String interfaceSummary;
|
||||
public final String packageSummary;
|
||||
public final String recordSummary;
|
||||
|
||||
protected ResourceBundle commonBundle;
|
||||
protected ResourceBundle docletBundle;
|
||||
|
@ -76,6 +77,7 @@ public class Resources {
|
|||
this.exceptionSummary = getText("doclet.Exception_Summary");
|
||||
this.interfaceSummary = getText("doclet.Interface_Summary");
|
||||
this.packageSummary = getText("doclet.Package_Summary");
|
||||
this.recordSummary = getText("doclet.Record_Summary");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,11 +25,21 @@
|
|||
|
||||
package jdk.javadoc.internal.doclets.toolkit.builders;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.Name;
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
|
||||
import jdk.javadoc.internal.doclets.formats.html.markup.ContentBuilder;
|
||||
import jdk.javadoc.internal.doclets.toolkit.ClassWriter;
|
||||
import jdk.javadoc.internal.doclets.toolkit.CommentUtils;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.DocFilesHandler;
|
||||
import jdk.javadoc.internal.doclets.toolkit.DocletException;
|
||||
|
@ -69,6 +79,16 @@ public class ClassBuilder extends AbstractBuilder {
|
|||
*/
|
||||
private final boolean isEnum;
|
||||
|
||||
/**
|
||||
* Keep track of whether or not this typeElement is a record.
|
||||
*/
|
||||
private final boolean isRecord;
|
||||
|
||||
/**
|
||||
* The content tree for the class documentation.
|
||||
*/
|
||||
private Content contentTree;
|
||||
|
||||
private final Utils utils;
|
||||
|
||||
/**
|
||||
|
@ -86,13 +106,21 @@ public class ClassBuilder extends AbstractBuilder {
|
|||
if (utils.isInterface(typeElement)) {
|
||||
isInterface = true;
|
||||
isEnum = false;
|
||||
isRecord = false;
|
||||
} else if (utils.isEnum(typeElement)) {
|
||||
isInterface = false;
|
||||
isEnum = true;
|
||||
utils.setEnumDocumentation(typeElement);
|
||||
isRecord = false;
|
||||
setEnumDocumentation(typeElement);
|
||||
} else if (utils.isRecord(typeElement)) {
|
||||
isInterface = false;
|
||||
isEnum = false;
|
||||
isRecord = true;
|
||||
setRecordDocumentation(typeElement);
|
||||
} else {
|
||||
isInterface = false;
|
||||
isEnum = false;
|
||||
isRecord = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,6 +155,8 @@ public class ClassBuilder extends AbstractBuilder {
|
|||
key = "doclet.Interface";
|
||||
} else if (isEnum) {
|
||||
key = "doclet.Enum";
|
||||
} else if (isRecord) {
|
||||
key = "doclet.Record";
|
||||
} else {
|
||||
key = "doclet.Class";
|
||||
}
|
||||
|
@ -162,7 +192,7 @@ public class ClassBuilder extends AbstractBuilder {
|
|||
*/
|
||||
protected void buildClassInfo(Content classContentTree) throws DocletException {
|
||||
Content classInfoTree = new ContentBuilder();
|
||||
buildTypeParamInfo(classInfoTree);
|
||||
buildParamInfo(classInfoTree);
|
||||
buildSuperInterfacesInfo(classInfoTree);
|
||||
buildImplementedInterfacesInfo(classInfoTree);
|
||||
buildSubClassInfo(classInfoTree);
|
||||
|
@ -179,12 +209,12 @@ public class ClassBuilder extends AbstractBuilder {
|
|||
}
|
||||
|
||||
/**
|
||||
* Build the type parameters of this class.
|
||||
* Build the type parameters and state components of this class.
|
||||
*
|
||||
* @param classInfoTree the content tree to which the documentation will be added
|
||||
*/
|
||||
protected void buildTypeParamInfo(Content classInfoTree) {
|
||||
writer.addTypeParamInfo(classInfoTree);
|
||||
protected void buildParamInfo(Content classInfoTree) {
|
||||
writer.addParamInfo(classInfoTree);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -386,4 +416,96 @@ public class ClassBuilder extends AbstractBuilder {
|
|||
protected void buildMethodDetails(Content memberDetailsTree) throws DocletException {
|
||||
builderFactory.getMethodBuilder(writer).build(memberDetailsTree);
|
||||
}
|
||||
|
||||
/**
|
||||
* The documentation for values() and valueOf() in Enums are set by the
|
||||
* doclet only iff the user or overridden methods are missing.
|
||||
* @param elem the enum element
|
||||
*/
|
||||
private void setEnumDocumentation(TypeElement elem) {
|
||||
CommentUtils cmtUtils = configuration.cmtUtils;
|
||||
for (ExecutableElement ee : utils.getMethods(elem)) {
|
||||
if (!utils.getFullBody(ee).isEmpty()) // ignore if already set
|
||||
continue;
|
||||
Name name = ee.getSimpleName();
|
||||
if (name.contentEquals("values") && ee.getParameters().isEmpty()) {
|
||||
utils.removeCommentHelper(ee); // purge previous entry
|
||||
cmtUtils.setEnumValuesTree(ee);
|
||||
} else if (name.contentEquals("valueOf") && ee.getParameters().size() == 1) {
|
||||
// TODO: check parameter type
|
||||
utils.removeCommentHelper(ee); // purge previous entry
|
||||
cmtUtils.setEnumValueOfTree(ee);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the documentation as needed for the mandated parts of a record type.
|
||||
* This includes the canonical constructor, methods like {@code equals},
|
||||
* {@code hashCode}, {@code toString}, the accessor methods, and the underlying
|
||||
* field.
|
||||
* @param elem the record element
|
||||
*/
|
||||
|
||||
@SuppressWarnings("preview")
|
||||
private void setRecordDocumentation(TypeElement elem) {
|
||||
CommentUtils cmtUtils = configuration.cmtUtils;
|
||||
Set<Name> componentNames = elem.getRecordComponents().stream()
|
||||
.map(Element::getSimpleName)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
for (ExecutableElement ee : utils.getConstructors(elem)) {
|
||||
if (utils.isCanonicalRecordConstructor(ee)) {
|
||||
if (utils.getFullBody(ee).isEmpty()) {
|
||||
utils.removeCommentHelper(ee); // purge previous entry
|
||||
cmtUtils.setRecordConstructorTree(ee);
|
||||
}
|
||||
// only one canonical constructor; no need to keep looking
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (VariableElement ve : utils.getFields(elem)) {
|
||||
// The fields for the record component cannot be declared by the
|
||||
// user and so cannot have any pre-existing comment.
|
||||
Name name = ve.getSimpleName();
|
||||
if (componentNames.contains(name)) {
|
||||
utils.removeCommentHelper(ve); // purge previous entry
|
||||
cmtUtils.setRecordFieldTree(ve);
|
||||
}
|
||||
}
|
||||
|
||||
TypeMirror objectType = utils.getObjectType();
|
||||
|
||||
for (ExecutableElement ee : utils.getMethods(elem)) {
|
||||
if (!utils.getFullBody(ee).isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Name name = ee.getSimpleName();
|
||||
List<? extends VariableElement> params = ee.getParameters();
|
||||
if (name.contentEquals("equals")) {
|
||||
if (params.size() == 1 && utils.typeUtils.isSameType(params.get(0).asType(), objectType)) {
|
||||
utils.removeCommentHelper(ee); // purge previous entry
|
||||
cmtUtils.setRecordEqualsTree(ee);
|
||||
}
|
||||
} else if (name.contentEquals("hashCode")) {
|
||||
if (params.isEmpty()) {
|
||||
utils.removeCommentHelper(ee); // purge previous entry
|
||||
cmtUtils.setRecordHashCodeTree(ee);
|
||||
}
|
||||
} else if (name.contentEquals("toString")) {
|
||||
if (params.isEmpty()) {
|
||||
utils.removeCommentHelper(ee); // purge previous entry
|
||||
cmtUtils.setRecordToStringTree(ee);
|
||||
}
|
||||
} else if (componentNames.contains(name)) {
|
||||
if (params.isEmpty()) {
|
||||
utils.removeCommentHelper(ee); // purge previous entry
|
||||
cmtUtils.setRecordAccessorTree(ee);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -411,7 +411,7 @@ public abstract class MemberSummaryBuilder extends AbstractMemberBuilder {
|
|||
blockTags.add(cmtutils.makeSeeTree(sb.toString(), setter));
|
||||
}
|
||||
}
|
||||
cmtutils.setDocCommentTree(member, fullBody, blockTags, utils);
|
||||
cmtutils.setDocCommentTree(member, fullBody, blockTags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -151,6 +151,7 @@ public class PackageSummaryBuilder extends AbstractBuilder {
|
|||
buildInterfaceSummary(summaryContentTree);
|
||||
buildClassSummary(summaryContentTree);
|
||||
buildEnumSummary(summaryContentTree);
|
||||
buildRecordSummary(summaryContentTree);
|
||||
buildExceptionSummary(summaryContentTree);
|
||||
buildErrorSummary(summaryContentTree);
|
||||
buildAnnotationTypeSummary(summaryContentTree);
|
||||
|
@ -206,6 +207,22 @@ public class PackageSummaryBuilder extends AbstractBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the summary for the records in this package.
|
||||
*
|
||||
* @param summaryContentTree the summary tree to which the record summary will
|
||||
* be added
|
||||
*/
|
||||
protected void buildRecordSummary(Content summaryContentTree) {
|
||||
SortedSet<TypeElement> rlist = utils.isSpecified(packageElement)
|
||||
? utils.getTypeElementsAsSortedSet(utils.getRecords(packageElement))
|
||||
: configuration.typeElementCatalog.records(packageElement);
|
||||
SortedSet<TypeElement> records = utils.filterOutPrivateClasses(rlist, configuration.javafx);
|
||||
if (!records.isEmpty()) {
|
||||
packageWriter.addRecordSummary(records, summaryContentTree);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the summary for the exceptions in this package.
|
||||
*
|
||||
|
|
|
@ -591,10 +591,10 @@ public class SerializedFormBuilder extends AbstractBuilder {
|
|||
}
|
||||
|
||||
/**
|
||||
* Return true if any of the given typeElements have a @serialinclude tag.
|
||||
* Return true if any of the given typeElements have a {@code @serial include} tag.
|
||||
*
|
||||
* @param classes the typeElements to check.
|
||||
* @return true if any of the given typeElements have a @serialinclude tag.
|
||||
* @return true if any of the given typeElements have a {@code @serial include} tag.
|
||||
*/
|
||||
private boolean serialClassFoundToDocument(SortedSet<TypeElement> classes) {
|
||||
for (TypeElement aClass : classes) {
|
||||
|
|
|
@ -93,10 +93,13 @@ doclet.PropertySetterWithName=Sets the value of the property {0}.
|
|||
doclet.Default=Default:
|
||||
doclet.Parameters=Parameters:
|
||||
doclet.TypeParameters=Type Parameters:
|
||||
doclet.RecordComponents=Record Components:
|
||||
doclet.Parameters_warn=@param argument "{0}" is not a parameter name.
|
||||
doclet.Parameters_dup_warn=Parameter "{0}" is documented more than once.
|
||||
doclet.Type_Parameters_warn=@param argument "{0}" is not a type parameter name.
|
||||
doclet.Type_Parameters_dup_warn=Type parameter "{0}" is documented more than once.
|
||||
doclet.TypeParameters_warn=@param argument "{0}" is not the name of a type parameter.
|
||||
doclet.TypeParameters_dup_warn=Type parameter "{0}" is documented more than once.
|
||||
doclet.RecordComponents_warn=@param argument "{0}" is not the name of a record component.
|
||||
doclet.RecordComponents_dup_warn=Record component "{0}" is documented more than once.
|
||||
doclet.Returns=Returns:
|
||||
doclet.Return_tag_on_void_method=@return tag cannot be used in method with void return type.
|
||||
doclet.See_Also=See Also:
|
||||
|
@ -137,6 +140,7 @@ doclet.Property_Summary=Property Summary
|
|||
doclet.Enum_Constant_Summary=Enum Constant Summary
|
||||
doclet.Constructor_Summary=Constructor Summary
|
||||
doclet.Method_Summary=Method Summary
|
||||
doclet.Record_Summary=Record Summary
|
||||
doclet.Interfaces=Interfaces
|
||||
doclet.Enums=Enums
|
||||
doclet.AnnotationTypes=Annotation Types
|
||||
|
@ -160,6 +164,7 @@ doclet.interface=interface
|
|||
doclet.interfaces=interfaces
|
||||
doclet.class=class
|
||||
doclet.classes=classes
|
||||
doclet.Record=Record
|
||||
doclet.Error=Error
|
||||
doclet.error=error
|
||||
doclet.errors=errors
|
||||
|
@ -268,3 +273,58 @@ doclet.enum_valueof_doc.throws_ila=\
|
|||
|
||||
doclet.enum_valueof_doc.throws_npe=\
|
||||
if the argument is null
|
||||
|
||||
|
||||
#Documentation for records
|
||||
doclet.record_constructor_doc.fullbody=\
|
||||
Creates an instance of a {0} record.
|
||||
|
||||
doclet.record_constructor_doc.param_name=\
|
||||
the value for the {0} record component
|
||||
|
||||
doclet.record_equals_doc.fullbody.head=\
|
||||
Indicates whether some other object is "equal to" this one. \
|
||||
The objects are equal if the other object is of the same class \
|
||||
and if all the record components are equal.
|
||||
|
||||
doclet.record_equals_doc.fullbody.tail.both=\
|
||||
Reference components are compared with \
|
||||
{@link java.util.Objects#equals(Object,Object) Objects::equals(Object,Object)}; \
|
||||
primitive components are compared with '=='.
|
||||
|
||||
doclet.record_equals_doc.fullbody.tail.primitive=\
|
||||
All components in this record are compared with '=='.
|
||||
|
||||
doclet.record_equals_doc.fullbody.tail.reference=\
|
||||
All components in this record are compared with \
|
||||
{@link java.util.Objects#equals(Object,Object) Objects::equals(Object,Object)}.
|
||||
|
||||
doclet.record_equals_doc.param_name=\
|
||||
the object with which to compare
|
||||
|
||||
doclet.record_equals_doc.return=\
|
||||
<code>true</code> if this object is the same as the {0} argument; <code>false</code> otherwise.
|
||||
|
||||
doclet.record_hashCode_doc.fullbody=\
|
||||
Returns a hash code value for this object. \
|
||||
The value is derived from the hash code of each of the record components.
|
||||
|
||||
doclet.record_hashCode_doc.return=\
|
||||
a hash code value for this object
|
||||
|
||||
doclet.record_toString_doc.fullbody=\
|
||||
Returns a string representation of this record. \
|
||||
The representation contains the name of the type, followed by \
|
||||
the name and value of each of the record components.
|
||||
|
||||
doclet.record_toString_doc.return=\
|
||||
a string representation of this object
|
||||
|
||||
doclet.record_accessor_doc.fullbody=\
|
||||
Returns the value of the {0} record component.
|
||||
|
||||
doclet.record_accessor_doc.return=\
|
||||
the value of the {0} record component
|
||||
|
||||
doclet.record_field_doc.fullbody=\
|
||||
The field for the {0} record component.
|
||||
|
|
|
@ -29,6 +29,7 @@ import java.util.*;
|
|||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.Name;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
|
@ -53,6 +54,14 @@ import static com.sun.source.doctree.DocTree.Kind.PARAM;
|
|||
* @author Jamie Ho
|
||||
*/
|
||||
public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
|
||||
private enum ParamKind {
|
||||
/** Parameter of an executable element. */
|
||||
PARAMETER,
|
||||
/** State components of a record. */
|
||||
RECORD_COMPONENT,
|
||||
/** Type parameters of an executable element or type element. */
|
||||
TYPE_PARAMETER
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a ParamTaglet.
|
||||
|
@ -101,7 +110,7 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
|
|||
String pname = input.isTypeVariableParamTag
|
||||
? utils.getTypeName(e.asType(), false)
|
||||
: utils.getSimpleName(e);
|
||||
if (pname.equals(target)) {
|
||||
if (pname.contentEquals(target)) {
|
||||
input.tagId = String.valueOf(i);
|
||||
break;
|
||||
}
|
||||
|
@ -128,19 +137,23 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("preview")
|
||||
public Content getTagletOutput(Element holder, TagletWriter writer) {
|
||||
Utils utils = writer.configuration().utils;
|
||||
if (utils.isExecutableElement(holder)) {
|
||||
ExecutableElement member = (ExecutableElement) holder;
|
||||
Content output = getTagletOutput(false, member, writer,
|
||||
Content output = getTagletOutput(ParamKind.TYPE_PARAMETER, member, writer,
|
||||
member.getTypeParameters(), utils.getTypeParamTrees(member));
|
||||
output.add(getTagletOutput(true, member, writer,
|
||||
output.add(getTagletOutput(ParamKind.PARAMETER, member, writer,
|
||||
member.getParameters(), utils.getParamTrees(member)));
|
||||
return output;
|
||||
} else {
|
||||
TypeElement typeElement = (TypeElement) holder;
|
||||
return getTagletOutput(false, typeElement, writer,
|
||||
Content output = getTagletOutput(ParamKind.TYPE_PARAMETER, typeElement, writer,
|
||||
typeElement.getTypeParameters(), utils.getTypeParamTrees(typeElement));
|
||||
output.add(getTagletOutput(ParamKind.RECORD_COMPONENT, typeElement, writer,
|
||||
typeElement.getRecordComponents(), utils.getParamTrees(typeElement)));
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,25 +163,25 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
|
|||
*
|
||||
* @param holder the element that holds the param tags.
|
||||
* @param writer the TagletWriter that will write this tag.
|
||||
* @param formalParameters The array of parmeters (from type or executable
|
||||
* @param formalParameters The array of parameters (from type or executable
|
||||
* member) to check.
|
||||
*
|
||||
* @return the content representation of these {@code @param DocTree}s.
|
||||
*/
|
||||
private Content getTagletOutput(boolean isParameters, Element holder,
|
||||
private Content getTagletOutput(ParamKind kind, Element holder,
|
||||
TagletWriter writer, List<? extends Element> formalParameters, List<? extends DocTree> paramTags) {
|
||||
Content result = writer.getOutputInstance();
|
||||
Set<String> alreadyDocumented = new HashSet<>();
|
||||
if (!paramTags.isEmpty()) {
|
||||
result.add(
|
||||
processParamTags(holder, isParameters, paramTags,
|
||||
processParamTags(holder, kind, paramTags,
|
||||
getRankMap(writer.configuration().utils, formalParameters), writer, alreadyDocumented)
|
||||
);
|
||||
}
|
||||
if (alreadyDocumented.size() != formalParameters.size()) {
|
||||
//Some parameters are missing corresponding @param tags.
|
||||
//Try to inherit them.
|
||||
result.add(getInheritedTagletOutput(isParameters, holder,
|
||||
result.add(getInheritedTagletOutput(kind, holder,
|
||||
writer, formalParameters, alreadyDocumented));
|
||||
}
|
||||
return result;
|
||||
|
@ -178,7 +191,7 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
|
|||
* Loop through each individual parameter, despite not having a
|
||||
* corresponding param tag, try to inherit it.
|
||||
*/
|
||||
private Content getInheritedTagletOutput(boolean isParameters, Element holder,
|
||||
private Content getInheritedTagletOutput(ParamKind kind, Element holder,
|
||||
TagletWriter writer, List<? extends Element> formalParameters,
|
||||
Set<String> alreadyDocumented) {
|
||||
Utils utils = writer.configuration().utils;
|
||||
|
@ -191,16 +204,16 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
|
|||
// This parameter does not have any @param documentation.
|
||||
// Try to inherit it.
|
||||
Input input = new DocFinder.Input(writer.configuration().utils, holder, this,
|
||||
Integer.toString(i), !isParameters);
|
||||
Integer.toString(i), kind == ParamKind.TYPE_PARAMETER);
|
||||
DocFinder.Output inheritedDoc = DocFinder.search(writer.configuration(), input);
|
||||
if (inheritedDoc.inlineTags != null && !inheritedDoc.inlineTags.isEmpty()) {
|
||||
Element e = formalParameters.get(i);
|
||||
String lname = isParameters
|
||||
String lname = kind != ParamKind.TYPE_PARAMETER
|
||||
? utils.getSimpleName(e)
|
||||
: utils.getTypeName(e.asType(), false);
|
||||
CommentHelper ch = utils.getCommentHelper(holder);
|
||||
ch.setOverrideElement(inheritedDoc.holder);
|
||||
Content content = processParamTag(holder, isParameters, writer,
|
||||
Content content = processParamTag(holder, kind, writer,
|
||||
inheritedDoc.holderTag,
|
||||
lname,
|
||||
alreadyDocumented.isEmpty());
|
||||
|
@ -230,7 +243,7 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
|
|||
when parameter documentation is inherited.
|
||||
* @return the Content representation of this {@code @param DocTree}.
|
||||
*/
|
||||
private Content processParamTags(Element e, boolean isParams,
|
||||
private Content processParamTags(Element e, ParamKind kind,
|
||||
List<? extends DocTree> paramTags, Map<String, String> rankMap, TagletWriter writer,
|
||||
Set<String> alreadyDocumented) {
|
||||
Messages messages = writer.configuration().getMessages();
|
||||
|
@ -238,26 +251,33 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
|
|||
if (!paramTags.isEmpty()) {
|
||||
CommentHelper ch = writer.configuration().utils.getCommentHelper(e);
|
||||
for (DocTree dt : paramTags) {
|
||||
String paramName = isParams
|
||||
? ch.getParameterName(dt)
|
||||
: "<" + ch.getParameterName(dt) + ">";
|
||||
if (!rankMap.containsKey(ch.getParameterName(dt))) {
|
||||
messages.warning(ch.getDocTreePath(dt),
|
||||
isParams
|
||||
? "doclet.Parameters_warn"
|
||||
: "doclet.Type_Parameters_warn",
|
||||
paramName);
|
||||
String name = ch.getParameterName(dt);
|
||||
String paramName = kind != ParamKind.TYPE_PARAMETER
|
||||
? name.toString()
|
||||
: "<" + name + ">";
|
||||
if (!rankMap.containsKey(name)) {
|
||||
String key;
|
||||
switch (kind) {
|
||||
case PARAMETER: key = "doclet.Parameters_warn" ; break;
|
||||
case TYPE_PARAMETER: key = "doclet.TypeParameters_warn" ; break;
|
||||
case RECORD_COMPONENT: key = "doclet.RecordComponents_warn" ; break;
|
||||
default: throw new IllegalArgumentException(kind.toString());
|
||||
}
|
||||
String rank = rankMap.get(ch.getParameterName(dt));
|
||||
messages.warning(ch.getDocTreePath(dt), key, paramName);
|
||||
}
|
||||
String rank = rankMap.get(name);
|
||||
if (rank != null && alreadyDocumented.contains(rank)) {
|
||||
messages.warning(ch.getDocTreePath(dt),
|
||||
isParams
|
||||
? "doclet.Parameters_dup_warn"
|
||||
: "doclet.Type_Parameters_dup_warn",
|
||||
paramName);
|
||||
String key;
|
||||
switch (kind) {
|
||||
case PARAMETER: key = "doclet.Parameters_dup_warn" ; break;
|
||||
case TYPE_PARAMETER: key = "doclet.TypeParameters_dup_warn" ; break;
|
||||
case RECORD_COMPONENT: key = "doclet.RecordComponents_dup_warn" ; break;
|
||||
default: throw new IllegalArgumentException(kind.toString());
|
||||
}
|
||||
result.add(processParamTag(e, isParams, writer, dt,
|
||||
ch.getParameterName(dt), alreadyDocumented.isEmpty()));
|
||||
messages.warning(ch.getDocTreePath(dt), key, paramName);
|
||||
}
|
||||
result.add(processParamTag(e, kind, writer, dt,
|
||||
name, alreadyDocumented.isEmpty()));
|
||||
alreadyDocumented.add(rank);
|
||||
}
|
||||
}
|
||||
|
@ -268,8 +288,7 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
|
|||
* Convert the individual ParamTag into Content.
|
||||
*
|
||||
* @param e the owner element
|
||||
* @param isParams true if this is just a regular param tag. False
|
||||
* if this is a type param tag.
|
||||
* @param kind the kind of param tag
|
||||
* @param writer the taglet writer for output writing.
|
||||
* @param paramTag the tag whose inline tags will be printed.
|
||||
* @param name the name of the parameter. We can't rely on
|
||||
|
@ -278,13 +297,19 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
|
|||
* @param isFirstParam true if this is the first param tag being printed.
|
||||
*
|
||||
*/
|
||||
private Content processParamTag(Element e, boolean isParams,
|
||||
private Content processParamTag(Element e, ParamKind kind,
|
||||
TagletWriter writer, DocTree paramTag, String name,
|
||||
boolean isFirstParam) {
|
||||
Content result = writer.getOutputInstance();
|
||||
String header = writer.configuration().getResources().getText(
|
||||
isParams ? "doclet.Parameters" : "doclet.TypeParameters");
|
||||
if (isFirstParam) {
|
||||
String key;
|
||||
switch (kind) {
|
||||
case PARAMETER: key = "doclet.Parameters" ; break;
|
||||
case TYPE_PARAMETER: key = "doclet.TypeParameters" ; break;
|
||||
case RECORD_COMPONENT: key = "doclet.RecordComponents" ; break;
|
||||
default: throw new IllegalArgumentException(kind.toString());
|
||||
}
|
||||
String header = writer.configuration().getResources().getText(key);
|
||||
result.add(writer.getParamHeader(header));
|
||||
}
|
||||
result.add(writer.paramTagOutput(e, paramTag, name));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2019, 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
|
||||
|
@ -34,7 +34,7 @@ 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.util.SimpleElementVisitor9;
|
||||
import javax.lang.model.util.SimpleElementVisitor14;
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
|
||||
|
@ -333,6 +333,7 @@ public class TagletManager {
|
|||
* @param trees the trees containing the comments
|
||||
* @param areInlineTags true if the array of tags are inline and false otherwise.
|
||||
*/
|
||||
@SuppressWarnings("preview")
|
||||
public void checkTags(Element element, Iterable<? extends DocTree> trees, boolean areInlineTags) {
|
||||
if (trees == null) {
|
||||
return;
|
||||
|
@ -365,7 +366,7 @@ public class TagletManager {
|
|||
if (element == null) {
|
||||
return;
|
||||
}
|
||||
new SimpleElementVisitor9<Void, Void>() {
|
||||
new SimpleElementVisitor14<Void, Void>() {
|
||||
@Override
|
||||
public Void visitModule(ModuleElement e, Void p) {
|
||||
if (!taglet.inModule()) {
|
||||
|
@ -521,6 +522,7 @@ public class TagletManager {
|
|||
case INTERFACE:
|
||||
case CLASS:
|
||||
case ENUM:
|
||||
case RECORD:
|
||||
return blockTagletsBySite.get(Site.TYPE);
|
||||
case MODULE:
|
||||
return blockTagletsBySite.get(Site.MODULE);
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
package jdk.javadoc.internal.doclets.toolkit.taglets;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
|
@ -233,8 +232,8 @@ public abstract class TagletWriter {
|
|||
tagletManager.checkTags(element, utils.getFullBody(element), true);
|
||||
for (Taglet taglet : taglets) {
|
||||
if (utils.isTypeElement(element) && taglet instanceof ParamTaglet) {
|
||||
//The type parameters are documented in a special section away
|
||||
//from the tag info, so skip here.
|
||||
// The type parameters and state components are documented in a special
|
||||
// section away from the tag info, so skip here.
|
||||
continue;
|
||||
}
|
||||
if (taglet instanceof DeprecatedTaglet) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2019, 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
|
||||
|
@ -41,7 +41,7 @@ import javax.lang.model.type.TypeVariable;
|
|||
import javax.lang.model.type.WildcardType;
|
||||
import javax.lang.model.util.ElementFilter;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.SimpleElementVisitor9;
|
||||
import javax.lang.model.util.SimpleElementVisitor14;
|
||||
import javax.lang.model.util.SimpleTypeVisitor9;
|
||||
import javax.lang.model.util.Types;
|
||||
|
||||
|
@ -483,8 +483,9 @@ public class ClassUseMapper {
|
|||
private <T extends Element> void mapTypeParameters(final Map<TypeElement, List<T>> map,
|
||||
Element element, final T holder) {
|
||||
|
||||
SimpleElementVisitor9<Void, Void> elementVisitor
|
||||
= new SimpleElementVisitor9<Void, Void>() {
|
||||
@SuppressWarnings("preview")
|
||||
SimpleElementVisitor14<Void, Void> elementVisitor
|
||||
= new SimpleElementVisitor14<Void, Void>() {
|
||||
|
||||
private void addParameters(TypeParameterElement e) {
|
||||
for (TypeMirror type : utils.getBounds(e)) {
|
||||
|
@ -560,9 +561,10 @@ public class ClassUseMapper {
|
|||
* @param e whose type parameters are being checked.
|
||||
* @param holder owning the type parameters.
|
||||
*/
|
||||
@SuppressWarnings("preview")
|
||||
private <T extends Element> void mapAnnotations(final Map<TypeElement, List<T>> map,
|
||||
Element e, final T holder) {
|
||||
new SimpleElementVisitor9<Void, Void>() {
|
||||
new SimpleElementVisitor14<Void, Void>() {
|
||||
|
||||
void addAnnotations(Element e) {
|
||||
for (AnnotationMirror a : e.getAnnotationMirrors()) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2019, 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
|
||||
|
@ -32,6 +32,7 @@ import java.util.List;
|
|||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.ModuleElement;
|
||||
import javax.lang.model.element.Name;
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
|
@ -99,7 +100,7 @@ public class CommentHelper {
|
|||
|
||||
public void setOverrideElement(Element ove) {
|
||||
if (this.element == ove) {
|
||||
throw new AssertionError("cannot set given element as overriden element");
|
||||
throw new AssertionError("cannot set given element as overridden element");
|
||||
}
|
||||
overriddenElement = ove;
|
||||
}
|
||||
|
@ -147,6 +148,9 @@ public class CommentHelper {
|
|||
Element getElement(BaseConfiguration c, ReferenceTree rtree) {
|
||||
// likely a synthesized tree
|
||||
if (path == null) {
|
||||
// NOTE: this code path only supports module/package/type signatures
|
||||
// and not member signatures. For more complete support,
|
||||
// set a suitable path and avoid this branch.
|
||||
TypeMirror symbol = c.utils.getSymbol(rtree.getSignature());
|
||||
if (symbol == null) {
|
||||
return null;
|
||||
|
@ -547,7 +551,7 @@ public class CommentHelper {
|
|||
return new SimpleDocTreeVisitor<List<? extends DocTree>, Void>() {
|
||||
List<? extends DocTree> asList(String content) {
|
||||
List<DocTree> out = new ArrayList<>();
|
||||
out.add((TextTree)c.cmtUtils.makeTextTree(content));
|
||||
out.add(c.cmtUtils.makeTextTree(content));
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2019, 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
|
||||
|
@ -73,6 +73,11 @@ public class TypeElementCatalog {
|
|||
*/
|
||||
private final Map<PackageElement, SortedSet<TypeElement>> enums;
|
||||
|
||||
/**
|
||||
* Stores records for each package.
|
||||
*/
|
||||
private final Map<PackageElement, SortedSet<TypeElement>> records;
|
||||
|
||||
/**
|
||||
* Stores annotation types for each package.
|
||||
*/
|
||||
|
@ -116,6 +121,7 @@ public class TypeElementCatalog {
|
|||
ordinaryClasses = new HashMap<>();
|
||||
exceptions = new HashMap<>();
|
||||
enums = new HashMap<>();
|
||||
records = new HashMap<>();
|
||||
annotationTypes = new HashMap<>();
|
||||
errors = new HashMap<>();
|
||||
interfaces = new HashMap<>();
|
||||
|
@ -138,6 +144,8 @@ public class TypeElementCatalog {
|
|||
addTypeElement(typeElement, exceptions);
|
||||
} else if (utils.isEnum(typeElement)) {
|
||||
addTypeElement(typeElement, enums);
|
||||
} else if (utils.isRecord(typeElement)) {
|
||||
addTypeElement(typeElement, records);
|
||||
} else if (utils.isAnnotationType(typeElement)) {
|
||||
addTypeElement(typeElement, annotationTypes);
|
||||
} else if (utils.isError(typeElement)) {
|
||||
|
@ -191,9 +199,7 @@ public class TypeElementCatalog {
|
|||
}
|
||||
|
||||
/**
|
||||
* Return all of the classes specified on the command-line that belong to the given package.
|
||||
*
|
||||
* @param packageName the name of the package specified on the command-line.
|
||||
* Return all of the classes specified on the command-line that belong to the unnamed package.
|
||||
*/
|
||||
public SortedSet<TypeElement> allUnnamedClasses() {
|
||||
for (PackageElement pkg : allClasses.keySet()) {
|
||||
|
@ -214,7 +220,7 @@ public class TypeElementCatalog {
|
|||
/**
|
||||
* Return all of the errors specified on the command-line that belong to the given package.
|
||||
*
|
||||
* @param packageName the name of the package specified on the command-line.
|
||||
* @param pkg the name of the package specified on the command-line.
|
||||
*/
|
||||
public SortedSet<TypeElement> errors(PackageElement pkg) {
|
||||
return getSet(errors, pkg);
|
||||
|
@ -223,7 +229,7 @@ public class TypeElementCatalog {
|
|||
/**
|
||||
* Return all of the exceptions specified on the command-line that belong to the given package.
|
||||
*
|
||||
* @param packageName the name of the package specified on the command-line.
|
||||
* @param pkg the name of the package specified on the command-line.
|
||||
*/
|
||||
public SortedSet<TypeElement> exceptions(PackageElement pkg) {
|
||||
return getSet(exceptions, pkg);
|
||||
|
@ -232,17 +238,26 @@ public class TypeElementCatalog {
|
|||
/**
|
||||
* Return all of the enums specified on the command-line that belong to the given package.
|
||||
*
|
||||
* @param packageName the name of the package specified on the command-line.
|
||||
* @param pkg the name of the package specified on the command-line.
|
||||
*/
|
||||
public SortedSet<TypeElement> enums(PackageElement pkg) {
|
||||
return getSet(enums, pkg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all of the records specified on the command-line that belong to the given package.
|
||||
*
|
||||
* @param pkg the name of the package specified on the command-line.
|
||||
*/
|
||||
public SortedSet<TypeElement> records(PackageElement pkg) {
|
||||
return getSet(records, pkg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all of the annotation types specified on the command-line that belong to the given
|
||||
* package.
|
||||
*
|
||||
* @param packageName the name of the package specified on the command-line.
|
||||
* @param pkg the name of the package specified on the command-line.
|
||||
*/
|
||||
public SortedSet<TypeElement> annotationTypes(PackageElement pkg) {
|
||||
return getSet(annotationTypes, pkg);
|
||||
|
@ -251,7 +266,7 @@ public class TypeElementCatalog {
|
|||
/**
|
||||
* Return all of the interfaces specified on the command-line that belong to the given package.
|
||||
*
|
||||
* @param packageName the name of the package specified on the command-line.
|
||||
* @param pkg the name of the package specified on the command-line.
|
||||
*/
|
||||
public SortedSet<TypeElement> interfaces(PackageElement pkg) {
|
||||
return getSet(interfaces, pkg);
|
||||
|
@ -261,7 +276,7 @@ public class TypeElementCatalog {
|
|||
* Return all of the ordinary classes specified on the command-line that belong to the given
|
||||
* package.
|
||||
*
|
||||
* @param packageName the name of the package specified on the command-line.
|
||||
* @param pkg the name of the package specified on the command-line.
|
||||
*/
|
||||
public SortedSet<TypeElement> ordinaryClasses(PackageElement pkg) {
|
||||
return getSet(ordinaryClasses, pkg);
|
||||
|
|
|
@ -47,6 +47,7 @@ import javax.lang.model.element.Modifier;
|
|||
import javax.lang.model.element.ModuleElement;
|
||||
import javax.lang.model.element.ModuleElement.RequiresDirective;
|
||||
import javax.lang.model.element.PackageElement;
|
||||
import javax.lang.model.element.RecordComponentElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.TypeParameterElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
|
@ -60,9 +61,9 @@ 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.ElementKindVisitor9;
|
||||
import javax.lang.model.util.ElementKindVisitor14;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.SimpleElementVisitor9;
|
||||
import javax.lang.model.util.SimpleElementVisitor14;
|
||||
import javax.lang.model.util.SimpleTypeVisitor9;
|
||||
import javax.lang.model.util.TypeKindVisitor9;
|
||||
import javax.lang.model.util.Types;
|
||||
|
@ -301,8 +302,9 @@ public class Utils {
|
|||
return !e.getAnnotationMirrors().isEmpty();
|
||||
}
|
||||
|
||||
@SuppressWarnings("preview")
|
||||
public boolean isAnnotationType(Element e) {
|
||||
return new SimpleElementVisitor9<Boolean, Void>() {
|
||||
return new SimpleElementVisitor14<Boolean, Void>() {
|
||||
@Override
|
||||
public Boolean visitExecutable(ExecutableElement e, Void p) {
|
||||
return visit(e.getEnclosingElement());
|
||||
|
@ -416,6 +418,34 @@ public class Utils {
|
|||
return typeUtils.isSubtype(e.asType(), getExternalizableType());
|
||||
}
|
||||
|
||||
@SuppressWarnings("preview")
|
||||
public boolean isRecord(TypeElement e) {
|
||||
return e.getKind() == ElementKind.RECORD;
|
||||
}
|
||||
|
||||
@SuppressWarnings("preview")
|
||||
public boolean isCanonicalRecordConstructor(ExecutableElement ee) {
|
||||
TypeElement te = (TypeElement) ee.getEnclosingElement();
|
||||
List<? extends RecordComponentElement> stateComps = te.getRecordComponents();
|
||||
List<? extends VariableElement> params = ee.getParameters();
|
||||
if (stateComps.size() != params.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Iterator<? extends RecordComponentElement> stateIter = stateComps.iterator();
|
||||
Iterator<? extends VariableElement> paramIter = params.iterator();
|
||||
while (paramIter.hasNext() && stateIter.hasNext()) {
|
||||
VariableElement param = paramIter.next();
|
||||
RecordComponentElement comp = stateIter.next();
|
||||
if (!Objects.equals(param.getSimpleName(), comp.getSimpleName())
|
||||
|| !typeUtils.isSameType(param.asType(), comp.asType())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public SortedSet<VariableElement> serializableFields(TypeElement aclass) {
|
||||
return configuration.workArounds.getSerializableFields(aclass);
|
||||
}
|
||||
|
@ -428,85 +458,93 @@ public class Utils {
|
|||
return configuration.workArounds.definesSerializableFields( aclass);
|
||||
}
|
||||
|
||||
@SuppressWarnings("preview")
|
||||
public String modifiersToString(Element e, boolean trailingSpace) {
|
||||
SortedSet<Modifier> set = new TreeSet<>(e.getModifiers());
|
||||
set.remove(Modifier.NATIVE);
|
||||
set.remove(Modifier.STRICTFP);
|
||||
set.remove(Modifier.SYNCHRONIZED);
|
||||
SortedSet<Modifier> modifiers = new TreeSet<>(e.getModifiers());
|
||||
modifiers.remove(NATIVE);
|
||||
modifiers.remove(STRICTFP);
|
||||
modifiers.remove(SYNCHRONIZED);
|
||||
|
||||
return new ElementKindVisitor9<String, SortedSet<Modifier>>() {
|
||||
return new ElementKindVisitor14<String, SortedSet<Modifier>>() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
void addVisibilityModifier(Set<Modifier> modifiers) {
|
||||
if (modifiers.contains(PUBLIC)) {
|
||||
sb.append("public").append(" ");
|
||||
append("public");
|
||||
} else if (modifiers.contains(PROTECTED)) {
|
||||
sb.append("protected").append(" ");
|
||||
append("protected");
|
||||
} else if (modifiers.contains(PRIVATE)) {
|
||||
sb.append("private").append(" ");
|
||||
append("private");
|
||||
}
|
||||
}
|
||||
|
||||
void addStatic(Set<Modifier> modifiers) {
|
||||
if (modifiers.contains(STATIC)) {
|
||||
sb.append("static").append(" ");
|
||||
append("static");
|
||||
}
|
||||
}
|
||||
|
||||
void addModifers(Set<Modifier> modifiers) {
|
||||
String s = set.stream().map(Modifier::toString).collect(Collectors.joining(" "));
|
||||
sb.append(s);
|
||||
if (!s.isEmpty())
|
||||
void addModifiers(Set<Modifier> modifiers) {
|
||||
modifiers.stream().map(Modifier::toString).forEach(this::append);
|
||||
}
|
||||
|
||||
void append(String s) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append(s);
|
||||
}
|
||||
|
||||
String finalString(String s) {
|
||||
sb.append(s);
|
||||
append(s);
|
||||
if (trailingSpace) {
|
||||
if (sb.lastIndexOf(" ") == sb.length() - 1) {
|
||||
return sb.toString();
|
||||
} else {
|
||||
return sb.append(" ").toString();
|
||||
sb.append(" ");
|
||||
}
|
||||
} else {
|
||||
return sb.toString().trim();
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitTypeAsInterface(TypeElement e, SortedSet<Modifier> p) {
|
||||
addVisibilityModifier(p);
|
||||
addStatic(p);
|
||||
public String visitTypeAsInterface(TypeElement e, SortedSet<Modifier> mods) {
|
||||
addVisibilityModifier(mods);
|
||||
addStatic(mods);
|
||||
return finalString("interface");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitTypeAsEnum(TypeElement e, SortedSet<Modifier> p) {
|
||||
addVisibilityModifier(p);
|
||||
addStatic(p);
|
||||
public String visitTypeAsEnum(TypeElement e, SortedSet<Modifier> mods) {
|
||||
addVisibilityModifier(mods);
|
||||
addStatic(mods);
|
||||
return finalString("enum");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitTypeAsAnnotationType(TypeElement e, SortedSet<Modifier> p) {
|
||||
addVisibilityModifier(p);
|
||||
addStatic(p);
|
||||
public String visitTypeAsAnnotationType(TypeElement e, SortedSet<Modifier> mods) {
|
||||
addVisibilityModifier(mods);
|
||||
addStatic(mods);
|
||||
return finalString("@interface");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String visitTypeAsClass(TypeElement e, SortedSet<Modifier> p) {
|
||||
addModifers(p);
|
||||
return finalString("class");
|
||||
public String visitTypeAsRecord(TypeElement e, SortedSet<Modifier> mods) {
|
||||
mods.remove(FINAL); // suppress the implicit `final`
|
||||
return visitTypeAsClass(e, mods);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String defaultAction(Element e, SortedSet<Modifier> p) {
|
||||
addModifers(p);
|
||||
@SuppressWarnings("preview")
|
||||
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, set);
|
||||
}.visit(e, modifiers);
|
||||
}
|
||||
|
||||
public boolean isFunctionalInterface(AnnotationMirror amirror) {
|
||||
|
@ -593,7 +631,7 @@ public class Utils {
|
|||
|
||||
public boolean isTypeElement(Element e) {
|
||||
switch (e.getKind()) {
|
||||
case CLASS: case ENUM: case INTERFACE: case ANNOTATION_TYPE:
|
||||
case CLASS: case ENUM: case INTERFACE: case ANNOTATION_TYPE: case RECORD:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -1362,27 +1400,6 @@ public class Utils {
|
|||
return sb;
|
||||
}
|
||||
|
||||
/**
|
||||
* The documentation for values() and valueOf() in Enums are set by the
|
||||
* doclet only iff the user or overridden methods are missing.
|
||||
* @param elem
|
||||
*/
|
||||
public void setEnumDocumentation(TypeElement elem) {
|
||||
for (Element e : getMethods(elem)) {
|
||||
ExecutableElement ee = (ExecutableElement)e;
|
||||
if (!getFullBody(e).isEmpty()) // ignore if already set
|
||||
continue;
|
||||
if (ee.getSimpleName().contentEquals("values") && ee.getParameters().isEmpty()) {
|
||||
removeCommentHelper(ee); // purge previous entry
|
||||
configuration.cmtUtils.setEnumValuesTree(e);
|
||||
}
|
||||
if (ee.getSimpleName().contentEquals("valueOf") && ee.getParameters().size() == 1) {
|
||||
removeCommentHelper(ee); // purge previous entry
|
||||
configuration.cmtUtils.setEnumValueOfTree(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a locale independent upper cased String. That is, it
|
||||
* always uses US locale, this is a clone of the one in StringUtils.
|
||||
|
@ -1760,7 +1777,7 @@ public class Utils {
|
|||
result = compareStrings(getFullyQualifiedName(o1), getFullyQualifiedName(o2));
|
||||
if (result != 0)
|
||||
return result;
|
||||
return compareElementTypeKinds(o1, o2);
|
||||
return compareElementKinds(o1, o2);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1809,7 +1826,7 @@ public class Utils {
|
|||
return result;
|
||||
}
|
||||
// if names are the same, compare element kinds
|
||||
result = compareElementTypeKinds(e1, e2);
|
||||
result = compareElementKinds(e1, e2);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
|
@ -1917,8 +1934,9 @@ public class Utils {
|
|||
return getFullyQualifiedName(e, true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("preview")
|
||||
public String getFullyQualifiedName(Element e, final boolean outer) {
|
||||
return new SimpleElementVisitor9<String, Void>() {
|
||||
return new SimpleElementVisitor14<String, Void>() {
|
||||
@Override
|
||||
public String visitModule(ModuleElement e, Void p) {
|
||||
return e.getQualifiedName().toString();
|
||||
|
@ -1985,7 +2003,7 @@ public class Utils {
|
|||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
return compareElementTypeKinds(e1, e2);
|
||||
return compareElementKinds(e1, e2);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1997,6 +2015,8 @@ public class Utils {
|
|||
* 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.
|
||||
|
@ -2005,21 +2025,6 @@ public class Utils {
|
|||
* @return a negative integer, zero, or a positive integer as the first
|
||||
* argument is less than, equal to, or greater than the second.
|
||||
*/
|
||||
final EnumMap<ElementKind, Integer> elementKindOrder;
|
||||
public ElementComparator() {
|
||||
elementKindOrder = new EnumMap<>(ElementKind.class);
|
||||
elementKindOrder.put(ElementKind.MODULE, 0);
|
||||
elementKindOrder.put(ElementKind.PACKAGE, 1);
|
||||
elementKindOrder.put(ElementKind.CLASS, 2);
|
||||
elementKindOrder.put(ElementKind.ENUM, 3);
|
||||
elementKindOrder.put(ElementKind.ENUM_CONSTANT, 4);
|
||||
elementKindOrder.put(ElementKind.INTERFACE, 5);
|
||||
elementKindOrder.put(ElementKind.ANNOTATION_TYPE, 6);
|
||||
elementKindOrder.put(ElementKind.FIELD, 7);
|
||||
elementKindOrder.put(ElementKind.CONSTRUCTOR, 8);
|
||||
elementKindOrder.put(ElementKind.METHOD, 9);
|
||||
}
|
||||
|
||||
protected int compareParameters(boolean caseSensitive, List<? extends VariableElement> params1,
|
||||
List<? extends VariableElement> params2) {
|
||||
|
||||
|
@ -2082,12 +2087,31 @@ public class Utils {
|
|||
String thatElement = getFullyQualifiedName(e2);
|
||||
return compareStrings(thisElement, thatElement);
|
||||
}
|
||||
protected int compareElementTypeKinds(Element e1, Element e2) {
|
||||
return Integer.compare(elementKindOrder.get(e1.getKind()),
|
||||
elementKindOrder.get(e2.getKind()));
|
||||
|
||||
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 SimpleElementVisitor9<Boolean, Void>() {
|
||||
return new SimpleElementVisitor14<Boolean, Void>() {
|
||||
@Override
|
||||
public Boolean visitExecutable(ExecutableElement e, Void p) {
|
||||
return true;
|
||||
|
@ -2107,8 +2131,9 @@ public class Utils {
|
|||
* @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 SimpleElementVisitor9<String, Void>() {
|
||||
return new SimpleElementVisitor14<String, Void>() {
|
||||
@Override
|
||||
public String visitModule(ModuleElement e, Void p) {
|
||||
return e.getQualifiedName().toString();
|
||||
|
@ -2187,6 +2212,7 @@ public class Utils {
|
|||
out.addAll(getClasses(pkg));
|
||||
out.addAll(getEnums(pkg));
|
||||
out.addAll(getAnnotationTypes(pkg));
|
||||
out.addAll(getRecords(pkg));
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -2217,6 +2243,16 @@ public class Utils {
|
|||
return convertToTypeElement(getItems(e, false, ANNOTATION_TYPE));
|
||||
}
|
||||
|
||||
@SuppressWarnings("preview")
|
||||
public List<TypeElement> getRecords(Element e) {
|
||||
return convertToTypeElement(getItems(e, true, RECORD));
|
||||
}
|
||||
|
||||
@SuppressWarnings("preview")
|
||||
public List<TypeElement> getRecordsUnfiltered(Element e) {
|
||||
return convertToTypeElement(getItems(e, false, RECORD));
|
||||
}
|
||||
|
||||
public List<VariableElement> getFields(Element e) {
|
||||
return convertToVariableElement(getItems(e, true, FIELD));
|
||||
}
|
||||
|
@ -2371,6 +2407,7 @@ public class Utils {
|
|||
List<TypeElement> clist = getClassesUnfiltered(e);
|
||||
clist.addAll(getInterfacesUnfiltered(e));
|
||||
clist.addAll(getAnnotationTypesUnfiltered(e));
|
||||
clist.addAll(getRecordsUnfiltered(e));
|
||||
SortedSet<TypeElement> oset = new TreeSet<>(makeGeneralPurposeComparator());
|
||||
oset.addAll(clist);
|
||||
return oset;
|
||||
|
@ -2391,6 +2428,7 @@ public class Utils {
|
|||
clist.addAll(getInterfaces(e));
|
||||
clist.addAll(getAnnotationTypes(e));
|
||||
clist.addAll(getEnums(e));
|
||||
clist.addAll(getRecords(e));
|
||||
oset = new TreeSet<>(makeGeneralPurposeComparator());
|
||||
oset.addAll(clist);
|
||||
cachedClasses.put(e, oset);
|
||||
|
@ -2459,9 +2497,10 @@ public class Utils {
|
|||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@SuppressWarnings("preview")
|
||||
List<Element> getItems(Element e, boolean filter, ElementKind select) {
|
||||
List<Element> elements = new ArrayList<>();
|
||||
return new SimpleElementVisitor9<List<Element>, Void>() {
|
||||
return new SimpleElementVisitor14<List<Element>, Void>() {
|
||||
|
||||
@Override
|
||||
public List<Element> visitPackage(PackageElement e, Void p) {
|
||||
|
@ -2506,11 +2545,13 @@ public class Utils {
|
|||
return elements;
|
||||
}
|
||||
|
||||
private SimpleElementVisitor9<Boolean, Void> shouldDocumentVisitor = null;
|
||||
@SuppressWarnings("preview")
|
||||
private SimpleElementVisitor14<Boolean, Void> shouldDocumentVisitor = null;
|
||||
|
||||
protected boolean shouldDocument(Element e) {
|
||||
@SuppressWarnings("preview")
|
||||
public boolean shouldDocument(Element e) {
|
||||
if (shouldDocumentVisitor == null) {
|
||||
shouldDocumentVisitor = new SimpleElementVisitor9<Boolean, Void>() {
|
||||
shouldDocumentVisitor = new SimpleElementVisitor14<Boolean, Void>() {
|
||||
private boolean hasSource(TypeElement e) {
|
||||
return configuration.docEnv.getFileKind(e) ==
|
||||
javax.tools.JavaFileObject.Kind.SOURCE;
|
||||
|
@ -2560,11 +2601,13 @@ public class Utils {
|
|||
return nameCache.computeIfAbsent(e, this::getSimpleName0);
|
||||
}
|
||||
|
||||
private SimpleElementVisitor9<String, Void> snvisitor = null;
|
||||
@SuppressWarnings("preview")
|
||||
private SimpleElementVisitor14<String, Void> snvisitor = null;
|
||||
|
||||
@SuppressWarnings("preview")
|
||||
private String getSimpleName0(Element e) {
|
||||
if (snvisitor == null) {
|
||||
snvisitor = new SimpleElementVisitor9<String, Void>() {
|
||||
snvisitor = new SimpleElementVisitor14<String, Void>() {
|
||||
@Override
|
||||
public String visitModule(ModuleElement e, Void p) {
|
||||
return e.getQualifiedName().toString(); // temp fix for 8182736
|
||||
|
@ -2745,10 +2788,12 @@ public class Utils {
|
|||
return configuration.docEnv.isIncluded(e);
|
||||
}
|
||||
|
||||
private SimpleElementVisitor9<Boolean, Void> specifiedVisitor = null;
|
||||
@SuppressWarnings("preview")
|
||||
private SimpleElementVisitor14<Boolean, Void> specifiedVisitor = null;
|
||||
@SuppressWarnings("preview")
|
||||
public boolean isSpecified(Element e) {
|
||||
if (specifiedVisitor == null) {
|
||||
specifiedVisitor = new SimpleElementVisitor9<Boolean, Void>() {
|
||||
specifiedVisitor = new SimpleElementVisitor14<Boolean, Void>() {
|
||||
@Override
|
||||
public Boolean visitModule(ModuleElement e, Void p) {
|
||||
return configuration.getSpecifiedModuleElements().contains(e);
|
||||
|
@ -3196,20 +3241,20 @@ public class Utils {
|
|||
return getBlockTags(element, DocTree.Kind.EXCEPTION, DocTree.Kind.THROWS);
|
||||
}
|
||||
|
||||
public List<? extends DocTree> getTypeParamTrees(Element element) {
|
||||
public List<? extends ParamTree> getTypeParamTrees(Element element) {
|
||||
return getParamTrees(element, true);
|
||||
}
|
||||
|
||||
public List<? extends DocTree> getParamTrees(Element element) {
|
||||
public List<? extends ParamTree> getParamTrees(Element element) {
|
||||
return getParamTrees(element, false);
|
||||
}
|
||||
|
||||
private List<? extends DocTree> getParamTrees(Element element, boolean isTypeParameters) {
|
||||
List<DocTree> out = new ArrayList<>();
|
||||
private List<? extends ParamTree> getParamTrees(Element element, boolean isTypeParameters) {
|
||||
List<ParamTree> out = new ArrayList<>();
|
||||
for (DocTree dt : getBlockTags(element, PARAM)) {
|
||||
ParamTree pt = (ParamTree) dt;
|
||||
if (pt.isTypeParameter() == isTypeParameters) {
|
||||
out.add(dt);
|
||||
out.add(pt);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
|
|
|
@ -32,7 +32,7 @@ import javax.lang.model.element.VariableElement;
|
|||
import javax.lang.model.type.TypeKind;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.SimpleElementVisitor9;
|
||||
import javax.lang.model.util.SimpleElementVisitor14;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -666,6 +666,7 @@ public class VisibleMemberTable {
|
|||
case INTERFACE:
|
||||
case ENUM:
|
||||
case ANNOTATION_TYPE:
|
||||
case RECORD:
|
||||
addMember(e, Kind.INNER_CLASSES);
|
||||
break;
|
||||
case FIELD:
|
||||
|
@ -700,8 +701,9 @@ public class VisibleMemberTable {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("preview")
|
||||
String getMemberKey(Element e) {
|
||||
return new SimpleElementVisitor9<String, Void>() {
|
||||
return new SimpleElementVisitor14<String, Void>() {
|
||||
@Override
|
||||
public String visitExecutable(ExecutableElement e, Void aVoid) {
|
||||
return e.getSimpleName() + ":" + e.getParameters().size();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2019, 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
|
||||
|
@ -47,7 +47,7 @@ import javax.lang.model.element.ModuleElement.RequiresDirective;
|
|||
import javax.lang.model.element.PackageElement;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.util.ElementFilter;
|
||||
import javax.lang.model.util.SimpleElementVisitor9;
|
||||
import javax.lang.model.util.SimpleElementVisitor14;
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileManager.Location;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
@ -985,7 +985,8 @@ public class ElementsTable {
|
|||
return (xclasses || toolEnv.getFileKind(te) == SOURCE) && isSelected(te);
|
||||
}
|
||||
|
||||
SimpleElementVisitor9<Boolean, Void> visibleElementVisitor = null;
|
||||
@SuppressWarnings("preview")
|
||||
SimpleElementVisitor14<Boolean, Void> visibleElementVisitor = null;
|
||||
/**
|
||||
* Returns true if the element is selected, by applying
|
||||
* the access filter checks. Special treatment is applied to
|
||||
|
@ -996,12 +997,13 @@ public class ElementsTable {
|
|||
* @param e the element to be checked
|
||||
* @return true if the element is visible
|
||||
*/
|
||||
@SuppressWarnings("preview")
|
||||
public boolean isSelected(Element e) {
|
||||
if (toolEnv.isSynthetic((Symbol) e)) {
|
||||
return false;
|
||||
}
|
||||
if (visibleElementVisitor == null) {
|
||||
visibleElementVisitor = new SimpleElementVisitor9<Boolean, Void>() {
|
||||
visibleElementVisitor = new SimpleElementVisitor14<Boolean, Void>() {
|
||||
@Override
|
||||
public Boolean visitType(TypeElement e, Void p) {
|
||||
if (!accessFilter.checkModifier(e)) {
|
||||
|
@ -1035,7 +1037,8 @@ public class ElementsTable {
|
|||
return visibleElementVisitor.visit(e);
|
||||
}
|
||||
|
||||
private class IncludedVisitor extends SimpleElementVisitor9<Boolean, Void> {
|
||||
@SuppressWarnings("preview")
|
||||
private class IncludedVisitor extends SimpleElementVisitor14<Boolean, Void> {
|
||||
final private Set<Element> includedCache;
|
||||
|
||||
public IncludedVisitor() {
|
||||
|
@ -1200,7 +1203,7 @@ public class ElementsTable {
|
|||
ElementKind.PACKAGE,
|
||||
ElementKind.MODULE);
|
||||
|
||||
// all possible accesss levels allowed for each element
|
||||
// all possible access levels allowed for each element
|
||||
private final EnumMap<ElementKind, EnumSet<AccessKind>> filterMap =
|
||||
new EnumMap<>(ElementKind.class);
|
||||
|
||||
|
@ -1285,7 +1288,7 @@ public class ElementsTable {
|
|||
switch (kind) {
|
||||
case CLASS: case METHOD: case MODULE: case PACKAGE:
|
||||
return kind;
|
||||
case ANNOTATION_TYPE: case ENUM: case INTERFACE:
|
||||
case RECORD: case ANNOTATION_TYPE: case ENUM: case INTERFACE:
|
||||
return ElementKind.CLASS;
|
||||
case CONSTRUCTOR: case ENUM_CONSTANT: case EXCEPTION_PARAMETER:
|
||||
case FIELD: case INSTANCE_INIT: case LOCAL_VARIABLE: case PARAMETER:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2019, 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
|
||||
|
@ -31,7 +31,10 @@ import com.sun.tools.javac.code.Symbol.*;
|
|||
import com.sun.tools.javac.comp.MemberEnter;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.JCTree.*;
|
||||
import com.sun.tools.javac.tree.TreeInfo;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.List;
|
||||
import com.sun.tools.javac.util.Names;
|
||||
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
import static com.sun.tools.javac.code.Kinds.Kind.*;
|
||||
|
@ -61,6 +64,7 @@ public class JavadocMemberEnter extends MemberEnter {
|
|||
|
||||
final ToolEnvironment toolEnv;
|
||||
|
||||
|
||||
protected JavadocMemberEnter(Context context) {
|
||||
super(context);
|
||||
toolEnv = ToolEnvironment.instance(context);
|
||||
|
@ -79,7 +83,12 @@ public class JavadocMemberEnter extends MemberEnter {
|
|||
toolEnv.setElementToTreePath(meth, treePath);
|
||||
}
|
||||
// release resources
|
||||
// handle constructors for record types specially, because of downstream checks
|
||||
if ((env.enclClass.mods.flags & Flags.RECORD) != 0 && TreeInfo.isConstructor(tree)) {
|
||||
tree.body.stats = List.nil();
|
||||
} else {
|
||||
tree.body = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue