Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/puppycrawl/tools/checkstyle/checks/HiddenFieldCheck.java


1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2002  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;
20  
21  import java.util.HashSet;
22  import java.util.Iterator;
23  import java.util.LinkedList;
24  
25  import com.puppycrawl.tools.checkstyle.api.Check;
26  import com.puppycrawl.tools.checkstyle.api.DetailAST;
27  import com.puppycrawl.tools.checkstyle.api.ScopeUtils;
28  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
29  
30  /**
31   * <p>Checks that a local variable or a parameter does not shadow
32   * a field that is defined in the same class.
33   * </p>
34   * <p>
35   * An example of how to configure the check is:
36   * </p>
37   * <pre>
38   * &lt;module name="HiddenField"/&gt;
39   * </pre>
40   * <p>
41   * An example of how to configure the check so that it checks variables but not
42   * parameters is:
43   * </p>
44   * <pre>
45   * &lt;module name="HiddenField"&gt;
46   *    &lt;property name="tokens" value="VARIABLE_DEF"/&gt;
47   * &lt;/module&gt;
48   * </pre>
49   * @author Rick Giles
50   * @version 1.0
51   */
52  public class HiddenFieldCheck
53      extends Check
54  {
55  
56      /** stack of sets of field names,
57       * one for each class of a set of nested classes */
58      private LinkedList mFieldsStack = null;
59  
60      /** @see com.puppycrawl.tools.checkstyle.api.Check */
61      public int[] getDefaultTokens()
62      {
63          return new int[] {
64              TokenTypes.VARIABLE_DEF,
65              TokenTypes.PARAMETER_DEF,
66              TokenTypes.CLASS_DEF,
67          };
68      }
69      
70      /** @see com.puppycrawl.tools.checkstyle.api.Check */
71      public int[] getAcceptableTokens()
72      {
73          return new int[] {
74              TokenTypes.VARIABLE_DEF,
75              TokenTypes.PARAMETER_DEF,
76          };
77      }
78      
79      /** @see com.puppycrawl.tools.checkstyle.api.Check */
80      public int[] getRequiredTokens()
81      {
82          return new int[] {
83              TokenTypes.CLASS_DEF,
84          };
85      }
86  
87      /** @see com.puppycrawl.tools.checkstyle.api.Check */
88      public void beginTree()
89      {
90          mFieldsStack = new LinkedList();
91      }
92  
93      /** @see com.puppycrawl.tools.checkstyle.api.Check */
94      public void visitToken(DetailAST aAST)
95      {
96          if (aAST.getType() == TokenTypes.CLASS_DEF) {
97              //find and push fields
98              final HashSet fieldSet = new HashSet(); //fields container
99              //add fields to container
100             final DetailAST objBlock =
101                 aAST.findFirstToken(TokenTypes.OBJBLOCK);
102             DetailAST child = (DetailAST) objBlock.getFirstChild();
103             while (child != null) {
104                 if (child.getType() == TokenTypes.VARIABLE_DEF) {
105                     final String name =
106                         child.findFirstToken(TokenTypes.IDENT).getText();
107                     fieldSet.add(name);
108                 }
109                 child = (DetailAST) child.getNextSibling();
110             }                
111             mFieldsStack.addLast(fieldSet); //push container              
112         }
113         else {
114             //must be VARIABLE_DEF or PARAMETER_DEF
115             processVariable(aAST);
116         }
117     }
118 
119     /** @see com.puppycrawl.tools.checkstyle.api.Check */
120     public void leaveToken(DetailAST aAST)
121     {
122         if (aAST.getType() == TokenTypes.CLASS_DEF) {
123             //pop
124             mFieldsStack.removeLast();
125         }
126     }
127 
128     /**
129      * Process a variable token.
130      * Check whether a local variable or parameter shadows a field.
131      * Store a field for later comparison with local variables and parameters.
132      * @param aAST the variable token.
133      */
134     private void processVariable(DetailAST aAST)
135     {
136         if (!ScopeUtils.inInterfaceBlock(aAST)) {
137             if (ScopeUtils.inCodeBlock(aAST)) {
138                 //local variable or parameter. Does it shadow a field?
139                 final DetailAST nameAST = aAST.findFirstToken(TokenTypes.IDENT);
140                 final String name = nameAST.getText();
141                 final Iterator it = mFieldsStack.iterator();
142                 while (it.hasNext()) {
143                     final HashSet aFieldsSet = (HashSet) it.next();
144                     if (aFieldsSet.contains(name)) {
145                         log(nameAST.getLineNo(), nameAST.getColumnNo(),
146                             "hidden.field", name);
147                         break;
148                     }
149                 }
150             }
151         }
152     }
153  }