| <?xml version="1.0" encoding="UTF-8"?> |
| |
| <document xmlns="http://maven.apache.org/XDOC/2.0" |
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd"> |
| |
| <head> |
| <title>Writing Javadoc Checks</title> |
| <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"/> |
| <script type="text/javascript" src="js/anchors.js"/> |
| <script type="text/javascript" src="js/google-analytics.js"/> |
| <link rel="icon" href="images/favicon.png" type="image/x-icon" /> |
| <link rel="shortcut icon" href="images/favicon.ico" type="image/ico" /> |
| </head> |
| |
| <body> |
| <section name="Content"> |
| <macro name="toc"> |
| <param name="fromDepth" value="1"/> |
| <param name="toDepth" value="1"/> |
| </macro> |
| </section> |
| |
| <section name="What is Javadoc comment"> |
| <p> |
| Javadoc comment is multiline comment <code>/* */</code> that starts with <b>*</b> character and placed above class definition, interface definition, enum definition, method definition or field definition. |
| <p>For example, here is java file:</p> |
| <source><![CDATA[ |
| /** |
| * My <b>class</b>. |
| * @see AbstractClass |
| */ |
| public class MyClass { |
| |
| } |
| ]]></source> |
| Javadoc content is: |
| <source><![CDATA[ |
| * My <b>class</b>. |
| * @see AbstractClass |
| ]]></source> |
| </p> |
| Attention that java comment starts with <code>/*</code>, following with Identificator of comment type. Javadoc Identificator is <code>*</code>. All symbols after Javadoc Identificator till <code>*/</code> are part of javadoc comment. |
| <p>Please not that javadoc-like comment inside a method is not a javadoc comment and skipped by |
| Sun/Oracle javadoc tool and by our parser. |
| </p> |
| <p>In internet you can find different types of documentation |
| generation tools similar to javadoc. Such tools rely on specific Identificator: "!", "#", "$". |
| Comments looks like <code>"/*! some comment */"</code> , <code>"/*# some comment */"</code> , <code>"/*$ some comment */"</code>. Such multiline comments are not a javadoc. |
| </p> |
| </section> |
| |
| <section name="Limitations"> |
| <p> |
| Javadoc by specification could contain any HTML tags that let user generate content he needs. |
| All tags are copied as is to result javadoc html pages by Sun/Oracle javadoc tool. |
| All bad formatting is responsibility of user and web-browser. To validate Checkstyle to parse |
| input to predictable structure - Abstract Syntax Tree(AST). It is very difficult to parse free style |
| format, so input text need to follow some format, so limitation appears. |
| </p> |
| <p> |
| The comment should be written in <a href="#Tight-HTML_rules">Tight-HTML</a> to build nested AST Tree that most Checks expect. |
| </p> |
| <p> |
| For more details about parsing of HTML into AST read <a href="#HTML_Code_In_Javadoc_Comments">HTML Code In Javadoc Comments</a> and <a href="#Javadoc_parser_behavior_for_current_HTML_version_and_new_HTML_version">Javadoc parser behavior |
| </a> section. |
| </p> |
| </section> |
| |
| <section name="Tight-HTML rules"> |
| <p> |
| Every HTML tag should have matching end HTML tag or it is a <a href="https://www.w3.org/TR/html/syntax.html#void-elements">void element</a>. |
| </p> |
| <p> |
| The only exceptions are HTML 4 tags whose end tag is optional (omittable) by HTML specification (example is <a href="https://www.w3.org/TR/html5/tabular-data.html#the-tr-element">TR</a>), so, Checkstyle won't show error about missing end tag, however, it leads to broken Tight-HTML structure and as a result |
| leads to not-nested content of the HTML tags in Abstract Syntax Tree of the Javadoc comment. |
| <br/> |
| In other words, if HTML tags are not closed Javadoc grammar cannot determine content of these tags, |
| so structure of the parse tree will not be nested like it is while using <a href="#Tight-HTML_rules">Tight-HTML</a> code. |
| It is done just to not fail on every Javadoc comment, because there are tons of using unclosed tags, etc. |
| </p> |
| Other rules: |
| <ul> |
| <li>Document Structure elements (DOCTYPE, <html>, <body>, etc) are not mandatory.</li> |
| <li>Elements must always be closed, except HTML4 elements whose end tag is optional (omittable) and HTML4 <a href="https://www.w3.org/TR/html/syntax.html#void-elements">void elements</a>. See <a href="#HTML_Code_In_Javadoc_Comments">HTML Code In Javadoc Comments</a> section</li> |
| <li>HTML elements can be either in lowercase or in uppercase</li> |
| <li>Attribute names can be either in lowercase or in uppercase</li> |
| <li>Attribute values can be either quoted or not be quoted</li> |
| </ul> |
| </section> |
| |
| <section name="How to create Javadoc Check"> |
| <p> |
| Principle of writing Javadoc Checks is similar to writing regular Checks. You just extend another abstract class and use another token types. |
| </p> |
| <p> |
| To start implementing new Check create a new class and extend <a href='apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html'>AbstractJavadocCheck</a>. |
| It has two abstract methods you should implement: |
| </p> |
| <ul> |
| <li> |
| <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#getDefaultJavadocTokens--">getDefaultJavadocTokens()</a> - return int array of |
| javadoc token types your Check is going to process. The array should contain int constants from <a href="apidocs/com/puppycrawl/tools/checkstyle/api/JavadocTokenTypes.html"> |
| JavadocTokenTypes</a> class. (There is also <a href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html">TokenTypes</a> class in Checkstyle. Make sure you use |
| <a href="apidocs/com/puppycrawl/tools/checkstyle/api/JavadocTokenTypes.html">JavadocTokenTypes</a> class in your Check, because the |
| <a href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html">TokenTypes</a> is used to describe standard Java |
| <a href="apidocs/com/puppycrawl/tools/checkstyle/api/DetailAST.html">DetailAST</a> token type.) |
| </li> |
| <li> |
| <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#visitJavadocToken-com.puppycrawl.tools.checkstyle.api.DetailNode-"> |
| visitJavadocToken(DetailNode)</a> - it's a place you should put tree nodes processing. The argument is Javadoc tree node of type you described before in |
| <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#getDefaultJavadocTokens--">getDefaultJavadocTokens()</a> method. |
| </li> |
| </ul> |
| </section> |
| |
| <section name="Difference between Java Grammar and Javadoc comments Grammar"> |
| <p> |
| Java grammar parses java file base on Java language specifications. So, there are singleline comments and multiline/block comments in it. |
| Java compiler doesn't know about Javadoc because it is just a multiline comment. |
| To parse multiline comment as a Javadoc comment, checkstyle has special Parser |
| that is based on ANTLR Javadoc grammar. So, it's supposed to process block comments |
| that start with Javadoc Identificator and parse them to Abstract Syntax Tree (AST). |
| </p> |
| <p> |
| The difference is that Java grammar uses ANTLR v2, while Javadoc grammar uses ANTLR v4. Because of that, these two grammars and their trees are not compatible. |
| Java AST consists of <a href="apidocs/com/puppycrawl/tools/checkstyle/api/DetailAST.html">DetailAST</a> objects, while Javadoc AST consists of <a href="apidocs/com/puppycrawl/tools/checkstyle/api/DetailNode.html">DetailNode</a> objects. |
| </p> |
| <p> |
| Main Java grammar skips any whitespaces and newlines, so in Java Abstract Syntax Tree there are no whitespace/newline nodes. |
| In Javadoc comment every whitespace matters, and Javadoc Checks need all those whitespaces and newline nodes to verify format and content of the Javadoc comment. |
| Because of that Javadoc grammar includes all whitespaces, newlines to the parse tree |
| (<a href="apidocs/com/puppycrawl/tools/checkstyle/api/JavadocTokenTypes.html#WS">WS</a>, <a href="apidocs/com/puppycrawl/tools/checkstyle/api/JavadocTokenTypes.html#NEWLINE">NEWLINE</a>). |
| </p> |
| </section> |
| |
| <section name="Tool to print Javadoc tree structure"> |
| <p> |
| Checkstyle can print Abstract Syntax Tree for Java and Javadoc trees. You need to run checkstyle jar file with <b>-J</b> argument, providing java file. |
| </p> |
| <p>For example, here is MyClass.java file:</p> |
| <source><![CDATA[ |
| /** |
| * My <b>class</b>. |
| * @see AbstractClass |
| */ |
| public class MyClass { |
| |
| } |
| ]]></source> |
| <p>Command:</p> |
| <source class="wrap-content">java -jar checkstyle-X.XX-all.jar -J MyClass.java</source> |
| <p>Output:</p> |
| <source><![CDATA[ |
| CLASS_DEF -> CLASS_DEF [5:0] |
| |--MODIFIERS -> MODIFIERS [5:0] |
| | |--BLOCK_COMMENT_BEGIN -> /* [1:0] |
| | | |--COMMENT_CONTENT -> *\n * My <b>class</b>.\n * @see AbstractClass\n [1:2] |
| | | | `--JAVADOC -> JAVADOC [1:3] |
| | | | |--NEWLINE -> \n [1:3] |
| | | | |--LEADING_ASTERISK -> * [2:0] |
| | | | |--TEXT -> My [2:2] |
| | | | |--HTML_ELEMENT -> HTML_ELEMENT [2:6] |
| | | | | `--HTML_TAG -> HTML_TAG [2:6] |
| | | | | |--HTML_ELEMENT_START -> HTML_ELEMENT_START [2:6] |
| | | | | | |--START -> < [2:6] |
| | | | | | |--HTML_TAG_NAME -> b [2:7] |
| | | | | | `--END -> > [2:8] |
| | | | | |--TEXT -> class [2:9] |
| | | | | `--HTML_ELEMENT_END -> HTML_ELEMENT_END [2:14] |
| | | | | |--START -> < [2:14] |
| | | | | |--SLASH -> / [2:15] |
| | | | | |--HTML_TAG_NAME -> b [2:16] |
| | | | | `--END -> > [2:17] |
| | | | |--TEXT -> . [2:18] |
| | | | |--NEWLINE -> \n [2:19] |
| | | | |--LEADING_ASTERISK -> * [3:0] |
| | | | |--WS -> [3:2] |
| | | | |--JAVADOC_TAG -> JAVADOC_TAG [3:3] |
| | | | | |--SEE_LITERAL -> @see [3:3] |
| | | | | |--WS -> [3:7] |
| | | | | |--REFERENCE -> REFERENCE [3:8] |
| | | | | | `--CLASS -> AbstractClass [3:8] |
| | | | | |--NEWLINE -> \n [3:21] |
| | | | | `--WS -> [4:0] |
| | | | `--EOF -> <EOF> [4:1] |
| | | `--BLOCK_COMMENT_END -> */ [4:1] |
| | `--LITERAL_PUBLIC -> public [5:0] |
| |--LITERAL_CLASS -> class [5:7] |
| |--IDENT -> MyClass [5:13] |
| `--OBJBLOCK -> OBJBLOCK [5:21] |
| |--LCURLY -> { [5:21] |
| `--RCURLY -> } [7:0] |
| ]]></source> |
| <p> |
| As you see very small java file transforms to a huge Abstract Syntax Tree, because that is the most detailed tree including all components of the java file: classes, methods, comments, etc. |
| </p> |
| <p>In most cases while developing Javadoc Check, you need to only parse the tree of the exact Javadoc comment. |
| To do that just copy Javadoc comment to separate file and remove <b>/**</b> at the beginning and <b>*/</b> at the end. After that, run checkstyle with <b>-j</b> argument. |
| </p> |
| <p>MyJavadocComment.javadoc file:</p> |
| <source><![CDATA[ |
| * My <b>class</b>. |
| * @see AbstractClass |
| ]]></source> |
| <p>Command:</p> |
| <source class="wrap-content">java -jar checkstyle-X.XX-all.jar -j MyJavadocComment.javadoc</source> |
| <p>Output:</p> |
| <source><![CDATA[ |
| JAVADOC -> JAVADOC [0:0] |
| |--LEADING_ASTERISK -> * [0:0] |
| |--TEXT -> My [0:2] |
| |--HTML_ELEMENT -> HTML_ELEMENT [0:6] |
| | `--HTML_TAG -> HTML_TAG [0:6] |
| | |--HTML_ELEMENT_START -> HTML_ELEMENT_START [0:6] |
| | | |--START -> < [0:6] |
| | | |--HTML_TAG_NAME -> b [0:7] |
| | | `--END -> > [0:8] |
| | |--TEXT -> class [0:9] |
| | `--HTML_ELEMENT_END -> HTML_ELEMENT_END [0:14] |
| | |--START -> < [0:14] |
| | |--SLASH -> / [0:15] |
| | |--HTML_TAG_NAME -> b [0:16] |
| | `--END -> > [0:17] |
| |--TEXT -> . [0:18] |
| |--NEWLINE -> \n [0:19] |
| |--LEADING_ASTERISK -> * [1:0] |
| |--WS -> [1:2] |
| |--JAVADOC_TAG -> JAVADOC_TAG [1:3] |
| | |--SEE_LITERAL -> @see [1:3] |
| | |--WS -> [1:7] |
| | `--REFERENCE -> REFERENCE [1:8] |
| | `--CLASS -> AbstractClass [1:8] |
| `--EOF -> <EOF> [1:21] |
| ]]></source> |
| </section> |
| |
| <section name="Access Java AST from Javadoc Check"> |
| As you already know Javadoc parse tree is a result of parsing block comment. There is a method to get the original block comment from Javadoc Check. |
| You may need this block comment to check its position or something else in java <a href="apidocs/com/puppycrawl/tools/checkstyle/api/DetailAST.html">DetailAST</a> tree. |
| <p> |
| For example, to write a JavadocCheck that verifies @param tags in Javadoc comment of a method definition, you also need all method's parameter names. To get method definition AST you should access java <a href="apidocs/com/puppycrawl/tools/checkstyle/api/DetailAST.html">DetailAST</a> tree from javadoc Check. For this purpose use <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#getBlockCommentAst--">getBlockCommentAst()</a> method that returns <a href="apidocs/com/puppycrawl/tools/checkstyle/api/DetailAST.html">DetailAST</a> node. |
| </p> |
| <p> |
| Example: |
| </p> |
| <source> |
| class MyCheck extends AbstractJavadocCheck { |
| |
| @Override |
| public int[] getDefaultJavadocTokens() { |
| return new int[]{JavadocTokenTypes.PARAMETER_NAME}; |
| } |
| |
| @Override |
| public void visitJavadocToken(DetailNode paramNameNode) { |
| String javadocParamName = paramNameNode.getText(); |
| DetailAST blockCommentAst = getBlockCommentAst(); |
| |
| if (BlockCommentPosition.isOnMethod(blockCommentAst)) { |
| |
| DetailAST methodDef = blockCommentAst.getParent(); |
| DetailAST methodParam = findMethodParameter(methodDef); |
| String methodParamName = methodParam.getText(); |
| |
| if (!javadocParamName.equals(methodParamName)) { |
| log(methodParam, "params.dont.match"); |
| } |
| |
| } |
| } |
| } |
| </source> |
| </section> |
| |
| <section name="HTML Code In Javadoc Comments"> |
| <p> |
| Checkstyle supports HTML4 tags in Javadoc comments: <a href="https://www.w3.org/TR/html4/index/elements.html">all HTML4 elements</a>. |
| </p> |
| <p> |
| HTML4 is picked just to have a list of elements whose end tag is optional(omittable) and a list of <a href="https://www.w3.org/TR/html/syntax.html#void-elements">void elements</a> (also known as <a href="https://www.w3schools.com/html/html_elements.asp">empty html tags</a>, for example <a href="https://www.w3.org/TR/html4/struct/text.html#edef-BR">BR tag</a>). |
| </p> |
| <p> |
| HTML4 elements whose end tag is optional (omittable): <P>, <LI>, <TR>, <TD>, <TH>, <BODY>, <COLGROUP>, <DD>, |
| <DT>, <HEAD>, <HTML>, <OPTION>, <TBODY>, <THEAD>, <TFOOT>. |
| </p> |
| <p> |
| Void HTML4 elements: <AREA>, <BASE>, <BASEFONT>, <BR>, <COL>, <FRAME>, |
| <HR>, <IMG>, <INPUT>, <ISINDEX>, <LINK>, <META>, <PARAM>. |
| </p> |
| |
| <p> |
| To make Checkstyle support HTML5 tags whose end tag is optional (omittable) and HTML5 void elements we should update Javadoc Parser |
| because each element that breaks <a href="#Tight-HTML_rules">Tight-HTML rules</a> have to be defined in Javadoc grammar. |
| In future we should update Javadoc grammar if those tag lists extend (new tags, new HTML standard, etc.). |
| (We already have an <a href='https://github.com/checkstyle/checkstyle/issues/3332'>issue on updating Javadoc grammar to HTML5</a>) |
| </p> |
| |
| <p> |
| If Checkstyle meets unknown tag (for example HTML5 tag) |
| it doesn't fail and parses this tag as <a href="apidocs/com/puppycrawl/tools/checkstyle/api/JavadocTokenTypes.html#HTML_TAG">HTML_TAG</a> Javadoc token type. |
| Just follow <a href="#Tight-HTML_rules">Tight-HTML rules</a> to make Checkstyle javadoc parser make nested AST, even though tags are unknown. |
| |
| <source><![CDATA[ |
| <audio><source src="horse.ogg" type="audio/ogg"/></audio> |
| ]]></source> |
| |
| <source><![CDATA[ |
| JAVADOC -> JAVADOC [0:0] |
| |--HTML_ELEMENT -> HTML_ELEMENT [0:0] |
| | `--HTML_TAG -> HTML_TAG [0:0] |
| | |--HTML_ELEMENT_START -> HTML_ELEMENT_START [0:0] |
| | | |--START -> < [0:0] |
| | | |--HTML_TAG_NAME -> audio [0:1] |
| | | `--END -> > [0:6] |
| | |--HTML_ELEMENT -> HTML_ELEMENT [0:7] |
| | | `--SINGLETON_ELEMENT -> SINGLETON_ELEMENT [0:7] |
| | | `--EMPTY_TAG -> EMPTY_TAG [0:7] |
| | | |--START -> < [0:7] |
| | | |--HTML_TAG_NAME -> source [0:8] |
| | | |--WS -> [0:14] |
| | | |--ATTRIBUTE -> ATTRIBUTE [0:15] |
| | | | |--HTML_TAG_NAME -> src [0:15] |
| | | | |--EQUALS -> = [0:18] |
| | | | `--ATTR_VALUE -> "horse.ogg" [0:19] |
| | | |--WS -> [0:31] |
| | | |--ATTRIBUTE -> ATTRIBUTE [0:32] |
| | | | |--HTML_TAG_NAME -> type [0:32] |
| | | | |--EQUALS -> = [0:36] |
| | | | `--ATTR_VALUE -> "audio/ogg" [0:37] |
| | | `--SLASH_END -> /> [0:49] |
| | `--HTML_ELEMENT_END -> HTML_ELEMENT_END [0:51] |
| | |--START -> < [0:51] |
| | |--SLASH -> / [0:52] |
| | |--HTML_TAG_NAME -> audio [0:53] |
| | `--END -> > [0:58] |
| `--EOF -> <EOF> [0:59] |
| ]]></source> |
| </p> |
| |
| <p> |
| Here is what you get if unknown tag doesn't have matching end tag (for example, HTML5 tag <audio>): <br/> |
| Input: |
| <source><audio>test</source> |
| Output: |
| <source class="wrap-content">[ERROR:0] Javadoc comment at column 1 has parse error. Missed HTML close tag 'audio'. Sometimes it means that close tag missed for one of previous tags.</source> |
| As you see Javadoc parser prints error and doesn't build AST if unknown HTML tag doesn't have matching end tag. If that a case please create an issue against Checkstyle to upgrade parser. |
| </p> |
| |
| <p> |
| There are also HTML tags that are marked as "Not supported in HTML5" (<a href='https://www.w3schools.com/tags/default.asp'>HTML Element Reference</a>). |
| Checkstyle Javadoc parser can parse those tags too if they are written in <a href="#Tight-HTML_rules">Tight-HTML</a>. |
| <br/> |
| Example. |
| <br/> |
| Input: |
| <source><![CDATA[ |
| <acronym title="as soon as possible">ASAP</acronym> |
| ]]></source> |
| <br/> |
| Output: |
| <source><![CDATA[ |
| JAVADOC -> JAVADOC [0:0] |
| |--HTML_ELEMENT -> HTML_ELEMENT [0:0] |
| | `--HTML_TAG -> HTML_TAG [0:0] |
| | |--HTML_ELEMENT_START -> HTML_ELEMENT_START [0:0] |
| | | |--START -> < [0:0] |
| | | |--HTML_TAG_NAME -> acronym [0:1] |
| | | |--WS -> [0:8] |
| | | |--ATTRIBUTE -> ATTRIBUTE [0:9] |
| | | | |--HTML_TAG_NAME -> title [0:9] |
| | | | |--EQUALS -> = [0:14] |
| | | | `--ATTR_VALUE -> "as soon as possible" [0:15] |
| | | `--END -> > [0:37] |
| | |--TEXT -> ASAP [0:38] |
| | `--HTML_ELEMENT_END -> HTML_ELEMENT_END [0:42] |
| | |--START -> < [0:42] |
| | |--SLASH -> / [0:43] |
| | |--HTML_TAG_NAME -> acronym [0:44] |
| | `--END -> > [0:51] |
| `--EOF -> <EOF> [0:52] |
| ]]></source> |
| </p> |
| |
| <p>More examples:</p> |
| |
| <table style="table-layout: fixed;"> |
| <tr> |
| <td> |
| 1) Unclosed paragraph HTML tag. As you see in the tree, content of the paragraph tag is not nested to this tag. |
| That is because HTML tags are not closed by pair tag </p>, and Checkstyle requires <a href="#Tight-HTML_rules">Tight-HTML</a> code to predictably parse Javadoc comments. |
| </td> |
| <td> |
| 2) Here is correct version with open and closed HTML tags. |
| </td> |
| </tr> |
| |
| <tr> |
| <td> |
| <source><![CDATA[ |
| <p> First |
| <p> Second |
| ]]></source> |
| </td> |
| <td> |
| <source><![CDATA[ |
| <p> First </p> |
| <p> Second </p> |
| ]]></source> |
| </td> |
| </tr> |
| |
| <tr> |
| <td> |
| <source><![CDATA[ |
| JAVADOC -> JAVADOC [0:0] |
| |--HTML_ELEMENT -> HTML_ELEMENT [0:0] |
| | `--P_TAG_START -> P_TAG_START [0:0] |
| | |--START -> < [0:0] |
| | |--P_HTML_TAG_NAME -> p [0:1] |
| | `--END -> > [0:2] |
| |--TEXT -> First [0:3] |
| |--NEWLINE -> \n [0:9] |
| |--HTML_ELEMENT -> HTML_ELEMENT [1:0] |
| | `--P_TAG_START -> P_TAG_START [1:0] |
| | |--START -> < [1:0] |
| | |--P_HTML_TAG_NAME -> p [1:1] |
| | `--END -> > [1:2] |
| |--TEXT -> Second [1:3] |
| `--EOF -> <EOF> [1:10] |
| ]]></source> |
| </td> |
| <td> |
| <source><![CDATA[ |
| JAVADOC -> JAVADOC [0:0] |
| |--HTML_ELEMENT -> HTML_ELEMENT [0:0] |
| | `--PARAGRAPH -> PARAGRAPH [0:0] |
| | |--P_TAG_START -> P_TAG_START [0:0] |
| | | |--START -> < [0:0] |
| | | |--P_HTML_TAG_NAME -> p [0:1] |
| | | `--END -> > [0:2] |
| | |--TEXT -> First [0:3] |
| | `--P_TAG_END -> P_TAG_END [0:10] |
| | |--START -> < [0:10] |
| | |--SLASH -> / [0:11] |
| | |--P_HTML_TAG_NAME -> p [0:12] |
| | `--END -> > [0:13] |
| |--NEWLINE -> \n [0:14] |
| |--HTML_ELEMENT -> HTML_ELEMENT [1:0] |
| | `--PARAGRAPH -> PARAGRAPH [1:0] |
| | |--P_TAG_START -> P_TAG_START [1:0] |
| | | |--START -> < [1:0] |
| | | |--P_HTML_TAG_NAME -> p [1:1] |
| | | `--END -> > [1:2] |
| | |--TEXT -> Second [1:3] |
| | `--P_TAG_END -> P_TAG_END [1:11] |
| | |--START -> < [1:11] |
| | |--SLASH -> / [1:12] |
| | |--P_HTML_TAG_NAME -> p [1:13] |
| | `--END -> > [1:14] |
| `--EOF -> <EOF> [1:15] |
| ]]></source> |
| </td> |
| </tr> |
| </table> |
| </section> |
| |
| <section name="Boolean flag indicating the presence of unclosed HTML tags"> |
| Not implemented yet, will be named "hasUnclosedTag". See <a href="https://github.com/checkstyle/checkstyle/issues/3311">Github Issue #3311</a>. |
| For expected behavior please read <a href="#Javadoc_parser_behavior_for_current_HTML_version_and_new_HTML_version">Javadoc parser behavior</a> section. |
| </section> |
| |
| <section name="Checkstyle SDK GUI"> |
| <p> |
| Checkstyle GUI allows to showing javadoc tree in java files. To run in use |
| </p> |
| <source class="wrap-content"> |
| java -cp checkstyle-${projectVersion}-all.jar com.puppycrawl.tools.checkstyle.gui.Main |
| </source> |
| <p> |
| and choose "JAVA WITH JAVADOC MODE" in dropdown list in bottom of frame. |
| </p> |
| <p> |
| Now you can see parsed javadoc tree as child of comment block. |
| </p> |
| <p> |
| <img alt="screenshot" src="images/gui_javadoc_screenshot.png"/> |
| </p> |
| <p> |
| Notice that only files with ".java" extension can be opened. |
| </p> |
| <p> |
| For detail reference you can see |
| <a href="http://checkstyle.sourceforge.net/writingchecks.html#The_Checkstyle_SDK_Gui">Checkstyle GUI documentation</a>. |
| </p> |
| </section> |
| |
| <section name="Customize token types in Javadoc Checks"> |
| <p> |
| Java checks controlled by method <a href="writingchecks.html#Understanding_token_sets">setTokens(), getDefaultTokens(), getAccessibleTokens(), getRequiredTokens(). </a> |
| JavaDoc checks use the same model plus extra 4 methods for Javadoc tokens. |
| As Java AST and Javadoc AST are not binded. |
| It is highly recommended for Javadoc checks do not use customization of java tokens and expect to be executed only on javadoc tokens. |
| </p> |
| <p> |
| There are four methods in AbstractJavadocCheck class to control the processed |
| <a href="apidocs/index.html">JavadocTokenTypes</a> - |
| one setter |
| <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#setJavadocTokens-java.lang.String...-"> |
| setJavadocTokens()</a>, which is used to define a custom set (which is different |
| from the default one) of the processed JavadocTokenTypes via config file and |
| three getters, which have to be overridden: |
| <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#getDefaultJavadocTokens--"> |
| getDefaultJavadocTokens()</a>, |
| <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#getAcceptableJavadocTokens--"> |
| getAcceptableJavadocTokens()</a>, |
| <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#getRequiredJavadocTokens--"> |
| getRequiredJavadocTokens()</a>. |
| </p> |
| |
| <ul> |
| |
| <li> |
| <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#setJavadocTokens-java.lang.String...-"> |
| setJavadocTokens()</a> - method then define actual set of tokens to run on. |
| </li> |
| <li> |
| <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#getDefaultJavadocTokens--"> |
| getDefaultJavadocTokens()</a> - returns a set of JavadocTokenTypes which are processed in |
| <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#visitToken-com.puppycrawl.tools.checkstyle.api.DetailAST-"> |
| visitToken()</a> method by default. |
| </li> |
| |
| <li> |
| <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#getRequiredJavadocTokens--"> |
| getRequiredJavadocTokens()</a> - returns a set of JavadocTokenTypes which Check must be subscribed to for |
| a valid execution. If the user wants to specify a custom set of JavadocTokenTypes then |
| this set must contain all the JavadocTokenTypes from RequiredJavadocTokens. |
| </li> |
| |
| <li> |
| <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html#getAcceptableJavadocTokens--"> |
| getAcceptableJavadocTokens()</a> - returns a set, which contains all the JavadocTokenTypes that |
| can be processed by the check. Both DefaultJavadocTokens and RequiredJavadocTokens and any custom |
| set of JavadocTokenTypes are subsets of AcceptableJavadocTokens. |
| </li> |
| |
| </ul> |
| </section> |
| |
| <section name="Integrating new Javadoc Check"> |
| Javadoc Checks as well as regular Checks extend <a href="apidocs/com/puppycrawl/tools/checkstyle/checks/javadoc/AbstractJavadocCheck.html">AbstractCheck</a> class. So integrating new Javadoc Check is similar to <a href="writingchecks.html#Integrate_your_Check">integrating other Checks</a>. |
| </section> |
| |
| <section name="Declare check's external resource locations"> |
| See <a href="writingchecks.html#Declare_checks_external_resource_locations">Declare check's external resource locations</a>. |
| </section> |
| |
| <section name="Examples of Javadoc Checks"> |
| The best source knowledge about how to write Javadoc Checks |
| could be taken from |
| <a href="https://github.com/search?q=path%3Asrc%2Fmain%2Fjava+repo%3Acheckstyle%2Fcheckstyle+%22extends+AbstractJavadocCheck%22"> |
| existing Checks</a>. |
| </section> |
| |
| <section name="Javadoc parser behavior for current HTML version and new HTML version"> |
| This section shows how parser should/will behave during parsing of current HTML version and any new HTML version. Current version is HTML4, new version that need to be supported is HTML5. |
| GeneralToken - mean that after parsing there will be general AstToken - HTML_TAG. |
| SpecialToken - mean that after parsing there will be special AstToken - PARAGRAPH, .... . |
| <p><b>Tags with optional (omittable) end tag:</b></p> |
| <table style="table-layout: fixed;"> |
| <tr> |
| <th>Input</th> |
| <th>Current standard (HTML4)</th> |
| <th>Current standard with hasUnclosedTag flag</th> |
| <th>After parser update for new standard (HTML5)</th> |
| <th>After parser update for new standard with hasUnclosedTag flag</th> |
| </tr> |
| <tr> |
| <td><![CDATA[<p>text</p>]]></td> |
| <td><![CDATA[No errors, Nested tree, SpecialToken]]></td> |
| <td><![CDATA[No errors, Nested tree, SpecialToken, hasUnclosedTag=false]]></td> |
| <td><![CDATA[No errors, Nested tree, SpecialToken]]></td> |
| <td><![CDATA[No errors, Nested tree, SpecialToken, hasUnclosedTag=false]]></td> |
| </tr> |
| <tr> |
| <td><![CDATA[<p>text]]></td> |
| <td><![CDATA[No errors, Non-nested tree, SpecialToken]]></td> |
| <td><![CDATA[No errors, Non-nested tree, SpecialToken, hasUnclosedTag=true]]></td> |
| <td><![CDATA[No errors, Non-nested tree, SpecialToken]]></td> |
| <td><![CDATA[No errors, Non-nested tree, SpecialToken, hasUnclosedTag=true]]></td> |
| </tr> |
| <tr> |
| <td> |
| <![CDATA[<rb>text</rb>]]> |
| <br/><i>New HTML5 tag with optional (omittable) end tag</i> |
| </td> |
| <td><![CDATA[No errors, Nested tree, GeneralToken]]></td> |
| <td><![CDATA[No errors, Nested tree, GeneralToken, hasUnclosedTag=false]]></td> |
| <td><![CDATA[No errors, Nested tree, SpecialToken]]></td> |
| <td><![CDATA[No errors, Nested tree, SpecialToken, hasUnclosedTag=false]]></td> |
| </tr> |
| <tr> |
| <td> |
| <![CDATA[<rb>text]]> |
| <br/><i>New HTML5 tag with optional (omittable) end tag</i> |
| </td> |
| <td><![CDATA[Parse error]]></td> |
| <td><![CDATA[Parse error]]></td> |
| <td><![CDATA[No errors, Non-nested tree, SpecialToken]]></td> |
| <td><![CDATA[No errors, Non-nested tree, SpecialToken, hasUnclosedTag=true]]></td> |
| </tr> |
| <tr> |
| <td> |
| <![CDATA[<qwerty>text</qwerty>]]> |
| <br/><i>Unknown HTML tag</i> |
| </td> |
| <td><![CDATA[No errors, Nested tree, GeneralToken]]></td> |
| <td><![CDATA[No errors, Nested tree, GeneralToken, hasUnclosedTag=false]]></td> |
| <td><![CDATA[No errors, Nested tree, GeneralToken]]></td> |
| <td><![CDATA[No errors, Nested tree, GeneralToken, hasUnclosedTag=false]]></td> |
| </tr> |
| <tr> |
| <td> |
| <![CDATA[<qwerty>text]]> |
| <br/><i>Unknown HTML tag</i> |
| </td> |
| <td><![CDATA[Parse error]]></td> |
| <td><![CDATA[Parse error]]></td> |
| <td><![CDATA[Parse error]]></td> |
| <td><![CDATA[Parse error]]></td> |
| </tr> |
| </table> |
| <br/> |
| <p><b>Void tags:</b></p> |
| Note: "Nested"/"Non-Nested" is not applicable for this type of tags - all of them are looks like Non-Nested. Flas "hasUnclosedTag" is "false" for all cases. |
| <table style="table-layout: fixed;"> |
| <tr> |
| <th>Input</th> |
| <th>Current standard (HTML4)</th> |
| <th>After parser update for new standard (HTML5)</th> |
| </tr> |
| <tr> |
| <td><![CDATA[<br/>]]></td> |
| <td>No errors, SpecialToken</td> |
| <td>No errors, SpecialToken</td> |
| </tr> |
| <tr> |
| <td><![CDATA[<br>]]></td> |
| <td>No errors, SpecialToken</td> |
| <td>No errors, SpecialToken</td> |
| </tr> |
| <tr> |
| <td> |
| <![CDATA[<embed/>]]> |
| <br/><i>New HTML5 tag</i> |
| </td> |
| <td>No errors, GeneralToken</td> |
| <td>No errors, SpecialToken</td> |
| </tr> |
| <tr> |
| <td> |
| <![CDATA[<embed>]]> |
| <br/><i>New HTML5 tag</i> |
| </td> |
| <td>Parse Error</td> |
| <td>No errors, SpecialToken</td> |
| </tr> |
| <tr> |
| <td> |
| <![CDATA[<basefont/>]]> |
| <br/><i>Supported in HTML4. Not supported tag in HTML5</i> |
| </td> |
| <td>No errors, SpecialToken</td> |
| <td>No errors, SpecialToken</td> |
| </tr> |
| <tr> |
| <td> |
| <![CDATA[<basefont>]]> |
| <br/><i>Supported in HTML4. Not supported tag in HTML5</i> |
| </td> |
| <td>No errors, SpecialToken</td> |
| <td>No errors, SpecialToken</td> |
| </tr> |
| <tr> |
| <td> |
| <![CDATA[<qwerty/>]]> |
| <br/><i>Unknown HTML tag</i> |
| </td> |
| <td>No errors, GeneralToken</td> |
| <td>No errors, GeneralToken</td> |
| </tr> |
| <tr> |
| <td> |
| <![CDATA[<qwerty>]]> |
| <br/><i>Unknown HTML tag</i> |
| </td> |
| <td>Parse Error</td> |
| <td>Parse Error</td> |
| </tr> |
| </table> |
| </section> |
| |
| </body> |
| </document> |