Coverage Report - com.puppycrawl.tools.checkstyle.checks.javadoc.AtclauseOrderCheck
 
Classes in this File Line Coverage Branch Coverage Complexity
AtclauseOrderCheck
100%
41/41
100%
18/18
2.286
 
 1  
 ////////////////////////////////////////////////////////////////////////////////
 2  
 // checkstyle: Checks Java source code for adherence to a set of rules.
 3  
 // Copyright (C) 2001-2017 the original author or authors.
 4  
 //
 5  
 // This library is free software; you can redistribute it and/or
 6  
 // modify it under the terms of the GNU Lesser General Public
 7  
 // License as published by the Free Software Foundation; either
 8  
 // version 2.1 of the License, or (at your option) any later version.
 9  
 //
 10  
 // This library is distributed in the hope that it will be useful,
 11  
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  
 // Lesser General Public License for more details.
 14  
 //
 15  
 // You should have received a copy of the GNU Lesser General Public
 16  
 // License along with this library; if not, write to the Free Software
 17  
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 18  
 ////////////////////////////////////////////////////////////////////////////////
 19  
 
 20  
 package com.puppycrawl.tools.checkstyle.checks.javadoc;
 21  
 
 22  
 import java.util.ArrayList;
 23  
 import java.util.Arrays;
 24  
 import java.util.List;
 25  
 
 26  
 import com.puppycrawl.tools.checkstyle.api.DetailAST;
 27  
 import com.puppycrawl.tools.checkstyle.api.DetailNode;
 28  
 import com.puppycrawl.tools.checkstyle.api.JavadocTokenTypes;
 29  
 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
 30  
 import com.puppycrawl.tools.checkstyle.utils.JavadocUtils;
 31  
 import com.puppycrawl.tools.checkstyle.utils.TokenUtils;
 32  
 
 33  
 /**
 34  
  * <p>
 35  
  * Checks the order of
 36  
  * <a href="https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDBEFIF">
 37  
  * javadoc block-tags or javadoc tags</a>.
 38  
  * </p>
 39  
  * <p>
 40  
  * Note: Google used term "at-clauses" for block tags in his guide till 2017-02-28.
 41  
  * </p>
 42  
  *
 43  
  * <p>
 44  
  * The check allows to configure itself by using the following properties:
 45  
  * </p>
 46  
  * <ul>
 47  
  * <li>
 48  
  * target - allows to specify targets to check at-clauses.
 49  
  * </li>
 50  
  * <li>
 51  
  * tagOrder - allows to specify the order by tags.
 52  
  * </li>
 53  
  * </ul>
 54  
  * <p>
 55  
  * Default configuration:
 56  
  * </p>
 57  
  * <pre>
 58  
  * &lt;module name=&quot;AtclauseOrderCheck&quot;&gt;
 59  
  *     &lt;property name=&quot;tagOrder&quot; value=&quot;&#64;author, &#64;version, &#64;param,
 60  
  *     &#64;return, &#64;throws, &#64;exception, &#64;see, &#64;since, &#64;serial,
 61  
  *     &#64;serialField, &#64;serialData, &#64;deprecated&quot;/&gt;
 62  
  *     &lt;property name=&quot;target&quot; value=&quot;CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
 63  
  *     METHOD_DEF, CTOR_DEF, VARIABLE_DEF&quot;/&gt;
 64  
  * &lt;/module&gt;
 65  
  * </pre>
 66  
  *
 67  
  * @author max
 68  
  *
 69  
  */
 70  15
 public class AtclauseOrderCheck extends AbstractJavadocCheck {
 71  
 
 72  
     /**
 73  
      * A key is pointing to the warning message text in "messages.properties"
 74  
      * file.
 75  
      */
 76  
     public static final String MSG_KEY = "at.clause.order";
 77  
 
 78  
     /**
 79  
      * Default order of atclauses.
 80  
      */
 81  2
     private static final String[] DEFAULT_ORDER = {
 82  
         "@author", "@version",
 83  
         "@param", "@return",
 84  
         "@throws", "@exception",
 85  
         "@see", "@since",
 86  
         "@serial", "@serialField",
 87  
         "@serialData", "@deprecated",
 88  
     };
 89  
 
 90  
     /**
 91  
      * Default target of checking atclauses.
 92  
      */
 93  30
     private List<Integer> target = Arrays.asList(
 94  15
         TokenTypes.CLASS_DEF,
 95  15
         TokenTypes.INTERFACE_DEF,
 96  15
         TokenTypes.ENUM_DEF,
 97  15
         TokenTypes.METHOD_DEF,
 98  15
         TokenTypes.CTOR_DEF,
 99  15
         TokenTypes.VARIABLE_DEF
 100  
     );
 101  
 
 102  
     /**
 103  
      * Order of atclauses.
 104  
      */
 105  15
     private List<String> tagOrder = Arrays.asList(DEFAULT_ORDER);
 106  
 
 107  
     /**
 108  
      * Sets custom targets.
 109  
      * @param targets user's targets.
 110  
      */
 111  
     public void setTarget(String... targets) {
 112  3
         final List<Integer> customTarget = new ArrayList<>();
 113  16
         for (String temp : targets) {
 114  13
             customTarget.add(TokenUtils.getTokenId(temp.trim()));
 115  
         }
 116  3
         target = customTarget;
 117  3
     }
 118  
 
 119  
     /**
 120  
      * Sets custom order of atclauses.
 121  
      * @param orders user's orders.
 122  
      */
 123  
     public void setTagOrder(String... orders) {
 124  3
         final List<String> customOrder = new ArrayList<>();
 125  31
         for (String order : orders) {
 126  28
             customOrder.add(order.trim());
 127  
         }
 128  3
         tagOrder = customOrder;
 129  3
     }
 130  
 
 131  
     @Override
 132  
     public int[] getDefaultJavadocTokens() {
 133  31
         return new int[] {
 134  
             JavadocTokenTypes.JAVADOC,
 135  
         };
 136  
     }
 137  
 
 138  
     @Override
 139  
     public int[] getRequiredJavadocTokens() {
 140  15
         return getAcceptableJavadocTokens();
 141  
     }
 142  
 
 143  
     @Override
 144  
     public void visitJavadocToken(DetailNode ast) {
 145  95
         final int parentType = getParentType(getBlockCommentAst());
 146  
 
 147  95
         if (target.contains(parentType)) {
 148  68
             checkOrderInTagSection(ast);
 149  
         }
 150  95
     }
 151  
 
 152  
     /**
 153  
      * Checks order of atclauses in tag section node.
 154  
      * @param javadoc Javadoc root node.
 155  
      */
 156  
     private void checkOrderInTagSection(DetailNode javadoc) {
 157  68
         int maxIndexOfPreviousTag = 0;
 158  
 
 159  1160
         for (DetailNode node : javadoc.getChildren()) {
 160  1092
             if (node.getType() == JavadocTokenTypes.JAVADOC_TAG) {
 161  203
                 final String tagText = JavadocUtils.getFirstChild(node).getText();
 162  203
                 final int indexOfCurrentTag = tagOrder.indexOf(tagText);
 163  
 
 164  203
                 if (indexOfCurrentTag != -1) {
 165  202
                     if (indexOfCurrentTag < maxIndexOfPreviousTag) {
 166  41
                         log(node.getLineNumber(), MSG_KEY, tagOrder.toString());
 167  
                     }
 168  
                     else {
 169  161
                         maxIndexOfPreviousTag = indexOfCurrentTag;
 170  
                     }
 171  
                 }
 172  
             }
 173  
         }
 174  68
     }
 175  
 
 176  
     /**
 177  
      * Returns type of parent node.
 178  
      * @param commentBlock child node.
 179  
      * @return parent type.
 180  
      */
 181  
     private static int getParentType(DetailAST commentBlock) {
 182  95
         final DetailAST parentNode = commentBlock.getParent();
 183  95
         int type = parentNode.getType();
 184  95
         if (type == TokenTypes.TYPE || type == TokenTypes.MODIFIERS) {
 185  81
             type = parentNode.getParent().getType();
 186  
         }
 187  95
         return type;
 188  
     }
 189  
 }