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.coding; |
20 | |
|
21 | |
import com.google.common.collect.Lists; |
22 | |
import com.puppycrawl.tools.checkstyle.api.DetailAST; |
23 | |
import com.puppycrawl.tools.checkstyle.api.FullIdent; |
24 | |
import com.puppycrawl.tools.checkstyle.api.TokenTypes; |
25 | |
import com.puppycrawl.tools.checkstyle.checks.AbstractTypeAwareCheck; |
26 | |
import java.util.Iterator; |
27 | |
import java.util.List; |
28 | |
|
29 | |
|
30 | |
|
31 | |
|
32 | |
|
33 | |
|
34 | |
|
35 | |
|
36 | |
|
37 | |
|
38 | |
|
39 | |
|
40 | |
|
41 | |
|
42 | |
|
43 | |
|
44 | |
|
45 | 10 | public class RedundantThrowsCheck extends AbstractTypeAwareCheck |
46 | |
{ |
47 | |
|
48 | |
|
49 | |
|
50 | |
|
51 | |
private boolean mAllowUnchecked; |
52 | |
|
53 | |
|
54 | |
|
55 | |
|
56 | |
|
57 | |
private boolean mAllowSubclasses; |
58 | |
|
59 | |
|
60 | |
|
61 | |
|
62 | |
|
63 | |
|
64 | |
public void setAllowUnchecked(boolean aAllowUnchecked) |
65 | |
{ |
66 | 2 | mAllowUnchecked = aAllowUnchecked; |
67 | 2 | } |
68 | |
|
69 | |
|
70 | |
|
71 | |
|
72 | |
|
73 | |
|
74 | |
public void setAllowSubclasses(boolean aAllowSubclasses) |
75 | |
{ |
76 | 2 | mAllowSubclasses = aAllowSubclasses; |
77 | 2 | } |
78 | |
|
79 | |
@Override |
80 | |
public int[] getDefaultTokens() |
81 | |
{ |
82 | 10 | return new int[] { |
83 | |
TokenTypes.PACKAGE_DEF, |
84 | |
TokenTypes.IMPORT, |
85 | |
TokenTypes.CLASS_DEF, |
86 | |
TokenTypes.ENUM_DEF, |
87 | |
TokenTypes.METHOD_DEF, |
88 | |
TokenTypes.CTOR_DEF, |
89 | |
}; |
90 | |
} |
91 | |
|
92 | |
@Override |
93 | |
protected final void processAST(DetailAST aAST) |
94 | |
{ |
95 | 46 | final List<ClassInfo> knownExcs = Lists.newLinkedList(); |
96 | 46 | final DetailAST throwsAST = |
97 | |
aAST.findFirstToken(TokenTypes.LITERAL_THROWS); |
98 | 46 | if (throwsAST != null) { |
99 | 39 | DetailAST child = throwsAST.getFirstChild(); |
100 | 120 | while (child != null) { |
101 | 81 | if ((child.getType() == TokenTypes.IDENT) |
102 | |
|| (child.getType() == TokenTypes.DOT)) |
103 | |
{ |
104 | 60 | final FullIdent fi = FullIdent.createFullIdent(child); |
105 | 60 | checkException(fi, knownExcs); |
106 | |
} |
107 | 81 | child = child.getNextSibling(); |
108 | |
} |
109 | |
} |
110 | 46 | } |
111 | |
|
112 | |
@Override |
113 | |
protected final void logLoadError(Token aIdent) |
114 | |
{ |
115 | 0 | logLoadErrorImpl(aIdent.getLineNo(), aIdent.getColumnNo(), |
116 | |
"redundant.throws.classInfo", aIdent.getText()); |
117 | 0 | } |
118 | |
|
119 | |
|
120 | |
|
121 | |
|
122 | |
|
123 | |
|
124 | |
|
125 | |
|
126 | |
|
127 | |
|
128 | |
|
129 | |
|
130 | |
|
131 | |
private void checkException(FullIdent aExc, List<ClassInfo> aKnownExcs) |
132 | |
{ |
133 | |
|
134 | 60 | final ClassInfo newClassInfo = |
135 | |
createClassInfo(new Token(aExc), getCurrentClassName()); |
136 | |
|
137 | 60 | if (!mAllowUnchecked && isUnchecked(newClassInfo.getClazz())) { |
138 | 13 | log(aExc.getLineNo(), aExc.getColumnNo(), |
139 | |
"redundant.throws.unchecked", aExc.getText()); |
140 | |
} |
141 | |
|
142 | 60 | boolean shouldAdd = true; |
143 | 60 | for (final Iterator<ClassInfo> known = aKnownExcs.iterator(); known |
144 | 81 | .hasNext();) |
145 | |
{ |
146 | 21 | final ClassInfo ci = known.next(); |
147 | 21 | final Token fi = ci.getName(); |
148 | |
|
149 | 21 | if (ci.getClazz() == newClassInfo.getClazz()) { |
150 | 5 | shouldAdd = false; |
151 | 5 | log(aExc.getLineNo(), aExc.getColumnNo(), |
152 | |
"redundant.throws.duplicate", aExc.getText()); |
153 | |
} |
154 | 16 | else if (!mAllowSubclasses) { |
155 | 10 | if (isSubclass(ci.getClazz(), newClassInfo.getClazz())) { |
156 | 4 | known.remove(); |
157 | 4 | log(fi.getLineNo(), fi.getColumnNo(), |
158 | |
"redundant.throws.subclass", |
159 | |
fi.getText(), aExc.getText()); |
160 | |
} |
161 | 6 | else if (isSubclass(newClassInfo.getClazz(), ci.getClazz())) { |
162 | 3 | shouldAdd = false; |
163 | 3 | log(aExc.getLineNo(), aExc.getColumnNo(), |
164 | |
"redundant.throws.subclass", |
165 | |
aExc.getText(), fi.getText()); |
166 | |
} |
167 | |
} |
168 | 21 | } |
169 | |
|
170 | 60 | if (shouldAdd) { |
171 | 52 | aKnownExcs.add(newClassInfo); |
172 | |
} |
173 | 60 | } |
174 | |
} |