mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-19 18:44:38 +02:00
8151102: Cleanup javadoc exception handling
Reviewed-by: jjg
This commit is contained in:
parent
a53b8b8a5d
commit
6f16c4713d
39 changed files with 881 additions and 568 deletions
|
@ -40,7 +40,6 @@ import jdk.javadoc.internal.doclets.toolkit.builders.AbstractBuilder;
|
|||
import jdk.javadoc.internal.doclets.toolkit.builders.BuilderFactory;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.ClassTree;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocFileIOException;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.DocPaths;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.InternalException;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.PackageListWriter;
|
||||
import jdk.javadoc.internal.doclets.toolkit.util.ResourceIOException;
|
||||
|
@ -112,8 +111,6 @@ public abstract class AbstractDoclet implements Doclet {
|
|||
return false;
|
||||
}
|
||||
|
||||
boolean dumpOnError = false; // set true to always show stack traces
|
||||
|
||||
try {
|
||||
startGeneration(docEnv);
|
||||
return true;
|
||||
|
@ -128,16 +125,16 @@ public abstract class AbstractDoclet implements Doclet {
|
|||
messages.error("doclet.exception.write.file",
|
||||
e.fileName.getPath(), e.getCause());
|
||||
}
|
||||
dumpStack(dumpOnError, e);
|
||||
dumpStack(configuration.dumpOnError, e);
|
||||
|
||||
} catch (ResourceIOException e) {
|
||||
messages.error("doclet.exception.read.resource",
|
||||
e.resource.getPath(), e.getCause());
|
||||
dumpStack(dumpOnError, e);
|
||||
dumpStack(configuration.dumpOnError, e);
|
||||
|
||||
} catch (SimpleDocletException e) {
|
||||
configuration.reporter.print(ERROR, e.getMessage());
|
||||
dumpStack(dumpOnError, e);
|
||||
dumpStack(configuration.dumpOnError, e);
|
||||
|
||||
} catch (InternalException e) {
|
||||
configuration.reporter.print(ERROR, e.getMessage());
|
||||
|
|
|
@ -281,6 +281,8 @@ public abstract class Configuration {
|
|||
|
||||
private String pkglistUrlForLinkOffline;
|
||||
|
||||
public boolean dumpOnError = false;
|
||||
|
||||
private List<GroupContainer> groups;
|
||||
|
||||
public abstract Messages getMessages();
|
||||
|
@ -616,6 +618,13 @@ public abstract class Configuration {
|
|||
showversion = true;
|
||||
return true;
|
||||
}
|
||||
},
|
||||
new Hidden(resources, "--dump-on-error") {
|
||||
@Override
|
||||
public boolean process(String opt, ListIterator<String> args) {
|
||||
dumpOnError = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
Set<Doclet.Option> set = new TreeSet<>();
|
||||
|
|
|
@ -75,6 +75,7 @@ import jdk.javadoc.doclet.DocletEnvironment;
|
|||
import jdk.javadoc.doclet.DocletEnvironment.ModuleMode;
|
||||
|
||||
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
|
||||
import static jdk.javadoc.internal.tool.Main.Result.*;
|
||||
import static jdk.javadoc.internal.tool.JavadocTool.isValidClassName;
|
||||
|
||||
/**
|
||||
|
@ -158,6 +159,7 @@ public class ElementsTable {
|
|||
private final Location location;
|
||||
private final Modules modules;
|
||||
private final Map<ToolOption, Object> opts;
|
||||
private final Messager messager;
|
||||
|
||||
private final Map<String, Entry> entries = new LinkedHashMap<>();
|
||||
|
||||
|
@ -201,6 +203,8 @@ public class ElementsTable {
|
|||
this.fm = toolEnv.fileManager;
|
||||
this.modules = Modules.instance(context);
|
||||
this.opts = opts;
|
||||
this.messager = Messager.instance0(context);
|
||||
|
||||
this.location = modules.multiModuleMode
|
||||
? StandardLocation.MODULE_SOURCE_PATH
|
||||
: toolEnv.fileManager.hasLocation(StandardLocation.SOURCE_PATH)
|
||||
|
@ -339,9 +343,9 @@ public class ElementsTable {
|
|||
* This is a terminal operation, thus no further modifications
|
||||
* are allowed to the specified data sets.
|
||||
*
|
||||
* @throws IOException if an error occurs
|
||||
* @throws ToolException if an error occurs
|
||||
*/
|
||||
void analyze() throws IOException {
|
||||
void analyze() throws ToolException {
|
||||
// compute the specified element, by expanding module dependencies
|
||||
computeSpecifiedModules();
|
||||
|
||||
|
@ -354,7 +358,6 @@ public class ElementsTable {
|
|||
// compute the packages belonging to all the specified modules
|
||||
Set<PackageElement> expandedModulePackages = computeModulePackages();
|
||||
initializeIncludedSets(expandedModulePackages);
|
||||
|
||||
}
|
||||
|
||||
ElementsTable classTrees(com.sun.tools.javac.util.List<JCCompilationUnit> classTrees) {
|
||||
|
@ -363,16 +366,17 @@ public class ElementsTable {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ElementsTable scanSpecifiedItems() throws IOException {
|
||||
ElementsTable scanSpecifiedItems() throws ToolException {
|
||||
|
||||
// scan modules specified on the command line
|
||||
List<String> moduleNames = (List<String>) opts.computeIfAbsent(ToolOption.MODULE,
|
||||
s -> Collections.EMPTY_LIST);
|
||||
List<String> mlist = new ArrayList<>();
|
||||
for (String m : moduleNames) {
|
||||
Location moduleLoc = fm.getModuleLocation(location, m);
|
||||
Location moduleLoc = getModuleLocation(location, m);
|
||||
if (moduleLoc == null) {
|
||||
toolEnv.error("main.module_not_found", m);
|
||||
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));
|
||||
|
@ -457,7 +461,7 @@ public class ElementsTable {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void computeSubpackages() throws IOException {
|
||||
private void computeSubpackages() throws ToolException {
|
||||
((List<String>) opts.computeIfAbsent(ToolOption.EXCLUDE, v -> Collections.EMPTY_LIST))
|
||||
.stream()
|
||||
.map((packageName) -> new ModulePackage(packageName))
|
||||
|
@ -469,7 +473,14 @@ public class ElementsTable {
|
|||
|
||||
for (ModulePackage modpkg : subPackages) {
|
||||
Location packageLocn = getLocation(modpkg);
|
||||
for (JavaFileObject fo : fm.list(packageLocn, modpkg.packageName, sourceKinds, true)) {
|
||||
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);
|
||||
|
@ -554,10 +565,11 @@ public class ElementsTable {
|
|||
specifiedModuleElements = Collections.unmodifiableSet(result);
|
||||
}
|
||||
|
||||
private Set<PackageElement> getAllModulePackages(ModuleElement mdle) throws IOException {
|
||||
private Set<PackageElement> getAllModulePackages(ModuleElement mdle) throws ToolException {
|
||||
Set<PackageElement> result = new HashSet<>();
|
||||
ModuleSymbol msym = (ModuleSymbol) mdle;
|
||||
Location msymloc = fm.getModuleLocation(location, msym.name.toString());
|
||||
Location msymloc = getModuleLocation(location, msym.name.toString());
|
||||
try {
|
||||
for (JavaFileObject fo : fm.list(msymloc, "", sourceKinds, true)) {
|
||||
if (fo.getName().endsWith("module-info.java"))
|
||||
continue;
|
||||
|
@ -566,10 +578,15 @@ public class ElementsTable {
|
|||
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);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Set<PackageElement> computeModulePackages() throws IOException {
|
||||
private Set<PackageElement> computeModulePackages() throws ToolException {
|
||||
final AccessKind accessValue = accessFilter.getAccessValue(ElementKind.PACKAGE);
|
||||
final boolean documentAllModulePackages = (accessValue == AccessKind.PACKAGE ||
|
||||
accessValue == AccessKind.PRIVATE);
|
||||
|
@ -662,10 +679,10 @@ public class ElementsTable {
|
|||
includedTypeElements = Collections.unmodifiableSet(iclasses);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Computes the included packages and freezes the specified packages list.
|
||||
*/
|
||||
private void computeSpecifiedPackages() throws IOException {
|
||||
private void computeSpecifiedPackages() throws ToolException {
|
||||
|
||||
computeSubpackages();
|
||||
|
||||
|
@ -683,7 +700,7 @@ public class ElementsTable {
|
|||
if (pkg != null) {
|
||||
packlist.add(pkg);
|
||||
} else {
|
||||
toolEnv.warning("main.package_not_found", modpkg.toString());
|
||||
messager.printWarningUsingKey("main.package_not_found", modpkg.toString());
|
||||
}
|
||||
});
|
||||
specifiedPackageElements = Collections.unmodifiableSet(packlist);
|
||||
|
@ -693,7 +710,7 @@ public class ElementsTable {
|
|||
* Adds all classes as well as inner classes, to the specified
|
||||
* list.
|
||||
*/
|
||||
private void computeSpecifiedTypes() {
|
||||
private void computeSpecifiedTypes() throws ToolException {
|
||||
Set<TypeElement> classes = new LinkedHashSet<>();
|
||||
classDecList.stream().filter((def) -> (shouldDocument(def.sym))).forEach((def) -> {
|
||||
TypeElement te = (TypeElement) def.sym;
|
||||
|
@ -701,24 +718,28 @@ public class ElementsTable {
|
|||
addAllClasses(classes, te, true);
|
||||
}
|
||||
});
|
||||
classArgList.forEach((className) -> {
|
||||
for (String className : classArgList) {
|
||||
TypeElement te = toolEnv.loadClass(className);
|
||||
if (te == null) {
|
||||
toolEnv.error("javadoc.class_not_found", className);
|
||||
String text = messager.getText("javadoc.class_not_found", className);
|
||||
throw new ToolException(CMDERR, text);
|
||||
} else {
|
||||
addAllClasses(classes, te, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
specifiedTypeElements = Collections.unmodifiableSet(classes);
|
||||
}
|
||||
|
||||
private void addFilesForParser(Collection<JavaFileObject> result,
|
||||
Collection<ModulePackage> collection, boolean recurse) throws IOException {
|
||||
Collection<ModulePackage> collection,
|
||||
boolean recurse) throws ToolException {
|
||||
for (ModulePackage modpkg : collection) {
|
||||
toolEnv.notice("main.Loading_source_files_for_package", modpkg.toString());
|
||||
List<JavaFileObject> files = getFiles(modpkg, recurse);
|
||||
if (files.isEmpty()) {
|
||||
toolEnv.error("main.no_source_files_for_package", modpkg.toString());
|
||||
String text = messager.getText("main.no_source_files_for_package",
|
||||
modpkg.toString());
|
||||
throw new ToolException(CMDERR, text);
|
||||
} else {
|
||||
result.addAll(files);
|
||||
}
|
||||
|
@ -732,7 +753,7 @@ public class ElementsTable {
|
|||
* @return a list of java file objects
|
||||
* @throws IOException if an error occurs
|
||||
*/
|
||||
List<JavaFileObject> getFilesToParse() throws IOException {
|
||||
List<JavaFileObject> getFilesToParse() throws ToolException {
|
||||
List<JavaFileObject> result = new ArrayList<>();
|
||||
addFilesForParser(result, cmdLinePackages, false);
|
||||
addFilesForParser(result, subPackages, true);
|
||||
|
@ -744,9 +765,10 @@ public class ElementsTable {
|
|||
*
|
||||
* @param packageName the specified package
|
||||
* @return the set of file objects for the specified package
|
||||
* @throws IOException if an error occurs while accessing the files
|
||||
* @throws ToolException if an error occurs while accessing the files
|
||||
*/
|
||||
private List<JavaFileObject> getFiles(ModulePackage modpkg, boolean recurse) throws IOException {
|
||||
private List<JavaFileObject> getFiles(ModulePackage modpkg,
|
||||
boolean recurse) throws ToolException {
|
||||
Entry e = getEntry(modpkg);
|
||||
// The files may have been found as a side effect of searching for subpackages
|
||||
if (e.files != null) {
|
||||
|
@ -759,6 +781,8 @@ public class ElementsTable {
|
|||
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);
|
||||
|
@ -766,6 +790,10 @@ public class ElementsTable {
|
|||
lb.append(fo);
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
String text = messager.getText("main.file.manager.list", pname);
|
||||
throw new ToolException(SYSERR, text, ioe);
|
||||
}
|
||||
|
||||
return lb.toList();
|
||||
}
|
||||
|
@ -781,20 +809,30 @@ public class ElementsTable {
|
|||
return null;
|
||||
}
|
||||
|
||||
private Location getLocation(ModulePackage modpkg) throws IOException {
|
||||
private Location getLocation(ModulePackage modpkg) throws ToolException {
|
||||
if (location != StandardLocation.MODULE_SOURCE_PATH) {
|
||||
return location;
|
||||
}
|
||||
|
||||
if (modpkg.hasModule()) {
|
||||
return fm.getModuleLocation(location, modpkg.moduleName);
|
||||
return getModuleLocation(location, modpkg.moduleName);
|
||||
}
|
||||
// TODO: handle invalid results better.
|
||||
ModuleSymbol msym = findModuleOfPackageName(modpkg.packageName);
|
||||
if (msym == null) {
|
||||
return null;
|
||||
}
|
||||
return fm.getModuleLocation(location, msym.name.toString());
|
||||
return getModuleLocation(location, msym.name.toString());
|
||||
}
|
||||
|
||||
private Location getModuleLocation(Location location, String msymName)
|
||||
throws ToolException {
|
||||
try {
|
||||
return fm.getModuleLocation(location, msymName);
|
||||
} catch (IOException ioe) {
|
||||
String text = messager.getText("main.doclet_could_not_get_location", msymName);
|
||||
throw new ToolException(ERROR, text, ioe);
|
||||
}
|
||||
}
|
||||
|
||||
private Entry getEntry(String name) {
|
||||
|
@ -841,7 +879,10 @@ public class ElementsTable {
|
|||
}
|
||||
}
|
||||
} catch (CompletionFailure e) {
|
||||
// quietly ignore completion failures
|
||||
if (e.getMessage() != null)
|
||||
messager.printWarning(e.getMessage());
|
||||
else
|
||||
messager.printWarningUsingKey("main.unexpected.exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.javadoc.internal.tool;
|
||||
|
||||
import static jdk.javadoc.internal.tool.Main.Result.CMDERR;
|
||||
|
||||
/**
|
||||
* Provides a mechanism for the javadoc tool to indicate an option
|
||||
* decoding issue, arising from command line error.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
|
||||
class IllegalOptionValue extends OptionException {
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
|
||||
/**
|
||||
* Constructs an object containing a runnable and a message.
|
||||
* @param method a method to display suitable usage text
|
||||
* @param message the detailed message
|
||||
*/
|
||||
IllegalOptionValue(Runnable method, String message) {
|
||||
super(CMDERR, method, message);
|
||||
}
|
||||
}
|
|
@ -27,7 +27,6 @@ package jdk.javadoc.internal.tool;
|
|||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
|
@ -51,6 +50,8 @@ import com.sun.tools.javac.util.ListBuffer;
|
|||
import com.sun.tools.javac.util.Position;
|
||||
import jdk.javadoc.doclet.DocletEnvironment;
|
||||
|
||||
import static jdk.javadoc.internal.tool.Main.Result.*;
|
||||
|
||||
/**
|
||||
* This class could be the main entry point for Javadoc when Javadoc is used as a
|
||||
* component in a larger software system. It provides operations to
|
||||
|
@ -120,9 +121,10 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
|
|||
}
|
||||
}
|
||||
|
||||
public DocletEnvironment getEnvironment(Map<ToolOption, Object> jdtoolOpts,
|
||||
public DocletEnvironment getEnvironment(Map<ToolOption,
|
||||
Object> jdtoolOpts,
|
||||
List<String> javaNames,
|
||||
Iterable<? extends JavaFileObject> fileObjects) throws IOException {
|
||||
Iterable<? extends JavaFileObject> fileObjects) throws ToolException {
|
||||
toolEnv = ToolEnvironment.instance(context);
|
||||
toolEnv.initialize(jdtoolOpts);
|
||||
ElementsTable etable = new ElementsTable(context, jdtoolOpts);
|
||||
|
@ -133,10 +135,12 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
|
|||
if (etable.xclasses) {
|
||||
// If -Xclasses is set, the args should be a list of class names
|
||||
for (String arg: javaNames) {
|
||||
if (!isValidPackageName(arg)) // checks
|
||||
toolEnv.error("main.illegal_class_name", arg);
|
||||
if (!isValidPackageName(arg)) { // checks
|
||||
String text = messager.getText("main.illegal_class_name", arg);
|
||||
throw new ToolException(CMDERR, text);
|
||||
}
|
||||
if (messager.nerrors() != 0) {
|
||||
}
|
||||
if (messager.hasErrors()) {
|
||||
return null;
|
||||
}
|
||||
etable.setClassArgList(javaNames);
|
||||
|
@ -157,19 +161,23 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
|
|||
for (String arg: javaNames) {
|
||||
if (fm != null && arg.endsWith(".java") && new File(arg).exists()) {
|
||||
if (new File(arg).getName().equals("module-info.java")) {
|
||||
toolEnv.warning("main.file_ignored", arg);
|
||||
messager.printWarningUsingKey("main.file_ignored", arg);
|
||||
} else {
|
||||
parse(fm.getJavaFileObjects(arg), classTrees, true);
|
||||
}
|
||||
} else if (isValidPackageName(arg)) {
|
||||
packageNames.add(arg);
|
||||
} else if (arg.endsWith(".java")) {
|
||||
if (fm == null)
|
||||
throw new IllegalArgumentException();
|
||||
else
|
||||
toolEnv.error("main.file_not_found", arg);
|
||||
if (fm == null) {
|
||||
String text = messager.getText("main.assertion.error", "fm == null");
|
||||
throw new ToolException(ABNORMAL, text);
|
||||
} else {
|
||||
toolEnv.error("main.illegal_package_name", arg);
|
||||
String text = messager.getText("main.file_not_found", arg);
|
||||
throw new ToolException(ERROR, text);
|
||||
}
|
||||
} else {
|
||||
String text = messager.getText("main.illegal_package_name", arg);
|
||||
throw new ToolException(CMDERR, text);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,7 +193,7 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
|
|||
parse(etable.getFilesToParse(), packageTrees, false);
|
||||
modules.enter(packageTrees.toList(), null);
|
||||
|
||||
if (messager.nerrors() != 0) {
|
||||
if (messager.hasErrors()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -197,10 +205,19 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
|
|||
enterDone = true;
|
||||
etable.analyze();
|
||||
} catch (CompletionFailure cf) {
|
||||
toolEnv.printError(cf.getMessage());
|
||||
} catch (Abort ex) {}
|
||||
throw new ToolException(ABNORMAL, cf.getMessage(), cf);
|
||||
} catch (Abort abort) {
|
||||
if (messager.hasErrors()) {
|
||||
// presumably a message has been emitted, keep silent
|
||||
throw new ToolException(ABNORMAL, "", abort);
|
||||
} else {
|
||||
String text = messager.getText("main.internal.error");
|
||||
Throwable t = abort.getCause() == null ? abort : abort.getCause();
|
||||
throw new ToolException(ABNORMAL, text, t);
|
||||
}
|
||||
}
|
||||
|
||||
if (messager.nerrors() != 0)
|
||||
if (messager.hasErrors())
|
||||
return null;
|
||||
|
||||
toolEnv.docEnv = new DocEnvImpl(toolEnv, etable);
|
||||
|
|
|
@ -60,7 +60,7 @@ public class Main {
|
|||
*/
|
||||
public static int execute(String... args) {
|
||||
Start jdoc = new Start();
|
||||
return jdoc.begin(args);
|
||||
return jdoc.begin(args).exitCode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,7 +72,7 @@ public class Main {
|
|||
*/
|
||||
public static int execute(String[] args, PrintWriter writer) {
|
||||
Start jdoc = new Start(writer, writer);
|
||||
return jdoc.begin(args);
|
||||
return jdoc.begin(args).exitCode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -85,6 +85,36 @@ public class Main {
|
|||
*/
|
||||
public static int execute(String[] args, PrintWriter outWriter, PrintWriter errWriter) {
|
||||
Start jdoc = new Start(outWriter, errWriter);
|
||||
return jdoc.begin(args);
|
||||
return jdoc.begin(args).exitCode;
|
||||
}
|
||||
|
||||
public static enum Result {
|
||||
/** completed with no errors */
|
||||
OK(0),
|
||||
/** Completed with reported errors */
|
||||
ERROR(1),
|
||||
/** Bad command-line arguments */
|
||||
CMDERR(2),
|
||||
/** System error or resource exhaustion */
|
||||
SYSERR(3),
|
||||
/** Terminated abnormally */
|
||||
ABNORMAL(4);
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
Result(int exitCode) {
|
||||
this.exitCode = exitCode;
|
||||
}
|
||||
|
||||
public boolean isOK() {
|
||||
return (exitCode == 0);
|
||||
}
|
||||
|
||||
public final int exitCode;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name() + '(' + exitCode + ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,10 +48,8 @@ import com.sun.tools.javac.util.Log;
|
|||
|
||||
/**
|
||||
* Utility for integrating with javadoc tools and for localization.
|
||||
* Handle Resources. Access to error and warning counts.
|
||||
* Message formatting.
|
||||
* <br>
|
||||
* Also provides implementation for DocErrorReporter.
|
||||
* Handle resources, access to error and warning counts and
|
||||
* message formatting.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
|
@ -139,10 +137,6 @@ public class Messager extends Log implements Reporter {
|
|||
}
|
||||
}
|
||||
|
||||
public static class ExitJavadoc extends Error {
|
||||
private static final long serialVersionUID = 0;
|
||||
}
|
||||
|
||||
final String programName;
|
||||
|
||||
private Locale locale;
|
||||
|
@ -240,7 +234,7 @@ public class Messager extends Log implements Reporter {
|
|||
report(DiagnosticType.ERROR, prefix, msg);
|
||||
return;
|
||||
}
|
||||
incrementErrorCount(prefix, msg);
|
||||
printError(prefix, msg);
|
||||
}
|
||||
|
||||
public void printError(Element e, String msg) {
|
||||
|
@ -249,10 +243,15 @@ public class Messager extends Log implements Reporter {
|
|||
report(DiagnosticType.ERROR, prefix, msg);
|
||||
return;
|
||||
}
|
||||
incrementErrorCount(prefix, msg);
|
||||
printError(prefix, msg);
|
||||
}
|
||||
|
||||
private void incrementErrorCount(String prefix, String msg) {
|
||||
public void printErrorUsingKey(String key, Object... args) {
|
||||
printError((Element)null, getText(key, args));
|
||||
}
|
||||
|
||||
// print the error and increment count
|
||||
private void printError(String prefix, String msg) {
|
||||
if (nerrors < MaxErrors) {
|
||||
PrintWriter errWriter = getWriter(WriterKind.ERROR);
|
||||
printRawLines(errWriter, prefix + ": " + getText("javadoc.error") + " - " + msg);
|
||||
|
@ -272,13 +271,21 @@ public class Messager extends Log implements Reporter {
|
|||
printWarning((DocTreePath)null, msg);
|
||||
}
|
||||
|
||||
public void printWarningUsingKey(String key, Object... args) {
|
||||
printWarning((Element)null, getText(key, args));
|
||||
}
|
||||
|
||||
public void printWarning(Element e, String key, Object... args) {
|
||||
printWarning(getText(key, args));
|
||||
}
|
||||
|
||||
public void printWarning(DocTreePath path, String msg) {
|
||||
String prefix = getDiagSource(path);
|
||||
if (diagListener != null) {
|
||||
report(DiagnosticType.WARNING, prefix, msg);
|
||||
return;
|
||||
}
|
||||
incrementWarningCount(prefix, msg);
|
||||
printWarning(prefix, msg);
|
||||
}
|
||||
|
||||
public void printWarning(Element e, String msg) {
|
||||
|
@ -287,10 +294,11 @@ public class Messager extends Log implements Reporter {
|
|||
report(DiagnosticType.WARNING, prefix, msg);
|
||||
return;
|
||||
}
|
||||
incrementWarningCount(prefix, msg);
|
||||
printWarning(prefix, msg);
|
||||
}
|
||||
|
||||
private void incrementWarningCount(String prefix, String msg) {
|
||||
// print the warning and increment count
|
||||
private void printWarning(String prefix, String msg) {
|
||||
if (nwarnings < MaxWarnings) {
|
||||
PrintWriter warnWriter = getWriter(WriterKind.WARNING);
|
||||
printRawLines(warnWriter, prefix + ": " + getText("javadoc.warning") + " - " + msg);
|
||||
|
@ -341,50 +349,6 @@ public class Messager extends Log implements Reporter {
|
|||
noticeWriter.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print error message, increment error count.
|
||||
*
|
||||
* @param key selects message from resource
|
||||
*/
|
||||
public void error(Element e, String key, Object... args) {
|
||||
printError(e, getText(key, args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Print error message, increment error count.
|
||||
*
|
||||
* @param key selects message from resource
|
||||
*/
|
||||
public void error(DocTreePath path, String key, Object... args) {
|
||||
printError(path, getText(key, args));
|
||||
}
|
||||
|
||||
public void error(String key, Object... args) {
|
||||
printError((Element)null, getText(key, args));
|
||||
}
|
||||
|
||||
public void warning(String key, Object... args) {
|
||||
printWarning((Element)null, getText(key, args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Print warning message, increment warning count.
|
||||
*
|
||||
* @param key selects message from resource
|
||||
*/
|
||||
public void warning(Element e, String key, Object... args) {
|
||||
printWarning(e, getText(key, args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Print warning message, increment warning count.
|
||||
*
|
||||
* @param key selects message from resource
|
||||
*/
|
||||
public void warning(DocTreePath path, String key, Object... args) {
|
||||
printWarning(path, getText(key, args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a message.
|
||||
*
|
||||
|
@ -395,21 +359,23 @@ public class Messager extends Log implements Reporter {
|
|||
}
|
||||
|
||||
/**
|
||||
* Return total number of errors, including those recorded
|
||||
* in the compilation log.
|
||||
* Returns true if errors have been recorded.
|
||||
*/
|
||||
public int nerrors() { return nerrors; }
|
||||
public boolean hasErrors() {
|
||||
return nerrors != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return total number of warnings, including those recorded
|
||||
* in the compilation log.
|
||||
* Returns true if warnings have been recorded.
|
||||
*/
|
||||
public int nwarnings() { return nwarnings; }
|
||||
public boolean hasWarnings() {
|
||||
return nwarnings != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print exit message.
|
||||
*/
|
||||
public void exitNotice() {
|
||||
public void printErrorWarningCounts() {
|
||||
if (nerrors > 0) {
|
||||
notice((nerrors > 1) ? "main.errors" : "main.error",
|
||||
"" + nerrors);
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.javadoc.internal.tool;
|
||||
|
||||
import jdk.javadoc.internal.tool.Main.Result;
|
||||
|
||||
/**
|
||||
* Provides a general mechanism for the javadoc tool to indicate an option
|
||||
* decoding issue.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
|
||||
class OptionException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
|
||||
public final Result result;
|
||||
public final String message;
|
||||
public final Runnable m;
|
||||
|
||||
/**
|
||||
* Constructs an object with a result, runnable and a message
|
||||
* to be printed out by the catcher. The runnable can be invoked
|
||||
* by the catcher to display the usage text.
|
||||
* @param result the exit code
|
||||
* @param method the method to invoke
|
||||
* @param message the detailed message
|
||||
*/
|
||||
public OptionException(Result result, Runnable method, String message) {
|
||||
this.result = result;
|
||||
this.m = method;
|
||||
this.message = message;
|
||||
if (result == null || result.isOK() || method == null || message == null) {
|
||||
throw new AssertionError("result == null || result.isOK() || " +
|
||||
"method == null || message == null");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an object with a result and a runnable.
|
||||
* The runnable can be invoked by the catcher to display the usage text.
|
||||
* @param result the exit code
|
||||
* @param method the method to invoke
|
||||
*/
|
||||
public OptionException(Result result, Runnable method) {
|
||||
this.result = result;
|
||||
this.m = method;
|
||||
this.message = null;
|
||||
if (result == null || method == null) {
|
||||
throw new AssertionError("result == null || method == null");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,7 +26,6 @@
|
|||
package jdk.javadoc.internal.tool;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.file.Path;
|
||||
|
@ -65,11 +64,12 @@ import com.sun.tools.javac.util.Options;
|
|||
import jdk.javadoc.doclet.Doclet;
|
||||
import jdk.javadoc.doclet.Doclet.Option;
|
||||
import jdk.javadoc.doclet.DocletEnvironment;
|
||||
import jdk.javadoc.internal.doclets.toolkit.Resources;
|
||||
import jdk.javadoc.internal.tool.Main.Result;
|
||||
|
||||
import static javax.tools.DocumentationTool.Location.*;
|
||||
|
||||
import static com.sun.tools.javac.main.Option.*;
|
||||
import static jdk.javadoc.internal.tool.Main.Result.*;
|
||||
|
||||
/**
|
||||
* Main program of Javadoc.
|
||||
|
@ -170,41 +170,28 @@ public class Start extends ToolOption.Helper {
|
|||
*/
|
||||
@Override
|
||||
void usage() {
|
||||
usage(true);
|
||||
}
|
||||
|
||||
void usage(boolean exit) {
|
||||
usage("main.usage", "-help", "main.usage.foot");
|
||||
|
||||
if (exit)
|
||||
throw new Messager.ExitJavadoc();
|
||||
usage("main.usage", OptionKind.STANDARD, "main.usage.foot");
|
||||
}
|
||||
|
||||
@Override
|
||||
void Xusage() {
|
||||
Xusage(true);
|
||||
usage("main.Xusage", OptionKind.EXTENDED, "main.Xusage.foot");
|
||||
}
|
||||
|
||||
void Xusage(boolean exit) {
|
||||
usage("main.Xusage", "-X", "main.Xusage.foot");
|
||||
|
||||
if (exit)
|
||||
throw new Messager.ExitJavadoc();
|
||||
}
|
||||
|
||||
private void usage(String header, String option, String footer) {
|
||||
messager.notice(header);
|
||||
showToolOptions(option.equals("-X") ? OptionKind.EXTENDED : OptionKind.STANDARD);
|
||||
private void usage(String headerKey, OptionKind kind, String footerKey) {
|
||||
messager.notice(headerKey);
|
||||
showToolOptions(kind);
|
||||
|
||||
// let doclet print usage information
|
||||
if (docletClass != null) {
|
||||
String name = doclet.getName();
|
||||
messager.notice("main.doclet.usage.header", name);
|
||||
showDocletOptions(option.equals("-X") ? Option.Kind.EXTENDED : Option.Kind.STANDARD);
|
||||
showDocletOptions(kind == OptionKind.EXTENDED
|
||||
? Option.Kind.EXTENDED
|
||||
: Option.Kind.STANDARD);
|
||||
}
|
||||
|
||||
if (footer != null)
|
||||
messager.notice(footer);
|
||||
if (footerKey != null)
|
||||
messager.notice(footerKey);
|
||||
}
|
||||
|
||||
void showToolOptions(OptionKind kind) {
|
||||
|
@ -326,25 +313,23 @@ public class Start extends ToolOption.Helper {
|
|||
* of class loader creation, needed to detect the doclet/taglet class variants.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
int begin(String... argv) {
|
||||
Result begin(String... argv) {
|
||||
// Preprocess @file arguments
|
||||
try {
|
||||
argv = CommandLine.parse(argv);
|
||||
} catch (FileNotFoundException e) {
|
||||
messager.error("main.cant.read", e.getMessage());
|
||||
throw new Messager.ExitJavadoc();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace(System.err);
|
||||
throw new Messager.ExitJavadoc();
|
||||
error("main.cant.read", e.getMessage());
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (argv.length > 0 && "-Xold".equals(argv[0])) {
|
||||
messager.warning("main.legacy_api");
|
||||
warn("main.legacy_api");
|
||||
String[] nargv = Arrays.copyOfRange(argv, 1, argv.length);
|
||||
return com.sun.tools.javadoc.Main.execute(nargv);
|
||||
return com.sun.tools.javadoc.Main.execute(nargv) == 0
|
||||
? OK
|
||||
: ERROR;
|
||||
}
|
||||
boolean ok = begin(Arrays.asList(argv), Collections.<JavaFileObject> emptySet());
|
||||
return ok ? 0 : 1;
|
||||
return begin(Arrays.asList(argv), Collections.<JavaFileObject> emptySet());
|
||||
}
|
||||
|
||||
// Called by 199 API.
|
||||
|
@ -356,11 +341,11 @@ public class Start extends ToolOption.Helper {
|
|||
for (String opt: options)
|
||||
opts.add(opt);
|
||||
|
||||
return begin(opts, fileObjects);
|
||||
return begin(opts, fileObjects).isOK();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private boolean begin(List<String> options, Iterable<? extends JavaFileObject> fileObjects) {
|
||||
private Result begin(List<String> options, Iterable<? extends JavaFileObject> fileObjects) {
|
||||
fileManager = context.get(JavaFileManager.class);
|
||||
if (fileManager == null) {
|
||||
JavacFileManager.preRegister(context);
|
||||
|
@ -369,8 +354,28 @@ public class Start extends ToolOption.Helper {
|
|||
((BaseFileManager) fileManager).autoClose = true;
|
||||
}
|
||||
}
|
||||
|
||||
// locale, doclet and maybe taglet, needs to be determined first
|
||||
docletClass = preProcess(fileManager, options);
|
||||
try {
|
||||
docletClass = preprocess(fileManager, options);
|
||||
} catch (ToolException te) {
|
||||
if (!te.result.isOK()) {
|
||||
if (te.message != null) {
|
||||
messager.printError(te.message);
|
||||
}
|
||||
Throwable t = te.getCause();
|
||||
dumpStack(t == null ? te : t);
|
||||
}
|
||||
return te.result;
|
||||
} catch (OptionException oe) {
|
||||
if (oe.message != null) {
|
||||
messager.printError(oe.message);
|
||||
}
|
||||
oe.m.run();
|
||||
Throwable t = oe.getCause();
|
||||
dumpStack(t == null ? oe : t);
|
||||
return oe.result;
|
||||
}
|
||||
if (jdk.javadoc.doclet.Doclet.class.isAssignableFrom(docletClass)) {
|
||||
// no need to dispatch to old, safe to init now
|
||||
initMessager();
|
||||
|
@ -379,43 +384,62 @@ public class Start extends ToolOption.Helper {
|
|||
Object o = docletClass.getConstructor().newInstance();
|
||||
doclet = (Doclet) o;
|
||||
} catch (ReflectiveOperationException exc) {
|
||||
exc.printStackTrace();
|
||||
if (!apiMode) {
|
||||
error("main.could_not_instantiate_class", docletClass);
|
||||
throw new Messager.ExitJavadoc();
|
||||
}
|
||||
if (apiMode) {
|
||||
throw new ClientCodeException(exc);
|
||||
}
|
||||
error("main.could_not_instantiate_class", docletClass);
|
||||
return ERROR;
|
||||
}
|
||||
} else {
|
||||
if (this.apiMode) {
|
||||
if (apiMode) {
|
||||
com.sun.tools.javadoc.main.Start ostart
|
||||
= new com.sun.tools.javadoc.main.Start(context);
|
||||
return ostart.begin(docletClass, options, fileObjects);
|
||||
return ostart.begin(docletClass, options, fileObjects)
|
||||
? OK
|
||||
: ERROR;
|
||||
}
|
||||
warn("main.legacy_api");
|
||||
String[] array = options.toArray(new String[options.size()]);
|
||||
return com.sun.tools.javadoc.Main.execute(array) == 0;
|
||||
return com.sun.tools.javadoc.Main.execute(array) == 0
|
||||
? OK
|
||||
: ERROR;
|
||||
}
|
||||
|
||||
boolean failed = false;
|
||||
Result result = OK;
|
||||
try {
|
||||
failed = !parseAndExecute(options, fileObjects);
|
||||
} catch (Messager.ExitJavadoc exc) {
|
||||
// ignore, we just exit this way
|
||||
result = parseAndExecute(options, fileObjects)
|
||||
? OK
|
||||
: ERROR;
|
||||
} catch (OptionException toe) {
|
||||
if (toe.message != null)
|
||||
messager.printError(toe.message);
|
||||
|
||||
toe.m.run();
|
||||
Throwable t = toe.getCause();
|
||||
dumpStack(t == null ? toe : t);
|
||||
return toe.result;
|
||||
} catch (ToolException exc) {
|
||||
if (exc.message != null) {
|
||||
messager.printError(exc.message);
|
||||
}
|
||||
Throwable t = exc.getCause();
|
||||
if (result == ABNORMAL) {
|
||||
reportInternalError(t == null ? exc : t);
|
||||
} else {
|
||||
dumpStack(t == null ? exc : t);
|
||||
}
|
||||
return exc.result;
|
||||
} catch (OutOfMemoryError ee) {
|
||||
messager.error("main.out.of.memory");
|
||||
failed = true;
|
||||
error("main.out.of.memory");
|
||||
result = SYSERR;
|
||||
dumpStack(ee);
|
||||
} catch (ClientCodeException e) {
|
||||
// simply rethrow these exceptions, to be caught and handled by JavadocTaskImpl
|
||||
throw e;
|
||||
} catch (Error ee) {
|
||||
ee.printStackTrace(System.err);
|
||||
messager.error("main.fatal.error");
|
||||
failed = true;
|
||||
} catch (Exception ee) {
|
||||
ee.printStackTrace(System.err);
|
||||
messager.error("main.fatal.exception");
|
||||
failed = true;
|
||||
} catch (Error | Exception ee) {
|
||||
error("main.fatal.error", ee);
|
||||
reportInternalError(ee);
|
||||
result = ABNORMAL;
|
||||
} finally {
|
||||
if (fileManager != null
|
||||
&& fileManager instanceof BaseFileManager
|
||||
|
@ -424,17 +448,34 @@ public class Start extends ToolOption.Helper {
|
|||
fileManager.close();
|
||||
} catch (IOException ignore) {}
|
||||
}
|
||||
boolean haveErrorWarnings = messager.nerrors() > 0 ||
|
||||
(rejectWarnings && messager.nwarnings() > 0);
|
||||
if (failed && !haveErrorWarnings) {
|
||||
boolean haveErrorWarnings = messager.hasErrors()
|
||||
|| (rejectWarnings && messager.hasWarnings());
|
||||
if (!result.isOK() && !haveErrorWarnings) {
|
||||
// the doclet failed, but nothing reported, flag it!.
|
||||
messager.error("main.unknown.error");
|
||||
error("main.unknown.error");
|
||||
}
|
||||
failed |= haveErrorWarnings;
|
||||
messager.exitNotice();
|
||||
if (haveErrorWarnings && result.isOK()) {
|
||||
result = ERROR;
|
||||
}
|
||||
messager.printErrorWarningCounts();
|
||||
messager.flush();
|
||||
}
|
||||
return !failed;
|
||||
return result;
|
||||
}
|
||||
|
||||
private void reportInternalError(Throwable t) {
|
||||
messager.printErrorUsingKey("doclet.internal.report.bug");
|
||||
dumpStack(true, t);
|
||||
}
|
||||
|
||||
private void dumpStack(Throwable t) {
|
||||
dumpStack(false, t);
|
||||
}
|
||||
|
||||
private void dumpStack(boolean enabled, Throwable t) {
|
||||
if (t != null && (enabled || dumpOnError)) {
|
||||
t.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -442,7 +483,7 @@ public class Start extends ToolOption.Helper {
|
|||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private boolean parseAndExecute(List<String> argList,
|
||||
Iterable<? extends JavaFileObject> fileObjects) throws IOException {
|
||||
Iterable<? extends JavaFileObject> fileObjects) throws ToolException, OptionException {
|
||||
long tm = System.currentTimeMillis();
|
||||
|
||||
List<String> javaNames = new ArrayList<>();
|
||||
|
@ -463,17 +504,21 @@ public class Start extends ToolOption.Helper {
|
|||
|
||||
if (platformString != null) {
|
||||
if (compOpts.isSet("-source")) {
|
||||
usageError("main.release.bootclasspath.conflict", "-source");
|
||||
String text = messager.getText("main.release.bootclasspath.conflict", "-source");
|
||||
throw new ToolException(CMDERR, text);
|
||||
}
|
||||
if (fileManagerOpts.containsKey(BOOT_CLASS_PATH)) {
|
||||
usageError("main.release.bootclasspath.conflict", BOOT_CLASS_PATH.getPrimaryName());
|
||||
String text = messager.getText("main.release.bootclasspath.conflict",
|
||||
BOOT_CLASS_PATH.getPrimaryName());
|
||||
throw new ToolException(CMDERR, text);
|
||||
}
|
||||
|
||||
PlatformDescription platformDescription =
|
||||
PlatformUtils.lookupPlatformDescription(platformString);
|
||||
|
||||
if (platformDescription == null) {
|
||||
usageError("main.unsupported.release.version", platformString);
|
||||
String text = messager.getText("main.unsupported.release.version", platformString);
|
||||
throw new IllegalArgumentException(text);
|
||||
}
|
||||
|
||||
compOpts.put(SOURCE, platformDescription.getSourceVersion());
|
||||
|
@ -485,10 +530,15 @@ public class Start extends ToolOption.Helper {
|
|||
if (platformCP != null) {
|
||||
if (fileManager instanceof StandardJavaFileManager) {
|
||||
StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager;
|
||||
|
||||
try {
|
||||
sfm.setLocationFromPaths(StandardLocation.PLATFORM_CLASS_PATH, platformCP);
|
||||
} catch (IOException ioe) {
|
||||
throw new ToolException(SYSERR, ioe.getMessage(), ioe);
|
||||
}
|
||||
} else {
|
||||
usageError("main.release.not.standard.file.manager", platformString);
|
||||
String text = messager.getText("main.release.not.standard.file.manager",
|
||||
platformString);
|
||||
throw new ToolException(ABNORMAL, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -502,7 +552,8 @@ public class Start extends ToolOption.Helper {
|
|||
s -> Collections.EMPTY_LIST);
|
||||
if (subpkgs.isEmpty()) {
|
||||
if (javaNames.isEmpty() && isEmpty(fileObjects)) {
|
||||
usageError("main.No_modules_packages_or_classes_specified");
|
||||
String text = messager.getText("main.No_modules_packages_or_classes_specified");
|
||||
throw new ToolException(CMDERR, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -535,7 +586,8 @@ public class Start extends ToolOption.Helper {
|
|||
}
|
||||
|
||||
Set<Doclet.Option> docletOptions = null;
|
||||
int handleDocletOptions(int idx, List<String> args, boolean isToolOption) {
|
||||
int handleDocletOptions(int idx, List<String> args, boolean isToolOption)
|
||||
throws OptionException {
|
||||
if (docletOptions == null) {
|
||||
docletOptions = doclet.getSupportedOptions();
|
||||
}
|
||||
|
@ -549,24 +601,25 @@ public class Start extends ToolOption.Helper {
|
|||
argBase = arg;
|
||||
argVal = null;
|
||||
}
|
||||
|
||||
String text = null;
|
||||
for (Doclet.Option opt : docletOptions) {
|
||||
if (opt.matches(argBase)) {
|
||||
if (argVal != null) {
|
||||
switch (opt.getArgumentCount()) {
|
||||
case 0:
|
||||
usageError("main.unnecessary_arg_provided", argBase);
|
||||
break;
|
||||
text = messager.getText("main.unnecessary_arg_provided", argBase);
|
||||
throw new OptionException(ERROR, this::usage, text);
|
||||
case 1:
|
||||
opt.process(arg, Arrays.asList(argVal).listIterator());
|
||||
break;
|
||||
default:
|
||||
usageError("main.only_one_argument_with_equals", argBase);
|
||||
break;
|
||||
text = messager.getText("main.only_one_argument_with_equals", argBase);
|
||||
throw new OptionException(ERROR, this::usage, text);
|
||||
}
|
||||
} else {
|
||||
if (args.size() - idx -1 < opt.getArgumentCount()) {
|
||||
usageError("main.requires_argument", arg);
|
||||
text = messager.getText("main.requires_argument", arg);
|
||||
throw new OptionException(ERROR, this::usage, text);
|
||||
}
|
||||
opt.process(arg, args.listIterator(idx + 1));
|
||||
idx += opt.getArgumentCount();
|
||||
|
@ -575,12 +628,15 @@ public class Start extends ToolOption.Helper {
|
|||
}
|
||||
}
|
||||
// check if arg is accepted by the tool before emitting error
|
||||
if (!isToolOption)
|
||||
usageError("main.invalid_flag", arg);
|
||||
if (!isToolOption) {
|
||||
text = messager.getText("main.invalid_flag", arg);
|
||||
throw new OptionException(ERROR, this::usage, text);
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
private Class<?> preProcess(JavaFileManager jfm, List<String> argv) {
|
||||
private Class<?> preprocess(JavaFileManager jfm,
|
||||
List<String> argv) throws ToolException, OptionException {
|
||||
// doclet specifying arguments
|
||||
String userDocletPath = null;
|
||||
String userDocletName = null;
|
||||
|
@ -593,19 +649,31 @@ public class Start extends ToolOption.Helper {
|
|||
// Step 1: loop through the args, set locale early on, if found.
|
||||
for (int i = 0 ; i < argv.size() ; i++) {
|
||||
String arg = argv.get(i);
|
||||
if (arg.equals(ToolOption.LOCALE.primaryName)) {
|
||||
if (arg.equals(ToolOption.DUMPONERROR.primaryName)) {
|
||||
dumpOnError = true;
|
||||
} else if (arg.equals(ToolOption.LOCALE.primaryName)) {
|
||||
checkOneArg(argv, i++);
|
||||
String lname = argv.get(i);
|
||||
locale = getLocale(lname);
|
||||
} else if (arg.equals(ToolOption.DOCLET.primaryName)) {
|
||||
checkOneArg(argv, i++);
|
||||
if (userDocletName != null) {
|
||||
usageError("main.more_than_one_doclet_specified_0_and_1",
|
||||
if (apiMode) {
|
||||
throw new IllegalArgumentException("More than one doclet specified (" +
|
||||
userDocletName + " and " + argv.get(i) + ").");
|
||||
}
|
||||
String text = messager.getText("main.more_than_one_doclet_specified_0_and_1",
|
||||
userDocletName, argv.get(i));
|
||||
throw new ToolException(CMDERR, text);
|
||||
}
|
||||
if (docletName != null) {
|
||||
usageError("main.more_than_one_doclet_specified_0_and_1",
|
||||
if (apiMode) {
|
||||
throw new IllegalArgumentException("More than one doclet specified (" +
|
||||
docletName + " and " + argv.get(i) + ").");
|
||||
}
|
||||
String text = messager.getText("main.more_than_one_doclet_specified_0_and_1",
|
||||
docletName, argv.get(i));
|
||||
throw new ToolException(CMDERR, text);
|
||||
}
|
||||
userDocletName = argv.get(i);
|
||||
} else if (arg.equals(ToolOption.DOCLETPATH.primaryName)) {
|
||||
|
@ -644,23 +712,37 @@ public class Start extends ToolOption.Helper {
|
|||
try {
|
||||
((StandardJavaFileManager)fileManager).setLocation(DOCLET_PATH, paths);
|
||||
} catch (IOException ioe) {
|
||||
error("main.doclet_could_not_set_location", paths);
|
||||
throw new Messager.ExitJavadoc();
|
||||
if (apiMode) {
|
||||
throw new IllegalArgumentException("Could not set location for " +
|
||||
userDocletPath, ioe);
|
||||
}
|
||||
String text = messager.getText("main.doclet_could_not_set_location",
|
||||
userDocletPath);
|
||||
throw new ToolException(CMDERR, text, ioe);
|
||||
}
|
||||
}
|
||||
cl = fileManager.getClassLoader(DOCLET_PATH);
|
||||
if (cl == null) {
|
||||
// despite doclet specified on cmdline no classloader found!
|
||||
error("main.doclet_no_classloader_found", userDocletName);
|
||||
throw new Messager.ExitJavadoc();
|
||||
if (apiMode) {
|
||||
throw new IllegalArgumentException("Could not obtain classloader to load "
|
||||
+ userDocletPath);
|
||||
}
|
||||
String text = messager.getText("main.doclet_no_classloader_found",
|
||||
userDocletName);
|
||||
throw new ToolException(CMDERR, text);
|
||||
}
|
||||
}
|
||||
try {
|
||||
Class<?> klass = cl.loadClass(userDocletName);
|
||||
return klass;
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
error("main.doclet_class_not_found", userDocletName);
|
||||
throw new Messager.ExitJavadoc();
|
||||
if (apiMode) {
|
||||
throw new IllegalArgumentException("Cannot find doclet class " + userDocletName,
|
||||
cnfe);
|
||||
}
|
||||
String text = messager.getText("main.doclet_class_not_found", userDocletName);
|
||||
throw new ToolException(CMDERR, text, cnfe);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -669,8 +751,11 @@ public class Start extends ToolOption.Helper {
|
|||
try {
|
||||
return Class.forName(docletName, true, getClass().getClassLoader());
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
error("main.doclet_class_not_found", userDocletName);
|
||||
throw new Messager.ExitJavadoc();
|
||||
if (apiMode) {
|
||||
throw new IllegalArgumentException("Cannot find doclet class " + userDocletName);
|
||||
}
|
||||
String text = messager.getText("main.doclet_class_not_found", userDocletName);
|
||||
throw new ToolException(CMDERR, text, cnfe);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -690,20 +775,20 @@ public class Start extends ToolOption.Helper {
|
|||
* nature to take its own course.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private boolean hasOldTaglet(List<String> tagletNames, List<File> tagletPaths) {
|
||||
private boolean hasOldTaglet(List<String> tagletNames, List<File> tagletPaths) throws ToolException {
|
||||
if (!fileManager.hasLocation(TAGLET_PATH)) {
|
||||
try {
|
||||
((StandardJavaFileManager) fileManager).setLocation(TAGLET_PATH, tagletPaths);
|
||||
} catch (IOException ioe) {
|
||||
error("main.doclet_could_not_set_location", tagletPaths);
|
||||
throw new Messager.ExitJavadoc();
|
||||
String text = messager.getText("main.doclet_could_not_set_location", tagletPaths);
|
||||
throw new ToolException(CMDERR, text, ioe);
|
||||
}
|
||||
}
|
||||
ClassLoader cl = fileManager.getClassLoader(TAGLET_PATH);
|
||||
if (cl == null) {
|
||||
// no classloader found!
|
||||
error("main.doclet_no_classloader_found", tagletNames.get(0));
|
||||
throw new Messager.ExitJavadoc();
|
||||
String text = messager.getText("main.doclet_no_classloader_found", tagletNames.get(0));
|
||||
throw new ToolException(CMDERR, text);
|
||||
}
|
||||
for (String tagletName : tagletNames) {
|
||||
try {
|
||||
|
@ -712,14 +797,15 @@ public class Start extends ToolOption.Helper {
|
|||
return true;
|
||||
}
|
||||
} catch (ClassNotFoundException cnfe) {
|
||||
error("main.doclet_class_not_found", tagletName);
|
||||
throw new Messager.ExitJavadoc();
|
||||
String text = messager.getText("main.doclet_class_not_found", tagletName);
|
||||
throw new ToolException(CMDERR, text, cnfe);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void parseArgs(List<String> args, List<String> javaNames) {
|
||||
private void parseArgs(List<String> args, List<String> javaNames) throws ToolException,
|
||||
OptionException {
|
||||
for (int i = 0 ; i < args.size() ; i++) {
|
||||
String arg = args.get(i);
|
||||
ToolOption o = ToolOption.get(arg);
|
||||
|
@ -727,7 +813,6 @@ public class Start extends ToolOption.Helper {
|
|||
// handle a doclet argument that may be needed however
|
||||
// don't increment the index, and allow the tool to consume args
|
||||
handleDocletOptions(i, args, true);
|
||||
|
||||
if (o.hasArg) {
|
||||
if (arg.startsWith("--") && arg.contains("=")) {
|
||||
o.process(this, arg.substring(arg.indexOf('=') + 1));
|
||||
|
@ -763,24 +848,19 @@ public class Start extends ToolOption.Helper {
|
|||
* Check the one arg option.
|
||||
* Error and exit if one argument is not provided.
|
||||
*/
|
||||
private void checkOneArg(List<String> args, int index) {
|
||||
private void checkOneArg(List<String> args, int index) throws OptionException {
|
||||
if ((index + 1) >= args.size() || args.get(index + 1).startsWith("-d")) {
|
||||
usageError("main.requires_argument", args.get(index));
|
||||
String text = messager.getText("main.requires_argument", args.get(index));
|
||||
throw new OptionException(CMDERR, this::usage, text);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void usageError(String key, Object... args) {
|
||||
error(key, args);
|
||||
usage(true);
|
||||
}
|
||||
|
||||
void error(String key, Object... args) {
|
||||
messager.error(key, args);
|
||||
messager.printErrorUsingKey(key, args);
|
||||
}
|
||||
|
||||
void warn(String key, Object... args) {
|
||||
messager.warning(key, args);
|
||||
messager.printWarningUsingKey(key, args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -788,7 +868,7 @@ public class Start extends ToolOption.Helper {
|
|||
* else return null and if locale option is not used
|
||||
* then return default locale.
|
||||
*/
|
||||
private Locale getLocale(String localeName) {
|
||||
private Locale getLocale(String localeName) throws ToolException {
|
||||
Locale userlocale = null;
|
||||
if (localeName == null || localeName.isEmpty()) {
|
||||
return Locale.getDefault();
|
||||
|
@ -804,8 +884,8 @@ public class Start extends ToolOption.Helper {
|
|||
if (seconduscore > 0) {
|
||||
if (seconduscore != firstuscore + 3
|
||||
|| localeName.length() <= seconduscore + 1) {
|
||||
usageError("main.malformed_locale_name", localeName);
|
||||
return null;
|
||||
String text = messager.getText("main.malformed_locale_name", localeName);
|
||||
throw new ToolException(CMDERR, text);
|
||||
}
|
||||
country = localeName.substring(firstuscore + 1,
|
||||
seconduscore);
|
||||
|
@ -813,19 +893,19 @@ public class Start extends ToolOption.Helper {
|
|||
} else if (localeName.length() == firstuscore + 3) {
|
||||
country = localeName.substring(firstuscore + 1);
|
||||
} else {
|
||||
usageError("main.malformed_locale_name", localeName);
|
||||
return null;
|
||||
String text = messager.getText("main.malformed_locale_name", localeName);
|
||||
throw new ToolException(CMDERR, text);
|
||||
}
|
||||
} else if (firstuscore == -1 && localeName.length() == 2) {
|
||||
language = localeName;
|
||||
} else {
|
||||
usageError("main.malformed_locale_name", localeName);
|
||||
return null;
|
||||
String text = messager.getText("main.malformed_locale_name", localeName);
|
||||
throw new ToolException(CMDERR, text);
|
||||
}
|
||||
userlocale = searchLocale(language, country, variant);
|
||||
if (userlocale == null) {
|
||||
usageError("main.illegal_locale_name", localeName);
|
||||
return null;
|
||||
String text = messager.getText("main.illegal_locale_name", localeName);
|
||||
throw new ToolException(CMDERR, text);
|
||||
} else {
|
||||
return userlocale;
|
||||
}
|
||||
|
@ -861,4 +941,9 @@ public class Start extends ToolOption.Helper {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
String getLocalizedMessage(String msg, Object... args) {
|
||||
return messager.getText(msg, args);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ public class ToolEnvironment {
|
|||
return instance;
|
||||
}
|
||||
|
||||
private final Messager messager;
|
||||
final Messager messager;
|
||||
|
||||
/** Predefined symbols known to the compiler. */
|
||||
public final Symtab syms;
|
||||
|
@ -204,182 +204,8 @@ public class ToolEnvironment {
|
|||
return path != null;
|
||||
}
|
||||
|
||||
//---------------- print forwarders ----------------//
|
||||
|
||||
// ERRORS
|
||||
/**
|
||||
* Print error message, increment error count.
|
||||
*
|
||||
* @param msg message to print.
|
||||
*/
|
||||
public void printError(String msg) {
|
||||
messager.printError(msg);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Print error message, increment error count.
|
||||
// *
|
||||
// * @param key selects message from resource
|
||||
// */
|
||||
// public void error(Element element, String key) {
|
||||
// if (element == null)
|
||||
// messager.error(key);
|
||||
// else
|
||||
// messager.error(element, key);
|
||||
// }
|
||||
//
|
||||
// public void error(String prefix, String key) {
|
||||
// printError(prefix + ":" + messager.getText(key));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Print error message, increment error count.
|
||||
// *
|
||||
// * @param path the path to the source
|
||||
// * @param key selects message from resource
|
||||
// */
|
||||
// public void error(DocTreePath path, String key) {
|
||||
// messager.error(path, key);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Print error message, increment error count.
|
||||
// *
|
||||
// * @param path the path to the source
|
||||
// * @param msg message to print.
|
||||
// */
|
||||
// public void printError(DocTreePath path, String msg) {
|
||||
// messager.printError(path, msg);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Print error message, increment error count.
|
||||
// * @param e the target element
|
||||
// * @param msg message to print.
|
||||
// */
|
||||
// public void printError(Element e, String msg) {
|
||||
// messager.printError(e, msg);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Print error message, increment error count.
|
||||
* @param key selects message from resource
|
||||
* @param args replacement arguments
|
||||
*/
|
||||
public void error(String key, String... args) {
|
||||
error(null, key, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print error message, increment error count.
|
||||
*
|
||||
* @param element the source element
|
||||
* @param key selects message from resource
|
||||
* @param args replacement arguments
|
||||
*/
|
||||
public void error(Element element, String key, String... args) {
|
||||
if (element == null)
|
||||
messager.error(key, (Object[]) args);
|
||||
else
|
||||
messager.error(element, key, (Object[]) args);
|
||||
}
|
||||
|
||||
// WARNINGS
|
||||
|
||||
// /**
|
||||
// * Print warning message, increment warning count.
|
||||
// *
|
||||
// * @param msg message to print.
|
||||
// */
|
||||
// public void printWarning(String msg) {
|
||||
// messager.printWarning(msg);
|
||||
// }
|
||||
//
|
||||
// public void warning(String key) {
|
||||
// warning((Element)null, key);
|
||||
// }
|
||||
|
||||
public void warning(String key, String... args) {
|
||||
warning((Element)null, key, args);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Print warning message, increment warning count.
|
||||
// *
|
||||
// * @param element the source element
|
||||
// * @param key selects message from resource
|
||||
// */
|
||||
// public void warning(Element element, String key) {
|
||||
// if (element == null)
|
||||
// messager.warning(key);
|
||||
// else
|
||||
// messager.warning(element, key);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Print warning message, increment warning count.
|
||||
// *
|
||||
// * @param path the path to the source
|
||||
// * @param msg message to print.
|
||||
// */
|
||||
// public void printWarning(DocTreePath path, String msg) {
|
||||
// messager.printWarning(path, msg);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Print warning message, increment warning count.
|
||||
// *
|
||||
// * @param e the source element
|
||||
// * @param msg message to print.
|
||||
// */
|
||||
// public void printWarning(Element e, String msg) {
|
||||
// messager.printWarning(e, msg);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Print warning message, increment warning count.
|
||||
*
|
||||
* @param e the source element
|
||||
* @param key selects message from resource
|
||||
* @param args the replace arguments
|
||||
*/
|
||||
public void warning(Element e, String key, String... args) {
|
||||
if (e == null)
|
||||
messager.warning(key, (Object[]) args);
|
||||
else
|
||||
messager.warning(e, key, (Object[]) args);
|
||||
}
|
||||
|
||||
// Note: no longer required
|
||||
// /**
|
||||
// * Print a message.
|
||||
// *
|
||||
// * @param msg message to print.
|
||||
// */
|
||||
// public void printNotice(String msg) {
|
||||
// if (quiet) {
|
||||
// return;
|
||||
// }
|
||||
// messager.printNotice(msg);
|
||||
// }
|
||||
|
||||
// Note: no longer required
|
||||
// /**
|
||||
// * Print a message.
|
||||
// *
|
||||
// * @param e the source element
|
||||
// * @param msg message to print.
|
||||
// */
|
||||
// public void printNotice(Element e, String msg) {
|
||||
// if (quiet) {
|
||||
// return;
|
||||
// }
|
||||
// messager.printNotice(e, msg);
|
||||
// }
|
||||
|
||||
// NOTICES
|
||||
/**
|
||||
* Print a message.
|
||||
* Print a notice, iff <em>quiet</em> is not specified.
|
||||
*
|
||||
* @param key selects message from resource
|
||||
*/
|
||||
|
@ -390,22 +216,8 @@ public class ToolEnvironment {
|
|||
messager.notice(key);
|
||||
}
|
||||
|
||||
// Note: not used anymore
|
||||
// /**
|
||||
// * Print a message.
|
||||
// *
|
||||
// * @param path the path to the source
|
||||
// * @param msg message to print.
|
||||
// */
|
||||
// public void printNotice(DocTreePath path, String msg) {
|
||||
// if (quiet) {
|
||||
// return;
|
||||
// }
|
||||
// messager.printNotice(path, msg);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Print a message.
|
||||
* Print a notice, iff <em>quiet</em> is not specified.
|
||||
*
|
||||
* @param key selects message from resource
|
||||
* @param a1 first argument
|
||||
|
@ -417,48 +229,6 @@ public class ToolEnvironment {
|
|||
messager.notice(key, a1);
|
||||
}
|
||||
|
||||
// Note: not used anymore
|
||||
// /**
|
||||
// * Print a message.
|
||||
// *
|
||||
// * @param key selects message from resource
|
||||
// * @param a1 first argument
|
||||
// * @param a2 second argument
|
||||
// */
|
||||
// public void notice(String key, String a1, String a2) {
|
||||
// if (quiet) {
|
||||
// return;
|
||||
// }
|
||||
// messager.notice(key, a1, a2);
|
||||
// }
|
||||
//
|
||||
|
||||
// Note: not used anymore
|
||||
// /**
|
||||
// * Print a message.
|
||||
// *
|
||||
// * @param key selects message from resource
|
||||
// * @param a1 first argument
|
||||
// * @param a2 second argument
|
||||
// * @param a3 third argument
|
||||
// */
|
||||
// public void notice(String key, String a1, String a2, String a3) {
|
||||
// if (quiet) {
|
||||
// return;
|
||||
// }
|
||||
// messager.notice(key, a1, a2, a3);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Exit, reporting errors and warnings.
|
||||
*/
|
||||
public void exit() {
|
||||
// Messager should be replaced by a more general
|
||||
// compilation environment. This can probably
|
||||
// subsume DocEnv as well.
|
||||
throw new Messager.ExitJavadoc();
|
||||
}
|
||||
|
||||
TreePath getTreePath(JCCompilationUnit tree) {
|
||||
TreePath p = treePaths.get(tree);
|
||||
if (p == null)
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.javadoc.internal.tool;
|
||||
|
||||
import jdk.javadoc.internal.tool.Main.Result;
|
||||
|
||||
/**
|
||||
* Provides a mechanism for the javadoc tool to terminate execution.
|
||||
* This class is constructed with a result and an error message,
|
||||
* that can be printed out before termination, a cause can also
|
||||
* be wrapped to supply extended information about the exception.
|
||||
*
|
||||
* <p><b>This is NOT part of any supported API.
|
||||
* If you write code that depends on this, you do so at your own risk.
|
||||
* This code and its internal interfaces are subject to change or
|
||||
* deletion without notice.</b>
|
||||
*/
|
||||
|
||||
class ToolException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 0;
|
||||
|
||||
final String message;
|
||||
|
||||
final Result result;
|
||||
|
||||
/**
|
||||
* Constructs an object containing a result and a message to be
|
||||
* printed out by the catcher.
|
||||
* @param result the exit code
|
||||
* @param message the detailed message
|
||||
*/
|
||||
ToolException(Result result, String message) {
|
||||
this.message = message;
|
||||
this.result = result;
|
||||
if (result == null || result.isOK() || message == null) {
|
||||
throw new AssertionError("result == null || result.isOK() || message == null");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an object containing a result, a messages and an underlying cause.
|
||||
* @param result the exit code
|
||||
* @param message the detailed message
|
||||
* @param cause the underlying cause
|
||||
*/
|
||||
ToolException(Result result, String message, Throwable cause) {
|
||||
super(cause);
|
||||
this.message = message;
|
||||
this.result = result;
|
||||
if (result == null || message == null || cause == null || result.isOK()) {
|
||||
throw new AssertionError("result == null || message == null"
|
||||
+ " || cause == null || result.isOK()");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -40,6 +40,7 @@ import com.sun.tools.javac.main.OptionHelper;
|
|||
import com.sun.tools.javac.util.Options;
|
||||
|
||||
import static com.sun.tools.javac.main.Option.OptionKind.*;
|
||||
import static jdk.javadoc.internal.tool.Main.Result.*;
|
||||
|
||||
/**
|
||||
* javadoc tool options.
|
||||
|
@ -226,63 +227,63 @@ public enum ToolOption {
|
|||
|
||||
PACKAGE("-package", STANDARD) {
|
||||
@Override
|
||||
public void process(Helper helper) {
|
||||
public void process(Helper helper) throws OptionException {
|
||||
helper.setSimpleFilter("package");
|
||||
}
|
||||
},
|
||||
|
||||
PRIVATE("-private", STANDARD) {
|
||||
@Override
|
||||
public void process(Helper helper) {
|
||||
public void process(Helper helper) throws OptionException {
|
||||
helper.setSimpleFilter("private");
|
||||
}
|
||||
},
|
||||
|
||||
PROTECTED("-protected", STANDARD) {
|
||||
@Override
|
||||
public void process(Helper helper) {
|
||||
public void process(Helper helper) throws OptionException {
|
||||
helper.setSimpleFilter("protected");
|
||||
}
|
||||
},
|
||||
|
||||
PUBLIC("-public", STANDARD) {
|
||||
@Override
|
||||
public void process(Helper helper) {
|
||||
public void process(Helper helper) throws OptionException {
|
||||
helper.setSimpleFilter("public");
|
||||
}
|
||||
},
|
||||
|
||||
SHOW_MEMBERS("--show-members", STANDARD, true) {
|
||||
@Override
|
||||
public void process(Helper helper, String arg) {
|
||||
public void process(Helper helper, String arg) throws OptionException {
|
||||
helper.setFilter(this, arg);
|
||||
}
|
||||
},
|
||||
|
||||
SHOW_TYPES("--show-types", STANDARD, true) {
|
||||
@Override
|
||||
public void process(Helper helper, String arg) {
|
||||
public void process(Helper helper, String arg) throws OptionException {
|
||||
helper.setFilter(this, arg);
|
||||
}
|
||||
},
|
||||
|
||||
SHOW_PACKAGES("--show-packages", STANDARD, true) {
|
||||
@Override
|
||||
public void process(Helper helper, String arg) {
|
||||
public void process(Helper helper, String arg) throws OptionException {
|
||||
helper.setShowPackageAccess(SHOW_PACKAGES, arg);
|
||||
}
|
||||
},
|
||||
|
||||
SHOW_MODULE_CONTENTS("--show-module-contents", STANDARD, true) {
|
||||
@Override
|
||||
public void process(Helper helper, String arg) {
|
||||
public void process(Helper helper, String arg) throws OptionException {
|
||||
helper.setShowModuleContents(SHOW_MODULE_CONTENTS, arg);
|
||||
}
|
||||
},
|
||||
|
||||
EXPAND_REQUIRES("--expand-requires", STANDARD, true) {
|
||||
@Override
|
||||
public void process(Helper helper, String arg) {
|
||||
public void process(Helper helper, String arg) throws OptionException {
|
||||
helper.setExpandRequires(EXPAND_REQUIRES, arg);
|
||||
}
|
||||
},
|
||||
|
@ -342,19 +343,26 @@ public enum ToolOption {
|
|||
}
|
||||
},
|
||||
|
||||
DUMPONERROR("--dump-on-error", HIDDEN) {
|
||||
@Override
|
||||
public void process(Helper helper) {
|
||||
helper.dumpOnError = true;
|
||||
}
|
||||
},
|
||||
|
||||
// ----- help options -----
|
||||
|
||||
HELP("--help -help", STANDARD) {
|
||||
@Override
|
||||
public void process(Helper helper) {
|
||||
helper.usage();
|
||||
public void process(Helper helper) throws OptionException {
|
||||
throw new OptionException(OK, helper::usage);
|
||||
}
|
||||
},
|
||||
|
||||
X("-X", STANDARD) {
|
||||
@Override
|
||||
public void process(Helper helper) {
|
||||
helper.Xusage();
|
||||
public void process(Helper helper) throws OptionException {
|
||||
throw new OptionException(OK, helper::Xusage);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -395,9 +403,9 @@ public enum ToolOption {
|
|||
this.hasSuffix = lastChar == ':' || lastChar == '=';
|
||||
}
|
||||
|
||||
void process(Helper helper, String arg) { }
|
||||
void process(Helper helper, String arg) throws OptionException { }
|
||||
|
||||
void process(Helper helper) { }
|
||||
void process(Helper helper) throws OptionException { }
|
||||
|
||||
List<String> getNames() {
|
||||
return names;
|
||||
|
@ -451,6 +459,9 @@ public enum ToolOption {
|
|||
/** Javadoc tool options */
|
||||
final Map<ToolOption, Object> jdtoolOpts = new EnumMap<>(ToolOption.class);
|
||||
|
||||
/** dump stack traces for debugging etc.*/
|
||||
boolean dumpOnError = false;
|
||||
|
||||
/** Set by -breakiterator. */
|
||||
boolean breakiterator = false;
|
||||
|
||||
|
@ -470,7 +481,8 @@ public enum ToolOption {
|
|||
abstract void usage();
|
||||
abstract void Xusage();
|
||||
|
||||
abstract void usageError(String msg, Object... args);
|
||||
abstract String getLocalizedMessage(String msg, Object... args);
|
||||
|
||||
abstract OptionHelper getOptionHelper();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -480,7 +492,7 @@ public enum ToolOption {
|
|||
jdtoolOpts.put(opt, list);
|
||||
}
|
||||
|
||||
void setExpandRequires(ToolOption opt, String arg) {
|
||||
void setExpandRequires(ToolOption opt, String arg) throws OptionException {
|
||||
switch (arg) {
|
||||
case "public":
|
||||
jdtoolOpts.put(opt, AccessKind.PUBLIC);
|
||||
|
@ -489,11 +501,12 @@ public enum ToolOption {
|
|||
jdtoolOpts.put(opt, AccessKind.PRIVATE);
|
||||
break;
|
||||
default:
|
||||
usageError("main.illegal_option_value", arg);
|
||||
String text = getLocalizedMessage("main.illegal_option_value", arg);
|
||||
throw new IllegalOptionValue(this::usage, text);
|
||||
}
|
||||
}
|
||||
|
||||
void setShowModuleContents(ToolOption opt, String arg) {
|
||||
void setShowModuleContents(ToolOption opt, String arg) throws OptionException {
|
||||
switch (arg) {
|
||||
case "api":
|
||||
jdtoolOpts.put(opt, AccessKind.PUBLIC);
|
||||
|
@ -502,11 +515,12 @@ public enum ToolOption {
|
|||
jdtoolOpts.put(opt, AccessKind.PRIVATE);
|
||||
break;
|
||||
default:
|
||||
usageError("main.illegal_option_value", arg);
|
||||
String text = getLocalizedMessage("main.illegal_option_value", arg);
|
||||
throw new IllegalOptionValue(this::usage, text);
|
||||
}
|
||||
}
|
||||
|
||||
void setShowPackageAccess(ToolOption opt, String arg) {
|
||||
void setShowPackageAccess(ToolOption opt, String arg) throws OptionException {
|
||||
switch (arg) {
|
||||
case "exported":
|
||||
jdtoolOpts.put(opt, AccessKind.PUBLIC);
|
||||
|
@ -515,16 +529,17 @@ public enum ToolOption {
|
|||
jdtoolOpts.put(opt, AccessKind.PRIVATE);
|
||||
break;
|
||||
default:
|
||||
usageError("main.illegal_option_value", arg);
|
||||
String text = getLocalizedMessage("main.illegal_option_value", arg);
|
||||
throw new IllegalOptionValue(this::usage, text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setFilter(ToolOption opt, String arg) {
|
||||
void setFilter(ToolOption opt, String arg) throws OptionException {
|
||||
jdtoolOpts.put(opt, getAccessValue(arg));
|
||||
}
|
||||
|
||||
void setSimpleFilter(String arg) {
|
||||
void setSimpleFilter(String arg) throws OptionException {
|
||||
handleSimpleOption(arg);
|
||||
}
|
||||
|
||||
|
@ -532,7 +547,7 @@ public enum ToolOption {
|
|||
fileManagerOpts.put(opt, arg);
|
||||
}
|
||||
|
||||
void handleSimpleOption(String arg) {
|
||||
void handleSimpleOption(String arg) throws OptionException {
|
||||
populateSimpleAccessMap(getAccessValue(arg));
|
||||
}
|
||||
|
||||
|
@ -541,7 +556,7 @@ public enum ToolOption {
|
|||
* -private, so on, in addition to the new ones such as
|
||||
* --show-types:public and so on.
|
||||
*/
|
||||
private AccessKind getAccessValue(String arg) {
|
||||
private AccessKind getAccessValue(String arg) throws OptionException {
|
||||
int colon = arg.indexOf(':');
|
||||
String value = (colon > 0)
|
||||
? arg.substring(colon + 1)
|
||||
|
@ -556,8 +571,8 @@ public enum ToolOption {
|
|||
case "private":
|
||||
return AccessKind.PRIVATE;
|
||||
default:
|
||||
usageError("main.illegal_option_value", value);
|
||||
return null;
|
||||
String text = getLocalizedMessage("main.illegal_option_value", value);
|
||||
throw new IllegalOptionValue(this::usage, text);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -265,13 +265,13 @@ main.Loading_source_file=Loading source file {0}...
|
|||
main.Building_tree=Constructing Javadoc information...
|
||||
main.no_source_files_for_package=No source files for package {0}
|
||||
main.package_not_found=Package {0} not found
|
||||
main.fatal.error=fatal error
|
||||
main.fatal.exception=fatal exception
|
||||
main.fatal.error=fatal error encountered: {0}
|
||||
main.out.of.memory=java.lang.OutOfMemoryError: Please increase memory.\n\
|
||||
For example, on the JDK Classic or HotSpot VMs, add the option -J-Xmx\n\
|
||||
such as -J-Xmx32m.
|
||||
main.done_in=[done in {0} ms]
|
||||
main.more_than_one_doclet_specified_0_and_1=More than one doclet specified ({0} and {1}).
|
||||
main.doclet_could_not_get_location=Could not get location for {0}
|
||||
main.doclet_could_not_set_location=Could not set location for {0}
|
||||
main.doclet_no_classloader_found=Could not obtain classloader to load {0}
|
||||
main.could_not_instantiate_class=Could not instantiate class {0}
|
||||
|
@ -286,7 +286,15 @@ main.illegal_option_value=Illegal option value: "{0}"
|
|||
main.release.bootclasspath.conflict=option {0} cannot be used together with -release
|
||||
main.unsupported.release.version=release version {0} not supported
|
||||
main.release.not.standard.file.manager=-release option specified, but the provided JavaFileManager is not a StandardJavaFileManager.
|
||||
main.file.manager.list=FileManager error listing files: "{0}"
|
||||
main.assertion.error=assertion failed: "{0}}"
|
||||
main.unknown.error=an unknown error has occurred
|
||||
main.internal.error=an internal error has occurred
|
||||
main.unexpected.exception=an unexpected exception was caught: {0}
|
||||
doclet.internal.report.bug=\
|
||||
Please file a bug against the javadoc tool via the Java bug reporting page\n\
|
||||
(http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com)\n\
|
||||
for duplicates. Include error messages and the following diagnostic in your report. Thank you.
|
||||
main.legacy_api=The old Doclet and Taglet APIs in the packages\n\
|
||||
com.sun.javadoc, com.sun.tools.doclets and their implementations\n\
|
||||
are planned to be removed in a future JDK release. These\n\
|
||||
|
|
|
@ -42,7 +42,7 @@ public class T6735320 extends JavadocTester {
|
|||
void test() {
|
||||
javadoc("-d", "out",
|
||||
testSrc("SerialFieldTest.java"));
|
||||
checkExit(Exit.FAILED);
|
||||
checkExit(Exit.ERROR);
|
||||
checkOutput(Output.STDERR, false,
|
||||
"OutOfBoundsException");
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public class TestDupThrowsTags extends JavadocTester {
|
|||
void test() {
|
||||
javadoc("-d", "out",
|
||||
testSrc("TestDupThrowsTags.java"));
|
||||
checkExit(Exit.FAILED);
|
||||
checkExit(Exit.ERROR);
|
||||
|
||||
checkOutput("TestDupThrowsTags.html", true,
|
||||
"Test 1 passes",
|
||||
|
|
|
@ -327,15 +327,27 @@ public abstract class JavadocTester {
|
|||
outputDirectoryCheck = c;
|
||||
}
|
||||
|
||||
/**
|
||||
* The exit codes returned by the javadoc tool.
|
||||
* @see jdk.javadoc.internal.tool.Main.Result
|
||||
*/
|
||||
public enum Exit {
|
||||
OK(0),
|
||||
FAILED(1);
|
||||
OK(0), // Javadoc completed with no errors.
|
||||
ERROR(1), // Completed but reported errors.
|
||||
CMDERR(2), // Bad command-line arguments
|
||||
SYSERR(3), // System error or resource exhaustion.
|
||||
ABNORMAL(4); // Javadoc terminated abnormally
|
||||
|
||||
Exit(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
final int code;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name() + '(' + code + ')';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -349,7 +361,7 @@ public abstract class JavadocTester {
|
|||
if (exitCode == expected.code) {
|
||||
passed("return code " + exitCode);
|
||||
} else {
|
||||
failed("return code " + exitCode +"; expected " + expected.code + " (" + expected + ")");
|
||||
failed("return code " + exitCode +"; expected " + expected);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,6 @@ public class TestBadSourceFile extends JavadocTester {
|
|||
javadoc("-Xdoclint:none",
|
||||
"-d", "out",
|
||||
testSrc("C2.java"));
|
||||
checkExit(Exit.FAILED);
|
||||
checkExit(Exit.ERROR);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public class TestConstantValuesPage extends JavadocTester {
|
|||
javadoc("-d", "out",
|
||||
"-sourcepath", testSrc,
|
||||
"foo");
|
||||
checkExit(Exit.FAILED);
|
||||
checkExit(Exit.CMDERR);
|
||||
|
||||
checkOutput(Output.OUT, false,
|
||||
"constant-values.html...");
|
||||
|
|
|
@ -52,6 +52,8 @@ public class TestDocErrorReporter extends JavadocTester {
|
|||
"-encoding", "xyz",
|
||||
testSrc("TestDocErrorReporter.java"));
|
||||
|
||||
checkExit(Exit.FAILED);
|
||||
checkExit(Exit.ERROR);
|
||||
|
||||
checkOutput(Output.OUT, true, "error: unsupported encoding: xyz");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ public class TestHelpOption extends JavadocTester {
|
|||
"-helpfile", testSrc("test-help.html"),
|
||||
"-helpfile", testSrc("test-help.html"),
|
||||
testSrc("Sample.java"));
|
||||
checkExit(Exit.FAILED);
|
||||
checkExit(Exit.ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -121,7 +121,7 @@ public class TestHelpOption extends JavadocTester {
|
|||
"-helpfile", testSrc("test-help.html"),
|
||||
"-nohelp",
|
||||
testSrc("Sample.java"));
|
||||
checkExit(Exit.FAILED);
|
||||
checkExit(Exit.ERROR);
|
||||
}
|
||||
|
||||
private void checkOutput(boolean withOption) {
|
||||
|
|
|
@ -57,7 +57,7 @@ public class TestIOException extends JavadocTester {
|
|||
try {
|
||||
javadoc("-d", outDir.toString(),
|
||||
new File(testSrc, "TestIOException.java").getPath());
|
||||
checkExit(Exit.FAILED);
|
||||
checkExit(Exit.ERROR);
|
||||
checkOutput(Output.OUT, true,
|
||||
"Destination directory not writable: " + outDir);
|
||||
} finally {
|
||||
|
@ -85,7 +85,7 @@ public class TestIOException extends JavadocTester {
|
|||
javadoc("-d", outDir.toString(),
|
||||
new File(testSrc, "TestIOException.java").getPath());
|
||||
|
||||
checkExit(Exit.FAILED);
|
||||
checkExit(Exit.ERROR);
|
||||
checkOutput(Output.OUT, true,
|
||||
"Error writing file: " + index);
|
||||
} finally {
|
||||
|
@ -123,7 +123,7 @@ public class TestIOException extends JavadocTester {
|
|||
setOutputDirectoryCheck(DirectoryCheck.NONE);
|
||||
javadoc("-d", outDir.toString(),
|
||||
src_p_C.getPath());
|
||||
checkExit(Exit.FAILED);
|
||||
checkExit(Exit.ERROR);
|
||||
checkOutput(Output.OUT, true,
|
||||
"Error writing file: " + new File(pkgOutDir, "C.html"));
|
||||
} finally {
|
||||
|
@ -167,7 +167,7 @@ public class TestIOException extends JavadocTester {
|
|||
javadoc("-d", outDir.toString(),
|
||||
"-sourcepath", srcDir.getPath(),
|
||||
"p");
|
||||
checkExit(Exit.FAILED);
|
||||
checkExit(Exit.ERROR);
|
||||
checkOutput(Output.OUT, true,
|
||||
"Error writing file: " + new File(docFilesOutDir, "info.txt"));
|
||||
} finally {
|
||||
|
|
|
@ -42,7 +42,7 @@ public class TestPackageHtml extends JavadocTester {
|
|||
javadoc("-d", "out-pkg-html",
|
||||
"-sourcepath", testSrc,
|
||||
"pkg1");
|
||||
checkExit(Exit.FAILED);
|
||||
checkExit(Exit.ERROR);
|
||||
checkOutput(Output.OUT, true, "package.html:10: error: bad use of '>'");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ public class TestParamTaglet extends JavadocTester {
|
|||
javadoc("-d", "out",
|
||||
"-sourcepath", testSrc,
|
||||
"pkg");
|
||||
checkExit(Exit.FAILED);
|
||||
checkExit(Exit.ERROR);
|
||||
|
||||
checkOutput("pkg/C.html", true,
|
||||
//Regular param tags.
|
||||
|
|
|
@ -73,7 +73,7 @@ public class TestSearch extends JavadocTester {
|
|||
void test2a() {
|
||||
javadoc("-d", "out-2a", "-Xdoclint:all", "-sourcepath", testSrc,
|
||||
"-use", "pkg", "pkg1", "pkg2", "pkg3");
|
||||
checkExit(Exit.FAILED);
|
||||
checkExit(Exit.ERROR);
|
||||
checkDocLintErrors();
|
||||
checkSearchOutput(true);
|
||||
checkSingleIndex(true);
|
||||
|
|
|
@ -44,7 +44,7 @@ public class TestSerializedFormDeprecationInfo extends JavadocTester {
|
|||
javadoc("-d", "out-default",
|
||||
"-sourcepath", testSrc,
|
||||
"pkg1");
|
||||
checkExit(Exit.FAILED); // TODO: should be OK
|
||||
checkExit(Exit.OK);
|
||||
|
||||
checkCommentDeprecated(true);
|
||||
checkNoComment(false);
|
||||
|
@ -56,7 +56,7 @@ public class TestSerializedFormDeprecationInfo extends JavadocTester {
|
|||
"-nocomment",
|
||||
"-sourcepath", testSrc,
|
||||
"pkg1");
|
||||
checkExit(Exit.FAILED); // TODO: should be OK
|
||||
checkExit(Exit.OK);
|
||||
|
||||
checkNoComment(true);
|
||||
checkCommentDeprecated(false);
|
||||
|
@ -68,7 +68,7 @@ public class TestSerializedFormDeprecationInfo extends JavadocTester {
|
|||
"-nodeprecated",
|
||||
"-sourcepath", testSrc,
|
||||
"pkg1");
|
||||
checkExit(Exit.FAILED); // TODO: should be OK
|
||||
checkExit(Exit.OK);
|
||||
|
||||
checkNoDeprecated(true);
|
||||
checkNoCommentNoDeprecated(false);
|
||||
|
@ -81,7 +81,7 @@ public class TestSerializedFormDeprecationInfo extends JavadocTester {
|
|||
"-nodeprecated",
|
||||
"-sourcepath", testSrc,
|
||||
"pkg1");
|
||||
checkExit(Exit.FAILED); // TODO: should be OK
|
||||
checkExit(Exit.OK);
|
||||
checkNoCommentNoDeprecated(true);
|
||||
checkNoDeprecated(false);
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ public class TestSerializedFormDeprecationInfo extends JavadocTester {
|
|||
"<dl>\n"
|
||||
+ "<dt><span class=\"throwsLabel\">Throws:</span></dt>\n"
|
||||
+ "<dd><code>"
|
||||
+ "java.io.IOException</code></dd>\n"
|
||||
+ "java.io.IOException</code> - on error</dd>\n"
|
||||
+ "<dt><span class=\"seeLabel\">See Also:</span>"
|
||||
+ "</dt>\n"
|
||||
+ "<dd><a href=\"pkg1/C1.html#setUndecorated-boolean-\">"
|
||||
|
@ -121,7 +121,7 @@ public class TestSerializedFormDeprecationInfo extends JavadocTester {
|
|||
+ "<div class=\"block\">Reads the object stream.</div>\n"
|
||||
+ "<dl>\n"
|
||||
+ "<dt><span class=\"throwsLabel\">Throws:</span></dt>\n"
|
||||
+ "<dd><code>java.io.IOException</code></dd>\n"
|
||||
+ "<dd><code>java.io.IOException</code> - on error</dd>\n"
|
||||
+ "</dl>",
|
||||
"<span class=\"deprecatedLabel\">Deprecated.</span>"
|
||||
+ " </div>\n"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -75,7 +75,6 @@ public class C1 implements Serializable {
|
|||
* @param test boolean value
|
||||
* @exception IllegalArgumentException if the <code>owner</code>'s
|
||||
* <code>GraphicsConfiguration</code> is not from a screen device
|
||||
* @exception HeadlessException
|
||||
*/
|
||||
public C1(String title, boolean test) {
|
||||
|
||||
|
@ -98,6 +97,7 @@ public class C1 implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @throws java.io.IOException on error
|
||||
* @see #setUndecorated(boolean)
|
||||
*/
|
||||
public void readObject() throws IOException {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -74,7 +74,7 @@ public class C2 implements Serializable {
|
|||
* Reads the object stream.
|
||||
*
|
||||
* @param s ObjectInputStream
|
||||
* @throws IOException
|
||||
* @throws IOException on error
|
||||
* @deprecated As of JDK version 1.5, replaced by
|
||||
* {@link C1#setUndecorated(boolean) setUndecorated(boolean)}.
|
||||
*/
|
||||
|
|
|
@ -45,7 +45,7 @@ public class TestSinceTag extends JavadocTester {
|
|||
javadoc("-d", "out-since",
|
||||
"-sourcepath", testSrc,
|
||||
"pkg1");
|
||||
checkExit(Exit.FAILED); // TODO: investigate
|
||||
checkExit(Exit.OK);
|
||||
|
||||
checkSince(true);
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ public class TestSinceTag extends JavadocTester {
|
|||
"-sourcepath", testSrc,
|
||||
"-nosince",
|
||||
"pkg1");
|
||||
checkExit(Exit.FAILED); // TODO: investigate
|
||||
checkExit(Exit.OK);
|
||||
|
||||
checkSince(false);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -72,7 +72,6 @@ public class C1 implements Serializable {
|
|||
* @param test boolean value
|
||||
* @exception IllegalArgumentException if the <code>owner</code>'s
|
||||
* <code>GraphicsConfiguration</code> is not from a screen device
|
||||
* @exception HeadlessException
|
||||
*/
|
||||
public C1(String title, boolean test) {
|
||||
}
|
||||
|
@ -93,6 +92,7 @@ public class C1 implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* @throws java.io.IOException on error
|
||||
* @see #setUndecorated(boolean)
|
||||
*/
|
||||
public void readObject() throws IOException {
|
||||
|
|
|
@ -52,7 +52,7 @@ public class TestSupplementary extends JavadocTester {
|
|||
javadoc("-locale", "en_US",
|
||||
"-d", "out",
|
||||
testSrc("C.java"));
|
||||
checkExit(Exit.FAILED);
|
||||
checkExit(Exit.ERROR);
|
||||
|
||||
checkOutput(Output.OUT, true,
|
||||
"C.java:36: error: unexpected text",
|
||||
|
|
|
@ -45,7 +45,7 @@ public class TestThrowsTag extends JavadocTester {
|
|||
javadoc("-d", "out",
|
||||
"-sourcepath", testSrc,
|
||||
"pkg");
|
||||
checkExit(Exit.FAILED); // TODO: investigate why failed
|
||||
checkExit(Exit.OK);
|
||||
|
||||
checkOutput("pkg/C.html", true,
|
||||
"<dd><code><a href=\"../pkg/T1.html\" title=\"class in pkg\">T1</a></code> - the first throws tag.</dd>\n" +
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -23,4 +23,4 @@
|
|||
|
||||
package pkg;
|
||||
|
||||
public class T1 extends Exception {}
|
||||
public class T1 extends RuntimeException {}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -23,4 +23,4 @@
|
|||
|
||||
package pkg;
|
||||
|
||||
public class T2 extends Exception {}
|
||||
public class T2 extends RuntimeException {}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -23,4 +23,4 @@
|
|||
|
||||
package pkg;
|
||||
|
||||
public class T3 extends Exception {}
|
||||
public class T3 extends RuntimeException {}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -23,4 +23,4 @@
|
|||
|
||||
package pkg;
|
||||
|
||||
public class T4 extends Exception {}
|
||||
public class T4 extends RuntimeException {}
|
||||
|
|
|
@ -46,7 +46,7 @@ public class TestValueTag extends JavadocTester {
|
|||
"-sourcepath", testSrc,
|
||||
"-tag", "todo",
|
||||
"pkg1", "pkg2");
|
||||
checkExit(Exit.FAILED);
|
||||
checkExit(Exit.ERROR);
|
||||
|
||||
checkOutput("pkg1/Class1.html", true,
|
||||
// Base case: using @value on a constant.
|
||||
|
|
|
@ -47,7 +47,7 @@ public class TestWarnings extends JavadocTester {
|
|||
javadoc("-d", "out-default",
|
||||
"-sourcepath", testSrc,
|
||||
"pkg");
|
||||
checkExit(Exit.FAILED);
|
||||
checkExit(Exit.ERROR);
|
||||
|
||||
checkOutput(Output.OUT, true,
|
||||
"X.java:23: error: self-closing element not allowed");
|
||||
|
@ -75,7 +75,7 @@ public class TestWarnings extends JavadocTester {
|
|||
"-private",
|
||||
"-sourcepath", testSrc,
|
||||
"pkg");
|
||||
checkExit(Exit.FAILED);
|
||||
checkExit(Exit.ERROR);
|
||||
|
||||
checkOutput("pkg/X.html", true,
|
||||
"<a href=\"../pkg/X.html#m--\"><code>m()</code></a><br/>",
|
||||
|
|
|
@ -28,7 +28,11 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import jdk.javadoc.internal.tool.Main;
|
||||
import jdk.javadoc.internal.tool.Main.Result;
|
||||
|
||||
import static jdk.javadoc.internal.tool.Main.Result.*;
|
||||
|
||||
/**
|
||||
* @test
|
||||
|
@ -43,13 +47,13 @@ public class ReleaseOption {
|
|||
}
|
||||
|
||||
void run() {
|
||||
doRunTest(0, out -> out.contains("compiler.err.doesnt.exist: java.util.stream"), "--release", "7");
|
||||
doRunTest(0, out -> !out.contains("compiler.err.doesnt.exist: java.util.stream"), "--release", "8");
|
||||
doRunTest(1, out -> true, "--release", "7", "-source", "7");
|
||||
doRunTest(1, out -> true, "--release", "7", "-bootclasspath", "any");
|
||||
doRunTest(OK, out -> out.contains("compiler.err.doesnt.exist: java.util.stream"), "--release", "7");
|
||||
doRunTest(OK, out -> !out.contains("compiler.err.doesnt.exist: java.util.stream"), "--release", "8");
|
||||
doRunTest(CMDERR, out -> true, "--release", "7", "-source", "7");
|
||||
doRunTest(CMDERR, out -> true, "--release", "7", "-bootclasspath", "any");
|
||||
}
|
||||
|
||||
void doRunTest(int expectedResult, Predicate<String> validate, String... args) {
|
||||
void doRunTest(Result expectedResult, Predicate<String> validate, String... args) {
|
||||
System.err.println("running with args: " + Arrays.asList(args));
|
||||
List<String> options = new ArrayList<>();
|
||||
options.addAll(Arrays.asList(args));
|
||||
|
@ -60,7 +64,7 @@ public class ReleaseOption {
|
|||
int actualResult = Main.execute(options.toArray(new String[0]), pw);
|
||||
System.err.println("actual result=" + actualResult);
|
||||
System.err.println("actual output=" + out.toString());
|
||||
if (actualResult != expectedResult)
|
||||
if (actualResult != expectedResult.exitCode)
|
||||
throw new Error("Exit code not as expected");
|
||||
if (!validate.test(out.toString())) {
|
||||
throw new Error("Output not as expected");
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8151102
|
||||
* @summary verify that option --dump-on-error functions correctly
|
||||
* @library /tools/lib
|
||||
* @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
|
||||
* @build toolbox.ToolBox toolbox.TestRunner
|
||||
* @run main TestExceptionHandling
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.PrintStream;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
|
||||
import toolbox.*;
|
||||
|
||||
/**
|
||||
* This class tests if stack traces printed when
|
||||
* --dump-on-error. The standard doclet is used,
|
||||
* to test the doclet as well as the tool.
|
||||
*/
|
||||
public class TestExceptionHandling extends TestRunner {
|
||||
|
||||
final ToolBox tb;
|
||||
final File testSrcFile;
|
||||
final PrintStream ostream;
|
||||
final JavadocTask cmdTask;
|
||||
final JavadocTask apiTask;
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
TestExceptionHandling tester = new TestExceptionHandling();
|
||||
tester.runTests();
|
||||
}
|
||||
|
||||
TestExceptionHandling() {
|
||||
super(System.err);
|
||||
tb = new ToolBox();
|
||||
ostream = System.err;
|
||||
testSrcFile = new File(System.getProperty("test.src"), "TestExceptionHandling.java");
|
||||
cmdTask = new JavadocTask(tb, Task.Mode.CMDLINE);
|
||||
apiTask = new JavadocTask(tb, Task.Mode.API);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDocletTrace() throws Exception {
|
||||
Path out = Paths.get("out");
|
||||
// create a file with the same name as the output
|
||||
out.toFile().createNewFile();
|
||||
cmdTask.outdir(out);
|
||||
cmdTask.options("--dump-on-error");
|
||||
cmdTask.files(testSrcFile.getAbsolutePath());
|
||||
Task.Result tr = cmdTask.run(Task.Expect.FAIL);
|
||||
|
||||
String errString = "Destination directory is not a directory: " + out.toString();
|
||||
// check the regular message
|
||||
assertPresent("javadoc: error - " + errString, tr.getOutputLines(Task.OutputKind.DIRECT));
|
||||
// check that first line of the stack trace is present
|
||||
assertPresent("jdk.javadoc.internal.doclets.toolkit.util.SimpleDocletException: " +
|
||||
errString, tr.getOutputLines(Task.OutputKind.STDERR));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToolTrace() throws Exception {
|
||||
Path out = Paths.get("out.dir");
|
||||
cmdTask.options("--dump-on-error", "-doclet", "NonExistentDoclet");
|
||||
cmdTask.outdir(out);
|
||||
cmdTask.files(testSrcFile.getAbsolutePath());
|
||||
Task.Result tr = cmdTask.run(Task.Expect.FAIL);
|
||||
|
||||
// check the regular message
|
||||
assertPresent("javadoc: error - Cannot find doclet class NonExistentDoclet",
|
||||
tr.getOutputLines(Task.OutputKind.DIRECT));
|
||||
|
||||
// check that first line of the stack trace is present
|
||||
assertPresent("java.lang.ClassNotFoundException: NonExistentDoclet",
|
||||
tr.getOutputLines(Task.OutputKind.STDERR));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApiModeMissingDoclet() throws Exception {
|
||||
apiTask.options("-doclet", "MissingDoclet");
|
||||
try {
|
||||
Task.Result result = apiTask.run(Task.Expect.FAIL);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// ok got the right exception
|
||||
return;
|
||||
}
|
||||
throw new Exception("expected exception/error not found");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApiModeMultipleDoclets() throws Exception {
|
||||
apiTask.options("-doclet", "MissingDoclet",
|
||||
"-doclet", "SomeDoclet");
|
||||
try {
|
||||
Task.Result result = apiTask.run(Task.Expect.FAIL);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// ok got the right exception
|
||||
return;
|
||||
}
|
||||
throw new Exception("expected exception/error not found");
|
||||
}
|
||||
|
||||
void assertPresent(String regex, List<String> output) throws Exception {
|
||||
List<String> gresult = tb.grep(regex, output);
|
||||
if (gresult.isEmpty()) {
|
||||
ostream.println("Expected: " + regex);
|
||||
ostream.println("Output: ");
|
||||
output.forEach(s -> {
|
||||
ostream.println(s);
|
||||
});
|
||||
throw new Exception("Test fails expected output not found: " + regex);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue