mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-16 09:04:41 +02:00
8178070: duplicate entries in package table
Reviewed-by: bpatel, ksrini
This commit is contained in:
parent
be25eb7f0e
commit
5bcb718441
9 changed files with 773 additions and 148 deletions
|
@ -96,6 +96,7 @@ public class Contents {
|
||||||
public final Content errors;
|
public final Content errors;
|
||||||
public final Content exception;
|
public final Content exception;
|
||||||
public final Content exceptions;
|
public final Content exceptions;
|
||||||
|
public final Content exportedTo;
|
||||||
public final Content fieldLabel;
|
public final Content fieldLabel;
|
||||||
public final Content fieldDetailsLabel;
|
public final Content fieldDetailsLabel;
|
||||||
public final Content fieldSummaryLabel;
|
public final Content fieldSummaryLabel;
|
||||||
|
@ -147,6 +148,7 @@ public class Contents {
|
||||||
public final Content noFramesLabel;
|
public final Content noFramesLabel;
|
||||||
public final Content noScriptMessage;
|
public final Content noScriptMessage;
|
||||||
public final Content openModuleLabel;
|
public final Content openModuleLabel;
|
||||||
|
public final Content openedTo;
|
||||||
public final Content overridesLabel;
|
public final Content overridesLabel;
|
||||||
public final Content overviewLabel;
|
public final Content overviewLabel;
|
||||||
public final Content packageHierarchies;
|
public final Content packageHierarchies;
|
||||||
|
@ -229,6 +231,7 @@ public class Contents {
|
||||||
errors = getContent("doclet.Errors");
|
errors = getContent("doclet.Errors");
|
||||||
exception = getContent("doclet.Exception");
|
exception = getContent("doclet.Exception");
|
||||||
exceptions = getContent("doclet.Exceptions");
|
exceptions = getContent("doclet.Exceptions");
|
||||||
|
exportedTo = getContent("doclet.ExportedTo");
|
||||||
fieldDetailsLabel = getContent("doclet.Field_Detail");
|
fieldDetailsLabel = getContent("doclet.Field_Detail");
|
||||||
fieldSummaryLabel = getContent("doclet.Field_Summary");
|
fieldSummaryLabel = getContent("doclet.Field_Summary");
|
||||||
fieldLabel = getContent("doclet.Field");
|
fieldLabel = getContent("doclet.Field");
|
||||||
|
@ -279,6 +282,7 @@ public class Contents {
|
||||||
nextPackageLabel = getNonBreakContent("doclet.Next_Package");
|
nextPackageLabel = getNonBreakContent("doclet.Next_Package");
|
||||||
noFramesLabel = getNonBreakContent("doclet.No_Frames");
|
noFramesLabel = getNonBreakContent("doclet.No_Frames");
|
||||||
noScriptMessage = getContent("doclet.No_Script_Message");
|
noScriptMessage = getContent("doclet.No_Script_Message");
|
||||||
|
openedTo = getContent("doclet.OpenedTo");
|
||||||
openModuleLabel = getContent("doclet.Open_Module");
|
openModuleLabel = getContent("doclet.Open_Module");
|
||||||
overridesLabel = getContent("doclet.Overrides");
|
overridesLabel = getContent("doclet.Overrides");
|
||||||
overviewLabel = getContent("doclet.Overview");
|
overviewLabel = getContent("doclet.Overview");
|
||||||
|
|
|
@ -106,21 +106,34 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||||
= new TreeMap<>(utils.makeModuleComparator());
|
= 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
|
class PackageEntry {
|
||||||
= new TreeMap<>(utils.makePackageComparator());
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map of opened packages by this module and the modules it has been opened to.
|
* 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.
|
||||||
*/
|
*/
|
||||||
private final Map<PackageElement, SortedSet<ModuleElement>> openedPackages
|
Set<ModuleElement> openedTo;
|
||||||
= new TreeMap<>(utils.makePackageComparator());
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of concealed packages of this module.
|
* Map of packages of this module, and details of whether they are exported or opened.
|
||||||
*/
|
*/
|
||||||
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.
|
* 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.
|
// Get all packages if module is open or if displaying concealed modules
|
||||||
utils.getModulePackageMap().getOrDefault(mdle, Collections.emptySet()).forEach((pkg) -> {
|
for (PackageElement pkg : utils.getModulePackageMap().getOrDefault(mdle, Collections.emptySet())) {
|
||||||
if (shouldDocument(pkg) && moduleMode == ModuleMode.ALL) {
|
if (shouldDocument(pkg) && (mdle.isOpen() || moduleMode == ModuleMode.ALL)) {
|
||||||
concealedPackages.add(pkg);
|
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.
|
// Get all exported packages for the module, using the exports directive for the module.
|
||||||
(ElementFilter.exportsIn(mdle.getDirectives())).forEach((directive) -> {
|
for (ModuleElement.ExportsDirective directive : ElementFilter.exportsIn(mdle.getDirectives())) {
|
||||||
PackageElement p = directive.getPackage();
|
PackageElement p = directive.getPackage();
|
||||||
if (shouldDocument(p)) {
|
if (shouldDocument(p)) {
|
||||||
SortedSet<ModuleElement> mdleList = new TreeSet<>(utils.makeModuleComparator());
|
|
||||||
List<? extends ModuleElement> targetMdles = directive.getTargetModules();
|
List<? extends ModuleElement> targetMdles = directive.getTargetModules();
|
||||||
|
// 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) {
|
if (targetMdles != null) {
|
||||||
mdleList.addAll(targetMdles);
|
mdleList.addAll(targetMdles);
|
||||||
}
|
}
|
||||||
// Qualified exports should not be displayed in the api mode. So if mdleList is empty,
|
packageEntry.exportedTo = mdleList;
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
// 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();
|
PackageElement p = directive.getPackage();
|
||||||
if (shouldDocument(p)) {
|
if (shouldDocument(p)) {
|
||||||
SortedSet<ModuleElement> mdleList = new TreeSet<>(utils.makeModuleComparator());
|
|
||||||
List<? extends ModuleElement> targetMdles = directive.getTargetModules();
|
List<? extends ModuleElement> targetMdles = directive.getTargetModules();
|
||||||
|
// 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) {
|
if (targetMdles != null) {
|
||||||
mdleList.addAll(targetMdles);
|
mdleList.addAll(targetMdles);
|
||||||
}
|
}
|
||||||
// Qualified opens should not be displayed in the api mode. So if mdleList is empty,
|
packageEntry.openedTo = mdleList;
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
// Get all the exported and opened packages, for the transitive closure of the module, to be displayed in
|
// Get all the exported and opened packages, for the transitive closure of the module, to be displayed in
|
||||||
// the indirect packages tables.
|
// the indirect packages tables.
|
||||||
dependentModules.forEach((module, mod) -> {
|
dependentModules.forEach((module, mod) -> {
|
||||||
|
@ -348,6 +362,9 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||||
indirectPackages.put(module, exportPkgList);
|
indirectPackages.put(module, exportPkgList);
|
||||||
}
|
}
|
||||||
SortedSet<PackageElement> openPkgList = new TreeSet<>(utils.makePackageComparator());
|
SortedSet<PackageElement> openPkgList = new TreeSet<>(utils.makePackageComparator());
|
||||||
|
if (module.isOpen()) {
|
||||||
|
openPkgList.addAll(utils.getModulePackageMap().getOrDefault(module, Collections.emptySet()));
|
||||||
|
} else {
|
||||||
(ElementFilter.opensIn(module.getDirectives())).forEach((directive) -> {
|
(ElementFilter.opensIn(module.getDirectives())).forEach((directive) -> {
|
||||||
PackageElement pkg = directive.getPackage();
|
PackageElement pkg = directive.getPackage();
|
||||||
if (shouldDocument(pkg)) {
|
if (shouldDocument(pkg)) {
|
||||||
|
@ -357,6 +374,7 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
// If none of the indirect modules have opened packages to be displayed, we should not be
|
// 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.
|
// displaying the table and so it should not be added to the map.
|
||||||
if (!openPkgList.isEmpty()) {
|
if (!openPkgList.isEmpty()) {
|
||||||
|
@ -556,13 +574,13 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addPackagesSummary(Content summaryContentTree) {
|
public void addPackagesSummary(Content summaryContentTree) {
|
||||||
if (display(exportedPackages) || display(openedPackages) || display(concealedPackages)
|
if (display(packages)
|
||||||
|| display(indirectPackages) || display(indirectOpenPackages)) {
|
|| display(indirectPackages) || display(indirectOpenPackages)) {
|
||||||
HtmlTree li = new HtmlTree(HtmlTag.LI);
|
HtmlTree li = new HtmlTree(HtmlTag.LI);
|
||||||
li.setStyle(HtmlStyle.blockList);
|
li.setStyle(HtmlStyle.blockList);
|
||||||
addSummaryHeader(HtmlConstants.START_OF_PACKAGES_SUMMARY, SectionName.PACKAGES,
|
addSummaryHeader(HtmlConstants.START_OF_PACKAGES_SUMMARY, SectionName.PACKAGES,
|
||||||
contents.navPackages, li);
|
contents.navPackages, li);
|
||||||
if (display(exportedPackages) || display(openedPackages) || display(concealedPackages)) {
|
if (display(packages)) {
|
||||||
String tableSummary = resources.getText("doclet.Member_Table_Summary",
|
String tableSummary = resources.getText("doclet.Member_Table_Summary",
|
||||||
resources.getText("doclet.Packages_Summary"),
|
resources.getText("doclet.Packages_Summary"),
|
||||||
resources.getText("doclet.packages"));
|
resources.getText("doclet.packages"));
|
||||||
|
@ -607,77 +625,115 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||||
Table table = new Table(configuration.htmlVersion, HtmlStyle.packagesSummary)
|
Table table = new Table(configuration.htmlVersion, HtmlStyle.packagesSummary)
|
||||||
.setSummary(tableSummary)
|
.setSummary(tableSummary)
|
||||||
.setDefaultTab(resources.getText("doclet.All_Packages"))
|
.setDefaultTab(resources.getText("doclet.All_Packages"))
|
||||||
.addTab(resources.getText("doclet.Exported_Packages_Summary"),
|
.addTab(resources.getText("doclet.Exported_Packages_Summary"), this::isExported)
|
||||||
e -> exportedPackages.containsKey((PackageElement) e))
|
.addTab(resources.getText("doclet.Opened_Packages_Summary"), this::isOpened)
|
||||||
.addTab(resources.getText("doclet.Opened_Packages_Summary"),
|
.addTab(resources.getText("doclet.Concealed_Packages_Summary"), this::isConcealed)
|
||||||
e -> openedPackages.containsKey((PackageElement) e))
|
|
||||||
.addTab(resources.getText("doclet.Concealed_Packages_Summary"),
|
|
||||||
e -> concealedPackages.contains((PackageElement) e))
|
|
||||||
.setTabScript(i -> String.format("showPkgs(%d);", i))
|
.setTabScript(i -> String.format("showPkgs(%d);", i))
|
||||||
.setTabScriptVariable("packages");
|
.setTabScriptVariable("packages");
|
||||||
|
|
||||||
if (configuration.docEnv.getModuleMode() == ModuleMode.API) {
|
// Determine whether to show the "Exported To" and "Opened To" columns,
|
||||||
table.setHeader(new TableHeader(contents.packageLabel, contents.descriptionLabel))
|
// based on whether such columns would provide "useful" info.
|
||||||
.setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colLast);
|
int numExports = 0;
|
||||||
} else {
|
int numUnqualifiedExports = 0;
|
||||||
table.setHeader(new TableHeader(contents.packageLabel, contents.moduleLabel, contents.descriptionLabel))
|
int numOpens = 0;
|
||||||
.setColumnStyles(HtmlStyle.colFirst, HtmlStyle.colSecond, HtmlStyle.colLast);
|
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());
|
li.addContent(table.toContent());
|
||||||
if (table.needsScript()) {
|
if (table.needsScript()) {
|
||||||
mainBodyScript.append(table.getScript());
|
mainBodyScript.append(table.getScript());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private boolean isExported(Element e) {
|
||||||
* Get the package table rows.
|
PackageEntry entry = packages.get((PackageElement) e);
|
||||||
*
|
return (entry != null) && (entry.exportedTo != null);
|
||||||
* @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 void addPackageTableRows(Table table, Map<PackageElement,SortedSet<ModuleElement>> ap) {
|
private boolean isOpened(Element e) {
|
||||||
for (Map.Entry<PackageElement, SortedSet<ModuleElement>> entry : ap.entrySet()) {
|
PackageEntry entry = packages.get((PackageElement) e);
|
||||||
List<Content> row = new ArrayList<>();
|
return (entry != null) && (entry.openedTo != null);
|
||||||
PackageElement pkg = entry.getKey();
|
}
|
||||||
SortedSet<ModuleElement> mdleList = entry.getValue();
|
|
||||||
Content pkgLinkContent = getPackageLink(pkg, new StringContent(utils.getPackageName(pkg)));
|
|
||||||
row.add(pkgLinkContent);
|
|
||||||
|
|
||||||
if (moduleMode == ModuleMode.ALL) {
|
private boolean isConcealed(Element e) {
|
||||||
Content modules = new ContentBuilder();
|
PackageEntry entry = packages.get((PackageElement) e);
|
||||||
if (!mdleList.isEmpty()) {
|
return (entry != null) && (entry.exportedTo == null) && (entry.openedTo == null);
|
||||||
for (ModuleElement m : mdleList) {
|
|
||||||
if (!modules.isEmpty()) {
|
|
||||||
modules.addContent(new HtmlTree(HtmlTag.BR));
|
|
||||||
}
|
|
||||||
modules.addContent(getModuleLink(m, new StringContent(m.getQualifiedName())));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
} else {
|
||||||
Content allModules = new StringContent(resources.getText("doclet.All_Modules"));
|
Content list = new ContentBuilder();
|
||||||
modules.addContent(allModules);
|
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();
|
return list;
|
||||||
addSummaryComment(pkg, summary);
|
|
||||||
row.add(summary);
|
|
||||||
table.addRow(pkg, row);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,14 +748,14 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW
|
||||||
ModuleElement m = entry.getKey();
|
ModuleElement m = entry.getKey();
|
||||||
SortedSet<PackageElement> pkgList = entry.getValue();
|
SortedSet<PackageElement> pkgList = entry.getValue();
|
||||||
Content moduleLinkContent = getModuleLink(m, new StringContent(m.getQualifiedName()));
|
Content moduleLinkContent = getModuleLink(m, new StringContent(m.getQualifiedName()));
|
||||||
Content packages = new ContentBuilder();
|
Content list = new ContentBuilder();
|
||||||
String sep = "";
|
String sep = "";
|
||||||
for (PackageElement pkg : pkgList) {
|
for (PackageElement pkg : pkgList) {
|
||||||
packages.addContent(sep);
|
list.addContent(sep);
|
||||||
packages.addContent(getPackageLink(pkg, new StringContent(utils.getPackageName(pkg))));
|
list.addContent(getPackageLink(pkg, new StringContent(utils.getPackageName(pkg))));
|
||||||
sep = " ";
|
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)
|
? Links.createLink(SectionName.MODULES, contents.navModules)
|
||||||
: contents.navModules);
|
: contents.navModules);
|
||||||
addNavGap(liNav);
|
addNavGap(liNav);
|
||||||
liNav.addContent((display(exportedPackages) || display(openedPackages) || display(concealedPackages)
|
liNav.addContent((display(packages)
|
||||||
|| display(indirectPackages) || display(indirectOpenPackages))
|
|| display(indirectPackages) || display(indirectOpenPackages))
|
||||||
? Links.createLink(SectionName.PACKAGES, contents.navPackages)
|
? Links.createLink(SectionName.PACKAGES, contents.navPackages)
|
||||||
: contents.navPackages);
|
: contents.navPackages);
|
||||||
|
|
|
@ -76,6 +76,14 @@ public class TableHeader {
|
||||||
this.cellContents = Arrays.asList(headerCellContents);
|
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.
|
* Set the style class names for each header cell.
|
||||||
* The number of names must match the number of cells given to the constructor.
|
* The number of names must match the number of cells given to the constructor.
|
||||||
|
@ -90,6 +98,20 @@ public class TableHeader {
|
||||||
return this;
|
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}.
|
* Converts this header to a {@link Content} object, for use in an {@link HtmlTree}.
|
||||||
* @return a Content object
|
* @return a Content object
|
||||||
|
|
|
@ -145,6 +145,8 @@ doclet.errors=errors
|
||||||
doclet.Exception=Exception
|
doclet.Exception=Exception
|
||||||
doclet.exception=exception
|
doclet.exception=exception
|
||||||
doclet.exceptions=exceptions
|
doclet.exceptions=exceptions
|
||||||
|
doclet.ExportedTo=Exported To Modules
|
||||||
|
doclet.OpenedTo=Opened To Modules
|
||||||
doclet.Package_private=(package private)
|
doclet.Package_private=(package private)
|
||||||
doclet.Nested_Classes_Interfaces_Inherited_From_Class=Nested classes/interfaces inherited from class
|
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
|
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. */
|
/** The current run of javadoc. Incremented when javadoc is called. */
|
||||||
private int javadocRunNum = 0;
|
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. */
|
/** Marker annotation for test methods to be invoked by runTests. */
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@interface Test { }
|
@interface Test { }
|
||||||
|
@ -295,11 +298,11 @@ public abstract class JavadocTester {
|
||||||
fileContentCache.clear();
|
fileContentCache.clear();
|
||||||
|
|
||||||
javadocRunNum++;
|
javadocRunNum++;
|
||||||
|
javadocTestNum = 0; // reset counter for this run of javadoc
|
||||||
if (javadocRunNum == 1) {
|
if (javadocRunNum == 1) {
|
||||||
out.println("Running javadoc...");
|
out.println("Running javadoc...");
|
||||||
} else {
|
} else {
|
||||||
out.println("Running javadoc (run "
|
out.println("Running javadoc (run "+ javadocRunNum + ")...");
|
||||||
+ javadocRunNum + ")...");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
outputDir = new File(".");
|
outputDir = new File(".");
|
||||||
|
@ -441,8 +444,7 @@ public abstract class JavadocTester {
|
||||||
* Check for content in (or not in) the generated output.
|
* Check for content in (or not in) the generated output.
|
||||||
* Within the search strings, the newline character \n
|
* Within the search strings, the newline character \n
|
||||||
* will be translated to the platform newline character sequence.
|
* will be translated to the platform newline character sequence.
|
||||||
* @param path a path within the most recent output directory
|
* @param path a path within the most recent output directory, identifying
|
||||||
* or the name of one of the output buffers, identifying
|
|
||||||
* where to look for the search strings.
|
* where to look for the search strings.
|
||||||
* @param expectedFound true if all of the search strings are expected
|
* @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
|
* 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) {
|
public void checkOutput(String path, boolean expectedFound, String... strings) {
|
||||||
// Read contents of file
|
// Read contents of file
|
||||||
String fileString;
|
|
||||||
try {
|
try {
|
||||||
fileString = readFile(outputDir, path);
|
String fileString = readFile(outputDir, path);
|
||||||
|
checkOutput(new File(outputDir, path).getPath(), fileString, expectedFound, strings);
|
||||||
} catch (Error e) {
|
} catch (Error e) {
|
||||||
checking("Read file");
|
checking("Read file");
|
||||||
failed("Error reading file: " + e);
|
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);
|
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) {
|
private void checkOutput(String path, String fileString, boolean expectedFound, String... strings) {
|
||||||
for (String stringToFind : strings) {
|
for (String stringToFind : strings) {
|
||||||
// log.logCheckOutput(path, expectedFound, stringToFind);
|
// log.logCheckOutput(path, expectedFound, stringToFind);
|
||||||
|
@ -484,25 +485,27 @@ public abstract class JavadocTester {
|
||||||
boolean isFound = findString(fileString, stringToFind);
|
boolean isFound = findString(fileString, stringToFind);
|
||||||
if (isFound == expectedFound) {
|
if (isFound == expectedFound) {
|
||||||
passed(path + ": following text " + (isFound ? "found:" : "not found:") + "\n"
|
passed(path + ": following text " + (isFound ? "found:" : "not found:") + "\n"
|
||||||
+ stringToFind + "\n");
|
+ stringToFind);
|
||||||
} else {
|
} else {
|
||||||
failed(path + ": following text " + (isFound ? "found:" : "not found:") + "\n"
|
failed(path + ": following text " + (isFound ? "found:" : "not found:") + "\n"
|
||||||
+ stringToFind + "\n");
|
+ stringToFind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the content of the one of the output streams written by
|
* Get the content of the one of the output streams written by javadoc.
|
||||||
* javadoc.
|
* @param output the name of the output stream
|
||||||
|
* @return the content of the output stream
|
||||||
*/
|
*/
|
||||||
public String getOutput(Output output) {
|
public String getOutput(Output output) {
|
||||||
return outputMap.get(output);
|
return outputMap.get(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the content of the one of the output streams written by
|
* Get the content of the one of the output streams written by javadoc.
|
||||||
* 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) {
|
public List<String> getOutputLines(Output output) {
|
||||||
String text = outputMap.get(output);
|
String text = outputMap.get(output);
|
||||||
|
@ -534,9 +537,9 @@ public abstract class JavadocTester {
|
||||||
File file = new File(outputDir, path);
|
File file = new File(outputDir, path);
|
||||||
boolean isFound = file.exists();
|
boolean isFound = file.exists();
|
||||||
if (isFound == expectedFound) {
|
if (isFound == expectedFound) {
|
||||||
passed(path + ": file " + (isFound ? "found:" : "not found:") + "\n");
|
passed(file, "file " + (isFound ? "found:" : "not found:") + "\n");
|
||||||
} else {
|
} 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
|
* @param strings the strings whose order to check
|
||||||
*/
|
*/
|
||||||
public void checkOrder(String path, String... strings) {
|
public void checkOrder(String path, String... strings) {
|
||||||
|
File file = new File(outputDir, path);
|
||||||
String fileString = readOutputFile(path);
|
String fileString = readOutputFile(path);
|
||||||
int prevIndex = -1;
|
int prevIndex = -1;
|
||||||
for (String s : strings) {
|
for (String s : strings) {
|
||||||
s = s.replace("\n", NL); // normalize new lines
|
s = s.replace("\n", NL); // normalize new lines
|
||||||
int currentIndex = fileString.indexOf(s, prevIndex + 1);
|
int currentIndex = fileString.indexOf(s, prevIndex + 1);
|
||||||
checking(s + " at index " + currentIndex);
|
checking("file: " + file + ": " + s + " at index " + currentIndex);
|
||||||
if (currentIndex == -1) {
|
if (currentIndex == -1) {
|
||||||
failed(s + " not found.");
|
failed(file, s + " not found.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (currentIndex > prevIndex) {
|
if (currentIndex > prevIndex) {
|
||||||
passed(s + " is in the correct order");
|
passed(file, s + " is in the correct order");
|
||||||
} else {
|
} else {
|
||||||
failed("file: " + path + ": " + s + " is in the wrong order.");
|
failed(file, s + " is in the wrong order.");
|
||||||
}
|
}
|
||||||
prevIndex = currentIndex;
|
prevIndex = currentIndex;
|
||||||
}
|
}
|
||||||
|
@ -575,19 +579,20 @@ public abstract class JavadocTester {
|
||||||
* @param strings ensure each are unique
|
* @param strings ensure each are unique
|
||||||
*/
|
*/
|
||||||
public void checkUnique(String path, String... strings) {
|
public void checkUnique(String path, String... strings) {
|
||||||
|
File file = new File(outputDir, path);
|
||||||
String fileString = readOutputFile(path);
|
String fileString = readOutputFile(path);
|
||||||
for (String s : strings) {
|
for (String s : strings) {
|
||||||
int currentIndex = fileString.indexOf(s);
|
int currentIndex = fileString.indexOf(s);
|
||||||
checking(s + " at index " + currentIndex);
|
checking(s + " at index " + currentIndex);
|
||||||
if (currentIndex == -1) {
|
if (currentIndex == -1) {
|
||||||
failed(s + " not found.");
|
failed(file, s + " not found.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int nextindex = fileString.indexOf(s, currentIndex + s.length());
|
int nextindex = fileString.indexOf(s, currentIndex + s.length());
|
||||||
if (nextindex == -1) {
|
if (nextindex == -1) {
|
||||||
passed(s + " is unique");
|
passed(file, s + " is unique");
|
||||||
} else {
|
} 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) {
|
protected void checking(String message) {
|
||||||
numTestsRun++;
|
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) {
|
protected void passed(String message) {
|
||||||
numTestsPassed++;
|
numTestsPassed++;
|
||||||
print("Passed", message);
|
print("Passed", message);
|
||||||
|
out.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void failed(File file, String message) {
|
||||||
|
failed(file + ": " + message);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void failed(String message) {
|
protected void failed(String message) {
|
||||||
print("FAILED", 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) {
|
private void print(String prefix, String message) {
|
||||||
|
@ -720,7 +744,10 @@ public abstract class JavadocTester {
|
||||||
else {
|
else {
|
||||||
out.print(prefix);
|
out.print(prefix);
|
||||||
out.print(": ");
|
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"
|
+ "</tr>\n"
|
||||||
+ "</tbody>\n"
|
+ "</tbody>\n"
|
||||||
+ "</table>");
|
+ "</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"
|
"<th class=\"colFirst\" scope=\"row\"><a href=\"testpkgmdltags/package-summary.html\">testpkgmdltags</a></th>\n"
|
||||||
+ "<td class=\"colLast\"> </td>");
|
+ "<td class=\"colLast\"> </td>");
|
||||||
}
|
}
|
||||||
|
@ -1025,6 +1025,7 @@ public class TestModules extends JavadocTester {
|
||||||
"<li><a href=\"#module.description\">Description</a> | <a href=\"#modules.summary\">"
|
"<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>",
|
+ "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"
|
"<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=\"colSecond\">All Modules</td>\n"
|
||||||
+ "<td class=\"colLast\"> </td>",
|
+ "<td class=\"colLast\"> </td>",
|
||||||
"<td class=\"colFirst\"> </td>\n"
|
"<td class=\"colFirst\"> </td>\n"
|
||||||
|
@ -1045,12 +1046,11 @@ public class TestModules extends JavadocTester {
|
||||||
"<caption><span>Exports</span><span class=\"tabEnd\"> </span></caption>\n"
|
"<caption><span>Exports</span><span class=\"tabEnd\"> </span></caption>\n"
|
||||||
+ "<tr>\n"
|
+ "<tr>\n"
|
||||||
+ "<th class=\"colFirst\" scope=\"col\">Package</th>\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"
|
+ "<th class=\"colLast\" scope=\"col\">Description</th>\n"
|
||||||
+ "</tr>");
|
+ "</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"
|
"<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>");
|
+ "<td class=\"colLast\"> </td>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ public class ModuleBuilder {
|
||||||
private final ToolBox tb;
|
private final ToolBox tb;
|
||||||
private final String name;
|
private final String name;
|
||||||
private String comment = "";
|
private String comment = "";
|
||||||
|
private boolean open;
|
||||||
private List<String> requires = new ArrayList<>();
|
private List<String> requires = new ArrayList<>();
|
||||||
private List<String> exports = new ArrayList<>();
|
private List<String> exports = new ArrayList<>();
|
||||||
private List<String> opens = new ArrayList<>();
|
private List<String> opens = new ArrayList<>();
|
||||||
|
@ -53,11 +54,22 @@ public class ModuleBuilder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a builder for a module.
|
* 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
|
* @param name the name of the module to be built
|
||||||
*/
|
*/
|
||||||
public ModuleBuilder(ToolBox tb, String name) {
|
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.tb = tb;
|
||||||
|
this.open = open;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,6 +226,9 @@ public class ModuleBuilder {
|
||||||
.append(comment.replace("\n", "\n * "))
|
.append(comment.replace("\n", "\n * "))
|
||||||
.append("\n */\n");
|
.append("\n */\n");
|
||||||
}
|
}
|
||||||
|
if (open) {
|
||||||
|
sb.append("open ");
|
||||||
|
}
|
||||||
sb.append("module ").append(name).append(" {\n");
|
sb.append("module ").append(name).append(" {\n");
|
||||||
requires.forEach(r -> sb.append(" " + r + "\n"));
|
requires.forEach(r -> sb.append(" " + r + "\n"));
|
||||||
exports.forEach(e -> sb.append(" " + e + "\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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -524,6 +524,8 @@ public class ToolBox {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Pattern commentPattern =
|
||||||
|
Pattern.compile("(?s)(\\s+//.*?\n|/\\*.*?\\*/)");
|
||||||
private static Pattern modulePattern =
|
private static Pattern modulePattern =
|
||||||
Pattern.compile("module\\s+((?:\\w+\\.)*)");
|
Pattern.compile("module\\s+((?:\\w+\\.)*)");
|
||||||
private static Pattern packagePattern =
|
private static Pattern packagePattern =
|
||||||
|
@ -533,13 +535,24 @@ public class ToolBox {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts the Java file name from the class declaration.
|
* Extracts the Java file name from the class declaration.
|
||||||
* This method is intended for simple files and uses regular expressions,
|
* This method is intended for simple files and uses regular expressions.
|
||||||
* so comments matching the pattern can make the method fail.
|
* Comments in the source are stripped before looking for the
|
||||||
|
* declarations from which the name is derived.
|
||||||
*/
|
*/
|
||||||
static String getJavaFileNameFromSource(String source) {
|
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;
|
String packageName = null;
|
||||||
|
|
||||||
Matcher matcher = modulePattern.matcher(source);
|
matcher = modulePattern.matcher(source);
|
||||||
if (matcher.find())
|
if (matcher.find())
|
||||||
return "module-info.java";
|
return "module-info.java";
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue