8164316: Refine the Doclet APIs

Reviewed-by: jjg
This commit is contained in:
Kumar Srinivasan 2016-11-24 20:48:52 -08:00
parent 54244b5e6d
commit f4c9d73b3e
42 changed files with 1079 additions and 789 deletions

View file

@ -25,7 +25,7 @@
package jdk.javadoc.doclet; package jdk.javadoc.doclet;
import java.util.ListIterator; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
@ -67,7 +67,7 @@ public interface Doclet {
* @param locale the locale to be used * @param locale the locale to be used
* @param reporter the reporter to be used * @param reporter the reporter to be used
*/ */
public void init(Locale locale, Reporter reporter); void init(Locale locale, Reporter reporter);
/** /**
* Returns a name identifying the doclet. A name is a simple identifier * Returns a name identifying the doclet. A name is a simple identifier
@ -76,14 +76,14 @@ public interface Doclet {
* *
* @return name of the Doclet * @return name of the Doclet
*/ */
public abstract String getName(); String getName();
/** /**
* Returns all the supported options. * Returns all the supported options.
* *
* @return a set containing all the supported options, an empty set if none * @return a set containing all the supported options, an empty set if none
*/ */
public Set<Option> getSupportedOptions(); Set<? extends Option> getSupportedOptions();
/** /**
* Returns the version of the Java Programming Language supported * Returns the version of the Java Programming Language supported
@ -92,7 +92,7 @@ public interface Doclet {
* @return the language version supported by this doclet, usually * @return the language version supported by this doclet, usually
* the latest version * the latest version
*/ */
public SourceVersion getSupportedSourceVersion(); SourceVersion getSupportedSourceVersion();
/** /**
* The entry point of the doclet. Further processing will commence as * The entry point of the doclet. Further processing will commence as
@ -101,7 +101,7 @@ public interface Doclet {
* @param environment from which essential information can be extracted * @param environment from which essential information can be extracted
* @return true on success * @return true on success
*/ */
public boolean run(DocletEnvironment environment); boolean run(DocletEnvironment environment);
/** /**
* An encapsulation of option name, aliases, parameters and descriptions * An encapsulation of option name, aliases, parameters and descriptions
@ -128,10 +128,12 @@ public interface Doclet {
Option.Kind getKind(); Option.Kind getKind();
/** /**
* Returns the option name. For instance for option "-group", will return "group" * Returns the list of names that may be used to identify the option. For instance, the
* @return name of the option, if set, otherwise an empty String * list could be {@code ["-classpath", "--class-path"]} for the
* option "-classpath", with an alias "--class-path".
* @return the names of the option
*/ */
String getName(); List<String> getNames();
/** /**
* Returns the parameters of the option. For instance "name &lt;p1&gt;:&lt;p2&gt;.." * Returns the parameters of the option. For instance "name &lt;p1&gt;:&lt;p2&gt;.."
@ -139,21 +141,14 @@ public interface Doclet {
*/ */
String getParameters(); String getParameters();
/**
* Checks if the given option name is handled by this option.
* @param option the option name with or without the leading "-"
* @return true if same
*/
boolean matches(String option);
/** /**
* Processes the option and arguments as needed. This method will * Processes the option and arguments as needed. This method will
* be invoked if the given option name matches the option. * be invoked if the given option name matches the option.
* @param option the option * @param option the option
* @param arguments a ListIterator encapsulating the arguments * @param arguments a list encapsulating the arguments
* @return true if operation succeeded, false otherwise * @return true if operation succeeded, false otherwise
*/ */
boolean process(String option, ListIterator<String> arguments); boolean process(String option, List<String> arguments);
/** /**
* The kind of an option. * The kind of an option.

View file

@ -25,17 +25,15 @@
package jdk.javadoc.doclet; package jdk.javadoc.doclet;
import java.util.List;
import java.util.Set; import java.util.Set;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element; 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.element.TypeElement;
import javax.lang.model.util.Elements; import javax.lang.model.util.Elements;
import javax.lang.model.util.Types; import javax.lang.model.util.Types;
import javax.tools.JavaFileManager; import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject.Kind;
import com.sun.source.util.DocTrees; import com.sun.source.util.DocTrees;
@ -48,29 +46,23 @@ import com.sun.source.util.DocTrees;
* @since 9 * @since 9
*/ */
public interface DocletEnvironment { public interface DocletEnvironment {
/**
* Returns the <a href="package-summary.html#included">included</a>
* modules.
*
* @return a set of included module elements
*/
Set<ModuleElement> getIncludedModuleElements();
/** /**
* Returns the <a href="package-summary.html#included">included</a> * Returns the elements <a href="package-summary.html#specified">specified</a>
* annotation types, classes, interfaces and enums in all packages. * when the tool is invoked.
* *
* @return a set of included type elements * @return the set of specified elements
*/ */
Set<TypeElement> getIncludedTypeElements(); Set<? extends Element> getSpecifiedElements();
/** /**
* Returns the <a href="package-summary.html#included">included</a> * Returns the module, package and type elements that should be
* packages. * <a href="package-summary.html#included">included</a> in the
* documentation.
* *
* @return a set of included package elements * @return the set of included elements
*/ */
Set<PackageElement> getIncludedPackageElements(); Set<? extends Element> getIncludedElements();
/** /**
* Returns an instance of the {@code DocTrees} utility class. * Returns an instance of the {@code DocTrees} utility class.
@ -90,25 +82,6 @@ public interface DocletEnvironment {
*/ */
Elements getElementUtils(); Elements getElementUtils();
/**
* Returns the <a href="package-summary.html#included">selected</a>
* elements that can be documented.
*
* @param elements those that need to be checked
* @return elements selected, an empty list if none
*/
List<Element> getSelectedElements(List<? extends Element> elements);
/**
* Returns the elements <a href="package-summary.html#specified">specified</a>
* on the command line, usually module elements, package elements and type elements.
* If {@code -subpackages} and {@code -exclude} options
* are used, return all the non-excluded packages.
*
* @return elements specified on the command line.
*/
Set<Element> getSpecifiedElements();
/** /**
* Returns an instance of the {@code Types} utility class. * Returns an instance of the {@code Types} utility class.
* This class provides methods for operating on * This class provides methods for operating on
@ -119,13 +92,23 @@ public interface DocletEnvironment {
Types getTypeUtils(); Types getTypeUtils();
/** /**
* Indicates if an element is <a href="package-summary.html#included">included</a>. * Returns true if an element should be
* <a href="package-summary.html#included">included</a> in the
* documentation.
* *
* @param e the Element in question * @param e the element
* @return true if included, false otherwise * @return true if included, false otherwise
*/ */
boolean isIncluded(Element e); boolean isIncluded(Element e);
/**
* Returns true if the element is <a href="package-summary.html#selected">selected</a>.
*
* @param e the element
* @return true if selected, false otherwise
*/
boolean isSelected(Element e);
/** /**
* Returns the file manager used to read and write files. * Returns the file manager used to read and write files.
* *
@ -145,7 +128,15 @@ public interface DocletEnvironment {
* *
* @return the required level of module documentation * @return the required level of module documentation
*/ */
public ModuleMode getModuleMode(); ModuleMode getModuleMode();
/**
* Returns the file kind of a type element.
*
* @param type the type element
* @return the file kind
*/
Kind getFileKind(TypeElement type);
enum ModuleMode { enum ModuleMode {
/** Indicate API level documentation is required */ /** Indicate API level documentation is required */

View file

@ -48,23 +48,46 @@
* <pre> * <pre>
* public boolean <b>run</b>(DocletEnvironment environment) * public boolean <b>run</b>(DocletEnvironment environment)
* </pre> * </pre>
* The {@link jdk.javadoc.doclet.DocletEnvironment} instance holds the environment that the * The {@link jdk.javadoc.doclet.DocletEnvironment} instance holds the
* doclet will be initialized with. From this environment all other information can be * environment that the doclet will be initialized with. From this environment
* extracted, in the form of {@link javax.lang.model} elements. One can further use the * all other information can be extracted, in the form of
* APIs and utilities described by {@link javax.lang.model} to query Elements and Types. * {@link javax.lang.model.element.Element elements}. One can further use the APIs and utilities
* described by {@link javax.lang.model Language Model API} to query Elements and Types.
* <p> * <p>
* *
* <a name="terminology"></a> * <a name="terminology"></a>
* <h3>Terminology</h3> * <h3>Terminology</h3>
* *
* <a name="specified"></a> * <dl>
* Module, package and source file names can be provided as parameters to the * <dt><a name="selected"></a>Selected</dt>
* javadoc tool -- these are called the <em>specified</em> set containing * <dd>An element is considered to be <em>selected</em>, if the
* module elements, package elements and type elements. * <em>selection controls</em> <a href="#options">allow</a> it
* to be documented. (Note that synthetic elements are never
* selected.)
* </dd>
*
* <dt><a name="specified"></a>Specified</dt>
* <dd>The set of elements specified by the user are considered to be <em>specified
* elements</em>. Specified elements provide the starting points
* for determining the <em>included elements</em> to be documented.
* </dd>
*
* <dt><a name="included"></a>Included</dt>
* <dd>An element is considered to be <em>included</em>, if it is
* <em>specified</em> if it contains a <em>specified</em> element,
* or it is enclosed in a <em>specified</em> element, and is <em>selected</em>.
* Included elements will be documented.
* </dd>
*
* </dl>
* <p> * <p>
* Javadoc <em>selection control</em> can be specified with * <a name="options"></a>
* {@code --show-members:value}, {@code --showtypes:value}, where value can be one of * <h3>Options</h3>
* the following: * Javadoc <em>selection control</em> can be specified with these options
* as follows:
* <ul>
* <li>{@code --show-members:value} and {@code --show-types:value} can
* be used to filter the members, with the following values:
* <ul> * <ul>
* <li> public -- considers only public elements * <li> public -- considers only public elements
* <li> protected -- considers public and protected elements * <li> protected -- considers public and protected elements
@ -72,41 +95,51 @@
* <li> private -- considers all elements * <li> private -- considers all elements
* </ul> * </ul>
* *
* The {@code --show-package:value} where a value of "exported" or "all" can be used to * <li>{@code --show-packages:value} "exported" or "all" can be used
* consider only exported packages or all packages within a module. * to consider only exported packages or all packages within a module.
* <p> *
* The {@code --expand-requires:value}, expands the "requires" directives of a * <li>{@code --show-module-contents:value} can be used to specify the level at
* module declaration, to create a module set to considered for documentation * module declarations could be documented. A value of "api" indicates API
* as follows: * level documentation, and "all" indicates detailed documentation.
* </ul>
* The following options can be used to specify the elements to be documented:
* <ul> * <ul>
* <li> public -- follows and expands all "requires public" edges in the module graph * <li>{@code --module} documents the specified modules.
* <li> all -- follows and expands all "requires" edges in the module graph. *
* <li>{@code --expand-requires:value} expand the set of modules to be documented
* by including some or all of the modules dependencies. The value may be
* one of:
* <ul>
* <li> public -- each module specified explicitly on the command line is
* expanded to include the closure of its transitive dependencies
* <li> all -- each module specified explicitly on the command line
* is expanded to include the closure of its transitive dependencies,
* and also all of its direct dependencies
* </ul>
* By default, only the specified modules will be considered, without expansion * By default, only the specified modules will be considered, without expansion
* of the module dependencies. * of the module dependencies.
*
* <li>{@code packagenames} can be used to specify packages.
* <li>{@code -subpackages} can be used to recursively load packages.
* <li>{@code -exclude} can be used exclude package directories.
* <li>{@code sourcefilenames} can be used to specify source file names.
* </ul> * </ul>
* <a name="included"></a>
* All of the above are used to select the elements, to produce the
* <em>included</em> or the <em>selected</em> set.
* <p>
* {@code --show-module-contents:value} can be used to specify the level at
* module declarations could be documented, a value of "api" indicates API
* level documentation, and "all" indicates detailed documentation.
* <p> * <p>
* <a name="legacy-interactions"></a> * <a name="legacy-interactions"></a>
* <h4>Interactions with older options.</h4> * <h4>Interactions with older options.</h4>
* *
* The new --show-* options provide a more detailed replacement for the older * The new {@code --show-*} options provide a more detailed replacement
* options -public, -protected, -package, -private. Alternatively, the older * for the older options -public, -protected, -package, -private.
* options can continue to be used as shorter forms for combinations of the * Alternatively, the older options can continue to be used as shorter
* new options, as described below: * forms for combinations of the new options, as described below:
<table style="font-family: monospace" border=1> <table style="font-family: monospace" border=1>
<caption>Short form options mapping</caption> <caption>Short form options mapping</caption>
<tr><th>Older option<th colspan="5">Equivalent to these values with the new option <tr><th>Older option<th colspan="5">Equivalent to these values with the new option
<tr><th><th>--show-members<th>--show-types<th>--show-packages<th>--show-module-contents <tr><th><th>{@code --show-members}<th>{@code --show-types}<th>{@code --show-packages}<th>{@code --show-module-contents}
<tr><td>-public<td>public<td>public<td>exported<td>api <tr><td>{@code -public}<td>public<td>public<td>exported<td>api
<tr><td>-protected<td>protected<td>protected<td>exported<td>api <tr><td>{@code -protected}<td>protected<td>protected<td>exported<td>api
<tr><td>-package<td>package<td>package<td>all<td>all <tr><td>{@code -package}<td>package<td>package<td>all<td>all
<tr><td>-private<td>private<td>private<td>all<td>all <tr><td>{@code -private}<td>private<td>private<td>all<td>all
</table> </table>
* <p> * <p>
* <a name="qualified"></a> * <a name="qualified"></a>
@ -119,60 +152,49 @@
* <h3>Example</h3> * <h3>Example</h3>
* *
* The following is an example doclet that displays information of a class * The following is an example doclet that displays information of a class
* and its members, supporting an option "someoption". * and its members, supporting an option.
* <pre> * <pre>
* import com.sun.source.doctree.DocCommentTree; * // note imports deleted for clarity
* import com.sun.source.util.DocTrees;
* import java.io.IOException;
* import java.util.Collections;
* import java.util.Set;
* import javax.lang.model.SourceVersion;
* import javax.lang.model.element.Element;
* import javax.lang.model.element.TypeElement;
* import jdk.javadoc.doclet.*;
*
* public class Example implements Doclet { * public class Example implements Doclet {
* * Reporter reporter;
* &#64;Override * &#64;Override
* public void init(Locale locale, Reporter reporter) { * public void init(Locale locale, Reporter reporter) {
* return; * reporter.print(Kind.NOTE, "Doclet using locale: " + locale);
* this.reporter = reporter;
* }
*
* public void printElement(DocTrees trees, Element e) {
* DocCommentTree docCommentTree = trees.getDocCommentTree(e);
* if (docCommentTree != null) {
* System.out.println("Element (" + e.getKind() + ": "
* + e + ") has the following comments:");
* System.out.println("Entire body: " + docCommentTree.getFullBody());
* System.out.println("Block tags: " + docCommentTree.getBlockTags());
* }
* } * }
* *
* &#64;Override * &#64;Override
* public boolean run(DocletEnvironment docEnv) { * public boolean run(DocletEnvironment docEnv) {
* // cache the DocTrees utility class to access DocComments * reporter.print(Kind.NOTE, "overviewfile: " + overviewfile);
* // get the DocTrees utility class to access document comments
* DocTrees docTrees = docEnv.getDocTrees(); * DocTrees docTrees = docEnv.getDocTrees();
* *
* // location of an element in the same directory as overview.html * // location of an element in the same directory as overview.html
* try { * try {
* Element barElement = null; * Element e = ElementFilter.typesIn(docEnv.getSpecifiedElements()).iterator().next();
* for (Element e : docEnv.getIncludedClasses()) { * DocCommentTree docCommentTree
* if (e.getSimpleName().toString().equals("FooBar")) { * = docTrees.getDocCommentTree(e, overviewfile);
* barElement = e;
* }
* }
* DocCommentTree docCommentTree =
* docTrees.getDocCommentTree(barElement, "overview.html");
* if (docCommentTree != null) { * if (docCommentTree != null) {
* System.out.println("Overview html: " + * System.out.println("Overview html: " + docCommentTree.getFullBody());
* docCommentTree.getFullBody());
* } * }
* } catch (IOException missing) { * } catch (IOException missing) {
* System.err.println("No overview.html found."); * reporter.print(Kind.ERROR, "No overview.html found.");
* } * }
* *
* for (TypeElement t : docEnv.getIncludedClasses()) { * for (TypeElement t : ElementFilter.typesIn(docEnv.getIncludedElements())) {
* System.out.println(t.getKind() + ":" + t); * System.out.println(t.getKind() + ":" + t);
* for (Element e : t.getEnclosedElements()) { * for (Element e : t.getEnclosedElements()) {
* DocCommentTree docCommentTree = docTrees.getDocCommentTree(e); * printElement(docTrees, e);
* if (docCommentTree != null) {
* System.out.println("Element (" + e.getKind() + ": " +
* e + ") has the following comments:");
* System.out.println("Entire body: " + docCommentTree.getFullBody());
* System.out.println("Block tags: " + docCommentTree.getBlockTags());
* } else {
* System.out.println("no comment.");
* }
* } * }
* } * }
* return true; * return true;
@ -183,38 +205,51 @@
* return "Example"; * return "Example";
* } * }
* *
* private String someOption; * private String overviewfile;
* *
* &#64;Override * &#64;Override
* public Set&lt;Option&gt; getSupportedOptions() { * public Set&lt;? extends Option&gt; getSupportedOptions() {
* Option[] options = { * Option[] options = {
* new Option() { * new Option() {
* private final List&lt;String&gt; someOption = Arrays.asList(
* "-overviewfile",
* "--overview-file",
* "-o"
* );
*
* &#64;Override
* public int getArgumentCount() { * public int getArgumentCount() {
* return 1; * return 1;
* } * }
*
* &#64;Override
* public String getDescription() { * public String getDescription() {
* return "someoption"; * return "an option with aliases";
* } * }
*
* &#64;Override
* public Option.Kind getKind() { * public Option.Kind getKind() {
* return Option.Kind.STANDARD; * return Option.Kind.STANDARD;
* } * }
* public String getName() { *
* return "someoption"; * &#64;Override
* public List&lt;String&gt; getNames() {
* return someOption;
* } * }
*
* &#64;Override
* public String getParameters() { * public String getParameters() {
* return "url"; * return "file";
* } * }
* public boolean matches(String option) { *
* String opt = option.startsWith("-") ? option.substring(1) : option; * &#64;Override
* return getName().equals(opt); * public boolean process(String opt, List&lt;String&gt; arguments) {
* } * overviewfile = arguments.get(0);
* public boolean process(String option, ListIterator&lt;String&gt; arguments) {
* overviewpath = arguments.next();
* return true; * return true;
* } * }
* } * }
* }; * };
* return new HashSet&lt;Option&gt;(Arrays.asList(options)); * return new HashSet&lt;&gt;(Arrays.asList(options));
* } * }
* *
* &#64;Override * &#64;Override
@ -225,21 +260,12 @@
* } * }
* </pre> * </pre>
* <p> * <p>
* This doclet when invoked with a command line, such as: * This doclet can be invoked with a command line, such as:
* <pre> * <pre>
* javadoc -doclet Example -sourcepath &lt;source-location&gt; * javadoc -doclet Example &#92;
* </pre> * -overviewfile overview.html &#92;
* will produce an output, such as: * -sourcepath source-location &#92;
* <pre> * source-location/Example.java
* Overview.html: overview comments
* ...
* ...
* CLASS: SomeKlass
* .....
* Element (METHOD: main(java.lang.String...)) has the following comments:
* Entire body: The main entry point.
* Block tags: @param an array of Strings
* ...
* </pre> * </pre>
* *
* <h3><a name="migration">Migration Guide</a></h3> * <h3><a name="migration">Migration Guide</a></h3>

View file

@ -54,13 +54,13 @@ public interface Taglet {
* @return true if this <code>Taglet</code> * @return true if this <code>Taglet</code>
* is an inline tag, false otherwise. * is an inline tag, false otherwise.
*/ */
public abstract boolean isInlineTag(); boolean isInlineTag();
/** /**
* Returns the name of the tag. * Returns the name of the tag.
* @return the name of this custom tag. * @return the name of this custom tag.
*/ */
public abstract String getName(); String getName();
/** /**
* Given the {@link DocTree DocTree} representation of this custom * Given the {@link DocTree DocTree} representation of this custom
@ -69,7 +69,7 @@ public interface Taglet {
* @param tag the <code>Tag</code> representation of this custom tag. * @param tag the <code>Tag</code> representation of this custom tag.
* @return the string representation of this <code>Tag</code>. * @return the string representation of this <code>Tag</code>.
*/ */
public abstract String toString(DocTree tag); String toString(DocTree tag);
/** /**
* Given a List of {@link DocTree DocTrees} representing this custom * Given a List of {@link DocTree DocTrees} representing this custom
@ -79,7 +79,7 @@ public interface Taglet {
* @param tags the list of <code>DocTree</code>s representing this custom tag. * @param tags the list of <code>DocTree</code>s representing this custom tag.
* @return the string representation of this <code>Tag</code>. * @return the string representation of this <code>Tag</code>.
*/ */
public abstract String toString(List<? extends DocTree> tags); String toString(List<? extends DocTree> tags);
/** /**
* The kind of location. * The kind of location.

View file

@ -52,6 +52,7 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocPath; import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
/** /**
* Generate class usage information. * Generate class usage information.
* *
@ -178,7 +179,7 @@ public class ClassUseWriter extends SubWriterHolderWriter {
*/ */
public static void generate(ConfigurationImpl configuration, ClassTree classtree) throws DocFileIOException { public static void generate(ConfigurationImpl configuration, ClassTree classtree) throws DocFileIOException {
ClassUseMapper mapper = new ClassUseMapper(configuration, classtree); ClassUseMapper mapper = new ClassUseMapper(configuration, classtree);
for (TypeElement aClass : configuration.docEnv.getIncludedTypeElements()) { for (TypeElement aClass : configuration.getIncludedTypeElements()) {
// If -nodeprecated option is set and the containing package is marked // If -nodeprecated option is set and the containing package is marked
// as deprecated, do not generate the class-use page. We will still generate // as deprecated, do not generate the class-use page. We will still generate
// the class-use page if the class is marked as deprecated but the containing // the class-use page if the class is marked as deprecated but the containing

View file

@ -288,83 +288,13 @@ public class ConfigurationImpl extends Configuration {
if (!generalValidOptions()) { if (!generalValidOptions()) {
return false; return false;
} }
boolean helpfileSeen = false; // check if helpfile exists
// otherwise look at our options if (!helpfile.isEmpty()) {
for (Doclet.Option opt : optionsProcessed) {
if (opt.matches("-helpfile")) {
if (nohelp == true) {
reporter.print(ERROR, getText("doclet.Option_conflict",
"-helpfile", "-nohelp"));
return false;
}
if (helpfileSeen) {
reporter.print(ERROR, getText("doclet.Option_reuse",
"-helpfile"));
return false;
}
helpfileSeen = true;
DocFile help = DocFile.createFileForInput(this, helpfile); DocFile help = DocFile.createFileForInput(this, helpfile);
if (!help.exists()) { if (!help.exists()) {
reporter.print(ERROR, getText("doclet.File_not_found", helpfile)); reporter.print(ERROR, getText("doclet.File_not_found", helpfile));
return false; return false;
} }
} else if (opt.matches("-nohelp")) {
if (helpfileSeen) {
reporter.print(ERROR, getText("doclet.Option_conflict",
"-nohelp", "-helpfile"));
return false;
}
} else if (opt.matches("-xdocrootparent")) {
try {
URL ignored = new URL(docrootparent);
} catch (MalformedURLException e) {
reporter.print(ERROR, getText("doclet.MalformedURL", docrootparent));
return false;
}
} else if (opt.matches("-overview")) {
if (nooverview == true) {
reporter.print(ERROR, getText("doclet.Option_conflict",
"-overview", "-nooverview"));
return false;
}
} else if (opt.matches("-nooverview")) {
if (overviewpath != null) {
reporter.print(ERROR, getText("doclet.Option_conflict",
"-nooverview", "-overview"));
return false;
}
} else if (opt.matches("-splitindex")) {
if (createindex == false) {
reporter.print(ERROR, getText("doclet.Option_conflict",
"-splitindex", "-noindex"));
return false;
}
} else if (opt.matches("-noindex")) {
if (splitindex == true) {
reporter.print(ERROR, getText("doclet.Option_conflict",
"-noindex", "-splitindex"));
return false;
}
} else if (opt.matches("-xdoclint:")) {
String dopt = doclintOpts.get(opt);
if (dopt == null) {
continue;
}
if (dopt.contains("/")) {
reporter.print(ERROR, getText("doclet.Option_doclint_no_qualifiers"));
return false;
}
if (!DocLint.isValidOption(dopt)) {
reporter.print(ERROR, getText("doclet.Option_doclint_invalid_arg"));
return false;
}
} else if (opt.matches("-xdoclint/package:")) {
String dopt = doclintOpts.get(opt);
if (!DocLint.isValidOption(dopt)) {
reporter.print(ERROR, getText("doclet.Option_doclint_package_invalid_arg"));
return false;
}
}
} }
return true; return true;
} }
@ -374,11 +304,10 @@ public class ConfigurationImpl extends Configuration {
if (!validateOptions()) { if (!validateOptions()) {
return false; return false;
} }
if (!docEnv.getSpecifiedElements().isEmpty()) { if (!getSpecifiedTypeElements().isEmpty()) {
Map<String, PackageElement> map = new HashMap<>(); Map<String, PackageElement> map = new HashMap<>();
PackageElement pkg; PackageElement pkg;
List<TypeElement> classes = new ArrayList<>(docEnv.getIncludedTypeElements()); for (TypeElement aClass : getIncludedTypeElements()) {
for (TypeElement aClass : classes) {
pkg = utils.containingPackage(aClass); pkg = utils.containingPackage(aClass);
if (!map.containsKey(utils.getPackageName(pkg))) { if (!map.containsKey(utils.getPackageName(pkg))) {
map.put(utils.getPackageName(pkg), pkg); map.put(utils.getPackageName(pkg), pkg);
@ -426,7 +355,7 @@ public class ConfigurationImpl extends Configuration {
if (showModules) { if (showModules) {
topFile = DocPath.empty.resolve(DocPaths.moduleSummary(modules.first())); topFile = DocPath.empty.resolve(DocPaths.moduleSummary(modules.first()));
} else if (packages.size() == 1 && packages.first().isUnnamed()) { } else if (packages.size() == 1 && packages.first().isUnnamed()) {
List<TypeElement> classes = new ArrayList<>(docEnv.getIncludedTypeElements()); List<TypeElement> classes = new ArrayList<>(getIncludedTypeElements());
if (!classes.isEmpty()) { if (!classes.isEmpty()) {
TypeElement te = getValidClass(classes); TypeElement te = getValidClass(classes);
topFile = DocPath.forClass(utils, te); topFile = DocPath.forClass(utils, te);
@ -450,7 +379,7 @@ public class ConfigurationImpl extends Configuration {
} }
protected boolean checkForDeprecation(DocletEnvironment docEnv) { protected boolean checkForDeprecation(DocletEnvironment docEnv) {
for (TypeElement te : docEnv.getIncludedTypeElements()) { for (TypeElement te : getIncludedTypeElements()) {
if (isGeneratedDoc(te)) { if (isGeneratedDoc(te)) {
return true; return true;
} }
@ -597,227 +526,245 @@ public class ConfigurationImpl extends Configuration {
Doclet.Option[] options = { Doclet.Option[] options = {
new Option(resources, "-bottom", 1) { new Option(resources, "-bottom", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); bottom = args.get(0);
bottom = args.next();
return true; return true;
} }
}, },
new Option(resources, "-charset", 1) { new Option(resources, "-charset", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); charset = args.get(0);
charset = args.next();
return true; return true;
} }
}, },
new Option(resources, "-doctitle", 1) { new Option(resources, "-doctitle", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); doctitle = args.get(0);
doctitle = args.next();
return true; return true;
} }
}, },
new Option(resources, "-footer", 1) { new Option(resources, "-footer", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); footer = args.get(0);
footer = args.next();
return true; return true;
} }
}, },
new Option(resources, "-header", 1) { new Option(resources, "-header", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); header = args.get(0);
header = args.next();
return true; return true;
} }
}, },
new Option(resources, "-helpfile", 1) { new Option(resources, "-helpfile", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); if (nohelp == true) {
helpfile = args.next(); reporter.print(ERROR, getText("doclet.Option_conflict",
"-helpfile", "-nohelp"));
return false;
}
if (!helpfile.isEmpty()) {
reporter.print(ERROR, getText("doclet.Option_reuse",
"-helpfile"));
return false;
}
helpfile = args.get(0);
return true; return true;
} }
}, },
new Option(resources, "-html4") { new Option(resources, "-html4") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
htmlVersion = HtmlVersion.HTML4; htmlVersion = HtmlVersion.HTML4;
return true; return true;
} }
}, },
new Option(resources, "-html5") { new Option(resources, "-html5") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
htmlVersion = HtmlVersion.HTML5; htmlVersion = HtmlVersion.HTML5;
return true; return true;
} }
}, },
new Option(resources, "-nohelp") { new Option(resources, "-nohelp") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
nohelp = true; nohelp = true;
if (!helpfile.isEmpty()) {
reporter.print(ERROR, getText("doclet.Option_conflict",
"-nohelp", "-helpfile"));
return false;
}
return true; return true;
} }
}, },
new Option(resources, "-nodeprecatedlist") { new Option(resources, "-nodeprecatedlist") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
nodeprecatedlist = true; nodeprecatedlist = true;
return true; return true;
} }
}, },
new Option(resources, "-noindex") { new Option(resources, "-noindex") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
createindex = false; createindex = false;
if (splitindex == true) {
reporter.print(ERROR, getText("doclet.Option_conflict",
"-noindex", "-splitindex"));
return false;
}
return true; return true;
} }
}, },
new Option(resources, "-nonavbar") { new Option(resources, "-nonavbar") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
nonavbar = true; nonavbar = true;
return true; return true;
} }
}, },
new Hidden(resources, "-nooverview") { new Hidden(resources, "-nooverview") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
nooverview = true; nooverview = true;
if (overviewpath != null) {
reporter.print(ERROR, getText("doclet.Option_conflict",
"-nooverview", "-overview"));
return false;
}
return true; return true;
} }
}, },
new Option(resources, "-notree") { new Option(resources, "-notree") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
createtree = false; createtree = false;
return true; return true;
} }
}, },
new Option(resources, "-overview", 1) { new Option(resources, "-overview", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); overviewpath = args.get(0);
overviewpath = args.next(); if (nooverview == true) {
reporter.print(ERROR, getText("doclet.Option_conflict",
"-overview", "-nooverview"));
return false;
}
return true; return true;
} }
}, },
new Option(resources, "--frames") { new Option(resources, "--frames") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
frames = true; frames = true;
return true; return true;
} }
}, },
new Option(resources, "--no-frames") { new Option(resources, "--no-frames") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
frames = false; frames = false;
return true; return true;
} }
}, },
new Hidden(resources, "-packagesheader", 1) { new Hidden(resources, "-packagesheader", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); packagesheader = args.get(0);
packagesheader = args.next();
return true; return true;
} }
}, },
new Option(resources, "-splitindex") { new Option(resources, "-splitindex") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
splitindex = true; splitindex = true;
if (createindex == false) {
reporter.print(ERROR, getText("doclet.Option_conflict",
"-splitindex", "-noindex"));
return false;
}
return true; return true;
} }
}, },
new Option(resources, "-stylesheetfile", 1) { new Option(resources, "-stylesheetfile", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); stylesheetfile = args.get(0);
stylesheetfile = args.next();
return true; return true;
} }
}, },
new Option(resources, "-top", 1) { new Option(resources, "-top", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); top = args.get(0);
top = args.next();
return true; return true;
} }
}, },
new Option(resources, "-use") { new Option(resources, "-use") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
classuse = true; classuse = true;
return true; return true;
} }
}, },
new Option(resources, "-windowtitle", 1) { new Option(resources, "-windowtitle", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); windowtitle = args.get(0).replaceAll("\\<.*?>", "");
windowtitle = args.next().replaceAll("\\<.*?>", "");
return true; return true;
} }
}, },
new XOption(resources, "-Xdoclint") { new XOption(resources, "-Xdoclint") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
doclintOpts.put(this, DocLint.XMSGS_OPTION); doclintOpts.put(this, DocLint.XMSGS_OPTION);
return true; return true;
} }
}, },
new XOption(resources, "-Xdocrootparent", 1) { new XOption(resources, "-Xdocrootparent", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); docrootparent = args.get(0);
docrootparent = args.next(); try {
URL ignored = new URL(docrootparent);
} catch (MalformedURLException e) {
reporter.print(ERROR, getText("doclet.MalformedURL", docrootparent));
return false;
}
return true; return true;
} }
}, },
new XOption(resources, "doclet.usage.xdoclint-extended", "-Xdoclint:", 0) { new XOption(resources, "doclet.usage.xdoclint-extended", "-Xdoclint:", 0) {
@Override @Override
public boolean matches(String option) { public boolean process(String opt, List<String> args) {
return option.toLowerCase().startsWith(getName().toLowerCase()); String dopt = opt.replace("-Xdoclint:", DocLint.XMSGS_CUSTOM_PREFIX);
doclintOpts.put(this, dopt);
if (dopt.contains("/")) {
reporter.print(ERROR, getText("doclet.Option_doclint_no_qualifiers"));
return false;
}
if (!DocLint.isValidOption(dopt)) {
reporter.print(ERROR, getText("doclet.Option_doclint_invalid_arg"));
return false;
} }
@Override
public boolean process(String opt, ListIterator<String> args) {
optionsProcessed.add(this);
doclintOpts.put(this, opt.replace("-Xdoclint:", DocLint.XMSGS_CUSTOM_PREFIX));
return true; return true;
} }
}, },
new XOption(resources, "doclet.usage.xdoclint-package", "-Xdoclint/package:", 0) { new XOption(resources, "doclet.usage.xdoclint-package", "-Xdoclint/package:", 0) {
@Override @Override
public boolean matches(String option) { public boolean process(String opt, List<String> args) {
return option.toLowerCase().startsWith(getName().toLowerCase()); String dopt = opt.replace("-Xdoclint/package:", DocLint.XCHECK_PACKAGE);
doclintOpts.put(this, dopt);
if (!DocLint.isValidOption(dopt)) {
reporter.print(ERROR, getText("doclet.Option_doclint_package_invalid_arg"));
return false;
} }
@Override
public boolean process(String opt, ListIterator<String> args) {
optionsProcessed.add(this);
doclintOpts.put(this, opt.replace("-Xdoclint/package:", DocLint.XCHECK_PACKAGE));
return true; return true;
} }
} }

View file

@ -91,10 +91,11 @@ public class HtmlDoclet extends AbstractDoclet {
* Create the configuration instance. * Create the configuration instance.
* Override this method to use a different * Override this method to use a different
* configuration. * configuration.
* @return the configuration for this doclet *
* @return the configuration
*/ */
@Override // defined by AbstractDoclet @Override // defined by AbstractDoclet
public ConfigurationImpl configuration() { public ConfigurationImpl getConfiguration() {
return configuration; return configuration;
} }
@ -166,8 +167,7 @@ public class HtmlDoclet extends AbstractDoclet {
IndexRedirectWriter.generate(configuration); IndexRedirectWriter.generate(configuration);
} }
if (configuration.helpfile.length() == 0 && if (configuration.helpfile.isEmpty() && !configuration.nohelp) {
!configuration.nohelp) {
HelpWriter.generate(configuration); HelpWriter.generate(configuration);
} }
// If a stylesheet file is not specified, copy the default stylesheet // If a stylesheet file is not specified, copy the default stylesheet

View file

@ -826,8 +826,8 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @return a content tree for the link * @return a content tree for the link
*/ */
protected Content getNavLinkTree() { protected Content getNavLinkTree() {
List<PackageElement> packages = new ArrayList<>(configuration.getSpecifiedPackages()); List<PackageElement> packages = new ArrayList<>(configuration.getSpecifiedPackageElements());
DocPath docPath = packages.size() == 1 && configuration.getSpecifiedClasses().isEmpty() DocPath docPath = packages.size() == 1 && configuration.getSpecifiedTypeElements().isEmpty()
? pathString(packages.get(0), DocPaths.PACKAGE_TREE) ? pathString(packages.get(0), DocPaths.PACKAGE_TREE)
: pathToRoot.resolve(DocPaths.OVERVIEW_TREE); : pathToRoot.resolve(DocPaths.OVERVIEW_TREE);
return HtmlTree.LI(getHyperLink(docPath, contents.treeLabel, "", "")); return HtmlTree.LI(getHyperLink(docPath, contents.treeLabel, "", ""));

View file

@ -32,6 +32,7 @@ import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementFilter; import javax.lang.model.util.ElementFilter;
import jdk.javadoc.doclet.DocletEnvironment;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
@ -41,7 +42,6 @@ import jdk.javadoc.internal.doclets.toolkit.Content;
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException; import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
/** /**
* Class to generate file for each module contents in the left-hand bottom * Class to generate file for each module contents in the left-hand bottom
* frame. This will list all the Class Kinds in the module. A click on any * frame. This will list all the Class Kinds in the module. A click on any
@ -78,9 +78,9 @@ public class ModuleFrameWriter extends HtmlDocletWriter {
public ModuleFrameWriter(ConfigurationImpl configuration, ModuleElement moduleElement) { public ModuleFrameWriter(ConfigurationImpl configuration, ModuleElement moduleElement) {
super(configuration, DocPaths.moduleTypeFrame(moduleElement)); super(configuration, DocPaths.moduleTypeFrame(moduleElement));
this.mdle = moduleElement; this.mdle = moduleElement;
if (configuration.getSpecifiedPackages().isEmpty()) { if (configuration.getSpecifiedPackageElements().isEmpty()) {
documentedClasses = new TreeSet<>(utils.makeGeneralPurposeComparator()); documentedClasses = new TreeSet<>(utils.makeGeneralPurposeComparator());
documentedClasses.addAll(configuration.docEnv.getIncludedTypeElements()); documentedClasses.addAll(configuration.getIncludedTypeElements());
} }
} }

View file

@ -30,6 +30,7 @@ import java.util.*;
import javax.lang.model.element.PackageElement; import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import jdk.javadoc.doclet.DocletEnvironment;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlConstants;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle;
import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag; import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTag;
@ -41,7 +42,6 @@ import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
import jdk.javadoc.internal.doclets.toolkit.util.DocPath; import jdk.javadoc.internal.doclets.toolkit.util.DocPath;
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths; import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
/** /**
* Class to generate file for each package contents in the left-hand bottom * Class to generate file for each package contents in the left-hand bottom
* frame. This will list all the Class Kinds in the package. A click on any * frame. This will list all the Class Kinds in the package. A click on any
@ -82,9 +82,9 @@ public class PackageFrameWriter extends HtmlDocletWriter {
public PackageFrameWriter(ConfigurationImpl configuration, PackageElement packageElement) { public PackageFrameWriter(ConfigurationImpl configuration, PackageElement packageElement) {
super(configuration, DocPath.forPackage(packageElement).resolve(DocPaths.PACKAGE_FRAME)); super(configuration, DocPath.forPackage(packageElement).resolve(DocPaths.PACKAGE_FRAME));
this.packageElement = packageElement; this.packageElement = packageElement;
if (configuration.getSpecifiedPackages().isEmpty()) { if (configuration.getSpecifiedPackageElements().isEmpty()) {
documentedClasses = new TreeSet<>(utils.makeGeneralPurposeComparator()); documentedClasses = new TreeSet<>(utils.makeGeneralPurposeComparator());
documentedClasses.addAll(configuration.docEnv.getIncludedTypeElements()); documentedClasses.addAll(configuration.getIncludedTypeElements());
} }
} }

View file

@ -66,7 +66,7 @@ public class SerializedFormWriterImpl extends SubWriterHolderWriter
*/ */
public SerializedFormWriterImpl(ConfigurationImpl configuration) { public SerializedFormWriterImpl(ConfigurationImpl configuration) {
super(configuration, DocPaths.SERIALIZED_FORM); super(configuration, DocPaths.SERIALIZED_FORM);
visibleClasses = configuration.docEnv.getIncludedTypeElements(); visibleClasses = configuration.getIncludedTypeElements();
} }
/** /**

View file

@ -115,13 +115,13 @@ public class SourceToHTMLConverter {
if (docEnv == null || outputdir == null) { if (docEnv == null || outputdir == null) {
return; return;
} }
for (PackageElement pkg : configuration.getSpecifiedPackages()) { for (PackageElement pkg : configuration.getSpecifiedPackageElements()) {
// If -nodeprecated option is set and the package is marked as deprecated, // If -nodeprecated option is set and the package is marked as deprecated,
// do not convert the package files to HTML. // do not convert the package files to HTML.
if (!(configuration.nodeprecated && utils.isDeprecated(pkg))) if (!(configuration.nodeprecated && utils.isDeprecated(pkg)))
convertPackage(pkg, outputdir); convertPackage(pkg, outputdir);
} }
for (TypeElement te : configuration.getSpecifiedClasses()) { for (TypeElement te : configuration.getSpecifiedTypeElements()) {
// If -nodeprecated option is set and the class is marked as deprecated // If -nodeprecated option is set and the class is marked as deprecated
// or the containing package is deprecated, do not convert the // or the containing package is deprecated, do not convert the
// package files to HTML. // package files to HTML.

View file

@ -99,8 +99,8 @@ public abstract class AbstractDoclet implements Doclet {
*/ */
@Override @Override
public boolean run(DocletEnvironment docEnv) { public boolean run(DocletEnvironment docEnv) {
configuration = configuration(); configuration = getConfiguration();
configuration.docEnv = docEnv; configuration.initConfiguration(docEnv);
configuration.cmtUtils = new CommentUtils(configuration); configuration.cmtUtils = new CommentUtils(configuration);
configuration.utils = new Utils(configuration); configuration.utils = new Utils(configuration);
utils = configuration.utils; utils = configuration.utils;
@ -171,13 +171,12 @@ public abstract class AbstractDoclet implements Doclet {
return SourceVersion.RELEASE_9; return SourceVersion.RELEASE_9;
} }
/** /**
* Create the configuration instance and returns it. * Create the configuration instance and returns it.
* *
* @return the configuration of the doclet. * @return the configuration of the doclet.
*/ */
public abstract Configuration configuration(); public abstract Configuration getConfiguration();
/** /**
* Start the generation of files. Call generate methods in the individual * Start the generation of files. Call generate methods in the individual
@ -189,7 +188,7 @@ public abstract class AbstractDoclet implements Doclet {
* @throws DocletException if there is a problem while generating the documentation * @throws DocletException if there is a problem while generating the documentation
*/ */
private void startGeneration(DocletEnvironment docEnv) throws DocletException { private void startGeneration(DocletEnvironment docEnv) throws DocletException {
if (docEnv.getIncludedTypeElements().isEmpty()) { if (configuration.getIncludedTypeElements().isEmpty()) {
messages.error("doclet.No_Public_Classes_To_Document"); messages.error("doclet.No_Public_Classes_To_Document");
return; return;
} }
@ -263,7 +262,7 @@ public abstract class AbstractDoclet implements Doclet {
throws DocletException { throws DocletException {
generateClassFiles(classtree); generateClassFiles(classtree);
SortedSet<PackageElement> packages = new TreeSet<>(utils.makePackageComparator()); SortedSet<PackageElement> packages = new TreeSet<>(utils.makePackageComparator());
packages.addAll(configuration.getSpecifiedPackages()); packages.addAll(configuration.getSpecifiedPackageElements());
configuration.modulePackages.values().stream().forEach(pset -> { configuration.modulePackages.values().stream().forEach(pset -> {
packages.addAll(pset); packages.addAll(pset);
}); });

View file

@ -33,10 +33,13 @@ import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement; import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementFilter; import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.SimpleElementVisitor9;
import javax.tools.JavaFileManager; import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import com.sun.source.util.DocTreePath; import com.sun.source.util.DocTreePath;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import jdk.javadoc.doclet.Doclet; import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.DocletEnvironment; import jdk.javadoc.doclet.DocletEnvironment;
import jdk.javadoc.doclet.Reporter; import jdk.javadoc.doclet.Reporter;
@ -96,7 +99,7 @@ public abstract class Configuration {
/** /**
* The path to Taglets * The path to Taglets
*/ */
public String tagletpath = ""; public String tagletpath = null;
/** /**
* This is true if option "-serialwarn" is used. Defualt value is false to * This is true if option "-serialwarn" is used. Defualt value is false to
@ -312,9 +315,7 @@ public abstract class Configuration {
*/ */
public SortedSet<PackageElement> packages = null; public SortedSet<PackageElement> packages = null;
protected final List<Doclet.Option> optionsProcessed; public OverviewElement overviewElement;
public final OverviewElement overviewElement;
// The following three fields provide caches for use by all instances of VisibleMemberMap. // The following three fields provide caches for use by all instances of VisibleMemberMap.
public final Map<TypeElement, List<Element>> propertiesCache = new HashMap<>(); public final Map<TypeElement, List<Element>> propertiesCache = new HashMap<>();
@ -336,16 +337,34 @@ public abstract class Configuration {
protected static final String sharedResourceBundleName = protected static final String sharedResourceBundleName =
"jdk.javadoc.internal.doclets.toolkit.resources.doclets"; "jdk.javadoc.internal.doclets.toolkit.resources.doclets";
/** /**
* Constructor. Constructs the message retriever with resource file. * Constructs the configurations needed by the doclet.
*/ */
public Configuration() { public Configuration() {
excludedDocFileDirs = new HashSet<>(); excludedDocFileDirs = new HashSet<>();
excludedQualifiers = new HashSet<>(); excludedQualifiers = new HashSet<>();
setTabWidth(DocletConstants.DEFAULT_TAB_STOP_LENGTH); setTabWidth(DocletConstants.DEFAULT_TAB_STOP_LENGTH);
metakeywords = new MetaKeywords(this); metakeywords = new MetaKeywords(this);
optionsProcessed = new ArrayList<>();
groups = new ArrayList<>(0); groups = new ArrayList<>(0);
}
private boolean initialized = false;
protected void initConfiguration(DocletEnvironment docEnv) {
if (initialized) {
throw new IllegalStateException("configuration previously initialized");
}
initialized = true;
this.docEnv = docEnv;
overviewElement = new OverviewElement(docEnv); overviewElement = new OverviewElement(docEnv);
Splitter specifiedSplitter = new Splitter(docEnv, false);
specifiedModuleElements = Collections.unmodifiableSet(specifiedSplitter.mset);
specifiedPackageElements = Collections.unmodifiableSet(specifiedSplitter.pset);
specifiedTypeElements = Collections.unmodifiableSet(specifiedSplitter.tset);
Splitter includedSplitter = new Splitter(docEnv, true);
includedModuleElements = Collections.unmodifiableSet(includedSplitter.mset);
includedPackageElements = Collections.unmodifiableSet(includedSplitter.pset);
includedTypeElements = Collections.unmodifiableSet(includedSplitter.tset);
} }
/** /**
@ -364,10 +383,40 @@ public abstract class Configuration {
return this.reporter; return this.reporter;
} }
private Set<ModuleElement> specifiedModuleElements;
public Set<ModuleElement> getSpecifiedModuleElements() {
return specifiedModuleElements;
}
private Set<PackageElement> specifiedPackageElements;
public Set<PackageElement> getSpecifiedPackageElements() {
return specifiedPackageElements;
}
private Set<TypeElement> specifiedTypeElements;
public Set<TypeElement> getSpecifiedTypeElements() {
return specifiedTypeElements;
}
private Set<ModuleElement> includedModuleElements;
public Set<ModuleElement> getIncludedModuleElements() {
return includedModuleElements;
}
private Set<PackageElement> includedPackageElements;
public Set<PackageElement> getIncludedPackageElements() {
return includedPackageElements;
}
private Set<TypeElement> includedTypeElements;
public Set<TypeElement> getIncludedTypeElements() {
return includedTypeElements;
}
private void initModules() { private void initModules() {
// Build the modules structure used by the doclet // Build the modules structure used by the doclet
modules = new TreeSet<>(utils.makeModuleComparator()); modules = new TreeSet<>(utils.makeModuleComparator());
modules.addAll(getSpecifiedModules()); modules.addAll(getSpecifiedModuleElements());
modulePackages = new TreeMap<>(utils.makeModuleComparator()); modulePackages = new TreeMap<>(utils.makeModuleComparator());
for (PackageElement p: packages) { for (PackageElement p: packages) {
@ -379,7 +428,7 @@ public abstract class Configuration {
} }
} }
for (PackageElement p: docEnv.getIncludedPackageElements()) { for (PackageElement p: getIncludedPackageElements()) {
ModuleElement mdle = docEnv.getElementUtils().getModuleOf(p); ModuleElement mdle = docEnv.getElementUtils().getModuleOf(p);
if (mdle != null && !mdle.isUnnamed()) { if (mdle != null && !mdle.isUnnamed()) {
Set<PackageElement> s = modulePackages Set<PackageElement> s = modulePackages
@ -398,7 +447,7 @@ public abstract class Configuration {
private void initPackages() { private void initPackages() {
packages = new TreeSet<>(utils.makePackageComparator()); packages = new TreeSet<>(utils.makePackageComparator());
// add all the included packages // add all the included packages
packages.addAll(docEnv.getIncludedPackageElements()); packages.addAll(includedPackageElements);
} }
public Set<Doclet.Option> getSupportedOptions() { public Set<Doclet.Option> getSupportedOptions() {
@ -406,165 +455,145 @@ public abstract class Configuration {
Doclet.Option[] options = { Doclet.Option[] options = {
new Option(resources, "-author") { new Option(resources, "-author") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
showauthor = true; showauthor = true;
return true; return true;
} }
}, },
new Option(resources, "-d", 1) { new Option(resources, "-d", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); destDirName = addTrailingFileSep(args.get(0));
destDirName = addTrailingFileSep(args.next());
return true; return true;
} }
}, },
new Option(resources, "-docencoding", 1) { new Option(resources, "-docencoding", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); docencoding = args.get(0);
docencoding = args.next();
return true; return true;
} }
}, },
new Option(resources, "-docfilessubdirs") { new Option(resources, "-docfilessubdirs") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
copydocfilesubdirs = true; copydocfilesubdirs = true;
return true; return true;
} }
}, },
new Hidden(resources, "-encoding", 1) { new Hidden(resources, "-encoding", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); encoding = args.get(0);
encoding = args.next();
return true; return true;
} }
}, },
new Option(resources, "-excludedocfilessubdir", 1) { new Option(resources, "-excludedocfilessubdir", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); addToSet(excludedDocFileDirs, args.get(0));
addToSet(excludedDocFileDirs, args.next());
return true; return true;
} }
}, },
new Option(resources, "-group", 2) { new Option(resources, "-group", 2) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); groups.add(new GroupContainer(args.get(0), args.get(1)));
groups.add(new GroupContainer(args.next(), args.next()));
return true; return true;
} }
}, },
new Hidden(resources, "-javafx") { new Hidden(resources, "-javafx") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
javafx = true; javafx = true;
return true; return true;
} }
}, },
new Option(resources, "-keywords") { new Option(resources, "-keywords") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
keywords = true; keywords = true;
return true; return true;
} }
}, },
new Option(resources, "-link", 1) { new Option(resources, "-link", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); urlForLink = args.get(0);
urlForLink = args.next();
pkglistUrlForLink = urlForLink; pkglistUrlForLink = urlForLink;
return true; return true;
} }
}, },
new Option(resources, "-linksource") { new Option(resources, "-linksource") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
linksource = true; linksource = true;
return true; return true;
} }
}, },
new Option(resources, "-linkoffline", 2) { new Option(resources, "-linkoffline", 2) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); urlForLinkOffline = args.get(0);
urlForLinkOffline = args.next(); pkglistUrlForLinkOffline = args.get(1);
pkglistUrlForLinkOffline = args.next();
return true; return true;
} }
}, },
new Option(resources, "-nocomment") { new Option(resources, "-nocomment") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
nocomment = true; nocomment = true;
return true; return true;
} }
}, },
new Option(resources, "-nodeprecated") { new Option(resources, "-nodeprecated") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
nodeprecated = true; nodeprecated = true;
return true; return true;
} }
}, },
new Option(resources, "-nosince") { new Option(resources, "-nosince") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
nosince = true; nosince = true;
return true; return true;
} }
}, },
new Option(resources, "-notimestamp") { new Option(resources, "-notimestamp") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
notimestamp = true; notimestamp = true;
return true; return true;
} }
}, },
new Option(resources, "-noqualifier", 1) { new Option(resources, "-noqualifier", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); addToSet(excludedQualifiers, args.get(0));
addToSet(excludedQualifiers, args.next());
return true; return true;
} }
}, },
new Hidden(resources, "-quiet") { new Hidden(resources, "-quiet") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
quiet = true; quiet = true;
return true; return true;
} }
}, },
new Option(resources, "-serialwarn") { new Option(resources, "-serialwarn") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
serialwarn = true; serialwarn = true;
return true; return true;
} }
}, },
new Option(resources, "-sourcetab", 1) { new Option(resources, "-sourcetab", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
linksource = true; linksource = true;
try { try {
setTabWidth(Integer.parseInt(args.next())); setTabWidth(Integer.parseInt(args.get(0)));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
//Set to -1 so that warning will be printed //Set to -1 so that warning will be printed
//to indicate what is valid argument. //to indicate what is valid argument.
@ -579,45 +608,41 @@ public abstract class Configuration {
}, },
new Option(resources, "-tag", 1) { new Option(resources, "-tag", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
ArrayList<String> list = new ArrayList<>(); ArrayList<String> list = new ArrayList<>();
list.add(opt); list.add(opt);
list.add(args.next()); list.add(args.get(0));
customTagStrs.add(list); customTagStrs.add(list);
return true; return true;
} }
}, },
new Option(resources, "-taglet", 1) { new Option(resources, "-taglet", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
ArrayList<String> list = new ArrayList<>(); ArrayList<String> list = new ArrayList<>();
list.add(opt); list.add(opt);
list.add(args.next()); list.add(args.get(0));
customTagStrs.add(list); customTagStrs.add(list);
return true; return true;
} }
}, },
new Option(resources, "-tagletpath", 1) { new Option(resources, "-tagletpath", 1) {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this); tagletpath = args.get(0);
tagletpath = args.next();
return true; return true;
} }
}, },
new Option(resources, "-version") { new Option(resources, "-version") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
optionsProcessed.add(this);
showversion = true; showversion = true;
return true; return true;
} }
}, },
new Hidden(resources, "--dump-on-error") { new Hidden(resources, "--dump-on-error") {
@Override @Override
public boolean process(String opt, ListIterator<String> args) { public boolean process(String opt, List<String> args) {
dumpOnError = true; dumpOnError = true;
return true; return true;
} }
@ -643,7 +668,7 @@ public abstract class Configuration {
if (docencoding == null) { if (docencoding == null) {
docencoding = encoding; docencoding = encoding;
} }
typeElementCatalog = new TypeElementCatalog(docEnv.getIncludedTypeElements(), this); typeElementCatalog = new TypeElementCatalog(includedTypeElements, this);
initTagletManager(customTagStrs); initTagletManager(customTagStrs);
groups.stream().forEach((grp) -> { groups.stream().forEach((grp) -> {
group.checkPackageGroups(grp.value1, grp.value2); group.checkPackageGroups(grp.value1, grp.value2);
@ -798,25 +823,19 @@ public abstract class Configuration {
} }
/** /**
*
* This checks for the validity of the options used by the user. * This checks for the validity of the options used by the user.
* This works exactly like DocErrorReporter. This will validate the options which are shared * As of this writing, this checks only docencoding.
* by our doclets. For example, this method will flag an error using
* the DocErrorReporter if user has used "-nohelp" and "-helpfile" option
* together.
* *
* @return true if all the options are valid. * @return true if all the options are valid.
*/ */
public boolean generalValidOptions() { public boolean generalValidOptions() {
boolean docencodingfound = false; if (docencoding != null) {
for (Doclet.Option opt : optionsProcessed) {
if (opt.matches("-docencoding")) {
docencodingfound = true;
if (!checkOutputFileEncoding(docencoding)) { if (!checkOutputFileEncoding(docencoding)) {
return false; return false;
} }
} }
} if (docencoding == null && (encoding != null && !encoding.isEmpty())) {
if (!docencodingfound && (encoding != null && !encoding.isEmpty())) {
if (!checkOutputFileEncoding(encoding)) { if (!checkOutputFileEncoding(encoding)) {
return false; return false;
} }
@ -897,35 +916,6 @@ public abstract class Configuration {
: utils.getFullyQualifiedName(te); : utils.getFullyQualifiedName(te);
} }
// cache these, as they are repeatedly called.
private Set<TypeElement> specifiedClasses = null;
private Set<PackageElement> specifiedPackages = null;
private Set<ModuleElement> specifiedModules = null;
public Set<TypeElement> getSpecifiedClasses() {
if (specifiedClasses == null) {
specifiedClasses = new LinkedHashSet<>(
ElementFilter.typesIn(docEnv.getSpecifiedElements()));
}
return specifiedClasses;
}
public Set<PackageElement> getSpecifiedPackages() {
if (specifiedPackages == null) {
specifiedPackages = new LinkedHashSet<>(
ElementFilter.packagesIn(docEnv.getSpecifiedElements()));
}
return specifiedPackages;
}
public Set<ModuleElement> getSpecifiedModules() {
if (specifiedModules == null) {
specifiedModules = new LinkedHashSet<>(
ElementFilter.modulesIn(docEnv.getSpecifiedElements()));
}
return specifiedModules;
}
/** /**
* Convenience method to obtain a resource from the doclet's * Convenience method to obtain a resource from the doclet's
* {@link Resources resources}. * {@link Resources resources}.
@ -1058,7 +1048,7 @@ public abstract class Configuration {
public abstract boolean showMessage(Element e, String key); public abstract boolean showMessage(Element e, String key);
public static abstract class Option implements Doclet.Option, Comparable<Option> { public static abstract class Option implements Doclet.Option, Comparable<Option> {
private final String name; private final String[] names;
private final String parameters; private final String parameters;
private final String description; private final String description;
private final int argCount; private final int argCount;
@ -1068,7 +1058,7 @@ public abstract class Configuration {
} }
protected Option(Resources resources, String keyBase, String name, int argCount) { protected Option(Resources resources, String keyBase, String name, int argCount) {
this.name = name; this.names = name.trim().split("\\s+");
String desc = getOptionsMessage(resources, keyBase + ".description"); String desc = getOptionsMessage(resources, keyBase + ".description");
if (desc.isEmpty()) { if (desc.isEmpty()) {
this.description = "<MISSING KEY>"; this.description = "<MISSING KEY>";
@ -1103,8 +1093,8 @@ public abstract class Configuration {
} }
@Override @Override
public String getName() { public List<String> getNames() {
return name; return Arrays.asList(names);
} }
@Override @Override
@ -1114,7 +1104,7 @@ public abstract class Configuration {
@Override @Override
public String toString() { public String toString() {
return name; return names.toString();
} }
@Override @Override
@ -1122,21 +1112,22 @@ public abstract class Configuration {
return argCount; return argCount;
} }
@Override
public boolean matches(String option) { public boolean matches(String option) {
for (String name : names) {
boolean matchCase = name.startsWith("--"); boolean matchCase = name.startsWith("--");
if (option.startsWith("--") && option.contains("=")) { if (option.startsWith("--") && option.contains("=")) {
return name.equals(option.substring(option.indexOf("=") + 1)); return name.equals(option.substring(option.indexOf("=") + 1));
} else if (matchCase) { } else if (matchCase) {
return name.equals(option); return name.equals(option);
} else { }
return name.toLowerCase().equals(option.toLowerCase()); return name.toLowerCase().equals(option.toLowerCase());
} }
return false;
} }
@Override @Override
public int compareTo(Option that) { public int compareTo(Option that) {
return this.getName().compareTo(that.getName()); return this.getNames().get(0).compareTo(that.getNames().get(0));
} }
} }
@ -1187,4 +1178,54 @@ public abstract class Configuration {
this.value2 = value2; this.value2 = value2;
} }
} }
/*
* Splits the elements in a collection to its individual
* collection.
*/
static private class Splitter {
final Set<ModuleElement> mset = new LinkedHashSet<>();
final Set<PackageElement> pset = new LinkedHashSet<>();
final Set<TypeElement> tset = new LinkedHashSet<>();
Splitter(DocletEnvironment docEnv, boolean included) {
Set<? extends Element> inset = included
? docEnv.getIncludedElements()
: docEnv.getSpecifiedElements();
for (Element e : inset) {
new SimpleElementVisitor9<Void, Void>() {
@Override
@DefinedBy(Api.LANGUAGE_MODEL)
public Void visitModule(ModuleElement e, Void p) {
mset.add(e);
return null;
}
@Override
@DefinedBy(Api.LANGUAGE_MODEL)
public Void visitPackage(PackageElement e, Void p) {
pset.add(e);
return null;
}
@Override
@DefinedBy(Api.LANGUAGE_MODEL)
public Void visitType(TypeElement e, Void p) {
tset.add(e);
return null;
}
@Override
@DefinedBy(Api.LANGUAGE_MODEL)
protected Void defaultAction(Element e, Void p) {
throw new AssertionError("unexpected element: " + e);
}
}.visit(e);
}
}
}
} }

View file

@ -187,11 +187,6 @@ public class WorkArounds {
return ((Attribute)aDesc).isSynthesized(); return ((Attribute)aDesc).isSynthesized();
} }
// TODO: implement using jx.l.model
public boolean isVisible(TypeElement te) {
return ((DocEnvImpl)(configuration.docEnv)).etable.isVisible(te);
}
// TODO: fix the caller // TODO: fix the caller
public Object getConstValue(VariableElement ve) { public Object getConstValue(VariableElement ve) {
return ((VarSymbol)ve).getConstValue(); return ((VarSymbol)ve).getConstValue();
@ -286,11 +281,6 @@ public class WorkArounds {
return null; return null;
} }
// TODO: investigate and reimplement without javac dependencies.
public boolean shouldDocument(Element e) {
return ((DocEnvImpl)(configuration.docEnv)).etable.shouldDocument(e);
}
// TODO: jx.l.m ? // TODO: jx.l.m ?
public Location getLocationForModule(ModuleElement mdle) { public Location getLocationForModule(ModuleElement mdle) {
ModuleSymbol msym = (ModuleSymbol)mdle; ModuleSymbol msym = (ModuleSymbol)mdle;

View file

@ -129,7 +129,7 @@ public class SerializedFormBuilder extends AbstractBuilder {
@Override @Override
public void build() throws DocletException { public void build() throws DocletException {
SortedSet<TypeElement> rootclasses = new TreeSet<>(utils.makeGeneralPurposeComparator()); SortedSet<TypeElement> rootclasses = new TreeSet<>(utils.makeGeneralPurposeComparator());
rootclasses.addAll(configuration.docEnv.getIncludedTypeElements()); rootclasses.addAll(configuration.getIncludedTypeElements());
if (!serialClassFoundToDocument(rootclasses)) { if (!serialClassFoundToDocument(rootclasses)) {
//Nothing to document. //Nothing to document.
return; return;

View file

@ -117,7 +117,7 @@ public class ClassTree {
baseEnums = new TreeSet<>(comparator); baseEnums = new TreeSet<>(comparator);
baseClasses = new TreeSet<>(comparator); baseClasses = new TreeSet<>(comparator);
baseInterfaces = new TreeSet<>(comparator); baseInterfaces = new TreeSet<>(comparator);
buildTree(configuration.docEnv.getIncludedTypeElements()); buildTree(configuration.getIncludedTypeElements());
} }
/** /**
@ -134,7 +134,7 @@ public class ClassTree {
baseEnums = new TreeSet<>(comparator); baseEnums = new TreeSet<>(comparator);
baseClasses = new TreeSet<>(comparator); baseClasses = new TreeSet<>(comparator);
baseInterfaces = new TreeSet<>(comparator); baseInterfaces = new TreeSet<>(comparator);
buildTree(configuration.docEnv.getIncludedTypeElements()); buildTree(configuration.getIncludedTypeElements());
} }
/** /**

View file

@ -206,7 +206,7 @@ public class ClassUseMapper {
implementingClasses(intfc); implementingClasses(intfc);
} }
// Map methods, fields, constructors using a class. // Map methods, fields, constructors using a class.
Set<TypeElement> classes = docEnv.getIncludedTypeElements(); Set<TypeElement> classes = configuration.getIncludedTypeElements();
for (TypeElement aClass : classes) { for (TypeElement aClass : classes) {
PackageElement pkg = elementUtils.getPackageOf(aClass); PackageElement pkg = elementUtils.getPackageOf(aClass);
mapAnnotations(classToPackageAnnotations, pkg, pkg); mapAnnotations(classToPackageAnnotations, pkg, pkg);

View file

@ -96,7 +96,7 @@ public class DeprecatedAPIListBuilder {
} }
} }
deprecatedMap.put(DeprElementKind.PACKAGE, pset); deprecatedMap.put(DeprElementKind.PACKAGE, pset);
for (Element e : configuration.docEnv.getIncludedTypeElements()) { for (Element e : configuration.getIncludedTypeElements()) {
TypeElement te = (TypeElement)e; TypeElement te = (TypeElement)e;
SortedSet<Element> eset; SortedSet<Element> eset;
if (utils.isDeprecated(e)) { if (utils.isDeprecated(e)) {

View file

@ -126,8 +126,8 @@ public class IndexBuilder {
* @param docEnv the doclet environment * @param docEnv the doclet environment
*/ */
protected void buildIndexMap(DocletEnvironment docEnv) { protected void buildIndexMap(DocletEnvironment docEnv) {
Set<PackageElement> packages = configuration.getSpecifiedPackages(); Set<PackageElement> packages = configuration.getSpecifiedPackageElements();
Set<TypeElement> classes = docEnv.getIncludedTypeElements(); Set<TypeElement> classes = configuration.getIncludedTypeElements();
if (!classesOnly) { if (!classesOnly) {
if (packages.isEmpty()) { if (packages.isEmpty()) {
Set<PackageElement> set = new HashSet<>(); Set<PackageElement> set = new HashSet<>();

View file

@ -2263,22 +2263,22 @@ public class Utils {
private List<TypeElement> getInnerClasses(Element e, boolean filter) { private List<TypeElement> getInnerClasses(Element e, boolean filter) {
List<TypeElement> olist = new ArrayList<>(); List<TypeElement> olist = new ArrayList<>();
for (TypeElement te : getClassesUnfiltered(e)) { for (TypeElement te : getClassesUnfiltered(e)) {
if (!filter || configuration.workArounds.isVisible(te)) { if (!filter || configuration.docEnv.isSelected(te)) {
olist.add(te); olist.add(te);
} }
} }
for (TypeElement te : getInterfacesUnfiltered(e)) { for (TypeElement te : getInterfacesUnfiltered(e)) {
if (!filter || configuration.workArounds.isVisible(te)) { if (!filter || configuration.docEnv.isSelected(te)) {
olist.add(te); olist.add(te);
} }
} }
for (TypeElement te : getAnnotationTypesUnfiltered(e)) { for (TypeElement te : getAnnotationTypesUnfiltered(e)) {
if (!filter || configuration.workArounds.isVisible(te)) { if (!filter || configuration.docEnv.isSelected(te)) {
olist.add(te); olist.add(te);
} }
} }
for (TypeElement te : getEnumsUnfiltered(e)) { for (TypeElement te : getEnumsUnfiltered(e)) {
if (!filter || configuration.workArounds.isVisible(te)) { if (!filter || configuration.docEnv.isSelected(te)) {
olist.add(te); olist.add(te);
} }
} }
@ -2361,7 +2361,7 @@ public class Utils {
List<Element> elements = new ArrayList<>(); List<Element> elements = new ArrayList<>();
for (Element e : te.getEnclosedElements()) { for (Element e : te.getEnclosedElements()) {
if (kinds.contains(e.getKind())) { if (kinds.contains(e.getKind())) {
if (!filter || configuration.workArounds.shouldDocument(e)) { if (!filter || shouldDocument(e)) {
elements.add(e); elements.add(e);
} }
} }
@ -2369,6 +2369,36 @@ public class Utils {
return elements; return elements;
} }
private SimpleElementVisitor9<Boolean, Void> shouldDocumentVisitor = null;
private boolean shouldDocument(Element e) {
if (shouldDocumentVisitor == null) {
shouldDocumentVisitor = new SimpleElementVisitor9<Boolean, Void>() {
private boolean hasSource(TypeElement e) {
return configuration.docEnv.getFileKind(e) ==
javax.tools.JavaFileObject.Kind.SOURCE;
}
// handle types
@Override
public Boolean visitType(TypeElement e, Void p) {
return configuration.docEnv.isSelected(e) && hasSource(e);
}
// handle everything else
@Override
protected Boolean defaultAction(Element e, Void p) {
return configuration.docEnv.isSelected(e);
}
@Override
public Boolean visitUnknown(Element e, Void p) {
throw new AssertionError("unkown element: " + p);
}
};
}
return shouldDocumentVisitor.visit(e);
}
/* /*
* nameCache is maintained for improving the comparator * nameCache is maintained for improving the comparator
* performance, noting that the Collator used by the comparators * performance, noting that the Collator used by the comparators
@ -2578,17 +2608,17 @@ public class Utils {
specifiedVisitor = new SimpleElementVisitor9<Boolean, Void>() { specifiedVisitor = new SimpleElementVisitor9<Boolean, Void>() {
@Override @Override
public Boolean visitModule(ModuleElement e, Void p) { public Boolean visitModule(ModuleElement e, Void p) {
return configuration.getSpecifiedModules().contains(e); return configuration.getSpecifiedModuleElements().contains(e);
} }
@Override @Override
public Boolean visitPackage(PackageElement e, Void p) { public Boolean visitPackage(PackageElement e, Void p) {
return configuration.getSpecifiedPackages().contains(e); return configuration.getSpecifiedPackageElements().contains(e);
} }
@Override @Override
public Boolean visitType(TypeElement e, Void p) { public Boolean visitType(TypeElement e, Void p) {
return configuration.getSpecifiedClasses().contains(e); return configuration.getSpecifiedTypeElements().contains(e);
} }
@Override @Override

View file

@ -25,19 +25,15 @@
package jdk.javadoc.internal.tool; package jdk.javadoc.internal.tool;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element; 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.element.TypeElement;
import javax.lang.model.util.Elements; import javax.lang.model.util.Elements;
import javax.lang.model.util.Types; import javax.lang.model.util.Types;
import javax.tools.JavaFileManager; import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject.Kind;
import com.sun.source.util.DocTrees; import com.sun.source.util.DocTrees;
import com.sun.tools.javac.code.Source; import com.sun.tools.javac.code.Source;
@ -74,24 +70,14 @@ public class DocEnvImpl implements DocletEnvironment {
this.toolEnv = toolEnv; this.toolEnv = toolEnv;
this.etable = etable; this.etable = etable;
} }
@Override @Override
public Set<ModuleElement> getIncludedModuleElements() { public Set<? extends Element> getSpecifiedElements() {
return etable.getIncludedModuleElements(); return etable.getSpecifiedElements();
} }
@Override @Override
public Set<PackageElement> getIncludedPackageElements() { public Set<? extends Element> getIncludedElements() {
return etable.getIncludedPackageElements(); return etable.getIncludedElements();
}
/**
* Return all TypeElements (including those inside
* packages) to be documented.
*/
@Override
public Set<TypeElement> getIncludedTypeElements() {
return etable.getIncludedTypeElements();
} }
@Override @Override
@ -109,22 +95,6 @@ public class DocEnvImpl implements DocletEnvironment {
return toolEnv.elements; return toolEnv.elements;
} }
@Override
public List<Element> getSelectedElements(List<? extends Element> elements) {
return elements.stream()
.filter(e -> isIncluded(e))
.collect(Collectors.<Element>toList());
}
@Override
public Set<Element> getSpecifiedElements() {
Set<Element> out = new LinkedHashSet<>();
out.addAll(etable.getSpecifiedModuleElements());
out.addAll(etable.getSpecifiedPackageElements());
out.addAll(etable.getSpecifiedTypeElements());
return out;
}
@Override @Override
public Types getTypeUtils() { public Types getTypeUtils() {
return toolEnv.typeutils; return toolEnv.typeutils;
@ -144,4 +114,14 @@ public class DocEnvImpl implements DocletEnvironment {
public ModuleMode getModuleMode() { public ModuleMode getModuleMode() {
return etable.getModuleMode(); return etable.getModuleMode();
} }
@Override
public Kind getFileKind(TypeElement type) {
return toolEnv.getFileKind(type);
}
@Override
public boolean isSelected(Element e) {
return etable.isSelected(e);
}
} }

View file

@ -137,7 +137,7 @@ import static jdk.javadoc.internal.tool.JavadocTool.isValidClassName;
* Rules for processing: * Rules for processing:
* *
* 1. A specified element, meaning an element given on the * 1. A specified element, meaning an element given on the
* command-line, and exposed via getSpecifiedElements() * command-line, and exposed via specified elements collections.
* 2. Expand-contents, an internal pseudo term, meaning * 2. Expand-contents, an internal pseudo term, meaning
* it is part of the recursive expansion of specified * it is part of the recursive expansion of specified
* elements, meaning, the modules are expanded first, then * elements, meaning, the modules are expanded first, then
@ -230,8 +230,28 @@ public class ElementsTable {
} }
} }
private Set<Element> specifiedElements = null;
/** /**
* Returns the selected/included module elements. * Returns a set of elements specified on the
* command line, including any inner classes.
*
* @return the set of elements specified on the command line
*/
public Set<? extends Element> getSpecifiedElements() {
if (specifiedElements == null) {
Set<Element> result = new LinkedHashSet<>();
result.addAll(specifiedModuleElements);
result.addAll(specifiedPackageElements);
result.addAll(specifiedTypeElements);
specifiedElements = Collections.unmodifiableSet(result);
}
return specifiedElements;
}
private Set<Element> includedElements = null;
/**
* Returns a set of elements included elements. The inclusion is as
* follows:
* A module is fully included, * A module is fully included,
* - is specified on the command line --module * - is specified on the command line --module
* - is derived from the module graph, that is, by expanding the * - is derived from the module graph, that is, by expanding the
@ -239,14 +259,7 @@ public class ElementsTable {
* *
* A module is included if an enclosed package or type is * A module is included if an enclosed package or type is
* specified on the command line. * specified on the command line.
* @return the included module elements *
*/
public Set<ModuleElement> getIncludedModuleElements() {
return includedModuleElements;
}
/**
* Returns the selected/included package elements.
* A package is fully included, * A package is fully included,
* - is specified on the command line * - is specified on the command line
* - is derived from expanding -subpackages * - is derived from expanding -subpackages
@ -255,66 +268,32 @@ public class ElementsTable {
* A package is included, if an enclosed package or a type is specified on * A package is included, if an enclosed package or a type is specified on
* the command line. * the command line.
* *
* @return the included package elements * Included type elements (including those within specified or included packages)
*/ * to be documented.
public Set<PackageElement> getIncludedPackageElements() { *
return includedPackageElements;
}
/**
* Returns the selected/included type elements (including those
* within specified or included packages) to be documented.
* A type is fully included if * A type is fully included if
* - is specified on the command line with -sourcepath * - is specified on the command line with -sourcepath
* - is visible with --show-types filter * - is visible with --show-types filter
* A nested type is fully included if * A nested type is fully included if
* - is visible with --show-types filter * - is visible with --show-types filter
* - is enclosed in a fully included type * - is enclosed in a fully included type
* * @return the set of elements specified on the command line
* @return the included type elements
* to be documented
*/ */
public Set<TypeElement> getIncludedTypeElements() { public Set<? extends Element> getIncludedElements() {
return includedTypeElements; if (includedElements == null) {
Set<Element> result = new LinkedHashSet<>();
result.addAll(includedModuleElements);
result.addAll(includedPackageElements);
result.addAll(includedTypeElements);
includedElements = Collections.unmodifiableSet(result);
} }
return includedElements;
/**
* Returns a set of module elements specified on the
* command line.
* @return the set of module elements specified on the
* command line
*/
public Set<ModuleElement> getSpecifiedModuleElements() {
return specifiedModuleElements;
}
/**
* Returns a set of package elements specified on the
* command line. These may also contain children packages
* if specified with -subpackage.
*
* @return the set of package elements specified on the
* command line
*/
public Set<PackageElement> getSpecifiedPackageElements() {
return specifiedPackageElements;
}
/**
* Returns a set of type elements specified on the
* command line, including any inner classes.
*
* @return the set of type elements specified on the command line
*/
public Set<TypeElement> getSpecifiedTypeElements() {
return specifiedTypeElements;
} }
private IncludedVisitor includedVisitor = null; private IncludedVisitor includedVisitor = null;
/** /**
* Returns true if the given element is included or selected for * Returns true if the given element is included for consideration.
* consideration.
* This method accumulates elements in the cache as enclosed elements of * This method accumulates elements in the cache as enclosed elements of
* fully included elements are tested. * fully included elements are tested.
* A member (constructor, method, field) is included if * A member (constructor, method, field) is included if
@ -539,7 +518,7 @@ public class ElementsTable {
ListBuffer<ModuleElement> queue = new ListBuffer<>(); ListBuffer<ModuleElement> queue = new ListBuffer<>();
// expand each specified module // expand each specified module
for (ModuleElement mdle : getSpecifiedModuleElements()) { for (ModuleElement mdle : specifiedModuleElements) {
result.add(mdle); // a specified module is included result.add(mdle); // a specified module is included
queue.append(mdle); queue.append(mdle);
Set<ModuleElement> publicRequires = getModuleRequires(mdle, true); Set<ModuleElement> publicRequires = getModuleRequires(mdle, true);
@ -700,7 +679,7 @@ public class ElementsTable {
*/ */
private void computeSpecifiedTypes() throws ToolException { private void computeSpecifiedTypes() throws ToolException {
Set<TypeElement> classes = new LinkedHashSet<>(); Set<TypeElement> classes = new LinkedHashSet<>();
classDecList.stream().filter((def) -> (shouldDocument(def.sym))).forEach((def) -> { classDecList.forEach((def) -> {
TypeElement te = (TypeElement) def.sym; TypeElement te = (TypeElement) def.sym;
if (te != null) { if (te != null) {
addAllClasses(classes, te, true); addAllClasses(classes, te, true);
@ -853,19 +832,16 @@ public class ElementsTable {
try { try {
// eliminate needless checking, do this first. // eliminate needless checking, do this first.
if (list.contains(klass)) return; if (list.contains(klass)) return;
if (toolEnv.isSynthetic(klass)) return;
// ignore classes with invalid Java class names // ignore classes with invalid Java class names
if (!JavadocTool.isValidClassName(klass.name.toString())) return; if (!JavadocTool.isValidClassName(klass.name.toString())) return;
if (filtered && !shouldDocument(klass)) return; if (filtered && !isTypeElementSelected(klass)) return;
list.add(klass); list.add(klass);
for (Symbol sym : klass.members().getSymbols(NON_RECURSIVE)) { for (Symbol sym : klass.members().getSymbols(NON_RECURSIVE)) {
if (sym != null && sym.kind == Kind.TYP) { if (sym != null && sym.kind == Kind.TYP) {
ClassSymbol s = (ClassSymbol)sym; ClassSymbol s = (ClassSymbol)sym;
if (!toolEnv.isSynthetic(s)) {
addAllClasses(list, s, filtered); addAllClasses(list, s, filtered);
} }
} }
}
} catch (CompletionFailure e) { } catch (CompletionFailure e) {
if (e.getMessage() != null) if (e.getMessage() != null)
messager.printWarning(e.getMessage()); messager.printWarning(e.getMessage());
@ -882,92 +858,65 @@ public class ElementsTable {
boolean filtered = true; boolean filtered = true;
PackageSymbol sym = (PackageSymbol)pkg; PackageSymbol sym = (PackageSymbol)pkg;
for (Symbol isym : sym.members().getSymbols(NON_RECURSIVE)) { for (Symbol isym : sym.members().getSymbols(NON_RECURSIVE)) {
if (isym != null) { addAllClasses(list, (TypeElement)isym, filtered);
ClassSymbol s = (ClassSymbol)isym;
if (!toolEnv.isSynthetic(sym)) {
addAllClasses(list, s, filtered);
}
}
} }
} }
SimpleElementVisitor9<Boolean, Void> shouldDocumentVisitor = null; private boolean isTypeElementSelected(TypeElement te) {
return (xclasses || toolEnv.isFromSource(te)) && isSelected(te);
}
SimpleElementVisitor9<Boolean, Void> visibleElementVisitor = null;
/** /**
* Returns whether an element ought to be documented. * Returns true if the element is selected, by applying
* @param e the element in question * the access filter checks. Special treatment is applied to
* @return true if the element should be documented * types, for a top level type the access filter applies completely,
* however if is a nested type then it is allowed either if
* the enclosing is a static or the enclosing is also selected.
*
* @param e the element to be checked
* @return true if the element is visible
*/ */
public boolean shouldDocument(Element e) { public boolean isSelected(Element e) {
if (shouldDocumentVisitor == null) { if (toolEnv.isSynthetic((Symbol) e)) {
shouldDocumentVisitor = new SimpleElementVisitor9<Boolean, Void>() { return false;
}
if (visibleElementVisitor == null) {
visibleElementVisitor = new SimpleElementVisitor9<Boolean, Void>() {
@Override @Override
public Boolean visitType(TypeElement e, Void p) { public Boolean visitType(TypeElement e, Void p) {
return shouldDocument((ClassSymbol) e); if (!accessFilter.checkModifier(e)) {
return false; // it is not allowed
}
Element encl = e.getEnclosingElement();
// check if nested
if (encl.getKind() == ElementKind.PACKAGE)
return true; // top-level class, allow it
// is enclosed static
if (encl.getModifiers().contains(Modifier.STATIC))
return true; // allowed
// check the enclosing
return visit(encl);
} }
@Override @Override
public Boolean visitVariable(VariableElement e, Void p) { protected Boolean defaultAction(Element e, Void p) {
return shouldDocument((VarSymbol) e);
}
@Override
public Boolean visitExecutable(ExecutableElement e, Void p) {
return shouldDocument((MethodSymbol) e);
}
@Override
public Boolean visitPackage(PackageElement e, Void p) {
return accessFilter.checkModifier(e); return accessFilter.checkModifier(e);
} }
@Override
public Boolean visitUnknown(Element e, Void p) {
throw new AssertionError("unkown element: " + p);
}
}; };
} }
return shouldDocumentVisitor.visit(e); return visibleElementVisitor.visit(e);
}
/** Check whether this member should be documented. */
private boolean shouldDocument(VarSymbol sym) {
if (toolEnv.isSynthetic(sym)) {
return false;
}
return accessFilter.checkModifier(sym);
}
/** Check whether this member should be documented. */
private boolean shouldDocument(MethodSymbol sym) {
if (toolEnv.isSynthetic(sym)) {
return false;
}
return accessFilter.checkModifier(sym);
}
/** Check whether this class should be documented. */
private boolean shouldDocument(ClassSymbol sym) {
return
!toolEnv.isSynthetic(sym) && // no synthetics
(xclasses || toolEnv.hasPath(sym)) &&
isVisible(sym);
}
/**
* Returns the visibility of a type element.
* If the type element is a nested type, then check if the
* enclosing is static or the enclosed is visible.
*
* @param te the type element to be checked
* @return true if the element is visible
*/
public boolean isVisible(TypeElement te) {
ClassSymbol sym = (ClassSymbol)te;
if (!accessFilter.checkModifier(sym)) {
return false;
}
ClassSymbol encl = sym.owner.enclClass();
return (encl == null || (sym.flags_field & Flags.STATIC) != 0 || isVisible(encl));
} }
private class IncludedVisitor extends SimpleElementVisitor9<Boolean, Void> { private class IncludedVisitor extends SimpleElementVisitor9<Boolean, Void> {
final private Set<Element> includedCache; final private Set<Element> includedCache;
public IncludedVisitor() { public IncludedVisitor() {
@ -991,7 +940,7 @@ public class ElementsTable {
if (includedTypeElements.contains(e)) { if (includedTypeElements.contains(e)) {
return true; return true;
} }
if (shouldDocument(e)) { if (isTypeElementSelected(e)) {
// Class is nameable from top-level and // Class is nameable from top-level and
// the class and all enclosing classes // the class and all enclosing classes
// pass the modifier filter. // pass the modifier filter.
@ -1019,7 +968,7 @@ public class ElementsTable {
public Boolean defaultAction(Element e, Void p) { public Boolean defaultAction(Element e, Void p) {
if (includedCache.contains(e)) if (includedCache.contains(e))
return true; return true;
if (visit(e.getEnclosingElement()) && shouldDocument(e)) { if (visit(e.getEnclosingElement()) && isSelected(e)) {
switch(e.getKind()) { switch(e.getKind()) {
case ANNOTATION_TYPE: case CLASS: case ENUM: case INTERFACE: case ANNOTATION_TYPE: case CLASS: case ENUM: case INTERFACE:
case MODULE: case OTHER: case PACKAGE: case MODULE: case OTHER: case PACKAGE:

View file

@ -99,6 +99,7 @@ public class JavadocEnter extends Enter {
if (tree.sym.kind == TYP || tree.sym.kind == ERR) { if (tree.sym.kind == TYP || tree.sym.kind == ERR) {
ClassSymbol c = tree.sym; ClassSymbol c = tree.sym;
toolEnv.setElementToTreePath(c, toolEnv.getTreePath(env.toplevel, tree)); toolEnv.setElementToTreePath(c, toolEnv.getTreePath(env.toplevel, tree));
c.classfile = env.toplevel.sourcefile;
} }
} }

View file

@ -62,6 +62,7 @@ import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Log; import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Log.WriterKind; import com.sun.tools.javac.util.Log.WriterKind;
import com.sun.tools.javac.util.Options; import com.sun.tools.javac.util.Options;
import com.sun.tools.javac.util.StringUtils;
import jdk.javadoc.doclet.Doclet; import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.Doclet.Option; import jdk.javadoc.doclet.Doclet.Option;
@ -233,7 +234,7 @@ public class Start extends ToolOption.Helper {
@Override @Override
public int compare(Doclet.Option o1, Doclet.Option o2) { public int compare(Doclet.Option o1, Doclet.Option o2) {
return collator.compare(o1.getName(), o2.getName()); return collator.compare(o1.getNames().get(0), o2.getNames().get(0));
} }
}; };
@ -244,10 +245,11 @@ public class Start extends ToolOption.Helper {
} }
void showDocletOption(Doclet.Option option) { void showDocletOption(Doclet.Option option) {
List<String> names = Arrays.asList(option.getName()); List<String> names = option.getNames();
String parameters; String parameters;
if (option.getArgumentCount() > 0 || option.getName().endsWith(":")) { String optname = names.get(0);
String sep = option.getName().endsWith(":") ? "" : " "; if (option.getArgumentCount() > 0 || optname.endsWith(":")) {
String sep = optname.endsWith(":") ? "" : " ";
parameters = sep + option.getParameters(); parameters = sep + option.getParameters();
} else { } else {
parameters = ""; parameters = "";
@ -610,7 +612,23 @@ public class Start extends ToolOption.Helper {
return ok; return ok;
} }
Set<Doclet.Option> docletOptions = null; boolean matches(List<String> names, String arg) {
for (String name : names) {
if (StringUtils.toLowerCase(name).equals(StringUtils.toLowerCase(arg)))
return true;
}
return false;
}
boolean matches(Doclet.Option option, String arg) {
if (matches(option.getNames(), arg))
return true;
int sep = arg.indexOf(':');
String targ = arg.substring(0, sep + 1);
return matches(option.getNames(), targ);
}
Set<? extends Doclet.Option> docletOptions = null;
int handleDocletOptions(int idx, List<String> args, boolean isToolOption) int handleDocletOptions(int idx, List<String> args, boolean isToolOption)
throws OptionException { throws OptionException {
if (docletOptions == null) { if (docletOptions == null) {
@ -628,14 +646,14 @@ public class Start extends ToolOption.Helper {
} }
String text = null; String text = null;
for (Doclet.Option opt : docletOptions) { for (Doclet.Option opt : docletOptions) {
if (opt.matches(argBase)) { if (matches(opt, argBase)) {
if (argVal != null) { if (argVal != null) {
switch (opt.getArgumentCount()) { switch (opt.getArgumentCount()) {
case 0: case 0:
text = messager.getText("main.unnecessary_arg_provided", argBase); text = messager.getText("main.unnecessary_arg_provided", argBase);
throw new OptionException(ERROR, this::usage, text); throw new OptionException(ERROR, this::usage, text);
case 1: case 1:
opt.process(arg, Arrays.asList(argVal).listIterator()); opt.process(arg, Arrays.asList(argVal));
break; break;
default: default:
text = messager.getText("main.only_one_argument_with_equals", argBase); text = messager.getText("main.only_one_argument_with_equals", argBase);
@ -646,7 +664,7 @@ public class Start extends ToolOption.Helper {
text = messager.getText("main.requires_argument", arg); text = messager.getText("main.requires_argument", arg);
throw new OptionException(ERROR, this::usage, text); throw new OptionException(ERROR, this::usage, text);
} }
opt.process(arg, args.listIterator(idx + 1)); opt.process(arg, args.subList(idx + 1, args.size()));
idx += opt.getArgumentCount(); idx += opt.getArgumentCount();
} }
return idx; return idx;

View file

@ -34,6 +34,7 @@ import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements; import javax.lang.model.util.Elements;
import javax.tools.JavaFileManager; import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;
import com.sun.source.util.DocTrees; import com.sun.source.util.DocTrees;
import com.sun.source.util.TreePath; import com.sun.source.util.TreePath;
@ -193,17 +194,20 @@ public class ToolEnvironment {
} }
/** /**
* Returns true if the symbol has a tree path associated with it. * Returns true if the type element originates from source.
* Primarily used to disambiguate a symbol associated with a source * Primarily used to disambiguate a type element associated with a source
* file versus a class file. * file versus a class file.
* @param sym the symbol to be checked * @param te the type element
* @return true if the symbol has a tree path * @return true if the symbol is from source
*/ */
boolean hasPath(ClassSymbol sym) { public boolean isFromSource(TypeElement te) {
TreePath path = elementToTreePath.get(sym); return getFileKind(te) == Kind.SOURCE;
return path != null;
} }
public Kind getFileKind(TypeElement te) {
JavaFileObject jfo = ((ClassSymbol)te).outermostClass().classfile;
return jfo == null ? Kind.SOURCE : jfo.getKind();
}
/** /**
* Print a notice, iff <em>quiet</em> is not specified. * Print a notice, iff <em>quiet</em> is not specified.
* *

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -39,14 +39,18 @@
*/ */
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element; import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind; import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.Elements; import javax.lang.model.util.Elements;
import jdk.javadoc.doclet.*; import jdk.javadoc.doclet.*;
@ -60,17 +64,17 @@ public class BaseClass implements Doclet {
throw new AssertionError("Base class is not included: baz.Foo"); throw new AssertionError("Base class is not included: baz.Foo");
} }
for (Element e : root.getSpecifiedElements()) { for (TypeElement te : ElementFilter.typesIn(root.getSpecifiedElements())) {
if (e.getKind() == ElementKind.CLASS && if (te.getKind() == ElementKind.CLASS &&
e.getSimpleName().contentEquals("Bar")) { te.getSimpleName().contentEquals("Bar")) {
klass = (TypeElement)e; klass = te;
} }
} }
if (klass == null) { if (klass == null) {
throw new AssertionError("class Bar not found"); throw new AssertionError("class Bar not found");
} }
List<? extends Element> members = klass.getEnclosedElements(); List<? extends Element> members = klass.getEnclosedElements();
List<Element> selected = root.getSelectedElements(members);
boolean foundPublic = false; boolean foundPublic = false;
boolean foundProtected = false; boolean foundProtected = false;
@ -78,8 +82,11 @@ public class BaseClass implements Doclet {
boolean foundPackagePrivate = false; boolean foundPackagePrivate = false;
boolean foundPrivate = false; boolean foundPrivate = false;
List<Element> included = members.stream()
.filter(cls -> root.isIncluded(cls))
.collect(Collectors.toList());
for (Element e :selected) { for (Element e : included) {
System.out.println("element: " + e); System.out.println("element: " + e);
if (e.getSimpleName().toString().equals("aPublicMethod")) { if (e.getSimpleName().toString().equals("aPublicMethod")) {
foundPublic = true; foundPublic = true;

View file

@ -25,19 +25,21 @@
* @test * @test
* @bug 6227454 * @bug 6227454
* @summary package.html and overview.html may not be read fully * @summary package.html and overview.html may not be read fully
* * @modules jdk.javadoc/jdk.javadoc.internal.tool * @modules jdk.javadoc/jdk.javadoc.internal.tool
*/ */
import java.io.*; import java.io.*;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.ListIterator; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element; import javax.lang.model.element.Element;
import javax.lang.model.util.ElementFilter;
import com.sun.source.doctree.DocCommentTree; import com.sun.source.doctree.DocCommentTree;
import com.sun.source.util.DocTrees; import com.sun.source.util.DocTrees;
@ -45,7 +47,6 @@ import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.Reporter; import jdk.javadoc.doclet.Reporter;
import jdk.javadoc.doclet.DocletEnvironment; import jdk.javadoc.doclet.DocletEnvironment;
public class Test implements Doclet { public class Test implements Doclet {
public static void main(String... args) throws Exception { public static void main(String... args) throws Exception {
new Test().run(); new Test().run();
@ -140,9 +141,9 @@ public class Test implements Doclet {
public boolean run(DocletEnvironment root) { public boolean run(DocletEnvironment root) {
DocTrees docTrees = root.getDocTrees(); DocTrees docTrees = root.getDocTrees();
System.out.println("classes:" + root.getIncludedTypeElements()); System.out.println("classes:" + ElementFilter.typesIn(root.getIncludedElements()));
Element klass = root.getIncludedTypeElements().iterator().next(); Element klass = ElementFilter.typesIn(root.getIncludedElements()).iterator().next();
String text = ""; String text = "";
try { try {
DocCommentTree dcTree = docTrees.getDocCommentTree(klass, overviewpath); DocCommentTree dcTree = docTrees.getDocCommentTree(klass, overviewpath);
@ -190,8 +191,10 @@ public class Test implements Doclet {
} }
@Override @Override
public String getName() { public List<String> getNames() {
return "overview"; List<String> out = new ArrayList<>();
out.add("overview");
return out;
} }
@Override @Override
@ -200,21 +203,13 @@ public class Test implements Doclet {
} }
@Override @Override
public boolean matches(String option) { public boolean process(String option, List<String> arguments) {
String opt = option.startsWith("-") ? option.substring(1) : option; overviewpath = arguments.get(0);
return getName().equals(opt);
}
@Override
public boolean process(String option, ListIterator<String> arguments) {
if (matches(option)) {
overviewpath = arguments.next();
}
return true; return true;
} }
} }
}; };
return new HashSet<Option>(Arrays.asList(options)); return new HashSet<>(Arrays.asList(options));
} }
@Override @Override

View file

@ -40,6 +40,7 @@ import javax.lang.model.SourceVersion;
import javax.lang.model.element.ElementKind; import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement; import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementFilter;
import com.sun.source.doctree.DocCommentTree; import com.sun.source.doctree.DocCommentTree;
import com.sun.source.doctree.DocTree; import com.sun.source.doctree.DocTree;
@ -75,7 +76,7 @@ public class BreakIteratorWarning implements Doclet {
} }
public boolean run(DocletEnvironment root) { public boolean run(DocletEnvironment root) {
TypeElement cd = root.getIncludedTypeElements().iterator().next(); TypeElement cd = ElementFilter.typesIn(root.getIncludedElements()).iterator().next();
VariableElement fd = getFields(cd).get(0); VariableElement fd = getFields(cd).get(0);
DocTrees docTrees = root.getDocTrees(); DocTrees docTrees = root.getDocTrees();
DocCommentTree docCommentTree = docTrees.getDocCommentTree(fd); DocCommentTree docCommentTree = docTrees.getDocCommentTree(fd);

View file

@ -80,7 +80,7 @@ public class InlineTagsWithBraces implements Doclet {
public boolean run(DocletEnvironment root) { public boolean run(DocletEnvironment root) {
DocTrees trees = root.getDocTrees(); DocTrees trees = root.getDocTrees();
TypeElement cd = root.getIncludedTypeElements().iterator().next(); TypeElement cd = ElementFilter.typesIn(root.getIncludedElements()).iterator().next();
DocCommentTree docCommentTree = trees.getDocCommentTree(cd); DocCommentTree docCommentTree = trees.getDocCommentTree(cd);
List<? extends DocTree> tags = docCommentTree.getBody(); List<? extends DocTree> tags = docCommentTree.getBody();

View file

@ -34,6 +34,7 @@ import java.util.*;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementFilter;
import com.sun.source.doctree.DocCommentTree; import com.sun.source.doctree.DocCommentTree;
import com.sun.source.util.DocTrees; import com.sun.source.util.DocTrees;
@ -62,7 +63,7 @@ public class NoStar implements Doclet
} }
public boolean run(DocletEnvironment root) { public boolean run(DocletEnvironment root) {
Set<TypeElement> classes = root.getIncludedTypeElements(); Set<TypeElement> classes = ElementFilter.typesIn(root.getIncludedElements());
if (classes.size() != 1) if (classes.size() != 1)
throw new Error("1 " + Arrays.asList(classes)); throw new Error("1 " + Arrays.asList(classes));
TypeElement self = classes.iterator().next(); TypeElement self = classes.iterator().next();

View file

@ -40,9 +40,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.ListIterator;
import java.util.Locale; import java.util.Locale;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
@ -97,11 +95,11 @@ public class OptionSyntaxTest extends TestRunner {
} }
static class DOption implements Doclet.Option { static class DOption implements Doclet.Option {
private final String name; private final List<String> names = new ArrayList<>();
private final int argCount; private final int argCount;
DOption(String name, int argCount) { DOption(String name, int argCount) {
this.name = name; this.names.add(name);
this.argCount = argCount; this.argCount = argCount;
} }
@ -112,7 +110,7 @@ public class OptionSyntaxTest extends TestRunner {
@Override @Override
public String getDescription() { public String getDescription() {
return "description[" + name + "]"; return "description[" + names.get(0) + "]";
} }
@Override @Override
@ -121,25 +119,20 @@ public class OptionSyntaxTest extends TestRunner {
} }
@Override @Override
public String getName() { public List<String> getNames() {
return name; return names;
} }
@Override @Override
public String getParameters() { public String getParameters() {
return argCount > 0 ? "parameters[" + name + "," + argCount + "]" : null; return argCount > 0 ? "parameters[" + names.get(0) + "," + argCount + "]" : null;
} }
@Override @Override
public boolean matches(String option) { public boolean process(String option, List<String> arguments) {
return option.equals(name);
}
@Override
public boolean process(String option, ListIterator<String> arguments) {
List<String> args = new ArrayList<>(); List<String> args = new ArrayList<>();
for (int i = 0; i < argCount && arguments.hasNext(); i++) { for (int i = 0; i < argCount && i < arguments.size(); i++) {
args.add(arguments.next()); args.add(arguments.get(i));
} }
System.out.println("process " + option + " " + args); System.out.println("process " + option + " " + args);
return args.stream().filter(s -> s.startsWith("arg")).count() == argCount; return args.stream().filter(s -> s.startsWith("arg")).count() == argCount;

View file

@ -41,6 +41,7 @@ import javax.lang.model.SourceVersion;
import javax.lang.model.element.ElementKind; import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementFilter;
import com.sun.source.tree.CompilationUnitTree; import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.LineMap; import com.sun.source.tree.LineMap;
@ -59,7 +60,7 @@ public class T4994049 implements Doclet {
DocTrees trees = root.getDocTrees(); DocTrees trees = root.getDocTrees();
SourcePositions sourcePositions = trees.getSourcePositions(); SourcePositions sourcePositions = trees.getSourcePositions();
for (TypeElement klass : root.getIncludedTypeElements()) { for (TypeElement klass : ElementFilter.typesIn(root.getIncludedElements())) {
for (ExecutableElement method : getMethods(klass)) { for (ExecutableElement method : getMethods(klass)) {
if (method.getSimpleName().toString().equals("tabbedMethod")) { if (method.getSimpleName().toString().equals("tabbedMethod")) {
TreePath path = trees.getPath(method); TreePath path = trees.getPath(method);

View file

@ -35,6 +35,7 @@ import java.util.*;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementFilter;
import jdk.javadoc.doclet.Doclet; import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.DocletEnvironment; import jdk.javadoc.doclet.DocletEnvironment;
@ -54,7 +55,7 @@ public class CompletionFailure implements Doclet {
} }
public boolean run(DocletEnvironment root) { public boolean run(DocletEnvironment root) {
Set<TypeElement> classes = root.getIncludedTypeElements(); Set<TypeElement> classes = ElementFilter.typesIn(root.getIncludedElements());
if (classes.size() != 1) if (classes.size() != 1)
throw new Error("1 " + Arrays.asList(classes)); throw new Error("1 " + Arrays.asList(classes));
return true; return true;

View file

@ -36,6 +36,7 @@ import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element; import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind; import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementFilter;
import jdk.javadoc.doclet.Doclet; import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.Reporter; import jdk.javadoc.doclet.Reporter;
@ -62,7 +63,7 @@ public class DupOk implements Doclet
} }
public boolean run(DocletEnvironment root) { public boolean run(DocletEnvironment root) {
Set<TypeElement> classes = root.getIncludedTypeElements(); Set<TypeElement> classes = ElementFilter.typesIn(root.getIncludedElements());
if (classes.size() != 2) if (classes.size() != 2)
throw new Error("1 " + Arrays.asList(classes)); throw new Error("1 " + Arrays.asList(classes));
for (TypeElement clazz : classes) { for (TypeElement clazz : classes) {

View file

@ -0,0 +1,159 @@
/*
* Copyright (c) 2016, 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.
*/
/*
* NOTE: this class is an almost a replica of the example used in the
* package-info.java.
*/
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementFilter;
import javax.tools.Diagnostic.Kind;
import com.sun.source.doctree.DocCommentTree;
import com.sun.source.util.DocTrees;
import jdk.javadoc.doclet.*;
/**
* An Example class implementing the Doclet.
*/
public class Example implements Doclet {
Reporter reporter;
@Override
public void init(Locale locale, Reporter reporter) {
reporter.print(Kind.NOTE, "Doclet using locale: " + locale);
this.reporter = reporter;
}
/**
* Prints an element.
*
* @param trees the utility class
* @param e the element to be printed
*/
public void printElement(DocTrees trees, Element e) {
DocCommentTree docCommentTree = trees.getDocCommentTree(e);
if (docCommentTree != null) {
System.out.println("Element (" + e.getKind() + ": "
+ e + ") has the following comments:");
System.out.println("Entire body: " + docCommentTree.getFullBody());
System.out.println("Block tags: " + docCommentTree.getBlockTags());
}
}
@Override
public boolean run(DocletEnvironment docEnv) {
reporter.print(Kind.NOTE, "overviewfile: " + overviewfile);
// get the DocTrees utility class to access DocComments
DocTrees docTrees = docEnv.getDocTrees();
// location of an element in the same directory as overview.html
try {
Element e = ElementFilter.typesIn(docEnv.getSpecifiedElements()).iterator().next();
DocCommentTree docCommentTree
= docTrees.getDocCommentTree(e, overviewfile);
if (docCommentTree != null) {
System.out.println("Overview html: " + docCommentTree.getFullBody());
}
} catch (IOException missing) {
reporter.print(Kind.ERROR, "No overview.html found.");
}
for (TypeElement t : ElementFilter.typesIn(docEnv.getIncludedElements())) {
System.out.println(t.getKind() + ":" + t);
for (Element e : t.getEnclosedElements()) {
printElement(docTrees, e);
}
}
return true;
}
@Override
public String getName() {
return "Example";
}
private String overviewfile;
@Override
public Set<? extends Option> getSupportedOptions() {
Option[] options = {
new Option() {
private final List<String> someOption = Arrays.asList(
"-overviewfile",
"-overview-file",
"--over-view-file"
);
@Override
public int getArgumentCount() {
return 1;
}
@Override
public String getDescription() {
return "an option with aliases";
}
@Override
public Option.Kind getKind() {
return Option.Kind.STANDARD;
}
@Override
public List<String> getNames() {
return someOption;
}
@Override
public String getParameters() {
return "file";
}
@Override
public boolean process(String opt, List<String> arguments) {
overviewfile = arguments.get(0);
return true;
}
}
};
return new HashSet<>(Arrays.asList(options));
}
@Override
public SourceVersion getSupportedSourceVersion() {
// support the latest release
return SourceVersion.latest();
}
}

View file

@ -0,0 +1,116 @@
/*
* Copyright (c) 2016, 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 8164316
* @summary tests the example used in package-info.java and doclet options.
* @modules
* jdk.javadoc/jdk.javadoc.internal.api
* jdk.javadoc/jdk.javadoc.internal.tool
* jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* @library /tools/lib
* @build toolbox.ToolBox toolbox.TestRunner Example
* @run main Tester
*/
import java.io.File;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import toolbox.*;
import toolbox.Task.Expect;
import static toolbox.Task.OutputKind.*;
public class Tester extends TestRunner {
final ToolBox tb;
final File testFile;
final File testSrc;
final Class<?> docletClass;
final static String OV_FN = "overview.html";
Tester() {
super(System.err);
testSrc = new File(System.getProperty("test.src"));
testFile = new File(testSrc, "Example.java");
tb = new ToolBox();
ClassLoader cl = Tester.class.getClassLoader();
try {
docletClass = cl.loadClass("Example");
} catch (ClassNotFoundException cfe) {
throw new Error(cfe);
}
}
public static void main(String... args) throws Exception {
new Tester().runTests();
}
private Task.Result execTask(String... extraArgs) {
return execTask(false, extraArgs);
}
private Task.Result execTask(boolean isNegative, String... extraArgs) {
JavadocTask et = new JavadocTask(tb, Task.Mode.API);
et.docletClass(docletClass);
List<String> args = new ArrayList<>();
args.add("-sourcepath");
args.add(testSrc.getAbsolutePath());
args.add(testFile.getAbsolutePath());
args.addAll(Arrays.asList(extraArgs));
//args.forEach((a -> System.err.println("arg: " + a)));
System.err.println(Arrays.asList(extraArgs));
Task.Result result = isNegative
? et.options(args).run(Expect.FAIL)
: et.options(args).run();
return result;
}
void assertPresence(String regex, List<String> output) throws Exception {
List<String> foundList = tb.grep(regex, output);
if (foundList.isEmpty()) {
throw new Exception("Not found, expected: " + regex);
}
}
@Test
public void testOption() throws Exception {
Task.Result result = execTask("-overviewfile", OV_FN);
assertPresence("overviewfile: " + OV_FN, result.getOutputLines(DIRECT));
}
@Test
public void testOptionAlias() throws Exception {
Task.Result result = execTask("-overview-file", OV_FN);
assertPresence("overviewfile: " + OV_FN, result.getOutputLines(DIRECT));
}
@Test
public void testOptionAliasDoubleDash() throws Exception {
Task.Result result = execTask("--over-view-file", OV_FN);
assertPresence("overviewfile: " + OV_FN, result.getOutputLines(DIRECT));
}
}

View file

@ -0,0 +1,27 @@
<!--
* Copyright (c) 2016, 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.
-->
<html>
<body>
A sample html document.
</body>
</html>

View file

@ -32,6 +32,7 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.stream.Collectors;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element; import javax.lang.model.element.Element;
@ -336,9 +337,7 @@ public class ModuleTestBase extends TestRunner {
public boolean run(DocletEnvironment docenv) { public boolean run(DocletEnvironment docenv) {
ps.println("ModuleMode" + FS + docenv.getModuleMode()); ps.println("ModuleMode" + FS + docenv.getModuleMode());
printDataSet("Specified", docenv.getSpecifiedElements()); printDataSet("Specified", docenv.getSpecifiedElements());
printDataSet("Included", docenv.getIncludedModuleElements()); printDataSet("Included", docenv.getIncludedElements());
printDataSet("Included", docenv.getIncludedPackageElements());
printDataSet("Included", docenv.getIncludedTypeElements());
printDataSet("Selected", getAllSelectedElements(docenv)); printDataSet("Selected", getAllSelectedElements(docenv));
System.out.println(sw); System.out.println(sw);
return true; return true;
@ -353,21 +352,24 @@ public class ModuleTestBase extends TestRunner {
if (rc != 0) return rc; if (rc != 0) return rc;
return Integer.compare(e1.hashCode(), e2.hashCode()); return Integer.compare(e1.hashCode(), e2.hashCode());
}); });
for (ModuleElement me : docenv.getIncludedModuleElements()) { Set<? extends Element> elements = docenv.getIncludedElements();
for (ModuleElement me : ElementFilter.modulesIn(elements)) {
addEnclosedElements(docenv, result, me); addEnclosedElements(docenv, result, me);
} }
for (PackageElement pe : docenv.getIncludedPackageElements()) { for (PackageElement pe : ElementFilter.packagesIn(elements)) {
addEnclosedElements(docenv, result, docenv.getElementUtils().getModuleOf(pe)); addEnclosedElements(docenv, result, docenv.getElementUtils().getModuleOf(pe));
addEnclosedElements(docenv, result, pe); addEnclosedElements(docenv, result, pe);
} }
for (TypeElement te : docenv.getIncludedTypeElements()) { for (TypeElement te : ElementFilter.typesIn(elements)) {
addEnclosedElements(docenv, result, te); addEnclosedElements(docenv, result, te);
} }
return result; return result;
} }
void addEnclosedElements(DocletEnvironment docenv, Set<Element> result, Element e) { void addEnclosedElements(DocletEnvironment docenv, Set<Element> result, Element e) {
List<? extends Element> elems = docenv.getSelectedElements(e.getEnclosedElements()); List<Element> elems = e.getEnclosedElements().stream()
.filter(el -> docenv.isIncluded(el))
.collect(Collectors.toList());
result.addAll(elems); result.addAll(elems);
for (TypeElement t : ElementFilter.typesIn(elems)) { for (TypeElement t : ElementFilter.typesIn(elems)) {
addEnclosedElements(docenv, result, t); addEnclosedElements(docenv, result, t);

View file

@ -29,6 +29,8 @@ import java.util.Locale;
import java.util.Set; import java.util.Set;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementFilter;
import jdk.javadoc.doclet.Doclet; import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.DocletEnvironment; import jdk.javadoc.doclet.DocletEnvironment;
@ -42,9 +44,10 @@ public class SourceOnly implements Doclet {
@Override @Override
public boolean run(DocletEnvironment root) { public boolean run(DocletEnvironment root) {
if (root.getIncludedTypeElements().size() != 1) Set<TypeElement> classes = ElementFilter.typesIn(root.getIncludedElements());
if (classes.size() != 1)
throw new Error("wrong set of classes documented: " + throw new Error("wrong set of classes documented: " +
Arrays.asList(root.getIncludedTypeElements())); Arrays.asList(classes));
return true; return true;
} }

View file

@ -61,6 +61,7 @@ import java.util.Locale;
import java.util.Set; import java.util.Set;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
import javax.lang.model.util.ElementFilter;
import javax.tools.Diagnostic.Kind; import javax.tools.Diagnostic.Kind;
import jdk.javadoc.doclet.Doclet; import jdk.javadoc.doclet.Doclet;
@ -92,7 +93,7 @@ public class SourceOption implements Doclet {
} }
public boolean run(DocletEnvironment root) { public boolean run(DocletEnvironment root) {
root.getIncludedTypeElements(); ElementFilter.typesIn(root.getIncludedElements());
return true; return true;
} }

View file

@ -179,6 +179,16 @@ public class JavadocTask extends AbstractTask<JavadocTask> {
return this; return this;
} }
/**
* Sets the options.
* @param options the options
* @return this task object
*/
public JavadocTask options(List<String> options) {
this.options = options;
return this;
}
/** /**
* Sets the files to be documented. * Sets the files to be documented.
* @param files the files * @param files the files