8129909: Add -Xdoclint/package: to javadoc

Adding -Xdoclint/package: command line option, similar to the javac -Xdoclint/package: option, to javadoc.

Reviewed-by: darcy, jjg, ksrini
This commit is contained in:
Jan Lahoda 2015-07-13 16:33:42 +02:00
parent 629ace2fd4
commit 85193a1a26
8 changed files with 125 additions and 40 deletions

View File

@ -344,6 +344,10 @@ public class DocLint implements Plugin {
checker.scan(dc, p);
}
public boolean shouldCheck(CompilationUnitTree unit) {
return env.shouldCheck(unit);
}
public void reportStats(PrintWriter out) {
env.messages.reportStats(out);
}
@ -406,26 +410,8 @@ public class DocLint implements Plugin {
@Override @DefinedBy(Api.COMPILER_TREE)
public Void visitCompilationUnit(CompilationUnitTree node, Void p) {
if (env.includePackages != null) {
String packageName = node.getPackageName() != null
? node.getPackageName().toString()
: "";
if (!env.includePackages.isEmpty()) {
boolean included = false;
for (Pattern pack : env.includePackages) {
if (pack.matcher(packageName).matches()) {
included = true;
break;
}
}
if (!included)
return null;
}
for (Pattern pack : env.excludePackages) {
if (pack.matcher(packageName).matches()) {
return null;
}
}
if (!env.shouldCheck(node)) {
return null;
}
return super.visitCompilationUnit(node, p);
}

View File

@ -43,6 +43,7 @@ import javax.lang.model.util.Types;
import javax.tools.Diagnostic.Kind;
import com.sun.source.doctree.DocCommentTree;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.util.DocTrees;
import com.sun.source.util.JavacTask;
import com.sun.source.util.SourcePositions;
@ -229,6 +230,35 @@ public class Env {
return sp.getStartPosition(p.getCompilationUnit(), p.getLeaf());
}
boolean shouldCheck(CompilationUnitTree unit) {
if (includePackages == null)
return true;
String packageName = unit.getPackageName() != null
? unit.getPackageName().toString()
: "";
if (!includePackages.isEmpty()) {
boolean included = false;
for (Pattern pack : includePackages) {
if (pack.matcher(packageName).matches()) {
included = true;
break;
}
}
if (!included)
return false;
}
for (Pattern pack : excludePackages) {
if (pack.matcher(packageName).matches()) {
return false;
}
}
return true;
}
private <T extends Comparable<T>> T min(T item1, T item2) {
return (item1 == null) ? item2
: (item2 == null) ? item1

View File

@ -289,9 +289,11 @@ public class ConfigurationImpl extends Configuration {
} else if (opt.equals("-html5")) {
htmlVersion = HtmlVersion.HTML5;
} else if (opt.equals("-xdoclint")) {
doclintOpts.add(null);
doclintOpts.add(DocLint.XMSGS_OPTION);
} else if (opt.startsWith("-xdoclint:")) {
doclintOpts.add(opt.substring(opt.indexOf(":") + 1));
doclintOpts.add(DocLint.XMSGS_CUSTOM_PREFIX + opt.substring(opt.indexOf(":") + 1));
} else if (opt.startsWith("-xdoclint/package:")) {
doclintOpts.add(DocLint.XCHECK_PACKAGE + opt.substring(opt.indexOf(":") + 1));
}
}
if (root.specifiedClasses().length > 0) {
@ -348,7 +350,8 @@ public class ConfigurationImpl extends Configuration {
option.equals("-html4") ||
option.equals("-html5") ||
option.equals("-xdoclint") ||
option.startsWith("-xdoclint:")) {
option.startsWith("-xdoclint:") ||
option.startsWith("-xdoclint/package:")) {
return 1;
} else if (option.equals("-help")) {
// Uugh: first, this should not be hidden inside optionLength,
@ -476,6 +479,12 @@ public class ConfigurationImpl extends Configuration {
reporter.printError(getText("doclet.Option_doclint_invalid_arg"));
return false;
}
} else if (opt.startsWith("-xdoclint/package:")) {
if (!DocLint.isValidOption(
opt.replace("-xdoclint/package:", DocLint.XCHECK_PACKAGE))) {
reporter.printError(getText("doclet.Option_doclint_package_invalid_arg"));
return false;
}
}
}
return true;

View File

@ -231,4 +231,10 @@ doclet.X.usage=Provided by standard doclet:\n\
\ -Xdoclint Enable recommended checks for problems in javadoc comments\n\
\ -Xdoclint:(all|none|[-]<group>) \n\
\ Enable or disable specific checks for problems in javadoc comments,\n\
\ where <group> is one of accessibility, html, missing, reference, or syntax.\n
\ where <group> is one of accessibility, html, missing, reference, or syntax.\n\
\ -Xdoclint/package:([-]<packages>)\n\
\ Enable or disable checks in specific packages. <packages> is a comma separated\n\
\ list of package specifiers. Package specifier is either a qualified name of a package\n\
\ or a package name prefix followed by .*, which expands to all sub-packages of\n\
\ the given package. Prefix the package specifier with - to disable checks for\n\
\ the specified packages.\n

View File

@ -13,6 +13,7 @@ doclet.Option_conflict=Option {0} conflicts with {1}
doclet.Option_reuse=Option reused: {0}
doclet.Option_doclint_no_qualifiers=Access qualifiers not permitted for -Xdoclint arguments
doclet.Option_doclint_invalid_arg=Invalid argument for -Xdoclint option
doclet.Option_doclint_package_invalid_arg=Invalid argument for -Xdoclint/package option
doclet.exception_encountered= {0} encountered \n\
\twhile attempting to create file: {1}
doclet.perform_copy_exception_encountered= {0} encountered while \n\

View File

@ -31,6 +31,7 @@ import java.util.*;
import javax.tools.JavaFileManager;
import com.sun.javadoc.*;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.util.JavacTask;
import com.sun.source.util.TreePath;
import com.sun.tools.doclint.DocLint;
@ -816,16 +817,19 @@ public class DocEnv {
void initDoclint(Collection<String> opts, Collection<String> customTagNames, String htmlVersion) {
ArrayList<String> doclintOpts = new ArrayList<>();
boolean msgOptionSeen = false;
for (String opt: opts) {
doclintOpts.add(opt == null ? DocLint.XMSGS_OPTION : DocLint.XMSGS_CUSTOM_PREFIX + opt);
for (String opt : opts) {
if (opt.startsWith(DocLint.XMSGS_OPTION)) {
if (opt.equals(DocLint.XMSGS_CUSTOM_PREFIX + "none"))
return;
msgOptionSeen = true;
}
doclintOpts.add(opt);
}
if (doclintOpts.isEmpty()) {
if (!msgOptionSeen) {
doclintOpts.add(DocLint.XMSGS_OPTION);
} else if (doclintOpts.size() == 1
&& doclintOpts.get(0).equals(DocLint.XMSGS_CUSTOM_PREFIX + "none")) {
return;
}
String sep = "";
@ -848,4 +852,10 @@ public class DocEnv {
boolean showTagMessages() {
return (doclint == null);
}
Map<CompilationUnitTree, Boolean> shouldCheck = new HashMap<>();
boolean shouldCheck(CompilationUnitTree unit) {
return shouldCheck.computeIfAbsent(unit, doclint :: shouldCheck);
}
}

View File

@ -129,6 +129,7 @@ public abstract class DocImpl implements Doc, Comparable<Object> {
String d = documentation();
if (env.doclint != null
&& treePath != null
&& env.shouldCheck(treePath.getCompilationUnit())
&& d.equals(getCommentText(treePath))) {
env.doclint.scan(treePath);
}

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 8004834 8007610
* @bug 8004834 8007610 8129909
* @summary Add doclint support into javadoc
* @modules jdk.compiler/com.sun.tools.javac.main
*/
@ -59,7 +59,7 @@ public class DocLintTest {
DocumentationTool javadoc;
StandardJavaFileManager fm;
JavaFileObject file;
Iterable<? extends JavaFileObject> files;
final String code =
/* 01 */ "/** Class comment. */\n" +
@ -77,6 +77,20 @@ public class DocLintTest {
/* 13 */ " public int emptyReturn() { return 0; }\n" +
/* 14 */ "}\n";
final String p1Code =
/* 01 */ "package p1;\n" +
/* 02 */ "public class P1Test {\n" +
/* 03 */ " /** Syntax < error. */\n" +
/* 04 */ " public void method() { }\n" +
/* 05 */ "}\n";
final String p2Code =
/* 01 */ "package p2;\n" +
/* 02 */ "public class P2Test {\n" +
/* 03 */ " /** Syntax < error. */\n" +
/* 04 */ " public void method() { }\n" +
/* 05 */ "}\n";
private final String rawDiags = "-XDrawDiagnostics";
private enum Message {
@ -85,6 +99,9 @@ public class DocLintTest {
DL_ERR9(ERROR, "Test.java:9:14: compiler.err.proc.messager: reference not found"),
DL_WRN12(WARNING, "Test.java:12:9: compiler.warn.proc.messager: no description for @return"),
DL_ERR_P1TEST(ERROR, "P1Test.java:3:16: compiler.err.proc.messager: malformed HTML"),
DL_ERR_P2TEST(ERROR, "P2Test.java:3:16: compiler.err.proc.messager: malformed HTML"),
// doclint messages when -XDrawDiagnostics is not in effect
DL_ERR9A(ERROR, "Test.java:9: error: reference not found"),
DL_WRN12A(WARNING, "Test.java:12: warning: no description for @return"),
@ -95,7 +112,8 @@ public class DocLintTest {
// javadoc messages for bad options
OPT_BADARG(ERROR, "javadoc: error - Invalid argument for -Xdoclint option"),
OPT_BADQUAL(ERROR, "javadoc: error - Access qualifiers not permitted for -Xdoclint arguments");
OPT_BADQUAL(ERROR, "javadoc: error - Access qualifiers not permitted for -Xdoclint arguments"),
OPT_BADPACKAGEARG(ERROR, "javadoc: error - Invalid argument for -Xdoclint/package option");
final Diagnostic.Kind kind;
final String text;
@ -124,12 +142,7 @@ public class DocLintTest {
fm = javadoc.getStandardFileManager(null, null, null);
try {
fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File(".")));
file = new SimpleJavaFileObject(URI.create("Test.java"), JavaFileObject.Kind.SOURCE) {
@Override
public CharSequence getCharContent(boolean ignoreEncoding) {
return code;
}
};
files = Arrays.asList(new TestJFO("Test.java", code));
test(Collections.<String>emptyList(),
Main.Result.ERROR,
@ -175,6 +188,21 @@ public class DocLintTest {
Main.Result.ERROR,
EnumSet.of(Message.OPT_BADARG));
files = Arrays.asList(new TestJFO("p1/P1Test.java", p1Code),
new TestJFO("p2/P2Test.java", p2Code));
test(Arrays.asList(rawDiags),
Main.Result.ERROR,
EnumSet.of(Message.DL_ERR_P1TEST, Message.DL_ERR_P2TEST));
test(Arrays.asList(rawDiags, "-Xdoclint/package:p1"),
Main.Result.ERROR,
EnumSet.of(Message.DL_ERR_P1TEST));
test(Arrays.asList(rawDiags, "-Xdoclint/package:*p"),
Main.Result.ERROR,
EnumSet.of(Message.OPT_BADPACKAGEARG));
if (errors > 0)
throw new Exception(errors + " errors occurred");
} finally {
@ -186,7 +214,6 @@ public class DocLintTest {
System.err.println("test: " + opts);
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
List<JavaFileObject> files = Arrays.asList(file);
try {
DocumentationTask t = javadoc.getTask(pw, fm, null, null, opts, files);
boolean ok = t.call();
@ -257,4 +284,19 @@ public class DocLintTest {
}
int errors;
class TestJFO extends SimpleJavaFileObject {
private final String content;
public TestJFO(String fileName, String content) {
super(URI.create(fileName), JavaFileObject.Kind.SOURCE);
this.content = content;
}
@Override
public CharSequence getCharContent(boolean ignoreEncoding) {
return content;
}
};
}