1.1 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java Thu Mar 16 17:13:10 2017 -0700
1.2 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java Thu Mar 16 18:50:50 2017 -0700
1.3 @@ -53,6 +53,7 @@
1.4 import javax.tools.StandardLocation;
1.5
1.6 import com.sun.tools.javac.code.Kinds.Kind;
1.7 +import com.sun.tools.javac.code.Source;
1.8 import com.sun.tools.javac.code.Symbol;
1.9 import com.sun.tools.javac.code.Symbol.ClassSymbol;
1.10 import com.sun.tools.javac.code.Symbol.CompletionFailure;
1.11 @@ -60,8 +61,11 @@
1.12 import com.sun.tools.javac.code.Symbol.PackageSymbol;
1.13 import com.sun.tools.javac.code.Symtab;
1.14 import com.sun.tools.javac.comp.Modules;
1.15 +import com.sun.tools.javac.main.JavaCompiler;
1.16 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
1.17 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
1.18 +import com.sun.tools.javac.tree.JCTree.JCModuleDecl;
1.19 +import com.sun.tools.javac.tree.TreeInfo;
1.20 import com.sun.tools.javac.util.Context;
1.21 import com.sun.tools.javac.util.ListBuffer;
1.22 import com.sun.tools.javac.util.Name;
1.23 @@ -70,7 +74,9 @@
1.24 import jdk.javadoc.doclet.DocletEnvironment.ModuleMode;
1.25
1.26 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
1.27 +
1.28 import static javax.tools.JavaFileObject.Kind.*;
1.29 +
1.30 import static jdk.javadoc.internal.tool.Main.Result.*;
1.31 import static jdk.javadoc.internal.tool.JavadocTool.isValidClassName;
1.32
1.33 @@ -153,10 +159,11 @@
1.34 private final Symtab syms;
1.35 private final Names names;
1.36 private final JavaFileManager fm;
1.37 - private final Location location;
1.38 + private final List<Location> locations;
1.39 private final Modules modules;
1.40 private final Map<ToolOption, Object> opts;
1.41 private final Messager messager;
1.42 + private final JavaCompiler compiler;
1.43
1.44 private final Map<String, Entry> entries = new LinkedHashMap<>();
1.45
1.46 @@ -201,12 +208,22 @@
1.47 this.modules = Modules.instance(context);
1.48 this.opts = opts;
1.49 this.messager = Messager.instance0(context);
1.50 + this.compiler = JavaCompiler.instance(context);
1.51 + Source source = Source.instance(context);
1.52
1.53 - this.location = modules.multiModuleMode
1.54 - ? StandardLocation.MODULE_SOURCE_PATH
1.55 - : toolEnv.fileManager.hasLocation(StandardLocation.SOURCE_PATH)
1.56 - ? StandardLocation.SOURCE_PATH
1.57 - : StandardLocation.CLASS_PATH;
1.58 + List<Location> locs = new ArrayList<>();
1.59 + if (modules.multiModuleMode) {
1.60 + locs.add(StandardLocation.MODULE_SOURCE_PATH);
1.61 + } else {
1.62 + if (toolEnv.fileManager.hasLocation(StandardLocation.SOURCE_PATH))
1.63 + locs.add(StandardLocation.SOURCE_PATH);
1.64 + else
1.65 + locs.add(StandardLocation.CLASS_PATH);
1.66 + }
1.67 + if (source.allowModules() && toolEnv.fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH))
1.68 + locs.add(StandardLocation.PATCH_MODULE_PATH);
1.69 + this.locations = Collections.unmodifiableList(locs);
1.70 +
1.71 getEntry("").excluded = false;
1.72
1.73 accessFilter = new ModifierFilter(opts);
1.74 @@ -341,6 +358,52 @@
1.75 return this;
1.76 }
1.77
1.78 + /*
1.79 + * This method sanity checks the following cases:
1.80 + * a. a source-path containing a single module and many modules specified with --module
1.81 + * b. no modules on source-path
1.82 + * c. mismatched source-path and many modules specified with --module
1.83 + */
1.84 + void sanityCheckSourcePathModules(List<String> moduleNames) throws ToolException {
1.85 + if (!haveSourceLocationWithModule)
1.86 + return;
1.87 +
1.88 + if (moduleNames.size() > 1) {
1.89 + String text = messager.getText("main.cannot_use_sourcepath_for_modules",
1.90 + String.join(", ", moduleNames));
1.91 + throw new ToolException(CMDERR, text);
1.92 + }
1.93 +
1.94 + String foundModule = getModuleName(StandardLocation.SOURCE_PATH);
1.95 + if (foundModule == null) {
1.96 + String text = messager.getText("main.module_not_found_on_sourcepath", moduleNames.get(0));
1.97 + throw new ToolException(CMDERR, text);
1.98 + }
1.99 +
1.100 + if (!moduleNames.get(0).equals(foundModule)) {
1.101 + String text = messager.getText("main.sourcepath_does_not_contain_module", moduleNames.get(0));
1.102 + throw new ToolException(CMDERR, text);
1.103 + }
1.104 + }
1.105 +
1.106 + private String getModuleName(Location location) throws ToolException {
1.107 + try {
1.108 + JavaFileObject jfo = fm.getJavaFileForInput(location,
1.109 + "module-info", JavaFileObject.Kind.SOURCE);
1.110 + if (jfo != null) {
1.111 + JCCompilationUnit jcu = compiler.parse(jfo);
1.112 + JCModuleDecl module = TreeInfo.getModule(jcu);
1.113 + if (module != null) {
1.114 + return module.getName().toString();
1.115 + }
1.116 + }
1.117 + } catch (IOException ioe) {
1.118 + String text = messager.getText("main.file.manager.list", location);
1.119 + throw new ToolException(SYSERR, text, ioe);
1.120 + }
1.121 + return null;
1.122 + }
1.123 +
1.124 @SuppressWarnings("unchecked")
1.125 ElementsTable scanSpecifiedItems() throws ToolException {
1.126
1.127 @@ -349,15 +412,17 @@
1.128 s -> Collections.EMPTY_LIST);
1.129 List<String> mlist = new ArrayList<>();
1.130 for (String m : moduleNames) {
1.131 - Location moduleLoc = getModuleLocation(location, m);
1.132 - if (moduleLoc == null) {
1.133 + List<Location> moduleLocations = getModuleLocation(locations, m);
1.134 + if (moduleLocations.isEmpty()) {
1.135 String text = messager.getText("main.module_not_found", m);
1.136 throw new ToolException(CMDERR, text);
1.137 - } else {
1.138 - mlist.add(m);
1.139 - ModuleSymbol msym = syms.enterModule(names.fromString(m));
1.140 - specifiedModuleElements.add((ModuleElement) msym);
1.141 }
1.142 + if (moduleLocations.contains(StandardLocation.SOURCE_PATH)) {
1.143 + sanityCheckSourcePathModules(moduleNames);
1.144 + }
1.145 + mlist.add(m);
1.146 + ModuleSymbol msym = syms.enterModule(names.fromString(m));
1.147 + specifiedModuleElements.add((ModuleElement) msym);
1.148 }
1.149
1.150 // scan for modules with qualified packages
1.151 @@ -448,35 +513,41 @@
1.152 });
1.153
1.154 for (ModulePackage modpkg : subPackages) {
1.155 - Location packageLocn = getLocation(modpkg);
1.156 - Iterable<JavaFileObject> list = null;
1.157 - try {
1.158 - list = fm.list(packageLocn, modpkg.packageName, sourceKinds, true);
1.159 - } catch (IOException ioe) {
1.160 - String text = messager.getText("main.file.manager.list", modpkg.packageName);
1.161 - throw new ToolException(SYSERR, text, ioe);
1.162 + List<Location> locs = getLocation(modpkg);
1.163 + for (Location loc : locs) {
1.164 + addPackagesFromLocations(loc, modpkg);
1.165 }
1.166 - for (JavaFileObject fo : list) {
1.167 - String binaryName = fm.inferBinaryName(packageLocn, fo);
1.168 - String pn = getPackageName(binaryName);
1.169 - String simpleName = getSimpleName(binaryName);
1.170 - Entry e = getEntry(pn);
1.171 - if (!e.isExcluded() && isValidClassName(simpleName)) {
1.172 - ModuleSymbol msym = (modpkg.hasModule())
1.173 - ? syms.getModule(names.fromString(modpkg.moduleName))
1.174 - : findModuleOfPackageName(modpkg.packageName);
1.175 + }
1.176 + }
1.177
1.178 - if (msym != null && !msym.isUnnamed()) {
1.179 - syms.enterPackage(msym, names.fromString(pn));
1.180 - ModulePackage npkg = new ModulePackage(msym.toString(), pn);
1.181 - cmdLinePackages.add(npkg);
1.182 - } else {
1.183 - cmdLinePackages.add(e.modpkg);
1.184 - }
1.185 - e.files = (e.files == null
1.186 - ? com.sun.tools.javac.util.List.of(fo)
1.187 - : e.files.prepend(fo));
1.188 + private void addPackagesFromLocations(Location packageLocn, ModulePackage modpkg) throws ToolException {
1.189 + Iterable<JavaFileObject> list = null;
1.190 + try {
1.191 + list = fm.list(packageLocn, modpkg.packageName, sourceKinds, true);
1.192 + } catch (IOException ioe) {
1.193 + String text = messager.getText("main.file.manager.list", modpkg.packageName);
1.194 + throw new ToolException(SYSERR, text, ioe);
1.195 + }
1.196 + for (JavaFileObject fo : list) {
1.197 + String binaryName = fm.inferBinaryName(packageLocn, fo);
1.198 + String pn = getPackageName(binaryName);
1.199 + String simpleName = getSimpleName(binaryName);
1.200 + Entry e = getEntry(pn);
1.201 + if (!e.isExcluded() && isValidClassName(simpleName)) {
1.202 + ModuleSymbol msym = (modpkg.hasModule())
1.203 + ? syms.getModule(names.fromString(modpkg.moduleName))
1.204 + : findModuleOfPackageName(modpkg.packageName);
1.205 +
1.206 + if (msym != null && !msym.isUnnamed()) {
1.207 + syms.enterPackage(msym, names.fromString(pn));
1.208 + ModulePackage npkg = new ModulePackage(msym.toString(), pn);
1.209 + cmdLinePackages.add(npkg);
1.210 + } else {
1.211 + cmdLinePackages.add(e.modpkg);
1.212 }
1.213 + e.files = (e.files == null
1.214 + ? com.sun.tools.javac.util.List.of(fo)
1.215 + : e.files.prepend(fo));
1.216 }
1.217 }
1.218 }
1.219 @@ -544,20 +615,23 @@
1.220 private Set<PackageElement> getAllModulePackages(ModuleElement mdle) throws ToolException {
1.221 Set<PackageElement> result = new HashSet<>();
1.222 ModuleSymbol msym = (ModuleSymbol) mdle;
1.223 - Location msymloc = getModuleLocation(location, msym.name.toString());
1.224 - try {
1.225 - for (JavaFileObject fo : fm.list(msymloc, "", sourceKinds, true)) {
1.226 - if (fo.getName().endsWith("module-info.java"))
1.227 - continue;
1.228 - String binaryName = fm.inferBinaryName(msymloc, fo);
1.229 - String pn = getPackageName(binaryName);
1.230 - PackageSymbol psym = syms.enterPackage(msym, names.fromString(pn));
1.231 - result.add((PackageElement) psym);
1.232 + List<Location> msymlocs = getModuleLocation(locations, msym.name.toString());
1.233 + for (Location msymloc : msymlocs) {
1.234 + try {
1.235 + for (JavaFileObject fo : fm.list(msymloc, "", sourceKinds, true)) {
1.236 + if (fo.getName().endsWith("module-info.java")) {
1.237 + continue;
1.238 + }
1.239 + String binaryName = fm.inferBinaryName(msymloc, fo);
1.240 + String pn = getPackageName(binaryName);
1.241 + PackageSymbol psym = syms.enterPackage(msym, names.fromString(pn));
1.242 + result.add((PackageElement) psym);
1.243 + }
1.244 +
1.245 + } catch (IOException ioe) {
1.246 + String text = messager.getText("main.file.manager.list", msymloc.getName());
1.247 + throw new ToolException(SYSERR, text, ioe);
1.248 }
1.249 -
1.250 - } catch (IOException ioe) {
1.251 - String text = messager.getText("main.file.manager.list", msymloc.getName());
1.252 - throw new ToolException(SYSERR, text, ioe);
1.253 }
1.254 return result;
1.255 }
1.256 @@ -741,25 +815,25 @@
1.257 }
1.258
1.259 ListBuffer<JavaFileObject> lb = new ListBuffer<>();
1.260 - Location packageLocn = getLocation(modpkg);
1.261 - if (packageLocn == null) {
1.262 + List<Location> locs = getLocation(modpkg);
1.263 + if (locs.isEmpty()) {
1.264 return Collections.emptyList();
1.265 }
1.266 String pname = modpkg.packageName;
1.267 -
1.268 - try {
1.269 - for (JavaFileObject fo : fm.list(packageLocn, pname, sourceKinds, recurse)) {
1.270 - String binaryName = fm.inferBinaryName(packageLocn, fo);
1.271 - String simpleName = getSimpleName(binaryName);
1.272 - if (isValidClassName(simpleName)) {
1.273 - lb.append(fo);
1.274 + for (Location packageLocn : locs) {
1.275 + try {
1.276 + for (JavaFileObject fo : fm.list(packageLocn, pname, sourceKinds, recurse)) {
1.277 + String binaryName = fm.inferBinaryName(packageLocn, fo);
1.278 + String simpleName = getSimpleName(binaryName);
1.279 + if (isValidClassName(simpleName)) {
1.280 + lb.append(fo);
1.281 + }
1.282 }
1.283 + } catch (IOException ioe) {
1.284 + String text = messager.getText("main.file.manager.list", pname);
1.285 + throw new ToolException(SYSERR, text, ioe);
1.286 }
1.287 - } catch (IOException ioe) {
1.288 - String text = messager.getText("main.file.manager.list", pname);
1.289 - throw new ToolException(SYSERR, text, ioe);
1.290 }
1.291 -
1.292 return lb.toList();
1.293 }
1.294
1.295 @@ -774,24 +848,49 @@
1.296 return null;
1.297 }
1.298
1.299 - private Location getLocation(ModulePackage modpkg) throws ToolException {
1.300 - if (location != StandardLocation.MODULE_SOURCE_PATH) {
1.301 - return location;
1.302 + private List<Location> getLocation(ModulePackage modpkg) throws ToolException {
1.303 + if (locations.size() == 1 && !locations.contains(StandardLocation.MODULE_SOURCE_PATH)) {
1.304 + return Collections.singletonList(locations.get(0));
1.305 }
1.306
1.307 if (modpkg.hasModule()) {
1.308 - return getModuleLocation(location, modpkg.moduleName);
1.309 + return getModuleLocation(locations, modpkg.moduleName);
1.310 }
1.311 // TODO: handle invalid results better.
1.312 ModuleSymbol msym = findModuleOfPackageName(modpkg.packageName);
1.313 if (msym == null) {
1.314 - return null;
1.315 + return Collections.emptyList();
1.316 }
1.317 - return getModuleLocation(location, msym.name.toString());
1.318 + return getModuleLocation(locations, msym.name.toString());
1.319 }
1.320
1.321 - private Location getModuleLocation(Location location, String msymName)
1.322 - throws ToolException {
1.323 + boolean haveSourceLocationWithModule = false;
1.324 +
1.325 + private List<Location> getModuleLocation(List<Location> locations, String msymName) throws ToolException {
1.326 + List<Location> out = new ArrayList<>();
1.327 + // search in the patch module first, this overrides others
1.328 + if (locations.contains(StandardLocation.PATCH_MODULE_PATH)) {
1.329 + Location loc = getModuleLocation(StandardLocation.PATCH_MODULE_PATH, msymName);
1.330 + if (loc != null)
1.331 + out.add(loc);
1.332 + }
1.333 + for (Location location : locations) {
1.334 + // skip patch module, already done
1.335 + if (location == StandardLocation.PATCH_MODULE_PATH) {
1.336 + continue;
1.337 + } else if (location == StandardLocation.MODULE_SOURCE_PATH) {
1.338 + Location loc = getModuleLocation(location, msymName);
1.339 + if (loc != null)
1.340 + out.add(loc);
1.341 + } else if (location == StandardLocation.SOURCE_PATH) {
1.342 + haveSourceLocationWithModule = true;
1.343 + out.add(StandardLocation.SOURCE_PATH);
1.344 + }
1.345 + }
1.346 + return out;
1.347 + }
1.348 +
1.349 + private Location getModuleLocation(Location location, String msymName) throws ToolException {
1.350 try {
1.351 return fm.getLocationForModule(location, msymName);
1.352 } catch (IOException ioe) {
2.1 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties Thu Mar 16 17:13:10 2017 -0700
2.2 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties Thu Mar 16 18:50:50 2017 -0700
2.3 @@ -258,6 +258,9 @@
2.4 main.invalid_flag=invalid flag: {0}
2.5 main.No_modules_packages_or_classes_specified=No modules, packages or classes specified.
2.6 main.module_not_found=module {0} not found.\n
2.7 +main.cannot_use_sourcepath_for_modules=cannot use source path for multiple modules {0}
2.8 +main.module_not_found_on_sourcepath=module {0} not found on source path
2.9 +main.sourcepath_does_not_contain_module=source path does not contain module {0}
2.10 main.cant.read=cannot read {0}
2.11 main.Loading_source_files_for_package=Loading source files for package {0}...
2.12 main.Loading_source_file=Loading source file {0}...
3.1 --- a/test/jdk/javadoc/tool/modules/ModuleTestBase.java Thu Mar 16 17:13:10 2017 -0700
3.2 +++ b/test/jdk/javadoc/tool/modules/ModuleTestBase.java Thu Mar 16 18:50:50 2017 -0700
3.3 @@ -27,7 +27,7 @@
3.4 import java.nio.file.Path;
3.5 import java.nio.file.Paths;
3.6 import java.util.Arrays;
3.7 -import java.util.Collections;
3.8 +import java.util.HashSet;
3.9 import java.util.List;
3.10 import java.util.Locale;
3.11 import java.util.Set;
3.12 @@ -158,6 +158,12 @@
3.13 }
3.14 }
3.15
3.16 + void checkTypesSelected(String... args) throws Exception {
3.17 + for (String arg : args) {
3.18 + checkDocletOutputPresent("Selected", ElementKind.CLASS, arg);
3.19 + }
3.20 + }
3.21 +
3.22 void checkMembersSelected(String... args) throws Exception {
3.23 for (String arg : args) {
3.24 checkDocletOutputPresent("Selected", ElementKind.METHOD, arg);
3.25 @@ -280,6 +286,17 @@
3.26 StringWriter sw = new StringWriter();
3.27 PrintWriter ps = new PrintWriter(sw);
3.28
3.29 + DocletEnvironment docEnv = null;
3.30 +
3.31 + boolean hasDocComments = false;
3.32 +
3.33 + String hasDocComments(Element e) {
3.34 + String comment = docEnv.getElementUtils().getDocComment(e);
3.35 + return comment != null && !comment.isEmpty()
3.36 + ? "hasDocComments"
3.37 + : "noDocComments";
3.38 + }
3.39 +
3.40 // csv style output, for simple regex verification
3.41 void printDataSet(String header, Set<? extends Element> set) {
3.42 for (Element e : set) {
3.43 @@ -290,7 +307,12 @@
3.44 ps.print(FS);
3.45 ps.print(e.getKind());
3.46 ps.print(FS);
3.47 - ps.println(e.getQualifiedName());
3.48 + ps.print(e.getQualifiedName());
3.49 + if (hasDocComments) {
3.50 + ps.print(FS);
3.51 + ps.print(hasDocComments(e));
3.52 + }
3.53 + ps.println();
3.54 return null;
3.55 }
3.56
3.57 @@ -299,7 +321,12 @@
3.58 ps.print(FS);
3.59 ps.print(e.getKind());
3.60 ps.print(FS);
3.61 - ps.println(e.getQualifiedName());
3.62 + ps.print(e.getQualifiedName());
3.63 + if (hasDocComments) {
3.64 + ps.print(FS);
3.65 + ps.print(hasDocComments(e));
3.66 + }
3.67 + ps.println();
3.68 return null;
3.69 }
3.70
3.71 @@ -308,7 +335,12 @@
3.72 ps.print(FS);
3.73 ps.print(ElementKind.CLASS);
3.74 ps.print(FS);
3.75 - ps.println(e.getQualifiedName());
3.76 + ps.print(e.getQualifiedName());
3.77 + if (hasDocComments) {
3.78 + ps.print(FS);
3.79 + ps.print(hasDocComments(e));
3.80 + }
3.81 + ps.println();
3.82 return null;
3.83 }
3.84
3.85 @@ -338,7 +370,12 @@
3.86 ps.print(FS);
3.87 ps.print(fqn);
3.88 ps.print(".");
3.89 - ps.println(e.getSimpleName());
3.90 + ps.print(e.getSimpleName());
3.91 + if (hasDocComments) {
3.92 + ps.print(FS);
3.93 + ps.print(hasDocComments(e));
3.94 + }
3.95 + ps.println();
3.96 return null;
3.97 }
3.98 }.visit(e);
3.99 @@ -347,6 +384,7 @@
3.100
3.101 @Override
3.102 public boolean run(DocletEnvironment docenv) {
3.103 + this.docEnv = docenv;
3.104 ps.println("ModuleMode" + FS + docenv.getModuleMode());
3.105 printDataSet("Specified", docenv.getSpecifiedElements());
3.106 printDataSet("Included", docenv.getIncludedElements());
3.107 @@ -369,7 +407,9 @@
3.108 addEnclosedElements(docenv, result, me);
3.109 }
3.110 for (PackageElement pe : ElementFilter.packagesIn(elements)) {
3.111 - addEnclosedElements(docenv, result, docenv.getElementUtils().getModuleOf(pe));
3.112 + ModuleElement mdle = docenv.getElementUtils().getModuleOf(pe);
3.113 + if (mdle != null)
3.114 + addEnclosedElements(docenv, result, mdle);
3.115 addEnclosedElements(docenv, result, pe);
3.116 }
3.117 for (TypeElement te : ElementFilter.typesIn(elements)) {
3.118 @@ -390,7 +430,45 @@
3.119
3.120 @Override
3.121 public Set<Doclet.Option> getSupportedOptions() {
3.122 - return Collections.emptySet();
3.123 + Option[] options = {
3.124 + new Option() {
3.125 + private final List<String> someOption = Arrays.asList(
3.126 + "-hasDocComments"
3.127 + );
3.128 +
3.129 + @Override
3.130 + public int getArgumentCount() {
3.131 + return 0;
3.132 + }
3.133 +
3.134 + @Override
3.135 + public String getDescription() {
3.136 + return "print disposition of doc comments on an element";
3.137 + }
3.138 +
3.139 + @Override
3.140 + public Option.Kind getKind() {
3.141 + return Option.Kind.STANDARD;
3.142 + }
3.143 +
3.144 + @Override
3.145 + public List<String> getNames() {
3.146 + return someOption;
3.147 + }
3.148 +
3.149 + @Override
3.150 + public String getParameters() {
3.151 + return "flag";
3.152 + }
3.153 +
3.154 + @Override
3.155 + public boolean process(String opt, List<String> arguments) {
3.156 + hasDocComments = true;
3.157 + return true;
3.158 + }
3.159 + }
3.160 + };
3.161 + return new HashSet<>(Arrays.asList(options));
3.162 }
3.163
3.164 @Override
4.1 --- a/test/jdk/javadoc/tool/modules/Modules.java Thu Mar 16 17:13:10 2017 -0700
4.2 +++ b/test/jdk/javadoc/tool/modules/Modules.java Thu Mar 16 18:50:50 2017 -0700
4.3 @@ -35,6 +35,7 @@
4.4 * @run main Modules
4.5 */
4.6
4.7 +import java.io.File;
4.8 import java.io.IOException;
4.9 import java.nio.file.Files;
4.10 import java.nio.file.Path;
4.11 @@ -321,38 +322,6 @@
4.12 }
4.13
4.14 @Test
4.15 - public void testPatchModuleOption(Path base) throws Exception {
4.16 - Path src = base.resolve("src");
4.17 - Path modulePath = base.resolve("modules");
4.18 - Path patchPath = base.resolve("patch");
4.19 -
4.20 - ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
4.21 - mb1.comment("Module on module path.")
4.22 - .exports("pkg1")
4.23 - .classes("package pkg1; /** Class A */ public class A { }")
4.24 - .build(modulePath);
4.25 -
4.26 - tb.writeJavaFiles(patchPath, "package pkg1; /** Class A */ public class A { public static int k; }");
4.27 - new JavacTask(tb)
4.28 - .files(patchPath.resolve("pkg1/A.java"))
4.29 - .run();
4.30 -
4.31 - ModuleBuilder mb2 = new ModuleBuilder(tb, "m2");
4.32 - mb2.comment("The second module.")
4.33 - .exports("pkg2")
4.34 - .requires("m1")
4.35 - .classes("package pkg2; /** Class B */ public class B { /** Field f */ public int f = pkg1.A.k; }")
4.36 - .write(src);
4.37 - execTask("--module-source-path", src.toString(),
4.38 - "--patch-module", "m1=" + patchPath.toString(),
4.39 - "--module-path", modulePath.toString(),
4.40 - "--module", "m2");
4.41 - checkModulesSpecified("m2");
4.42 - checkPackagesIncluded("pkg2");
4.43 - checkMembersSelected("pkg2.B.f");
4.44 - }
4.45 -
4.46 - @Test
4.47 public void testAddReadsOption(Path base) throws Exception {
4.48 Path src = base.resolve("src");
4.49 Path modulePath = base.resolve("modules");
4.50 @@ -550,6 +519,52 @@
4.51 assertMessagePresent("javadoc: error - module MIA not found");
4.52 }
4.53
4.54 + @Test
4.55 + public void testSingleModuleOptionWithSourcePath(Path base) throws Exception {
4.56 + Path src = base.resolve("src");
4.57 + Path mod = createSimpleModule(src, "m1");
4.58 + execTask("--source-path", mod.toString(),
4.59 + "--module", "m1");
4.60 + checkModulesSpecified("m1");
4.61 + checkPackagesIncluded("p");
4.62 + checkTypesIncluded("p.C");
4.63 + }
4.64 +
4.65 + @Test
4.66 + public void testSingleModuleOptionWithMissingModuleInSourcePath(Path base) throws Exception {
4.67 + Path src = base.resolve("src");
4.68 + Path mod = createSimpleModule(src, "m1");
4.69 + execNegativeTask("--source-path", mod.toString(),
4.70 + "--module", "m2");
4.71 + assertMessagePresent("source path does not contain module m2");
4.72 + }
4.73 +
4.74 + @Test
4.75 + public void testMultipleModuleOptionWithSourcePath(Path base) throws Exception {
4.76 + Path src = base.resolve("src");
4.77 + Path mod = createSimpleModule(src, "m1");
4.78 + execNegativeTask("--source-path", mod.toString(),
4.79 + "--module", "m1,m2,m3");
4.80 + assertMessagePresent("cannot use source path for multiple modules m1, m2, m3");
4.81 + }
4.82 +
4.83 + @Test
4.84 + public void testSingleModuleOptionWithNoModuleOnSourcePath(Path base) throws Exception {
4.85 + Path src = base.resolve("src");
4.86 + Path mod1 = Paths.get(src.toString(), "m1");
4.87 + execNegativeTask("--source-path", mod1.toString(),
4.88 + "--module", "m1");
4.89 + assertMessagePresent("module m1 not found on source path");
4.90 + }
4.91 +
4.92 + Path createSimpleModule(Path src, String mname) throws IOException {
4.93 + Path mpath = Paths.get(src.toString(), mname);
4.94 + tb.writeJavaFiles(mpath,
4.95 + "module " + mname + " { exports p; }",
4.96 + "package p; public class C { }");
4.97 + return mpath;
4.98 + }
4.99 +
4.100 void createAuxiliaryModules(Path src) throws IOException {
4.101
4.102 new ModuleBuilder(tb, "J")
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/test/jdk/javadoc/tool/modules/PatchModules.java Thu Mar 16 18:50:50 2017 -0700
5.3 @@ -0,0 +1,210 @@
5.4 +/*
5.5 + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5.7 + *
5.8 + * This code is free software; you can redistribute it and/or modify it
5.9 + * under the terms of the GNU General Public License version 2 only, as
5.10 + * published by the Free Software Foundation.
5.11 + *
5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5.15 + * version 2 for more details (a copy is included in the LICENSE file that
5.16 + * accompanied this code).
5.17 + *
5.18 + * You should have received a copy of the GNU General Public License version
5.19 + * 2 along with this work; if not, write to the Free Software Foundation,
5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
5.21 + *
5.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
5.23 + * or visit www.oracle.com if you need additional information or have any
5.24 + * questions.
5.25 + */
5.26 +
5.27 +/**
5.28 + * @test
5.29 + * @bug 8175346
5.30 + * @summary Test patch module options
5.31 + * @modules
5.32 + * jdk.javadoc/jdk.javadoc.internal.api
5.33 + * jdk.javadoc/jdk.javadoc.internal.tool
5.34 + * jdk.compiler/com.sun.tools.javac.api
5.35 + * jdk.compiler/com.sun.tools.javac.main
5.36 + * @library /tools/lib
5.37 + * @build toolbox.ToolBox toolbox.TestRunner
5.38 + * @run main PatchModules
5.39 + */
5.40 +
5.41 +import java.nio.file.Path;
5.42 +import java.nio.file.Paths;
5.43 +
5.44 +import toolbox.*;
5.45 +
5.46 +public class PatchModules extends ModuleTestBase {
5.47 +
5.48 + public static void main(String... args) throws Exception {
5.49 + new PatchModules().runTests();
5.50 + }
5.51 +
5.52 + // Case A.1, m2 augmenting m1
5.53 + @Test
5.54 + public void testPatchModuleOption(Path base) throws Exception {
5.55 + Path src = base.resolve("src");
5.56 + Path modulePath = base.resolve("modules");
5.57 + Path patchPath = base.resolve("patch");
5.58 +
5.59 + ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
5.60 + mb1.comment("Module on module path.")
5.61 + .exports("pkg1")
5.62 + .classes("package pkg1; /** Class A */ public class A { }")
5.63 + .build(modulePath);
5.64 +
5.65 + tb.writeJavaFiles(patchPath, "package pkg1; /** Class A */ public class A { public static int k; }");
5.66 + new JavacTask(tb)
5.67 + .files(patchPath.resolve("pkg1/A.java"))
5.68 + .run();
5.69 +
5.70 + ModuleBuilder mb2 = new ModuleBuilder(tb, "m2");
5.71 + mb2.comment("The second module.")
5.72 + .exports("pkg2")
5.73 + .requires("m1")
5.74 + .classes("package pkg2; /** Class B */ public class B { /** Field f */ public int f = pkg1.A.k; }")
5.75 + .write(src);
5.76 + execTask("--module-source-path", src.toString(),
5.77 + "--patch-module", "m1=" + patchPath.toString(),
5.78 + "--module-path", modulePath.toString(),
5.79 + "--module", "m2");
5.80 + checkModulesSpecified("m2");
5.81 + checkPackagesIncluded("pkg2");
5.82 + checkMembersSelected("pkg2.B.f");
5.83 + }
5.84 +
5.85 + // Case A.2: use package, source form of m1 augmenting binary form of m1
5.86 + @Test
5.87 + public void testPatchModuleWithPackage(Path base) throws Exception {
5.88 + Path modulePath = base.resolve("modules");
5.89 + Path moduleSrcPath = base.resolve("modulesSrc");
5.90 +
5.91 + Path mpath = Paths.get(moduleSrcPath.toString(), "m1");
5.92 +
5.93 + ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
5.94 + mb1.comment("Module m1.")
5.95 + .exports("pkg1")
5.96 + .classes("package pkg1; /** Class A */ public class A { }")
5.97 + .classes("package pkg1.pkg2; /** Class B */ public class B { }")
5.98 + .build(modulePath);
5.99 +
5.100 + execTask("-hasDocComments",
5.101 + "--module-path", modulePath.toString(),
5.102 + "--add-modules", "m1",
5.103 + "--patch-module", "m1=" + mpath.toString(),
5.104 + "pkg1");
5.105 + checkTypesIncluded("pkg1.A hasDocComments");
5.106 + }
5.107 +
5.108 + // Case A.2: use subpackages, source form of m1 augmenting binary form of m1
5.109 + @Test
5.110 + public void testPatchModuleWithSubPackages(Path base) throws Exception {
5.111 + Path modulePath = base.resolve("modules");
5.112 + Path moduleSrcPath = base.resolve("modulesSrc");
5.113 +
5.114 + Path mpath = Paths.get(moduleSrcPath.toString(), "m1");
5.115 +
5.116 + ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
5.117 + mb1.comment("Module m1.")
5.118 + .exports("pkg1")
5.119 + .classes("package pkg1; /** Class A */ public class A { }")
5.120 + .classes("package pkg1.pkg2; /** Class B */ public class B { }")
5.121 + .build(modulePath);
5.122 +
5.123 + execTask("-hasDocComments",
5.124 + "--module-path", modulePath.toString(),
5.125 + "--add-modules", "m1",
5.126 + "--patch-module", "m1=" + mpath.toString(),
5.127 + "-subpackages", "pkg1");
5.128 + checkTypesIncluded("pkg1.A hasDocComments");
5.129 + checkTypesIncluded("pkg1.pkg2.B hasDocComments");
5.130 + }
5.131 +
5.132 + // Case B.1: (jsr166) augment and override system module
5.133 + @Test
5.134 + public void testPatchModuleModifyingSystemModule(Path base) throws Exception {
5.135 + Path src = base.resolve("src");
5.136 + Path patchSrc = base.resolve("patch");
5.137 +
5.138 + // build the patching sources
5.139 + tb.writeJavaFiles(patchSrc, "package java.util;\n" +
5.140 + "/** Class Collection */\n" +
5.141 + "public interface Collection<K> {}");
5.142 +
5.143 + tb.writeJavaFiles(patchSrc, "package java.util;\n"
5.144 + + "/** Class MyCollection */\n" +
5.145 + "public interface MyCollection<K> extends Collection {}");
5.146 +
5.147 + execTask("-hasDocComments", "--patch-module", "java.base=" + patchSrc.toString(),
5.148 + "java.util");
5.149 +
5.150 + checkPackagesSpecified("java.util");
5.151 + checkTypesIncluded("java.util.Collection hasDocComments",
5.152 + "java.util.MyCollection hasDocComments");
5.153 + }
5.154 +
5.155 + // Case C.1: patch a user module's sources using source path
5.156 + @Test
5.157 + public void testPatchModuleUsingSourcePath(Path base) throws Exception {
5.158 + Path src = base.resolve("src");
5.159 + Path patchSrc = base.resolve("patch");
5.160 +
5.161 + ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
5.162 + mb1.comment("Module m1.")
5.163 + .exports("pkg1")
5.164 + .classes("package pkg1; /** Class A */ public class A { }")
5.165 + .write(src);
5.166 +
5.167 + // build the patching module
5.168 + tb.writeJavaFiles(patchSrc, "package pkg1;\n" +
5.169 + "/** Class A */ public class A extends java.util.ArrayList { }");
5.170 + tb.writeJavaFiles(patchSrc, "package pkg1;\n"
5.171 + + "/** Class B */ public class B { }");
5.172 +
5.173 + Path m1src = Paths.get(src.toString(), "m1");
5.174 +
5.175 + execTask("--source-path", m1src.toString(),
5.176 + "--patch-module", "m1=" + patchSrc.toString(),
5.177 + "pkg1");
5.178 +
5.179 + checkPackagesSpecified("pkg1");
5.180 + checkModulesIncluded("m1");
5.181 + checkTypesIncluded("pkg1.A", "pkg1.B");
5.182 + }
5.183 +
5.184 + // Case C.2: patch a user module's sources using module source path
5.185 + @Test
5.186 + public void testPatchModuleWithModuleSourcePath(Path base) throws Exception {
5.187 + Path src = base.resolve("src");
5.188 + Path patchSrc = base.resolve("patch");
5.189 +
5.190 + ModuleBuilder mb1 = new ModuleBuilder(tb, "m1");
5.191 + mb1.comment("Module on module-source-path.")
5.192 + .exports("pkg1")
5.193 + .classes("package pkg1; /** Class A */ public class A { }")
5.194 + .write(src);
5.195 +
5.196 + // build the patching module
5.197 + tb.writeJavaFiles(patchSrc, "package pkg1;\n" +
5.198 + "/** Class A */ public class A extends java.util.ArrayList { }");
5.199 + tb.writeJavaFiles(patchSrc, "package pkg1;\n"
5.200 + + "/** Class B */ public class B { }");
5.201 +
5.202 +
5.203 + execTask("--module-source-path", src.toString(),
5.204 + "--add-modules", "m1",
5.205 + "--patch-module", "m1=" + patchSrc.toString(),
5.206 + "pkg1");
5.207 +
5.208 + checkPackagesSpecified("pkg1");
5.209 + checkModulesIncluded("m1");
5.210 + checkTypesIncluded("pkg1.A", "pkg1.B");
5.211 + }
5.212 +
5.213 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/test/jdk/javadoc/tool/modules/ReleaseOptions.java Thu Mar 16 18:50:50 2017 -0700
6.3 @@ -0,0 +1,99 @@
6.4 +/*
6.5 + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6.7 + *
6.8 + * This code is free software; you can redistribute it and/or modify it
6.9 + * under the terms of the GNU General Public License version 2 only, as
6.10 + * published by the Free Software Foundation.
6.11 + *
6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6.15 + * version 2 for more details (a copy is included in the LICENSE file that
6.16 + * accompanied this code).
6.17 + *
6.18 + * You should have received a copy of the GNU General Public License version
6.19 + * 2 along with this work; if not, write to the Free Software Foundation,
6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
6.21 + *
6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
6.23 + * or visit www.oracle.com if you need additional information or have any
6.24 + * questions.
6.25 + */
6.26 +
6.27 +/**
6.28 + * @test
6.29 + * @bug 8175346
6.30 + * @summary Test release option interactions
6.31 + * @modules
6.32 + * jdk.javadoc/jdk.javadoc.internal.api
6.33 + * jdk.javadoc/jdk.javadoc.internal.tool
6.34 + * jdk.compiler/com.sun.tools.javac.api
6.35 + * jdk.compiler/com.sun.tools.javac.main
6.36 + * @library /tools/lib
6.37 + * @build toolbox.ToolBox toolbox.TestRunner
6.38 + * @run main ReleaseOptions
6.39 + */
6.40 +
6.41 +import java.nio.file.Path;
6.42 +import java.nio.file.Paths;
6.43 +
6.44 +import toolbox.*;
6.45 +
6.46 +public class ReleaseOptions extends ModuleTestBase {
6.47 +
6.48 + public static void main(String... args) throws Exception {
6.49 + new ReleaseOptions().runTests();
6.50 + }
6.51 +
6.52 + @Test
6.53 + public void testReleaseWithPatchModule(Path base) throws Exception {
6.54 + Path src = Paths.get(base.toString(), "src");
6.55 + Path mpath = Paths.get(src. toString(), "m");
6.56 +
6.57 + tb.writeJavaFiles(mpath,
6.58 + "module m { exports p; }",
6.59 + "package p; public class C { }");
6.60 +
6.61 + Task.Result result = execNegativeTask("--release", "8",
6.62 + "--patch-module", "m=" + mpath.toString(),
6.63 + "p");
6.64 + assertMessagePresent(".*No source files for package p.*");
6.65 + assertMessageNotPresent(".*Exception*");
6.66 + assertMessageNotPresent(".java.lang.AssertionError.*");
6.67 + }
6.68 +
6.69 + @Test
6.70 + public void testReleaseWithSourcepath(Path base) throws Exception {
6.71 + Path src = Paths.get(base.toString(), "src");
6.72 + Path mpath = Paths.get(src. toString(), "m");
6.73 +
6.74 + tb.writeJavaFiles(mpath,
6.75 + "module m { exports p; }",
6.76 + "package p; public class C { }");
6.77 +
6.78 + Task.Result result = execNegativeTask("--release", "8",
6.79 + "--source-path", mpath.toString(),
6.80 + "--module", "m");
6.81 + assertMessagePresent(".*(use -source 9 or higher to enable modules).*");
6.82 + assertMessageNotPresent(".*Exception*");
6.83 + assertMessageNotPresent(".java.lang.AssertionError.*");
6.84 + }
6.85 +
6.86 +// @Test TBD, JDK-8175277, argument validation should fail on this
6.87 +// public void testReleaseWithModuleSourcepath(Path base) throws Exception {
6.88 +// Path src = Paths.get(base.toString(), "src");
6.89 +// Path mpath = Paths.get(src.toString(), "m");
6.90 +//
6.91 +// tb.writeJavaFiles(mpath,
6.92 +// "module m { exports p; }",
6.93 +// "package p; public class C { }");
6.94 +//
6.95 +// Task.Result result = execNegativeTask("--release", "8",
6.96 +// "--module-source-path", src.toString(),
6.97 +// "--module", "m");
6.98 +// assertMessagePresent(".*(use -source 9 or higher to enable modules).*");
6.99 +// assertMessageNotPresent(".*Exception*");
6.100 +// assertMessageNotPresent(".java.lang.AssertionError.*");
6.101 +// }
6.102 +}