Coverage Report - com.puppycrawl.tools.checkstyle.checks.imports.RedundantImportCheck
 
Classes in this File Line Coverage Branch Coverage Complexity
RedundantImportCheck
97%
34/35
81%
18/22
3.5
 
 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  
 
 20  
 package com.puppycrawl.tools.checkstyle.checks.imports;
 21  
 
 22  
 import com.google.common.collect.Sets;
 23  
 import com.puppycrawl.tools.checkstyle.api.Check;
 24  
 import com.puppycrawl.tools.checkstyle.api.DetailAST;
 25  
 import com.puppycrawl.tools.checkstyle.api.FullIdent;
 26  
 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
 27  
 import java.util.Set;
 28  
 
 29  
 /**
 30  
  * <p>
 31  
  * Checks for imports that are redundant. An import statement is
 32  
  * considered redundant if:
 33  
  * </p>
 34  
  *<ul>
 35  
  *  <li>It is a duplicate of another import. This is, when a class is imported
 36  
  *  more than once.</li>
 37  
  *  <li>The class non-statically imported is from the <code>java.lang</code>
 38  
  *  package. For example importing <code>java.lang.String</code>.</li>
 39  
  *  <li>The class non-statically imported is from the same package as the
 40  
  *  current package.</li>
 41  
  *</ul>
 42  
  * <p>
 43  
  * An example of how to configure the check is:
 44  
  * </p>
 45  
  * <pre>
 46  
  * &lt;module name="RedundantImport"/&gt;
 47  
  * </pre>
 48  
  *
 49  
  * Compatible with Java 1.5 source.
 50  
  *
 51  
  * @author Oliver Burn
 52  
  * @version 1.0
 53  
  */
 54  1
 public class RedundantImportCheck
 55  
     extends Check
 56  
 {
 57  
     /** name of package in file */
 58  
     private String mPkgName;
 59  
     /** set of the imports */
 60  1
     private final Set<FullIdent> mImports = Sets.newHashSet();
 61  
     /** set of static imports */
 62  1
     private final Set<FullIdent> mStaticImports = Sets.newHashSet();
 63  
 
 64  
     @Override
 65  
     public void beginTree(DetailAST aRootAST)
 66  
     {
 67  1
         mPkgName = null;
 68  1
         mImports.clear();
 69  1
         mStaticImports.clear();
 70  1
     }
 71  
 
 72  
     @Override
 73  
     public int[] getDefaultTokens()
 74  
     {
 75  1
         return new int[]
 76  
         {TokenTypes.IMPORT,
 77  
          TokenTypes.STATIC_IMPORT,
 78  
          TokenTypes.PACKAGE_DEF, };
 79  
     }
 80  
 
 81  
     @Override
 82  
     public void visitToken(DetailAST aAST)
 83  
     {
 84  29
         if (aAST.getType() == TokenTypes.PACKAGE_DEF) {
 85  1
             mPkgName = FullIdent.createFullIdent(
 86  
                     aAST.getLastChild().getPreviousSibling()).getText();
 87  
         }
 88  28
         else if (aAST.getType() == TokenTypes.IMPORT) {
 89  23
             final FullIdent imp = FullIdent.createFullIdentBelow(aAST);
 90  23
             if (fromPackage(imp.getText(), "java.lang")) {
 91  2
                 log(aAST.getLineNo(), aAST.getColumnNo(), "import.lang",
 92  
                     imp.getText());
 93  
             }
 94  21
             else if (fromPackage(imp.getText(), mPkgName)) {
 95  2
                 log(aAST.getLineNo(), aAST.getColumnNo(), "import.same",
 96  
                     imp.getText());
 97  
             }
 98  
             // Check for a duplicate import
 99  23
             for (FullIdent full : mImports) {
 100  253
                 if (imp.getText().equals(full.getText())) {
 101  1
                     log(aAST.getLineNo(), aAST.getColumnNo(),
 102  
                             "import.duplicate", full.getLineNo(),
 103  
                             imp.getText());
 104  
                 }
 105  
             }
 106  
 
 107  23
             mImports.add(imp);
 108  23
         }
 109  
         else {
 110  
             // Check for a duplicate static import
 111  5
             final FullIdent imp =
 112  
                 FullIdent.createFullIdent(
 113  
                     aAST.getLastChild().getPreviousSibling());
 114  5
             for (FullIdent full : mStaticImports) {
 115  10
                 if (imp.getText().equals(full.getText())) {
 116  1
                     log(aAST.getLineNo(), aAST.getColumnNo(),
 117  
                         "import.duplicate", full.getLineNo(), imp.getText());
 118  
                 }
 119  
             }
 120  
 
 121  5
             mStaticImports.add(imp);
 122  
         }
 123  29
     }
 124  
 
 125  
     /**
 126  
      * Determines if an import statement is for types from a specified package.
 127  
      * @param aImport the import name
 128  
      * @param aPkg the package name
 129  
      * @return whether from the package
 130  
      */
 131  
     private static boolean fromPackage(String aImport, String aPkg)
 132  
     {
 133  44
         boolean retVal = false;
 134  44
         if (aPkg == null) {
 135  
             // If not package, then check for no package in the import.
 136  0
             retVal = (aImport.indexOf('.') == -1);
 137  
         }
 138  
         else {
 139  44
             final int index = aImport.lastIndexOf('.');
 140  44
             if (index != -1) {
 141  44
                 final String front = aImport.substring(0, index);
 142  44
                 retVal = front.equals(aPkg);
 143  
             }
 144  
         }
 145  44
         return retVal;
 146  
     }
 147  
 }