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/blocks/EmptyBlockCheck.java


1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2003  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.blocks;
20  
21  import com.puppycrawl.tools.checkstyle.api.DetailAST;
22  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
23  import com.puppycrawl.tools.checkstyle.checks.AbstractOptionCheck;
24  
25  /**
26   * Checks for empty blocks. The policy to verify is specified using the {@link
27   * BlockOption} class and defaults to {@link BlockOption#STMT}.
28   *
29   * <p> By default the check will check the following blocks:
30   *  {@link TokenTypes#LITERAL_WHILE LITERAL_WHILE},
31   *  {@link TokenTypes#LITERAL_TRY LITERAL_TRY},
32   *  {@link TokenTypes#LITERAL_CATCH LITERAL_CATCH},
33   *  {@link TokenTypes#LITERAL_FINALLY LITERAL_FINALLY},
34   *  {@link TokenTypes#LITERAL_DO LITERAL_DO},
35   *  {@link TokenTypes#LITERAL_IF LITERAL_IF},
36   *  {@link TokenTypes#LITERAL_ELSE LITERAL_ELSE},
37   *  {@link TokenTypes#LITERAL_FOR LITERAL_FOR},
38   *  {@link TokenTypes#STATIC_INIT STATIC_INIT}.
39   *
40   * <p> An example of how to configure the check is:
41   * <pre>
42   * &lt;module name="EmptyBlock"/&gt;
43   * </pre>
44   *
45   * <p> An example of how to configure the check for the {@link
46   * BlockOption#TEXT} policy and only catch blocks is:
47   *
48   * <pre>
49   * &lt;module name="EmptyBlock"&gt;
50   *    &lt;property name="tokens" value="LITERAL_CATCH"/&gt;
51   *    &lt;property name="option" value="text"/&gt;
52   * &lt;/module&gt;
53   * </pre>
54   *
55   * @author Lars Kühne
56   */
57  public class EmptyBlockCheck
58      extends AbstractOptionCheck
59  {
60      /**
61       * Creates a new <code>EmptyBlockCheck</code> instance.
62       */
63      public EmptyBlockCheck()
64      {
65          super(BlockOption.STMT);
66      }
67  
68      /** @see com.puppycrawl.tools.checkstyle.api.Check */
69      public int[] getDefaultTokens()
70      {
71          return new int[] {
72              TokenTypes.LITERAL_WHILE,
73              TokenTypes.LITERAL_TRY,
74              TokenTypes.LITERAL_CATCH,
75              TokenTypes.LITERAL_FINALLY,
76              TokenTypes.LITERAL_DO,
77              TokenTypes.LITERAL_IF,
78              TokenTypes.LITERAL_ELSE,
79              TokenTypes.LITERAL_FOR,
80              TokenTypes.INSTANCE_INIT,
81              TokenTypes.STATIC_INIT,
82              // TODO: need to handle....
83              //TokenTypes.LITERAL_SWITCH,
84              //TODO: does this handle TokenTypes.LITERAL_SYNCHRONIZED?
85          };
86      }
87  
88      /** @see com.puppycrawl.tools.checkstyle.api.Check */
89      public void visitToken(DetailAST aAST)
90      {
91          final DetailAST slistAST = aAST.findFirstToken(TokenTypes.SLIST);
92          if (slistAST != null) {
93              if (getAbstractOption() == BlockOption.STMT) {
94                  if (slistAST.getChildCount() <= 1) {
95                      log(slistAST.getLineNo(),
96                          slistAST.getColumnNo(),
97                          "block.noStmt",
98                          aAST.getText());
99                  }
100             }
101             else if (getAbstractOption() == BlockOption.TEXT) {
102                 if (!hasText(slistAST)) {
103                     log(slistAST.getLineNo(),
104                         slistAST.getColumnNo(),
105                         "block.empty",
106                         aAST.getText());
107                 }
108             }
109         }
110     }
111 
112     /**
113      * @param aSlistAST a <code>DetailAST</code> value
114      * @return whether the SLIST token contains any text.
115      */
116     private boolean hasText(final DetailAST aSlistAST)
117     {
118         boolean retVal = false;
119 
120         final DetailAST rcurlyAST = aSlistAST.findFirstToken(TokenTypes.RCURLY);
121         if (rcurlyAST != null) {
122             final int slistLineNo = aSlistAST.getLineNo();
123             final int slistColNo = aSlistAST.getColumnNo();
124             final int rcurlyLineNo = rcurlyAST.getLineNo();
125             final int rcurlyColNo = rcurlyAST.getColumnNo();
126             final String[] lines = getLines();
127             if (slistLineNo == rcurlyLineNo) {
128                 // Handle braces on the same line
129                 final String txt = lines[slistLineNo - 1]
130                     .substring(slistColNo + 1, rcurlyColNo);
131                 if (txt.trim().length() != 0) {
132                     retVal = true;
133                 }
134             }
135             else {
136                 // check only whitespace of first & last lines
137                 if ((lines[slistLineNo - 1]
138                      .substring(slistColNo + 1).trim().length() != 0)
139                     || (lines[rcurlyLineNo - 1]
140                         .substring(0, rcurlyColNo).trim().length() != 0))
141                 {
142                     retVal = true;
143                 }
144                 else {
145                     // check if all lines are also only whitespace
146                     for (int i = slistLineNo; i < (rcurlyLineNo - 1); i++) {
147                         if (lines[i].trim().length() > 0) {
148                             retVal = true;
149                             break;
150                         }
151                     }
152                 }
153             }
154         }
155         return retVal;
156     }
157 }