KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > puppycrawl > tools > checkstyle > checks > coding > CovariantEqualsCheck


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 JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.Set JavaDoc;
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 JavaDoc mEqualsMethods = new HashSet JavaDoc();
50
51     /** {@inheritDoc} */
52     public int[] getDefaultTokens()
53     {
54         return new int[] {TokenTypes.CLASS_DEF, TokenTypes.LITERAL_NEW, };
55     }
56
57     /** {@inheritDoc} */
58     public int[] getRequiredTokens()
59     {
60         return getDefaultTokens();
61     }
62
63     /** {@inheritDoc} */
64     public void visitToken(DetailAST aAST)
65     {
66         mEqualsMethods.clear();
67         boolean hasEqualsObject = false;
68
69         // examine method definitions for equals methods
70
final DetailAST objBlock = aAST.findFirstToken(TokenTypes.OBJBLOCK);
71         if (objBlock != null) {
72             DetailAST child = (DetailAST) objBlock.getFirstChild();
73             while (child != null) {
74                 if (child.getType() == TokenTypes.METHOD_DEF) {
75                     if (CheckUtils.isEqualsMethod(child)) {
76                         if (hasObjectParameter(child)) {
77                             hasEqualsObject = true;
78                         }
79                         else {
80                             mEqualsMethods.add(child);
81                         }
82                     }
83                 }
84                 child = (DetailAST) child.getNextSibling();
85             }
86
87             // report equals method definitions
88
if (!hasEqualsObject) {
89                 final Iterator JavaDoc it = mEqualsMethods.iterator();
90                 while (it.hasNext()) {
91                     final DetailAST equalsAST = (DetailAST) it.next();
92                     final DetailAST nameNode =
93                         equalsAST.findFirstToken(TokenTypes.IDENT);
94                     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     private boolean hasObjectParameter(DetailAST aAST)
111     {
112         // one parameter?
113
final DetailAST paramsNode = aAST.findFirstToken(TokenTypes.PARAMETERS);
114         if (paramsNode.getChildCount() != 1) {
115             return false;
116         }
117
118         // parameter type "Object"?
119
final DetailAST paramNode =
120             paramsNode.findFirstToken(TokenTypes.PARAMETER_DEF);
121         final DetailAST typeNode = paramNode.findFirstToken(TokenTypes.TYPE);
122         final FullIdent fullIdent = FullIdent.createFullIdentBelow(typeNode);
123         final String JavaDoc name = fullIdent.getText();
124         return (name.equals("Object") || name.equals("java.lang.Object"));
125     }
126 }
127
Popular Tags