8235306: Support doc-comment tags that can be inline or block tags
Reviewed-by: hannesw
This commit is contained in:
parent
4d1176fd60
commit
3c0e2b4e16
@ -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
|
||||
@ -36,9 +36,10 @@ import com.sun.source.doctree.DocTree;
|
||||
* The interface for a custom taglet supported by doclets such as
|
||||
* the {@link jdk.javadoc.doclet.StandardDoclet standard doclet}.
|
||||
* Custom taglets are used to handle custom tags in documentation
|
||||
* comments; custom tags can be either <i>block tags</i>, which
|
||||
* appear at the end of a comment, or <i>inline tags</i>, which
|
||||
* can appear within the main body of a documentation comment.
|
||||
* comments; custom tags can be instantiated individually as either
|
||||
* <i>block tags</i>, which appear at the end of a comment,
|
||||
* or <i>inline tags</i>, which can appear within the main body of a
|
||||
* documentation comment.
|
||||
*
|
||||
* <p> Each implementation of a taglet must provide a public no-argument constructor
|
||||
* to be used by doclets to instantiate the taglet. A doclet will interact
|
||||
@ -78,20 +79,32 @@ import com.sun.source.doctree.DocTree;
|
||||
public interface Taglet {
|
||||
|
||||
/**
|
||||
* Returns the set of locations in which a tag may be used.
|
||||
* @return the set of locations in which a tag may be used
|
||||
* Returns the set of supported locations for block tags.
|
||||
* @return the set of supported locations for block tags
|
||||
*/
|
||||
Set<Location> getAllowedLocations();
|
||||
|
||||
/**
|
||||
* Indicates whether this taglet is for inline tags or not.
|
||||
* @return true if this taglet is for an inline tag, and false otherwise
|
||||
* Indicates whether this taglet supports inline tags.
|
||||
*
|
||||
* @return true if this taglet supports inline tags
|
||||
*/
|
||||
boolean isInlineTag();
|
||||
|
||||
/**
|
||||
* Returns the name of the tag.
|
||||
* @return the name of this custom tag.
|
||||
* Indicates whether this taglet supports block tags.
|
||||
*
|
||||
* @return true if this taglet supports block tags
|
||||
* @implSpec This implementation returns the inverse
|
||||
* result to {@code isInlineTag}.
|
||||
*/
|
||||
default boolean isBlockTag() {
|
||||
return !isInlineTag();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the tag supported by this taglet.
|
||||
* @return the name of this tag
|
||||
*/
|
||||
String getName();
|
||||
|
||||
@ -115,10 +128,11 @@ public interface Taglet {
|
||||
* Returns the string representation of a series of instances of
|
||||
* this tag to be included in the generated output.
|
||||
*
|
||||
* <p>If this taglet is for an {@link #isInlineTag inline} tag it will
|
||||
* be called once per instance of the tag, each time with a singleton list.
|
||||
* Otherwise, if this tag is a block tag, it will be called once per
|
||||
* comment, with a list of all the instances of the tag in a comment.
|
||||
* <p>If this taglet supports {@link #isInlineTag inline} tags, it will
|
||||
* be called once per instance of the inline tag, each time with a singleton list.
|
||||
* If this taglet supports {@link #isBlockTag block} tags, it will be called once
|
||||
* for each comment containing instances of block tags, with a list of all the instances
|
||||
* of the block tag in that comment.
|
||||
*
|
||||
* @param tags the list of instances of this tag
|
||||
* @param element the element to which the enclosing comment belongs
|
||||
@ -133,14 +147,14 @@ public interface Taglet {
|
||||
/**
|
||||
* The kind of location in which a tag may be used.
|
||||
*/
|
||||
public static enum Location {
|
||||
enum Location {
|
||||
/** In an Overview document. */
|
||||
OVERVIEW,
|
||||
/** In the documentation for a module. */
|
||||
MODULE,
|
||||
/** In the documentation for a package. */
|
||||
PACKAGE,
|
||||
/** In the documentation for a class, interface or enum. */
|
||||
/** In the documentation for a type, such as a class, interface or enum. */
|
||||
TYPE,
|
||||
/** In the documentation for a constructor. */
|
||||
CONSTRUCTOR,
|
||||
|
@ -1323,16 +1323,16 @@ public class HtmlDocletWriter {
|
||||
* an inline tag, such as in comments or in free-form text arguments
|
||||
* to block tags.
|
||||
*
|
||||
* @param holderTag specific tag where comment resides
|
||||
* @param element specific element where comment resides
|
||||
* @param tags array of text tags and inline tags (often alternating)
|
||||
present in the text of interest for this element
|
||||
* @param isFirstSentence true if text is first sentence
|
||||
* @param inSummary if the comment tags are added into the summary section
|
||||
* @param holderTag specific tag where comment resides
|
||||
* @param element specific element where comment resides
|
||||
* @param trees array of text tags and inline tags (often alternating)
|
||||
* present in the text of interest for this element
|
||||
* @param isFirstSentence true if text is first sentence
|
||||
* @param inSummary if the comment tags are added into the summary section
|
||||
* @return a Content object
|
||||
*/
|
||||
public Content commentTagsToContent(DocTree holderTag, Element element,
|
||||
List<? extends DocTree> tags, boolean isFirstSentence, boolean inSummary) {
|
||||
List<? extends DocTree> trees, boolean isFirstSentence, boolean inSummary) {
|
||||
|
||||
final Content result = new ContentBuilder() {
|
||||
@Override
|
||||
@ -1342,10 +1342,10 @@ public class HtmlDocletWriter {
|
||||
};
|
||||
CommentHelper ch = utils.getCommentHelper(element);
|
||||
// Array of all possible inline tags for this javadoc run
|
||||
configuration.tagletManager.checkTags(element, tags, true);
|
||||
configuration.tagletManager.checkTags(element, trees, true);
|
||||
commentRemoved = false;
|
||||
|
||||
for (ListIterator<? extends DocTree> iterator = tags.listIterator(); iterator.hasNext();) {
|
||||
for (ListIterator<? extends DocTree> iterator = trees.listIterator(); iterator.hasNext();) {
|
||||
boolean isFirstNode = !iterator.hasPrevious();
|
||||
DocTree tag = iterator.next();
|
||||
boolean isLastNode = !iterator.hasNext();
|
||||
|
@ -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
|
||||
@ -29,6 +29,7 @@ import java.util.EnumSet;
|
||||
import javax.lang.model.element.Element;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import jdk.javadoc.doclet.Taglet.Location;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
|
||||
/**
|
||||
@ -44,7 +45,7 @@ import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
public abstract class BasePropertyTaglet extends BaseTaglet {
|
||||
|
||||
public BasePropertyTaglet(String name) {
|
||||
super(name, false, EnumSet.of(Site.METHOD));
|
||||
super(name, false, EnumSet.of(Location.METHOD));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,6 +29,7 @@ import java.util.Set;
|
||||
import javax.lang.model.element.Element;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import jdk.javadoc.doclet.Taglet.Location;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
|
||||
/**
|
||||
@ -40,30 +41,29 @@ import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
public class BaseTaglet implements Taglet {
|
||||
/**
|
||||
* The different kinds of place where any given tag may be used.
|
||||
*/
|
||||
enum Site {
|
||||
OVERVIEW, MODULE, PACKAGE, TYPE, CONSTRUCTOR, METHOD, FIELD
|
||||
}
|
||||
|
||||
protected final String name;
|
||||
private final boolean inline;
|
||||
private final Set<Site> sites;
|
||||
private final Set<Location> sites;
|
||||
|
||||
BaseTaglet(String name, boolean inline, Set<Site> sites) {
|
||||
BaseTaglet(String name, boolean inline, Set<Location> sites) {
|
||||
this.name = name;
|
||||
this.inline = inline;
|
||||
this.sites = sites;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Location> getAllowedLocations() {
|
||||
return sites;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this {@code Taglet} can be used in constructor documentation.
|
||||
* @return true if this {@code Taglet} can be used in constructor documentation and false
|
||||
* otherwise.
|
||||
*/
|
||||
public final boolean inConstructor() {
|
||||
return sites.contains(Site.CONSTRUCTOR);
|
||||
return sites.contains(Location.CONSTRUCTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -72,7 +72,7 @@ public class BaseTaglet implements Taglet {
|
||||
* otherwise.
|
||||
*/
|
||||
public final boolean inField() {
|
||||
return sites.contains(Site.FIELD);
|
||||
return sites.contains(Location.FIELD);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -81,7 +81,7 @@ public class BaseTaglet implements Taglet {
|
||||
* otherwise.
|
||||
*/
|
||||
public final boolean inMethod() {
|
||||
return sites.contains(Site.METHOD);
|
||||
return sites.contains(Location.METHOD);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,7 +90,7 @@ public class BaseTaglet implements Taglet {
|
||||
* otherwise.
|
||||
*/
|
||||
public final boolean inOverview() {
|
||||
return sites.contains(Site.OVERVIEW);
|
||||
return sites.contains(Location.OVERVIEW);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,7 +99,7 @@ public class BaseTaglet implements Taglet {
|
||||
* otherwise.
|
||||
*/
|
||||
public final boolean inModule() {
|
||||
return sites.contains(Site.MODULE);
|
||||
return sites.contains(Location.MODULE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,7 +108,7 @@ public class BaseTaglet implements Taglet {
|
||||
* otherwise.
|
||||
*/
|
||||
public final boolean inPackage() {
|
||||
return sites.contains(Site.PACKAGE);
|
||||
return sites.contains(Location.PACKAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -117,7 +117,7 @@ public class BaseTaglet implements Taglet {
|
||||
* otherwise.
|
||||
*/
|
||||
public final boolean inType() {
|
||||
return sites.contains(Site.TYPE);
|
||||
return sites.contains(Location.TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,6 +30,7 @@ import java.util.EnumSet;
|
||||
import javax.lang.model.element.Element;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import jdk.javadoc.doclet.Taglet.Location;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
|
||||
import static com.sun.source.doctree.DocTree.Kind.CODE;
|
||||
@ -55,7 +56,7 @@ import static com.sun.source.doctree.DocTree.Kind.CODE;
|
||||
public class CodeTaglet extends BaseTaglet {
|
||||
|
||||
CodeTaglet() {
|
||||
super(CODE.tagName, true, EnumSet.allOf(Site.class));
|
||||
super(CODE.tagName, true, EnumSet.allOf(Location.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -28,7 +28,7 @@ package jdk.javadoc.internal.doclets.toolkit.taglets;
|
||||
import java.util.EnumSet;
|
||||
import javax.lang.model.element.Element;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import jdk.javadoc.doclet.Taglet.Location;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
|
||||
import static com.sun.source.doctree.DocTree.Kind.DEPRECATED;
|
||||
@ -46,7 +46,7 @@ public class DeprecatedTaglet extends BaseTaglet {
|
||||
|
||||
public DeprecatedTaglet() {
|
||||
super(DEPRECATED.tagName, false,
|
||||
EnumSet.of(Site.MODULE, Site.TYPE, Site.CONSTRUCTOR, Site.METHOD, Site.FIELD));
|
||||
EnumSet.of(Location.MODULE, Location.TYPE, Location.CONSTRUCTOR, Location.METHOD, Location.FIELD));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -29,6 +29,7 @@ import java.util.EnumSet;
|
||||
import javax.lang.model.element.Element;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import jdk.javadoc.doclet.Taglet.Location;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
|
||||
import static com.sun.source.doctree.DocTree.Kind.DOC_ROOT;
|
||||
@ -50,7 +51,7 @@ public class DocRootTaglet extends BaseTaglet {
|
||||
* Construct a new DocRootTaglet.
|
||||
*/
|
||||
public DocRootTaglet() {
|
||||
super(DOC_ROOT.tagName, true, EnumSet.allOf(Site.class));
|
||||
super(DOC_ROOT.tagName, true, EnumSet.allOf(Location.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -29,6 +29,7 @@ import java.util.EnumSet;
|
||||
import javax.lang.model.element.Element;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import jdk.javadoc.doclet.Taglet.Location;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
|
||||
import static com.sun.source.doctree.DocTree.Kind.INDEX;
|
||||
@ -42,7 +43,7 @@ import static com.sun.source.doctree.DocTree.Kind.INDEX;
|
||||
public class IndexTaglet extends BaseTaglet {
|
||||
|
||||
IndexTaglet() {
|
||||
super(INDEX.tagName, true, EnumSet.allOf(Site.class));
|
||||
super(INDEX.tagName, true, EnumSet.allOf(Location.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -30,6 +30,7 @@ import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import jdk.javadoc.doclet.Taglet.Location;
|
||||
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Messages;
|
||||
@ -57,7 +58,7 @@ public class InheritDocTaglet extends BaseTaglet {
|
||||
* Construct a new InheritDocTaglet.
|
||||
*/
|
||||
public InheritDocTaglet () {
|
||||
super(INHERIT_DOC.tagName, true, EnumSet.of(Site.TYPE, Site.METHOD));
|
||||
super(INHERIT_DOC.tagName, true, EnumSet.of(Location.TYPE, Location.METHOD));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,6 +29,7 @@ import java.util.EnumSet;
|
||||
import javax.lang.model.element.Element;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import jdk.javadoc.doclet.Taglet.Location;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
|
||||
import static com.sun.source.doctree.DocTree.Kind.LITERAL;
|
||||
@ -48,7 +49,7 @@ import static com.sun.source.doctree.DocTree.Kind.LITERAL;
|
||||
public class LiteralTaglet extends BaseTaglet {
|
||||
|
||||
LiteralTaglet() {
|
||||
super(LITERAL.tagName, true, EnumSet.allOf(Site.class));
|
||||
super(LITERAL.tagName, true, EnumSet.allOf(Location.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -34,6 +34,7 @@ import javax.lang.model.element.TypeElement;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import com.sun.source.doctree.ParamTree;
|
||||
import jdk.javadoc.doclet.Taglet.Location;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Messages;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
|
||||
@ -65,7 +66,7 @@ public class ParamTaglet extends BaseTaglet implements InheritableTaglet {
|
||||
* Construct a ParamTaglet.
|
||||
*/
|
||||
public ParamTaglet() {
|
||||
super(PARAM.tagName, false, EnumSet.of(Site.TYPE, Site.CONSTRUCTOR, Site.METHOD));
|
||||
super(PARAM.tagName, false, EnumSet.of(Location.TYPE, Location.CONSTRUCTOR, Location.METHOD));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -34,6 +34,7 @@ import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import jdk.javadoc.doclet.Taglet.Location;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Messages;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
|
||||
@ -54,7 +55,7 @@ import static com.sun.source.doctree.DocTree.Kind.RETURN;
|
||||
public class ReturnTaglet extends BaseTaglet implements InheritableTaglet {
|
||||
|
||||
public ReturnTaglet() {
|
||||
super(RETURN.tagName, false, EnumSet.of(Site.METHOD));
|
||||
super(RETURN.tagName, false, EnumSet.of(Location.METHOD));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -31,6 +31,7 @@ import java.util.List;
|
||||
import javax.lang.model.element.Element;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import jdk.javadoc.doclet.Taglet.Location;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocFinder;
|
||||
@ -50,7 +51,7 @@ import static com.sun.source.doctree.DocTree.Kind.SEE;
|
||||
public class SeeTaglet extends BaseTaglet implements InheritableTaglet {
|
||||
|
||||
public SeeTaglet() {
|
||||
super(SEE.tagName, false, EnumSet.allOf(Site.class));
|
||||
super(SEE.tagName, false, EnumSet.allOf(Location.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,6 +32,7 @@ import java.util.Set;
|
||||
import javax.lang.model.element.Element;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import jdk.javadoc.doclet.Taglet.Location;
|
||||
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
|
||||
@ -84,7 +85,7 @@ public class SimpleTaglet extends BaseTaglet implements InheritableTaglet {
|
||||
* for package, 't' for type, 'm' for method, 'c' for constructor
|
||||
* and 'f' for field.
|
||||
*/
|
||||
public SimpleTaglet(String tagName, String header, Set<Site> sites) {
|
||||
public SimpleTaglet(String tagName, String header, Set<Location> sites) {
|
||||
this(tagName, header, sites, true);
|
||||
}
|
||||
|
||||
@ -97,38 +98,38 @@ public class SimpleTaglet extends BaseTaglet implements InheritableTaglet {
|
||||
* for package, 't' for type, 'm' for method, 'c' for constructor
|
||||
* and 'f' for field.
|
||||
*/
|
||||
public SimpleTaglet(String tagName, String header, Set<Site> sites, boolean enabled) {
|
||||
public SimpleTaglet(String tagName, String header, Set<Location> sites, boolean enabled) {
|
||||
super(tagName, false, sites);
|
||||
this.header = header;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
private static Set<Site> getSites(String locations) {
|
||||
Set<Site> set = EnumSet.noneOf(Site.class);
|
||||
private static Set<Location> getSites(String locations) {
|
||||
Set<Location> set = EnumSet.noneOf(Location.class);
|
||||
for (int i = 0; i < locations.length(); i++) {
|
||||
switch (locations.charAt(i)) {
|
||||
case 'a': case 'A':
|
||||
return EnumSet.allOf(Site.class);
|
||||
return EnumSet.allOf(Location.class);
|
||||
case 'c': case 'C':
|
||||
set.add(Site.CONSTRUCTOR);
|
||||
set.add(Location.CONSTRUCTOR);
|
||||
break;
|
||||
case 'f': case 'F':
|
||||
set.add(Site.FIELD);
|
||||
set.add(Location.FIELD);
|
||||
break;
|
||||
case 'm': case 'M':
|
||||
set.add(Site.METHOD);
|
||||
set.add(Location.METHOD);
|
||||
break;
|
||||
case 'o': case 'O':
|
||||
set.add(Site.OVERVIEW);
|
||||
set.add(Location.OVERVIEW);
|
||||
break;
|
||||
case 'p': case 'P':
|
||||
set.add(Site.PACKAGE);
|
||||
set.add(Location.PACKAGE);
|
||||
break;
|
||||
case 's': case 'S': // super-packages, anyone?
|
||||
set.add(Site.MODULE);
|
||||
set.add(Location.MODULE);
|
||||
break;
|
||||
case 't': case 'T':
|
||||
set.add(Site.TYPE);
|
||||
set.add(Location.TYPE);
|
||||
break;
|
||||
case 'x': case 'X':
|
||||
break;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 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
|
||||
@ -29,6 +29,7 @@ import java.util.EnumSet;
|
||||
import javax.lang.model.element.Element;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import jdk.javadoc.doclet.Taglet.Location;
|
||||
import com.sun.source.doctree.SummaryTree;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
|
||||
@ -46,7 +47,7 @@ import static com.sun.source.doctree.DocTree.Kind.SUMMARY;
|
||||
public class SummaryTaglet extends BaseTaglet {
|
||||
|
||||
public SummaryTaglet() {
|
||||
super(SUMMARY.tagName, true, EnumSet.allOf(Site.class));
|
||||
super(SUMMARY.tagName, true, EnumSet.allOf(Location.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 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,6 +26,7 @@
|
||||
package jdk.javadoc.internal.doclets.toolkit.taglets;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import jdk.javadoc.doclet.Taglet.Location;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
@ -45,8 +46,8 @@ import static com.sun.source.doctree.DocTree.Kind.SYSTEM_PROPERTY;
|
||||
public class SystemPropertyTaglet extends BaseTaglet {
|
||||
|
||||
SystemPropertyTaglet(){
|
||||
super(SYSTEM_PROPERTY.tagName, true, EnumSet.of(Site.CONSTRUCTOR, Site.METHOD, Site.FIELD,
|
||||
Site.PACKAGE, Site.MODULE, Site.TYPE));
|
||||
super(SYSTEM_PROPERTY.tagName, true, EnumSet.of(Location.CONSTRUCTOR, Location.METHOD, Location.FIELD,
|
||||
Location.PACKAGE, Location.MODULE, Location.TYPE));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -25,9 +25,11 @@
|
||||
|
||||
package jdk.javadoc.internal.doclets.toolkit.taglets;
|
||||
|
||||
import java.util.Set;
|
||||
import javax.lang.model.element.Element;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import jdk.javadoc.doclet.Taglet.Location;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
|
||||
/**
|
||||
@ -35,6 +37,13 @@ import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
*/
|
||||
|
||||
public interface Taglet {
|
||||
/**
|
||||
* Returns the set of allowed locations for block tags
|
||||
* handled by this taglet.
|
||||
*
|
||||
* @return the set of allowable locations
|
||||
*/
|
||||
Set<Location> getAllowedLocations();
|
||||
|
||||
/**
|
||||
* Return true if this <code>Taglet</code>
|
||||
@ -43,7 +52,7 @@ public interface Taglet {
|
||||
* is used in field documentation and false
|
||||
* otherwise.
|
||||
*/
|
||||
public abstract boolean inField();
|
||||
boolean inField();
|
||||
|
||||
/**
|
||||
* Return true if this <code>Taglet</code>
|
||||
@ -52,7 +61,7 @@ public interface Taglet {
|
||||
* is used in constructor documentation and false
|
||||
* otherwise.
|
||||
*/
|
||||
public abstract boolean inConstructor();
|
||||
boolean inConstructor();
|
||||
|
||||
/**
|
||||
* Return true if this <code>Taglet</code>
|
||||
@ -61,7 +70,7 @@ public interface Taglet {
|
||||
* is used in method documentation and false
|
||||
* otherwise.
|
||||
*/
|
||||
public abstract boolean inMethod();
|
||||
boolean inMethod();
|
||||
|
||||
/**
|
||||
* Return true if this <code>Taglet</code>
|
||||
@ -70,7 +79,7 @@ public interface Taglet {
|
||||
* is used in method documentation and false
|
||||
* otherwise.
|
||||
*/
|
||||
public abstract boolean inOverview();
|
||||
boolean inOverview();
|
||||
|
||||
/**
|
||||
* Return true if this <code>Taglet</code>
|
||||
@ -79,7 +88,7 @@ public interface Taglet {
|
||||
* is used in module documentation and false
|
||||
* otherwise.
|
||||
*/
|
||||
public abstract boolean inModule();
|
||||
boolean inModule();
|
||||
|
||||
/**
|
||||
* Return true if this <code>Taglet</code>
|
||||
@ -88,7 +97,7 @@ public interface Taglet {
|
||||
* is used in package documentation and false
|
||||
* otherwise.
|
||||
*/
|
||||
public abstract boolean inPackage();
|
||||
boolean inPackage();
|
||||
|
||||
/**
|
||||
* Return true if this <code>Taglet</code>
|
||||
@ -98,7 +107,7 @@ public interface Taglet {
|
||||
* is used in type documentation and false
|
||||
* otherwise.
|
||||
*/
|
||||
public abstract boolean inType();
|
||||
boolean inType();
|
||||
|
||||
/**
|
||||
* Return true if this <code>Taglet</code>
|
||||
@ -106,13 +115,24 @@ public interface Taglet {
|
||||
* @return true if this <code>Taglet</code>
|
||||
* is an inline tag and false otherwise.
|
||||
*/
|
||||
public abstract boolean isInlineTag();
|
||||
boolean isInlineTag();
|
||||
|
||||
/**
|
||||
* Indicates whether this taglet supports block tags.
|
||||
*
|
||||
* @return true if this taglet supports block tags
|
||||
* @implSpec This implementation returns the inverse
|
||||
* result to {@code isInlineTag}.
|
||||
*/
|
||||
default boolean isBlockTag() {
|
||||
return !isInlineTag();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of this custom tag.
|
||||
* @return the name of this custom tag.
|
||||
*/
|
||||
public abstract String getName();
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Given the <code>Tag</code> representation of this custom
|
||||
@ -124,26 +144,23 @@ public interface Taglet {
|
||||
* @throws UnsupportedOperationException thrown when the method is not supported by the taglet.
|
||||
* @return the Content representation of this <code>Tag</code>.
|
||||
*/
|
||||
public abstract Content getTagletOutput(Element holder, DocTree tag, TagletWriter writer) throws
|
||||
Content getTagletOutput(Element holder, DocTree tag, TagletWriter writer) throws
|
||||
UnsupportedOperationException;
|
||||
|
||||
/**
|
||||
* Given a <code>Doc</code> object, check if it holds any tags of
|
||||
* this type. If it does, return the string representing the output.
|
||||
* Given an element object, check if it holds any tags of
|
||||
* this type. If it does, return the content representing the output.
|
||||
* If it does not, return null.
|
||||
* @param holder a {@link Doc} object holding the custom tag.
|
||||
* @param holder an element holding the custom tag.
|
||||
* @param writer a {@link TagletWriter} Taglet writer.
|
||||
* @throws UnsupportedTagletOperationException thrown when the method is not
|
||||
* supported by the taglet.
|
||||
* @return the TagletOutput representation of this <code>Tag</code>.
|
||||
* @return the content representation of this <code>Tag</code>.
|
||||
*/
|
||||
public abstract Content getTagletOutput(Element holder, TagletWriter writer) throws
|
||||
Content getTagletOutput(Element holder, TagletWriter writer) throws
|
||||
UnsupportedTagletOperationException;
|
||||
|
||||
@Override
|
||||
public abstract String toString();
|
||||
|
||||
static class UnsupportedTagletOperationException extends UnsupportedOperationException {
|
||||
class UnsupportedTagletOperationException extends UnsupportedOperationException {
|
||||
private static final long serialVersionUID = -3530273193380250271L;
|
||||
public UnsupportedTagletOperationException(String message) {
|
||||
super(message);
|
||||
|
@ -25,8 +25,22 @@
|
||||
|
||||
package jdk.javadoc.internal.doclets.toolkit.taglets;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
@ -39,20 +53,32 @@ import javax.tools.JavaFileManager;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
|
||||
import jdk.javadoc.doclet.Doclet;
|
||||
import jdk.javadoc.doclet.DocletEnvironment;
|
||||
import jdk.javadoc.doclet.Taglet.Location;
|
||||
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
|
||||
import jdk.javadoc.internal.doclets.toolkit.DocletElement;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Messages;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Resources;
|
||||
|
||||
import jdk.javadoc.internal.doclets.toolkit.taglets.BaseTaglet.Site;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.Utils;
|
||||
|
||||
import static javax.tools.DocumentationTool.Location.*;
|
||||
|
||||
import static com.sun.source.doctree.DocTree.Kind.*;
|
||||
import static com.sun.source.doctree.DocTree.Kind.AUTHOR;
|
||||
import static com.sun.source.doctree.DocTree.Kind.EXCEPTION;
|
||||
import static com.sun.source.doctree.DocTree.Kind.HIDDEN;
|
||||
import static com.sun.source.doctree.DocTree.Kind.LINK;
|
||||
import static com.sun.source.doctree.DocTree.Kind.LINK_PLAIN;
|
||||
import static com.sun.source.doctree.DocTree.Kind.PROVIDES;
|
||||
import static com.sun.source.doctree.DocTree.Kind.SEE;
|
||||
import static com.sun.source.doctree.DocTree.Kind.SERIAL;
|
||||
import static com.sun.source.doctree.DocTree.Kind.SERIAL_DATA;
|
||||
import static com.sun.source.doctree.DocTree.Kind.SERIAL_FIELD;
|
||||
import static com.sun.source.doctree.DocTree.Kind.SINCE;
|
||||
import static com.sun.source.doctree.DocTree.Kind.THROWS;
|
||||
import static com.sun.source.doctree.DocTree.Kind.USES;
|
||||
import static com.sun.source.doctree.DocTree.Kind.VERSION;
|
||||
import static javax.tools.DocumentationTool.Location.TAGLET_PATH;
|
||||
|
||||
/**
|
||||
* Manages the {@code Taglet}s used by doclets.
|
||||
@ -76,9 +102,9 @@ public class TagletManager {
|
||||
private final LinkedHashMap<String,Taglet> allTaglets;
|
||||
|
||||
/**
|
||||
* Block (non-line) taglets, grouped by Site
|
||||
* Block (non-inline) taglets, grouped by Location
|
||||
*/
|
||||
private Map<Site, List<Taglet>> blockTagletsBySite;
|
||||
private Map<Location, List<Taglet>> blockTagletsByLocation;
|
||||
|
||||
/**
|
||||
* The taglets that can appear inline in descriptive text.
|
||||
@ -329,10 +355,10 @@ public class TagletManager {
|
||||
* Given a series of {@code DocTree}s, check for spelling mistakes.
|
||||
* @param element the tags holder
|
||||
* @param trees the trees containing the comments
|
||||
* @param areInlineTags true if the array of tags are inline and false otherwise.
|
||||
* @param inlineTrees true if the trees are inline and false otherwise.
|
||||
*/
|
||||
@SuppressWarnings("preview")
|
||||
public void checkTags(Element element, Iterable<? extends DocTree> trees, boolean areInlineTags) {
|
||||
public void checkTags(Element element, Iterable<? extends DocTree> trees, boolean inlineTrees) {
|
||||
if (trees == null) {
|
||||
return;
|
||||
}
|
||||
@ -357,69 +383,72 @@ public class TagletManager {
|
||||
final Taglet taglet = allTaglets.get(name);
|
||||
// Check and verify tag usage
|
||||
if (taglet != null) {
|
||||
if (areInlineTags && !taglet.isInlineTag()) {
|
||||
if (inlineTrees && !taglet.isInlineTag()) {
|
||||
printTagMisuseWarn(ch, taglet, tag, "inline");
|
||||
}
|
||||
// nothing more to do
|
||||
if (element == null) {
|
||||
return;
|
||||
}
|
||||
new SimpleElementVisitor14<Void, Void>() {
|
||||
@Override
|
||||
public Void visitModule(ModuleElement e, Void p) {
|
||||
if (!taglet.inModule()) {
|
||||
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "module");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitPackage(PackageElement e, Void p) {
|
||||
if (!taglet.inPackage()) {
|
||||
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "package");
|
||||
if (!inlineTrees) {
|
||||
new SimpleElementVisitor14<Void, Void>() {
|
||||
@Override
|
||||
public Void visitModule(ModuleElement e, Void p) {
|
||||
if (!taglet.inModule()) {
|
||||
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "module");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitType(TypeElement e, Void p) {
|
||||
if (!taglet.inType()) {
|
||||
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "class");
|
||||
@Override
|
||||
public Void visitPackage(PackageElement e, Void p) {
|
||||
if (!taglet.inPackage()) {
|
||||
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "package");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitExecutable(ExecutableElement e, Void p) {
|
||||
if (utils.isConstructor(e) && !taglet.inConstructor()) {
|
||||
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "constructor");
|
||||
} else if (!taglet.inMethod()) {
|
||||
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "method");
|
||||
@Override
|
||||
public Void visitType(TypeElement e, Void p) {
|
||||
if (!taglet.inType()) {
|
||||
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "class");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitVariable(VariableElement e, Void p) {
|
||||
if (utils.isField(e) && !taglet.inField()) {
|
||||
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "field");
|
||||
@Override
|
||||
public Void visitExecutable(ExecutableElement e, Void p) {
|
||||
if (utils.isConstructor(e) && !taglet.inConstructor()) {
|
||||
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "constructor");
|
||||
} else if (!taglet.inMethod()) {
|
||||
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "method");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitUnknown(Element e, Void p) {
|
||||
if (utils.isOverviewElement(e) && !taglet.inOverview()) {
|
||||
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "overview");
|
||||
@Override
|
||||
public Void visitVariable(VariableElement e, Void p) {
|
||||
if (utils.isField(e) && !taglet.inField()) {
|
||||
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "field");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void defaultAction(Element e, Void p) {
|
||||
return null;
|
||||
}
|
||||
}.visit(element);
|
||||
@Override
|
||||
public Void visitUnknown(Element e, Void p) {
|
||||
if (utils.isOverviewElement(e) && !taglet.inOverview()) {
|
||||
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "overview");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void defaultAction(Element e, Void p) {
|
||||
return null;
|
||||
}
|
||||
}.visit(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -504,36 +533,36 @@ public class TagletManager {
|
||||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
public List<Taglet> getBlockTaglets(Element e) {
|
||||
if (blockTagletsBySite == null) {
|
||||
if (blockTagletsByLocation == null) {
|
||||
initBlockTaglets();
|
||||
}
|
||||
|
||||
switch (e.getKind()) {
|
||||
case CONSTRUCTOR:
|
||||
return blockTagletsBySite.get(Site.CONSTRUCTOR);
|
||||
return blockTagletsByLocation.get(Location.CONSTRUCTOR);
|
||||
case METHOD:
|
||||
return blockTagletsBySite.get(Site.METHOD);
|
||||
return blockTagletsByLocation.get(Location.METHOD);
|
||||
case ENUM_CONSTANT:
|
||||
case FIELD:
|
||||
return blockTagletsBySite.get(Site.FIELD);
|
||||
return blockTagletsByLocation.get(Location.FIELD);
|
||||
case ANNOTATION_TYPE:
|
||||
case INTERFACE:
|
||||
case CLASS:
|
||||
case ENUM:
|
||||
case RECORD:
|
||||
return blockTagletsBySite.get(Site.TYPE);
|
||||
return blockTagletsByLocation.get(Location.TYPE);
|
||||
case MODULE:
|
||||
return blockTagletsBySite.get(Site.MODULE);
|
||||
return blockTagletsByLocation.get(Location.MODULE);
|
||||
case PACKAGE:
|
||||
return blockTagletsBySite.get(Site.PACKAGE);
|
||||
return blockTagletsByLocation.get(Location.PACKAGE);
|
||||
case OTHER:
|
||||
if (e instanceof DocletElement) {
|
||||
DocletElement de = (DocletElement)e;
|
||||
switch (de.getSubKind()) {
|
||||
case DOCFILE:
|
||||
return blockTagletsBySite.get(Site.PACKAGE);
|
||||
return blockTagletsByLocation.get(Location.PACKAGE);
|
||||
case OVERVIEW:
|
||||
return blockTagletsBySite.get(Site.OVERVIEW);
|
||||
return blockTagletsByLocation.get(Location.OVERVIEW);
|
||||
default:
|
||||
// fall through
|
||||
}
|
||||
@ -549,9 +578,9 @@ public class TagletManager {
|
||||
*/
|
||||
private void initBlockTaglets() {
|
||||
|
||||
blockTagletsBySite = new EnumMap<>(Site.class);
|
||||
for (Site site : Site.values()) {
|
||||
blockTagletsBySite.put(site, new ArrayList<>());
|
||||
blockTagletsByLocation = new EnumMap<>(Location.class);
|
||||
for (Location site : Location.values()) {
|
||||
blockTagletsByLocation.put(site, new ArrayList<>());
|
||||
}
|
||||
|
||||
inlineTags = new ArrayList<>();
|
||||
@ -559,27 +588,11 @@ public class TagletManager {
|
||||
for (Taglet current : allTaglets.values()) {
|
||||
if (current.isInlineTag()) {
|
||||
inlineTags.add(current);
|
||||
} else {
|
||||
if (current.inOverview()) {
|
||||
blockTagletsBySite.get(Site.OVERVIEW).add(current);
|
||||
}
|
||||
if (current.inModule()) {
|
||||
blockTagletsBySite.get(Site.MODULE).add(current);
|
||||
}
|
||||
if (current.inPackage()) {
|
||||
blockTagletsBySite.get(Site.PACKAGE).add(current);
|
||||
}
|
||||
if (current.inType()) {
|
||||
blockTagletsBySite.get(Site.TYPE).add(current);
|
||||
}
|
||||
if (current.inConstructor()) {
|
||||
blockTagletsBySite.get(Site.CONSTRUCTOR).add(current);
|
||||
}
|
||||
if (current.inMethod()) {
|
||||
blockTagletsBySite.get(Site.METHOD).add(current);
|
||||
}
|
||||
if (current.inField()) {
|
||||
blockTagletsBySite.get(Site.FIELD).add(current);
|
||||
}
|
||||
|
||||
if (current.isBlockTag()) {
|
||||
for (Location l : current.getAllowedLocations()) {
|
||||
blockTagletsByLocation.get(l).add(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -610,26 +623,26 @@ public class TagletManager {
|
||||
addStandardTaglet(new ThrowsTaglet());
|
||||
addStandardTaglet(
|
||||
new SimpleTaglet(EXCEPTION.tagName, null,
|
||||
EnumSet.of(Site.METHOD, Site.CONSTRUCTOR)));
|
||||
EnumSet.of(Location.METHOD, Location.CONSTRUCTOR)));
|
||||
addStandardTaglet(
|
||||
new SimpleTaglet(SINCE.tagName, resources.getText("doclet.Since"),
|
||||
EnumSet.allOf(Site.class), !nosince));
|
||||
EnumSet.allOf(Location.class), !nosince));
|
||||
addStandardTaglet(
|
||||
new SimpleTaglet(VERSION.tagName, resources.getText("doclet.Version"),
|
||||
EnumSet.of(Site.OVERVIEW, Site.MODULE, Site.PACKAGE, Site.TYPE), showversion));
|
||||
EnumSet.of(Location.OVERVIEW, Location.MODULE, Location.PACKAGE, Location.TYPE), showversion));
|
||||
addStandardTaglet(
|
||||
new SimpleTaglet(AUTHOR.tagName, resources.getText("doclet.Author"),
|
||||
EnumSet.of(Site.OVERVIEW, Site.MODULE, Site.PACKAGE, Site.TYPE), showauthor));
|
||||
EnumSet.of(Location.OVERVIEW, Location.MODULE, Location.PACKAGE, Location.TYPE), showauthor));
|
||||
addStandardTaglet(
|
||||
new SimpleTaglet(SERIAL_DATA.tagName, resources.getText("doclet.SerialData"),
|
||||
EnumSet.noneOf(Site.class)));
|
||||
EnumSet.noneOf(Location.class)));
|
||||
addStandardTaglet(
|
||||
new SimpleTaglet(HIDDEN.tagName, null,
|
||||
EnumSet.of(Site.TYPE, Site.METHOD, Site.FIELD)));
|
||||
EnumSet.of(Location.TYPE, Location.METHOD, Location.FIELD)));
|
||||
|
||||
// This appears to be a default custom (non-standard) taglet
|
||||
Taglet factoryTaglet = new SimpleTaglet("factory", resources.getText("doclet.Factory"),
|
||||
EnumSet.of(Site.METHOD));
|
||||
EnumSet.of(Location.METHOD));
|
||||
allTaglets.put(factoryTaglet.getName(), factoryTaglet);
|
||||
|
||||
addStandardTaglet(new SeeTaglet());
|
||||
@ -647,15 +660,15 @@ public class TagletManager {
|
||||
// Keep track of the names of standard tags for error checking purposes.
|
||||
// The following are not handled above.
|
||||
addStandardTaglet(new DeprecatedTaglet());
|
||||
addStandardTaglet(new BaseTaglet(LINK.tagName, true, EnumSet.allOf(Site.class)));
|
||||
addStandardTaglet(new BaseTaglet(LINK_PLAIN.tagName, true, EnumSet.allOf(Site.class)));
|
||||
addStandardTaglet(new BaseTaglet(USES.tagName, false, EnumSet.of(Site.MODULE)));
|
||||
addStandardTaglet(new BaseTaglet(PROVIDES.tagName, false, EnumSet.of(Site.MODULE)));
|
||||
addStandardTaglet(new BaseTaglet(LINK.tagName, true, EnumSet.allOf(Location.class)));
|
||||
addStandardTaglet(new BaseTaglet(LINK_PLAIN.tagName, true, EnumSet.allOf(Location.class)));
|
||||
addStandardTaglet(new BaseTaglet(USES.tagName, false, EnumSet.of(Location.MODULE)));
|
||||
addStandardTaglet(new BaseTaglet(PROVIDES.tagName, false, EnumSet.of(Location.MODULE)));
|
||||
addStandardTaglet(
|
||||
new SimpleTaglet(SERIAL.tagName, null,
|
||||
EnumSet.of(Site.PACKAGE, Site.TYPE, Site.FIELD)));
|
||||
EnumSet.of(Location.PACKAGE, Location.TYPE, Location.FIELD)));
|
||||
addStandardTaglet(
|
||||
new SimpleTaglet(SERIAL_FIELD.tagName, null, EnumSet.of(Site.FIELD)));
|
||||
new SimpleTaglet(SERIAL_FIELD.tagName, null, EnumSet.of(Location.FIELD)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -666,11 +679,11 @@ public class TagletManager {
|
||||
addStandardTaglet(new PropertySetterTaglet());
|
||||
addStandardTaglet(new SimpleTaglet("propertyDescription",
|
||||
resources.getText("doclet.PropertyDescription"),
|
||||
EnumSet.of(Site.METHOD, Site.FIELD)));
|
||||
EnumSet.of(Location.METHOD, Location.FIELD)));
|
||||
addStandardTaglet(new SimpleTaglet("defaultValue", resources.getText("doclet.DefaultValue"),
|
||||
EnumSet.of(Site.METHOD, Site.FIELD)));
|
||||
EnumSet.of(Location.METHOD, Location.FIELD)));
|
||||
addStandardTaglet(new SimpleTaglet("treatAsPrivate", null,
|
||||
EnumSet.of(Site.TYPE, Site.METHOD, Site.FIELD)));
|
||||
EnumSet.of(Location.TYPE, Location.METHOD, Location.FIELD)));
|
||||
}
|
||||
|
||||
private void addStandardTaglet(Taglet taglet) {
|
||||
@ -735,6 +748,7 @@ public class TagletManager {
|
||||
for (Taglet t : taglets) {
|
||||
String name = t.isInlineTag() ? "{@" + t.getName() + "}" : "@" + t.getName();
|
||||
out.println(String.format("%20s", name) + ": "
|
||||
+ format(t.isBlockTag(), "block")+ " "
|
||||
+ format(t.inOverview(), "overview") + " "
|
||||
+ format(t.inModule(), "module") + " "
|
||||
+ format(t.inPackage(), "package") + " "
|
||||
|
@ -25,8 +25,13 @@
|
||||
|
||||
package jdk.javadoc.internal.doclets.toolkit.taglets;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
@ -34,6 +39,8 @@ import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
|
||||
import jdk.javadoc.doclet.Taglet.Location;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocFinder;
|
||||
@ -54,7 +61,7 @@ public class ThrowsTaglet extends BaseTaglet
|
||||
implements InheritableTaglet {
|
||||
|
||||
public ThrowsTaglet() {
|
||||
super(THROWS.tagName, false, EnumSet.of(Site.CONSTRUCTOR, Site.METHOD));
|
||||
super(THROWS.tagName, false, EnumSet.of(Location.CONSTRUCTOR, Location.METHOD));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -174,7 +181,7 @@ public class ThrowsTaglet extends BaseTaglet
|
||||
* @return the Content representation of this <code>Tag</code>.
|
||||
*/
|
||||
protected Content throwsTagsOutput(Map<List<? extends DocTree>, ExecutableElement> throwTags,
|
||||
TagletWriter writer, Set<String> alreadyDocumented, boolean allowDups) {
|
||||
TagletWriter writer, Set<String> alreadyDocumented, boolean allowDups) {
|
||||
Utils utils = writer.configuration().utils;
|
||||
Content result = writer.getOutputInstance();
|
||||
if (!throwTags.isEmpty()) {
|
||||
|
@ -22,10 +22,12 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.javadoc.internal.doclets.toolkit.taglets;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
|
||||
@ -53,60 +55,57 @@ public class UserTaglet implements Taglet {
|
||||
userTaglet = t;
|
||||
}
|
||||
|
||||
public Set<jdk.javadoc.doclet.Taglet.Location> getAllowedLocations() {
|
||||
return userTaglet.getAllowedLocations();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean inField() {
|
||||
return userTaglet.isInlineTag()
|
||||
|| userTaglet.getAllowedLocations().contains(FIELD);
|
||||
return userTaglet.getAllowedLocations().contains(FIELD);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean inConstructor() {
|
||||
return userTaglet.isInlineTag()
|
||||
|| userTaglet.getAllowedLocations().contains(CONSTRUCTOR);
|
||||
return userTaglet.getAllowedLocations().contains(CONSTRUCTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean inMethod() {
|
||||
return userTaglet.isInlineTag()
|
||||
|| userTaglet.getAllowedLocations().contains(METHOD);
|
||||
return userTaglet.getAllowedLocations().contains(METHOD);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean inOverview() {
|
||||
return userTaglet.isInlineTag()
|
||||
|| userTaglet.getAllowedLocations().contains(OVERVIEW);
|
||||
return userTaglet.getAllowedLocations().contains(OVERVIEW);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean inModule() {
|
||||
return userTaglet.isInlineTag()
|
||||
|| userTaglet.getAllowedLocations().contains(MODULE);
|
||||
return userTaglet.getAllowedLocations().contains(MODULE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean inPackage() {
|
||||
return userTaglet.isInlineTag()
|
||||
|| userTaglet.getAllowedLocations().contains(PACKAGE);
|
||||
return userTaglet.getAllowedLocations().contains(PACKAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean inType() {
|
||||
return userTaglet.isInlineTag()
|
||||
|| userTaglet.getAllowedLocations().contains(TYPE);
|
||||
return userTaglet.getAllowedLocations().contains(TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -118,6 +117,10 @@ public class UserTaglet implements Taglet {
|
||||
return userTaglet.isInlineTag();
|
||||
}
|
||||
|
||||
public boolean isBlockTag() {
|
||||
return userTaglet.isBlockTag();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -30,6 +30,7 @@ import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import jdk.javadoc.doclet.Taglet.Location;
|
||||
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Content;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Messages;
|
||||
@ -59,7 +60,7 @@ public class ValueTaglet extends BaseTaglet {
|
||||
* Construct a new ValueTaglet.
|
||||
*/
|
||||
public ValueTaglet() {
|
||||
super(VALUE.tagName, true, EnumSet.allOf(Site.class));
|
||||
super(VALUE.tagName, true, EnumSet.allOf(Location.class));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8202947
|
||||
* @summary Test bimodal (inline and block) taglets
|
||||
* @library /tools/lib ../../lib
|
||||
* @modules jdk.javadoc/jdk.javadoc.internal.tool
|
||||
* @build toolbox.ToolBox javadoc.tester.*
|
||||
* @run main TestBimodalTaglets
|
||||
*/
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
|
||||
import com.sun.source.doctree.DocTree;
|
||||
import com.sun.source.doctree.UnknownBlockTagTree;
|
||||
import com.sun.source.doctree.UnknownInlineTagTree;
|
||||
import javadoc.tester.JavadocTester;
|
||||
import jdk.javadoc.doclet.Taglet;
|
||||
import toolbox.ToolBox;
|
||||
|
||||
public class TestBimodalTaglets extends JavadocTester implements Taglet {
|
||||
public static void main(String... args) throws Exception {
|
||||
new TestBimodalTaglets().runTests(m -> new Object[] { Path.of(m.getName()) });
|
||||
}
|
||||
|
||||
ToolBox tb = new ToolBox();
|
||||
|
||||
@Test
|
||||
public void testBimodalTaglet(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
tb.writeJavaFiles(src,
|
||||
"package p;\n"
|
||||
+ comment("This is a comment.",
|
||||
"Here is an inline {@test abc} test tag {@test def}.",
|
||||
"@see Object",
|
||||
"@test 123",
|
||||
"@see String",
|
||||
"@test 456")
|
||||
+ "public class C { }\n");
|
||||
|
||||
javadoc("-d", base.resolve("out").toString(),
|
||||
"--source-path", src.toString(),
|
||||
"-tagletpath", System.getProperty("test.class.path"),
|
||||
"-taglet", "TestBimodalTaglets",
|
||||
"p");
|
||||
|
||||
checkOutput("p/C.html", true,
|
||||
"Here is an inline INLINE[abc] test tag INLINE[def].",
|
||||
"<dt>BLOCK:<dd>123<dd>456");
|
||||
}
|
||||
|
||||
String comment(String... lines) {
|
||||
return Arrays.stream(lines)
|
||||
.collect(Collectors.joining("\n * ", "/**\n * ", "\n */"));
|
||||
}
|
||||
|
||||
// the taglet ....
|
||||
|
||||
@Override
|
||||
public Set<Location> getAllowedLocations() {
|
||||
return EnumSet.allOf(Location.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInlineTag() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlockTag() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(List<? extends DocTree> tags, Element element) {
|
||||
if (tags.size() == 1 && tags.get(0) instanceof UnknownInlineTagTree) {
|
||||
return inlineTagToString((UnknownInlineTagTree) tags.get(0));
|
||||
} else {
|
||||
return blockTagsToString(tags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an inline tag to a string composed of its contents wrapped in "INLINE[" ... "]"
|
||||
*
|
||||
* @param tag the tag
|
||||
* @return the string
|
||||
*/
|
||||
private String inlineTagToString(UnknownInlineTagTree tag) {
|
||||
return "INLINE[" +
|
||||
toString(tag.getContent())
|
||||
+ "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a series of block tags to a string composed of a {@code> <dt>} header,
|
||||
* followed by the contents of each tag preceded by {@code <dd>}.
|
||||
* Note that the doclet provides the enclosing {@code <dl>...</dl>} around all the
|
||||
* block tags.
|
||||
*
|
||||
* @param tags the tags
|
||||
* @return the string
|
||||
*/
|
||||
private String blockTagsToString(List<? extends DocTree> tags) {
|
||||
return "<dt>BLOCK:"
|
||||
+ tags.stream()
|
||||
.map (t -> (UnknownBlockTagTree) t)
|
||||
.map(t -> "<dd>" + toString(t.getContent()))
|
||||
.collect(Collectors.joining());
|
||||
}
|
||||
|
||||
private String toString(List<? extends DocTree> trees) {
|
||||
return trees.stream()
|
||||
.map(Object::toString)
|
||||
.collect(Collectors.joining());
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +1,31 @@
|
||||
@author: overview module package type ........... ...... ..... ...... disabled
|
||||
{@code}: overview module package type constructor method field inline ........
|
||||
@defaultValue: ........ ...... ....... .... ........... method field ...... ........
|
||||
@deprecated: ........ module ....... type constructor method field ...... ........
|
||||
{@docRoot}: overview module package type constructor method field inline ........
|
||||
@exception: ........ ...... ....... .... constructor method ..... ...... ........
|
||||
@factory: ........ ...... ....... .... ........... method ..... ...... ........
|
||||
@hidden: ........ ...... ....... type ........... method field ...... ........
|
||||
{@index}: overview module package type constructor method field inline ........
|
||||
{@inheritDoc}: ........ ...... ....... type ........... method ..... inline ........
|
||||
{@link}: overview module package type constructor method field inline ........
|
||||
{@linkplain}: overview module package type constructor method field inline ........
|
||||
{@literal}: overview module package type constructor method field inline ........
|
||||
@param: ........ ...... ....... type constructor method ..... ...... ........
|
||||
@propertyDescription: ........ ...... ....... .... ........... method field ...... ........
|
||||
@propertyGetter: ........ ...... ....... .... ........... method ..... ...... ........
|
||||
@propertySetter: ........ ...... ....... .... ........... method ..... ...... ........
|
||||
@provides: ........ module ....... .... ........... ...... ..... ...... ........
|
||||
@return: ........ ...... ....... .... ........... method ..... ...... ........
|
||||
@see: overview module package type constructor method field ...... ........
|
||||
@serial: ........ ...... package type ........... ...... field ...... ........
|
||||
@serialData: ........ ...... ....... .... ........... ...... ..... ...... ........
|
||||
@serialField: ........ ...... ....... .... ........... ...... field ...... ........
|
||||
@since: overview module package type constructor method field ...... ........
|
||||
{@summary}: overview module package type constructor method field inline ........
|
||||
{@systemProperty}: ........ module package type constructor method field inline ........
|
||||
@throws: ........ ...... ....... .... constructor method ..... ...... ........
|
||||
@treatAsPrivate: ........ ...... ....... type ........... method field ...... ........
|
||||
@uses: ........ module ....... .... ........... ...... ..... ...... ........
|
||||
{@value}: overview module package type constructor method field inline ........
|
||||
@version: overview module package type ........... ...... ..... ...... disabled
|
||||
@author: block overview module package type ........... ...... ..... ...... disabled
|
||||
{@code}: ..... overview module package type constructor method field inline ........
|
||||
@defaultValue: block ........ ...... ....... .... ........... method field ...... ........
|
||||
@deprecated: block ........ module ....... type constructor method field ...... ........
|
||||
{@docRoot}: ..... overview module package type constructor method field inline ........
|
||||
@exception: block ........ ...... ....... .... constructor method ..... ...... ........
|
||||
@factory: block ........ ...... ....... .... ........... method ..... ...... ........
|
||||
@hidden: block ........ ...... ....... type ........... method field ...... ........
|
||||
{@index}: ..... overview module package type constructor method field inline ........
|
||||
{@inheritDoc}: ..... ........ ...... ....... type ........... method ..... inline ........
|
||||
{@link}: ..... overview module package type constructor method field inline ........
|
||||
{@linkplain}: ..... overview module package type constructor method field inline ........
|
||||
{@literal}: ..... overview module package type constructor method field inline ........
|
||||
@param: block ........ ...... ....... type constructor method ..... ...... ........
|
||||
@propertyDescription: block ........ ...... ....... .... ........... method field ...... ........
|
||||
@propertyGetter: block ........ ...... ....... .... ........... method ..... ...... ........
|
||||
@propertySetter: block ........ ...... ....... .... ........... method ..... ...... ........
|
||||
@provides: block ........ module ....... .... ........... ...... ..... ...... ........
|
||||
@return: block ........ ...... ....... .... ........... method ..... ...... ........
|
||||
@see: block overview module package type constructor method field ...... ........
|
||||
@serial: block ........ ...... package type ........... ...... field ...... ........
|
||||
@serialData: block ........ ...... ....... .... ........... ...... ..... ...... ........
|
||||
@serialField: block ........ ...... ....... .... ........... ...... field ...... ........
|
||||
@since: block overview module package type constructor method field ...... ........
|
||||
{@summary}: ..... overview module package type constructor method field inline ........
|
||||
{@systemProperty}: ..... ........ module package type constructor method field inline ........
|
||||
@throws: block ........ ...... ....... .... constructor method ..... ...... ........
|
||||
@treatAsPrivate: block ........ ...... ....... type ........... method field ...... ........
|
||||
@uses: block ........ module ....... .... ........... ...... ..... ...... ........
|
||||
{@value}: ..... overview module package type constructor method field inline ........
|
||||
@version: block overview module package type ........... ...... ..... ...... disabled
|
||||
|
Loading…
Reference in New Issue
Block a user