1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 public class EmptyBlockCheck
61 extends AbstractOptionCheck<BlockOption>
62 {
63
64
65
66
67 public static final String MSG_KEY_BLOCK_NO_STMT = "block.noStmt";
68
69
70
71
72
73 public static final String MSG_KEY_BLOCK_EMPTY = "block.empty";
74
75
76
77
78 public EmptyBlockCheck()
79 {
80 super(BlockOption.STMT, BlockOption.class);
81 }
82
83 @Override
84 public int[] getDefaultTokens()
85 {
86 return new int[] {
87 TokenTypes.LITERAL_WHILE,
88 TokenTypes.LITERAL_TRY,
89 TokenTypes.LITERAL_FINALLY,
90 TokenTypes.LITERAL_DO,
91 TokenTypes.LITERAL_IF,
92 TokenTypes.LITERAL_ELSE,
93 TokenTypes.LITERAL_FOR,
94 TokenTypes.INSTANCE_INIT,
95 TokenTypes.STATIC_INIT,
96 TokenTypes.LITERAL_SWITCH,
97
98 };
99 }
100
101 @Override
102 public int[] getAcceptableTokens()
103 {
104 return new int[] {
105 TokenTypes.LITERAL_WHILE,
106 TokenTypes.LITERAL_TRY,
107 TokenTypes.LITERAL_CATCH,
108 TokenTypes.LITERAL_FINALLY,
109 TokenTypes.LITERAL_DO,
110 TokenTypes.LITERAL_IF,
111 TokenTypes.LITERAL_ELSE,
112 TokenTypes.LITERAL_FOR,
113 TokenTypes.INSTANCE_INIT,
114 TokenTypes.STATIC_INIT,
115 TokenTypes.LITERAL_SWITCH,
116 TokenTypes.LITERAL_CASE,
117 TokenTypes.LITERAL_SWITCH,
118 TokenTypes.LITERAL_DEFAULT,
119 TokenTypes.ARRAY_INIT,
120
121 };
122 }
123
124 @Override
125 public void visitToken(DetailAST ast)
126 {
127 final DetailAST slistToken = ast.findFirstToken(TokenTypes.SLIST);
128 final DetailAST leftCurly = slistToken != null
129 ? slistToken : ast.findFirstToken(TokenTypes.LCURLY);
130 if (leftCurly != null) {
131 if (getAbstractOption() == BlockOption.STMT) {
132 boolean emptyBlock;
133 if (leftCurly.getType() == TokenTypes.LCURLY) {
134 emptyBlock = leftCurly.getNextSibling().getType() != TokenTypes.CASE_GROUP;
135 }
136 else {
137 emptyBlock = leftCurly.getChildCount() <= 1;
138 }
139 if (emptyBlock) {
140 log(leftCurly.getLineNo(),
141 leftCurly.getColumnNo(),
142 MSG_KEY_BLOCK_NO_STMT,
143 ast.getText());
144 }
145 }
146 else if (getAbstractOption() == BlockOption.TEXT
147 && !hasText(leftCurly))
148 {
149 log(leftCurly.getLineNo(),
150 leftCurly.getColumnNo(),
151 MSG_KEY_BLOCK_EMPTY,
152 ast.getText());
153 }
154 }
155 }
156
157
158
159
160
161 protected boolean hasText(final DetailAST slistAST)
162 {
163 boolean retVal = false;
164
165 final DetailAST rightCurly = slistAST.findFirstToken(TokenTypes.RCURLY);
166 final DetailAST rcurlyAST = rightCurly != null
167 ? rightCurly : slistAST.getParent().findFirstToken(TokenTypes.RCURLY);
168 if (rcurlyAST != null) {
169 final int slistLineNo = slistAST.getLineNo();
170 final int slistColNo = slistAST.getColumnNo();
171 final int rcurlyLineNo = rcurlyAST.getLineNo();
172 final int rcurlyColNo = rcurlyAST.getColumnNo();
173 final String[] lines = getLines();
174 if (slistLineNo == rcurlyLineNo) {
175
176 final String txt = lines[slistLineNo - 1]
177 .substring(slistColNo + 1, rcurlyColNo);
178 if (txt.trim().length() != 0) {
179 retVal = true;
180 }
181 }
182 else {
183
184 if (lines[slistLineNo - 1]
185 .substring(slistColNo + 1).trim().length() != 0
186 || lines[rcurlyLineNo - 1]
187 .substring(0, rcurlyColNo).trim().length() != 0)
188 {
189 retVal = true;
190 }
191 else {
192
193 for (int i = slistLineNo; i < rcurlyLineNo - 1; i++) {
194 if (lines[i].trim().length() > 0) {
195 retVal = true;
196 break;
197 }
198 }
199 }
200 }
201 }
202 return retVal;
203 }
204 }