Coverage Report - com.puppycrawl.tools.checkstyle.checks.metrics.NPathComplexityCheck
 
Classes in this File Line Coverage Branch Coverage Complexity
NPathComplexityCheck
100%
26/26
10%
6/56
3.222
 
 1  
 ////////////////////////////////////////////////////////////////////////////////
 2  
 // checkstyle: Checks Java source code for adherence to a set of rules.
 3  
 // Copyright (C) 2001-2014  Oliver Burn
 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  
 package com.puppycrawl.tools.checkstyle.checks.metrics;
 20  
 
 21  
 import java.math.BigInteger;
 22  
 
 23  
 import com.puppycrawl.tools.checkstyle.api.DetailAST;
 24  
 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
 25  
 
 26  
 /**
 27  
  * Checks the npath complexity against a specified limit (default = 200).
 28  
  * The npath metric computes the number of possible execution paths
 29  
  * through a function. Similar to the cyclomatic complexity but also
 30  
  * takes into account the nesting of conditional statements and
 31  
  * multi-part boolean expressions.
 32  
  *
 33  
  * @author <a href="mailto:simon@redhillconsulting.com.au">Simon Harris</a>
 34  
  * @author o_sukhodolsky
 35  
  * TODO: For every or: _value += (_orCount * (nestedValue - 1));
 36  
  * TODO: For every and: ???
 37  
  */
 38  
 public final class NPathComplexityCheck extends AbstractComplexityCheck
 39  
 {
 40  
     /** Default allowed complexity. */
 41  
     private static final int DEFAULT_MAX = 200;
 42  
 
 43  
     /** Creates new instance of the check. */
 44  
     public NPathComplexityCheck()
 45  
     {
 46  2
         super(DEFAULT_MAX);
 47  2
     }
 48  
 
 49  
     @Override
 50  
     public int[] getDefaultTokens()
 51  
     {
 52  2
         return new int[] {
 53  
             TokenTypes.CTOR_DEF,
 54  
             TokenTypes.METHOD_DEF,
 55  
             TokenTypes.STATIC_INIT,
 56  
             TokenTypes.INSTANCE_INIT,
 57  
             TokenTypes.LITERAL_WHILE,
 58  
             TokenTypes.LITERAL_DO,
 59  
             TokenTypes.LITERAL_FOR,
 60  
             TokenTypes.LITERAL_IF,
 61  
             TokenTypes.LITERAL_ELSE,
 62  
             TokenTypes.LITERAL_SWITCH,
 63  
             TokenTypes.LITERAL_CASE,
 64  
             TokenTypes.LITERAL_TRY,
 65  
             TokenTypes.LITERAL_CATCH,
 66  
             TokenTypes.QUESTION,
 67  
         };
 68  
     }
 69  
 
 70  
     @Override
 71  
     public void visitToken(DetailAST aAST)
 72  
     {
 73  119
         switch (aAST.getType()) {
 74  
         case TokenTypes.LITERAL_WHILE:
 75  
         case TokenTypes.LITERAL_DO:
 76  
         case TokenTypes.LITERAL_FOR:
 77  
         case TokenTypes.LITERAL_IF:
 78  
         case TokenTypes.QUESTION:
 79  
         case TokenTypes.LITERAL_TRY:
 80  
         case TokenTypes.LITERAL_SWITCH:
 81  98
             visitMultiplyingConditional();
 82  98
             break;
 83  
         case TokenTypes.LITERAL_ELSE:
 84  
         case TokenTypes.LITERAL_CATCH:
 85  
         case TokenTypes.LITERAL_CASE:
 86  10
             visitAddingConditional();
 87  10
             break;
 88  
         default:
 89  11
             super.visitToken(aAST);
 90  
         }
 91  119
     }
 92  
 
 93  
     @Override
 94  
     public void leaveToken(DetailAST aAST)
 95  
     {
 96  119
         switch (aAST.getType()) {
 97  
         case TokenTypes.LITERAL_WHILE:
 98  
         case TokenTypes.LITERAL_DO:
 99  
         case TokenTypes.LITERAL_FOR:
 100  
         case TokenTypes.LITERAL_IF:
 101  
         case TokenTypes.QUESTION:
 102  
         case TokenTypes.LITERAL_TRY:
 103  
         case TokenTypes.LITERAL_SWITCH:
 104  98
             leaveMultiplyingConditional();
 105  98
             break;
 106  
         case TokenTypes.LITERAL_ELSE:
 107  
         case TokenTypes.LITERAL_CATCH:
 108  
         case TokenTypes.LITERAL_CASE:
 109  10
             leaveAddingConditional();
 110  10
             break;
 111  
         default:
 112  11
             super.leaveToken(aAST);
 113  
         }
 114  119
     }
 115  
 
 116  
     @Override
 117  
     protected String getMessageID()
 118  
     {
 119  11
         return "npathComplexity";
 120  
     }
 121  
 
 122  
     /** Visits else, catch or case. */
 123  
     private void visitAddingConditional()
 124  
     {
 125  10
         pushValue();
 126  10
     }
 127  
 
 128  
     /** Leaves else, catch or case. */
 129  
     private void leaveAddingConditional()
 130  
     {
 131  10
         setCurrentValue(
 132  
                 getCurrentValue().subtract(BigInteger.ONE).add(popValue()));
 133  10
     }
 134  
 
 135  
     /** Visits while, do, for, if, try, ? (in ?::) or switch. */
 136  
     private void visitMultiplyingConditional()
 137  
     {
 138  98
         pushValue();
 139  98
     }
 140  
 
 141  
     /** Leaves while, do, for, if, try, ? (in ?::) or switch. */
 142  
     private void leaveMultiplyingConditional()
 143  
     {
 144  98
         setCurrentValue(
 145  
                 getCurrentValue().add(BigInteger.ONE).multiply(popValue()));
 146  98
     }
 147  
 }