KickJava   Java API By Example, From Geeks To Geeks.

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


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 com.puppycrawl.tools.checkstyle.api.DetailAST;
22 import com.puppycrawl.tools.checkstyle.api.ScopeUtils;
23 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
24 import com.puppycrawl.tools.checkstyle.checks.DeclarationCollector;
25
26 /**
27  * <p>Checks that code doesn't rely on the &quot;this&quot; default.
28  * That is references to instance variables and methods of the present
29  * object are explicitly of the form &quot;this.varName&quot; or
30  * &quot;this.methodName(args)&quot;.
31  *</p>
32  * <p>Examples of use:
33  * <pre>
34  * &lt;module name=&quot;RequireThis&quot;/&gt;
35  * </pre>
36  * An example of how to configure to check <code>this</code> qualifier for
37  * methods only:
38  * <pre>
39  * &lt;module name=&quot;RequireThis&quot;&gt;
40  * &lt;property name=&quot;checkFields&quot; value=&quot;false&quot;/&gt;
41  * &lt;property name=&quot;checkMethods&quot; value=&quot;true&quot;/&gt;
42  * &lt;/module&gt;
43  * </pre>
44  * </p>
45  * <p>Limitations: I'm not currently doing anything about static variables
46  * or catch-blocks. Static methods invoked on a class name seem to be OK;
47  * both the class name and the method name have a DOT parent.
48  * Non-static methods invoked on either this or a variable name seem to be
49  * OK, likewise.</p>
50  * <p>Much of the code for this check was cribbed from Rick Giles's
51  * <code>HiddenFieldCheck</code>.</p>
52  *
53  * @author Stephen Bloch
54  * @author o_sukhodolsky
55  */

56 public class RequireThisCheck extends DeclarationCollector
57 {
58     /** whether we should check fields usage. */
59     private boolean mCheckFields = true;
60     /** whether we should check methods usage. */
61     private boolean mCheckMethods = true;
62
63     /**
64      * Setter for checkFields property.
65      * @param aCheckFields should we check fields usage or not.
66      */

67     public void setCheckFields(boolean aCheckFields)
68     {
69         mCheckFields = aCheckFields;
70     }
71     /**
72      * @return true if we should check fields usage false overwise.
73      */

74     public boolean getCheckFields()
75     {
76         return mCheckFields;
77     }
78
79     /**
80      * Setter for checkMethods property.
81      * @param aCheckMethods should we check methods usage or not.
82      */

83     public void setCheckMethods(boolean aCheckMethods)
84     {
85         mCheckMethods = aCheckMethods;
86     }
87     /**
88      * @return true if we should check methods usage false overwise.
89      */

90     public boolean getCheckMethods()
91     {
92         return mCheckMethods;
93     }
94
95     /** Creates new instance of the check. */
96     public RequireThisCheck()
97     {
98     }
99
100     /** {@inheritDoc} */
101     public int[] getDefaultTokens()
102     {
103         return new int[] {
104             TokenTypes.CLASS_DEF,
105             TokenTypes.CTOR_DEF,
106             TokenTypes.ENUM_DEF,
107             TokenTypes.IDENT,
108             TokenTypes.INTERFACE_DEF,
109             TokenTypes.METHOD_DEF,
110             TokenTypes.PARAMETER_DEF,
111             TokenTypes.SLIST,
112             TokenTypes.VARIABLE_DEF,
113         };
114     }
115
116     /** {@inheritDoc} */
117     public int[] getRequiredTokens()
118     {
119         return getDefaultTokens();
120     }
121
122     /** {@inheritDoc} */
123     public void visitToken(DetailAST aAST)
124     {
125         super.visitToken(aAST);
126         if (aAST.getType() == TokenTypes.IDENT) {
127             processIDENT(aAST);
128         }
129     } // end visitToken
130

131     /**
132      * Checks if a given IDENT is method call or field name which
133      * require explicit <code>this</code> qualifier.
134      *
135      * @param aAST IDENT to check.
136      */

137     private void processIDENT(DetailAST aAST)
138     {
139         final int parentType = aAST.getParent().getType();
140
141         // let's check method calls
142
if (parentType == TokenTypes.METHOD_CALL) {
143             if (mCheckMethods) {
144                 log(aAST, "require.this.method", aAST.getText());
145             }
146             return;
147         }
148
149         // let's check fields
150
if (!mCheckFields) {
151             // we shouldn't check fields
152
return;
153         }
154
155         if (ScopeUtils.getSurroundingScope(aAST) == null) {
156             // it is not a class or inteface it's
157
// either import or package
158
// we shouldn't checks this
159
return;
160         }
161
162         if ((parentType == TokenTypes.DOT)
163             && (aAST.getPreviousSibling() != null))
164         {
165             // it's the method name in a method call; no problem
166
return;
167         }
168         if ((parentType == TokenTypes.TYPE)
169             || (parentType == TokenTypes.LITERAL_NEW))
170         {
171             // it's a type name; no problem
172
return;
173         }
174         if ((parentType == TokenTypes.VARIABLE_DEF)
175             || (parentType == TokenTypes.CTOR_DEF)
176             || (parentType == TokenTypes.METHOD_DEF)
177             || (parentType == TokenTypes.CLASS_DEF)
178             || (parentType == TokenTypes.ENUM_DEF)
179             || (parentType == TokenTypes.INTERFACE_DEF)
180             || (parentType == TokenTypes.PARAMETER_DEF))
181         {
182             // it's being declared; no problem
183
return;
184         }
185
186         final String JavaDoc name = aAST.getText();
187         if (isClassField(name)) {
188             log(aAST, "require.this.variable", name);
189         }
190     }
191 } // end class RequireThis
192
Popular Tags