# HG changeset patch # User jlahoda # Date 1436798022 -7200 # Node ID 94c1f3391e374ae95cd71265ab994aeb37a8e338 # Parent d1e5707cd4ebd1353fcd666dbc642d45043b9acf 8129909: Add -Xdoclint/package: to javadoc Summary: Adding -Xdoclint/package: command line option, similar to the javac -Xdoclint/package: option, to javadoc. Reviewed-by: darcy, jjg, ksrini diff -r d1e5707cd4eb -r 94c1f3391e37 src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java --- a/src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java Mon Jul 13 16:57:52 2015 +0400 +++ b/src/jdk.compiler/share/classes/com/sun/tools/doclint/DocLint.java Mon Jul 13 16:33:42 2015 +0200 @@ -344,6 +344,10 @@ 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 @@ @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); } diff -r d1e5707cd4eb -r 94c1f3391e37 src/jdk.compiler/share/classes/com/sun/tools/doclint/Env.java --- a/src/jdk.compiler/share/classes/com/sun/tools/doclint/Env.java Mon Jul 13 16:57:52 2015 +0400 +++ b/src/jdk.compiler/share/classes/com/sun/tools/doclint/Env.java Mon Jul 13 16:33:42 2015 +0200 @@ -43,6 +43,7 @@ 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 @@ 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 min(T item1, T item2) { return (item1 == null) ? item2 : (item2 == null) ? item1 diff -r d1e5707cd4eb -r 94c1f3391e37 src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java --- a/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java Mon Jul 13 16:57:52 2015 +0400 +++ b/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java Mon Jul 13 16:33:42 2015 +0200 @@ -289,9 +289,11 @@ } 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 @@ 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 @@ 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; diff -r d1e5707cd4eb -r 94c1f3391e37 src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties --- a/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties Mon Jul 13 16:57:52 2015 +0400 +++ b/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties Mon Jul 13 16:33:42 2015 +0200 @@ -231,4 +231,10 @@ \ -Xdoclint Enable recommended checks for problems in javadoc comments\n\ \ -Xdoclint:(all|none|[-]) \n\ \ Enable or disable specific checks for problems in javadoc comments,\n\ -\ where is one of accessibility, html, missing, reference, or syntax.\n +\ where is one of accessibility, html, missing, reference, or syntax.\n\ +\ -Xdoclint/package:([-])\n\ +\ Enable or disable checks in specific 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 diff -r d1e5707cd4eb -r 94c1f3391e37 src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties --- a/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties Mon Jul 13 16:57:52 2015 +0400 +++ b/src/jdk.javadoc/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties Mon Jul 13 16:33:42 2015 +0200 @@ -13,6 +13,7 @@ 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\ diff -r d1e5707cd4eb -r 94c1f3391e37 src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocEnv.java --- a/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocEnv.java Mon Jul 13 16:57:52 2015 +0400 +++ b/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocEnv.java Mon Jul 13 16:33:42 2015 +0200 @@ -31,6 +31,7 @@ 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 @@ void initDoclint(Collection opts, Collection customTagNames, String htmlVersion) { ArrayList 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 @@ boolean showTagMessages() { return (doclint == null); } + + Map shouldCheck = new HashMap<>(); + + boolean shouldCheck(CompilationUnitTree unit) { + return shouldCheck.computeIfAbsent(unit, doclint :: shouldCheck); + } } diff -r d1e5707cd4eb -r 94c1f3391e37 src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocImpl.java --- a/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocImpl.java Mon Jul 13 16:57:52 2015 +0400 +++ b/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocImpl.java Mon Jul 13 16:33:42 2015 +0200 @@ -129,6 +129,7 @@ String d = documentation(); if (env.doclint != null && treePath != null + && env.shouldCheck(treePath.getCompilationUnit()) && d.equals(getCommentText(treePath))) { env.doclint.scan(treePath); } diff -r d1e5707cd4eb -r 94c1f3391e37 test/tools/javadoc/doclint/DocLintTest.java --- a/test/tools/javadoc/doclint/DocLintTest.java Mon Jul 13 16:57:52 2015 +0400 +++ b/test/tools/javadoc/doclint/DocLintTest.java Mon Jul 13 16:33:42 2015 +0200 @@ -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 @@ DocumentationTool javadoc; StandardJavaFileManager fm; - JavaFileObject file; + Iterable files; final String code = /* 01 */ "/** Class comment. */\n" + @@ -77,6 +77,20 @@ /* 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 @@ 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 @@ // 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 @@ 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.emptyList(), Main.Result.ERROR, @@ -175,6 +188,21 @@ 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 @@ System.err.println("test: " + opts); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); - List files = Arrays.asList(file); try { DocumentationTask t = javadoc.getTask(pw, fm, null, null, opts, files); boolean ok = t.call(); @@ -257,4 +284,19 @@ } 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; + } + }; }