Coverage Report - com.puppycrawl.tools.checkstyle.checks.modifier.RedundantModifierCheck
 
Classes in this File Line Coverage Branch Coverage Complexity
RedundantModifierCheck
92%
38/41
93%
28/30
6
 
 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.modifier;
 20  
 
 21  
 import com.puppycrawl.tools.checkstyle.api.Check;
 22  
 import com.puppycrawl.tools.checkstyle.api.DetailAST;
 23  
 import com.puppycrawl.tools.checkstyle.api.ScopeUtils;
 24  
 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
 25  
 
 26  
 /**
 27  
  * Checks for redundant modifiers in interface and annotation definitions.
 28  
  * Also checks for redundant final modifiers on methods of final classes.
 29  
  *
 30  
  * @author lkuehne
 31  
  */
 32  1
 public class RedundantModifierCheck
 33  
     extends Check
 34  
 {
 35  
     @Override
 36  
     public int[] getDefaultTokens()
 37  
     {
 38  1
         return new int[] {
 39  
             TokenTypes.METHOD_DEF,
 40  
             TokenTypes.VARIABLE_DEF,
 41  
             TokenTypes.ANNOTATION_FIELD_DEF,
 42  
             TokenTypes.INTERFACE_DEF,
 43  
         };
 44  
     }
 45  
 
 46  
     @Override
 47  
     public int[] getRequiredTokens()
 48  
     {
 49  0
         return new int[] {};
 50  
     }
 51  
 
 52  
     @Override
 53  
     public void visitToken(DetailAST aAST)
 54  
     {
 55  27
         if (TokenTypes.INTERFACE_DEF == aAST.getType()) {
 56  2
             final DetailAST modifiers =
 57  
                 aAST.findFirstToken(TokenTypes.MODIFIERS);
 58  2
             if (null != modifiers) {
 59  2
                 final DetailAST modifier =
 60  
                     modifiers.findFirstToken(TokenTypes.LITERAL_STATIC);
 61  2
                 if (null != modifier) {
 62  1
                     log(modifier.getLineNo(), modifier.getColumnNo(),
 63  
                         "redundantModifier", modifier.getText());
 64  
                 }
 65  
             }
 66  2
         }
 67  25
         else if (ScopeUtils.inInterfaceOrAnnotationBlock(aAST)) {
 68  14
             final DetailAST modifiers =
 69  
                 aAST.findFirstToken(TokenTypes.MODIFIERS);
 70  
 
 71  14
             DetailAST modifier = modifiers.getFirstChild();
 72  14
             while (modifier != null) {
 73  
 
 74  
                 // javac does not allow final or static in interface methods
 75  
                 // order annotation fields hence no need to check that this
 76  
                 // is not a method or annotation field
 77  
 
 78  9
                 final int type = modifier.getType();
 79  9
                 if ((type == TokenTypes.LITERAL_PUBLIC)
 80  
                     || (type == TokenTypes.ABSTRACT)
 81  
                     || (type == TokenTypes.LITERAL_STATIC)
 82  
                     || (type == TokenTypes.FINAL))
 83  
                 {
 84  9
                     log(modifier.getLineNo(), modifier.getColumnNo(),
 85  
                             "redundantModifier", modifier.getText());
 86  9
                     break;
 87  
                 }
 88  
 
 89  0
                 modifier = modifier.getNextSibling();
 90  0
             }
 91  14
         }
 92  11
         else if (aAST.getType() == TokenTypes.METHOD_DEF) {
 93  10
             final DetailAST modifiers =
 94  
                             aAST.findFirstToken(TokenTypes.MODIFIERS);
 95  
             // private method?
 96  10
             boolean checkFinal =
 97  
                 modifiers.branchContains(TokenTypes.LITERAL_PRIVATE);
 98  
             // declared in a final class?
 99  10
             DetailAST parent = aAST.getParent();
 100  26
             while (parent != null) {
 101  25
                 if (parent.getType() == TokenTypes.CLASS_DEF) {
 102  9
                     final DetailAST classModifiers =
 103  
                         parent.findFirstToken(TokenTypes.MODIFIERS);
 104  9
                     checkFinal |=
 105  
                         classModifiers.branchContains(TokenTypes.FINAL);
 106  9
                     break;
 107  
                 }
 108  16
                 parent = parent.getParent();
 109  
             }
 110  10
             if (checkFinal) {
 111  9
                 DetailAST modifier = modifiers.getFirstChild();
 112  28
                 while (modifier != null) {
 113  21
                     final int type = modifier.getType();
 114  21
                     if (type == TokenTypes.FINAL) {
 115  2
                         log(modifier.getLineNo(), modifier.getColumnNo(),
 116  
                                 "redundantModifier", modifier.getText());
 117  2
                         break;
 118  
                     }
 119  19
                     modifier = modifier.getNextSibling();
 120  19
                 }
 121  
             }
 122  
         }
 123  27
     }
 124  
 }