8178070: duplicate entries in package table
Reviewed-by: bpatel, ksrini
This commit is contained in:
parent
be25eb7f0e
commit
5bcb718441
@ -96,6 +96,7 @@ public class Contents {
|
||||
public final Content errors;
|
||||
public final Content exception;
|
||||
public final Content exceptions;
|
||||
public final Content exportedTo;
|
||||
public final Content fieldLabel;
|
||||
public final Content fieldDetailsLabel;
|
||||
public final Content fieldSummaryLabel;
|
||||
@ -147,6 +148,7 @@ public class Contents {
|
||||
public final Content noFramesLabel;
|
||||
public final Content noScriptMessage;
|
||||
public final Content openModuleLabel;
|
||||
public final Content openedTo;
|
||||
public final Content overridesLabel;
|
||||
public final Content overviewLabel;
|
||||
public final Content packageHierarchies;
|
||||
@ -229,6 +231,7 @@ public class Contents {
|
||||
errors = getContent("doclet.Errors");
|
||||
exception = getContent("doclet.Exception");
|
||||
exceptions = getContent("doclet.Exceptions");
|
||||
exportedTo = getContent("doclet.ExportedTo");
|
||||
fieldDetailsLabel = getContent("doclet.Field_Detail");
|
||||
fieldSummaryLabel = getContent("doclet.Field_Summary");
|
||||
fieldLabel = getContent("doclet.Field");
|
||||
@ -279,6 +282,7 @@ public class Contents {
|
||||
nextPackageLabel = getNonBreakContent("doclet.Next_Package");
|
||||
noFramesLabel = getNonBreakContent("doclet.No_Frames");
|
||||
noScriptMessage = getContent("doclet.No_Script_Message");
|
||||
openedTo = getContent("doclet.OpenedTo");
|
||||
openModuleLabel = getContent("doclet.Open_Module");
|
||||
overridesLabel = getContent("doclet.Overrides");
|
||||
overviewLabel = getContent("doclet.Overview");
|
||||
|
@ -106,21 +106,34 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||
= new TreeMap<>(utils.makeModuleComparator());
|
||||
|
||||
/**
|
||||
* Map of packages exported by this module and the modules it has been exported to.
|
||||
* Details about a package in a module.
|
||||
* A package may be not exported, or exported to some modules, or exported to all modules.
|
||||
* A package may be not opened, or opened to some modules, or opened to all modules.
|
||||
* A package that is neither exported or opened to any modules is a concealed package.
|
||||
* An open module opens all its packages to all modules.
|
||||
*/
|
||||
private final Map<PackageElement, SortedSet<ModuleElement>> exportedPackages
|
||||
= new TreeMap<>(utils.makePackageComparator());
|
||||
class PackageEntry {
|
||||
/**
|
||||
* Summary of package exports:
|
||||
* If null, the package is not exported to any modules;
|
||||
* if empty, the package is exported to all modules;
|
||||
* otherwise, the package is exported to these modules.
|
||||
*/
|
||||
Set<ModuleElement> exportedTo;
|
||||
|
||||
/**
|
||||
* Summary of package opens:
|
||||
* If null, the package is not opened to any modules;
|
||||
* if empty, the package is opened to all modules;
|
||||
* otherwise, the package is opened to these modules.
|
||||
*/
|
||||
Set<ModuleElement> openedTo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map of opened packages by this module and the modules it has been opened to.
|
||||
* Map of packages of this module, and details of whether they are exported or opened.
|
||||
*/
|
||||
private final Map<PackageElement, SortedSet<ModuleElement>> openedPackages
|
||||
= new TreeMap<>(utils.makePackageComparator());
|
||||
|
||||
/**
|
||||
* Set of concealed packages of this module.
|
||||
*/
|
||||
private final SortedSet<PackageElement> concealedPackages = new TreeSet<>(utils.makePackageComparator());
|
||||
private final Map<PackageElement, PackageEntry> packages = new TreeMap<>(utils.makePackageComparator());
|
||||
|
||||
/**
|
||||
* Map of indirect modules (transitive closure) and their exported packages.
|
||||
@ -284,51 +297,52 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||
}
|
||||
});
|
||||
|
||||
// Get all packages for the module and put it in the concealed packages set.
|
||||
utils.getModulePackageMap().getOrDefault(mdle, Collections.emptySet()).forEach((pkg) -> {
|
||||
if (shouldDocument(pkg) && moduleMode == ModuleMode.ALL) {
|
||||
concealedPackages.add(pkg);
|
||||
// Get all packages if module is open or if displaying concealed modules
|
||||
for (PackageElement pkg : utils.getModulePackageMap().getOrDefault(mdle, Collections.emptySet())) {
|
||||
if (shouldDocument(pkg) && (mdle.isOpen() || moduleMode == ModuleMode.ALL)) {
|
||||
PackageEntry e = new PackageEntry();
|
||||
if (mdle.isOpen()) {
|
||||
e.openedTo = Collections.emptySet();
|
||||
}
|
||||
packages.put(pkg, e);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Get all exported packages for the module using the exports directive for the module.
|
||||
(ElementFilter.exportsIn(mdle.getDirectives())).forEach((directive) -> {
|
||||
// Get all exported packages for the module, using the exports directive for the module.
|
||||
for (ModuleElement.ExportsDirective directive : ElementFilter.exportsIn(mdle.getDirectives())) {
|
||||
PackageElement p = directive.getPackage();
|
||||
if (shouldDocument(p)) {
|
||||
SortedSet<ModuleElement> mdleList = new TreeSet<>(utils.makeModuleComparator());
|
||||
List<? extends ModuleElement> targetMdles = directive.getTargetModules();
|
||||
if (targetMdles != null) {
|
||||
mdleList.addAll(targetMdles);
|
||||
}
|
||||
// Qualified exports should not be displayed in the api mode. So if mdleList is empty,
|
||||
// its exported to all modules and hence can be added.
|
||||
if (moduleMode == ModuleMode.ALL || mdleList.isEmpty()) {
|
||||
exportedPackages.put(p, mdleList);
|
||||
}
|
||||
if (moduleMode == ModuleMode.ALL) {
|
||||
concealedPackages.remove(p);
|
||||
// Include package if in details mode, or exported to all (i.e. targetModules == null)
|
||||
if (moduleMode == ModuleMode.ALL || targetMdles == null) {
|
||||
PackageEntry packageEntry = packages.computeIfAbsent(p, pkg -> new PackageEntry());
|
||||
SortedSet<ModuleElement> mdleList = new TreeSet<>(utils.makeModuleComparator());
|
||||
if (targetMdles != null) {
|
||||
mdleList.addAll(targetMdles);
|
||||
}
|
||||
packageEntry.exportedTo = mdleList;
|
||||
}
|
||||
}
|
||||
});
|
||||
// Get all opened packages for the module using the opens directive for the module.
|
||||
(ElementFilter.opensIn(mdle.getDirectives())).forEach((directive) -> {
|
||||
}
|
||||
|
||||
// Get all opened packages for the module, using the opens directive for the module.
|
||||
// If it is an open module, there will be no separate opens directives.
|
||||
for (ModuleElement.OpensDirective directive : ElementFilter.opensIn(mdle.getDirectives())) {
|
||||
PackageElement p = directive.getPackage();
|
||||
if (shouldDocument(p)) {
|
||||
SortedSet<ModuleElement> mdleList = new TreeSet<>(utils.makeModuleComparator());
|
||||
List<? extends ModuleElement> targetMdles = directive.getTargetModules();
|
||||
if (targetMdles != null) {
|
||||
mdleList.addAll(targetMdles);
|
||||
}
|
||||
// Qualified opens should not be displayed in the api mode. So if mdleList is empty,
|
||||
// it is opened to all modules and hence can be added.
|
||||
if (moduleMode == ModuleMode.ALL || mdleList.isEmpty()) {
|
||||
openedPackages.put(p, mdleList);
|
||||
}
|
||||
if (moduleMode == ModuleMode.ALL) {
|
||||
concealedPackages.remove(p);
|
||||
// Include package if in details mode, or opened to all (i.e. targetModules == null)
|
||||
if (moduleMode == ModuleMode.ALL || targetMdles == null) {
|
||||
PackageEntry packageEntry = packages.computeIfAbsent(p, pkg -> new PackageEntry());
|
||||
SortedSet<ModuleElement> mdleList = new TreeSet<>(utils.makeModuleComparator());
|
||||
if (targetMdles != null) {
|
||||
mdleList.addAll(targetMdles);
|
||||
}
|
||||
packageEntry.openedTo = mdleList;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Get all the exported and opened packages, for the transitive closure of the module, to be displayed in
|
||||
// the indirect packages tables.
|
||||
dependentModules.forEach((module, mod) -> {
|
||||
@ -348,15 +362,19 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||
indirectPackages.put(module, exportPkgList);
|
||||
}
|
||||
SortedSet<PackageElement> openPkgList = new TreeSet<>(utils.makePackageComparator());
|
||||
(ElementFilter.opensIn(module.getDirectives())).forEach((directive) -> {
|
||||
PackageElement pkg = directive.getPackage();
|
||||
if (shouldDocument(pkg)) {
|
||||
// Qualified opens are not displayed in API mode
|
||||
if (moduleMode == ModuleMode.ALL || directive.getTargetModules() == null) {
|
||||
openPkgList.add(pkg);
|
||||
if (module.isOpen()) {
|
||||
openPkgList.addAll(utils.getModulePackageMap().getOrDefault(module, Collections.emptySet()));
|
||||
} else {
|
||||
(ElementFilter.opensIn(module.getDirectives())).forEach((directive) -> {
|
||||
PackageElement pkg = directive.getPackage();
|
||||
if (shouldDocument(pkg)) {
|
||||
// Qualified opens are not displayed in API mode
|
||||
if (moduleMode == ModuleMode.ALL || directive.getTargetModules() == null) {
|
||||
openPkgList.add(pkg);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
// If none of the indirect modules have opened packages to be displayed, we should not be
|
||||
// displaying the table and so it should not be added to the map.
|
||||
if (!openPkgList.isEmpty()) {
|
||||
@ -556,13 +574,13 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||
|
||||
@Override
|
||||
public void addPackagesSummary(Content summaryContentTree) {
|
||||
if (display(exportedPackages) || display(openedPackages) || display(concealedPackages)
|
||||
if (display(packages)
|
||||
|| display(indirectPackages) || display(indirectOpenPackages)) {
|
||||
HtmlTree li = new HtmlTree(HtmlTag.LI);
|
||||
li.setStyle(HtmlStyle.blockList);
|
||||
addSummaryHeader(HtmlConstants.START_OF_PACKAGES_SUMMARY, SectionName.PACKAGES,
|
||||
contents.navPackages, li);
|
||||
if (display(exportedPackages) || display(openedPackages) || display(concealedPackages)) {
|
||||
if (display(packages)) {
|
||||
String tableSummary = resources.getText("doclet.Member_Table_Summary",
|
||||
resources.getText("doclet.Packages_Summary"),
|
||||
resources.getText("doclet.packages"));
|
||||
@ -607,77 +625,115 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||
Table table = new Table(configuration.htmlVersion, HtmlStyle.packagesSummary)
|
||||
.setSummary(tableSummary)
|
||||
.setDefaultTab(resources.getText("doclet.All_Packages"))
|
||||
.addTab(resources.getText("doclet.Exported_Packages_Summary"),
|
||||
e -> exportedPackages.containsKey((PackageElement) e))
|
||||
.addTab(resources.getText("doclet.Opened_Packages_Summary"),
|
||||
e -> openedPackages.containsKey((PackageElement) e))
|
||||
.addTab(resources.getText("doclet.Concealed_Packages_Summary"),
|
||||
e -> concealedPackages.contains((PackageElement) e))
|
||||
.addTab(resources.getText("doclet.Exported_Packages_Summary"), this::isExported)
|
||||
.addTab(resources.getText("doclet.Opened_Packages_Summary"), this::isOpened)
|
||||
.addTab(resources.getText("doclet.Concealed_Packages_Summary"), this::isConcealed)
|
||||
.setTabScript(i -> String.format("showPkgs(%d);", i))
|
||||
.setTabScriptVariable("packages");
|
||||
|
||||
if (configuration.docEnv.getModuleMode() == ModuleMode.API) {
|
||||
table.setHeader(new TableHeader(contents.packageLabel, contents.descriptionLabel))
|
||||
.setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colLast);
|
||||
} else {
|
||||
table.setHeader(new TableHeader(contents.packageLabel, contents.moduleLabel, contents.descriptionLabel))
|
||||
.setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colSecond, HtmlStyle.colLast);
|
||||
// Determine whether to show the "Exported To" and "Opened To" columns,
|
||||
// based on whether such columns would provide "useful" info.
|
||||
int numExports = 0;
|
||||
int numUnqualifiedExports = 0;
|
||||
int numOpens = 0;
|
||||
int numUnqualifiedOpens = 0;
|
||||
|
||||
for (PackageEntry e : packages.values()) {
|
||||
if (e.exportedTo != null) {
|
||||
numExports++;
|
||||
if (e.exportedTo.isEmpty()) {
|
||||
numUnqualifiedExports++;
|
||||
}
|
||||
}
|
||||
if (e.openedTo != null) {
|
||||
numOpens++;
|
||||
if (e.openedTo.isEmpty()) {
|
||||
numUnqualifiedOpens++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean showExportedTo = numExports > 0 && (numOpens > 0 || numUnqualifiedExports < packages.size());
|
||||
boolean showOpenedTo = numOpens > 0 && (numExports > 0 || numUnqualifiedOpens < packages.size());
|
||||
|
||||
// Create the table header and column styles.
|
||||
List<Content> colHeaders = new ArrayList<>();
|
||||
List<HtmlStyle> colStyles = new ArrayList<>();
|
||||
colHeaders.add(contents.packageLabel);
|
||||
colStyles.add(HtmlStyle.colFirst);
|
||||
|
||||
if (showExportedTo) {
|
||||
colHeaders.add(contents.exportedTo);
|
||||
colStyles.add(HtmlStyle.colSecond);
|
||||
}
|
||||
|
||||
if (showOpenedTo) {
|
||||
colHeaders.add(contents.openedTo);
|
||||
colStyles.add(HtmlStyle.colSecond);
|
||||
}
|
||||
|
||||
colHeaders.add(contents.descriptionLabel);
|
||||
colStyles.add(HtmlStyle.colLast);
|
||||
|
||||
table.setHeader(new TableHeader(colHeaders).styles(colStyles))
|
||||
.setColumnStyles(colStyles);
|
||||
|
||||
// Add the table rows, based on the "packages" map.
|
||||
for (Map.Entry<PackageElement, PackageEntry> e : packages.entrySet()) {
|
||||
PackageElement pkg = e.getKey();
|
||||
PackageEntry entry = e.getValue();
|
||||
List<Content> row = new ArrayList<>();
|
||||
Content pkgLinkContent = getPackageLink(pkg, new StringContent(utils.getPackageName(pkg)));
|
||||
row.add(pkgLinkContent);
|
||||
|
||||
if (showExportedTo) {
|
||||
row.add(getPackageExportOpensTo(entry.exportedTo));
|
||||
}
|
||||
if (showOpenedTo) {
|
||||
row.add(getPackageExportOpensTo(entry.openedTo));
|
||||
}
|
||||
Content summary = new ContentBuilder();
|
||||
addSummaryComment(pkg, summary);
|
||||
row.add(summary);
|
||||
|
||||
table.addRow(pkg, row);
|
||||
}
|
||||
|
||||
addPackageTableRows(table);
|
||||
li.addContent(table.toContent());
|
||||
if (table.needsScript()) {
|
||||
mainBodyScript.append(table.getScript());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the package table rows.
|
||||
*
|
||||
* @return a content object
|
||||
*/
|
||||
private void addPackageTableRows(Table table) {
|
||||
addPackageTableRows(table, exportedPackages);
|
||||
addPackageTableRows(table, openedPackages);
|
||||
// Show concealed packages only in "all" mode.
|
||||
if (moduleMode == ModuleMode.ALL) {
|
||||
for (PackageElement pkg : concealedPackages) {
|
||||
Content pkgLinkContent = getPackageLink(pkg, new StringContent(utils.getPackageName(pkg)));
|
||||
Content noModules = new StringContent(resources.getText("doclet.None"));
|
||||
Content summary = new ContentBuilder();
|
||||
addSummaryComment(pkg, summary);
|
||||
table.addRow(pkg, pkgLinkContent, noModules, summary);
|
||||
}
|
||||
}
|
||||
private boolean isExported(Element e) {
|
||||
PackageEntry entry = packages.get((PackageElement) e);
|
||||
return (entry != null) && (entry.exportedTo != null);
|
||||
}
|
||||
|
||||
private void addPackageTableRows(Table table, Map<PackageElement,SortedSet<ModuleElement>> ap) {
|
||||
for (Map.Entry<PackageElement, SortedSet<ModuleElement>> entry : ap.entrySet()) {
|
||||
List<Content> row = new ArrayList<>();
|
||||
PackageElement pkg = entry.getKey();
|
||||
SortedSet<ModuleElement> mdleList = entry.getValue();
|
||||
Content pkgLinkContent = getPackageLink(pkg, new StringContent(utils.getPackageName(pkg)));
|
||||
row.add(pkgLinkContent);
|
||||
private boolean isOpened(Element e) {
|
||||
PackageEntry entry = packages.get((PackageElement) e);
|
||||
return (entry != null) && (entry.openedTo != null);
|
||||
}
|
||||
|
||||
if (moduleMode == ModuleMode.ALL) {
|
||||
Content modules = new ContentBuilder();
|
||||
if (!mdleList.isEmpty()) {
|
||||
for (ModuleElement m : mdleList) {
|
||||
if (!modules.isEmpty()) {
|
||||
modules.addContent(new HtmlTree(HtmlTag.BR));
|
||||
}
|
||||
modules.addContent(getModuleLink(m, new StringContent(m.getQualifiedName())));
|
||||
}
|
||||
} else {
|
||||
Content allModules = new StringContent(resources.getText("doclet.All_Modules"));
|
||||
modules.addContent(allModules);
|
||||
private boolean isConcealed(Element e) {
|
||||
PackageEntry entry = packages.get((PackageElement) e);
|
||||
return (entry != null) && (entry.exportedTo == null) && (entry.openedTo == null);
|
||||
}
|
||||
|
||||
private Content getPackageExportOpensTo(Set<ModuleElement> modules) {
|
||||
if (modules == null) {
|
||||
return new StringContent(resources.getText("doclet.None"));
|
||||
} else if (modules.isEmpty()) {
|
||||
return new StringContent(resources.getText("doclet.All_Modules"));
|
||||
} else {
|
||||
Content list = new ContentBuilder();
|
||||
for (ModuleElement m : modules) {
|
||||
if (!list.isEmpty()) {
|
||||
list.addContent(new StringContent(", "));
|
||||
}
|
||||
row.add(modules);
|
||||
list.addContent(getModuleLink(m, new StringContent(m.getQualifiedName())));
|
||||
}
|
||||
Content summary = new ContentBuilder();
|
||||
addSummaryComment(pkg, summary);
|
||||
row.add(summary);
|
||||
table.addRow(pkg, row);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
@ -692,14 +748,14 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||
ModuleElement m = entry.getKey();
|
||||
SortedSet<PackageElement> pkgList = entry.getValue();
|
||||
Content moduleLinkContent = getModuleLink(m, new StringContent(m.getQualifiedName()));
|
||||
Content packages = new ContentBuilder();
|
||||
Content list = new ContentBuilder();
|
||||
String sep = "";
|
||||
for (PackageElement pkg : pkgList) {
|
||||
packages.addContent(sep);
|
||||
packages.addContent(getPackageLink(pkg, new StringContent(utils.getPackageName(pkg))));
|
||||
list.addContent(sep);
|
||||
list.addContent(getPackageLink(pkg, new StringContent(utils.getPackageName(pkg))));
|
||||
sep = " ";
|
||||
}
|
||||
table.addRow(moduleLinkContent, packages);
|
||||
table.addRow(moduleLinkContent, list);
|
||||
}
|
||||
}
|
||||
|
||||
@ -898,7 +954,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||
? Links.createLink(SectionName.MODULES, contents.navModules)
|
||||
: contents.navModules);
|
||||
addNavGap(liNav);
|
||||
liNav.addContent((display(exportedPackages) || display(openedPackages) || display(concealedPackages)
|
||||
liNav.addContent((display(packages)
|
||||
|| display(indirectPackages) || display(indirectOpenPackages))
|
||||
? Links.createLink(SectionName.PACKAGES, contents.navPackages)
|
||||
: contents.navPackages);
|
||||
|
@ -76,6 +76,14 @@ public class TableHeader {
|
||||
this.cellContents = Arrays.asList(headerCellContents);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a header row, with specified content for each cell.
|
||||
* @param headerCellContents a content object for each header cell
|
||||
*/
|
||||
public TableHeader(List<Content> headerCellContents) {
|
||||
this.cellContents = headerCellContents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the style class names for each header cell.
|
||||
* The number of names must match the number of cells given to the constructor.
|
||||
@ -90,6 +98,20 @@ public class TableHeader {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the style class names for each header cell.
|
||||
* The number of names must match the number of cells given to the constructor.
|
||||
* @param styles the style class names
|
||||
* @return this object
|
||||
*/
|
||||
public TableHeader styles(List<HtmlStyle> styles) {
|
||||
if (styles.size() != cellContents.size()) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
this.styles = styles;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this header to a {@link Content} object, for use in an {@link HtmlTree}.
|
||||
* @return a Content object
|
||||
|
@ -145,6 +145,8 @@ doclet.errors=errors
|
||||
doclet.Exception=Exception
|
||||
doclet.exception=exception
|
||||
doclet.exceptions=exceptions
|
||||
doclet.ExportedTo=Exported To Modules
|
||||
doclet.OpenedTo=Opened To Modules
|
||||
doclet.Package_private=(package private)
|
||||
doclet.Nested_Classes_Interfaces_Inherited_From_Class=Nested classes/interfaces inherited from class
|
||||
doclet.Nested_Classes_Interfaces_Inherited_From_Interface=Nested classes/interfaces inherited from interface
|
||||
|
@ -236,6 +236,9 @@ public abstract class JavadocTester {
|
||||
/** The current run of javadoc. Incremented when javadoc is called. */
|
||||
private int javadocRunNum = 0;
|
||||
|
||||
/** The current subtest number for this run of javadoc. Incremented when checking(...) is called. */
|
||||
private int javadocTestNum = 0;
|
||||
|
||||
/** Marker annotation for test methods to be invoked by runTests. */
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface Test { }
|
||||
@ -295,11 +298,11 @@ public abstract class JavadocTester {
|
||||
fileContentCache.clear();
|
||||
|
||||
javadocRunNum++;
|
||||
javadocTestNum = 0; // reset counter for this run of javadoc
|
||||
if (javadocRunNum == 1) {
|
||||
out.println("Running javadoc...");
|
||||
} else {
|
||||
out.println("Running javadoc (run "
|
||||
+ javadocRunNum + ")...");
|
||||
out.println("Running javadoc (run "+ javadocRunNum + ")...");
|
||||
}
|
||||
|
||||
outputDir = new File(".");
|
||||
@ -441,8 +444,7 @@ public abstract class JavadocTester {
|
||||
* Check for content in (or not in) the generated output.
|
||||
* Within the search strings, the newline character \n
|
||||
* will be translated to the platform newline character sequence.
|
||||
* @param path a path within the most recent output directory
|
||||
* or the name of one of the output buffers, identifying
|
||||
* @param path a path within the most recent output directory, identifying
|
||||
* where to look for the search strings.
|
||||
* @param expectedFound true if all of the search strings are expected
|
||||
* to be found, or false if all of the strings are expected to be
|
||||
@ -451,15 +453,13 @@ public abstract class JavadocTester {
|
||||
*/
|
||||
public void checkOutput(String path, boolean expectedFound, String... strings) {
|
||||
// Read contents of file
|
||||
String fileString;
|
||||
try {
|
||||
fileString = readFile(outputDir, path);
|
||||
String fileString = readFile(outputDir, path);
|
||||
checkOutput(new File(outputDir, path).getPath(), fileString, expectedFound, strings);
|
||||
} catch (Error e) {
|
||||
checking("Read file");
|
||||
failed("Error reading file: " + e);
|
||||
return;
|
||||
}
|
||||
checkOutput(path, fileString, expectedFound, strings);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -476,6 +476,7 @@ public abstract class JavadocTester {
|
||||
checkOutput(output.toString(), outputMap.get(output), expectedFound, strings);
|
||||
}
|
||||
|
||||
// NOTE: path may be the name of an Output stream as well as a file path
|
||||
private void checkOutput(String path, String fileString, boolean expectedFound, String... strings) {
|
||||
for (String stringToFind : strings) {
|
||||
// log.logCheckOutput(path, expectedFound, stringToFind);
|
||||
@ -484,25 +485,27 @@ public abstract class JavadocTester {
|
||||
boolean isFound = findString(fileString, stringToFind);
|
||||
if (isFound == expectedFound) {
|
||||
passed(path + ": following text " + (isFound ? "found:" : "not found:") + "\n"
|
||||
+ stringToFind + "\n");
|
||||
+ stringToFind);
|
||||
} else {
|
||||
failed(path + ": following text " + (isFound ? "found:" : "not found:") + "\n"
|
||||
+ stringToFind + "\n");
|
||||
+ stringToFind);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content of the one of the output streams written by
|
||||
* javadoc.
|
||||
* Get the content of the one of the output streams written by javadoc.
|
||||
* @param output the name of the output stream
|
||||
* @return the content of the output stream
|
||||
*/
|
||||
public String getOutput(Output output) {
|
||||
return outputMap.get(output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content of the one of the output streams written by
|
||||
* javadoc.
|
||||
* Get the content of the one of the output streams written by javadoc.
|
||||
* @param output the name of the output stream
|
||||
* @return the content of the output stream, as a line of lines
|
||||
*/
|
||||
public List<String> getOutputLines(Output output) {
|
||||
String text = outputMap.get(output);
|
||||
@ -534,9 +537,9 @@ public abstract class JavadocTester {
|
||||
File file = new File(outputDir, path);
|
||||
boolean isFound = file.exists();
|
||||
if (isFound == expectedFound) {
|
||||
passed(path + ": file " + (isFound ? "found:" : "not found:") + "\n");
|
||||
passed(file, "file " + (isFound ? "found:" : "not found:") + "\n");
|
||||
} else {
|
||||
failed(path + ": file " + (isFound ? "found:" : "not found:") + "\n");
|
||||
failed(file, "file " + (isFound ? "found:" : "not found:") + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -548,20 +551,21 @@ public abstract class JavadocTester {
|
||||
* @param strings the strings whose order to check
|
||||
*/
|
||||
public void checkOrder(String path, String... strings) {
|
||||
File file = new File(outputDir, path);
|
||||
String fileString = readOutputFile(path);
|
||||
int prevIndex = -1;
|
||||
for (String s : strings) {
|
||||
s = s.replace("\n", NL); // normalize new lines
|
||||
int currentIndex = fileString.indexOf(s, prevIndex + 1);
|
||||
checking(s + " at index " + currentIndex);
|
||||
checking("file: " + file + ": " + s + " at index " + currentIndex);
|
||||
if (currentIndex == -1) {
|
||||
failed(s + " not found.");
|
||||
failed(file, s + " not found.");
|
||||
continue;
|
||||
}
|
||||
if (currentIndex > prevIndex) {
|
||||
passed(s + " is in the correct order");
|
||||
passed(file, s + " is in the correct order");
|
||||
} else {
|
||||
failed("file: " + path + ": " + s + " is in the wrong order.");
|
||||
failed(file, s + " is in the wrong order.");
|
||||
}
|
||||
prevIndex = currentIndex;
|
||||
}
|
||||
@ -575,19 +579,20 @@ public abstract class JavadocTester {
|
||||
* @param strings ensure each are unique
|
||||
*/
|
||||
public void checkUnique(String path, String... strings) {
|
||||
File file = new File(outputDir, path);
|
||||
String fileString = readOutputFile(path);
|
||||
for (String s : strings) {
|
||||
int currentIndex = fileString.indexOf(s);
|
||||
checking(s + " at index " + currentIndex);
|
||||
if (currentIndex == -1) {
|
||||
failed(s + " not found.");
|
||||
failed(file, s + " not found.");
|
||||
continue;
|
||||
}
|
||||
int nextindex = fileString.indexOf(s, currentIndex + s.length());
|
||||
if (nextindex == -1) {
|
||||
passed(s + " is unique");
|
||||
passed(file, s + " is unique");
|
||||
} else {
|
||||
failed(s + " is not unique, found at " + nextindex);
|
||||
failed(file, s + " is not unique, found at " + nextindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -702,16 +707,35 @@ public abstract class JavadocTester {
|
||||
|
||||
protected void checking(String message) {
|
||||
numTestsRun++;
|
||||
print("Starting subtest " + numTestsRun, message);
|
||||
javadocTestNum++;
|
||||
print("Starting subtest " + javadocRunNum + "." + javadocTestNum, message);
|
||||
}
|
||||
|
||||
protected void passed(File file, String message) {
|
||||
passed(file + ": " + message);
|
||||
}
|
||||
|
||||
protected void passed(String message) {
|
||||
numTestsPassed++;
|
||||
print("Passed", message);
|
||||
out.println();
|
||||
}
|
||||
|
||||
protected void failed(File file, String message) {
|
||||
failed(file + ": " + message);
|
||||
}
|
||||
|
||||
protected void failed(String message) {
|
||||
print("FAILED", message);
|
||||
StackWalker.getInstance().walk(s -> {
|
||||
s.dropWhile(f -> f.getMethodName().equals("failed"))
|
||||
.takeWhile(f -> !f.getMethodName().equals("runTests"))
|
||||
.forEach(f -> out.println(" at "
|
||||
+ f.getClassName() + "." + f.getMethodName()
|
||||
+ "(" + f.getFileName() + ":" + f.getLineNumber() + ")"));
|
||||
return null;
|
||||
});
|
||||
out.println();
|
||||
}
|
||||
|
||||
private void print(String prefix, String message) {
|
||||
@ -720,7 +744,10 @@ public abstract class JavadocTester {
|
||||
else {
|
||||
out.print(prefix);
|
||||
out.print(": ");
|
||||
out.println(message.replace("\n", NL));
|
||||
out.print(message.replace("\n", NL));
|
||||
if (!(message.endsWith("\n") || message.endsWith(NL))) {
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,486 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2017, 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 8178070
|
||||
* @summary Test packages table in module summary pages
|
||||
* @library /tools/lib ../lib
|
||||
* @modules jdk.javadoc/jdk.javadoc.internal.tool
|
||||
* @build toolbox.ModuleBuilder toolbox.ToolBox JavadocTester
|
||||
* @run main TestModulePackages
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Set;
|
||||
|
||||
import toolbox.ModuleBuilder;
|
||||
import toolbox.ToolBox;
|
||||
|
||||
public class TestModulePackages extends JavadocTester {
|
||||
enum TabKind { EXPORTS, OPENS, CONCEALED };
|
||||
enum ColKind { EXPORTED_TO, OPENED_TO };
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
TestModulePackages tester = new TestModulePackages();
|
||||
tester.runTests(m -> new Object[] { Paths.get(m.getName()) });
|
||||
}
|
||||
|
||||
private final ToolBox tb;
|
||||
|
||||
public TestModulePackages() {
|
||||
tb = new ToolBox();
|
||||
}
|
||||
|
||||
// @Test: See: https://bugs.openjdk.java.net/browse/JDK-8193107
|
||||
public void empty(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
new ModuleBuilder(tb, "m")
|
||||
.comment("empty module")
|
||||
.write(src);
|
||||
|
||||
javadoc("-d", base.resolve("out").toString(),
|
||||
"-quiet",
|
||||
"-noindex",
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkOutput("m-summary.html", false,
|
||||
"<h3>Packages</h3>\n"
|
||||
+ "<table class=\"packagesSummary\" summary=\"Packages table, "
|
||||
+ "listing packages, and an explanation\">");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exportSingle(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
new ModuleBuilder(tb, "m")
|
||||
.comment("exports single package to all")
|
||||
.exports("p")
|
||||
.classes("package p; public class C { }")
|
||||
.write(src);
|
||||
|
||||
javadoc("-d", base.resolve("out").toString(),
|
||||
"-quiet",
|
||||
"-noindex",
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkCaption("m", TabKind.EXPORTS);
|
||||
checkTableHead("m");
|
||||
checkPackageRow("m", "p", "i0", null, null, " ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exportMultiple(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
new ModuleBuilder(tb, "m")
|
||||
.comment("exports multiple packages to all")
|
||||
.exports("p")
|
||||
.exports("q")
|
||||
.classes("package p; public class C { }")
|
||||
.classes("package q; public class D { }")
|
||||
.write(src);
|
||||
|
||||
javadoc("-d", base.resolve("out").toString(),
|
||||
"-quiet",
|
||||
"-noindex",
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkCaption("m", TabKind.EXPORTS);
|
||||
checkTableHead("m");
|
||||
checkPackageRow("m", "p", "i0", null, null, " ");
|
||||
checkPackageRow("m", "q", "i1", null, null, " ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exportSomeQualified(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
new ModuleBuilder(tb, "m")
|
||||
.comment("exports multiple packages, some qualified")
|
||||
.exports("p")
|
||||
.exportsTo("q", "other")
|
||||
.classes("package p; public class C { }")
|
||||
.classes("package q; public class D { }")
|
||||
.write(src);
|
||||
|
||||
new ModuleBuilder(tb, "other")
|
||||
.comment("dummy module for target of export")
|
||||
.write(src);
|
||||
|
||||
javadoc("-d", base.resolve("out-api").toString(),
|
||||
"-quiet",
|
||||
"-noindex",
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m,other");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkCaption("m", TabKind.EXPORTS);
|
||||
checkTableHead("m");
|
||||
checkPackageRow("m", "p", "i0", null, null, " ");
|
||||
|
||||
javadoc("-d", base.resolve("out-all").toString(),
|
||||
"-quiet",
|
||||
"-noindex",
|
||||
"--show-module-contents", "all",
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m,other");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkCaption("m", TabKind.EXPORTS);
|
||||
checkTableHead("m", ColKind.EXPORTED_TO);
|
||||
checkPackageRow("m", "p", "i0", "All Modules", null, " ");
|
||||
checkPackageRow("m", "q", "i1",
|
||||
"<a href=\"other-summary.html\">other</a>", null, " ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exportWithConcealed(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
new ModuleBuilder(tb, "m")
|
||||
.comment("exports package, has concealed package")
|
||||
.exports("p")
|
||||
.classes("package p; public class C { }")
|
||||
.classes("package q; public class D { }")
|
||||
.write(src);
|
||||
|
||||
javadoc("-d", base.resolve("out-api").toString(),
|
||||
"-quiet",
|
||||
"-noindex",
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkCaption("m", TabKind.EXPORTS);
|
||||
checkTableHead("m");
|
||||
checkPackageRow("m", "p", "i0", null, null, " ");
|
||||
|
||||
javadoc("-d", base.resolve("out-all").toString(),
|
||||
"-quiet",
|
||||
"-noindex",
|
||||
"--show-module-contents", "all",
|
||||
"--show-packages", "all",
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkCaption("m", TabKind.EXPORTS, TabKind.CONCEALED);
|
||||
checkTableHead("m", ColKind.EXPORTED_TO);
|
||||
checkPackageRow("m", "p", "i0", "All Modules", null, " ");
|
||||
checkPackageRow("m", "q", "i1", "None", null, " ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exportOpenWithConcealed(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
new ModuleBuilder(tb, "m")
|
||||
.comment("exports and opens qual and unqual, with concealed")
|
||||
.exports("e.all")
|
||||
.exportsTo("e.other", "other")
|
||||
.opens("o.all")
|
||||
.opensTo("o.other", "other")
|
||||
.exports("eo")
|
||||
.opens("eo")
|
||||
.classes("package e.all; public class CEAll { }")
|
||||
.classes("package e.other; public class CEOther { }")
|
||||
.classes("package o.all; public class COAll { }")
|
||||
.classes("package o.other; public class COOther { }")
|
||||
.classes("package eo; public class CEO { }")
|
||||
.classes("package c; public class C { }")
|
||||
.write(src);
|
||||
|
||||
new ModuleBuilder(tb, "other")
|
||||
.comment("dummy module for target of export and open")
|
||||
.write(src);
|
||||
|
||||
javadoc("-d", base.resolve("out-api").toString(),
|
||||
"-quiet",
|
||||
"-noindex",
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m,other");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkCaption("m", TabKind.EXPORTS, TabKind.OPENS);
|
||||
checkTableHead("m", ColKind.EXPORTED_TO, ColKind.OPENED_TO);
|
||||
checkPackageRow("m", "e.all", "i0", "All Modules", "None", " ");
|
||||
checkPackageRow("m", "eo", "i1", "All Modules", "All Modules", " ");
|
||||
|
||||
javadoc("-d", base.resolve("out-all").toString(),
|
||||
"-quiet",
|
||||
"-noindex",
|
||||
"--show-module-contents", "all",
|
||||
"--show-packages", "all",
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m,other");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkCaption("m", TabKind.EXPORTS, TabKind.OPENS, TabKind.CONCEALED);
|
||||
checkTableHead("m", ColKind.EXPORTED_TO, ColKind.OPENED_TO);
|
||||
checkPackageRow("m", "c", "i0", "None", "None", " ");
|
||||
checkPackageRow("m", "e.all", "i1", "All Modules", "None", " ");
|
||||
checkPackageRow("m", "e.other", "i2",
|
||||
"<a href=\"other-summary.html\">other</a>", "None", " ");
|
||||
checkPackageRow("m", "eo", "i3", "All Modules", "All Modules", " ");
|
||||
checkPackageRow("m", "o.all", "i4", "None", "All Modules", " ");
|
||||
checkPackageRow("m", "o.other", "i5", "None",
|
||||
"<a href=\"other-summary.html\">other</a>", " ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void openModule(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
new ModuleBuilder(tb, true, "m")
|
||||
.comment("open module")
|
||||
.classes("/** implicitly open package */ package p;")
|
||||
.classes("package p; public class C { } ")
|
||||
.classes("/** implicitly open package */ package q;")
|
||||
.classes("package q; public class D { }")
|
||||
.write(src);
|
||||
|
||||
javadoc("-d", base.resolve("out").toString(),
|
||||
"-quiet",
|
||||
"-noindex",
|
||||
"--show-packages", "all", // required, to show open packages; see JDK-8193107
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkCaption("m", TabKind.OPENS);
|
||||
checkTableHead("m");
|
||||
checkPackageRow("m", "p", "i0", null, null,
|
||||
"\n<div class=\"block\">implicitly open package</div>\n");
|
||||
checkPackageRow("m", "q", "i1", null, null,
|
||||
"\n<div class=\"block\">implicitly open package</div>\n");
|
||||
}
|
||||
@Test
|
||||
public void openSingle(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
new ModuleBuilder(tb, "m")
|
||||
.comment("opens single package to all")
|
||||
.opens("p")
|
||||
.classes("package p; public class C { }")
|
||||
.write(src);
|
||||
|
||||
javadoc("-d", base.resolve("out").toString(),
|
||||
"-quiet",
|
||||
"-noindex",
|
||||
"--show-packages", "all", // required, to show open packages; see JDK-8193107
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkCaption("m", TabKind.OPENS);
|
||||
checkTableHead("m");
|
||||
checkPackageRow("m", "p", "i0", null, null, " ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void openMultiple(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
new ModuleBuilder(tb, "m")
|
||||
.comment("opens multiple packages to all")
|
||||
.opens("p")
|
||||
.opens("q")
|
||||
.classes("package p; public class C { }")
|
||||
.classes("package q; public class D { }")
|
||||
.write(src);
|
||||
|
||||
javadoc("-d", base.resolve("out").toString(),
|
||||
"-quiet",
|
||||
"-noindex",
|
||||
"--show-packages", "all", // required, to show open packages; see JDK-8193107
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkCaption("m", TabKind.OPENS);
|
||||
checkTableHead("m");
|
||||
checkPackageRow("m", "p", "i0", null, null, " ");
|
||||
checkPackageRow("m", "q", "i1", null, null, " ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void openSomeQualified(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
new ModuleBuilder(tb, "m")
|
||||
.comment("opens multiple packages, some qualified")
|
||||
.opens("p")
|
||||
.opensTo("q", "other")
|
||||
.classes("package p; public class C { }")
|
||||
.classes("package q; public class D { }")
|
||||
.write(src);
|
||||
|
||||
new ModuleBuilder(tb, "other")
|
||||
.comment("dummy module for target of export")
|
||||
.write(src);
|
||||
|
||||
javadoc("-d", base.resolve("out-api").toString(),
|
||||
"-quiet",
|
||||
"-noindex",
|
||||
"--show-packages", "all", // required, to show open packages; see JDK-8193107
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m,other");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkCaption("m", TabKind.OPENS);
|
||||
checkTableHead("m");
|
||||
checkPackageRow("m", "p", "i0", null, null, " ");
|
||||
|
||||
javadoc("-d", base.resolve("out-all").toString(),
|
||||
"-quiet",
|
||||
"-noindex",
|
||||
"--show-packages", "all", // required, to show open packages; see JDK-8193107
|
||||
"--show-module-contents", "all",
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m,other");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkCaption("m", TabKind.OPENS);
|
||||
checkTableHead("m", ColKind.OPENED_TO);
|
||||
checkPackageRow("m", "p", "i0", null, "All Modules", " ");
|
||||
checkPackageRow("m", "q", "i1", null,
|
||||
"<a href=\"other-summary.html\">other</a>", " ");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void openWithConcealed(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
new ModuleBuilder(tb, "m")
|
||||
.comment("opens package, has concealed package")
|
||||
.opens("p")
|
||||
.classes("package p; public class C { }")
|
||||
.classes("package q; public class D { }")
|
||||
.write(src);
|
||||
|
||||
javadoc("-d", base.resolve("out-api").toString(),
|
||||
"-quiet",
|
||||
"-noindex",
|
||||
"--show-packages", "all", // required, to show open packages; see JDK-8193107
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkCaption("m", TabKind.OPENS);
|
||||
checkTableHead("m");
|
||||
checkPackageRow("m", "p", "i0", null, null, " ");
|
||||
|
||||
javadoc("-d", base.resolve("out-all").toString(),
|
||||
"-quiet",
|
||||
"-noindex",
|
||||
"--show-module-contents", "all",
|
||||
"--show-packages", "all",
|
||||
"--module-source-path", src.toString(),
|
||||
"--module", "m");
|
||||
|
||||
checkExit(Exit.OK);
|
||||
checkCaption("m", TabKind.OPENS, TabKind.CONCEALED);
|
||||
checkTableHead("m", ColKind.OPENED_TO);
|
||||
checkPackageRow("m", "p", "i0", null, "All Modules", " ");
|
||||
checkPackageRow("m", "q", "i1", null, "None", " ");
|
||||
}
|
||||
|
||||
|
||||
private void checkCaption(String moduleName, TabKind... kinds) {
|
||||
String expect;
|
||||
if (kinds.length > 1) {
|
||||
Set<TabKind> kindSet = Set.of(kinds);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<caption>"
|
||||
+ "<span id=\"t0\" class=\"activeTableTab\">"
|
||||
+ "<span>All Packages</span>"
|
||||
+ "<span class=\"tabEnd\"> </span></span>");
|
||||
if (kindSet.contains(TabKind.EXPORTS)) {
|
||||
sb.append("<span id=\"t1\" class=\"tableTab\">"
|
||||
+ "<span><a href=\"javascript:showPkgs(1);\">Exports</a></span>"
|
||||
+ "<span class=\"tabEnd\"> </span></span>");
|
||||
}
|
||||
if (kindSet.contains(TabKind.OPENS)) {
|
||||
sb.append("<span id=\"t2\" class=\"tableTab\">"
|
||||
+ "<span><a href=\"javascript:showPkgs(2);\">Opens</a></span>"
|
||||
+ "<span class=\"tabEnd\"> </span></span>");
|
||||
}
|
||||
if (kindSet.contains(TabKind.CONCEALED)) {
|
||||
sb.append("<span id=\"t3\" class=\"tableTab\"><span>"
|
||||
+ "<a href=\"javascript:showPkgs(4);\">Concealed</a></span>"
|
||||
+ "<span class=\"tabEnd\"> </span></span>");
|
||||
}
|
||||
sb.append("</caption>");
|
||||
expect = sb.toString();
|
||||
} else {
|
||||
TabKind k = kinds[0];
|
||||
String name = k.toString().charAt(0) + k.toString().substring(1).toLowerCase();
|
||||
expect = "<caption>"
|
||||
+ "<span>" + name + "</span>"
|
||||
+ "<span class=\"tabEnd\"> </span>"
|
||||
+ "</caption>";
|
||||
}
|
||||
|
||||
checkOutput(moduleName + "-summary.html", true, expect);
|
||||
}
|
||||
|
||||
|
||||
private void checkTableHead(String moduleName, ColKind... kinds) {
|
||||
Set<ColKind> kindSet = Set.of(kinds);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("<tr>\n"
|
||||
+ "<th class=\"colFirst\" scope=\"col\">Package</th>\n");
|
||||
if (kindSet.contains(ColKind.EXPORTED_TO)) {
|
||||
sb.append("<th class=\"colSecond\" scope=\"col\">Exported To Modules</th>\n");
|
||||
}
|
||||
if (kindSet.contains(ColKind.OPENED_TO)) {
|
||||
sb.append("<th class=\"colSecond\" scope=\"col\">Opened To Modules</th>\n");
|
||||
}
|
||||
sb.append("<th class=\"colLast\" scope=\"col\">Description</th>\n"
|
||||
+ "</tr>");
|
||||
|
||||
checkOutput(moduleName + "-summary.html", true, sb.toString());
|
||||
}
|
||||
|
||||
private void checkPackageRow(String moduleName, String packageName,
|
||||
String id, String exportedTo, String openedTo, String desc) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int idNum = Integer.parseInt(id.substring(1));
|
||||
String color = (idNum % 2 == 1 ? "rowColor" : "altColor");
|
||||
sb.append("<tr class=\"" + color + "\" id=\"" + id + "\">\n"
|
||||
+ "<th class=\"colFirst\" scope=\"row\">"
|
||||
+ "<a href=\"" + packageName.replace('.', '/') + "/package-summary.html\">"
|
||||
+ packageName + "</a></th>\n");
|
||||
if (exportedTo != null) {
|
||||
sb.append("<td class=\"colSecond\">" + exportedTo + "</td>\n");
|
||||
}
|
||||
if (openedTo != null) {
|
||||
sb.append("<td class=\"colSecond\">" + openedTo + "</td>\n");
|
||||
}
|
||||
sb.append("<td class=\"colLast\">" + desc + "</td>");
|
||||
|
||||
checkOutput(moduleName + "-summary.html", true, sb.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -994,7 +994,7 @@ public class TestModules extends JavadocTester {
|
||||
+ "</tr>\n"
|
||||
+ "</tbody>\n"
|
||||
+ "</table>");
|
||||
checkOutput("moduletags-summary.html", found,
|
||||
checkOutput("moduletags-summary.html", true,
|
||||
"<th class=\"colFirst\" scope=\"row\"><a href=\"testpkgmdltags/package-summary.html\">testpkgmdltags</a></th>\n"
|
||||
+ "<td class=\"colLast\"> </td>");
|
||||
}
|
||||
@ -1025,6 +1025,7 @@ public class TestModules extends JavadocTester {
|
||||
"<li><a href=\"#module.description\">Description</a> | <a href=\"#modules.summary\">"
|
||||
+ "Modules</a> | <a href=\"#packages.summary\">Packages</a> | <a href=\"#services.summary\">Services</a></li>",
|
||||
"<th class=\"colFirst\" scope=\"row\"><a href=\"testpkgmdlB/package-summary.html\">testpkgmdlB</a></th>\n"
|
||||
+ "<td class=\"colSecond\">None</td>\n"
|
||||
+ "<td class=\"colSecond\">All Modules</td>\n"
|
||||
+ "<td class=\"colLast\"> </td>",
|
||||
"<td class=\"colFirst\"> </td>\n"
|
||||
@ -1045,12 +1046,11 @@ public class TestModules extends JavadocTester {
|
||||
"<caption><span>Exports</span><span class=\"tabEnd\"> </span></caption>\n"
|
||||
+ "<tr>\n"
|
||||
+ "<th class=\"colFirst\" scope=\"col\">Package</th>\n"
|
||||
+ "<th class=\"colSecond\" scope=\"col\">Module</th>\n"
|
||||
+ "<th class=\"colSecond\" scope=\"col\">Exported To Modules</th>\n"
|
||||
+ "<th class=\"colLast\" scope=\"col\">Description</th>\n"
|
||||
+ "</tr>");
|
||||
checkOutput("moduletags-summary.html", found,
|
||||
checkOutput("moduletags-summary.html", true,
|
||||
"<th class=\"colFirst\" scope=\"row\"><a href=\"testpkgmdltags/package-summary.html\">testpkgmdltags</a></th>\n"
|
||||
+ "<td class=\"colSecond\">All Modules</td>\n"
|
||||
+ "<td class=\"colLast\"> </td>");
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,7 @@ public class ModuleBuilder {
|
||||
private final ToolBox tb;
|
||||
private final String name;
|
||||
private String comment = "";
|
||||
private boolean open;
|
||||
private List<String> requires = new ArrayList<>();
|
||||
private List<String> exports = new ArrayList<>();
|
||||
private List<String> opens = new ArrayList<>();
|
||||
@ -53,11 +54,22 @@ public class ModuleBuilder {
|
||||
|
||||
/**
|
||||
* Creates a builder for a module.
|
||||
* @param tb a Toolbox that can be used to compile the module declaration.
|
||||
* @param tb a Toolbox that can be used to compile the module declaration
|
||||
* @param name the name of the module to be built
|
||||
*/
|
||||
public ModuleBuilder(ToolBox tb, String name) {
|
||||
this(tb, false, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a builder for a module.
|
||||
* @param tb a Toolbox that can be used to compile the module declaration
|
||||
* @param open whether or not this is an open module
|
||||
* @param name the name of the module to be built
|
||||
*/
|
||||
public ModuleBuilder(ToolBox tb, boolean open, String name) {
|
||||
this.tb = tb;
|
||||
this.open = open;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@ -214,6 +226,9 @@ public class ModuleBuilder {
|
||||
.append(comment.replace("\n", "\n * "))
|
||||
.append("\n */\n");
|
||||
}
|
||||
if (open) {
|
||||
sb.append("open ");
|
||||
}
|
||||
sb.append("module ").append(name).append(" {\n");
|
||||
requires.forEach(r -> sb.append(" " + r + "\n"));
|
||||
exports.forEach(e -> sb.append(" " + e + "\n"));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2017, 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
|
||||
@ -524,6 +524,8 @@ public class ToolBox {
|
||||
return source;
|
||||
}
|
||||
|
||||
private static Pattern commentPattern =
|
||||
Pattern.compile("(?s)(\\s+//.*?\n|/\\*.*?\\*/)");
|
||||
private static Pattern modulePattern =
|
||||
Pattern.compile("module\\s+((?:\\w+\\.)*)");
|
||||
private static Pattern packagePattern =
|
||||
@ -533,13 +535,24 @@ public class ToolBox {
|
||||
|
||||
/**
|
||||
* Extracts the Java file name from the class declaration.
|
||||
* This method is intended for simple files and uses regular expressions,
|
||||
* so comments matching the pattern can make the method fail.
|
||||
* This method is intended for simple files and uses regular expressions.
|
||||
* Comments in the source are stripped before looking for the
|
||||
* declarations from which the name is derived.
|
||||
*/
|
||||
static String getJavaFileNameFromSource(String source) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Matcher matcher = commentPattern.matcher(source);
|
||||
int start = 0;
|
||||
while (matcher.find()) {
|
||||
sb.append(source.substring(start, matcher.start()));
|
||||
start = matcher.end();
|
||||
}
|
||||
sb.append(source.substring(start));
|
||||
source = sb.toString();
|
||||
|
||||
String packageName = null;
|
||||
|
||||
Matcher matcher = modulePattern.matcher(source);
|
||||
matcher = modulePattern.matcher(source);
|
||||
if (matcher.find())
|
||||
return "module-info.java";
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user