Clover Coverage Report - Checkstyle
Coverage timestamp: Fri May 9 2008 10:48:13 EST
../../../../../../img/srcFileCovDistChart10.png 0% of files have more coverage
28   126   12   7
16   68   0.43   4
4     3  
1    
 
  CovariantEqualsCheck       Line # 46 91.7% 0.9166667
12.08 28 12 12 0.43
 
  (1)
 
1    ////////////////////////////////////////////////////////////////////////////////
2    // checkstyle: Checks Java source code for adherence to a set of rules.
3    // Copyright (C) 2001-2005 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.coding;
20   
21    import java.util.HashSet;
22    import java.util.Iterator;
23    import java.util.Set;
24   
25    import com.puppycrawl.tools.checkstyle.api.Check;
26    import com.puppycrawl.tools.checkstyle.api.DetailAST;
27    import com.puppycrawl.tools.checkstyle.api.FullIdent;
28    import com.puppycrawl.tools.checkstyle.api.TokenTypes;
29    import com.puppycrawl.tools.checkstyle.checks.CheckUtils;
30   
31    /**
32    * <p>Checks that if a class defines a covariant method equals,
33    * then it defines method equals(java.lang.Object).
34    * Inspired by findbugs,
35    * http://www.cs.umd.edu/~pugh/java/bugs/docs/findbugsPaper.pdf
36    * </p>
37    * <p>
38    * An example of how to configure the check is:
39    * </p>
40    * <pre>
41    * &lt;module name="CovariantEquals"/&gt;
42    * </pre>
43    * @author Rick Giles
44    * @version 1.0
45    */
 
46    public class CovariantEqualsCheck extends Check
47    {
48    /** Set of equals method definitions */
49    private final Set mEqualsMethods = new HashSet();
50   
51    /** {@inheritDoc} */
 
52  1 toggle public int[] getDefaultTokens()
53    {
54  1 return new int[] {TokenTypes.CLASS_DEF, TokenTypes.LITERAL_NEW, };
55    }
56   
57    /** {@inheritDoc} */
 
58  0 toggle public int[] getRequiredTokens()
59    {
60  0 return getDefaultTokens();
61    }
62   
63    /** {@inheritDoc} */
 
64  12 toggle public void visitToken(DetailAST aAST)
65    {
66  12 mEqualsMethods.clear();
67  12 boolean hasEqualsObject = false;
68   
69    // examine method definitions for equals methods
70  12 final DetailAST objBlock = aAST.findFirstToken(TokenTypes.OBJBLOCK);
71  12 if (objBlock != null) {
72  11 DetailAST child = (DetailAST) objBlock.getFirstChild();
73  54 while (child != null) {
74  43 if (child.getType() == TokenTypes.METHOD_DEF) {
75  18 if (CheckUtils.isEqualsMethod(child)) {
76  15 if (hasObjectParameter(child)) {
77  6 hasEqualsObject = true;
78    }
79    else {
80  9 mEqualsMethods.add(child);
81    }
82    }
83    }
84  43 child = (DetailAST) child.getNextSibling();
85    }
86   
87    // report equals method definitions
88  11 if (!hasEqualsObject) {
89  5 final Iterator it = mEqualsMethods.iterator();
90  9 while (it.hasNext()) {
91  4 final DetailAST equalsAST = (DetailAST) it.next();
92  4 final DetailAST nameNode =
93    equalsAST.findFirstToken(TokenTypes.IDENT);
94  4 log(
95    nameNode.getLineNo(),
96    nameNode.getColumnNo(),
97    "covariant.equals");
98    }
99    }
100    }
101    }
102   
103    /**
104    * Tests whether a method definition AST has exactly one
105    * parameter of type Object.
106    * @param aAST the method definition AST to test.
107    * Precondition: aAST is a TokenTypes.METHOD_DEF node.
108    * @return true if aAST has exactly one parameter of type Object.
109    */
 
110  15 toggle private boolean hasObjectParameter(DetailAST aAST)
111    {
112    // one parameter?
113  15 final DetailAST paramsNode = aAST.findFirstToken(TokenTypes.PARAMETERS);
114  15 if (paramsNode.getChildCount() != 1) {
115  0 return false;
116    }
117   
118    // parameter type "Object"?
119  15 final DetailAST paramNode =
120    paramsNode.findFirstToken(TokenTypes.PARAMETER_DEF);
121  15 final DetailAST typeNode = paramNode.findFirstToken(TokenTypes.TYPE);
122  15 final FullIdent fullIdent = FullIdent.createFullIdentBelow(typeNode);
123  15 final String name = fullIdent.getText();
124  15 return (name.equals("Object") || name.equals("java.lang.Object"));
125    }
126    }