8220379: Fix doclint handling of headings

Reviewed-by: erikj, jlahoda
This commit is contained in:
Jonathan Gibbons 2019-03-14 11:39:00 -07:00
parent 4bfd3db2e0
commit d3242724c9
17 changed files with 144 additions and 84 deletions

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2014, 2019, 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
@ -38,7 +38,7 @@ $(eval $(call IncludeCustomExtension, CompileJavaModules.gmk))
################################################################################
# Module specific build settings
java.base_ADD_JAVAC_FLAGS += -Xdoclint:all/protected,-reference '-Xdoclint/package:java.*,javax.*' -XDstringConcat=inline
java.base_ADD_JAVAC_FLAGS += -Xdoclint:all/protected,-reference,-accessibility '-Xdoclint/package:java.*,javax.*' -XDstringConcat=inline
java.base_COPY += .icu .dat .spp content-types.properties hijrah-config-islamic-umalqura.properties
java.base_CLEAN += intrinsic.properties
@ -70,7 +70,7 @@ endif
################################################################################
java.compiler_ADD_JAVAC_FLAGS += -Xdoclint:all/protected '-Xdoclint/package:java.*,javax.*'
java.compiler_ADD_JAVAC_FLAGS += -Xdoclint:all/protected,-accessibility '-Xdoclint/package:java.*,javax.*'
################################################################################
@ -79,7 +79,7 @@ java.datatransfer_COPY += flavormap.properties
################################################################################
java.desktop_ADD_JAVAC_FLAGS += -Xdoclint:all/protected,-reference \
java.desktop_ADD_JAVAC_FLAGS += -Xdoclint:all/protected,-reference,-accessibility \
'-Xdoclint/package:java.*,javax.*' -Xlint:exports \
--doclint-format html4
java.desktop_COPY += .gif .png .wav .txt .xml .css .pf
@ -220,15 +220,15 @@ java.scripting_CLEAN += .properties
################################################################################
java.instrument_ADD_JAVAC_FLAGS += -Xdoclint:all/protected '-Xdoclint/package:java.*,javax.*'
java.instrument_ADD_JAVAC_FLAGS += -Xdoclint:all/protected,-accessibility '-Xdoclint/package:java.*,javax.*'
################################################################################
java.logging_ADD_JAVAC_FLAGS += -Xdoclint:all/protected,-reference '-Xdoclint/package:java.*,javax.*'
java.logging_ADD_JAVAC_FLAGS += -Xdoclint:all/protected,-reference,-accessibility '-Xdoclint/package:java.*,javax.*'
################################################################################
java.management_ADD_JAVAC_FLAGS += -Xdoclint:all/protected,-reference '-Xdoclint/package:java.*,javax.*'
java.management_ADD_JAVAC_FLAGS += -Xdoclint:all/protected,-reference,-accessibility '-Xdoclint/package:java.*,javax.*'
################################################################################
@ -249,7 +249,7 @@ java.sql_SETUP := GENERATE_JDKBYTECODE_NOWARNINGS
################################################################################
java.sql.rowset_ADD_JAVAC_FLAGS += -Xdoclint:all/protected '-Xdoclint/package:java.*,javax.*'
java.sql.rowset_ADD_JAVAC_FLAGS += -Xdoclint:all/protected,-accessibility '-Xdoclint/package:java.*,javax.*'
java.sql.rowset_CLEAN_FILES += $(wildcard \
$(TOPDIR)/src/java.sql.rowset/share/classes/com/sun/rowset/*.properties \
$(TOPDIR)/src/java.sql.rowset/share/classes/javax/sql/rowset/*.properties)
@ -263,14 +263,14 @@ java.rmi_CLEAN_FILES += $(wildcard \
################################################################################
java.xml_ADD_JAVAC_FLAGS += -Xdoclint:all/protected \
java.xml_ADD_JAVAC_FLAGS += -Xdoclint:all/protected,-accessibility \
'-Xdoclint/package:$(call CommaList, javax.xml.catalog javax.xml.datatype \
javax.xml.transform javax.xml.validation javax.xml.xpath)'
java.xml_CLEAN += .properties
################################################################################
java.naming_ADD_JAVAC_FLAGS += -Xdoclint:all/protected '-Xdoclint/package:java.*,javax.*' -Xlint:-exports
java.naming_ADD_JAVAC_FLAGS += -Xdoclint:all/protected,-accessibility '-Xdoclint/package:java.*,javax.*' -Xlint:-exports
java.naming_CLEAN += jndiprovider.properties
################################################################################
@ -279,7 +279,7 @@ java.security.jgss_ADD_JAVAC_FLAGS += -Xdoclint:all/protected '-Xdoclint/package
################################################################################
java.smartcardio_ADD_JAVAC_FLAGS += -Xdoclint:all/protected '-Xdoclint/package:java.*,javax.*'
java.smartcardio_ADD_JAVAC_FLAGS += -Xdoclint:all/protected,-accessibility '-Xdoclint/package:java.*,javax.*'
################################################################################

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2019, 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
@ -61,7 +61,6 @@ import com.sun.source.doctree.ErroneousTree;
import com.sun.source.doctree.IdentifierTree;
import com.sun.source.doctree.IndexTree;
import com.sun.source.doctree.InheritDocTree;
import com.sun.source.doctree.InlineTagTree;
import com.sun.source.doctree.LinkTree;
import com.sun.source.doctree.LiteralTree;
import com.sun.source.doctree.ParamTree;
@ -140,16 +139,15 @@ public class Checker extends DocTreePathScanner<Void, Void> {
}
private final Deque<TagStackItem> tagStack; // TODO: maybe want to record starting tree as well
private HtmlTag currHeaderTag;
private HtmlTag currHeadingTag;
private final int implicitHeaderLevel;
private int implicitHeadingRank;
// <editor-fold defaultstate="collapsed" desc="Top level">
Checker(Env env) {
this.env = Assert.checkNonNull(env);
tagStack = new LinkedList<>();
implicitHeaderLevel = env.implicitHeaderLevel;
}
public Void scan(DocCommentTree tree, TreePath p) {
@ -188,7 +186,7 @@ public class Checker extends DocTreePathScanner<Void, Void> {
}
tagStack.clear();
currHeaderTag = null;
currHeadingTag = null;
foundParams.clear();
foundThrows.clear();
@ -196,6 +194,37 @@ public class Checker extends DocTreePathScanner<Void, Void> {
foundReturn = false;
hasNonWhitespaceText = false;
switch (p.getLeaf().getKind()) {
// the following are for declarations that have their own top-level page,
// and so the doc comment comes after the <h1> page title.
case MODULE:
case PACKAGE:
case CLASS:
case INTERFACE:
case ENUM:
case ANNOTATION_TYPE:
implicitHeadingRank = 1;
break;
// this is for html files
// ... if it is a legacy package.html, the doc comment comes after the <h1> page title
// ... otherwise, (e.g. overview file and doc-files/*.html files) no additional headings are inserted
case COMPILATION_UNIT:
implicitHeadingRank = fo.isNameCompatible("package", JavaFileObject.Kind.HTML) ? 1 : 0;
break;
// the following are for member declarations, which appear in the page
// for the enclosing type, and so appear after the <h2> "Members"
// aggregate heading and the specific <h3> "Member signature" heading.
case METHOD:
case VARIABLE:
implicitHeadingRank = 3;
break;
default:
Assert.error("unexpected tree kind: " + p.getLeaf().getKind() + " " + fo);
}
scan(new DocTreePath(p, tree), null);
if (!isOverridingMethod) {
@ -328,9 +357,9 @@ public class Checker extends DocTreePathScanner<Void, Void> {
// tag specific checks
switch (t) {
// check for out of sequence headers, such as <h1>...</h1> <h3>...</h3>
// check for out of sequence headings, such as <h1>...</h1> <h3>...</h3>
case H1: case H2: case H3: case H4: case H5: case H6:
checkHeader(tree, t);
checkHeading(tree, t);
break;
}
@ -446,23 +475,27 @@ public class Checker extends DocTreePathScanner<Void, Void> {
env.messages.error(HTML, tree, "dc.tag.not.allowed.here", treeName);
}
private void checkHeader(StartElementTree tree, HtmlTag tag) {
private void checkHeading(StartElementTree tree, HtmlTag tag) {
// verify the new tag
if (getHeaderLevel(tag) > getHeaderLevel(currHeaderTag) + 1) {
if (currHeaderTag == null) {
env.messages.error(ACCESSIBILITY, tree, "dc.tag.header.sequence.1", tag);
if (getHeadingRank(tag) > getHeadingRank(currHeadingTag) + 1) {
if (currHeadingTag == null) {
env.messages.error(ACCESSIBILITY, tree, "dc.tag.heading.sequence.1",
tag, implicitHeadingRank);
} else {
env.messages.error(ACCESSIBILITY, tree, "dc.tag.header.sequence.2",
tag, currHeaderTag);
env.messages.error(ACCESSIBILITY, tree, "dc.tag.heading.sequence.2",
tag, currHeadingTag);
}
} else if (getHeadingRank(tag) <= implicitHeadingRank) {
env.messages.error(ACCESSIBILITY, tree, "dc.tag.heading.sequence.3",
tag, implicitHeadingRank);
}
currHeaderTag = tag;
currHeadingTag = tag;
}
private int getHeaderLevel(HtmlTag tag) {
private int getHeadingRank(HtmlTag tag) {
if (tag == null)
return implicitHeaderLevel;
return implicitHeadingRank;
switch (tag) {
case H1: return 1;
case H2: return 2;
@ -666,11 +699,11 @@ public class Checker extends DocTreePathScanner<Void, Void> {
break;
case OBSOLETE:
env.messages.warning(ACCESSIBILITY, tree, "dc.attr.obsolete", name);
env.messages.warning(HTML, tree, "dc.attr.obsolete", name);
break;
case USE_CSS:
env.messages.warning(ACCESSIBILITY, tree, "dc.attr.obsolete.use.css", name);
env.messages.warning(HTML, tree, "dc.attr.obsolete.use.css", name);
break;
case HTML5:

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2019, 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
@ -80,7 +80,6 @@ public class DocLint implements Plugin {
public static final String XMSGS_OPTION = "-Xmsgs";
public static final String XMSGS_CUSTOM_PREFIX = "-Xmsgs:";
private static final String STATS = "-stats";
public static final String XIMPLICIT_HEADERS = "-XimplicitHeaders:";
public static final String XCUSTOM_TAGS_PREFIX = "-XcustomTags:";
public static final String XHTML_VERSION_PREFIX = "-XhtmlVersion:";
public static final String XCHECK_PACKAGE = "-XcheckPackage:";
@ -289,9 +288,6 @@ public class DocLint implements Plugin {
env.messages.setOptions(null);
} else if (arg.startsWith(XMSGS_CUSTOM_PREFIX)) {
env.messages.setOptions(arg.substring(arg.indexOf(":") + 1));
} else if (arg.matches(XIMPLICIT_HEADERS + "[1-6]")) {
char ch = arg.charAt(arg.length() - 1);
env.setImplicitHeaders(Character.digit(ch, 10));
} else if (arg.startsWith(XCUSTOM_TAGS_PREFIX)) {
env.setCustomTags(arg.substring(arg.indexOf(":") + 1));
} else if (arg.startsWith(XHTML_VERSION_PREFIX)) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2019, 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
@ -93,8 +93,6 @@ public class Env {
/** Message handler. */
final Messages messages;
int implicitHeaderLevel = 0;
Set<String> customTags;
Set<Pattern> includePackages;
@ -153,10 +151,6 @@ public class Env {
java_lang_Void = elements.getTypeElement("java.lang.Void").asType();
}
void setImplicitHeaders(int n) {
implicitHeaderLevel = n;
}
void setCustomTags(String cTags) {
customTags = new LinkedHashSet<>();
for (String s : cTags.split(DocLint.SEPARATOR)) {

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2012, 2019, 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
@ -63,8 +63,9 @@ dc.tag.empty = empty <{0}> tag
dc.tag.a.within.a = {0} tag, which expands to <a>, within <a>
dc.tag.end.not.permitted = invalid end tag: </{0}>
dc.tag.end.unexpected = unexpected end tag: </{0}>
dc.tag.header.sequence.1 = header used out of sequence: <{0}>
dc.tag.header.sequence.2 = header used out of sequence: <{0}>
dc.tag.heading.sequence.1 = heading used out of sequence: <{0}>, compared to implicit preceding heading: <H{1}>
dc.tag.heading.sequence.2 = heading used out of sequence: <{0}>, compared to previous heading: <{1}>
dc.tag.heading.sequence.3 = unexpected heading used: <{0}>, compared to implicit preceding heading: <H{1}>
dc.tag.nested.not.allowed=nested tag not allowed: <{0}>
dc.tag.not.allowed.here = tag not allowed here: <{0}>
dc.tag.not.allowed = element not allowed in documentation comments: <{0}>

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2019, 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
@ -852,9 +852,6 @@ public class Arguments {
doclintOpts.add(DocLint.XHTML_VERSION_PREFIX + format);
}
// standard doclet normally generates H1, H2,
// so for now, allow user comments to assume that
doclintOpts.add(DocLint.XIMPLICIT_HEADERS + "2");
return List.from(doclintOpts.toArray(new String[doclintOpts.size()]));
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, 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
@ -141,8 +141,6 @@ public class WorkArounds {
JavacTask t = BasicJavacTask.instance(toolEnv.context);
doclint = new DocLint();
// standard doclet normally generates H1, H2
doclintOpts.add(DocLint.XIMPLICIT_HEADERS + "2");
doclint.init(t, doclintOpts.toArray(new String[doclintOpts.size()]), false);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2019, 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
@ -24,19 +24,23 @@
/*
* @test
* @bug 8006346
* @summary doclint should make allowance for headers generated by standard doclet
* @summary doclint should make allowance for headings generated by standard doclet
* @modules jdk.javadoc/jdk.javadoc.internal.tool
*/
import java.io.File;
/**
* <h3> Header </h3>
* <h2> Class heading </h2>
*/
public class ImplicitHeadingsTest {
/**
* <h4>Method heading</h4>
* @param args command-line args
*/
public class ImplicitHeadersTest {
public static void main(String... args) {
File testSrc = new File(System.getProperty("test.src"));
File testFile = new File(testSrc, ImplicitHeadersTest.class.getSimpleName() + ".java");
File testFile = new File(testSrc, ImplicitHeadingsTest.class.getSimpleName() + ".java");
String[] javadocArgs = { "-d", "out", testFile.getPath() };
int rc = jdk.javadoc.internal.tool.Main.execute(javadocArgs);
if (rc != 0)

View File

@ -10,17 +10,37 @@
/** */
public class AccessibilityTest {
/**
* <h1> ... </h1>
*/
public class Bad_H1 { }
/**
* <h3> ... </h3>
*/
public class Missing_H2 { }
/**
* <h2> ... </h2>
* <h4> ... </h4>
*/
public class Missing_H3 { }
/**
* <h2> ... </h2>
*/
public void missing_h1() { }
public void bad_h2() { }
/**
* <h1> ... </h1>
* <h3> ... </h3>
* <h4> ... </h4>
*/
public void missing_h2() { }
public void missing_h3() { }
/**
* <h3> ... </h3>
* <h5> ... </h5>
*/
public void missing_h4() { }
/**
* <img src="x.jpg">

View File

@ -1,13 +1,25 @@
AccessibilityTest.java:15: error: header used out of sequence: <H2>
* <h2> ... </h2>
AccessibilityTest.java:14: error: unexpected heading used: <H1>, compared to implicit preceding heading: <H1>
* <h1> ... </h1>
^
AccessibilityTest.java:21: error: header used out of sequence: <H3>
AccessibilityTest.java:19: error: heading used out of sequence: <H3>, compared to implicit preceding heading: <H1>
* <h3> ... </h3>
^
AccessibilityTest.java:26: error: no "alt" attribute for image
AccessibilityTest.java:25: error: heading used out of sequence: <H4>, compared to previous heading: <H2>
* <h4> ... </h4>
^
AccessibilityTest.java:30: error: unexpected heading used: <H2>, compared to implicit preceding heading: <H3>
* <h2> ... </h2>
^
AccessibilityTest.java:40: error: unexpected heading used: <H3>, compared to implicit preceding heading: <H3>
* <h3> ... </h3>
^
AccessibilityTest.java:41: error: heading used out of sequence: <H5>, compared to previous heading: <H3>
* <h5> ... </h5>
^
AccessibilityTest.java:46: error: no "alt" attribute for image
* <img src="x.jpg">
^
AccessibilityTest.java:41: error: no summary or caption for table
AccessibilityTest.java:61: error: no summary or caption for table
* <table><tr><th>head<tr><td>data</table>
^
4 errors
8 errors

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2019, 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
@ -28,7 +28,7 @@
* @library ..
* @modules jdk.compiler/com.sun.tools.doclint
* @build DocLintTester
* @run main DocLintTester -Xmsgs BlockTagsTest.java
* @run main DocLintTester -Xmsgs:-accessibility BlockTagsTest.java
*/
/** */

View File

@ -83,7 +83,7 @@ public class HtmlVersionTagsAttrsTest {
* </ol>
* <img src="testImg.jpg" alt="imgTest" crossorigin="anonymous">
* <div aria-labelledby="Topics" aria-describedby="t1">
* <h1 id="Topics">Topics</h1>
* <h4 id="Topics">Topics</h4>
* <p id="t1">Aria attribute test</p>
* <p id="t2" aria-label="Label">Label test</p>
* </div>
@ -98,8 +98,8 @@ public class HtmlVersionTagsAttrsTest {
* <p><tt>Teletype text</tt></p>
* <section>
* <hgroup>
* <h1>Section</h1>
* <h2> Another heading</h2>
* <h4>Section</h4>
* <h5> Another heading</h5>
* </hgroup>
* hgroup no longer supported in HTML5.
* </section>
@ -113,12 +113,12 @@ public class HtmlVersionTagsAttrsTest {
/**
* <section>
* <p>Testing section tag</p>
* <h1>Section</h1>
* <h4>Section</h4>
* Section text.
* </section>
* <article>
* <p>Testing article tag</p>
* <h1>Article</h1>
* <h5>Article</h5>
* Article text.
* </article>
* <header>
@ -133,7 +133,7 @@ public class HtmlVersionTagsAttrsTest {
* Main content
* </main>
* <aside>
* <h2>Test aside</h2>
* <h4>Test aside</h4>
* <p>Description</p>
* </aside>
* <ul>

View File

@ -13,6 +13,6 @@
/**
* <a name="here">valid</a>
* <a name="here">duplicate</a>
* <h1 id="here">duplicate</h1>
* <h2 id="here">duplicate</h2>
*/
public class AnchorAlreadyDefined { }

View File

@ -2,6 +2,6 @@ AnchorAlreadyDefined.java:15: error: anchor already defined: "here"
* <a name="here">duplicate</a>
^
AnchorAlreadyDefined.java:16: error: anchor already defined: "here"
* <h1 id="here">duplicate</h1>
* <h2 id="here">duplicate</h2>
^
2 errors

View File

@ -13,6 +13,6 @@
/**
* </p>
* <h1> <b> text </h1>
* <h2> <b> text </h2>
*/
public class MissingTag { }

View File

@ -2,6 +2,6 @@ MissingTag.java:15: error: unexpected end tag: </p>
* </p>
^
MissingTag.java:16: error: end tag missing: </b>
* <h1> <b> text </h1>
* <h2> <b> text </h2>
^
2 errors

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2019, 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
@ -24,12 +24,17 @@
/*
* @test
* @bug 8006346
* @summary doclint should make allowance for headers generated by standard doclet
* @compile -Xdoclint:all/public ImplicitHeadersTest.java
* @summary doclint should make allowance for headings generated by standard doclet
* @compile -Xdoclint:all/public ImplicitHeadingsTest.java
*/
/**
* <h3> Header </h3>
* <h2> Class heading </h2>
*/
public class ImplicitHeadersTest { }
public class ImplicitHeadingsTest {
/**
* <h4>Method heading</h4>
*/
public void m() { }
}