Coverage Report - com.puppycrawl.tools.checkstyle.checks.metrics.AbstractComplexityCheck
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractComplexityCheck
92%
36/39
35%
5/14
1.562
 
 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 com.puppycrawl.tools.checkstyle.api.Check;
 22  
 import com.puppycrawl.tools.checkstyle.api.DetailAST;
 23  
 import com.puppycrawl.tools.checkstyle.api.FastStack;
 24  
 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
 25  
 import java.math.BigInteger;
 26  
 
 27  
 /**
 28  
  * Base class for checks the calculate complexity based around methods.
 29  
  *
 30  
  * @author <a href="mailto:simon@redhillconsulting.com.au">Simon Harris</a>
 31  
  * @author Oliver Burn
 32  
  */
 33  
 public abstract class AbstractComplexityCheck
 34  
     extends Check
 35  
 {
 36  
     /** the initial current value */
 37  1
     private static final BigInteger INITIAL_VALUE = BigInteger.ONE;
 38  
 
 39  
     /** stack of values - all but the current value */
 40  3
     private final FastStack<BigInteger> mValueStack = FastStack.newInstance();
 41  
 
 42  
     /** the current value */
 43  3
     private BigInteger mCurrentValue = BigInteger.ZERO;
 44  
 
 45  
     /** threshold to report error for */
 46  
     private int mMax;
 47  
 
 48  
     /**
 49  
      * Creates an instance.
 50  
      * @param aMax the threshold of when to report an error
 51  
      */
 52  
     public AbstractComplexityCheck(int aMax)
 53  3
     {
 54  3
         mMax = aMax;
 55  3
     }
 56  
 
 57  
     /**
 58  
      * @return the message ID to log violations with
 59  
      */
 60  
     protected abstract String getMessageID();
 61  
 
 62  
     /**
 63  
      * Hook called when visiting a token. Will not be called the method
 64  
      * definition tokens.
 65  
      *
 66  
      * @param aAST the token being visited
 67  
      */
 68  
     protected void visitTokenHook(DetailAST aAST)
 69  
     {
 70  0
     }
 71  
 
 72  
     /**
 73  
      * Hook called when leaving a token. Will not be called the method
 74  
      * definition tokens.
 75  
      *
 76  
      * @param aAST the token being left
 77  
      */
 78  
     protected void leaveTokenHook(DetailAST aAST)
 79  
     {
 80  20
     }
 81  
 
 82  
     @Override
 83  
     public final int[] getRequiredTokens()
 84  
     {
 85  0
         return new int[] {
 86  
             TokenTypes.CTOR_DEF,
 87  
             TokenTypes.METHOD_DEF,
 88  
             TokenTypes.INSTANCE_INIT,
 89  
             TokenTypes.STATIC_INIT,
 90  
         };
 91  
     }
 92  
 
 93  
     /** @return the maximum threshold allowed */
 94  
     public final int getMax()
 95  
     {
 96  0
         return mMax;
 97  
     }
 98  
 
 99  
     /**
 100  
      * Set the maximum threshold allowed.
 101  
      *
 102  
      * @param aMax the maximum threshold
 103  
      */
 104  
     public final void setMax(int aMax)
 105  
     {
 106  3
         mMax = aMax;
 107  3
     }
 108  
 
 109  
     @Override
 110  
     public void visitToken(DetailAST aAST)
 111  
     {
 112  41
         switch (aAST.getType()) {
 113  
         case TokenTypes.CTOR_DEF:
 114  
         case TokenTypes.METHOD_DEF:
 115  
         case TokenTypes.INSTANCE_INIT:
 116  
         case TokenTypes.STATIC_INIT:
 117  21
             visitMethodDef();
 118  21
             break;
 119  
         default:
 120  20
             visitTokenHook(aAST);
 121  
         }
 122  41
     }
 123  
 
 124  
     @Override
 125  
     public void leaveToken(DetailAST aAST)
 126  
     {
 127  41
         switch (aAST.getType()) {
 128  
         case TokenTypes.CTOR_DEF:
 129  
         case TokenTypes.METHOD_DEF:
 130  
         case TokenTypes.INSTANCE_INIT:
 131  
         case TokenTypes.STATIC_INIT:
 132  21
             leaveMethodDef(aAST);
 133  21
             break;
 134  
         default:
 135  20
             leaveTokenHook(aAST);
 136  
         }
 137  41
     }
 138  
 
 139  
     /**
 140  
      * @return the current value
 141  
      */
 142  
     protected final BigInteger getCurrentValue()
 143  
     {
 144  128
         return mCurrentValue;
 145  
     }
 146  
 
 147  
     /**
 148  
      * Set the current value
 149  
      * @param aValue the new value
 150  
      */
 151  
     protected final void setCurrentValue(BigInteger aValue)
 152  
     {
 153  128
         mCurrentValue = aValue;
 154  128
     }
 155  
 
 156  
     /**
 157  
      * Increments the current value by a specified amount.
 158  
      *
 159  
      * @param aBy the amount to increment by
 160  
      */
 161  
     protected final void incrementCurrentValue(BigInteger aBy)
 162  
     {
 163  20
         setCurrentValue(getCurrentValue().add(aBy));
 164  20
     }
 165  
 
 166  
     /** Push the current value on the stack */
 167  
     protected final void pushValue()
 168  
     {
 169  129
         mValueStack.push(mCurrentValue);
 170  129
         mCurrentValue = INITIAL_VALUE;
 171  129
     }
 172  
 
 173  
     /**
 174  
      * @return pop a value off the stack and make it the current value
 175  
      */
 176  
     protected final BigInteger popValue()
 177  
     {
 178  129
         mCurrentValue = mValueStack.pop();
 179  129
         return mCurrentValue;
 180  
     }
 181  
 
 182  
     /** Process the start of the method definition */
 183  
     private void visitMethodDef()
 184  
     {
 185  21
         pushValue();
 186  21
     }
 187  
 
 188  
     /**
 189  
      * Process the end of a method definition.
 190  
      *
 191  
      * @param aAST the token representing the method definition
 192  
      */
 193  
     private void leaveMethodDef(DetailAST aAST)
 194  
     {
 195  21
         final BigInteger max = BigInteger.valueOf(mMax);
 196  21
         if (mCurrentValue.compareTo(max) > 0) {
 197  21
             log(aAST, getMessageID(), mCurrentValue, max);
 198  
         }
 199  21
         popValue();
 200  21
     }
 201  
 }