8175346: javadoc does not handle Locations correctly with --patch-module
Reviewed-by: jjg
This commit is contained in:
parent
833ecc754c
commit
7feb5d6fb7
@ -53,6 +53,7 @@ import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import com.sun.tools.javac.code.Kinds.Kind;
|
||||
import com.sun.tools.javac.code.Source;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.code.Symbol.ClassSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.CompletionFailure;
|
||||
@ -60,8 +61,11 @@ import com.sun.tools.javac.code.Symbol.ModuleSymbol;
|
||||
import com.sun.tools.javac.code.Symbol.PackageSymbol;
|
||||
import com.sun.tools.javac.code.Symtab;
|
||||
import com.sun.tools.javac.comp.Modules;
|
||||
import com.sun.tools.javac.main.JavaCompiler;
|
||||
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
|
||||
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
|
||||
import com.sun.tools.javac.tree.JCTree.JCModuleDecl;
|
||||
import com.sun.tools.javac.tree.TreeInfo;
|
||||
import com.sun.tools.javac.util.Context;
|
||||
import com.sun.tools.javac.util.ListBuffer;
|
||||
import com.sun.tools.javac.util.Name;
|
||||
@ -70,7 +74,9 @@ import jdk.javadoc.doclet.DocletEnvironment;
|
||||
import jdk.javadoc.doclet.DocletEnvironment.ModuleMode;
|
||||
|
||||
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
|
||||
|
||||
import static javax.tools.JavaFileObject.Kind.*;
|
||||
|
||||
import static jdk.javadoc.internal.tool.Main.Result.*;
|
||||
import static jdk.javadoc.internal.tool.JavadocTool.isValidClassName;
|
||||
|
||||
@ -153,10 +159,11 @@ public class ElementsTable {
|
||||
private final Symtab syms;
|
||||
private final Names names;
|
||||
private final JavaFileManager fm;
|
||||
private final Location location;
|
||||
private final List<Location> locations;
|
||||
private final Modules modules;
|
||||
private final Map<ToolOption, Object> opts;
|
||||
private final Messager messager;
|
||||
private final JavaCompiler compiler;
|
||||
|
||||
private final Map<String, Entry> entries = new LinkedHashMap<>();
|
||||
|
||||
@ -201,12 +208,22 @@ public class ElementsTable {
|
||||
this.modules = Modules.instance(context);
|
||||
this.opts = opts;
|
||||
this.messager = Messager.instance0(context);
|
||||
this.compiler = JavaCompiler.instance(context);
|
||||
Source source = Source.instance(context);
|
||||
|
||||
List<Location> locs = new ArrayList<>();
|
||||
if (modules.multiModuleMode) {
|
||||
locs.add(StandardLocation.MODULE_SOURCE_PATH);
|
||||
} else {
|
||||
if (toolEnv.fileManager.hasLocation(StandardLocation.SOURCE_PATH))
|
||||
locs.add(StandardLocation.SOURCE_PATH);
|
||||
else
|
||||
locs.add(StandardLocation.CLASS_PATH);
|
||||
}
|
||||
if (source.allowModules() && toolEnv.fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH))
|
||||
locs.add(StandardLocation.PATCH_MODULE_PATH);
|
||||
this.locations = Collections.unmodifiableList(locs);
|
||||
|
||||
this.location = modules.multiModuleMode
|
||||
? StandardLocation.MODULE_SOURCE_PATH
|
||||
: toolEnv.fileManager.hasLocation(StandardLocation.SOURCE_PATH)
|
||||
? StandardLocation.SOURCE_PATH
|
||||
: StandardLocation.CLASS_PATH;
|
||||
getEntry("").excluded = false;
|
||||
|
||||
accessFilter = new ModifierFilter(opts);
|
||||
@ -341,6 +358,52 @@ public class ElementsTable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method sanity checks the following cases:
|
||||
* a. a source-path containing a single module and many modules specified with --module
|
||||
* b. no modules on source-path
|
||||
* c. mismatched source-path and many modules specified with --module
|
||||
*/
|
||||
void sanityCheckSourcePathModules(List<String> moduleNames) throws ToolException {
|
||||
if (!haveSourceLocationWithModule)
|
||||
return;
|
||||
|
||||
if (moduleNames.size() > 1) {
|
||||
String text = messager.getText("main.cannot_use_sourcepath_for_modules",
|
||||
String.join(", ", moduleNames));
|
||||
throw new ToolException(CMDERR, text);
|
||||
}
|
||||
|
||||
String foundModule = getModuleName(StandardLocation.SOURCE_PATH);
|
||||
if (foundModule == null) {
|
||||
String text = messager.getText("main.module_not_found_on_sourcepath", moduleNames.get(0));
|
||||
throw new ToolException(CMDERR, text);
|
||||
}
|
||||
|
||||
if (!moduleNames.get(0).equals(foundModule)) {
|
||||
String text = messager.getText("main.sourcepath_does_not_contain_module", moduleNames.get(0));
|
||||
throw new ToolException(CMDERR, text);
|
||||
}
|
||||
}
|
||||
|
||||
private String getModuleName(Location location) throws ToolException {
|
||||
try {
|
||||
JavaFileObject jfo = fm.getJavaFileForInput(location,
|
||||
"module-info", JavaFileObject.Kind.SOURCE);
|
||||
if (jfo != null) {
|
||||
JCCompilationUnit jcu = compiler.parse(jfo);
|
||||
JCModuleDecl module = TreeInfo.getModule(jcu);
|
||||
if (module != null) {
|
||||
return module.getName().toString();
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
String text = messager.getText("main.file.manager.list", location);
|
||||
throw new ToolException(SYSERR, text, ioe);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ElementsTable scanSpecifiedItems() throws ToolException {
|
||||
|
||||
@ -349,15 +412,17 @@ public class ElementsTable {
|
||||
s -> Collections.EMPTY_LIST);
|
||||
List<String> mlist = new ArrayList<>();
|
||||
for (String m : moduleNames) {
|
||||
Location moduleLoc = getModuleLocation(location, m);
|
||||
if (moduleLoc == null) {
|
||||
List<Location> moduleLocations = getModuleLocation(locations, m);
|
||||
if (moduleLocations.isEmpty()) {
|
||||
String text = messager.getText("main.module_not_found", m);
|
||||
throw new ToolException(CMDERR, text);
|
||||
} else {
|
||||
mlist.add(m);
|
||||
ModuleSymbol msym = syms.enterModule(names.fromString(m));
|
||||
specifiedModuleElements.add((ModuleElement) msym);
|
||||
}
|
||||
if (moduleLocations.contains(StandardLocation.SOURCE_PATH)) {
|
||||
sanityCheckSourcePathModules(moduleNames);
|
||||
}
|
||||
mlist.add(m);
|
||||
ModuleSymbol msym = syms.enterModule(names.fromString(m));
|
||||
specifiedModuleElements.add((ModuleElement) msym);
|
||||
}
|
||||
|
||||
// scan for modules with qualified packages
|
||||
@ -448,35 +513,41 @@ public class ElementsTable {
|
||||
});
|
||||
|
||||
for (ModulePackage modpkg : subPackages) {
|
||||
Location packageLocn = getLocation(modpkg);
|
||||
Iterable<JavaFileObject> list = null;
|
||||
try {
|
||||
list = fm.list(packageLocn, modpkg.packageName, sourceKinds, true);
|
||||
} catch (IOException ioe) {
|
||||
String text = messager.getText("main.file.manager.list", modpkg.packageName);
|
||||
throw new ToolException(SYSERR, text, ioe);
|
||||
List<Location> locs = getLocation(modpkg);
|
||||
for (Location loc : locs) {
|
||||
addPackagesFromLocations(loc, modpkg);
|
||||
}
|
||||
for (JavaFileObject fo : list) {
|
||||
String binaryName = fm.inferBinaryName(packageLocn, fo);
|
||||
String pn = getPackageName(binaryName);
|
||||
String simpleName = getSimpleName(binaryName);
|
||||
Entry e = getEntry(pn);
|
||||
if (!e.isExcluded() && isValidClassName(simpleName)) {
|
||||
ModuleSymbol msym = (modpkg.hasModule())
|
||||
? syms.getModule(names.fromString(modpkg.moduleName))
|
||||
: findModuleOfPackageName(modpkg.packageName);
|
||||
}
|
||||
}
|
||||
|
||||
if (msym != null && !msym.isUnnamed()) {
|
||||
syms.enterPackage(msym, names.fromString(pn));
|
||||
ModulePackage npkg = new ModulePackage(msym.toString(), pn);
|
||||
cmdLinePackages.add(npkg);
|
||||
} else {
|
||||
cmdLinePackages.add(e.modpkg);
|
||||
}
|
||||
e.files = (e.files == null
|
||||
? com.sun.tools.javac.util.List.of(fo)
|
||||
: e.files.prepend(fo));
|
||||
private void addPackagesFromLocations(Location packageLocn, ModulePackage modpkg) throws ToolException {
|
||||
Iterable<JavaFileObject> list = null;
|
||||
try {
|
||||
list = fm.list(packageLocn, modpkg.packageName, sourceKinds, true);
|
||||
} catch (IOException ioe) {
|
||||
String text = messager.getText("main.file.manager.list", modpkg.packageName);
|
||||
throw new ToolException(SYSERR, text, ioe);
|
||||
}
|
||||
for (JavaFileObject fo : list) {
|
||||
String binaryName = fm.inferBinaryName(packageLocn, fo);
|
||||
String pn = getPackageName(binaryName);
|
||||
String simpleName = getSimpleName(binaryName);
|
||||
Entry e = getEntry(pn);
|
||||
if (!e.isExcluded() && isValidClassName(simpleName)) {
|
||||
ModuleSymbol msym = (modpkg.hasModule())
|
||||
? syms.getModule(names.fromString(modpkg.moduleName))
|
||||
: findModuleOfPackageName(modpkg.packageName);
|
||||
|
||||
if (msym != null && !msym.isUnnamed()) {
|
||||
syms.enterPackage(msym, names.fromString(pn));
|
||||
ModulePackage npkg = new ModulePackage(msym.toString(), pn);
|
||||
cmdLinePackages.add(npkg);
|
||||
} else {
|
||||
cmdLinePackages.add(e.modpkg);
|
||||
}
|
||||
e.files = (e.files == null
|
||||
? com.sun.tools.javac.util.List.of(fo)
|
||||
: e.files.prepend(fo));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -544,20 +615,23 @@ public class ElementsTable {
|
||||
private Set<PackageElement> getAllModulePackages(ModuleElement mdle) throws ToolException {
|
||||
Set<PackageElement> result = new HashSet<>();
|
||||
ModuleSymbol msym = (ModuleSymbol) mdle;
|
||||
Location msymloc = getModuleLocation(location, msym.name.toString());
|
||||
try {
|
||||
for (JavaFileObject fo : fm.list(msymloc, "", sourceKinds, true)) {
|
||||
if (fo.getName().endsWith("module-info.java"))
|
||||
continue;
|
||||
String binaryName = fm.inferBinaryName(msymloc, fo);
|
||||
String pn = getPackageName(binaryName);
|
||||
PackageSymbol psym = syms.enterPackage(msym, names.fromString(pn));
|
||||
result.add((PackageElement) psym);
|
||||
}
|
||||
List<Location> msymlocs = getModuleLocation(locations, msym.name.toString());
|
||||
for (Location msymloc : msymlocs) {
|
||||
try {
|
||||
for (JavaFileObject fo : fm.list(msymloc, "", sourceKinds, true)) {
|
||||
if (fo.getName().endsWith("module-info.java")) {
|
||||
continue;
|
||||
}
|
||||
String binaryName = fm.inferBinaryName(msymloc, fo);
|
||||
String pn = getPackageName(binaryName);
|
||||
PackageSymbol psym = syms.enterPackage(msym, names.fromString(pn));
|
||||
result.add((PackageElement) psym);
|
||||
}
|
||||
|
||||
} catch (IOException ioe) {
|
||||
String text = messager.getText("main.file.manager.list", msymloc.getName());
|
||||
throw new ToolException(SYSERR, text, ioe);
|
||||
} catch (IOException ioe) {
|
||||
String text = messager.getText("main.file.manager.list", msymloc.getName());
|
||||
throw new ToolException(SYSERR, text, ioe);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -741,25 +815,25 @@ public class ElementsTable {
|
||||
}
|
||||
|
||||
ListBuffer<JavaFileObject> lb = new ListBuffer<>();
|
||||
Location packageLocn = getLocation(modpkg);
|
||||
if (packageLocn == null) {
|
||||
List<Location> locs = getLocation(modpkg);
|
||||
if (locs.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
String pname = modpkg.packageName;
|
||||
|
||||
try {
|
||||
for (JavaFileObject fo : fm.list(packageLocn, pname, sourceKinds, recurse)) {
|
||||
String binaryName = fm.inferBinaryName(packageLocn, fo);
|
||||
String simpleName = getSimpleName(binaryName);
|
||||
if (isValidClassName(simpleName)) {
|
||||
lb.append(fo);
|
||||
for (Location packageLocn : locs) {
|
||||
try {
|
||||
for (JavaFileObject fo : fm.list(packageLocn, pname, sourceKinds, recurse)) {
|
||||
String binaryName = fm.inferBinaryName(packageLocn, fo);
|
||||
String simpleName = getSimpleName(binaryName);
|
||||
if (isValidClassName(simpleName)) {
|
||||
lb.append(fo);
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
String text = messager.getText("main.file.manager.list", pname);
|
||||
throw new ToolException(SYSERR, text, ioe);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
String text = messager.getText("main.file.manager.list", pname);
|
||||
throw new ToolException(SYSERR, text, ioe);
|
||||
}
|
||||
|
||||
return lb.toList();
|
||||
}
|
||||
|
||||
@ -774,24 +848,49 @@ public class ElementsTable {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Location getLocation(ModulePackage modpkg) throws ToolException {
|
||||
if (location != StandardLocation.MODULE_SOURCE_PATH) {
|
||||
return location;
|
||||
private List<Location> getLocation(ModulePackage modpkg) throws ToolException {
|
||||
if (locations.size() == 1 && !locations.contains(StandardLocation.MODULE_SOURCE_PATH)) {
|
||||
return Collections.singletonList(locations.get(0));
|
||||
}
|
||||
|
||||
if (modpkg.hasModule()) {
|
||||
return getModuleLocation(location, modpkg.moduleName);
|
||||
return getModuleLocation(locations, modpkg.moduleName);
|
||||
}
|
||||
// TODO: handle invalid results better.
|
||||
ModuleSymbol msym = findModuleOfPackageName(modpkg.packageName);
|
||||
if (msym == null) {
|
||||
return null;
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return getModuleLocation(location, msym.name.toString());
|
||||
return getModuleLocation(locations, msym.name.toString());
|
||||
}
|
||||
|
||||
private Location getModuleLocation(Location location, String msymName)
|
||||
throws ToolException {
|
||||
boolean haveSourceLocationWithModule = false;
|
||||
|
||||
private List<Location> getModuleLocation(List<Location> locations, String msymName) throws ToolException {
|
||||
List<Location> out = new ArrayList<>();
|
||||
// search in the patch module first, this overrides others
|
||||
if (locations.contains(StandardLocation.PATCH_MODULE_PATH)) {
|
||||
Location loc = getModuleLocation(StandardLocation.PATCH_MODULE_PATH, msymName);
|
||||
if (loc != null)
|
||||
out.add(loc);
|
||||
}
|
||||
for (Location location : locations) {
|
||||
// skip patch module, already done
|
||||
if (location == StandardLocation.PATCH_MODULE_PATH) {
|
||||
continue;
|
||||
} else if (location == StandardLocation.MODULE_SOURCE_PATH) {
|
||||
Location loc = getModuleLocation(location, msymName);
|
||||
if (loc != null)
|
||||
out.add(loc);
|
||||
} else if (location == StandardLocation.SOURCE_PATH) {
|
||||
haveSourceLocationWithModule = true;
|
||||
out.add(StandardLocation.SOURCE_PATH);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
private Location getModuleLocation(Location location, String msymName) throws ToolException {
|
||||
try {
|
||||
return fm.getLocationForModule(location, msymName);
|
||||
} catch (IOException ioe) {
|
||||
|
@ -258,6 +258,9 @@ main.only_one_argument_with_equals=cannot use ''='' syntax for options that requ
|
||||
main.invalid_flag=invalid flag: {0}
|
||||
main.No_modules_packages_or_classes_specified=No modules, packages or classes specified.
|
||||
main.module_not_found=module {0} not found.\n
|
||||
main.cannot_use_sourcepath_for_modules=cannot use source path for multiple modules {0}
|
||||
main.module_not_found_on_sourcepath=module {0} not found on source path
|
||||
main.sourcepath_does_not_contain_module=source path does not contain module {0}
|
||||
main.cant.read=cannot read {0}
|
||||
main.Loading_source_files_for_package=Loading source files for package {0}...
|
||||
main.Loading_source_file=Loading source file {0}...
|
||||
|
@ -27,7 +27,7 @@ import java.io.StringWriter;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
@ -158,6 +158,12 @@ public class ModuleTestBase extends TestRunner {
|
||||
}
|
||||
}
|
||||
|
||||
void checkTypesSelected(String... args) throws Exception {
|
||||
for (String arg : args) {
|
||||
checkDocletOutputPresent("Selected", ElementKind.CLASS, arg);
|
||||
}
|
||||
}
|
||||
|
||||
void checkMembersSelected(String... args) throws Exception {
|
||||
for (String arg : args) {
|
||||
checkDocletOutputPresent("Selected", ElementKind.METHOD, arg);
|
||||
@ -280,6 +286,17 @@ public class ModuleTestBase extends TestRunner {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter ps = new PrintWriter(sw);
|
||||
|
||||
DocletEnvironment docEnv = null;
|
||||
|
||||
boolean hasDocComments = false;
|
||||
|
||||
String hasDocComments(Element e) {
|
||||
String comment = docEnv.getElementUtils().getDocComment(e);
|
||||
return comment != null && !comment.isEmpty()
|
||||
? "hasDocComments"
|
||||
: "noDocComments";
|
||||
}
|
||||
|
||||
// csv style output, for simple regex verification
|
||||
void printDataSet(String header, Set<? extends Element> set) {
|
||||
for (Element e : set) {
|
||||
@ -290,7 +307,12 @@ public class ModuleTestBase extends TestRunner {
|
||||
ps.print(FS);
|
||||
ps.print(e.getKind());
|
||||
ps.print(FS);
|
||||
ps.println(e.getQualifiedName());
|
||||
ps.print(e.getQualifiedName());
|
||||
if (hasDocComments) {
|
||||
ps.print(FS);
|
||||
ps.print(hasDocComments(e));
|
||||
}
|
||||
ps.println();
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -299,7 +321,12 @@ public class ModuleTestBase extends TestRunner {
|
||||
ps.print(FS);
|
||||
ps.print(e.getKind());
|
||||
ps.print(FS);
|
||||
ps.println(e.getQualifiedName());
|
||||
ps.print(e.getQualifiedName());
|
||||
if (hasDocComments) {
|
||||
ps.print(FS);
|
||||
ps.print(hasDocComments(e));
|
||||
}
|
||||
ps.println();
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -308,7 +335,12 @@ public class ModuleTestBase extends TestRunner {
|
||||
ps.print(FS);
|
||||
ps.print(ElementKind.CLASS);
|
||||
ps.print(FS);
|
||||
ps.println(e.getQualifiedName());
|
||||
ps.print(e.getQualifiedName());
|
||||
if (hasDocComments) {
|
||||
ps.print(FS);
|
||||
ps.print(hasDocComments(e));
|
||||
}
|
||||
ps.println();
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -338,7 +370,12 @@ public class ModuleTestBase extends TestRunner {
|
||||
ps.print(FS);
|
||||
ps.print(fqn);
|
||||
ps.print(".");
|
||||
ps.println(e.getSimpleName());
|
||||
ps.print(e.getSimpleName());
|
||||
if (hasDocComments) {
|
||||
ps.print(FS);
|
||||
ps.print(hasDocComments(e));
|
||||
}
|
||||
ps.println();
|
||||
return null;
|
||||
}
|
||||
}.visit(e);
|
||||
@ -347,6 +384,7 @@ public class ModuleTestBase extends TestRunner {
|
||||
|
||||
@Override
|
||||
public boolean run(DocletEnvironment docenv) {
|
||||
this.docEnv = docenv;
|
||||
ps.println("ModuleMode" + FS + docenv.getModuleMode());
|
||||
printDataSet("Specified", docenv.getSpecifiedElements());
|
||||
printDataSet("Included", docenv.getIncludedElements());
|
||||
@ -369,7 +407,9 @@ public class ModuleTestBase extends TestRunner {
|
||||
addEnclosedElements(docenv, result, me);
|
||||
}
|
||||
for (PackageElement pe : ElementFilter.packagesIn(elements)) {
|
||||
addEnclosedElements(docenv, result, docenv.getElementUtils().getModuleOf(pe));
|
||||
ModuleElement mdle = docenv.getElementUtils().getModuleOf(pe);
|
||||
if (mdle != null)
|
||||
addEnclosedElements(docenv, result, mdle);
|
||||
addEnclosedElements(docenv, result, pe);
|
||||
}
|
||||
for (TypeElement te : ElementFilter.typesIn(elements)) {
|
||||
@ -390,7 +430,45 @@ public class ModuleTestBase extends TestRunner {
|
||||
|
||||
@Override
|
||||
public Set<Doclet.Option> getSupportedOptions() {
|
||||
return Collections.emptySet();
|
||||
Option[] options = {
|
||||
new Option() {
|
||||
private final List<String> someOption = Arrays.asList(
|
||||
"-hasDocComments"
|
||||
);
|
||||
|
||||
@Override
|
||||
public int getArgumentCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "print disposition of doc comments on an element";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Option.Kind getKind() {
|
||||
return Option.Kind.STANDARD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNames() {
|
||||
return someOption;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameters() {
|
||||
return "flag";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean process(String opt, List<String> arguments) {
|
||||
hasDocComments = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
return new HashSet<>(Arrays.asList(options));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -35,6 +35,7 @@
|
||||
* @run main Modules
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
@ -320,38 +321,6 @@ public class Modules extends ModuleTestBase {
|
||||
checkMembersSelected("pkg2.B.f");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPatchModuleOption(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
Path modulePath = base.resolve("modules");
|
||||
Path patchPath = base.resolve("patch");
|
||||
|
||||
ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
|
||||
mb1.comment("Module on module path.")
|
||||
.exports("pkg1")
|
||||
.classes("package pkg1; /** Class A */ public class A { }")
|
||||
.build(modulePath);
|
||||
|
||||
tb.writeJavaFiles(patchPath, "package pkg1; /** Class A */ public class A { public static int k; }");
|
||||
new JavacTask(tb)
|
||||
.files(patchPath.resolve("pkg1/A.java"))
|
||||
.run();
|
||||
|
||||
ModuleBuilder mb2 = new ModuleBuilder(tb, "m2");
|
||||
mb2.comment("The second module.")
|
||||
.exports("pkg2")
|
||||
.requires("m1")
|
||||
.classes("package pkg2; /** Class B */ public class B { /** Field f */ public int f = pkg1.A.k; }")
|
||||
.write(src);
|
||||
execTask("--module-source-path", src.toString(),
|
||||
"--patch-module", "m1=" + patchPath.toString(),
|
||||
"--module-path", modulePath.toString(),
|
||||
"--module", "m2");
|
||||
checkModulesSpecified("m2");
|
||||
checkPackagesIncluded("pkg2");
|
||||
checkMembersSelected("pkg2.B.f");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddReadsOption(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
@ -550,6 +519,52 @@ public class Modules extends ModuleTestBase {
|
||||
assertMessagePresent("javadoc: error - module MIA not found");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleModuleOptionWithSourcePath(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
Path mod = createSimpleModule(src, "m1");
|
||||
execTask("--source-path", mod.toString(),
|
||||
"--module", "m1");
|
||||
checkModulesSpecified("m1");
|
||||
checkPackagesIncluded("p");
|
||||
checkTypesIncluded("p.C");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleModuleOptionWithMissingModuleInSourcePath(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
Path mod = createSimpleModule(src, "m1");
|
||||
execNegativeTask("--source-path", mod.toString(),
|
||||
"--module", "m2");
|
||||
assertMessagePresent("source path does not contain module m2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleModuleOptionWithSourcePath(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
Path mod = createSimpleModule(src, "m1");
|
||||
execNegativeTask("--source-path", mod.toString(),
|
||||
"--module", "m1,m2,m3");
|
||||
assertMessagePresent("cannot use source path for multiple modules m1, m2, m3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleModuleOptionWithNoModuleOnSourcePath(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
Path mod1 = Paths.get(src.toString(), "m1");
|
||||
execNegativeTask("--source-path", mod1.toString(),
|
||||
"--module", "m1");
|
||||
assertMessagePresent("module m1 not found on source path");
|
||||
}
|
||||
|
||||
Path createSimpleModule(Path src, String mname) throws IOException {
|
||||
Path mpath = Paths.get(src.toString(), mname);
|
||||
tb.writeJavaFiles(mpath,
|
||||
"module " + mname + " { exports p; }",
|
||||
"package p; public class C { }");
|
||||
return mpath;
|
||||
}
|
||||
|
||||
void createAuxiliaryModules(Path src) throws IOException {
|
||||
|
||||
new ModuleBuilder(tb, "J")
|
||||
|
210
langtools/test/jdk/javadoc/tool/modules/PatchModules.java
Normal file
210
langtools/test/jdk/javadoc/tool/modules/PatchModules.java
Normal file
@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (c) 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 8175346
|
||||
* @summary Test patch module options
|
||||
* @modules
|
||||
* jdk.javadoc/jdk.javadoc.internal.api
|
||||
* jdk.javadoc/jdk.javadoc.internal.tool
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @library /tools/lib
|
||||
* @build toolbox.ToolBox toolbox.TestRunner
|
||||
* @run main PatchModules
|
||||
*/
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import toolbox.*;
|
||||
|
||||
public class PatchModules extends ModuleTestBase {
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
new PatchModules().runTests();
|
||||
}
|
||||
|
||||
// Case A.1, m2 augmenting m1
|
||||
@Test
|
||||
public void testPatchModuleOption(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
Path modulePath = base.resolve("modules");
|
||||
Path patchPath = base.resolve("patch");
|
||||
|
||||
ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
|
||||
mb1.comment("Module on module path.")
|
||||
.exports("pkg1")
|
||||
.classes("package pkg1; /** Class A */ public class A { }")
|
||||
.build(modulePath);
|
||||
|
||||
tb.writeJavaFiles(patchPath, "package pkg1; /** Class A */ public class A { public static int k; }");
|
||||
new JavacTask(tb)
|
||||
.files(patchPath.resolve("pkg1/A.java"))
|
||||
.run();
|
||||
|
||||
ModuleBuilder mb2 = new ModuleBuilder(tb, "m2");
|
||||
mb2.comment("The second module.")
|
||||
.exports("pkg2")
|
||||
.requires("m1")
|
||||
.classes("package pkg2; /** Class B */ public class B { /** Field f */ public int f = pkg1.A.k; }")
|
||||
.write(src);
|
||||
execTask("--module-source-path", src.toString(),
|
||||
"--patch-module", "m1=" + patchPath.toString(),
|
||||
"--module-path", modulePath.toString(),
|
||||
"--module", "m2");
|
||||
checkModulesSpecified("m2");
|
||||
checkPackagesIncluded("pkg2");
|
||||
checkMembersSelected("pkg2.B.f");
|
||||
}
|
||||
|
||||
// Case A.2: use package, source form of m1 augmenting binary form of m1
|
||||
@Test
|
||||
public void testPatchModuleWithPackage(Path base) throws Exception {
|
||||
Path modulePath = base.resolve("modules");
|
||||
Path moduleSrcPath = base.resolve("modulesSrc");
|
||||
|
||||
Path mpath = Paths.get(moduleSrcPath.toString(), "m1");
|
||||
|
||||
ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
|
||||
mb1.comment("Module m1.")
|
||||
.exports("pkg1")
|
||||
.classes("package pkg1; /** Class A */ public class A { }")
|
||||
.classes("package pkg1.pkg2; /** Class B */ public class B { }")
|
||||
.build(modulePath);
|
||||
|
||||
execTask("-hasDocComments",
|
||||
"--module-path", modulePath.toString(),
|
||||
"--add-modules", "m1",
|
||||
"--patch-module", "m1=" + mpath.toString(),
|
||||
"pkg1");
|
||||
checkTypesIncluded("pkg1.A hasDocComments");
|
||||
}
|
||||
|
||||
// Case A.2: use subpackages, source form of m1 augmenting binary form of m1
|
||||
@Test
|
||||
public void testPatchModuleWithSubPackages(Path base) throws Exception {
|
||||
Path modulePath = base.resolve("modules");
|
||||
Path moduleSrcPath = base.resolve("modulesSrc");
|
||||
|
||||
Path mpath = Paths.get(moduleSrcPath.toString(), "m1");
|
||||
|
||||
ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
|
||||
mb1.comment("Module m1.")
|
||||
.exports("pkg1")
|
||||
.classes("package pkg1; /** Class A */ public class A { }")
|
||||
.classes("package pkg1.pkg2; /** Class B */ public class B { }")
|
||||
.build(modulePath);
|
||||
|
||||
execTask("-hasDocComments",
|
||||
"--module-path", modulePath.toString(),
|
||||
"--add-modules", "m1",
|
||||
"--patch-module", "m1=" + mpath.toString(),
|
||||
"-subpackages", "pkg1");
|
||||
checkTypesIncluded("pkg1.A hasDocComments");
|
||||
checkTypesIncluded("pkg1.pkg2.B hasDocComments");
|
||||
}
|
||||
|
||||
// Case B.1: (jsr166) augment and override system module
|
||||
@Test
|
||||
public void testPatchModuleModifyingSystemModule(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
Path patchSrc = base.resolve("patch");
|
||||
|
||||
// build the patching sources
|
||||
tb.writeJavaFiles(patchSrc, "package java.util;\n" +
|
||||
"/** Class Collection */\n" +
|
||||
"public interface Collection<K> {}");
|
||||
|
||||
tb.writeJavaFiles(patchSrc, "package java.util;\n"
|
||||
+ "/** Class MyCollection */\n" +
|
||||
"public interface MyCollection<K> extends Collection {}");
|
||||
|
||||
execTask("-hasDocComments", "--patch-module", "java.base=" + patchSrc.toString(),
|
||||
"java.util");
|
||||
|
||||
checkPackagesSpecified("java.util");
|
||||
checkTypesIncluded("java.util.Collection hasDocComments",
|
||||
"java.util.MyCollection hasDocComments");
|
||||
}
|
||||
|
||||
// Case C.1: patch a user module's sources using source path
|
||||
@Test
|
||||
public void testPatchModuleUsingSourcePath(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
Path patchSrc = base.resolve("patch");
|
||||
|
||||
ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
|
||||
mb1.comment("Module m1.")
|
||||
.exports("pkg1")
|
||||
.classes("package pkg1; /** Class A */ public class A { }")
|
||||
.write(src);
|
||||
|
||||
// build the patching module
|
||||
tb.writeJavaFiles(patchSrc, "package pkg1;\n" +
|
||||
"/** Class A */ public class A extends java.util.ArrayList { }");
|
||||
tb.writeJavaFiles(patchSrc, "package pkg1;\n"
|
||||
+ "/** Class B */ public class B { }");
|
||||
|
||||
Path m1src = Paths.get(src.toString(), "m1");
|
||||
|
||||
execTask("--source-path", m1src.toString(),
|
||||
"--patch-module", "m1=" + patchSrc.toString(),
|
||||
"pkg1");
|
||||
|
||||
checkPackagesSpecified("pkg1");
|
||||
checkModulesIncluded("m1");
|
||||
checkTypesIncluded("pkg1.A", "pkg1.B");
|
||||
}
|
||||
|
||||
// Case C.2: patch a user module's sources using module source path
|
||||
@Test
|
||||
public void testPatchModuleWithModuleSourcePath(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
Path patchSrc = base.resolve("patch");
|
||||
|
||||
ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
|
||||
mb1.comment("Module on module-source-path.")
|
||||
.exports("pkg1")
|
||||
.classes("package pkg1; /** Class A */ public class A { }")
|
||||
.write(src);
|
||||
|
||||
// build the patching module
|
||||
tb.writeJavaFiles(patchSrc, "package pkg1;\n" +
|
||||
"/** Class A */ public class A extends java.util.ArrayList { }");
|
||||
tb.writeJavaFiles(patchSrc, "package pkg1;\n"
|
||||
+ "/** Class B */ public class B { }");
|
||||
|
||||
|
||||
execTask("--module-source-path", src.toString(),
|
||||
"--add-modules", "m1",
|
||||
"--patch-module", "m1=" + patchSrc.toString(),
|
||||
"pkg1");
|
||||
|
||||
checkPackagesSpecified("pkg1");
|
||||
checkModulesIncluded("m1");
|
||||
checkTypesIncluded("pkg1.A", "pkg1.B");
|
||||
}
|
||||
|
||||
}
|
99
langtools/test/jdk/javadoc/tool/modules/ReleaseOptions.java
Normal file
99
langtools/test/jdk/javadoc/tool/modules/ReleaseOptions.java
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 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 8175346
|
||||
* @summary Test release option interactions
|
||||
* @modules
|
||||
* jdk.javadoc/jdk.javadoc.internal.api
|
||||
* jdk.javadoc/jdk.javadoc.internal.tool
|
||||
* jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* @library /tools/lib
|
||||
* @build toolbox.ToolBox toolbox.TestRunner
|
||||
* @run main ReleaseOptions
|
||||
*/
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import toolbox.*;
|
||||
|
||||
public class ReleaseOptions extends ModuleTestBase {
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
new ReleaseOptions().runTests();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReleaseWithPatchModule(Path base) throws Exception {
|
||||
Path src = Paths.get(base.toString(), "src");
|
||||
Path mpath = Paths.get(src. toString(), "m");
|
||||
|
||||
tb.writeJavaFiles(mpath,
|
||||
"module m { exports p; }",
|
||||
"package p; public class C { }");
|
||||
|
||||
Task.Result result = execNegativeTask("--release", "8",
|
||||
"--patch-module", "m=" + mpath.toString(),
|
||||
"p");
|
||||
assertMessagePresent(".*No source files for package p.*");
|
||||
assertMessageNotPresent(".*Exception*");
|
||||
assertMessageNotPresent(".java.lang.AssertionError.*");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReleaseWithSourcepath(Path base) throws Exception {
|
||||
Path src = Paths.get(base.toString(), "src");
|
||||
Path mpath = Paths.get(src. toString(), "m");
|
||||
|
||||
tb.writeJavaFiles(mpath,
|
||||
"module m { exports p; }",
|
||||
"package p; public class C { }");
|
||||
|
||||
Task.Result result = execNegativeTask("--release", "8",
|
||||
"--source-path", mpath.toString(),
|
||||
"--module", "m");
|
||||
assertMessagePresent(".*(use -source 9 or higher to enable modules).*");
|
||||
assertMessageNotPresent(".*Exception*");
|
||||
assertMessageNotPresent(".java.lang.AssertionError.*");
|
||||
}
|
||||
|
||||
// @Test TBD, JDK-8175277, argument validation should fail on this
|
||||
// public void testReleaseWithModuleSourcepath(Path base) throws Exception {
|
||||
// Path src = Paths.get(base.toString(), "src");
|
||||
// Path mpath = Paths.get(src.toString(), "m");
|
||||
//
|
||||
// tb.writeJavaFiles(mpath,
|
||||
// "module m { exports p; }",
|
||||
// "package p; public class C { }");
|
||||
//
|
||||
// Task.Result result = execNegativeTask("--release", "8",
|
||||
// "--module-source-path", src.toString(),
|
||||
// "--module", "m");
|
||||
// assertMessagePresent(".*(use -source 9 or higher to enable modules).*");
|
||||
// assertMessageNotPresent(".*Exception*");
|
||||
// assertMessageNotPresent(".java.lang.AssertionError.*");
|
||||
// }
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user