8159305: Enhance the javadoc tool to support module related options
Reviewed-by: bpatel, jjg
--- a/langtools/src/java.compiler/share/classes/javax/tools/JavaCompiler.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/java.compiler/share/classes/javax/tools/JavaCompiler.java Thu Aug 18 05:48:35 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -160,7 +160,7 @@
* log all calls to {@linkplain JavaFileManager#flush}:
*
* <pre>
- * final {@linkplain java.util.logging.Logger Logger} logger = ...;
+ * final Logger logger = ...;
* {@code Iterable<? extends JavaFileObject>} compilationUnits = ...;
* JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
* StandardJavaFileManager stdFileManager = compiler.getStandardFileManager(null, null, null);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/Doclet.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/Doclet.java Thu Aug 18 05:48:35 2016 -0700
@@ -63,8 +63,7 @@
/**
* Initializes this doclet with the given locale and error reporter.
* This locale will be used by the reporter and the doclet components.
- * It is recommended to call this as early as possible, for a
- * uniform localized user experience,
+ *
* @param locale the locale to be used
* @param reporter the reporter to be used
*/
@@ -74,6 +73,7 @@
* Returns a name identifying the doclet. A name is a simple identifier
* without white spaces, as defined in <cite>The Java™ Language Specification</cite>,
* section 6.2 "Names and Identifiers".
+ *
* @return name of the Doclet
*/
public abstract String getName();
@@ -81,7 +81,7 @@
/**
* 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();
@@ -90,7 +90,7 @@
* by this doclet.
*
* @return the language version supported by this doclet, usually
- * the latest version.
+ * the latest version
*/
public SourceVersion getSupportedSourceVersion();
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/DocletEnvironment.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/DocletEnvironment.java Thu Aug 18 05:48:35 2016 -0700
@@ -30,6 +30,8 @@
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
@@ -48,17 +50,34 @@
public interface DocletEnvironment {
/**
* Returns the <a href="package-summary.html#included">included</a>
- * classes, interfaces and enums in all packages.
+ * modules.
+ *
+ * @return a set of included module elements
+ */
+ Set<ModuleElement> getIncludedModuleElements();
+
+ /**
+ * Returns the <a href="package-summary.html#included">included</a>
+ * annotation types, classes, interfaces and enums in all packages.
*
- * @return a Set containing {@link javax.lang.model.element.TypeElement TypeElements}.
+ * @return a set of included type elements
*/
- Set<TypeElement> getIncludedClasses();
+ Set<TypeElement> getIncludedTypeElements();
+
+ /**
+ * Returns the <a href="package-summary.html#included">included</a>
+ * packages.
+ *
+ * @return a set of included package elements
+ */
+ Set<PackageElement> getIncludedPackageElements();
/**
* Returns an instance of the {@code DocTrees} utility class.
* This class provides methods to access {@code TreePath}s, {@code DocCommentTree}s
* and so on.
- * @return a utility class to operate on doc trees.
+ *
+ * @return a utility class to operate on doc trees
*/
DocTrees getDocTrees();
@@ -66,21 +85,23 @@
* Returns an instance of the {@code Elements} utility class.
* This class provides methods for operating on
* {@link javax.lang.model.element.Element elements}.
+ *
* @return a utility class to operate on elements
*/
Elements getElementUtils();
/**
- * Returns the selected elements that can be documented.
+ * 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.
+ * @return elements selected, an empty list if none
*/
List<Element> getSelectedElements(List<? extends Element> elements);
/**
- * Returns the elements <a href="package-summary.html#included">specified</a>
- * on the command line, usually PackageElements and TypeElements.
+ * 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.
*
@@ -92,6 +113,7 @@
* Returns an instance of the {@code Types} utility class.
* This class provides methods for operating on
* {@link javax.lang.model.type.TypeMirror type mirrors}.
+ *
* @return a utility class to operate on type mirrors
*/
Types getTypeUtils();
@@ -117,4 +139,18 @@
* @return the source version
*/
SourceVersion getSourceVersion();
+
+ /**
+ * Returns the required level of module documentation.
+ *
+ * @return the required level of module documentation
+ */
+ public ModuleMode getModuleMode();
+
+ enum ModuleMode {
+ /** Indicate API level documentation is required */
+ API,
+ /** Indicate Detailed documentation is required */
+ ALL
+ }
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/package-info.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/doclet/package-info.java Thu Aug 18 05:48:35 2016 -0700
@@ -27,7 +27,7 @@
* The Doclet API provides an environment which, in conjunction with
* the Language Model API and Compiler Tree API, allows clients
* to inspect the source-level structures of programs and
- * libraries, including javadoc comments embedded in the source.
+ * libraries, including API comments embedded in the source.
*
* <p style="font-style: italic">
* <b>Note:</b> The declarations in this package supersede those
@@ -57,15 +57,58 @@
* <a name="terminology"></a>
* <h3>Terminology</h3>
*
+ * <a name="specified"></a>
+ * Module, package and source file names can be provided as parameters to the
+ * javadoc tool -- these are called the <em>specified</em> set containing
+ * module elements, package elements and type elements.
+ * <p>
+ * Javadoc <em>selection control</em> can be specified with
+ * {@code --show-members:value}, {@code --showtypes:value}, where value can be one of
+ * the following:
+ * <ul>
+ * <li> public -- considers only public elements
+ * <li> protected -- considers public and protected elements
+ * <li> package -- considers public, protected and package private elements
+ * <li> private -- considers all elements
+ * </ul>
+ *
+ * The {@code --show-package:value} where a value of "exported" or "all" can be used to
+ * consider only exported packages or all packages within a module.
+ * <p>
+ * The {@code --expand-requires:value}, expands the "requires" directives of a
+ * module declaration, to create a module set to considered for documentation
+ * as follows:
+ * <ul>
+ * <li> public -- follows and expands all "requires public" edges in the module graph
+ * <li> all -- follows and expands all "requires" edges in the module graph.
+ * By default, only the specified modules will be considered, without expansion
+ * of the module dependencies.
+ * </ul>
* <a name="included"></a>
- * When calling javadoc, one can pass in package names and source file names --
- * these are called the <em>specified</em> PackageElements and TypeElements.
- * Javadoc options are also passed in; the <em>access control</em> Javadoc options
- * ({@code -public}, {@code -protected}, {@code -package},
- * and {@code -private}) are used to filter program elements, producing a
- * result set, called the <em>included</em> set, or "selected" set.
+ * 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>
-
+ * <a name="legacy-interactions"></a>
+ * <h4>Interactions with older options.</h4>
+ *
+ * The new --show-* options provide a more detailed replacement for the older
+ * options -public, -protected, -package, -private. Alternatively, the older
+ * options can continue to be used as shorter forms for combinations of the
+ * new options, as described below:
+ <table style="font-family: monospace" border=1>
+ <caption>Short form options mapping</caption>
+ <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><td>-public<td>public<td>public<td>exported<td>api
+ <tr><td>-protected<td>protected<td>protected<td>exported<td>api
+ <tr><td>-package<td>package<td>package<td>all<td>all
+ <tr><td>-private<td>private<td>private<td>all<td>all
+ </table>
+ * <p>
* <a name="qualified"></a>
* A <em>qualified</em> element name is one that has its package
* name prepended to it, such as {@code java.lang.String}. A non-qualified
@@ -96,14 +139,14 @@
* }
*
* @Override
- * public boolean run(RootDoc root) {
+ * public boolean run(DocletEnvironment docEnv) {
* // cache the DocTrees utility class to access DocComments
- * DocTrees docTrees = root.getDocTrees();
+ * DocTrees docTrees = docEnv.getDocTrees();
*
* // location of an element in the same directory as overview.html
* try {
* Element barElement = null;
- * for (Element e : root.getIncludedClasses()) {
+ * for (Element e : docEnv.getIncludedClasses()) {
* if (e.getSimpleName().toString().equals("FooBar")) {
* barElement = e;
* }
@@ -118,7 +161,7 @@
* System.err.println("No overview.html found.");
* }
*
- * for (TypeElement t : root.getIncludedClasses()) {
+ * for (TypeElement t : docEnv.getIncludedClasses()) {
* System.out.println(t.getKind() + ":" + t);
* for (Element e : t.getEnclosedElements()) {
* DocCommentTree docCommentTree = docTrees.getDocCommentTree(e);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractExecutableMemberWriter.java Thu Aug 18 05:48:35 2016 -0700
@@ -115,7 +115,7 @@
* Add the summary link for the member.
*
* @param context the id of the context where the link will be printed
- * @param te the classDoc that we should link to
+ * @param te the type element being linked to
* @param member the member being linked to
* @param tdSummary the content tree to which the link will be added
*/
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractModuleIndexWriter.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractModuleIndexWriter.java Thu Aug 18 05:48:35 2016 -0700
@@ -28,6 +28,7 @@
import java.io.*;
import java.util.Map;
import java.util.Set;
+import java.util.SortedMap;
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
@@ -57,7 +58,7 @@
/**
* Modules to be documented.
*/
- protected Map<ModuleElement, Set<PackageElement>> modules;
+ protected SortedMap<ModuleElement, Set<PackageElement>> modules;
/**
* Constructor. Also initializes the modules variable.
@@ -142,7 +143,7 @@
*
* @param title the title of the window.
* @param includeScript boolean set true if windowtitle script is to be included
- * @param moduleName the name of the module being documented
+ * @param mdle the name of the module being documented
*/
protected void buildModulePackagesIndexFile(String title,
boolean includeScript, ModuleElement mdle) throws IOException {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeRequiredMemberWriterImpl.java Thu Aug 18 05:48:35 2016 -0700
@@ -105,7 +105,7 @@
/**
* {@inheritDoc}
*/
- public void addAnnotationDetailsTreeHeader(TypeElement classDoc,
+ public void addAnnotationDetailsTreeHeader(TypeElement te,
Content memberDetailsTree) {
if (!writer.printedAnnotationHeading) {
memberDetailsTree.addContent(writer.getMarkerAnchor(
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java Thu Aug 18 05:48:35 2016 -0700
@@ -179,7 +179,7 @@
*/
public static void generate(ConfigurationImpl configuration, ClassTree classtree) {
ClassUseMapper mapper = new ClassUseMapper(configuration, classtree);
- for (TypeElement aClass : configuration.docEnv.getIncludedClasses()) {
+ for (TypeElement aClass : configuration.docEnv.getIncludedTypeElements()) {
// If -nodeprecated option is set and the containing package is marked
// 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
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConfigurationImpl.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ConfigurationImpl.java Thu Aug 18 05:48:35 2016 -0700
@@ -25,7 +25,6 @@
package jdk.javadoc.internal.doclets.formats.html;
-import java.io.IOException;
import java.net.*;
import java.util.*;
@@ -34,14 +33,10 @@
import javax.lang.model.element.TypeElement;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
-import javax.tools.JavaFileManager.Location;
import javax.tools.StandardJavaFileManager;
-import javax.tools.StandardLocation;
import com.sun.source.util.DocTreePath;
import com.sun.tools.doclint.DocLint;
-import com.sun.tools.javac.code.Symbol.ModuleSymbol;
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.DocletEnvironment;
@@ -383,7 +378,7 @@
if (!docEnv.getSpecifiedElements().isEmpty()) {
Map<String, PackageElement> map = new HashMap<>();
PackageElement pkg;
- List<TypeElement> classes = new ArrayList<>(docEnv.getIncludedClasses());
+ List<TypeElement> classes = new ArrayList<>(docEnv.getIncludedTypeElements());
for (TypeElement aClass : classes) {
pkg = utils.containingPackage(aClass);
if (!map.containsKey(utils.getPackageName(pkg))) {
@@ -420,7 +415,7 @@
* package to document. It will be a class page(first in the sorted order),
* if only classes are provided on the command line.
*
- * @param docEnv Root of the program structure.
+ * @param docEnv the doclet environment
*/
protected void setTopFile(DocletEnvironment docEnv) {
if (!checkForDeprecation(docEnv)) {
@@ -429,9 +424,11 @@
if (createoverview) {
topFile = DocPaths.overviewSummary(frames);
} else {
- if (packages.size() == 1 && packages.first().isUnnamed()) {
- if (!docEnv.getIncludedClasses().isEmpty()) {
- List<TypeElement> classes = new ArrayList<>(docEnv.getIncludedClasses());
+ if (showModules) {
+ topFile = DocPath.empty.resolve(DocPaths.moduleSummary(modules.first()));
+ } else if (packages.size() == 1 && packages.first().isUnnamed()) {
+ List<TypeElement> classes = new ArrayList<>(docEnv.getIncludedTypeElements());
+ if (!classes.isEmpty()) {
TypeElement te = getValidClass(classes);
topFile = DocPath.forClass(utils, te);
}
@@ -454,7 +451,7 @@
}
protected boolean checkForDeprecation(DocletEnvironment docEnv) {
- for (TypeElement te : docEnv.getIncludedClasses()) {
+ for (TypeElement te : docEnv.getIncludedTypeElements()) {
if (isGeneratedDoc(te)) {
return true;
}
@@ -579,21 +576,6 @@
return contents.getContent(key, o0, o1, o2);
}
-
- @Override
- public Location getLocationForPackage(PackageElement pd) {
- JavaFileManager fm = getFileManager();
- if (fm.hasLocation(StandardLocation.MODULE_SOURCE_PATH) && (pd instanceof PackageSymbol)) {
- try {
- ModuleSymbol msym = ((PackageSymbol) pd).modle;
- return fm.getModuleLocation(StandardLocation.MODULE_SOURCE_PATH, msym.name.toString());
- } catch (IOException e) {
- throw new DocletAbortException(e);
- }
- }
- return StandardLocation.SOURCE_PATH;
- }
-
protected void buildSearchTagIndex() {
for (SearchIndexItem sii : tagSearchIndex) {
String tagLabel = sii.getLabel();
@@ -725,7 +707,7 @@
return true;
}
},
- new Hidden(this, "-overview", 1) {
+ new Option(this, "-overview", 1) {
@Override
public boolean process(String opt, ListIterator<String> args) {
optionsProcessed.add(this);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java Thu Aug 18 05:48:35 2016 -0700
@@ -827,8 +827,8 @@
* @return a content tree for the link
*/
protected Content getNavLinkTree() {
- List<PackageElement> packages = new ArrayList<>(utils.getSpecifiedPackages());
- DocPath docPath = packages.size() == 1 && utils.getSpecifiedClasses().isEmpty()
+ List<PackageElement> packages = new ArrayList<>(configuration.getSpecifiedPackages());
+ DocPath docPath = packages.size() == 1 && configuration.getSpecifiedClasses().isEmpty()
? pathString(packages.get(0), DocPaths.PACKAGE_TREE)
: pathToRoot.resolve(DocPaths.OVERVIEW_TREE);
return HtmlTree.LI(getHyperLink(docPath, contents.treeLabel, "", ""));
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleFrameWriter.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleFrameWriter.java Thu Aug 18 05:48:35 2016 -0700
@@ -80,9 +80,9 @@
throws IOException {
super(configuration, DocPaths.moduleTypeFrame(moduleElement));
this.mdle = moduleElement;
- if (utils.getSpecifiedPackages().isEmpty()) {
+ if (configuration.getSpecifiedPackages().isEmpty()) {
documentedClasses = new TreeSet<>(utils.makeGeneralPurposeComparator());
- documentedClasses.addAll(configuration.docEnv.getIncludedClasses());
+ documentedClasses.addAll(configuration.docEnv.getIncludedTypeElements());
}
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageFrameWriter.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageFrameWriter.java Thu Aug 18 05:48:35 2016 -0700
@@ -84,9 +84,9 @@
public PackageFrameWriter(ConfigurationImpl configuration, PackageElement packageElement) {
super(configuration, DocPath.forPackage(packageElement).resolve(DocPaths.PACKAGE_FRAME));
this.packageElement = packageElement;
- if (utils.getSpecifiedPackages().isEmpty()) {
+ if (configuration.getSpecifiedPackages().isEmpty()) {
documentedClasses = new TreeSet<>(utils.makeGeneralPurposeComparator());
- documentedClasses.addAll(configuration.docEnv.getIncludedClasses());
+ documentedClasses.addAll(configuration.docEnv.getIncludedTypeElements());
}
}
@@ -136,7 +136,7 @@
*/
protected void addClassListing(HtmlTree contentTree) {
Configuration config = configuration;
- if (utils.isIncluded(packageElement)) {
+ if (utils.isSpecified(packageElement)) {
addClassKindListing(utils.getInterfaces(packageElement),
contents.interfaces, contentTree);
addClassKindListing(utils.getOrdinaryClasses(packageElement),
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SerializedFormWriterImpl.java Thu Aug 18 05:48:35 2016 -0700
@@ -70,7 +70,7 @@
public SerializedFormWriterImpl(ConfigurationImpl configuration)
throws IOException {
super(configuration, DocPaths.SERIALIZED_FORM);
- visibleClasses = configuration.docEnv.getIncludedClasses();
+ visibleClasses = configuration.docEnv.getIncludedTypeElements();
}
/**
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/SourceToHTMLConverter.java Thu Aug 18 05:48:35 2016 -0700
@@ -112,13 +112,13 @@
if (docEnv == null || outputdir == null) {
return;
}
- for (PackageElement pkg : utils.getSpecifiedPackages()) {
+ for (PackageElement pkg : configuration.getSpecifiedPackages()) {
// If -nodeprecated option is set and the package is marked as deprecated,
// do not convert the package files to HTML.
if (!(configuration.nodeprecated && utils.isDeprecated(pkg)))
convertPackage(pkg, outputdir);
}
- for (TypeElement te : utils.getSpecifiedClasses()) {
+ for (TypeElement te : configuration.getSpecifiedClasses()) {
// If -nodeprecated option is set and the class is marked as deprecated
// or the containing package is deprecated, do not convert the
// package files to HTML.
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties Thu Aug 18 05:48:35 2016 -0700
@@ -204,6 +204,10 @@
doclet.usage.splitindex.description=Split index into one file per letter
+doclet.usage.overview.parameters=<file>
+doclet.usage.overview.description=Read overview documentation from HTML file
+
+
doclet.usage.windowtitle.parameters=<text>
doclet.usage.windowtitle.description=Browser window title for the documentation
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/AbstractDoclet.java Thu Aug 18 05:48:35 2016 -0700
@@ -90,13 +90,13 @@
/**
* The method that starts the execution of the doclet.
*
- * @param root the {@link DocletEnvironment} that points to the source to document.
+ * @param docEnv the {@link DocletEnvironment}.
* @return true if the doclet executed without error. False otherwise.
*/
@Override
- public boolean run(DocletEnvironment root) {
+ public boolean run(DocletEnvironment docEnv) {
configuration = configuration();
- configuration.docEnv = root;
+ configuration.docEnv = docEnv;
configuration.cmtUtils = new CommentUtils(configuration);
configuration.utils = new Utils(configuration);
utils = configuration.utils;
@@ -108,7 +108,7 @@
}
try {
- startGeneration(root);
+ startGeneration(docEnv);
} catch (Configuration.Fault f) {
configuration.reporter.print(ERROR, f.getMessage());
return false;
@@ -153,8 +153,8 @@
*
* @see jdk.doclet.DocletEnvironment
*/
- private void startGeneration(DocletEnvironment root) throws Configuration.Fault, Exception {
- if (root.getIncludedClasses().isEmpty()) {
+ private void startGeneration(DocletEnvironment docEnv) throws Configuration.Fault, Exception {
+ if (docEnv.getIncludedTypeElements().isEmpty()) {
messages.error("doclet.No_Public_Classes_To_Document");
return;
}
@@ -165,24 +165,24 @@
configuration.getDocletSpecificBuildDate());
ClassTree classtree = new ClassTree(configuration, configuration.nodeprecated);
- generateClassFiles(root, classtree);
+ generateClassFiles(docEnv, classtree);
configuration.utils.copyDocFiles(DocPaths.DOC_FILES);
PackageListWriter.generate(configuration);
generatePackageFiles(classtree);
generateModuleFiles();
- generateOtherFiles(root, classtree);
+ generateOtherFiles(docEnv, classtree);
configuration.tagletManager.printReport();
}
/**
* Generate additional documentation that is added to the API documentation.
*
- * @param root the DocletEnvironment of source to document.
+ * @param docEnv the DocletEnvironment.
* @param classtree the data structure representing the class tree.
*/
- protected void generateOtherFiles(DocletEnvironment root, ClassTree classtree) throws Exception {
+ protected void generateOtherFiles(DocletEnvironment docEnv, ClassTree classtree) throws Exception {
BuilderFactory builderFactory = configuration.getBuilderFactory();
AbstractBuilder constantsSummaryBuilder = builderFactory.getConstantsSummaryBuilder();
constantsSummaryBuilder.build();
@@ -213,13 +213,16 @@
/**
* Iterate through all classes and construct documentation for them.
*
- * @param root the DocletEnvironment of source to document.
+ * @param docEnv the DocletEnvironment.
* @param classtree the data structure representing the class tree.
*/
- protected void generateClassFiles(DocletEnvironment root, ClassTree classtree) {
+ protected void generateClassFiles(DocletEnvironment docEnv, ClassTree classtree) {
generateClassFiles(classtree);
SortedSet<PackageElement> packages = new TreeSet<>(utils.makePackageComparator());
- packages.addAll(utils.getSpecifiedPackages());
+ packages.addAll(configuration.getSpecifiedPackages());
+ configuration.modulePackages.values().stream().forEach(pset -> {
+ packages.addAll(pset);
+ });
packages.stream().forEach((pkg) -> {
generateClassFiles(utils.getAllClasses(pkg), classtree);
});
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java Thu Aug 18 05:48:35 2016 -0700
@@ -32,8 +32,8 @@
import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementFilter;
import javax.tools.JavaFileManager;
-import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import com.sun.source.util.DocTreePath;
@@ -164,17 +164,17 @@
public final MetaKeywords metakeywords;
/**
- * The list of doc-file subdirectories to exclude
+ * The set of doc-file subdirectories to exclude
*/
protected Set<String> excludedDocFileDirs;
/**
- * The list of qualifiers to exclude
+ * The set of qualifiers to exclude
*/
protected Set<String> excludedQualifiers;
/**
- * The Root of the generated Program Structure from the Doclet API.
+ * The doclet environment.
*/
public DocletEnvironment docEnv;
@@ -314,14 +314,13 @@
public abstract boolean finishOptionSettings();
public CommentUtils cmtUtils;
- public SortedSet<ModuleElement> modules;
/**
* A sorted set of packages specified on the command-line merged with a
* collection of packages that contain the classes specified on the
* command-line.
*/
- public SortedSet<PackageElement> packages;
+ public SortedSet<PackageElement> packages = null;
protected final List<Doclet.Option> optionsProcessed;
@@ -335,9 +334,14 @@
public DocFileFactory docFileFactory;
/**
- * A sorted set of modules containing the packages.
+ * A sorted map, giving the (specified|included|other) packages for each module.
*/
- public Map<ModuleElement, Set<PackageElement>> modulePackages;
+ public SortedMap<ModuleElement, Set<PackageElement>> modulePackages;
+
+ /**
+ * The list of known modules, that should be documented.
+ */
+ public SortedSet<ModuleElement> modules;
protected static final String sharedResourceBundleName =
"jdk.javadoc.internal.doclets.toolkit.resources.doclets";
@@ -372,25 +376,39 @@
private void initModules() {
// Build the modules structure used by the doclet
+ modules = new TreeSet<>(utils.makeModuleComparator());
+ modules.addAll(getSpecifiedModules());
+
modulePackages = new TreeMap<>(utils.makeModuleComparator());
for (PackageElement p: packages) {
ModuleElement mdle = docEnv.getElementUtils().getModuleOf(p);
if (mdle != null && !mdle.isUnnamed()) {
- Set<PackageElement> s = modulePackages.get(mdle);
- if (s == null)
- modulePackages.put(mdle, s = new TreeSet<>(utils.makePackageComparator()));
+ Set<PackageElement> s = modulePackages
+ .computeIfAbsent(mdle, m -> new TreeSet<>(utils.makePackageComparator()));
s.add(p);
}
}
- modules = new TreeSet<>(utils.makeModuleComparator());
+
+ for (PackageElement p: docEnv.getIncludedPackageElements()) {
+ ModuleElement mdle = docEnv.getElementUtils().getModuleOf(p);
+ if (mdle != null && !mdle.isUnnamed()) {
+ Set<PackageElement> s = modulePackages
+ .computeIfAbsent(mdle, m -> new TreeSet<>(utils.makePackageComparator()));
+ s.add(p);
+ }
+ }
+
modules.addAll(modulePackages.keySet());
- showModules = (modulePackages.size() > 1);
+ showModules = !modules.isEmpty();
+ for (Set<PackageElement> pkgs : modulePackages.values()) {
+ packages.addAll(pkgs);
+ }
}
private void initPackages() {
packages = new TreeSet<>(utils.makePackageComparator());
- packages.addAll(utils.getSpecifiedPackages());
- for (TypeElement aClass : utils.getSpecifiedClasses()) {
+ packages.addAll(getSpecifiedPackages());
+ for (TypeElement aClass : getSpecifiedClasses()) {
packages.add(utils.containingPackage(aClass));
}
}
@@ -629,7 +647,7 @@
if (docencoding == null) {
docencoding = encoding;
}
- typeElementCatalog = new TypeElementCatalog(utils.getSpecifiedClasses(), this);
+ typeElementCatalog = new TypeElementCatalog(getSpecifiedClasses(), this);
initTagletManager(customTagStrs);
groups.stream().forEach((grp) -> {
group.checkPackageGroups(grp.value1, grp.value2);
@@ -880,6 +898,35 @@
: 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
* {@link Resources resources}.
@@ -1146,6 +1193,4 @@
this.value2 = value2;
}
}
-
- public abstract Location getLocationForPackage(PackageElement pd);
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/OverviewElement.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/OverviewElement.java Thu Aug 18 05:48:35 2016 -0700
@@ -40,8 +40,8 @@
import jdk.javadoc.doclet.DocletEnvironment;
/**
- * This is a pseudo element wrapper for the root element, essentially to
- * associate overview documentation's DocCommentTree to this Element.
+ * This is a pseudo element wrapper for the overview element, essentially to
+ * associate overview documentation's DocCommentTree to this element.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
@@ -50,10 +50,10 @@
*/
public class OverviewElement implements Element {
- public final DocletEnvironment root;
+ public final DocletEnvironment docEnv;
- OverviewElement(DocletEnvironment root) {
- this.root = root;
+ OverviewElement(DocletEnvironment docEnv) {
+ this.docEnv = docEnv;
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/WorkArounds.java Thu Aug 18 05:48:35 2016 -0700
@@ -187,7 +187,7 @@
// TODO: implement using jx.l.model
public boolean isVisible(TypeElement te) {
- return toolEnv.isVisible((ClassSymbol)te);
+ return ((DocEnvImpl)(configuration.docEnv)).etable.isVisible(te);
}
// TODO: fix the caller
@@ -286,7 +286,7 @@
// TODO: investigate and reimplement without javac dependencies.
public boolean shouldDocument(Element e) {
- return toolEnv.shouldDocument(e);
+ return ((DocEnvImpl)(configuration.docEnv)).etable.shouldDocument(e);
}
//------------------Start of Serializable Implementation---------------------//
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/PackageSummaryBuilder.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/PackageSummaryBuilder.java Thu Aug 18 05:48:35 2016 -0700
@@ -175,7 +175,7 @@
List<String> interfaceTableHeader = Arrays.asList(configuration.getText("doclet.Interface"),
configuration.getText("doclet.Description"));
- SortedSet<TypeElement> ilist = utils.isIncluded(packageElement)
+ SortedSet<TypeElement> ilist = utils.isSpecified(packageElement)
? utils.getTypeElementsAsSortedSet(utils.getInterfaces(packageElement))
: configuration.typeElementCatalog.interfaces(packageElement);
SortedSet<TypeElement> interfaces = utils.filterOutPrivateClasses(ilist, configuration.javafx);
@@ -200,7 +200,7 @@
configuration.getText("doclet.classes"));
List<String> classTableHeader = Arrays.asList(configuration.getText("doclet.Class"),
configuration.getText("doclet.Description"));
- SortedSet<TypeElement> clist = utils.isIncluded(packageElement)
+ SortedSet<TypeElement> clist = utils.isSpecified(packageElement)
? utils.getTypeElementsAsSortedSet(utils.getOrdinaryClasses(packageElement))
: configuration.typeElementCatalog.ordinaryClasses(packageElement);
SortedSet<TypeElement> classes = utils.filterOutPrivateClasses(clist, configuration.javafx);
@@ -225,7 +225,7 @@
configuration.getText("doclet.enums"));
List<String> enumTableHeader = Arrays.asList(configuration.getText("doclet.Enum"),
configuration.getText("doclet.Description"));
- SortedSet<TypeElement> elist = utils.isIncluded(packageElement)
+ SortedSet<TypeElement> elist = utils.isSpecified(packageElement)
? utils.getTypeElementsAsSortedSet(utils.getEnums(packageElement))
: configuration.typeElementCatalog.enums(packageElement);
SortedSet<TypeElement> enums = utils.filterOutPrivateClasses(elist, configuration.javafx);
@@ -251,7 +251,7 @@
List<String> exceptionTableHeader = Arrays.asList(configuration.getText("doclet.Exception"),
configuration.getText("doclet.Description"));
Set<TypeElement> iexceptions =
- utils.isIncluded(packageElement)
+ utils.isSpecified(packageElement)
? utils.getTypeElementsAsSortedSet(utils.getExceptions(packageElement))
: configuration.typeElementCatalog.exceptions(packageElement);
SortedSet<TypeElement> exceptions = utils.filterOutPrivateClasses(iexceptions,
@@ -278,7 +278,7 @@
List<String> errorTableHeader = Arrays.asList(configuration.getText("doclet.Error"),
configuration.getText("doclet.Description"));
Set<TypeElement> ierrors =
- utils.isIncluded(packageElement)
+ utils.isSpecified(packageElement)
? utils.getTypeElementsAsSortedSet(utils.getErrors(packageElement))
: configuration.typeElementCatalog.errors(packageElement);
SortedSet<TypeElement> errors = utils.filterOutPrivateClasses(ierrors, configuration.javafx);
@@ -305,7 +305,7 @@
configuration.getText("doclet.AnnotationType"),
configuration.getText("doclet.Description"));
SortedSet<TypeElement> iannotationTypes =
- utils.isIncluded(packageElement)
+ utils.isSpecified(packageElement)
? utils.getTypeElementsAsSortedSet(utils.getAnnotationTypes(packageElement))
: configuration.typeElementCatalog.annotationTypes(packageElement);
SortedSet<TypeElement> annotationTypes = utils.filterOutPrivateClasses(iannotationTypes,
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/SerializedFormBuilder.java Thu Aug 18 05:48:35 2016 -0700
@@ -125,7 +125,7 @@
*/
public void build() throws IOException {
SortedSet<TypeElement> rootclasses = new TreeSet<>(utils.makeGeneralPurposeComparator());
- rootclasses.addAll(configuration.docEnv.getIncludedClasses());
+ rootclasses.addAll(configuration.docEnv.getIncludedTypeElements());
if (!serialClassFoundToDocument(rootclasses)) {
//Nothing to document.
return;
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassTree.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassTree.java Thu Aug 18 05:48:35 2016 -0700
@@ -117,16 +117,16 @@
baseEnums = new TreeSet<>(comparator);
baseClasses = new TreeSet<>(comparator);
baseInterfaces = new TreeSet<>(comparator);
- buildTree(configuration.docEnv.getIncludedClasses());
+ buildTree(configuration.docEnv.getIncludedTypeElements());
}
/**
* Constructor. Build the Tree using the Root of this Javadoc run.
*
- * @param root Root of the Document.
+ * @param docEnv the DocletEnvironment.
* @param configuration The current configuration of the doclet.
*/
- public ClassTree(DocletEnvironment root, Configuration configuration) {
+ public ClassTree(DocletEnvironment docEnv, Configuration configuration) {
this.configuration = configuration;
this.utils = configuration.utils;
comparator = utils.makeClassUseComparator();
@@ -134,7 +134,7 @@
baseEnums = new TreeSet<>(comparator);
baseClasses = new TreeSet<>(comparator);
baseInterfaces = new TreeSet<>(comparator);
- buildTree(configuration.docEnv.getIncludedClasses());
+ buildTree(configuration.docEnv.getIncludedTypeElements());
}
/**
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassUseMapper.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/ClassUseMapper.java Thu Aug 18 05:48:35 2016 -0700
@@ -208,7 +208,7 @@
implementingClasses(intfc);
}
// Map methods, fields, constructors using a class.
- Set<TypeElement> classes = docEnv.getIncludedClasses();
+ Set<TypeElement> classes = docEnv.getIncludedTypeElements();
for (TypeElement aClass : classes) {
PackageElement pkg = elementUtils.getPackageOf(aClass);
mapAnnotations(classToPackageAnnotations, pkg, pkg);
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DeprecatedAPIListBuilder.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DeprecatedAPIListBuilder.java Thu Aug 18 05:48:35 2016 -0700
@@ -96,7 +96,7 @@
}
}
deprecatedMap.put(DeprElementKind.PACKAGE, pset);
- for (Element e : configuration.docEnv.getIncludedClasses()) {
+ for (Element e : configuration.docEnv.getIncludedTypeElements()) {
TypeElement te = (TypeElement)e;
SortedSet<Element> eset;
if (utils.isDeprecated(e)) {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/IndexBuilder.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/IndexBuilder.java Thu Aug 18 05:48:35 2016 -0700
@@ -122,11 +122,11 @@
* given on the command line. Form separate list of those members depending
* upon their names.
*
- * @param root Root of the documemt.
+ * @param docEnv the doclet environment
*/
- protected void buildIndexMap(DocletEnvironment root) {
- Set<PackageElement> packages = utils.getSpecifiedPackages();
- Set<TypeElement> classes = root.getIncludedClasses();
+ protected void buildIndexMap(DocletEnvironment docEnv) {
+ Set<PackageElement> packages = configuration.getSpecifiedPackages();
+ Set<TypeElement> classes = docEnv.getIncludedTypeElements();
if (!classesOnly) {
if (packages.isEmpty()) {
Set<PackageElement> set = new HashSet<>();
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/PackageListWriter.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/PackageListWriter.java Thu Aug 18 05:48:35 2016 -0700
@@ -81,7 +81,7 @@
}
}
- protected void generatePackageListFile(DocletEnvironment root) {
+ protected void generatePackageListFile(DocletEnvironment docEnv) {
ArrayList<PackageElement> names = new ArrayList<>();
for (PackageElement pkg : configuration.packages) {
// if the -nodeprecated option is set and the package is marked as
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/TypeElementCatalog.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/TypeElementCatalog.java Thu Aug 18 05:48:35 2016 -0700
@@ -100,7 +100,7 @@
public TypeElementCatalog(Iterable<TypeElement> typeElements, Configuration config) {
this(config);
for (TypeElement typeElement : typeElements) {
- addClassDoc(typeElement);
+ addTypeElement(typeElement);
}
}
@@ -127,39 +127,38 @@
*
* @param typeElement the TypeElement to add to the catalog.
*/
- public final void addClassDoc(TypeElement typeElement) {
+ public final void addTypeElement(TypeElement typeElement) {
if (typeElement == null) {
return;
}
- addClass(typeElement, allClasses);
+ addTypeElement(typeElement, allClasses);
if (utils.isOrdinaryClass(typeElement)) {
- addClass(typeElement, ordinaryClasses);
+ addTypeElement(typeElement, ordinaryClasses);
} else if (utils.isException(typeElement)) {
- addClass(typeElement, exceptions);
+ addTypeElement(typeElement, exceptions);
} else if (utils.isEnum(typeElement)) {
- addClass(typeElement, enums);
+ addTypeElement(typeElement, enums);
} else if (utils.isAnnotationType(typeElement)) {
- addClass(typeElement, annotationTypes);
+ addTypeElement(typeElement, annotationTypes);
} else if (utils.isError(typeElement)) {
- addClass(typeElement, errors);
+ addTypeElement(typeElement, errors);
} else if (utils.isInterface(typeElement)) {
- addClass(typeElement, interfaces);
+ addTypeElement(typeElement, interfaces);
}
}
/**
* Add the given class to the given map.
*
- * @param typeElement the ClassDoc to add to the catalog.
+ * @param typeElement the class to add to the catalog.
* @param map the Map to add the TypeElement to.
*/
- private void addClass(TypeElement typeElement, Map<PackageElement, SortedSet<TypeElement>> map) {
+ private void addTypeElement(TypeElement typeElement, Map<PackageElement, SortedSet<TypeElement>> map) {
PackageElement pkg = utils.containingPackage(typeElement);
- if (utils.isIncluded(pkg) || (configuration.nodeprecated && utils.isDeprecated(pkg))) {
+ if (utils.isSpecified(pkg) || configuration.nodeprecated && utils.isDeprecated(pkg)) {
// No need to catalog this class if it's package is
- // included on the command line or if -nodeprecated option is set
- // and the containing package is marked as deprecated.
+ // specified on the command line or if -nodeprecated option is set
return;
}
@@ -186,7 +185,7 @@
* @param packageElement the package to return the classes for.
*/
public SortedSet<TypeElement> allClasses(PackageElement packageElement) {
- return utils.isIncluded(packageElement)
+ return utils.isSpecified(packageElement)
? utils.getTypeElementsAsSortedSet(utils.getEnclosedTypeElements(packageElement))
: getSet(allClasses, packageElement);
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java Thu Aug 18 05:48:35 2016 -0700
@@ -86,7 +86,6 @@
import static com.sun.source.doctree.DocTree.Kind.*;
-import com.sun.source.util.SimpleDocTreeVisitor;
import jdk.javadoc.internal.doclets.toolkit.Messages;
import static jdk.javadoc.internal.doclets.toolkit.builders.ConstantsSummaryBuilder.MAX_CONSTANT_VALUE_INDEX_LENGTH;
@@ -2220,31 +2219,6 @@
return oset;
}
- // cache these two as they are repeatedly called.
- private Set<TypeElement> specifiedClasses = null;
- private Set<PackageElement> specifiedPackages = null;
-
- private void initSpecifiedElements() {
- specifiedClasses = new LinkedHashSet<>(
- ElementFilter.typesIn(configuration.docEnv.getSpecifiedElements()));
- specifiedPackages = new LinkedHashSet<>(
- ElementFilter.packagesIn(configuration.docEnv.getSpecifiedElements()));
- }
-
- public Set<TypeElement> getSpecifiedClasses() {
- if (specifiedClasses == null || specifiedPackages == null) {
- initSpecifiedElements();
- }
- return specifiedClasses;
- }
-
- public Set<PackageElement> getSpecifiedPackages() {
- if (specifiedClasses == null || specifiedPackages == null) {
- initSpecifiedElements();
- }
- return specifiedPackages;
- }
-
private final HashMap<Element, SortedSet<TypeElement>> cachedClasses = new HashMap<>();
/**
* Returns a list containing classes and interfaces,
@@ -2577,6 +2551,34 @@
return configuration.docEnv.isIncluded(e);
}
+ private SimpleElementVisitor9<Boolean, Void> specifiedVisitor = null;
+ public boolean isSpecified(Element e) {
+ if (specifiedVisitor == null) {
+ specifiedVisitor = new SimpleElementVisitor9<Boolean, Void>() {
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitModule(ModuleElement e, Void p) {
+ return configuration.getSpecifiedModules().contains(e);
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitPackage(PackageElement e, Void p) {
+ return configuration.getSpecifiedPackages().contains(e);
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitType(TypeElement e, Void p) {
+ return configuration.getSpecifiedClasses().contains(e);
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ protected Boolean defaultAction(Element e, Void p) {
+ return false;
+ }
+ };
+ }
+ return specifiedVisitor.visit(e);
+ }
+
/**
* package name, an unnamed package is returned as <Unnamed>
* @param pkg
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/AccessKind.java Thu Aug 18 05:48:35 2016 -0700
@@ -0,0 +1,41 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package jdk.javadoc.internal.tool;
+
+/**
+ * The access value kinds.
+ */
+
+public enum AccessKind {
+ /** Limits access to public entities */
+ PUBLIC,
+ /** Limits access to public and protected entities */
+ PROTECTED,
+ /** Limits access to public, protected and package private entities */
+ PACKAGE,
+ /** No limits */
+ PRIVATE;
+}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/DocEnvImpl.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/DocEnvImpl.java Thu Aug 18 05:48:35 2016 -0700
@@ -25,7 +25,6 @@
package jdk.javadoc.internal.tool;
-import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -33,6 +32,7 @@
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
+import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
@@ -41,7 +41,6 @@
import com.sun.source.util.DocTrees;
import com.sun.tools.javac.code.Source;
-import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import jdk.javadoc.doclet.DocletEnvironment;
/**
@@ -60,202 +59,44 @@
*/
public class DocEnvImpl implements DocletEnvironment {
- /**
- * list of classes specified on the command line.
- */
- private Set<TypeElement> cmdLineClasses;
-
- /**
- * list of packages specified on the command line.
- */
- private Set<PackageElement> cmdLinePackages;
+ public final ElementsTable etable;
public final ToolEnvironment toolEnv;
/**
- * Constructor used when reading source files.
- *
- * @param toolEnv the documentation environment, state for this javadoc run
- * @param classes list of classes specified on the commandline
- * @param packages list of package names specified on the commandline
- */
- public DocEnvImpl(ToolEnvironment toolEnv, List<JCClassDecl> classes, List<String> packages) {
- this.toolEnv = toolEnv;
- setPackages(toolEnv, packages);
- setClasses(toolEnv, classes);
- }
-
- /**
- * Constructor used when reading class files.
+ * Construct a doclet environment.
*
- * @param toolEnv the documentation environment, state for this javadoc run
- * @param classes list of class names specified on the commandline
+ * @param toolEnv the tool environment
+ * @param etable the includes table, providing all the information
+ * with respect to specified, included/selected elements.
*/
- public DocEnvImpl(ToolEnvironment toolEnv, List<String> classes) {
- //super(env, null);
+ public DocEnvImpl(ToolEnvironment toolEnv, ElementsTable etable) {
this.toolEnv = toolEnv;
-
- Set<TypeElement> classList = new LinkedHashSet<>();
- for (String className : classes) {
- TypeElement c = toolEnv.loadClass(className);
- if (c == null)
- toolEnv.error(null, "javadoc.class_not_found", className);
- else
- classList.add(c);
- }
- cmdLineClasses = classList;
+ this.etable = etable;
}
- /**
- * Initialize classes information. Those classes are input from
- * command line.
- *
- * @param toolEnv the compilation environment
- * @param classes a list of ClassDeclaration
- */
- private void setClasses(ToolEnvironment toolEnv, List<JCClassDecl> classes) {
- Set<TypeElement> result = new LinkedHashSet<>();
- classes.stream().filter((def) -> (toolEnv.shouldDocument(def.sym))).forEach((def) -> {
- TypeElement te = (TypeElement)def.sym;
- if (te != null) {
- toolEnv.setIncluded((Element)def.sym);
- result.add(te);
- }
- });
- cmdLineClasses = Collections.unmodifiableSet(result);
+ @Override
+ public Set<ModuleElement> getIncludedModuleElements() {
+ return etable.getIncludedModuleElements();
}
- /**
- * Initialize packages information.
- *
- * @param toolEnv the compilation environment
- * @param packages a list of package names (String)
- */
- private void setPackages(ToolEnvironment toolEnv, List<String> packages) {
- Set<PackageElement> packlist = new LinkedHashSet<>();
- packages.stream().forEach((name) -> {
- PackageElement pkg = getElementUtils().getPackageElement(name);
- if (pkg != null) {
- toolEnv.setIncluded(pkg);
- packlist.add(pkg);
- } else {
- toolEnv.warning("main.no_source_files_for_package", name);
- }
- });
- cmdLinePackages = Collections.unmodifiableSet(packlist);
- }
-
- /**
- * Packages specified on the command line.
- */
- public Set<PackageElement> specifiedPackages() {
- return cmdLinePackages;
+ @Override
+ public Set<PackageElement> getIncludedPackageElements() {
+ return etable.getIncludedPackageElements();
}
/**
- * Classes and interfaces specified on the command line,
- * including their inner classes
- */
- public Set<TypeElement> specifiedClasses() {
- Set<TypeElement> out = new LinkedHashSet<>();
- cmdLineClasses.stream().forEach((te) -> {
- toolEnv.addAllClasses(out, te, true);
- });
- return out;
- }
-
- private Set<TypeElement> classesToDocument = null;
- /**
- * Return all classes and interfaces (including those inside
+ * Return all TypeElements (including those inside
* packages) to be documented.
*/
- public Set<TypeElement> getIncludedClasses() {
- if (classesToDocument == null) {
- Set<TypeElement> classes = new LinkedHashSet<>();
-
- cmdLineClasses.stream().forEach((te) -> {
- toolEnv.addAllClasses(classes, te, true);
- });
- cmdLinePackages.stream().forEach((pkg) -> {
- toolEnv.addAllClasses(classes, pkg);
- });
- classesToDocument = Collections.unmodifiableSet(classes);
- }
- return classesToDocument;
- }
-
- /**
- * Return the name of this item.
- *
- * @return the string <code>"*RootDocImpl*"</code>.
- */
- public String name() {
- return "*RootDocImpl*";
- }
-
- /**
- * Return the name of this Doc item.
- *
- * @return the string <code>"*RootDocImpl*"</code>.
- */
- public String qualifiedName() {
- return "*RootDocImpl*";
+ @Override
+ public Set<TypeElement> getIncludedTypeElements() {
+ return etable.getIncludedTypeElements();
}
- /**
- * Return true if this Element is included in the active set.
- * RootDocImpl isn't even a program entity so it is always false.
- */
@Override
public boolean isIncluded(Element e) {
- return toolEnv.isIncluded(e);
- }
-
-// Note: these reporting methods are no longer used.
-// /**
-// * Print error message, increment error count.
-// *
-// * @param msg message to print
-// */
-// public void printError(String msg) {
-// env.printError(msg);
-// }
-//
-// /**
-// * Print error message, increment error count.
-// *
-// * @param msg message to print
-// */
-// public void printError(DocTreePath path, String msg) {
-// env.printError(path, msg);
-// }
-//
-// public void printError(Element e, String msg) {
-// env.printError(e, msg);
-// }
-//
-// public void printWarning(Element e, String msg) {
-// env.printWarning(e, msg);
-// }
-//
-// public void printNotice(Element e, String msg) {
-// env.printNotice(e, msg);
-// }
-//
-// /**
-// * Print warning message, increment warning count.
-// *
-// * @param msg message to print
-// */
-// public void printWarning(String msg) {
-// env.printWarning(msg);
-// }
-
- /**
- * Return the current file manager.
- */
- public JavaFileManager getFileManager() {
- return toolEnv.fileManager;
+ return etable.isIncluded(e);
}
@Override
@@ -278,12 +119,9 @@
@Override
public Set<Element> getSpecifiedElements() {
Set<Element> out = new LinkedHashSet<>();
- specifiedPackages().stream().forEach((pe) -> {
- out.add(pe);
- });
- specifiedClasses().stream().forEach((e) -> {
- out.add(e);
- });
+ out.addAll(etable.getSpecifiedModuleElements());
+ out.addAll(etable.getSpecifiedPackageElements());
+ out.addAll(etable.getSpecifiedTypeElements());
return out;
}
@@ -301,4 +139,9 @@
public SourceVersion getSourceVersion() {
return Source.toSourceVersion(toolEnv.source);
}
+
+ @Override
+ public ModuleMode getModuleMode() {
+ return etable.getModuleMode();
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java Thu Aug 18 05:48:35 2016 -0700
@@ -0,0 +1,1204 @@
+/*
+ * Copyright (c) 2001, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+package jdk.javadoc.internal.tool;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.ModuleElement.ExportsDirective;
+import javax.lang.model.element.ModuleElement.RequiresDirective;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.SimpleElementVisitor9;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardLocation;
+
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.code.Kinds.Kind;
+import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symbol.CompletionFailure;
+import com.sun.tools.javac.code.Symbol.MethodSymbol;
+import com.sun.tools.javac.code.Symbol.ModuleSymbol;
+import com.sun.tools.javac.code.Symbol.PackageSymbol;
+import com.sun.tools.javac.code.Symbol.VarSymbol;
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.comp.Modules;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.DefinedBy;
+import com.sun.tools.javac.util.DefinedBy.Api;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Name;
+import com.sun.tools.javac.util.Names;
+import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.doclet.DocletEnvironment.ModuleMode;
+
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
+import static jdk.javadoc.internal.tool.JavadocTool.isValidClassName;
+
+/**
+ * This class manages elements specified on the command line, and
+ * produces "specified" and "included" data sets, needed by the
+ * doclet environment, as well as querying an elements' visibility
+ * or inclusion.
+ *
+ * A. Initialization phase: the class is initialized with the
+ * options table by the caller. Some program elements may not
+ * be specified via specific options, such as packages, classes,
+ * these are set with the use of setter methods, such setClassArgList
+ * and setClassDeclList.
+ *
+ * B. Scan and decode phase: this is performed by scanSpecifiedItems,
+ * to identify the modules specified on the command line, modules
+ * specified with qualified packages and qualified subpackages, the
+ * modules so identified are used to initialize the module system.
+ *
+ * C. Intermediate phase: before the final analysis can be done,
+ * intermediate methods can be used to get specified elements from
+ * the initialization phase, typically used to parse sources or packages
+ * specified on the command line.
+ *
+ * D. Analysis phase: the final analysis is performed to determine
+ * the packages that ought to be included, as follows:
+ *
+ * 1. computes the specified modules, by considering the option
+ * "expand-requires", this must be done exhaustively, as the package
+ * computation phase expects a completed module graph, in order to
+ * check the target of a qualified export is in the included set.
+ *
+ * 2. computes the packages that must be documented, by considering
+ * the option "show-packages", also if only exported packages are
+ * to be considered, then also check for qualified packages, and
+ * include only those packages whose target is in the included set.
+ *
+ * 3. compute the specified packages, as part of this, first compute
+ * the subpackages and exclude any packages, if required.
+ *
+ * 4. Finally, compute the types found by previous parsing steps,
+ * noting that, all enclosed types (nested types) must also be
+ * considered.
+ *
+ * E. Finally, this class provides methods to obtain the specified sets,
+ * which are frozen and cached in the analysis phase, the included
+ * sets, are computed lazily and cached for future use. An element
+ * can be checked if it should be documented, in which case, the
+ * element is checked against the included set and the result is
+ * cached, for performance reasons.
+ *
+ * Definitions:
+ * Fully included: an element is included and some or parts
+ * of it components are included implicitly, subject to a
+ * selection criteria of its enclosed children.
+ *
+ * Included: if the item should be documented.
+ *
+ * Rules for processing:
+ *
+ * 1. A specified element, meaning an element given on the
+ * command-line, and exposed via getSpecifiedElements()
+ * 2. Expand-contents, an internal pseudo term, meaning
+ * it is part of the recursive expansion of specified
+ * elements, meaning, the modules are expanded first, then
+ * the packages contained in the expanded modules, and then
+ * the types contained within the packages, to produce the
+ * collections returned by the methods
+ * getInclude{Module|Package|Type}Elements(), this is a
+ * downward expansion.
+ * 3. An included element, meaning it should be documented, and
+ * exposed via isIncluded, this enclosing element (module, package)
+ * is recursively included.
+ */
+public class ElementsTable {
+
+ private final ToolEnvironment toolEnv;
+ private final Symtab syms;
+ private final Names names;
+ private final JavaFileManager fm;
+ private final Location location;
+ private final Modules modules;
+ private final Map<ToolOption, Object> opts;
+
+ private final Map<String, Entry> entries = new LinkedHashMap<>();
+
+ // specified elements
+ private Set<ModuleElement> specifiedModuleElements = new LinkedHashSet<>();
+ private Set<PackageElement> specifiedPackageElements = new LinkedHashSet<>();
+ private Set<TypeElement> specifiedTypeElements =new LinkedHashSet<>();
+
+ // included elements
+ private Set<ModuleElement> includedModuleElements = null;
+ private Set<PackageElement> includedPackageElements = null;
+ private Set<TypeElement> includedTypeElements = null;
+
+ // cmdline specifiers
+ private Set<ModulePackage> cmdLinePackages = new LinkedHashSet<>();
+ private Set<ModulePackage> excludePackages = new LinkedHashSet<>();
+ private Set<ModulePackage> subPackages = new LinkedHashSet<>();
+
+ private List<JCClassDecl> classDecList = Collections.emptyList();
+ private List<String> classArgList = Collections.emptyList();
+ private com.sun.tools.javac.util.List<JCCompilationUnit> classTreeList = null;
+
+ private final Set<JavaFileObject.Kind> sourceKinds = EnumSet.of(JavaFileObject.Kind.SOURCE);
+
+ private final ModifierFilter accessFilter;
+
+ private final AccessKind expandRequires;
+
+ final boolean xclasses;
+
+ /**
+ * Creates the table to manage included and excluded elements.
+ *
+ * @param context the context to locate commonly used objects
+ * @param location the location used to locate source files
+ */
+ ElementsTable(Context context, Map<ToolOption, Object> opts) {
+ this.toolEnv = ToolEnvironment.instance(context);
+ this.syms = Symtab.instance(context);
+ this.names = Names.instance(context);
+ this.fm = toolEnv.fileManager;
+ this.modules = Modules.instance(context);
+ this.opts = opts;
+ this.location = modules.multiModuleMode
+ ? StandardLocation.MODULE_SOURCE_PATH
+ : toolEnv.fileManager.hasLocation(StandardLocation.SOURCE_PATH)
+ ? StandardLocation.SOURCE_PATH
+ : StandardLocation.CLASS_PATH;
+ getEntry("").excluded = false;
+
+ accessFilter = new ModifierFilter(opts);
+ xclasses = (boolean)opts.getOrDefault(ToolOption.XCLASSES, false);
+ expandRequires = (AccessKind)opts.get(ToolOption.EXPAND_REQUIRES);
+ }
+
+ /**
+ * Returns the module documentation level mode.
+ * @return the module documentation level mode
+ */
+ public ModuleMode getModuleMode() {
+ switch(accessFilter.getAccessValue(ElementKind.MODULE)) {
+ case PACKAGE: case PRIVATE:
+ return DocletEnvironment.ModuleMode.ALL;
+ default:
+ return DocletEnvironment.ModuleMode.API;
+ }
+ }
+
+ /**
+ * Returns the selected/included module elements.
+ * A module is fully included,
+ * - is specified on the command line --module
+ * - is derived from the module graph, that is, by expanding the
+ * requires directive, based on --expand-requires
+ *
+ * A module is included if an enclosed package or type is
+ * 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,
+ * - is specified on the command line
+ * - is derived from expanding -subpackages
+ * - can be documented in a fully included module based on --show-packages
+ *
+ * A package is included, if an enclosed package or a type is specified on
+ * the command line.
+ *
+ * @return the included package elements
+ */
+ 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
+ * - is specified on the command line with -sourcepath
+ * - is visible with --show-types filter
+ * A nested type is fully included if
+ * - is visible with --show-types filter
+ * - is enclosed in a fully included type
+ *
+ * @return the included type elements
+ * to be documented
+ */
+ public Set<TypeElement> getIncludedTypeElements() {
+ return includedTypeElements;
+ }
+
+ /**
+ * 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;
+
+ /**
+ * Returns true if the given element is included or selected for
+ * consideration.
+ * This method accumulates elements in the cache as enclosed elements of
+ * fully included elements are tested.
+ * A member (constructor, method, field) is included if
+ * - it is visible in a fully included type (--show-members)
+ *
+ * @param e the element in question
+ *
+ * @see getIncludedModuleElements
+ * @see getIncludedPackageElements
+ * @see getIncludedTypeElements
+ *
+ * @return true if included
+ */
+ public boolean isIncluded(Element e) {
+ if (e == null) {
+ return false;
+ }
+ if (includedVisitor == null) {
+ includedVisitor = new IncludedVisitor();
+ }
+ return includedVisitor.visit(e);
+ }
+
+ /**
+ * Performs the final computation and freezes the collections.
+ * This is a terminal operation, thus no further modifications
+ * are allowed to the specified data sets.
+ *
+ * @throws IOException if an error occurs
+ */
+ void analyze() throws IOException {
+ // compute the specified element, by expanding module dependencies
+ computeSpecifiedModules();
+
+ // compute all specified packages and subpackages
+ computeSpecifiedPackages();
+
+ // compute the specified types
+ computeSpecifiedTypes();
+
+ // compute the packages belonging to all the specified modules
+ Set<PackageElement> expandedModulePackages = computeModulePackages();
+ initializeIncludedSets(expandedModulePackages);
+
+ }
+
+ ElementsTable classTrees(com.sun.tools.javac.util.List<JCCompilationUnit> classTrees) {
+ this.classTreeList = classTrees;
+ return this;
+ }
+
+ @SuppressWarnings("unchecked")
+ ElementsTable scanSpecifiedItems() throws IOException {
+
+ // scan modules specified on the command line
+ List<String> moduleNames = (List<String>) opts.computeIfAbsent(ToolOption.MODULE,
+ s -> Collections.EMPTY_LIST);
+ List<String> mlist = new ArrayList<>();
+ for (String m : moduleNames) {
+ Location moduleLoc = fm.getModuleLocation(location, m);
+ if (moduleLoc == null) {
+ toolEnv.error("main.module_not_found", m);
+ } else {
+ mlist.add(m);
+ ModuleSymbol msym = syms.enterModule(names.fromString(m));
+ specifiedModuleElements.add((ModuleElement) msym);
+ }
+ }
+
+ // scan for modules with qualified packages
+ cmdLinePackages.stream()
+ .filter((mpkg) -> (mpkg.hasModule()))
+ .forEachOrdered((mpkg) -> {
+ mlist.add(mpkg.moduleName);
+ });
+
+ // scan for modules with qualified subpackages
+ ((List<String>)opts.computeIfAbsent(ToolOption.SUBPACKAGES, v -> Collections.EMPTY_LIST))
+ .stream()
+ .map((packageName) -> new ModulePackage(packageName))
+ .forEachOrdered((mpkg) -> {
+ subPackages.add(mpkg);
+ if (mpkg.hasModule()) {
+ mlist.add(mpkg.moduleName);
+ }
+ });
+
+ // all the modules specified on the command line have been scraped
+ // init the module systems
+ modules.addExtraAddModules(mlist.toArray(new String[mlist.size()]));
+ modules.initModules(this.classTreeList);
+
+ return this;
+ }
+
+ /**
+ * Returns the includes table after setting a class names specified on the command line.
+ *
+ * @param classList
+ * @return the include table
+ */
+ ElementsTable setClassArgList(List<String> classList) {
+ classArgList = classList;
+ return this;
+ }
+
+ /**
+ * Returns the includes table after setting the parsed class names.
+ *
+ * @param classesDecList
+ * @return the include table
+ */
+ ElementsTable setClassDeclList(List<JCClassDecl> classesDecList) {
+ this.classDecList = classesDecList;
+ return this;
+ }
+
+ /**
+ * Returns an includes table after setting the specified package
+ * names.
+ * @param packageNames packages on the command line
+ * @return the includes table after setting the specified package
+ * names
+ */
+ ElementsTable packages(Collection<String> packageNames) {
+ packageNames.stream()
+ .map((packageName) -> new ModulePackage(packageName))
+ .forEachOrdered((mpkg) -> cmdLinePackages.add(mpkg));
+ return this;
+ }
+
+ /**
+ * Returns the aggregate set of included packages and specified
+ * sub packages.
+ *
+ * @return the aggregate set of included packages and specified
+ * sub packages
+ */
+ Iterable<ModulePackage> getPackagesToParse() throws IOException {
+ List<ModulePackage> result = new ArrayList<>();
+ result.addAll(cmdLinePackages);
+ result.addAll(subPackages);
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ private void computeSubpackages() throws IOException {
+ ((List<String>) opts.computeIfAbsent(ToolOption.EXCLUDE, v -> Collections.EMPTY_LIST))
+ .stream()
+ .map((packageName) -> new ModulePackage(packageName))
+ .forEachOrdered((mpkg) -> excludePackages.add(mpkg));
+
+ excludePackages.forEach((p) -> {
+ getEntry(p).excluded = true;
+ });
+
+ for (ModulePackage modpkg : subPackages) {
+ Location packageLocn = getLocation(modpkg);
+ for (JavaFileObject fo : fm.list(packageLocn, modpkg.packageName, sourceKinds, true)) {
+ String binaryName = fm.inferBinaryName(packageLocn, fo);
+ String pn = getPackageName(binaryName);
+ String simpleName = getSimpleName(binaryName);
+ Entry e = getEntry(pn);
+ if (!e.isExcluded() && isValidClassName(simpleName)) {
+ ModuleSymbol msym = (modpkg.hasModule())
+ ? syms.getModule(names.fromString(modpkg.moduleName))
+ : findModuleOfPackageName(modpkg.packageName);
+
+ if (msym != null && !msym.isUnnamed()) {
+ syms.enterPackage(msym, names.fromString(pn));
+ ModulePackage npkg = new ModulePackage(msym.toString(), pn);
+ cmdLinePackages.add(npkg);
+ } else {
+ cmdLinePackages.add(e.modpkg);
+ }
+ e.files = (e.files == null
+ ? com.sun.tools.javac.util.List.of(fo)
+ : e.files.prepend(fo));
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the "requires" modules for the target module.
+ * @param mdle the target module element
+ * @param isPublic true gets all the public requires, otherwise
+ * gets all the non-public requires
+ *
+ * @return a set of modules
+ */
+ private Set<ModuleElement> getModuleRequires(ModuleElement mdle, boolean isPublic) {
+ Set<ModuleElement> result = new HashSet<>();
+ for (RequiresDirective rd : ElementFilter.requiresIn(mdle.getDirectives())) {
+ if (isPublic && rd.isPublic()) {
+ result.add(rd.getDependency());
+ }
+ if (!isPublic && !rd.isPublic()) {
+ result.add(rd.getDependency());
+ }
+ }
+ return result;
+ }
+
+ private void computeSpecifiedModules() {
+ if (expandRequires == null) { // no expansion requested
+ specifiedModuleElements = Collections.unmodifiableSet(specifiedModuleElements);
+ return;
+ }
+
+ final boolean expandAll = expandRequires.equals(AccessKind.PRIVATE)
+ || expandRequires.equals(AccessKind.PACKAGE);
+
+ Set<ModuleElement> result = new LinkedHashSet<>();
+ ListBuffer<ModuleElement> queue = new ListBuffer<>();
+
+ // expand each specified module
+ for (ModuleElement mdle : getSpecifiedModuleElements()) {
+ result.add(mdle); // a specified module is included
+ queue.append(mdle);
+ Set<ModuleElement> publicRequires = getModuleRequires(mdle, true);
+ result.addAll(publicRequires);
+ // add all requires public
+ queue.addAll(publicRequires);
+
+ if (expandAll) {
+ // add non-public requires if needed
+ result.addAll(getModuleRequires(mdle, !expandAll));
+ }
+ }
+
+ // compute the transitive closure of all the requires public
+ for (ModuleElement m = queue.poll() ; m != null ; m = queue.poll()) {
+ for (ModuleElement mdle : getModuleRequires(m, true)) {
+ if (!result.contains(mdle)) {
+ result.add(mdle);
+ queue.append(mdle);
+ }
+ }
+ }
+ specifiedModuleElements = Collections.unmodifiableSet(result);
+ }
+
+ private Set<PackageElement> getAllModulePackages(ModuleElement mdle) throws IOException {
+ Set<PackageElement> result = new HashSet<>();
+ ModuleSymbol msym = (ModuleSymbol)mdle;
+ Location msymloc = fm.getModuleLocation(location, msym.name.toString());
+ for (JavaFileObject fo : fm.list(msymloc, "", sourceKinds, true)) {
+ if (fo.getName().endsWith("module-info.java"))
+ continue;
+ String binaryName = fm.inferBinaryName(msymloc, fo);
+ String pn = getPackageName(binaryName);
+ PackageSymbol psym = syms.enterPackage(msym, names.fromString(pn));
+ result.add((PackageElement)psym);
+ }
+ return result;
+ }
+
+ private Set<PackageElement> computeModulePackages() throws IOException {
+ final AccessKind accessValue = accessFilter.getAccessValue(ElementKind.PACKAGE);
+ final boolean documentAllModulePackages = (accessValue == AccessKind.PACKAGE ||
+ accessValue == AccessKind.PRIVATE);
+
+ Set<PackageElement> expandedModulePackages = new LinkedHashSet<>();
+
+ for (ModuleElement mdle : specifiedModuleElements) {
+ // add all exported packages belonging to a specified module
+ if (specifiedModuleElements.contains(mdle)) {
+ List<ExportsDirective> exports = ElementFilter.exportsIn(mdle.getDirectives());
+ for (ExportsDirective export : exports) {
+ expandedModulePackages.add(export.getPackage());
+ }
+ }
+
+ // add all packages specified on the command line
+ // belonging to this module
+ if (!cmdLinePackages.isEmpty()) {
+ for (ModulePackage modpkg : cmdLinePackages) {
+ PackageElement pkg = toolEnv.elements.getPackageElement(mdle,
+ modpkg.packageName);
+ if (pkg != null) {
+ expandedModulePackages.add(pkg);
+ }
+ }
+ }
+
+ if (!documentAllModulePackages) {
+ List<ExportsDirective> exports = ElementFilter.exportsIn(mdle.getDirectives());
+ // check exported packages
+ for (ExportsDirective export : exports) {
+ List<? extends ModuleElement> targetModules = export.getTargetModules();
+ if (targetModules == null) { // no qualified exports, add 'em all
+ expandedModulePackages.add(export.getPackage());
+ } else { // qualified export, add only if target module is being considered
+ for (ModuleElement target : targetModules) {
+ if (specifiedModuleElements.contains(target)) {
+ expandedModulePackages.add(export.getPackage());
+ }
+ }
+ }
+ }
+ } else { // add all exported and module private packages
+ List<PackageElement> packages = ElementFilter.packagesIn(mdle.getEnclosedElements());
+ expandedModulePackages.addAll(packages);
+ expandedModulePackages.addAll(getAllModulePackages(mdle));
+ }
+ }
+ return expandedModulePackages;
+ }
+
+ private void initializeIncludedSets(Set<PackageElement> expandedModulePackages) {
+
+ // process modules
+ Set<ModuleElement> imodules = new LinkedHashSet<>();
+ // add all the expanded modules
+ imodules.addAll(specifiedModuleElements);
+
+ // process packages
+ Set<PackageElement> ipackages = new LinkedHashSet<>();
+ // add all packages belonging to expanded modules
+ ipackages.addAll(expandedModulePackages);
+ // add all specified packages
+ specifiedPackageElements.forEach(pkg -> {
+ ModuleElement mdle = toolEnv.elements.getModuleOf(pkg);
+ imodules.add(mdle);
+ ipackages.add(pkg);
+ });
+
+ // process types
+ Set<TypeElement> iclasses = new LinkedHashSet<>();
+ // add all types enclosed in expanded modules and packages
+ ipackages.forEach((pkg) -> {
+ addAllClasses(iclasses, pkg);
+ });
+ // add all types and its nested types
+ specifiedTypeElements.forEach((klass) -> {
+ ModuleElement mdle = toolEnv.elements.getModuleOf(klass);
+ if (!mdle.isUnnamed())
+ imodules.add(mdle);
+ PackageElement pkg = toolEnv.elements.getPackageOf(klass);
+ if (!pkg.isUnnamed())
+ ipackages.add(pkg);
+ addAllClasses(iclasses, klass, true);
+ });
+
+ // all done, freeze the collections
+ includedModuleElements = Collections.unmodifiableSet(imodules);
+ includedPackageElements = Collections.unmodifiableSet(ipackages);
+ includedTypeElements = Collections.unmodifiableSet(iclasses);
+ }
+
+ /**
+ * Computes the included packages and freezes the specified packages list.
+ */
+ private void computeSpecifiedPackages() throws IOException {
+
+ computeSubpackages();
+
+ Set<PackageElement> packlist = new LinkedHashSet<>();
+ cmdLinePackages.forEach((modpkg) -> {
+ ModuleElement mdle = null;
+ PackageElement pkg;
+ if (modpkg.hasModule()) {
+ mdle = toolEnv.elements.getModuleElement(modpkg.moduleName);
+ pkg = toolEnv.elements.getPackageElement(mdle, modpkg.packageName);
+ } else {
+ pkg = toolEnv.elements.getPackageElement(modpkg.toString());
+ }
+
+ if (pkg != null) {
+ packlist.add(pkg);
+ } else {
+ toolEnv.warning("main.package_not_found", modpkg.toString());
+ }
+ });
+ specifiedPackageElements = Collections.unmodifiableSet(packlist);
+ }
+
+ /**
+ * Adds all classes as well as inner classes, to the specified
+ * list.
+ */
+ private void computeSpecifiedTypes() {
+ Set<TypeElement> classes = new LinkedHashSet<>();
+ classDecList.stream().filter((def) -> (shouldDocument(def.sym))).forEach((def) -> {
+ TypeElement te = (TypeElement) def.sym;
+ if (te != null) {
+ addAllClasses(classes, te, true);
+ }
+ });
+ classArgList.forEach((className) -> {
+ TypeElement te = toolEnv.loadClass(className);
+ if (te == null) {
+ toolEnv.error("javadoc.class_not_found", className);
+ } else {
+ addAllClasses(classes, te, true);
+ }
+ });
+ specifiedTypeElements = Collections.unmodifiableSet(classes);
+ }
+
+ private void addFilesForParser(Collection<JavaFileObject> result,
+ Collection<ModulePackage> collection, boolean recurse) throws IOException {
+ for (ModulePackage modpkg : collection) {
+ toolEnv.notice("main.Loading_source_files_for_package", modpkg.toString());
+ List<JavaFileObject> files = getFiles(modpkg, recurse);
+ if (files.isEmpty()) {
+ toolEnv.error("main.no_source_files_for_package", modpkg.toString());
+ } else {
+ result.addAll(files);
+ }
+ }
+ }
+
+ /**
+ * Returns an aggregated list of java file objects from the items
+ * specified on the command line. The packages specified should not
+ * recurse, however sub-packages should recurse into the sub directories.
+ * @return a list of java file objects
+ * @throws IOException if an error occurs
+ */
+ List<JavaFileObject> getFilesToParse() throws IOException {
+ List<JavaFileObject> result = new ArrayList<>();
+ addFilesForParser(result, cmdLinePackages, false);
+ addFilesForParser(result, subPackages, true);
+ return result;
+ }
+
+ /**
+ * Returns the set of source files for a package.
+ *
+ * @param packageName the specified package
+ * @return the set of file objects for the specified package
+ * @throws IOException if an error occurs while accessing the files
+ */
+ private List<JavaFileObject> getFiles(ModulePackage modpkg, boolean recurse) throws IOException {
+ Entry e = getEntry(modpkg);
+ // The files may have been found as a side effect of searching for subpackages
+ if (e.files != null) {
+ return e.files;
+ }
+
+ ListBuffer<JavaFileObject> lb = new ListBuffer<>();
+ Location packageLocn = getLocation(modpkg);
+ if (packageLocn == null) {
+ return Collections.emptyList();
+ }
+ String pname = modpkg.packageName;
+ for (JavaFileObject fo : fm.list(packageLocn, pname, sourceKinds, recurse)) {
+ String binaryName = fm.inferBinaryName(packageLocn, fo);
+ String simpleName = getSimpleName(binaryName);
+ if (isValidClassName(simpleName)) {
+ lb.append(fo);
+ }
+ }
+
+ return lb.toList();
+ }
+
+ private ModuleSymbol findModuleOfPackageName(String packageName) {
+ Name pack = names.fromString(packageName);
+ for (ModuleSymbol msym : modules.allModules()) {
+ PackageSymbol p = syms.getPackage(msym, pack);
+ if (p != null && !p.members().isEmpty()) {
+ return msym;
+ }
+ }
+ return null;
+ }
+
+ private Location getLocation(ModulePackage modpkg) throws IOException {
+ if (location != StandardLocation.MODULE_SOURCE_PATH) {
+ return location;
+ }
+
+ if (modpkg.hasModule()) {
+ return fm.getModuleLocation(location, modpkg.moduleName);
+ }
+ // TODO: handle invalid results better.
+ ModuleSymbol msym = findModuleOfPackageName(modpkg.packageName);
+ if (msym == null) {
+ return null;
+ }
+ return fm.getModuleLocation(location, msym.name.toString());
+ }
+
+ private Entry getEntry(String name) {
+ return getEntry(new ModulePackage(name));
+ }
+
+ private Entry getEntry(ModulePackage modpkg) {
+ Entry e = entries.get(modpkg.packageName);
+ if (e == null) {
+ entries.put(modpkg.packageName, e = new Entry(modpkg));
+ }
+ return e;
+ }
+
+ private String getPackageName(String name) {
+ int lastDot = name.lastIndexOf(".");
+ return (lastDot == -1 ? "" : name.substring(0, lastDot));
+ }
+
+ private String getSimpleName(String name) {
+ int lastDot = name.lastIndexOf(".");
+ return (lastDot == -1 ? name : name.substring(lastDot + 1));
+ }
+
+ /**
+ * Adds all inner classes of this class, and their inner classes recursively, to the list
+ */
+ private void addAllClasses(Collection<TypeElement> list, TypeElement typeElement, boolean filtered) {
+ ClassSymbol klass = (ClassSymbol)typeElement;
+ try {
+ // eliminate needless checking, do this first.
+ if (list.contains(klass)) return;
+ if (toolEnv.isSynthetic(klass)) return;
+ // ignore classes with invalid Java class names
+ if (!JavadocTool.isValidClassName(klass.name.toString())) return;
+ if (filtered && !shouldDocument(klass)) return;
+ list.add(klass);
+ for (Symbol sym : klass.members().getSymbols(NON_RECURSIVE)) {
+ if (sym != null && sym.kind == Kind.TYP) {
+ ClassSymbol s = (ClassSymbol)sym;
+ if (!toolEnv.isSynthetic(s)) {
+ addAllClasses(list, s, filtered);
+ }
+ }
+ }
+ } catch (CompletionFailure e) {
+ // quietly ignore completion failures
+ }
+ }
+
+ /**
+ * Returns a list of all classes contained in this package, including
+ * member classes of those classes, and their member classes, etc.
+ */
+ private void addAllClasses(Collection<TypeElement> list, PackageElement pkg) {
+ boolean filtered = true;
+ PackageSymbol sym = (PackageSymbol)pkg;
+ for (Symbol isym : sym.members().getSymbols(NON_RECURSIVE)) {
+ if (isym != null) {
+ ClassSymbol s = (ClassSymbol)isym;
+ if (!toolEnv.isSynthetic(sym)) {
+ addAllClasses(list, s, filtered);
+ }
+ }
+ }
+ }
+
+ SimpleElementVisitor9<Boolean, Void> shouldDocumentVisitor = null;
+ /**
+ * Returns whether an element ought to be documented.
+ * @param e the element in question
+ * @return true if the element should be documented
+ */
+ public boolean shouldDocument(Element e) {
+ if (shouldDocumentVisitor == null) {
+ shouldDocumentVisitor = new SimpleElementVisitor9<Boolean, Void>() {
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitType(TypeElement e, Void p) {
+ return shouldDocument((ClassSymbol) e);
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitVariable(VariableElement e, Void p) {
+ return shouldDocument((VarSymbol) e);
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitExecutable(ExecutableElement e, Void p) {
+ return shouldDocument((MethodSymbol) e);
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitPackage(PackageElement e, Void p) {
+ return accessFilter.checkModifier(e);
+ }
+ };
+ }
+ return shouldDocumentVisitor.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> {
+
+ final private Set<Element> includedCache;
+
+ public IncludedVisitor() {
+ includedCache = new LinkedHashSet<>();
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitModule(ModuleElement e, Void p) {
+ // deduced by specified and/or requires expansion
+ return includedModuleElements.contains(e);
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitPackage(PackageElement e, Void p) {
+ // deduced by specified or downward expansions
+ return includedPackageElements.contains(e);
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitType(TypeElement e, Void p) {
+ if (includedTypeElements.contains(e)) {
+ return true;
+ }
+ if (shouldDocument(e)) {
+ // Class is nameable from top-level and
+ // the class and all enclosing classes
+ // pass the modifier filter.
+ PackageElement pkg = toolEnv.elements.getPackageOf(e);
+ if (specifiedPackageElements.contains(pkg)) {
+ return true;
+ }
+ Element enclosing = e.getEnclosingElement();
+ if (enclosing != null) {
+ switch(enclosing.getKind()) {
+ case PACKAGE:
+ return specifiedPackageElements.contains((PackageElement)enclosing);
+ case CLASS: case INTERFACE: case ENUM: case ANNOTATION_TYPE:
+ return visit((TypeElement) enclosing);
+ default:
+ throw new AssertionError("unknown element: " + enclosing);
+ }
+ }
+ }
+ return false;
+ }
+
+ // members
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean defaultAction(Element e, Void p) {
+ if (includedCache.contains(e))
+ return true;
+ if (visit(e.getEnclosingElement()) && shouldDocument(e)) {
+ switch(e.getKind()) {
+ case ANNOTATION_TYPE: case CLASS: case ENUM: case INTERFACE:
+ case MODULE: case OTHER: case PACKAGE:
+ throw new AssertionError("invalid element for this operation: " + e);
+ default:
+ // the only allowed kinds in the cache are "members"
+ includedCache.add(e);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public Boolean visitUnknown(Element e, Void p) {
+ throw new AssertionError("unknown element: " + e);
+ }
+
+ }
+
+ class Entry {
+ final ModulePackage modpkg;
+ Boolean excluded = false;
+ com.sun.tools.javac.util.List<JavaFileObject> files;
+
+ Entry(ModulePackage modpkg) {
+ this.modpkg = modpkg;
+ }
+
+ Entry(String name) {
+ modpkg = new ModulePackage(name);
+ }
+
+ boolean isExcluded() {
+ return excluded;
+ }
+
+ @Override
+ public String toString() {
+ return "Entry{" + "modpkg=" + modpkg + ", excluded=" + excluded + ", files=" + files + '}';
+ }
+ }
+
+ /**
+ * A container class to retrieve the module and package pair
+ * from a parsed qualified package name.
+ */
+ static class ModulePackage {
+
+ public final String moduleName;
+ public final String packageName;
+
+ ModulePackage(String modulename, String packagename) {
+ this.moduleName = modulename;
+ this.packageName = packagename;
+ }
+
+ ModulePackage(ModuleElement msym, String packagename) {
+ this.moduleName = msym.toString();
+ this.packageName = packagename;
+ }
+
+ ModulePackage(String name) {
+ String a[] = name.split("/");
+ if (a.length == 2) {
+ this.moduleName = a[0];
+ this.packageName = a[1];
+ } else {
+ moduleName = null;
+ packageName = name;
+ }
+ }
+
+ boolean hasModule() {
+ return this.moduleName != null;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof ModulePackage) {
+ ModulePackage that = (ModulePackage)obj;
+ return this.toString().equals(that.toString());
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return toString().hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return moduleName == null ? packageName : moduleName + "/" + packageName;
+ }
+ }
+
+ /**
+ * A class which filters the access flags on classes, fields, methods, etc.
+ *
+ * @see javax.lang.model.element.Modifier
+ */
+
+ static class ModifierFilter {
+ /**
+ * The allowed ElementKind that can be stored.
+ */
+ static final EnumSet<ElementKind> ALLOWED_KINDS = EnumSet.of(ElementKind.METHOD,
+ ElementKind.CLASS,
+ ElementKind.PACKAGE,
+ ElementKind.MODULE);
+
+ // all possible accesss levels allowed for each element
+ private final EnumMap<ElementKind, EnumSet<AccessKind>> filterMap =
+ new EnumMap<>(ElementKind.class);
+
+ // the specified access level for each element
+ private final EnumMap<ElementKind, AccessKind> accessMap =
+ new EnumMap<>(ElementKind.class);
+
+ /**
+ * Constructor - Specify a filter.
+ *
+ * @param accessSet an Access filter.
+ */
+ ModifierFilter(Map<ToolOption, Object> opts) {
+
+ AccessKind accessValue = null;
+ for (ElementKind kind : ALLOWED_KINDS) {
+ switch (kind) {
+ case METHOD:
+ accessValue = (AccessKind)opts.get(ToolOption.SHOW_MEMBERS);
+ break;
+ case CLASS:
+ accessValue = (AccessKind)opts.get(ToolOption.SHOW_TYPES);
+ break;
+ case PACKAGE:
+ accessValue = (AccessKind)opts.get(ToolOption.SHOW_PACKAGES);
+ break;
+ case MODULE:
+ accessValue = (AccessKind)opts.get(ToolOption.SHOW_MODULE_CONTENTS);
+ break;
+ default:
+ throw new AssertionError("unknown element: " + kind);
+
+ }
+ accessMap.put(kind, accessValue);
+ filterMap.put(kind, getFilterSet(accessValue));
+ }
+ }
+
+ static EnumSet<AccessKind> getFilterSet(AccessKind acccessValue) {
+ switch (acccessValue) {
+ case PUBLIC:
+ return EnumSet.of(AccessKind.PUBLIC);
+ case PROTECTED:
+ default:
+ return EnumSet.of(AccessKind.PUBLIC, AccessKind.PROTECTED);
+ case PACKAGE:
+ return EnumSet.of(AccessKind.PUBLIC, AccessKind.PROTECTED, AccessKind.PACKAGE);
+ case PRIVATE:
+ return EnumSet.allOf(AccessKind.class);
+ }
+ }
+
+ public AccessKind getAccessValue(ElementKind kind) {
+ if (!ALLOWED_KINDS.contains(kind)) {
+ throw new IllegalArgumentException("not allowed: " + kind);
+ }
+ return accessMap.getOrDefault(kind, AccessKind.PROTECTED);
+ }
+
+ /**
+ * Returns true if access is allowed.
+ *
+ * @param e the element in question
+ * @return whether the modifiers pass this filter
+ */
+ public boolean checkModifier(Element e) {
+ Set<Modifier> modifiers = e.getModifiers();
+ AccessKind fflag = AccessKind.PACKAGE;
+ if (modifiers.contains(Modifier.PUBLIC)) {
+ fflag = AccessKind.PUBLIC;
+ } else if (modifiers.contains(Modifier.PROTECTED)) {
+ fflag = AccessKind.PROTECTED;
+ } else if (modifiers.contains(Modifier.PRIVATE)) {
+ fflag = AccessKind.PRIVATE;
+ }
+ EnumSet<AccessKind> filterSet = filterMap.get(getAllowedKind(e.getKind()));
+ return filterSet.contains(fflag);
+ }
+
+ // convert a requested element kind to an allowed access kind
+ private ElementKind getAllowedKind(ElementKind kind) {
+ switch (kind) {
+ case CLASS: case METHOD: case MODULE: case PACKAGE:
+ return kind;
+ case ANNOTATION_TYPE: case ENUM: case INTERFACE:
+ return ElementKind.CLASS;
+ case CONSTRUCTOR: case ENUM_CONSTANT: case EXCEPTION_PARAMETER:
+ case FIELD: case INSTANCE_INIT: case LOCAL_VARIABLE: case PARAMETER:
+ case RESOURCE_VARIABLE: case STATIC_INIT: case TYPE_PARAMETER:
+ return ElementKind.METHOD;
+ default:
+ throw new AssertionError("unsupported kind: " + kind);
+ }
+ }
+ } // end ModifierFilter
+}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java Thu Aug 18 05:48:35 2016 -0700
@@ -29,27 +29,18 @@
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
import java.util.HashSet;
-import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
-import javax.tools.StandardLocation;
import com.sun.tools.javac.code.ClassFinder;
import com.sun.tools.javac.code.Symbol.Completer;
import com.sun.tools.javac.code.Symbol.CompletionFailure;
-import com.sun.tools.javac.code.Symbol.ModuleSymbol;
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.comp.Enter;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
@@ -57,11 +48,9 @@
import com.sun.tools.javac.util.Abort;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.ListBuffer;
-import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Position;
import jdk.javadoc.doclet.DocletEnvironment;
-
/**
* This class could be the main entry point for Javadoc when Javadoc is used as a
* component in a larger software system. It provides operations to
@@ -131,44 +120,41 @@
}
}
- public DocletEnvironment getEnvironment(String encoding,
- String showAccess,
- String overviewpath,
- List<String> args,
- Iterable<? extends JavaFileObject> fileObjects,
- List<String> subPackages,
- List<String> excludedPackages,
- boolean docClasses,
- boolean quiet) throws IOException {
+ public DocletEnvironment getEnvironment(Map<ToolOption, Object> jdtoolOpts,
+ List<String> javaNames,
+ Iterable<? extends JavaFileObject> fileObjects) throws IOException {
toolEnv = ToolEnvironment.instance(context);
- toolEnv.intialize(encoding, showAccess, overviewpath, args, fileObjects,
- subPackages, excludedPackages, docClasses, quiet);
-
- javadocFinder.sourceCompleter = docClasses ? Completer.NULL_COMPLETER : sourceCompleter;
+ toolEnv.initialize(jdtoolOpts);
+ ElementsTable etable = new ElementsTable(context, jdtoolOpts);
+ javadocFinder.sourceCompleter = etable.xclasses
+ ? Completer.NULL_COMPLETER
+ : sourceCompleter;
- if (docClasses) {
- // If -Xclasses is set, the args should be a series of class names
- for (String arg: args) {
+ if (etable.xclasses) {
+ // If -Xclasses is set, the args should be a list of class names
+ for (String arg: javaNames) {
if (!isValidPackageName(arg)) // checks
- toolEnv.error(null, "main.illegal_class_name", arg);
+ toolEnv.error("main.illegal_class_name", arg);
}
if (messager.nerrors() != 0) {
return null;
}
- return new DocEnvImpl(toolEnv, args);
+ etable.setClassArgList(javaNames);
+ // prepare, force the data structures to be analyzed
+ etable.analyze();
+ return new DocEnvImpl(toolEnv, etable);
}
ListBuffer<JCCompilationUnit> classTrees = new ListBuffer<>();
- Set<String> includedPackages = new LinkedHashSet<>();
try {
-
StandardJavaFileManager fm = toolEnv.fileManager instanceof StandardJavaFileManager
- ? (StandardJavaFileManager) toolEnv.fileManager : null;
+ ? (StandardJavaFileManager) toolEnv.fileManager
+ : null;
Set<String> packageNames = new LinkedHashSet<>();
// Normally, the args should be a series of package names or file names.
// Parse the files and collect the package names.
- for (String arg: args) {
+ for (String arg: javaNames) {
if (fm != null && arg.endsWith(".java") && new File(arg).exists()) {
if (new File(arg).getName().equals("module-info.java")) {
toolEnv.warning("main.file_ignored", arg);
@@ -181,37 +167,22 @@
if (fm == null)
throw new IllegalArgumentException();
else
- toolEnv.error(null, "main.file_not_found", arg);
+ toolEnv.error("main.file_not_found", arg);
} else {
- toolEnv.error(null, "main.illegal_package_name", arg);
+ toolEnv.error("main.illegal_package_name", arg);
}
}
// Parse file objects provide via the DocumentationTool API
parse(fileObjects, classTrees, true);
- modules.initModules(classTrees.toList());
-
- // Build up the complete list of any packages to be documented
- Location location = modules.multiModuleMode ? StandardLocation.MODULE_SOURCE_PATH
- : toolEnv.fileManager.hasLocation(StandardLocation.SOURCE_PATH) ? StandardLocation.SOURCE_PATH
- : StandardLocation.CLASS_PATH;
-
- PackageTable t = new PackageTable(toolEnv.fileManager, location)
- .packages(packageNames)
- .subpackages(subPackages, excludedPackages);
+ etable.packages(packageNames)
+ .classTrees(classTrees.toList())
+ .scanSpecifiedItems();
- includedPackages = t.getIncludedPackages();
-
- // Parse the files in the packages to be documented
+ // Parse the files in the packages and subpackages to be documented
ListBuffer<JCCompilationUnit> packageTrees = new ListBuffer<>();
- for (String packageName: includedPackages) {
- List<JavaFileObject> files = t.getFiles(packageName);
- toolEnv.notice("main.Loading_source_files_for_package", packageName);
- if (files.isEmpty())
- toolEnv.warning("main.no_source_files_for_package", packageName);
- parse(files, packageTrees, false);
- }
+ parse(etable.getFilesToParse(), packageTrees, false);
modules.enter(packageTrees.toList(), null);
if (messager.nerrors() != 0) {
@@ -220,24 +191,40 @@
// Enter symbols for all files
toolEnv.notice("main.Building_tree");
- javadocEnter.main(classTrees.toList().appendList(packageTrees.toList()));
+ javadocEnter.main(classTrees.toList().appendList(packageTrees));
+ etable.setClassDeclList(listClasses(classTrees.toList()));
enterDone = true;
+ etable.analyze();
+ } catch (CompletionFailure cf) {
+ toolEnv.printError(cf.getMessage());
} catch (Abort ex) {}
if (messager.nerrors() != 0)
return null;
- toolEnv.docEnv = new DocEnvImpl(toolEnv, listClasses(classTrees.toList()),
- new ArrayList<>(includedPackages));
+
+ toolEnv.docEnv = new DocEnvImpl(toolEnv, etable);
return toolEnv.docEnv;
}
/** Is the given string a valid package name? */
boolean isValidPackageName(String s) {
- int index;
- while ((index = s.indexOf('.')) != -1) {
- if (!isValidClassName(s.substring(0, index))) return false;
- s = s.substring(index+1);
+ if (s.contains("/")) {
+ String[] a = s.split("/");
+ if (a.length == 2) {
+ return isValidPackageName0(a[0]) && isValidPackageName0(a[1]);
+ }
+ return false;
+ }
+ return isValidPackageName0(s);
+ }
+
+ private boolean isValidPackageName0(String s) {
+ for (int index = s.indexOf('.') ; index != -1; index = s.indexOf('.')) {
+ if (!isValidClassName(s.substring(0, index))) {
+ return false;
+ }
+ s = s.substring(index + 1);
}
return isValidClassName(s);
}
@@ -253,8 +240,7 @@
}
}
- /** Are surrogates supported?
- */
+ /** Are surrogates supported? */
final static boolean surrogatesSupported = surrogatesSupported();
private static boolean surrogatesSupported() {
try {
@@ -279,7 +265,7 @@
int cp = s.codePointAt(0);
if (!Character.isJavaIdentifierStart(cp))
return false;
- for (int j=Character.charCount(cp); j<s.length(); j+=Character.charCount(cp)) {
+ for (int j = Character.charCount(cp); j < s.length(); j += Character.charCount(cp)) {
cp = s.codePointAt(j);
if (!Character.isJavaIdentifierPart(cp))
return false;
@@ -287,7 +273,7 @@
} else {
if (!Character.isJavaIdentifierStart(s.charAt(0)))
return false;
- for (int j=1; j<s.length(); j++)
+ for (int j = 1; j < s.length(); j++)
if (!Character.isJavaIdentifierPart(s.charAt(j)))
return false;
}
@@ -307,141 +293,4 @@
}
return result;
}
-
- /**
- * A table to manage included and excluded packages.
- */
- class PackageTable {
- private final Map<String, Entry> entries = new LinkedHashMap<>();
- private final Set<String> includedPackages = new LinkedHashSet<>();
- private final JavaFileManager fm;
- private final Location location;
- private final Set<JavaFileObject.Kind> sourceKinds = EnumSet.of(JavaFileObject.Kind.SOURCE);
-
- /**
- * Creates a table to manage included and excluded packages.
- * @param fm The file manager used to locate source files
- * @param locn the location used to locate source files
- */
- PackageTable(JavaFileManager fm, Location locn) {
- this.fm = fm;
- this.location = locn;
- getEntry("").excluded = false;
- }
-
- PackageTable packages(Collection<String> packageNames) {
- includedPackages.addAll(packageNames);
- return this;
- }
-
- PackageTable subpackages(Collection<String> packageNames, Collection<String> excludePackageNames)
- throws IOException {
- for (String p: excludePackageNames) {
- getEntry(p).excluded = true;
- }
-
- for (String packageName: packageNames) {
- for (JavaFileObject fo: fm.list(location, packageName, sourceKinds, true)) {
- String binaryName = fm.inferBinaryName(location, fo);
- String pn = getPackageName(binaryName);
- String simpleName = getSimpleName(binaryName);
- Entry e = getEntry(pn);
- if (!e.isExcluded() && isValidClassName(simpleName)) {
- includedPackages.add(pn);
- e.files = (e.files == null
- ? com.sun.tools.javac.util.List.of(fo)
- : e.files.prepend(fo));
- }
- }
- }
- return this;
- }
-
- /**
- * Returns the aggregate set of included packages.
- * @return the aggregate set of included packages
- */
- Set<String> getIncludedPackages() {
- return includedPackages;
- }
-
- /**
- * Returns the set of source files for a package.
- * @param packageName the specified package
- * @return the set of file objects for the specified package
- * @throws IOException if an error occurs while accessing the files
- */
- List<JavaFileObject> getFiles(String packageName) throws IOException {
- Entry e = getEntry(packageName);
- // The files may have been found as a side effect of searching for subpackages
- if (e.files != null)
- return e.files;
-
- ListBuffer<JavaFileObject> lb = new ListBuffer<>();
- Location packageLocn = getLocation(packageName);
- if (packageLocn == null)
- return Collections.emptyList();
- for (JavaFileObject fo: fm.list(packageLocn, packageName, sourceKinds, false)) {
- String binaryName = fm.inferBinaryName(packageLocn, fo);
- String simpleName = getSimpleName(binaryName);
- if (isValidClassName(simpleName)) {
- lb.append(fo);
- }
- }
-
- return lb.toList();
- }
-
- private Location getLocation(String packageName) throws IOException {
- if (location == StandardLocation.MODULE_SOURCE_PATH) {
- // TODO: handle invalid results better.
- Name pack = names.fromString(packageName);
-
- for (ModuleSymbol msym : modules.allModules()) {
- PackageSymbol p = syms.getPackage(msym, pack);
- if (p != null && !p.members().isEmpty()) {
- return fm.getModuleLocation(location, msym.name.toString());
- }
- }
-
- return null;
- } else {
- return location;
- }
- }
-
- private Entry getEntry(String name) {
- Entry e = entries.get(name);
- if (e == null)
- entries.put(name, e = new Entry(name));
- return e;
- }
-
- private String getPackageName(String name) {
- int lastDot = name.lastIndexOf(".");
- return (lastDot == -1 ? "" : name.substring(0, lastDot));
- }
-
- private String getSimpleName(String name) {
- int lastDot = name.lastIndexOf(".");
- return (lastDot == -1 ? name : name.substring(lastDot + 1));
- }
-
- class Entry {
- final String name;
- Boolean excluded;
- com.sun.tools.javac.util.List<JavaFileObject> files;
-
- Entry(String name) {
- this.name = name;
- }
-
- boolean isExcluded() {
- if (excluded == null)
- excluded = getEntry(getPackageName(name)).isExcluded();
- return excluded;
- }
- }
- }
-
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java Thu Aug 18 05:48:35 2016 -0700
@@ -29,7 +29,6 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
-import java.lang.reflect.Method;
import java.nio.file.Path;
import java.text.BreakIterator;
import java.util.ArrayList;
@@ -41,8 +40,6 @@
import java.util.Objects;
import java.util.Set;
-import static javax.tools.DocumentationTool.Location.*;
-
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
@@ -65,6 +62,8 @@
import jdk.javadoc.doclet.Doclet.Option;
import jdk.javadoc.doclet.DocletEnvironment;
+import static javax.tools.DocumentationTool.Location.*;
+
import static com.sun.tools.javac.main.Option.*;
/**
@@ -92,9 +91,6 @@
private static final String ProgramName = "javadoc";
- // meaning we allow all visibility of PROTECTED and PUBLIC
- private static final String defaultModifier = "protected";
-
private Messager messager;
private final String docletName;
@@ -337,6 +333,7 @@
/**
* Main program - internal
*/
+ @SuppressWarnings("unchecked")
private boolean parseAndExecute(List<String> argList,
Iterable<? extends JavaFileObject> fileObjects) throws IOException {
long tm = System.currentTimeMillis();
@@ -390,28 +387,25 @@
}
compOpts.notifyListeners();
+ List<String> modules = (List<String>) jdtoolOpts.computeIfAbsent(ToolOption.MODULE,
+ s -> Collections.EMPTY_LIST);
- if (javaNames.isEmpty() && subPackages.isEmpty() && isEmpty(fileObjects)) {
- usageError("main.No_packages_or_classes_specified");
+ if (modules.isEmpty()) {
+ List<String> subpkgs = (List<String>) jdtoolOpts.computeIfAbsent(ToolOption.SUBPACKAGES,
+ s -> Collections.EMPTY_LIST);
+ if (subpkgs.isEmpty()) {
+ if (javaNames.isEmpty() && isEmpty(fileObjects)) {
+ usageError("main.No_modules_packages_or_classes_specified");
+ }
+ }
}
JavadocTool comp = JavadocTool.make0(context);
if (comp == null) return false;
- if (showAccess == null) {
- setFilter(defaultModifier);
- }
-
- DocletEnvironment root = comp.getEnvironment(
- encoding,
- showAccess,
- overviewpath,
+ DocletEnvironment docEnv = comp.getEnvironment(jdtoolOpts,
javaNames,
- fileObjects,
- subPackages,
- excludedPackages,
- docClasses,
- quiet);
+ fileObjects);
// release resources
comp = null;
@@ -421,8 +415,8 @@
trees.setBreakIterator(BreakIterator.getSentenceInstance(locale));
}
// pass off control to the doclet
- boolean ok = root != null;
- if (ok) ok = doclet.run(root);
+ boolean ok = docEnv != null;
+ if (ok) ok = doclet.run(docEnv);
// We're done.
if (compOpts.get("-verbose") != null) {
@@ -470,11 +464,11 @@
for (int i = 0 ; i < argv.size() ; i++) {
String arg = argv.get(i);
if (arg.equals(ToolOption.LOCALE.opt)) {
- oneArg(argv, i++);
+ checkOneArg(argv, i++);
String lname = argv.get(i);
locale = getLocale(lname);
} else if (arg.equals(ToolOption.DOCLET.opt)) {
- oneArg(argv, i++);
+ checkOneArg(argv, i++);
if (userDocletName != null) {
usageError("main.more_than_one_doclet_specified_0_and_1",
userDocletName, argv.get(i));
@@ -485,7 +479,7 @@
}
userDocletName = argv.get(i);
} else if (arg.equals(ToolOption.DOCLETPATH.opt)) {
- oneArg(argv, i++);
+ checkOneArg(argv, i++);
if (userDocletPath == null) {
userDocletPath = argv.get(i);
} else {
@@ -605,12 +599,11 @@
handleDocletOptions(i, args, true);
if (o.hasArg) {
- oneArg(args, i++);
+ checkOneArg(args, i++);
o.process(this, args.get(i));
} else if (o.hasSuffix) {
o.process(this, arg);
} else {
- setOption(arg);
o.process(this);
}
} else if (arg.startsWith("-XD")) {
@@ -633,13 +626,11 @@
}
/**
- * Set one arg option.
+ * Check the one arg option.
* Error and exit if one argument is not provided.
*/
- private void oneArg(List<String> args, int index) {
- if ((index + 1) < args.size()) {
- setOption(args.get(index), args.get(index+1));
- } else {
+ private void checkOneArg(List<String> args, int index) {
+ if ((index + 1) >= args.size() || args.get(index + 1).startsWith("-d")) {
usageError("main.requires_argument", args.get(index));
}
}
@@ -659,32 +650,6 @@
}
/**
- * indicate an option with no arguments was given.
- */
- private void setOption(String opt) {
- String[] option = { opt };
- options.add(Arrays.asList(option));
- }
-
- /**
- * indicate an option with one argument was given.
- */
- private void setOption(String opt, String argument) {
- String[] option = { opt, argument };
- options.add(Arrays.asList(option));
- }
-
- /**
- * indicate an option with the specified list of arguments was given.
- */
- private void setOption(String opt, List<String> arguments) {
- List<String> args = new ArrayList<>(arguments.size() + 1);
- args.add(opt);
- args.addAll(arguments);
- options.add(args);
- }
-
- /**
* Get the locale if specified on the command line
* else return null and if locale option is not used
* then return default locale.
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolEnvironment.java Thu Aug 18 05:48:35 2016 -0700
@@ -26,16 +26,12 @@
package jdk.javadoc.internal.tool;
-import java.lang.reflect.Modifier;
import java.util.*;
import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
import javax.lang.model.util.Elements;
-import javax.lang.model.util.SimpleElementVisitor9;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
@@ -44,15 +40,11 @@
import com.sun.tools.javac.api.JavacTrees;
import com.sun.tools.javac.code.ClassFinder;
import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.code.Kinds.Kind;
import com.sun.tools.javac.code.Source;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.CompletionFailure;
-import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
-import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Check;
@@ -67,13 +59,9 @@
import com.sun.tools.javac.tree.JCTree.JCPackageDecl;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Convert;
-import com.sun.tools.javac.util.DefinedBy;
-import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names;
-import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
-
/**
* Holds the environment for a run of javadoc.
* Holds only the information needed throughout the
@@ -113,14 +101,8 @@
/** The name table. */
private Names names;
- /** The encoding name. */
- private String encoding;
-
final Symbol externalizableSym;
- /** Access filter (public, protected, ...). */
- protected ModifierFilter filter;
-
/**
* True if we do not want to print any notifications at all.
*/
@@ -181,20 +163,8 @@
elementToTreePath = new HashMap<>();
}
- public void intialize(String encoding,
- String showAccess,
- String overviewpath,
- List<String> javaNames,
- Iterable<? extends JavaFileObject> fileObjects,
- List<String> subPackages,
- List<String> excludedPackages,
- boolean docClasses,
- boolean quiet) {
- this.filter = ModifierFilter.getModifierFilter(showAccess);
- this.quiet = quiet;
-
- this.setEncoding(encoding);
- this.docClasses = docClasses;
+ public void initialize(Map<ToolOption, Object> toolOpts) {
+ this.quiet = (boolean)toolOpts.getOrDefault(ToolOption.QUIET, false);
}
/**
@@ -212,54 +182,8 @@
}
}
- private boolean isSynthetic(long flags) {
- return (flags & Flags.SYNTHETIC) != 0;
- }
-
- private boolean isSynthetic(Symbol sym) {
- return isSynthetic(sym.flags_field);
- }
-
- SimpleElementVisitor9<Boolean, Void> shouldDocumentVisitor = null;
- public boolean shouldDocument(Element e) {
- if (shouldDocumentVisitor == null) {
- shouldDocumentVisitor = new SimpleElementVisitor9<Boolean, Void>() {
-
- @Override @DefinedBy(Api.LANGUAGE_MODEL)
- public Boolean visitType(TypeElement e, Void p) {
- return shouldDocument((ClassSymbol)e);
- }
-
- @Override @DefinedBy(Api.LANGUAGE_MODEL)
- public Boolean visitVariable(VariableElement e, Void p) {
- return shouldDocument((VarSymbol)e);
- }
-
- @Override @DefinedBy(Api.LANGUAGE_MODEL)
- public Boolean visitExecutable(ExecutableElement e, Void p) {
- return shouldDocument((MethodSymbol)e);
- }
- };
- }
- return shouldDocumentVisitor.visit(e);
- }
-
- /** Check whether this member should be documented. */
- public boolean shouldDocument(VarSymbol sym) {
- long mod = sym.flags();
- if (isSynthetic(mod)) {
- return false;
- }
- return filter.checkModifier(translateModifiers(mod));
- }
-
- /** Check whether this member should be documented. */
- public boolean shouldDocument(MethodSymbol sym) {
- long mod = sym.flags();
- if (isSynthetic(mod)) {
- return false;
- }
- return filter.checkModifier(translateModifiers(mod));
+ boolean isSynthetic(Symbol sym) {
+ return (sym.flags() & Flags.SYNTHETIC) != 0;
}
void setElementToTreePath(Element e, TreePath tree) {
@@ -268,43 +192,16 @@
elementToTreePath.put(e, tree);
}
- private boolean hasLeaf(ClassSymbol sym) {
+ /**
+ * Returns true if the symbol has a tree path associated with it.
+ * Primarily used to disambiguate a symbol associated with a source
+ * file versus a class file.
+ * @param sym the symbol to be checked
+ * @return true if the symbol has a tree path
+ */
+ boolean hasPath(ClassSymbol sym) {
TreePath path = elementToTreePath.get(sym);
- if (path == null)
- return false;
- return path.getLeaf() != null;
- }
-
- /** check whether this class should be documented. */
- public boolean shouldDocument(ClassSymbol sym) {
- return
- !isSynthetic(sym.flags_field) && // no synthetics
- (docClasses || hasLeaf(sym)) &&
- isVisible(sym);
- }
-
- //### Comment below is inaccurate wrt modifier filter testing
- /**
- * Check the visibility if this is an nested class.
- * if this is not a nested class, return true.
- * if this is an static visible nested class,
- * return true.
- * if this is an visible nested class
- * if the outer class is visible return true.
- * else return false.
- * IMPORTANT: This also allows, static nested classes
- * to be defined inside an nested class, which is not
- * allowed by the compiler. So such an test case will
- * not reach upto this method itself, but if compiler
- * allows it, then that will go through.
- */
- public boolean isVisible(ClassSymbol sym) {
- long mod = sym.flags_field;
- if (!filter.checkModifier(translateModifiers(mod))) {
- return false;
- }
- ClassSymbol encl = sym.owner.enclClass();
- return (encl == null || (mod & Flags.STATIC) != 0 || isVisible(encl));
+ return path != null;
}
//---------------- print forwarders ----------------//
@@ -366,6 +263,15 @@
/**
* Print error message, increment error count.
+ * @param key selects message from resource
+ * @param args replacement arguments
+ */
+ public void error(String key, String... args) {
+ error(null, key, args);
+ }
+
+ /**
+ * Print error message, increment error count.
*
* @param element the source element
* @param key selects message from resource
@@ -553,48 +459,6 @@
throw new Messager.ExitJavadoc();
}
- /**
- * Adds all inner classes of this class, and their inner classes recursively, to the list
- */
- void addAllClasses(Collection<TypeElement> list, TypeElement typeElement, boolean filtered) {
- ClassSymbol klass = (ClassSymbol)typeElement;
- try {
- if (isSynthetic(klass.flags())) return;
- // sometimes synthetic classes are not marked synthetic
- if (!JavadocTool.isValidClassName(klass.name.toString())) return;
- if (filtered && !shouldDocument(klass)) return;
- if (list.contains(klass)) return;
- list.add(klass);
- for (Symbol sym : klass.members().getSymbols(NON_RECURSIVE)) {
- if (sym != null && sym.kind == Kind.TYP) {
- ClassSymbol s = (ClassSymbol)sym;
- if (!isSynthetic(s.flags())) {
- addAllClasses(list, s, filtered);
- }
- }
- }
- } catch (CompletionFailure e) {
- // quietly ignore completion failures
- }
- }
-
- /**
- * Return a list of all classes contained in this package, including
- * member classes of those classes, and their member classes, etc.
- */
- void addAllClasses(Collection<TypeElement> list, PackageElement pkg) {
- boolean filtered = true;
- PackageSymbol sym = (PackageSymbol)pkg;
- for (Symbol isym : sym.members().getSymbols(NON_RECURSIVE)) {
- if (isym != null) {
- ClassSymbol s = (ClassSymbol)isym;
- if (!isSynthetic(s)) {
- addAllClasses(list, s, filtered);
- }
- }
- }
- }
-
TreePath getTreePath(JCCompilationUnit tree) {
TreePath p = treePaths.get(tree);
if (p == null)
@@ -624,225 +488,11 @@
return types;
}
- /**
- * Set the encoding.
- */
- public void setEncoding(String encoding) {
- this.encoding = encoding;
- }
-
public Env<AttrContext> getEnv(ClassSymbol tsym) {
return enter.getEnv(tsym);
}
- /**
- * Get the encoding.
- */
- public String getEncoding() {
- return encoding;
- }
-
- /**
- * Convert modifier bits from private coding used by
- * the compiler to that of java.lang.reflect.Modifier.
- */
- static int translateModifiers(long flags) {
- int result = 0;
- if ((flags & Flags.ABSTRACT) != 0)
- result |= Modifier.ABSTRACT;
- if ((flags & Flags.FINAL) != 0)
- result |= Modifier.FINAL;
- if ((flags & Flags.INTERFACE) != 0)
- result |= Modifier.INTERFACE;
- if ((flags & Flags.NATIVE) != 0)
- result |= Modifier.NATIVE;
- if ((flags & Flags.PRIVATE) != 0)
- result |= Modifier.PRIVATE;
- if ((flags & Flags.PROTECTED) != 0)
- result |= Modifier.PROTECTED;
- if ((flags & Flags.PUBLIC) != 0)
- result |= Modifier.PUBLIC;
- if ((flags & Flags.STATIC) != 0)
- result |= Modifier.STATIC;
- if ((flags & Flags.SYNCHRONIZED) != 0)
- result |= Modifier.SYNCHRONIZED;
- if ((flags & Flags.TRANSIENT) != 0)
- result |= Modifier.TRANSIENT;
- if ((flags & Flags.VOLATILE) != 0)
- result |= Modifier.VOLATILE;
- return result;
- }
-
- private final Set<Element> includedSet = new HashSet<>();
-
- public void setIncluded(Element element) {
- includedSet.add(element);
- }
-
- private SimpleElementVisitor9<Boolean, Void> includedVisitor = null;
-
- public boolean isIncluded(Element e) {
- if (e == null) {
- return false;
- }
- if (includedVisitor == null) {
- includedVisitor = new SimpleElementVisitor9<Boolean, Void>() {
- @Override @DefinedBy(Api.LANGUAGE_MODEL)
- public Boolean visitType(TypeElement e, Void p) {
- if (includedSet.contains(e)) {
- return true;
- }
- if (shouldDocument(e)) {
- // Class is nameable from top-level and
- // the class and all enclosing classes
- // pass the modifier filter.
- PackageElement pkg = elements.getPackageOf(e);
- if (includedSet.contains(pkg)) {
- setIncluded(e);
- return true;
- }
- Element enclosing = e.getEnclosingElement();
- if (enclosing != null && includedSet.contains(enclosing)) {
- setIncluded(e);
- return true;
- }
- }
- return false;
- }
-
- @Override @DefinedBy(Api.LANGUAGE_MODEL)
- public Boolean visitPackage(PackageElement e, Void p) {
- return includedSet.contains(e);
- }
-
- @Override @DefinedBy(Api.LANGUAGE_MODEL)
- public Boolean visitUnknown(Element e, Void p) {
- throw new AssertionError("unknown element: " + e);
- }
-
- @Override @DefinedBy(Api.LANGUAGE_MODEL)
- public Boolean defaultAction(Element e, Void p) {
- return visit(e.getEnclosingElement()) && shouldDocument(e);
- }
- };
- }
- return includedVisitor.visit(e);
- }
-
public boolean isQuiet() {
return quiet;
}
-
- /**
- * A class which filters the access flags on classes, fields, methods, etc.
- *
- * <p>
- * <b>This is NOT part of any supported API. If you write code that depends on this, you do so
- * at your own risk. This code and its internal interfaces are subject to change or deletion
- * without notice.</b>
- *
- * @see javax.lang.model.element.Modifier
- * @author Robert Field
- */
-
- private static class ModifierFilter {
-
- static enum FilterFlag {
- PACKAGE,
- PRIVATE,
- PROTECTED,
- PUBLIC
- }
-
- private Set<FilterFlag> oneOf;
-
- /**
- * Constructor - Specify a filter.
- *
- * @param oneOf a set containing desired flags to be matched.
- */
- ModifierFilter(Set<FilterFlag> oneOf) {
- this.oneOf = oneOf;
- }
-
- /**
- * Constructor - Specify a filter.
- *
- * @param oneOf an array containing desired flags to be matched.
- */
- ModifierFilter(FilterFlag... oneOf) {
- this.oneOf = new HashSet<>();
- this.oneOf.addAll(Arrays.asList(oneOf));
- }
-
- static ModifierFilter getModifierFilter(String showAccess) {
- switch (showAccess) {
- case "public":
- return new ModifierFilter(FilterFlag.PUBLIC);
- case "package":
- return new ModifierFilter(FilterFlag.PUBLIC, FilterFlag.PROTECTED,
- FilterFlag.PACKAGE);
- case "private":
- return new ModifierFilter(FilterFlag.PRIVATE);
- default:
- return new ModifierFilter(FilterFlag.PUBLIC, FilterFlag.PROTECTED);
- }
- }
-
- private boolean hasFlag(long flag, long modifierBits) {
- return (flag & modifierBits) != 0;
- }
-
- private List<FilterFlag> flagsToModifiers(long modifierBits) {
- List<FilterFlag> list = new ArrayList<>();
- boolean isPackage = true;
- if (hasFlag(com.sun.tools.javac.code.Flags.PRIVATE, modifierBits)) {
- list.add(FilterFlag.PRIVATE);
- isPackage = false;
- }
- if (hasFlag(com.sun.tools.javac.code.Flags.PROTECTED, modifierBits)) {
- list.add(FilterFlag.PROTECTED);
- isPackage = false;
- }
- if (hasFlag(com.sun.tools.javac.code.Flags.PUBLIC, modifierBits)) {
- list.add(FilterFlag.PUBLIC);
- isPackage = false;
- }
- if (isPackage) {
- list.add(FilterFlag.PACKAGE);
- }
- return list;
- }
-
- /**
- * Filter on modifier bits.
- *
- * @param modifierBits Bits as specified in the Modifier class
- *
- * @return Whether the modifierBits pass this filter.
- */
- public boolean checkModifier(int modifierBits) {
- return checkModifier(flagsToModifiers(modifierBits));
- }
-
- /**
- * Filter on Filter flags
- *
- * @param modifiers Flags as specified in the FilterFlags enumeration.
- *
- * @return if the modifier is contained.
- */
- public boolean checkModifier(List<FilterFlag> modifiers) {
- if (oneOf.contains(FilterFlag.PRIVATE)) {
- return true;
- }
- for (FilterFlag mod : modifiers) {
- if (oneOf.contains(mod)) {
- return true;
- }
- }
- return false;
- }
-
- } // end ModifierFilter
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java Thu Aug 18 05:48:35 2016 -0700
@@ -26,10 +26,13 @@
package jdk.javadoc.internal.tool;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.StringTokenizer;
+
+import javax.lang.model.element.ElementKind;
import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.main.OptionHelper;
@@ -44,6 +47,7 @@
* deletion without notice.</b>
*/
public enum ToolOption {
+
// ----- options for underlying compiler -----
BOOTCLASSPATH("-bootclasspath", true) {
@@ -193,10 +197,16 @@
}
},
+ MODULE("--module", true) {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.addToList(this, ",", arg);
+ }
+ },
+
ENCODING("-encoding", true) {
@Override
public void process(Helper helper, String arg) {
- helper.encoding = arg;
helper.setFileManagerOpt(Option.ENCODING, arg);
}
},
@@ -296,14 +306,14 @@
SUBPACKAGES("-subpackages", true) {
@Override
public void process(Helper helper, String arg) {
- helper.addToList(helper.subPackages, arg);
+ helper.addToList(this, ":", arg);
}
},
EXCLUDE("-exclude", true) {
@Override
public void process(Helper helper, String arg) {
- helper.addToList(helper.excludedPackages, arg);
+ helper.addToList(this, ":", arg);
}
},
@@ -312,28 +322,63 @@
PACKAGE("-package") {
@Override
public void process(Helper helper) {
- helper.setFilter("package");
+ helper.setSimpleFilter("package");
}
},
PRIVATE("-private") {
@Override
public void process(Helper helper) {
- helper.setFilter("private");
+ helper.setSimpleFilter("private");
}
},
PROTECTED("-protected") {
@Override
public void process(Helper helper) {
- helper.setFilter("protected");
+ helper.setSimpleFilter("protected");
}
},
PUBLIC("-public") {
@Override
public void process(Helper helper) {
- helper.setFilter("public");
+ helper.setSimpleFilter("public");
+ }
+ },
+
+ SHOW_MEMBERS("--show-members:") {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.setFilter(this, arg);
+ }
+ },
+
+ SHOW_TYPES("--show-types:") {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.setFilter(this, arg);
+ }
+ },
+
+ SHOW_PACKAGES("--show-packages:") {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.setShowPackageAccess(SHOW_PACKAGES, helper.getOptionArgumentValue(arg));
+ }
+ },
+
+ SHOW_MODULE_CONTENTS("--show-module-contents:") {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.setShowModuleContents(SHOW_MODULE_CONTENTS, helper.getOptionArgumentValue(arg));
+ }
+ },
+
+ EXPAND_REQUIRES("--expand-requires:") {
+ @Override
+ public void process(Helper helper, String arg) {
+ helper.setExpandRequires(EXPAND_REQUIRES, helper.getOptionArgumentValue(arg));
}
},
@@ -350,7 +395,7 @@
QUIET("-quiet") {
@Override
public void process(Helper helper) {
- helper.quiet = true;
+ helper.jdtoolOpts.put(QUIET, true);
}
},
@@ -385,19 +430,10 @@
}
},
- // the doclet consumes this
- OVERVIEW("-overview", true) {
- @Override
- public void process(Helper helper, String arg) {
- helper.setOverviewpath(arg);
- }
- },
-
XCLASSES("-Xclasses") {
@Override
public void process(Helper helper) {
- helper.docClasses = true;
-
+ helper.jdtoolOpts.put(XCLASSES, true);
}
},
@@ -452,14 +488,6 @@
}
static abstract class Helper {
- /** List of decoded options. */
- final List<List<String>> options = new ArrayList<>();
-
- /** Selected packages, from -subpackages. */
- final List<String> subPackages = new ArrayList<>();
-
- /** Excluded packages, from -exclude. */
- final List<String> excludedPackages = new ArrayList<>();
// File manager options
final Map<Option, String> fileManagerOpts = new LinkedHashMap<>();
@@ -467,18 +495,12 @@
/** javac options, set by various options. */
Options compOpts; // = Options.instance(context)
- /* Encoding for javac, and files written? set by -encoding. */
- String encoding = null;
+ /** Javadoc tool options */
+ final Map<ToolOption, Object> jdtoolOpts = new EnumMap<>(ToolOption.class);
/** Set by -breakiterator. */
boolean breakiterator = false;
- /** Set by -quiet. */
- boolean quiet = false;
-
- /** Set by -Xclasses. */
- boolean docClasses = false;
-
/** Set by -Xwerror. */
boolean rejectWarnings = false;
@@ -488,9 +510,9 @@
/** Set by -locale. */
String docLocale = "";
- /** Set by -public, private, -protected, -package. */
- String showAccess = null;
- String overviewpath;
+ Helper() {
+ populateDefaultAccessMap();
+ }
abstract void usage();
abstract void Xusage();
@@ -498,33 +520,129 @@
abstract void usageError(String msg, Object... args);
abstract OptionHelper getOptionHelper();
- void addToList(List<String> list, String str){
- StringTokenizer st = new StringTokenizer(str, ":");
- String current;
- while(st.hasMoreTokens()){
- current = st.nextToken();
- list.add(current);
+ @SuppressWarnings("unchecked")
+ void addToList(ToolOption opt, String delimiter, String str) {
+ List<String> list = (List<String>) jdtoolOpts.computeIfAbsent(opt, v -> new ArrayList<>());
+ list.addAll(Arrays.asList(str.split(delimiter)));
+ jdtoolOpts.put(opt, list);
+ }
+
+ String getOptionArgumentValue(String in) {
+ String[] values = in.trim().split(":");
+ return values[1];
+ }
+
+ void setExpandRequires(ToolOption opt, String arg) {
+ switch (arg) {
+ case "public":
+ jdtoolOpts.put(opt, AccessKind.PUBLIC);
+ break;
+ case "all":
+ jdtoolOpts.put(opt, AccessKind.PRIVATE);
+ break;
+ default:
+ usageError("main.illegal_option_value", arg);
}
}
- void setFilter(String showAccess) {
- if (showAccess != null) {
- if (!"public".equals(showAccess)
- && !"protected".equals(showAccess)
- && !"private".equals(showAccess)
- && !"package".equals(showAccess)) {
- usageError("main.incompatible.access.flags");
- }
- this.showAccess = showAccess;
+ void setShowModuleContents(ToolOption opt, String arg) {
+ switch (arg) {
+ case "api":
+ jdtoolOpts.put(opt, AccessKind.PUBLIC);
+ break;
+ case "all":
+ jdtoolOpts.put(opt, AccessKind.PRIVATE);
+ break;
+ default:
+ usageError("main.illegal_option_value", arg);
}
}
+ void setShowPackageAccess(ToolOption opt, String arg) {
+ switch (arg) {
+ case "exported":
+ jdtoolOpts.put(opt, AccessKind.PUBLIC);
+ break;
+ case "all":
+ jdtoolOpts.put(opt, AccessKind.PRIVATE);
+ break;
+ default:
+ usageError("main.illegal_option_value", arg);
+ }
+ }
+
+
+ void setFilter(ToolOption opt, String arg) {
+ jdtoolOpts.put(opt, getAccessValue(arg));
+ }
+
+ void setSimpleFilter(String arg) {
+ handleSimpleOption(arg);
+ }
+
void setFileManagerOpt(Option opt, String arg) {
fileManagerOpts.put(opt, arg);
}
- private void setOverviewpath(String arg) {
- this.overviewpath = arg;
+ void handleSimpleOption(String arg) {
+ populateSimpleAccessMap(getAccessValue(arg));
+ }
+
+ /*
+ * This method handles both the simple options -package,
+ * -private, so on, in addition to the new ones such as
+ * --show-types:public and so on.
+ */
+ private AccessKind getAccessValue(String arg) {
+ int colon = arg.indexOf(':');
+ String value = (colon > 0)
+ ? arg.substring(colon + 1)
+ : arg;
+ switch (value) {
+ case "public":
+ return AccessKind.PUBLIC;
+ case "protected":
+ return AccessKind.PROTECTED;
+ case "package":
+ return AccessKind.PACKAGE;
+ case "private":
+ return AccessKind.PRIVATE;
+ default:
+ usageError("main.illegal_option_value", value);
+ return null;
+ }
+ }
+
+ /*
+ * Sets the entire kind map to PROTECTED this is the default.
+ */
+ private void populateDefaultAccessMap() {
+ populateSimpleAccessMap(AccessKind.PROTECTED);
+ }
+
+ /*
+ * This sets access to all the allowed kinds in the
+ * access map.
+ */
+ void populateSimpleAccessMap(AccessKind accessValue) {
+ for (ElementKind kind : ElementsTable.ModifierFilter.ALLOWED_KINDS) {
+ switch (kind) {
+ case METHOD:
+ jdtoolOpts.put(SHOW_MEMBERS, accessValue);
+ break;
+ case CLASS:
+ jdtoolOpts.put(SHOW_TYPES, accessValue);
+ break;
+ case PACKAGE:
+ jdtoolOpts.put(SHOW_PACKAGES, accessValue);
+ break;
+ case MODULE:
+ jdtoolOpts.put(SHOW_MODULE_CONTENTS, accessValue);
+ break;
+ default:
+ throw new AssertionError("unknown element kind:" + kind);
+ }
+ }
}
}
}
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties Thu Aug 18 05:48:35 2016 -0700
@@ -31,18 +31,53 @@
main.usage=Usage: javadoc [options] [packagenames] [sourcefiles] [@files]\n\
\ -overview <file> Read overview documentation from HTML file\n\
\ -public Show only public classes and members\n\
-\ -protected Show protected/public classes and members (default)\n\
-\ -package Show package/protected/public classes and members\n\
+\ -protected Show protected/public classes and \n\
+\ members (default)\n\
+\ -package Show package/protected/public classes\n\
+\ and members\n\
\ -private Show all classes and members\n\
+\ --show-members:value Specifies which members (fields, methods\n\
+\ etc.) will be documented, where value can\n\
+\ be one of "public", "protected", "package"\n\
+\ or "private".\n\
+\ Default is protected, will show public and\n\
+\ protected members, "public" will show only\n\
+\ public members, "package" will show public,\n\
+\ protected and package members and \n\
+\ "private" will show all members\n\
+\ --show-types:value Specifies which types (classes, interfaces\n\
+\ etc.) will be documented, where value can be\n\
+\ one of "public", "protected", "package" or\n\
+\ "private".\n\
+\ Default is "protected", show public and\n\
+\ protected types, "package" will show public,\n\
+\ protected and package types and "private"\n\
+\ will show all types\n\
+\ --show-packages:value Specifies which module's packages will be\n\
+\ documented. Possible values are "exported"\n\
+\ or "all" packages\n\
+\ --show-module-contents:value Specifies the documentation granularity of\n\
+\ module declarations.\n\
+\ Possible values are "api" or "all".\n\
+\ --expand-requires:value Instructs the tool to expand the "requires"\n\
+\ module dependencies "public" expands all the\n\
+\ "requires public" edges of the module graph.\n\
+\ "all" expands all the "requires" edges of\n\
+\ the module graph by default only the\n\
+\ specified modules will be considered.\n\
\ -help Display command line options and exit\n\
+\ --module m1, m2.. Document the specified module(s)\n\
\ -doclet <class> Generate output via alternate doclet\n\
\ -docletpath <path> Specify where to find doclet class files\n\
-\ --module-source-path <path> Specify where to find input source files for multiple modules\n\
+\ --module-source-path <path> Specify where to find input source files\n\
+\ for multiple modules\n\
\ --upgrade-module-path <path> Override location of upgradeable modules\n\
\ --module-path <path>, -p <path> Specify where to find application modules\n\
\ --add-modules <module>(,<module>)*\n\
-\ Root modules to resolve in addition to the initial modules,\n\
-\ or all modules on the module path if <module> is ALL-MODULE-PATH.\n\
+\ Root modules to resolve in addition to the\n\
+\ initial modules,\n\
+\ or all modules on the module path if\n\
+\ <module> is ALL-MODULE-PATH.\n\
\ --limit-modules <module>(,<module>)*\n\
\ Limit the universe of observable modules\n\
\ --source-path <path> Specify where to find source files\n\
@@ -57,35 +92,40 @@
\ used for non-modular releases\n\
\ --system <jdk> Override location of system modules used\n\
\ for modular releases.\n\
-\ --release <release> Provide source compatibility with specified release\n\
-\ -source <release> Provide source compatibility with specified release\n\
+\ --release <release> Provide source compatibility with\n\
+\ specified release\n\
+\ -source <release> Provide source compatibility with\n\
+\ specified release\n\
\ -extdirs <dirlist> Override location of installed extensions\n\
\ -verbose Output messages about what Javadoc is doing\n\
\ -locale <name> Locale to be used, e.g. en_US or en_US_WIN\n\
\ -encoding <name> Source file encoding name\n\
\ -quiet Do not display status messages\n\
\ -J<flag> Pass <flag> directly to the runtime system\n\
-\ -X Print a synopsis of nonstandard options and exit\n
+\ -X Print a synopsis of nonstandard\n\
+\ options and exit\n
main.usage.foot=\n\
-GNU-style options may use '=' instead whitespace to separate the name of an option\n\
-from its value.\n
+GNU-style options may use '=' instead of whitespace to separate the name of an\n\
+option from its value.\n
main.Xusage=\
\ -Xmaxerrs <number> Set the maximum number of errors to print\n\
\ -Xmaxwarns <number> Set the maximum number of warnings to print\n\
\ --add-exports <module>/<package>=<other-module>(,<other-module>)*\n\
-\ Specify a package to be considered as exported from its \n\
-\ defining module to additional modules, or to all unnamed \n\
-\ modules if <other-module> is ALL-UNNAMED.\n\
+\ Specify a package to be considered as exported\n\
+\ from its defining module to additional modules,\n\
+\ or to all unnamed modules if <other-module> is\n\
+\ ALL-UNNAMED.\n\
\ --add-reads <module>=<other-module>(,<other-module>)*\n\
-\ Specify additional modules to be considered as required by a\n\
-\ given module. <other-module> may be ALL-UNNAMED to require\n\
-\ the unnamed module.\n\
-\ -Xmodule:<module-name> Specify a module to which the classes being compiled belong.\n\
+\ Specify additional modules to be considered as\n\
+\ required by a given module. <other-module> may be\n\
+\ ALL-UNNAMED to require the unnamed module.\n\
+\ -Xmodule:<module-name> Specify a module to which the classes being\n\
+\ compiled belong.\n\
\ --patch-module <module>=<file>(:<file>)*\n\
-\ Override or augment a module with classes and resources\n\
-\ in JAR files or directories\n\
+\ Override or augment a module with classes\n\
+\ and resources in JAR files or directories\n\
\ -Xold Invoke the legacy javadoc tool\n
main.Xusage.foot=\
@@ -95,13 +135,14 @@
main.requires_argument=option {0} requires an argument.
main.invalid_flag=invalid flag: {0}
-main.No_packages_or_classes_specified=No packages or classes specified.
-main.incompatible.access.flags=More than one of -public, -private, -package, or -protected specified.
+main.No_modules_packages_or_classes_specified=No modules, packages or classes specified.
+main.module_not_found=module {0} not found.\n
main.cant.read=cannot read {0}
main.Loading_source_files_for_package=Loading source files for package {0}...
main.Loading_source_file=Loading source file {0}...
main.Building_tree=Constructing Javadoc information...
main.no_source_files_for_package=No source files for package {0}
+main.package_not_found=Package {0} not found
main.fatal.error=fatal error
main.fatal.exception=fatal exception
main.out.of.memory=java.lang.OutOfMemoryError: Please increase memory.\n\
@@ -119,6 +160,7 @@
main.file_ignored=File ignored: "{0}" (not yet supported)
main.illegal_class_name=Illegal class name: "{0}"
main.illegal_package_name=Illegal package name: "{0}"
+main.illegal_option_value=Illegal option value: "{0}"
main.release.bootclasspath.conflict=option {0} cannot be used together with -release
main.unsupported.release.version=release version {0} not supported
main.release.not.standard.file.manager=-release option specified, but the provided JavaFileManager is not a StandardJavaFileManager.
--- a/langtools/test/jdk/javadoc/doclet/testFramesNoFrames/TestFramesNoFrames.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/doclet/testFramesNoFrames/TestFramesNoFrames.java Thu Aug 18 05:48:35 2016 -0700
@@ -205,10 +205,7 @@
void testModules(Path base, FrameKind fKind, OverviewKind oKind, HtmlKind hKind) throws IOException {
javadoc(base, fKind, oKind, hKind,
"-modulesourcepath", gensrcModules.toString(),
- "-addmods", "m1,m2,m3", // TEMPORARY, SHOULD NOT BE NECESSARY
- "m1p1", "m1p2", "m1p3",
- "m2p1", "m2p2", "m2p3",
- "m3p1", "m3p2", "m3p3");
+ "--module", "m1,m2,m3");
new Checker(fKind, oKind, hKind)
.classes("m1/m1p1.M1P1C1", "m1/m1p1.M1P1C2", "m1/m1p1.M1P1C3",
--- a/langtools/test/jdk/javadoc/doclet/testLinkTaglet/TestLinkTaglet.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/doclet/testLinkTaglet/TestLinkTaglet.java Thu Aug 18 05:48:35 2016 -0700
@@ -70,5 +70,7 @@
checkOutput(Output.OUT, false,
"Tag @see: reference not found: A");
+
+ checkFiles(false, "checkPkg/A.html");
}
}
--- a/langtools/test/jdk/javadoc/doclet/testModules/TestModules.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/doclet/testModules/TestModules.java Thu Aug 18 05:48:35 2016 -0700
@@ -158,7 +158,7 @@
javadoc("-d", "out-moduleSummary", "-use",
"-modulesourcepath", testSrc,
"-addmods", "module1,module2",
- "testpkgmdl1", "testpkgmdl2", "testpkg2mdl2");
+ "testpkgmdl1", "testpkgmdl2", "module2/testpkg2mdl2");
checkExit(Exit.OK);
checkModuleSummary();
checkNegatedModuleSummary();
@@ -174,7 +174,7 @@
"-addmods", "module1",
"testpkgmdl1");
checkExit(Exit.OK);
- checkModuleFilesAndLinks(false);
+ checkModuleFilesAndLinks(true);
}
void checkDescription(boolean found) {
@@ -418,7 +418,8 @@
+ "</a>");
checkOutput("module2-summary.html", true,
"<tr class=\"rowColor\">\n"
- + "<td class=\"colFirst\">testpkg2mdl2</td>\n"
+ + "<td class=\"colFirst\"><a href=\"testpkg2mdl2/package-summary.html\">"
+ + "testpkg2mdl2</a></td>\n"
+ "<td class=\"colSecond\">module1</td>\n"
+ "<td class=\"colLast\"> </td>\n"
+ "</tr>");
@@ -445,9 +446,10 @@
+ "</tr>");
checkOutput("module2-summary.html", true,
"<tr class=\"altColor\">\n"
- + "<td class=\"colFirst\">testpkg2mdl2.TestInterfaceInModule2<br>(<span "
- + "class=\"implementationLabel\">Implementation:</span> <a "
- + "href=\"testpkgmdl2/TestClassInModule2.html\" title=\"class in testpkgmdl2\">"
+ + "<td class=\"colFirst\"><a href=\"testpkg2mdl2/TestInterfaceInModule2.html\" "
+ + "title=\"interface in testpkg2mdl2\">TestInterfaceInModule2</a><br>"
+ + "(<span class=\"implementationLabel\">Implementation:</span> "
+ + "<a href=\"testpkgmdl2/TestClassInModule2.html\" title=\"class in testpkgmdl2\">"
+ "TestClassInModule2</a>)</td>\n"
+ "<td class=\"colLast\"> </td>\n"
+ "</tr");
--- a/langtools/test/jdk/javadoc/tool/6227454/Test.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/6227454/Test.java Thu Aug 18 05:48:35 2016 -0700
@@ -140,9 +140,9 @@
public boolean run(DocletEnvironment root) {
DocTrees docTrees = root.getDocTrees();
- System.out.println("classes:" + root.getIncludedClasses());
+ System.out.println("classes:" + root.getIncludedTypeElements());
- Element klass = root.getIncludedClasses().iterator().next();
+ Element klass = root.getIncludedTypeElements().iterator().next();
String text = "";
try {
DocCommentTree dcTree = docTrees.getDocCommentTree(klass, overviewpath);
--- a/langtools/test/jdk/javadoc/tool/BreakIteratorWarning.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/BreakIteratorWarning.java Thu Aug 18 05:48:35 2016 -0700
@@ -75,7 +75,7 @@
}
public boolean run(DocletEnvironment root) {
- TypeElement cd = root.getIncludedClasses().iterator().next();
+ TypeElement cd = root.getIncludedTypeElements().iterator().next();
VariableElement fd = getFields(cd).get(0);
DocTrees docTrees = root.getDocTrees();
DocCommentTree docCommentTree = docTrees.getDocCommentTree(fd);
--- a/langtools/test/jdk/javadoc/tool/InlineTagsWithBraces.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/InlineTagsWithBraces.java Thu Aug 18 05:48:35 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -80,7 +80,7 @@
public boolean run(DocletEnvironment root) {
DocTrees trees = root.getDocTrees();
- TypeElement cd = root.getIncludedClasses().iterator().next();
+ TypeElement cd = root.getIncludedTypeElements().iterator().next();
DocCommentTree docCommentTree = trees.getDocCommentTree(cd);
List<? extends DocTree> tags = docCommentTree.getBody();
--- a/langtools/test/jdk/javadoc/tool/NoStar.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/NoStar.java Thu Aug 18 05:48:35 2016 -0700
@@ -62,7 +62,7 @@
}
public boolean run(DocletEnvironment root) {
- Set<TypeElement> classes = root.getIncludedClasses();
+ Set<TypeElement> classes = root.getIncludedTypeElements();
if (classes.size() != 1)
throw new Error("1 " + Arrays.asList(classes));
TypeElement self = classes.iterator().next();
--- a/langtools/test/jdk/javadoc/tool/T4994049/T4994049.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/T4994049/T4994049.java Thu Aug 18 05:48:35 2016 -0700
@@ -59,7 +59,7 @@
DocTrees trees = root.getDocTrees();
SourcePositions sourcePositions = trees.getSourcePositions();
- for (TypeElement klass : root.getIncludedClasses()) {
+ for (TypeElement klass : root.getIncludedTypeElements()) {
for (ExecutableElement method : getMethods(klass)) {
if (method.getSimpleName().toString().equals("tabbedMethod")) {
TreePath path = trees.getPath(method);
--- a/langtools/test/jdk/javadoc/tool/completionFailure/CompletionFailure.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/completionFailure/CompletionFailure.java Thu Aug 18 05:48:35 2016 -0700
@@ -54,7 +54,7 @@
}
public boolean run(DocletEnvironment root) {
- Set<TypeElement> classes = root.getIncludedClasses();
+ Set<TypeElement> classes = root.getIncludedTypeElements();
if (classes.size() != 1)
throw new Error("1 " + Arrays.asList(classes));
return true;
--- a/langtools/test/jdk/javadoc/tool/dupOk/DupOk.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/dupOk/DupOk.java Thu Aug 18 05:48:35 2016 -0700
@@ -48,7 +48,6 @@
String path1 = new File(srcFile, "sp1").getPath();
String path2 = new File(srcFile, "sp2").getPath();
String[] aargs = {
- "javadoc",
"-docletpath",
new File(System.getProperty("test.classes", ".")).getPath(),
"-doclet",
@@ -63,7 +62,7 @@
}
public boolean run(DocletEnvironment root) {
- Set<TypeElement> classes = root.getIncludedClasses();
+ Set<TypeElement> classes = root.getIncludedTypeElements();
if (classes.size() != 2)
throw new Error("1 " + Arrays.asList(classes));
for (TypeElement clazz : classes) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/modules/FilterOptions.java Thu Aug 18 05:48:35 2016 -0700
@@ -0,0 +1,429 @@
+/*
+ * 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 8159305
+ * @summary Tests elements filtering options
+ * @modules
+ * jdk.javadoc/jdk.javadoc.internal.api
+ * jdk.javadoc/jdk.javadoc.internal.doclets.standard
+ * 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
+ * @run main FilterOptions
+ */
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import toolbox.*;
+
+public class FilterOptions extends ModuleTestBase {
+
+ private static final String NL = System.getProperty("line.separator");
+ private static final String INDENT = " ";
+
+ // the sources are shared, so create it once
+ private final String src;
+
+ public static void main(String... args) throws Exception {
+ new FilterOptions().runTests();
+ }
+
+ FilterOptions() throws IOException {
+ this.src = createSources(Paths.get(".").resolve("src"));
+ }
+
+ @Test
+ public void testDefault(Path base) throws Exception {
+ execTask("-modulesourcepath", src, "--module", "m1");
+
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+ checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
+ }
+
+ @Test
+ public void testModuleModeApi(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1", "--show-module-contents:api");
+
+ checkModuleMode("API");
+ }
+
+ @Test
+ public void testModuleModeAll(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1", "--show-module-contents:all");
+
+ checkModuleMode("ALL");
+ }
+
+ @Test
+ public void testShowPackagesExported(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-packages:exported"); // default
+
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+ checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
+ }
+
+ @Test
+ public void testShowPackagesAll(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-packages:all");
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub", "pro");
+
+ checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested",
+ "pro.A", "pro.A.ProtectedNested", "pro.A.PublicNested");
+ }
+
+ @Test
+ public void testShowTypesPrivate(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-types:private");
+
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+
+ checkTypesIncluded("pub.A", "pub.A.PrivateNested", "pub.A.Nested", "pub.A.ProtectedNested",
+ "pub.A.PublicNested",
+ "pub.B", "pub.B.PrivateNested", "pub.B.Nested", "pub.B.ProtectedNested",
+ "pub.B.PublicNested");
+
+ }
+
+ @Test
+ public void testShowTypesPackage(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-types:package");
+
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+
+ checkTypesIncluded("pub.A", "pub.A.Nested", "pub.A.ProtectedNested", "pub.A.PublicNested",
+ "pub.B", "pub.B.Nested", "pub.B.ProtectedNested", "pub.B.PublicNested");
+
+ checkTypesNotIncluded(".*private.*");
+ }
+
+ @Test
+ public void testShowTypesProtected(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-types:protected");
+
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+
+ checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
+
+ checkTypesNotIncluded("pub.A.Nested", "pub.A.PrivateNested", "pub.B.Nested",
+ "pub.B.PrivateNested", "pub.B.ProtectedNested",
+ "pub.B.PublicNested");
+ }
+
+ @Test
+ public void testShowTypesPublic(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-types:public");
+
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+
+ checkTypesIncluded("pub.A", "pub.A.PublicNested");
+ checkTypesNotIncluded("pub.A.Nested",
+ "pub.A.ProtectedNested", "pub.A.PrivateNested",
+ "pub.B.Nested", "pub.B.ProtectedNested", "pub.B.PrivateNested",
+ "pub.B.PublicNested");
+ }
+
+ @Test
+ public void testShowMembersPrivate(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-members:private");
+
+ checkMembers(Visibility.PRIVATE);
+ }
+
+ @Test
+ public void testShowMembersPackage(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-members:package");
+
+ checkMembers(Visibility.PACKAGE);
+ }
+
+ @Test
+ public void testShowMembersProtected(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-members:protected");
+
+ checkMembers(Visibility.PROTECTED);
+ }
+
+ @Test
+ public void testShowMembersPublic(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "--show-members:public");
+
+ checkMembers(Visibility.PUBLIC);
+ }
+
+ @Test
+ public void testLegacyPublic(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "-public");
+
+ checkModuleMode("API");
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+ checkTypesIncluded("pub.A", "pub.A.PublicNested");
+
+ checkMembers(Visibility.PUBLIC);
+ }
+
+ @Test
+ public void testLegacyDefault(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1");
+
+ checkModuleMode("API");
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+ checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
+
+ checkMembers(Visibility.PROTECTED);
+ }
+
+ @Test
+ public void testLegacyProtected(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "-protected");
+
+ checkModuleMode("API");
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+ checkTypesIncluded("pub.A", "pub.A.ProtectedNested", "pub.A.PublicNested");
+
+ checkMembers(Visibility.PROTECTED);
+ }
+
+ @Test
+ public void testLegacyPackage(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "-package");
+
+ checkModuleMode("ALL");
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+ checkPackagesIncluded("pro");
+ checkTypesIncluded("pub.B", "pub.B.Nested", "pub.B.ProtectedNested", "pub.B.PublicNested",
+ "pub.A", "pub.A.Nested", "pub.A.ProtectedNested", "pub.A.PublicNested",
+ "pro.B", "pro.B.Nested", "pro.B.ProtectedNested", "pro.B.PublicNested",
+ "pro.A", "pro.A.Nested", "pro.A.ProtectedNested", "pro.A.PublicNested");
+
+ checkMembers(Visibility.PACKAGE);
+ }
+
+ @Test
+ public void testLegacyPrivate(Path base) throws Exception {
+ execTask("-modulesourcepath", src,
+ "--module", "m1",
+ "-private");
+
+ checkModuleMode("ALL");
+ checkModulesSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("pub");
+ checkPackagesIncluded("pro");
+ checkTypesIncluded("pub.B", "pub.B.PrivateNested", "pub.B.Nested", "pub.B.ProtectedNested",
+ "pub.B.PublicNested",
+ "pub.A", "pub.A.PrivateNested", "pub.A.Nested", "pub.A.ProtectedNested",
+ "pub.A.PublicNested",
+ "pro.B", "pro.B.PrivateNested", "pro.B.Nested", "pro.B.ProtectedNested",
+ "pro.B.PublicNested",
+ "pro.A", "pro.A.PrivateNested", "pro.A.Nested", "pro.A.ProtectedNested",
+ "pro.A.PublicNested");
+
+ checkMembers(Visibility.PRIVATE);
+ }
+
+ private static enum Visibility {
+ PRIVATE, PACKAGE, PROTECTED, PUBLIC;
+ }
+
+ void checkMembers(Visibility v) throws Exception {
+ checkMembersPresence(v);
+ checkMembersAbsence(v);
+ }
+
+ void checkMembersPresence(Visibility v) throws Exception {
+ switch (v) {
+ case PRIVATE:
+ checkMembersSelected("pub.A.privateFieldA",
+ "pub.A.PublicNested.privateFieldPublicNested",
+ "pub.A.ProtectedNested.privateFieldProtectedNested");
+
+ case PACKAGE:
+ checkMembersSelected("pub.A.FieldA",
+ "pub.A.PublicNested.FieldPublicNested",
+ "pub.A.ProtectedNested.FieldProtectedNested");
+
+ case PROTECTED:
+ checkMembersSelected("pub.A.<init>",
+ "pub.A.protectedFieldA",
+ "pub.A.PublicNested.protectedFieldPublicNested",
+ "pub.A.ProtectedNested.<init>",
+ "pub.A.ProtectedNested.protectedFieldProtectedNested",
+ "pub.A.ProtectedNested.publicFieldProtectedNested");
+
+ case PUBLIC:
+ checkMembersSelected("pub.A.publicFieldA",
+ "pub.A.PublicNested.<init>",
+ "pub.A.PublicNested.publicFieldPublicNested");
+
+ break;
+ }
+ }
+
+ void checkMembersAbsence(Visibility v) throws Exception {
+ switch (v) {
+ case PUBLIC:
+ checkMembersNotSelected("pub.A.protectedFieldA",
+ "pub.A.PublicNested.protectedFieldPublicNested",
+ "pub.A.ProtectedNested.<init>",
+ "pub.A.ProtectedNested.protectedFieldProtectedNested");
+
+ case PROTECTED:
+ checkMembersNotSelected("pub.A.FieldA",
+ "pub.A.PublicNested.FieldPublicNested",
+ "pub.A.ProtectedNested.FieldProtectedNested");
+
+ case PACKAGE:
+ checkMembersNotSelected("pub.A.privateFieldA",
+ "pub.A.PublicNested.privateFieldPublicNested",
+ "pub.A.ProtectedNested.privateFieldProtectedNested");
+
+ case PRIVATE:
+ break;
+ }
+ }
+
+ String createSources(Path src) throws IOException {
+ ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
+ mb1.comment("The first module.")
+ .classes(createClass("pub", "A", true))
+ .classes(createClass("pub", "B", false))
+ .classes(createClass("pro", "A", true))
+ .classes(createClass("pro", "B", false))
+ .exports("pub")
+ .write(src);
+ return src.toString();
+ }
+
+ String createClass(String pkg, String name, boolean isPublic) {
+ StringBuilder sb = new StringBuilder("package ")
+ .append(pkg)
+ .append("; ")
+ .append(NL);
+ sb.append(" /** Klass ")
+ .append(name)
+ .append(" */")
+ .append(NL);
+ sb.append(isPublic ? "public " : " ")
+ .append("class ")
+ .append(name)
+ .append(" {")
+ .append(NL);
+
+ sb.append(createMembers(INDENT, name));
+ sb.append(createNestedClass(INDENT, "PublicNested", name, "public"));
+ sb.append(createNestedClass(INDENT, "ProtectedNested", name, "protected"));
+ sb.append(createNestedClass(INDENT, "Nested", name, ""));
+ sb.append(createNestedClass(INDENT, "PrivateNested", name, "private"));
+
+ return sb.append("}").toString();
+ }
+
+ StringBuilder createNestedClass(String indent, String name, String enclosing, String visibility) {
+ return new StringBuilder()
+ .append(indent).append(" /** Klass ").append(name).append(" */").append(NL)
+ .append(indent).append(visibility).append(" class ").append(name).append(" {").append(NL)
+ .append(createMembers(indent + INDENT, name)).append(indent).append("}").append(NL);
+ }
+
+ StringBuilder createMembers(String indent, String enclosing) {
+ return new StringBuilder()
+ .append(indent).append(createMember(enclosing, "public"))
+ .append(indent).append(createMember(enclosing, "protected"))
+ .append(indent).append(createMember(enclosing, ""))
+ .append(indent).append(createMember(enclosing, "private"))
+ .append(NL);
+ }
+
+ StringBuilder createMember(String enclosingClass, String visibility) {
+ return new StringBuilder()
+ .append("/** a ")
+ .append(visibility)
+ .append("Field in ")
+ .append(enclosingClass)
+ .append(" */ ")
+ .append(visibility)
+ .append(" String ")
+ .append(visibility)
+ .append("Field")
+ .append(enclosingClass)
+ .append(";")
+ .append(NL);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/modules/ModuleTestBase.java Thu Aug 18 05:48:35 2016 -0700
@@ -0,0 +1,391 @@
+/*
+ * 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.
+ */
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.SimpleElementVisitor9;
+
+import jdk.javadoc.doclet.Doclet;
+import jdk.javadoc.doclet.DocletEnvironment;
+import jdk.javadoc.doclet.Reporter;
+
+import toolbox.JavadocTask;
+import toolbox.Task;
+import toolbox.Task.Expect;
+import toolbox.TestRunner;
+import toolbox.ToolBox;
+
+import static toolbox.Task.OutputKind.*;
+
+/**
+ * Base class for module tests.
+ */
+public class ModuleTestBase extends TestRunner {
+
+ // Field Separator
+ private static final String FS = " ";
+
+ protected ToolBox tb;
+ private final Class<?> docletClass;
+
+ private Task.Result currentTask = null;
+
+ ModuleTestBase() {
+ super(System.err);
+ tb = new ToolBox();
+ ClassLoader cl = ModuleTestBase.class.getClassLoader();
+ try {
+ docletClass = cl.loadClass("ModuleTestBase$ModulesTesterDoclet");
+ } catch (ClassNotFoundException cfe) {
+ throw new Error(cfe);
+ }
+ }
+
+ /**
+ * Execute methods annotated with @Test, and throw an exception if any
+ * errors are reported..
+ *
+ * @throws Exception if any errors occurred
+ */
+ protected void runTests() throws Exception {
+ runTests(m -> new Object[] { Paths.get(m.getName()) });
+ }
+
+ Task.Result execTask(String... args) {
+ return execTask0(false, args);
+ }
+
+ Task.Result execNegativeTask(String... args) {
+ return execTask0(true, args);
+ }
+
+ private Task.Result execTask0(boolean isNegative, String... args) {
+ JavadocTask et = new JavadocTask(tb, Task.Mode.API);
+ et.docletClass(docletClass);
+ //Arrays.asList(args).forEach((a -> System.err.println("arg: " + a)));
+ System.err.println(Arrays.asList(args));
+ currentTask = isNegative
+ ? et.options(args).run(Expect.FAIL)
+ : et.options(args).run();
+ return currentTask;
+ }
+
+ Path[] findHtmlFiles(Path... paths) throws IOException {
+ return tb.findFiles(".html", paths);
+ }
+
+ boolean grep(String regex, Path file) throws Exception {
+ List<String> lines = tb.readAllLines(file);
+ List<String> foundList = tb.grep(regex, lines);
+ return !foundList.isEmpty();
+ }
+
+ String normalize(String in) {
+ return in.replace('\\', '/');
+ }
+
+ void checkModulesSpecified(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputPresent("Specified", ElementKind.MODULE, arg);
+ }
+ }
+
+ void checkPackagesSpecified(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputPresent("Specified", ElementKind.PACKAGE, arg);
+ }
+ }
+
+ void checkTypesSpecified(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputPresent("Specified", ElementKind.CLASS, arg);
+ }
+ }
+
+ void checkModulesIncluded(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputPresent("Included", ElementKind.MODULE, arg);
+ }
+ }
+
+ void checkPackagesIncluded(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputPresent("Included", ElementKind.PACKAGE, arg);
+ }
+ }
+
+ void checkTypesIncluded(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputPresent("Included", ElementKind.CLASS, arg);
+ }
+ }
+
+ void checkMembersSelected(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputPresent("Selected", ElementKind.METHOD, arg);
+ }
+ }
+
+ void checkModuleMode(String mode) throws Exception {
+ assertPresent("^ModuleMode" + FS + mode);
+ }
+
+ void checkStringPresent(String regex) throws Exception {
+ assertPresent(regex);
+ }
+
+ void checkDocletOutputPresent(String category, ElementKind kind, String regex) throws Exception {
+ assertPresent("^" + category + " " + kind.toString() + " " + regex);
+ }
+
+ void assertPresent(String regex) throws Exception {
+ assertPresent(regex, STDOUT);
+ }
+
+ void assertErrorPresent(String regex) throws Exception {
+ assertPresent(regex, Task.OutputKind.DIRECT);
+ }
+
+ void assertPresent(String regex, Task.OutputKind kind) throws Exception {
+ List<String> foundList = tb.grep(regex, currentTask.getOutputLines(kind));
+ if (foundList.isEmpty()) {
+ dumpDocletDiagnostics();
+ throw new Exception(regex + " not found in: " + kind);
+ }
+ }
+
+ void dumpDocletDiagnostics() {
+ for (Task.OutputKind kind : Task.OutputKind.values()) {
+ String output = currentTask.getOutput(kind);
+ if (output != null && !output.isEmpty()) {
+ System.err.println("<" + kind + ">");
+ System.err.println(output);
+ }
+ }
+ }
+
+ void checkModulesNotSpecified(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputAbsent("Specified", ElementKind.MODULE, arg);
+ }
+ }
+
+ void checkPackagesNotSpecified(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputAbsent("Specified", ElementKind.PACKAGE, arg);
+ }
+ }
+
+ void checkTypesNotSpecified(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputAbsent("Specified", ElementKind.CLASS, arg);
+ }
+ }
+
+ void checkModulesNotIncluded(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputAbsent("Included", ElementKind.MODULE, arg);
+ }
+ }
+
+ void checkPackagesNotIncluded(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputAbsent("Included", ElementKind.PACKAGE, arg);
+ }
+ }
+
+ void checkTypesNotIncluded(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputAbsent("Included", ElementKind.CLASS, arg);
+ }
+ }
+
+ void checkMembersNotSelected(String... args) throws Exception {
+ for (String arg : args) {
+ checkDocletOutputAbsent("Selected", ElementKind.METHOD, arg);
+ }
+ }
+
+ void checkStringAbsent(String regex) throws Exception {
+ assertAbsent(regex);
+ }
+
+ void checkDocletOutputAbsent(String category, ElementKind kind, String regex) throws Exception {
+ assertAbsent("^" + category + FS + kind.toString() + FS + regex);
+ }
+
+ void assertAbsent(String regex) throws Exception {
+ List<String> foundList = tb.grep(regex, currentTask.getOutputLines(STDOUT));
+ if (!foundList.isEmpty()) {
+ dumpDocletDiagnostics();
+ throw new Exception(regex + " found in: " + STDOUT);
+ }
+ }
+
+ public static class ModulesTesterDoclet implements Doclet {
+ StringWriter sw = new StringWriter();
+ PrintWriter ps = new PrintWriter(sw);
+
+ // csv style output, for simple regex verification
+ void printDataSet(String header, Set<? extends Element> set) {
+ for (Element e : set) {
+ ps.print(header);
+ new SimpleElementVisitor9<Void, Void>() {
+ @Override
+ public Void visitModule(ModuleElement e, Void p) {
+ ps.print(FS);
+ ps.print(e.getKind());
+ ps.print(FS);
+ ps.println(e.getQualifiedName());
+ return null;
+ }
+
+ @Override
+ public Void visitPackage(PackageElement e, Void p) {
+ ps.print(FS);
+ ps.print(e.getKind());
+ ps.print(FS);
+ ps.println(e.getQualifiedName());
+ return null;
+ }
+
+ @Override
+ public Void visitType(TypeElement e, Void p) {
+ ps.print(FS);
+ ps.print(ElementKind.CLASS);
+ ps.print(FS);
+ ps.println(e.getQualifiedName());
+ return null;
+ }
+
+ @Override
+ protected Void defaultAction(Element e, Void p) {
+ Element encl = e.getEnclosingElement();
+ CharSequence fqn = new SimpleElementVisitor9<CharSequence, Void>() {
+ @Override
+ public CharSequence visitModule(ModuleElement e, Void p) {
+ return e.getQualifiedName();
+ }
+
+ @Override
+ public CharSequence visitType(TypeElement e, Void p) {
+ return e.getQualifiedName();
+ }
+
+ @Override
+ public CharSequence visitPackage(PackageElement e, Void p) {
+ return e.getQualifiedName();
+ }
+
+ }.visit(encl);
+
+ ps.print(FS);
+ ps.print(ElementKind.METHOD); // always METHOD
+ ps.print(FS);
+ ps.print(fqn);
+ ps.print(".");
+ ps.println(e.getSimpleName());
+ return null;
+ }
+ }.visit(e);
+ }
+ }
+
+ @Override
+ public boolean run(DocletEnvironment docenv) {
+ ps.println("ModuleMode" + FS + docenv.getModuleMode());
+ printDataSet("Specified", docenv.getSpecifiedElements());
+ printDataSet("Included", docenv.getIncludedModuleElements());
+ printDataSet("Included", docenv.getIncludedPackageElements());
+ printDataSet("Included", docenv.getIncludedTypeElements());
+ printDataSet("Selected", getAllSelectedElements(docenv));
+ System.out.println(sw);
+ return true;
+ }
+
+ Set<Element> getAllSelectedElements(DocletEnvironment docenv) {
+ Set<Element> result = new TreeSet<Element>((Element e1, Element e2) -> {
+ // some grouping by kind preferred
+ int rc = e1.getKind().compareTo(e2.getKind());
+ if (rc != 0) return rc;
+ rc = e1.toString().compareTo(e2.toString());
+ if (rc != 0) return rc;
+ return Integer.compare(e1.hashCode(), e2.hashCode());
+ });
+ for (ModuleElement me : docenv.getIncludedModuleElements()) {
+ addEnclosedElements(docenv, result, me);
+ }
+ for (PackageElement pe : docenv.getIncludedPackageElements()) {
+ addEnclosedElements(docenv, result, docenv.getElementUtils().getModuleOf(pe));
+ addEnclosedElements(docenv, result, pe);
+ }
+ for (TypeElement te : docenv.getIncludedTypeElements()) {
+ addEnclosedElements(docenv, result, te);
+ }
+ return result;
+ }
+
+ void addEnclosedElements(DocletEnvironment docenv, Set<Element> result, Element e) {
+ List<? extends Element> elems = docenv.getSelectedElements(e.getEnclosedElements());
+ result.addAll(elems);
+ for (TypeElement t : ElementFilter.typesIn(elems)) {
+ addEnclosedElements(docenv, result, t);
+ }
+ }
+
+ @Override
+ public Set<Doclet.Option> getSupportedOptions() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public void init(Locale locale, Reporter reporter) {}
+
+ @Override
+ public String getName() {
+ return "ModulesTesterDoclet";
+ }
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/modules/Modules.java Thu Aug 18 05:48:35 2016 -0700
@@ -0,0 +1,311 @@
+/*
+ * 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 8159305
+ * @summary Tests primarily the module graph computations.
+ * @modules
+ * jdk.javadoc/jdk.javadoc.internal.api
+ * jdk.javadoc/jdk.javadoc.internal.doclets.standard
+ * 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
+ * @run main Modules
+ */
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import toolbox.*;
+
+public class Modules extends ModuleTestBase {
+
+ public static void main(String... args) throws Exception {
+ new Modules().runTests();
+ }
+
+ @Test
+ public void testBasicMoption(Path base) throws Exception {
+ Files.createDirectory(base);
+ Path src = base.resolve("src");
+ ModuleBuilder mb = new ModuleBuilder(tb, "m1");
+ mb.comment("The first module.")
+ .exports("pub")
+ .classes("package pub; /** Klass A */ public class A {}")
+ .classes("package pro; /** Klass B */ public class B {}")
+ .write(src);
+ execTask("-modulesourcepath", src.toString(),
+ "--module", "m1");
+ checkModulesSpecified("m1");
+ checkPackagesIncluded("pub");
+ checkTypesIncluded("pub.A");
+ }
+
+ @Test
+ public void testMultipleModulesOption1(Path base) throws Exception {
+ Path src = base.resolve("src");
+
+ ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
+ mb1.comment("The first module.")
+ .exports("m1pub")
+ .requires("m2")
+ .classes("package m1pub; /** Klass A */ public class A {}")
+ .classes("package m1pro; /** Klass B */ public class B {}")
+ .write(src);
+
+ ModuleBuilder mb2 = new ModuleBuilder(tb, "m2");
+ mb2.comment("The second module.")
+ .exports("m2pub")
+ .classes("package m2pub; /** Klass A */ public class A {}")
+ .classes("package m2pro; /** Klass B */ public class B {}")
+ .write(src);
+ execTask("-modulesourcepath", src.toString(),
+ "--module", "m1,m2");
+ checkModulesSpecified("m1", "m2");
+ checkPackagesIncluded("m1pub", "m2pub");
+ checkTypesIncluded("m1pub.A", "m2pub.A");
+
+ }
+
+ @Test
+ public void testMultipleModulesAggregatedModuleOption(Path base) throws Exception {
+ Path src = base.resolve("src");
+
+ ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
+ mb1.comment("The first module.")
+ .exports("m1pub")
+ .requires("m2")
+ .classes("package m1pub; /** Klass A */ public class A {}")
+ .classes("package m1pro; /** Klass B */ public class B {}")
+ .write(src);
+
+ ModuleBuilder mb2 = new ModuleBuilder(tb, "m2");
+ mb2.comment("The second module.")
+ .exports("m2pub")
+ .classes("package m2pub; /** Klass A */ public class A {}")
+ .classes("package m2pro; /** Klass B */ public class B {}")
+ .write(src);
+ execTask("-modulesourcepath", src.toString(),
+ "--module", "m1",
+ "--module", "m2");
+ checkModulesSpecified("m1", "m2");
+ checkPackagesIncluded("m1pub", "m2pub");
+ checkTypesIncluded("m1pub.A", "m2pub.A");
+
+ }
+
+ /**
+ * Tests diamond graph, inspired by javac diamond tests.
+ *
+ *
+ * Module M : test module, with variable requires
+ *
+ * Module N :
+ * requires public O ---> Module O:
+ * requires J ----> Module J:
+ * exports openO exports openJ
+ *
+ *
+ * Module L :
+ * requires public P ---> Module P:
+ * exports openP
+ *
+ *
+ */
+
+ @Test
+ public void testExpandRequiresNone(Path base) throws Exception {
+ Path src = base.resolve("src");
+
+ createAuxiliaryModules(src);
+
+ new ModuleBuilder(tb, "M")
+ .comment("The M module.")
+ .requires("N", src)
+ .requires("L", src)
+ .requires("O", src)
+ .exports("p")
+ .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }")
+ .write(src);
+
+ execTask("-modulesourcepath", src.toString(),
+ "--module", "M");
+
+ checkModulesSpecified("M");
+ checkModulesIncluded("M");
+ checkPackagesIncluded("p");
+ checkTypesIncluded("p.Main");
+ checkPackagesNotIncluded(".*open.*");
+ }
+
+ @Test
+ public void testExpandRequiresPublic(Path base) throws Exception {
+ Path src = base.resolve("src");
+
+ createAuxiliaryModules(src);
+
+ new ModuleBuilder(tb, "M")
+ .comment("The M module.")
+ .requiresPublic("N", src)
+ .requires("L", src)
+ .exports("p")
+ .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }")
+ .write(src);
+
+ execTask("-modulesourcepath", src.toString(),
+ "--module", "M",
+ "--expand-requires:public");
+
+ checkModulesSpecified("M", "N", "O");
+ checkModulesIncluded("M", "N", "O");
+ checkPackagesIncluded("p", "openN", "openO");
+ checkTypesIncluded("p.Main", "openN.N", "openO.O");
+ }
+
+ @Test
+ public void testExpandRequiresAll(Path base) throws Exception {
+ Path src = base.resolve("src");
+
+ createAuxiliaryModules(src);
+
+ new ModuleBuilder(tb, "M")
+ .comment("The M module.")
+ .requiresPublic("N", src)
+ .requires("L", src)
+ .requires("O", src)
+ .exports("p")
+ .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }")
+ .write(src);
+
+ execTask("-modulesourcepath", src.toString(),
+ "--module", "M",
+ "--expand-requires:all");
+
+ checkModulesSpecified("M", "java.base", "N", "L", "O");
+ checkModulesIncluded("M", "java.base", "N", "L", "O");
+ checkModulesNotIncluded("P", "J", "Q");
+ checkPackagesIncluded("p", "openN", "openL", "openO");
+ checkPackagesNotIncluded(".*openP.*", ".*openJ.*");
+ checkTypesIncluded("p.Main", "openN.N", "openL.L", "openO.O");
+ checkTypesNotIncluded(".*openP.*", ".*openJ.*");
+ }
+
+ @Test
+ public void testMissingModule(Path base) throws Exception {
+ Path src = base.resolve("src");
+
+ createAuxiliaryModules(src);
+
+ new ModuleBuilder(tb, "M")
+ .comment("The M module.")
+ .requiresPublic("N", src)
+ .requires("L", src)
+ .requires("O", src)
+ .exports("p")
+ .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }")
+ .write(src);
+
+ execNegativeTask("-modulesourcepath", src.toString(),
+ "--module", "MIA",
+ "--expand-requires:all");
+
+ assertErrorPresent("javadoc: error - module MIA not found.");
+ }
+
+ @Test
+ public void testMissingModuleMultiModuleCmdline(Path base) throws Exception {
+ Path src = base.resolve("src");
+
+ createAuxiliaryModules(src);
+
+ new ModuleBuilder(tb, "M")
+ .comment("The M module.")
+ .requiresPublic("N", src)
+ .requires("L", src)
+ .requires("O", src)
+ .exports("p")
+ .classes("package p; public class Main { openO.O o; openN.N n; openL.L l; }")
+ .write(src);
+
+ execNegativeTask("-modulesourcepath", src.toString(),
+ "--module", "M,N,L,MIA,O,P",
+ "--expand-requires:all");
+
+ assertErrorPresent("javadoc: error - module MIA not found");
+ }
+
+ void createAuxiliaryModules(Path src) throws IOException {
+
+ new ModuleBuilder(tb, "J")
+ .comment("The J module.")
+ .exports("openJ")
+ .classes("package openJ; /** Klass J open. */ public class J { }")
+ .classes("package closedJ; /** Klass J closed. */ public class J { }")
+ .write(src);
+
+ new ModuleBuilder(tb, "L")
+ .comment("The L module.")
+ .exports("openL")
+ .requiresPublic("P")
+ .classes("package openL; /** Klass L open */ public class L { }")
+ .classes("package closedL; /** Klass L closed */ public class L { }")
+ .write(src);
+
+ new ModuleBuilder(tb, "N")
+ .comment("The N module.")
+ .exports("openN")
+ .requiresPublic("O")
+ .classes("package openN; /** Klass N open */ public class N { }")
+ .classes("package closedN; /** Klass N closed */ public class N { }")
+ .write(src);
+
+ new ModuleBuilder(tb, "O")
+ .comment("The O module.")
+ .exports("openO")
+ .requires("J")
+ .classes("package openO; /** Klass O open. */ public class O { openJ.J j; }")
+ .classes("package closedO; /** Klass O closed. */ public class O { }")
+ .write(src);
+
+ new ModuleBuilder(tb, "P")
+ .comment("The O module.")
+ .exports("openP")
+ .requires("J")
+ .classes("package openP; /** Klass O open. */ public class O { openJ.J j; }")
+ .classes("package closedP; /** Klass O closed. */ public class O { }")
+ .write(src);
+
+ new ModuleBuilder(tb, "Q")
+ .comment("The Q module.")
+ .exports("openQ")
+ .requires("J")
+ .classes("package openQ; /** Klass Q open. */ public class Q { openJ.J j; }")
+ .classes("package closedQ; /** Klass Q closed. */ public class Q { }")
+ .write(src);
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/modules/PackageOptions.java Thu Aug 18 05:48:35 2016 -0700
@@ -0,0 +1,304 @@
+/*
+ * 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 8159305
+ * @summary Test modules with packages and subpackages filtering
+ * @modules
+ * jdk.javadoc/jdk.javadoc.internal.api
+ * jdk.javadoc/jdk.javadoc.internal.doclets.standard
+ * 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
+ * @run main PackageOptions
+ */
+
+import java.io.IOException;
+import java.nio.file.DirectoryIteratorException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import toolbox.*;
+
+public class PackageOptions extends ModuleTestBase {
+
+ public static void main(String... args) throws Exception {
+ new PackageOptions().runTests();
+ }
+
+ @Test
+ public void testExportedNonQualifiedPackagesLegacyMode(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src")),
+ "-addmods", "m1",
+ "m1pub");
+
+ checkModulesNotSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesSpecified("m1pub");
+ checkPackagesIncluded("m1pub");
+ }
+
+ @Test
+ public void testExportedQualifiedPackagesLegacyMode(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src")),
+ "-addmods", "m1",
+ "m1/m1pub");
+
+ checkModulesNotSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesSpecified("m1pub");
+ checkPackagesIncluded("m1pub");
+ }
+
+ @Test
+ public void testNonExportedQualifedPackagesLegacyMode(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src")),
+ "-addmods", "m1",
+ "m1/m1pro.pro1" /* not exported, therefore qualify with module */);
+
+ checkModulesNotSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesSpecified("m1pro.pro1");
+ checkPackagesIncluded("m1pro.pro1");
+ checkPackagesNotIncluded("m1pro.pro2");
+ checkPackagesNotIncluded("m1pub");
+ }
+
+ @Test
+ public void testTypesLegacyMode(Path base) throws Exception {
+ Path srcPath = base.resolve("src");
+ Path typPath = srcPath.resolve("m1/m1pub/A.java");
+ execTask("-modulesourcepath", createSources(srcPath),
+ "-addmods", "m1",
+ typPath.toString());
+ checkModulesNotSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("m1pub");
+ checkPackagesNotIncluded("m1pro");
+ checkTypesSpecified("m1pub.A");
+ checkTypesIncluded("m1pub.A");
+ checkTypesNotIncluded("m1pub.B");
+ checkTypesNotIncluded("m1pub.C");
+ }
+
+ @Test
+ public void testSubclassedTypesLegacyMode(Path base) throws Exception {
+ Path srcPath = base.resolve("src");
+ Path typPath = srcPath.resolve("m1/m1pub/B.java");
+ execTask("-modulesourcepath", createSources(srcPath),
+ "-addmods", "m1",
+ typPath.toString());
+ checkModulesNotSpecified("m1");
+ checkModulesIncluded("m1");
+ checkPackagesIncluded("m1pub");
+ checkPackagesNotIncluded("m1pro");
+ checkTypesSpecified("m1pub.B");
+ checkTypesIncluded("m1pub.B");
+ checkTypesNotIncluded("m1pub.A");
+ checkTypesNotIncluded("m1pub.C");
+ }
+
+ @Test
+ public void testDefaultPackages(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src")),
+ "--module", "m1");
+
+ checkModulesSpecified("m1");
+
+ checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+ "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+ }
+
+ @Test
+ public void testEmptyPackageDirectory(Path base) throws Exception {
+ Path src = base.resolve("src");
+ createSources(src);
+
+ // need an empty package directory, to check whether
+ // the behavior of subpackage and package
+ Path pkgdir = src.resolve("m1/m1pro/");
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(pkgdir, "*.java")) {
+ for (Path entry : stream) {
+ Files.deleteIfExists(entry);
+ }
+ } catch (DirectoryIteratorException ex) {
+ // I/O error encounted during the iteration
+ throw ex.getCause();
+ }
+ execTask("-modulesourcepath", src.toString(),
+ "-subpackages", "m1/m1pro");
+
+ checkPackagesSpecified("m1pro", "m1pro.pro1", "m1pro.pro2");
+
+ // empty package directory should cause an error
+ execNegativeTask("-modulesourcepath", src.toString(),
+ "m1/m1pro");
+
+ }
+
+ @Test
+ public void testExportedQualifiedSubpackageWithMultipleModules(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src"), 2),
+ "--module", "m1",
+ "-subpackages", "m1/m1pro.pro1:m1/m1pro.pro2:m2/m2pub.pub1");
+
+ checkModulesSpecified("m1");
+ checkPackagesSpecified("m1pro", "m1pro.pro2");
+ checkPackagesSpecified("m2pub.pub1");
+
+ checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+ "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+ checkPackagesIncluded("m2pub.pub1");
+ }
+
+ @Test
+ public void testUnexportedUnqualifiedSubpackages(Path base) throws Exception {
+ execNegativeTask("-modulesourcepath", createSources(base.resolve("src")),
+ "--module", "m1",
+ "-subpackages", "m1pub.pub1:pro");
+
+ assertErrorPresent("javadoc: error - No source files for package pro");
+ }
+
+ @Test
+ public void testUnexportedQualifiedPackage(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src")),
+ "--module", "m1",
+ "m1/m1pro");
+
+ checkModulesSpecified("m1");
+ checkPackagesSpecified("m1pro");
+
+ checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+ "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+
+ checkTypesIncluded("m1pro.L");
+ }
+
+ @Test
+ public void testUnexportedQualifiedSubpackage(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src")),
+ "--module", "m1",
+ "-subpackages", "m1/m1pro");
+
+ checkModulesSpecified("m1");
+ checkPackagesSpecified("m1pro", "m1pro.pro1", "m1pro.pro2");
+
+ checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+ "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+
+ checkTypesIncluded("m1pro.L", "m1pro.pro1.M", "m1pro.pro2.O");
+ }
+
+ @Test
+ public void testUnexportedQualifiedSubpackageExcludeQualified(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src")),
+ "--module", "m1",
+ "-subpackages", "m1/m1pro",
+ "-exclude", "m1/m1pro.pro1.pro11:m1/m1pro.pro2.pro21");
+
+ checkModulesSpecified("m1");
+ checkPackagesSpecified("m1pro", "m1pro.pro1", "m1pro.pro2");
+
+ checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+ "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+
+ checkTypesIncluded("m1pro.L", "m1pro.pro1.M", "m1pro.pro2.O");
+ checkPackagesNotSpecified(".*pro11.*", ".*pro21.*");
+ }
+
+ @Test
+ public void testUnexportedQualifiedSubpackageExcludeUnqualified(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src")),
+ "--module", "m1",
+ "-subpackages", "m1/m1pro",
+ "-exclude", "m1pro.pro1.pro11:m1pro.pro2.pro21");
+
+ checkModulesSpecified("m1");
+ checkPackagesSpecified("m1pro", "m1pro.pro1", "m1pro.pro2");
+
+ checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+ "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+
+ checkTypesIncluded("m1pro.L", "m1pro.pro1.M", "m1pro.pro2.O");
+ checkPackagesNotSpecified(".*pro11.*", ".*pro21.*");
+ }
+
+ @Test
+ public void testUnexportedQualifiedSubpackages(Path base) throws Exception {
+ execTask("-modulesourcepath", createSources(base.resolve("src")),
+ "--module", "m1",
+ "-subpackages", "m1/m1pro.pro1:m1/m1pro.pro2");
+
+ checkModulesSpecified("m1");
+ checkPackagesSpecified("m1pro.pro1.pro11");
+
+ checkPackagesIncluded("m1pub", "m1pub.pub1", "m1pub.pub1.pub11",
+ "m1pub.pub1.pub12", "m1pub.pub2.pub21");
+ checkTypesIncluded("m1pro.pro1.pro11.N", "m1pro.pro2.pro21.P");
+ checkTypesNotIncluded("m1pro.L");
+ }
+
+ String createSources(Path src) throws IOException {
+ return createSources0(src, 1);
+ }
+
+ String createSources(Path src, int n) throws IOException {
+ for (int i = 1 ; i <= n ; i++) {
+ createSources0(src, i);
+ }
+ return src.toString();
+ }
+
+ String createSources0(Path src, int n) throws IOException {
+ String mn = "m" + n;
+ String pn = "package " + mn;
+
+ ModuleBuilder mb1 = new ModuleBuilder(tb, mn);
+ mb1.comment("The module #" + n)
+ .classes(pn + "pub; /** Klass A */ public class A {}")
+ .classes(pn + "pub; /** Klass B */ public class B extends A{}")
+ .classes(pn + "pub; /** Klass C */ public class C {}")
+ .classes(pn + "pub;")
+ .classes(pn + "pub.pub1; /** Klass B */ public class B {}")
+ .classes(pn + "pub.pub1.pub11; /** Klass C */ public class C {}")
+ .classes(pn + "pub.pub1.pub12; /** Klass C */ public class C {}")
+ .classes(pn + "pub.pub2.pub21; /** Klass C */ public class C {}")
+ .classes(pn + "pro; /** Klass L */ public class L {}")
+ .classes(pn + "pro.pro1; /** Klass M */ public class M {}")
+ .classes(pn + "pro.pro1.pro11; /** Klass N */ public class N {}")
+ .classes(pn + "pro.pro2; /** Klass O */ public class O {}")
+ .classes(pn + "pro.pro2.pro21; /** Klass P */ public class P {}")
+ .exports(mn + "pub")
+ .exports(mn + "pub.pub1")
+ .exports(mn + "pub.pub1.pub11")
+ .exports(mn + "pub.pub1.pub12")
+ .exports(mn + "pub.pub2.pub21")
+ .write(src);
+ return src.toString();
+ }
+}
--- a/langtools/test/jdk/javadoc/tool/sourceOnly/Test.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/sourceOnly/Test.java Thu Aug 18 05:48:35 2016 -0700
@@ -34,7 +34,12 @@
public class Test {
public static void main(String[] args) {
// run javadoc on package p
- if (jdk.javadoc.internal.tool.Main.execute("javadoc", "p.SourceOnly", "p") != 0)
+ String[] jdargs = {
+ "-doclet", "p.SourceOnly",
+ "-docletpath", System.getProperty("test.classes", "."),
+ "p"
+ };
+ if (jdk.javadoc.internal.tool.Main.execute(jdargs) != 0)
throw new Error();
}
}
Binary file langtools/test/jdk/javadoc/tool/sourceOnly/p/NonSource.class has changed
--- a/langtools/test/jdk/javadoc/tool/sourceOnly/p/SourceOnly.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/sourceOnly/p/SourceOnly.java Thu Aug 18 05:48:35 2016 -0700
@@ -39,11 +39,12 @@
*/
public class SourceOnly implements Doclet {
NonSource dependency; // force a compilation error if not on classpath.
+
@Override
public boolean run(DocletEnvironment root) {
- if (root.getIncludedClasses().size() != 1)
+ if (root.getIncludedTypeElements().size() != 1)
throw new Error("wrong set of classes documented: " +
- Arrays.asList(root.getIncludedClasses()));
+ Arrays.asList(root.getIncludedTypeElements()));
return true;
}
--- a/langtools/test/jdk/javadoc/tool/sourceOption/SourceOption.java Wed Aug 17 10:34:48 2016 +0530
+++ b/langtools/test/jdk/javadoc/tool/sourceOption/SourceOption.java Thu Aug 18 05:48:35 2016 -0700
@@ -92,7 +92,7 @@
}
public boolean run(DocletEnvironment root) {
- root.getIncludedClasses(); // force parser into action
+ root.getIncludedTypeElements();
return true;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/tool/subpackageIgnore/pkg1/ValidFile.java Thu Aug 18 05:48:35 2016 -0700
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+
+package pkg1;
+
+/**
+ * This file exists simply to ensure that javadoc passes
+ * without complaining about empty directory.
+ */
+public class ValidFile {}