Coverage Report - com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocVariableCheck
 
Classes in this File Line Coverage Branch Coverage Complexity
JavadocVariableCheck
100%
33/33
100%
28/28
2.333
 
 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.regex.Pattern;
 23  
 
 24  
 import com.puppycrawl.tools.checkstyle.StatelessCheck;
 25  
 import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
 26  
 import com.puppycrawl.tools.checkstyle.api.DetailAST;
 27  
 import com.puppycrawl.tools.checkstyle.api.FileContents;
 28  
 import com.puppycrawl.tools.checkstyle.api.Scope;
 29  
 import com.puppycrawl.tools.checkstyle.api.TextBlock;
 30  
 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
 31  
 import com.puppycrawl.tools.checkstyle.utils.ScopeUtils;
 32  
 
 33  
 /**
 34  
  * Checks that a variable has Javadoc comment. Ignores {@code serialVersionUID} fields.
 35  
  *
 36  
  * @author Oliver Burn
 37  
  */
 38  
 @StatelessCheck
 39  23
 public class JavadocVariableCheck
 40  
     extends AbstractCheck {
 41  
 
 42  
     /**
 43  
      * A key is pointing to the warning message text in "messages.properties"
 44  
      * file.
 45  
      */
 46  
     public static final String MSG_JAVADOC_MISSING = "javadoc.missing";
 47  
 
 48  
     /** The scope to check. */
 49  23
     private Scope scope = Scope.PRIVATE;
 50  
 
 51  
     /** The visibility scope where Javadoc comments shouldn't be checked. **/
 52  
     private Scope excludeScope;
 53  
 
 54  
     /** The pattern to ignore variable name. */
 55  
     private Pattern ignoreNamePattern;
 56  
 
 57  
     /**
 58  
      * Sets the scope to check.
 59  
      * @param scope a scope.
 60  
      */
 61  
     public void setScope(Scope scope) {
 62  6
         this.scope = scope;
 63  6
     }
 64  
 
 65  
     /**
 66  
      * Set the excludeScope.
 67  
      * @param excludeScope a scope.
 68  
      */
 69  
     public void setExcludeScope(Scope excludeScope) {
 70  2
         this.excludeScope = excludeScope;
 71  2
     }
 72  
 
 73  
     /**
 74  
      * Sets the variable names to ignore in the check.
 75  
      * @param pattern a pattern.
 76  
      */
 77  
     public void setIgnoreNamePattern(Pattern pattern) {
 78  3
         ignoreNamePattern = pattern;
 79  3
     }
 80  
 
 81  
     @Override
 82  
     public int[] getDefaultTokens() {
 83  37
         return getAcceptableTokens();
 84  
     }
 85  
 
 86  
     @Override
 87  
     public int[] getAcceptableTokens() {
 88  43
         return new int[] {
 89  
             TokenTypes.VARIABLE_DEF,
 90  
             TokenTypes.ENUM_CONSTANT_DEF,
 91  
         };
 92  
     }
 93  
 
 94  
     /*
 95  
      * Skipping enum values is requested.
 96  
      * Checkstyle's issue #1669: https://github.com/checkstyle/checkstyle/issues/1669
 97  
      */
 98  
     @Override
 99  
     public int[] getRequiredTokens() {
 100  39
         return new int[] {
 101  
             TokenTypes.VARIABLE_DEF,
 102  
         };
 103  
     }
 104  
 
 105  
     @Override
 106  
     public void visitToken(DetailAST ast) {
 107  252
         if (shouldCheck(ast)) {
 108  176
             final FileContents contents = getFileContents();
 109  176
             final TextBlock textBlock =
 110  176
                 contents.getJavadocBefore(ast.getLineNo());
 111  
 
 112  176
             if (textBlock == null) {
 113  163
                 log(ast, MSG_JAVADOC_MISSING);
 114  
             }
 115  
         }
 116  252
     }
 117  
 
 118  
     /**
 119  
      * Decides whether the variable name of an AST is in the ignore list.
 120  
      * @param ast the AST to check
 121  
      * @return true if the variable name of ast is in the ignore list.
 122  
      */
 123  
     private boolean isIgnored(DetailAST ast) {
 124  237
         final String name = ast.findFirstToken(TokenTypes.IDENT).getText();
 125  474
         return ignoreNamePattern != null && ignoreNamePattern.matcher(name).matches()
 126  236
             || "serialVersionUID".equals(name);
 127  
     }
 128  
 
 129  
     /**
 130  
      * Whether we should check this node.
 131  
      * @param ast a given node.
 132  
      * @return whether we should check a given node.
 133  
      */
 134  
     private boolean shouldCheck(final DetailAST ast) {
 135  252
         boolean result = false;
 136  252
         if (!ScopeUtils.isInCodeBlock(ast) && !isIgnored(ast)) {
 137  230
             Scope customScope = Scope.PUBLIC;
 138  230
             if (ast.getType() != TokenTypes.ENUM_CONSTANT_DEF
 139  223
                     && !ScopeUtils.isInInterfaceOrAnnotationBlock(ast)) {
 140  215
                 final DetailAST mods = ast.findFirstToken(TokenTypes.MODIFIERS);
 141  215
                 customScope = ScopeUtils.getScopeFromMods(mods);
 142  
             }
 143  
 
 144  230
             final Scope surroundingScope = ScopeUtils.getSurroundingScope(ast);
 145  230
             result = customScope.isIn(scope) && surroundingScope.isIn(scope)
 146  
                 && (excludeScope == null
 147  37
                     || !customScope.isIn(excludeScope)
 148  18
                     || !surroundingScope.isIn(excludeScope));
 149  
         }
 150  252
         return result;
 151  
     }
 152  
 }