KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > puppycrawl > tools > checkstyle > checks > usage > OneMethodPrivateFieldCheck


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.usage;
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.DetailAST;
26 import com.puppycrawl.tools.checkstyle.api.Scope;
27 import com.puppycrawl.tools.checkstyle.api.ScopeUtils;
28 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
29 import com.puppycrawl.tools.checkstyle.checks.usage.transmogrify.Definition;
30 import com.puppycrawl.tools.checkstyle.checks.usage.transmogrify.Reference;
31 import com.puppycrawl.tools.checkstyle.checks.usage.transmogrify.SymTabAST;
32
33
34 /**
35  * <p>Checks that a private field is used in more than one method,
36  * constructor, or initializer.
37  * </p>
38  * <p>
39  * Rationale: a private field used in only one method, constructor, or
40  * initializer should be replaced by a local variable.
41  * </p>
42  * <p>
43  * An example of how to configure the check is:
44  * </p>
45  * <pre>
46  * &lt;module name="usage.OneMethodPrivateField"/&gt;
47  * </pre>
48  *
49  * @author Rick Giles
50  */

51 public class OneMethodPrivateFieldCheck
52     extends AbstractUsageCheck
53 {
54     /** @see com.puppycrawl.tools.checkstyle.api.Check */
55     public int[] getDefaultTokens()
56     {
57         return new int[] {
58             TokenTypes.VARIABLE_DEF,
59         };
60     }
61
62     /** @see com.puppycrawl.tools.checkstyle.checks.usage.AbstractUsageCheck */
63     public String JavaDoc getErrorKey()
64     {
65         return "one.method.private.field";
66     }
67
68     /** @see com.puppycrawl.tools.checkstyle.checks.usage.AbstractUsageCheck */
69     public boolean mustCheckReferenceCount(DetailAST aAST)
70     {
71         final DetailAST mods = aAST.findFirstToken(TokenTypes.MODIFIERS);
72         return ((mods != null)
73             && (ScopeUtils.getScopeFromMods(mods) == Scope.PRIVATE));
74     }
75
76     /** @see com.puppycrawl.tools.checkstyle.checks.usage.AbstractUsageCheck */
77     public void applyTo(Set JavaDoc aNodes)
78     {
79         // apply the check to each private field
80
final Set JavaDoc methods = new HashSet JavaDoc();
81         final Iterator JavaDoc it = aNodes.iterator();
82         while (it.hasNext()) {
83             methods.clear();
84             final DetailAST nameAST = (DetailAST) it.next();
85             // find methods using the field
86
final Iterator JavaDoc refIt = getReferences(nameAST);
87             while (refIt.hasNext()) {
88                 final Reference ref = (Reference) refIt.next();
89                 final SymTabAST refNode = ref.getTreeNode();
90                 final DetailAST refDetail = refNode.getDetailNode();
91                 // don't need to check a self-reference
92
if (refDetail == nameAST) {
93                     continue;
94                 }
95                 DetailAST parent = refDetail.getParent();
96                 while (parent != null) {
97                     final int type = parent.getType();
98                     if ((type == TokenTypes.METHOD_DEF)
99                         || (type == TokenTypes.CTOR_DEF)
100                         || (type == TokenTypes.INSTANCE_INIT)
101                         || (type == TokenTypes.STATIC_INIT))
102                     {
103                         methods.add(parent);
104                         break;
105                     }
106                     // initializer for inner class?
107
else if (type == TokenTypes.CLASS_DEF) {
108                         break;
109                     }
110                     parent = parent.getParent();
111                 }
112             }
113             if (methods.size() == 1) {
114                 log(
115                     nameAST.getLineNo(),
116                     nameAST.getColumnNo(),
117                     getErrorKey(),
118                     nameAST.getText());
119             }
120         }
121     }
122
123     /**
124      * Returns the references to an AST.
125      * @param aAST the AST for the references.
126      * @return an iterator for the references to aAST.
127      */

128     private Iterator JavaDoc getReferences(DetailAST aAST)
129     {
130         final SymTabAST ident = getASTManager().get(aAST);
131         final Definition definition =
132             (Definition) ident.getDefinition();
133         if (definition != null) {
134             return definition.getReferences();
135         }
136         final Set JavaDoc dummy = new HashSet JavaDoc();
137         return dummy.iterator();
138     }
139 }
140
Popular Tags