2 * Copyright 2003-2006 Dave Griffith, Bas Leijdekkers
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.siyeh
.ipp
.exceptions
;
18 import com
.intellij
.psi
.*;
20 import java
.util
.HashSet
;
25 private ExceptionUtils(){
29 public static Set
<PsiType
> getExceptionTypesHandled(
30 PsiTryStatement statement
){
31 final Set
<PsiType
> out
= new HashSet
<PsiType
>(10);
32 final PsiParameter
[] params
= statement
.getCatchBlockParameters();
33 for(PsiParameter param
: params
){
34 final PsiType type
= param
.getType();
40 private static void calculateExceptionsThrownForStatement(
41 PsiStatement statement
,
42 Set
<PsiType
> exceptionTypes
){
43 if(statement
== null){
46 if(statement
instanceof PsiBreakStatement
||
47 statement
instanceof PsiContinueStatement
){
49 } else if(statement
instanceof PsiReturnStatement
){
50 final PsiReturnStatement returnStatement
=
51 (PsiReturnStatement
) statement
;
52 final PsiExpression returnValue
= returnStatement
.getReturnValue();
53 if(returnValue
!= null){
54 calculateExceptionsThrown(returnValue
, exceptionTypes
);
56 } else if(statement
instanceof PsiThrowStatement
){
57 final PsiThrowStatement throwStatement
=
58 (PsiThrowStatement
)statement
;
59 calculateExceptionsThrownForThrowStatement(throwStatement
,
61 } else if(statement
instanceof PsiExpressionListStatement
){
62 final PsiExpressionListStatement expressionListStatement
=
63 (PsiExpressionListStatement
) statement
;
64 calculateExceptionsThrownForExpressionListStatement(
65 expressionListStatement
, exceptionTypes
);
66 } else if(statement
instanceof PsiExpressionStatement
){
67 final PsiExpressionStatement expressionStatement
=
68 (PsiExpressionStatement
) statement
;
69 final PsiExpression expression
=
70 expressionStatement
.getExpression();
71 calculateExceptionsThrown(expression
, exceptionTypes
);
72 } else if(statement
instanceof PsiAssertStatement
){
73 final PsiAssertStatement assertStatement
=
74 (PsiAssertStatement
) statement
;
75 calculateExceptionsThrownForAssertStatement(assertStatement
,
77 } else if(statement
instanceof PsiDeclarationStatement
){
78 final PsiDeclarationStatement declarationStatement
=
79 (PsiDeclarationStatement
) statement
;
80 calculateExceptionsThrownForDeclarationStatemt(declarationStatement
,
82 } else if(statement
instanceof PsiForStatement
){
83 final PsiForStatement forStatement
= (PsiForStatement
)statement
;
84 calculateExceptionsThrownForForExpression(
85 forStatement
, exceptionTypes
);
86 } else if(statement
instanceof PsiWhileStatement
){
87 final PsiWhileStatement whileStatement
=
88 (PsiWhileStatement
)statement
;
89 calculateExceptionsThrownForWhileStatement(
90 whileStatement
, exceptionTypes
);
91 } else if(statement
instanceof PsiDoWhileStatement
){
92 final PsiDoWhileStatement doWhileStatement
=
93 (PsiDoWhileStatement
)statement
;
94 calculateExceptionsThrownForDoWhileStatement(doWhileStatement
,
96 } else if(statement
instanceof PsiSynchronizedStatement
){
97 final PsiSynchronizedStatement synchronizedStatement
=
98 (PsiSynchronizedStatement
)statement
;
99 calculateExceptionsThrownForSynchronizedStatement(
100 synchronizedStatement
, exceptionTypes
);
101 } else if(statement
instanceof PsiBlockStatement
){
102 final PsiBlockStatement block
= (PsiBlockStatement
) statement
;
103 calculateExceptionsThrownForBlockStatement(block
, exceptionTypes
);
104 } else if(statement
instanceof PsiLabeledStatement
){
105 final PsiLabeledStatement labeledStatement
=
106 (PsiLabeledStatement
) statement
;
107 calculateExceptionsThrownForLabeledStatement(labeledStatement
,
109 } else if(statement
instanceof PsiIfStatement
){
110 final PsiIfStatement ifStatement
= (PsiIfStatement
) statement
;
111 calculateExceptionsThrownForIfStatement(ifStatement
,
113 } else if(statement
instanceof PsiTryStatement
){
114 final PsiTryStatement tryStatement
= (PsiTryStatement
) statement
;
115 calculateExceptionsThrownForTryStatement(tryStatement
,
117 } else if(statement
instanceof PsiSwitchStatement
){
118 final PsiSwitchStatement switchStatement
=
119 (PsiSwitchStatement
) statement
;
120 calculateExceptionsThrownForSwitchStatement(switchStatement
,
125 private static void calculateExceptionsThrownForLabeledStatement(
126 PsiLabeledStatement labeledStatement
,
127 Set
<PsiType
> exceptionTypes
){
128 final PsiStatement statement
= labeledStatement
.getStatement();
129 calculateExceptionsThrownForStatement(statement
, exceptionTypes
);
132 private static void calculateExceptionsThrownForExpressionListStatement(
133 PsiExpressionListStatement listStatement
,
134 Set
<PsiType
> exceptionTypes
){
135 final PsiExpressionList expressionList
=
136 listStatement
.getExpressionList();
137 final PsiExpression
[] expressions
= expressionList
.getExpressions();
138 for(PsiExpression expression
: expressions
){
139 calculateExceptionsThrown(expression
, exceptionTypes
);
143 private static void calculateExceptionsThrownForDeclarationStatemt(
144 PsiDeclarationStatement declarationStatement
,
145 Set
<PsiType
> exceptionTypes
){
146 final PsiElement
[] elements
=
147 declarationStatement
.getDeclaredElements();
148 for(PsiElement element
: elements
){
149 if (element
instanceof PsiVariable
) {
150 final PsiVariable var
= (PsiVariable
) element
;
151 final PsiExpression initializer
= var
.getInitializer();
152 if(initializer
!= null){
153 calculateExceptionsThrown(initializer
, exceptionTypes
);
159 private static void calculateExceptionsThrownForAssertStatement(
160 PsiAssertStatement assertStatement
,
161 Set
<PsiType
> exceptionTypes
) {
162 final PsiExpression assertCondition
=
163 assertStatement
.getAssertCondition();
164 calculateExceptionsThrown(assertCondition
, exceptionTypes
);
165 final PsiExpression assertDescription
=
166 assertStatement
.getAssertDescription();
167 calculateExceptionsThrown(assertDescription
, exceptionTypes
);
170 private static void calculateExceptionsThrownForThrowStatement(
171 PsiThrowStatement throwStatement
,
172 Set
<PsiType
> exceptionTypes
){
173 final PsiExpression exception
= throwStatement
.getException();
174 if(exception
== null){
177 final PsiType type
= exception
.getType();
179 exceptionTypes
.add(type
);
181 calculateExceptionsThrown(exception
, exceptionTypes
);
184 private static void calculateExceptionsThrownForSwitchStatement(
185 PsiSwitchStatement switchStatement
,
186 Set
<PsiType
> exceptionTypes
){
187 final PsiExpression switchExpression
= switchStatement
.getExpression();
188 calculateExceptionsThrown(switchExpression
, exceptionTypes
);
189 final PsiCodeBlock body
= switchStatement
.getBody();
190 calculateExceptionsThrownForCodeBlock(body
, exceptionTypes
);
193 private static void calculateExceptionsThrownForTryStatement(
194 PsiTryStatement tryStatement
,
195 Set
<PsiType
> exceptionTypes
){
196 final Set
<PsiType
> exceptionThrown
= new HashSet
<PsiType
>(10);
197 final PsiCodeBlock tryBlock
= tryStatement
.getTryBlock();
198 calculateExceptionsThrownForCodeBlock(tryBlock
, exceptionThrown
);
199 final Set
<PsiType
> exceptionHandled
=
200 getExceptionTypesHandled(tryStatement
);
201 for(PsiType thrownType
: exceptionThrown
){
202 boolean found
= false;
203 for(PsiType handledType
: exceptionHandled
){
204 if(handledType
.isAssignableFrom(thrownType
)){
210 exceptionTypes
.add(thrownType
);
213 final PsiCodeBlock finallyBlock
= tryStatement
.getFinallyBlock();
214 if(finallyBlock
!= null){
215 calculateExceptionsThrownForCodeBlock(finallyBlock
, exceptionTypes
);
217 final PsiCodeBlock
[] catchBlocks
= tryStatement
.getCatchBlocks();
218 for(PsiCodeBlock catchBlock
: catchBlocks
){
219 calculateExceptionsThrownForCodeBlock(catchBlock
, exceptionTypes
);
223 private static void calculateExceptionsThrownForIfStatement(
224 PsiIfStatement ifStatement
,
225 Set
<PsiType
> exceptionTypes
){
226 final PsiExpression condition
= ifStatement
.getCondition();
227 final PsiStatement thenBranch
= ifStatement
.getThenBranch();
228 final PsiStatement elseBranch
= ifStatement
.getElseBranch();
229 calculateExceptionsThrown(condition
, exceptionTypes
);
230 calculateExceptionsThrownForStatement(thenBranch
, exceptionTypes
);
231 calculateExceptionsThrownForStatement(elseBranch
, exceptionTypes
);
234 private static void calculateExceptionsThrownForBlockStatement(
235 PsiBlockStatement block
,
236 Set
<PsiType
> exceptionTypes
){
237 final PsiCodeBlock codeBlock
= block
.getCodeBlock();
238 calculateExceptionsThrownForCodeBlock(codeBlock
, exceptionTypes
);
241 private static void calculateExceptionsThrownForSynchronizedStatement(
242 PsiSynchronizedStatement synchronizedStatement
,
243 Set
<PsiType
> exceptionTypes
){
244 final PsiExpression lockExpression
=
245 synchronizedStatement
.getLockExpression();
246 if(lockExpression
!= null){
247 calculateExceptionsThrown(lockExpression
, exceptionTypes
);
249 final PsiCodeBlock body
= synchronizedStatement
.getBody();
250 calculateExceptionsThrownForCodeBlock(body
, exceptionTypes
);
253 private static void calculateExceptionsThrownForDoWhileStatement(
254 PsiDoWhileStatement loopStatement
,
255 Set
<PsiType
> exceptionTypes
){
256 final PsiExpression condition
= loopStatement
.getCondition();
257 calculateExceptionsThrown(condition
, exceptionTypes
);
258 final PsiStatement body
= loopStatement
.getBody();
259 calculateExceptionsThrownForStatement(body
, exceptionTypes
);
262 private static void calculateExceptionsThrownForWhileStatement(
263 PsiWhileStatement loopStatement
,
264 Set
<PsiType
> exceptionTypes
){
265 final PsiExpression condition
= loopStatement
.getCondition();
266 calculateExceptionsThrown(condition
, exceptionTypes
);
267 final PsiStatement body
= loopStatement
.getBody();
268 calculateExceptionsThrownForStatement(body
, exceptionTypes
);
271 private static void calculateExceptionsThrownForForExpression(
272 PsiForStatement loopStatement
,
273 Set
<PsiType
> exceptionTypes
){
274 final PsiStatement initialization
= loopStatement
.getInitialization();
275 final PsiExpression condition
= loopStatement
.getCondition();
276 final PsiStatement update
= loopStatement
.getUpdate();
277 final PsiStatement body
= loopStatement
.getBody();
278 calculateExceptionsThrownForStatement(initialization
, exceptionTypes
);
279 calculateExceptionsThrown(condition
, exceptionTypes
);
280 calculateExceptionsThrownForStatement(update
, exceptionTypes
);
281 calculateExceptionsThrownForStatement(body
, exceptionTypes
);
284 private static void calculateExceptionsThrown(PsiExpression expression
,
285 Set
<PsiType
> exceptionTypes
){
286 if(expression
== null){
289 if(expression
instanceof PsiThisExpression
||
290 expression
instanceof PsiLiteralExpression
||
291 expression
instanceof PsiSuperExpression
||
292 expression
instanceof PsiClassObjectAccessExpression
){
293 } else if(expression
instanceof PsiTypeCastExpression
){
294 final PsiTypeCastExpression typeCastExpression
=
295 (PsiTypeCastExpression
)expression
;
296 calculateExceptionsThrownForTypeCast(typeCastExpression
,
298 } else if(expression
instanceof PsiInstanceOfExpression
){
299 final PsiInstanceOfExpression instanceOfExpression
=
300 (PsiInstanceOfExpression
)expression
;
301 calculateExceptionsThrownForInstanceOf(instanceOfExpression
,
303 } else if(expression
instanceof PsiReferenceExpression
){
304 final PsiReferenceExpression referenceExpression
=
305 (PsiReferenceExpression
) expression
;
306 final PsiExpression qualifier
=
307 referenceExpression
.getQualifierExpression();
308 if(qualifier
!= null){
309 calculateExceptionsThrown(qualifier
, exceptionTypes
);
311 } else if(expression
instanceof PsiMethodCallExpression
){
312 final PsiMethodCallExpression methodCallExpression
=
313 (PsiMethodCallExpression
)expression
;
314 calculateExceptionsThrownForMethodCall(methodCallExpression
,
316 } else if(expression
instanceof PsiNewExpression
){
317 final PsiNewExpression newExpression
= (PsiNewExpression
)expression
;
318 calculateExceptionsThrownForNewExpression(newExpression
,
320 } else if(expression
instanceof PsiArrayInitializerExpression
){
321 final PsiArrayInitializerExpression arrayInitializerExpression
=
322 (PsiArrayInitializerExpression
)expression
;
323 calculateExceptionsThrownForArrayInitializerExpression(
324 arrayInitializerExpression
, exceptionTypes
);
325 } else if(expression
instanceof PsiArrayAccessExpression
){
326 final PsiArrayAccessExpression arrayAccessExpression
=
327 (PsiArrayAccessExpression
)expression
;
328 calculateExceptionsThrownForArrayAccessExpression(
329 arrayAccessExpression
, exceptionTypes
);
330 } else if(expression
instanceof PsiPrefixExpression
){
331 final PsiPrefixExpression prefixExpression
=
332 (PsiPrefixExpression
)expression
;
333 calculateExceptionsThrownForPrefixException(prefixExpression
,
335 } else if(expression
instanceof PsiPostfixExpression
){
336 final PsiPostfixExpression postfixExpression
=
337 (PsiPostfixExpression
)expression
;
338 calculateExceptionsThrownForPostixExpression(postfixExpression
,
340 } else if(expression
instanceof PsiBinaryExpression
){
341 final PsiBinaryExpression binaryExpression
=
342 (PsiBinaryExpression
)expression
;
343 calculateExceptionsThrownForBinaryExpression(binaryExpression
,
345 } else if(expression
instanceof PsiAssignmentExpression
){
346 final PsiAssignmentExpression assignmentExpression
=
347 (PsiAssignmentExpression
)expression
;
348 calculateExceptionsThrownForAssignmentExpression(
349 assignmentExpression
, exceptionTypes
);
350 } else if(expression
instanceof PsiConditionalExpression
){
351 final PsiConditionalExpression conditionalExpression
=
352 (PsiConditionalExpression
)expression
;
353 calculateExceptionsThrownForConditionalExcpression(
354 conditionalExpression
, exceptionTypes
);
358 private static void calculateExceptionsThrownForTypeCast(
359 PsiTypeCastExpression typeCastExpression
,
360 Set
<PsiType
> exceptionTypes
){
361 final PsiExpression operand
= typeCastExpression
.getOperand();
362 calculateExceptionsThrown(operand
, exceptionTypes
);
365 private static void calculateExceptionsThrownForInstanceOf(
366 PsiInstanceOfExpression instanceOfExpression
,
367 Set
<PsiType
> exceptionTypes
){
368 final PsiExpression operand
= instanceOfExpression
.getOperand();
369 calculateExceptionsThrown(operand
, exceptionTypes
);
372 private static void calculateExceptionsThrownForNewExpression(
373 PsiNewExpression newExpression
, Set
<PsiType
> exceptionTypes
){
374 final PsiExpressionList argumentList
= newExpression
.getArgumentList();
375 if(argumentList
!= null){
376 final PsiExpression
[] args
= argumentList
.getExpressions();
377 for(PsiExpression arg
: args
){
378 calculateExceptionsThrown(arg
, exceptionTypes
);
381 final PsiExpression
[] arrayDims
= newExpression
.getArrayDimensions();
382 for(PsiExpression arrayDim
: arrayDims
){
383 calculateExceptionsThrown(arrayDim
, exceptionTypes
);
385 final PsiExpression qualifier
= newExpression
.getQualifier();
386 calculateExceptionsThrown(qualifier
, exceptionTypes
);
387 final PsiArrayInitializerExpression arrayInitializer
=
388 newExpression
.getArrayInitializer();
389 calculateExceptionsThrown(arrayInitializer
, exceptionTypes
);
390 final PsiMethod method
= newExpression
.resolveMethod();
392 final PsiReferenceList throwsList
= method
.getThrowsList();
393 final PsiJavaCodeReferenceElement
[] list
=
394 throwsList
.getReferenceElements();
395 for(final PsiJavaCodeReferenceElement referenceElement
: list
){
396 final PsiClass exceptionClass
=
397 (PsiClass
) referenceElement
.resolve();
398 if(exceptionClass
!= null){
399 final PsiManager psiManager
= exceptionClass
.getManager();
400 final PsiElementFactory factory
= JavaPsiFacade
.getInstance(psiManager
.getProject()).getElementFactory();
401 final PsiClassType exceptionType
=
402 factory
.createType(exceptionClass
);
403 exceptionTypes
.add(exceptionType
);
409 private static void calculateExceptionsThrownForMethodCall(
410 PsiMethodCallExpression methodCallExpression
,
411 Set
<PsiType
> exceptionTypes
){
412 final PsiExpressionList argumentList
=
413 methodCallExpression
.getArgumentList();
414 final PsiExpression
[] expressions
= argumentList
.getExpressions();
415 for(PsiExpression expression
: expressions
){
416 calculateExceptionsThrown(expression
, exceptionTypes
);
418 final PsiReferenceExpression methodExpression
=
419 methodCallExpression
.getMethodExpression();
420 calculateExceptionsThrown(methodExpression
, exceptionTypes
);
421 final PsiMethod method
= methodCallExpression
.resolveMethod();
423 final PsiReferenceList throwsList
= method
.getThrowsList();
424 final PsiJavaCodeReferenceElement
[] list
=
425 throwsList
.getReferenceElements();
426 for(final PsiJavaCodeReferenceElement referenceElement
: list
){
427 final PsiClass exceptionClass
=
428 (PsiClass
) referenceElement
.resolve();
429 if(exceptionClass
!= null){
430 final PsiManager psiManager
= exceptionClass
.getManager();
431 final PsiElementFactory factory
= JavaPsiFacade
.getInstance(psiManager
.getProject()).getElementFactory();
432 final PsiClassType exceptionType
=
433 factory
.createType(exceptionClass
);
434 exceptionTypes
.add(exceptionType
);
440 private static void calculateExceptionsThrownForConditionalExcpression(
441 PsiConditionalExpression conditionalExpression
,
442 Set
<PsiType
> exceptionTypes
){
443 final PsiExpression condition
= conditionalExpression
.getCondition();
444 final PsiExpression elseExpression
=
445 conditionalExpression
.getElseExpression();
446 final PsiExpression thenExpression
=
447 conditionalExpression
.getThenExpression();
448 calculateExceptionsThrown(condition
, exceptionTypes
);
449 calculateExceptionsThrown(elseExpression
, exceptionTypes
);
450 calculateExceptionsThrown(thenExpression
, exceptionTypes
);
453 private static void calculateExceptionsThrownForBinaryExpression(
454 PsiBinaryExpression binaryExpression
,
455 Set
<PsiType
> exceptionTypes
){
456 final PsiExpression lOperand
= binaryExpression
.getLOperand();
457 calculateExceptionsThrown(lOperand
, exceptionTypes
);
458 final PsiExpression rhs
= binaryExpression
.getROperand();
459 calculateExceptionsThrown(rhs
, exceptionTypes
);
462 private static void calculateExceptionsThrownForAssignmentExpression(
463 PsiAssignmentExpression assignmentExpression
,
464 Set
<PsiType
> exceptionTypes
){
465 final PsiExpression lOperand
= assignmentExpression
.getLExpression();
466 calculateExceptionsThrown(lOperand
, exceptionTypes
);
467 final PsiExpression rhs
= assignmentExpression
.getRExpression();
468 calculateExceptionsThrown(rhs
, exceptionTypes
);
471 private static void calculateExceptionsThrownForArrayInitializerExpression(
472 PsiArrayInitializerExpression arrayInitializerExpression
,
473 Set
<PsiType
> exceptionTypes
){
474 final PsiExpression
[] initializers
=
475 arrayInitializerExpression
.getInitializers();
476 for(PsiExpression initializer
: initializers
){
477 calculateExceptionsThrown(initializer
, exceptionTypes
);
481 private static void calculateExceptionsThrownForArrayAccessExpression(
482 PsiArrayAccessExpression arrayAccessExpression
,
483 Set
<PsiType
> exceptionTypes
){
484 final PsiExpression arrayExpression
=
485 arrayAccessExpression
.getArrayExpression();
486 calculateExceptionsThrown(arrayExpression
, exceptionTypes
);
487 final PsiExpression indexExpression
=
488 arrayAccessExpression
.getIndexExpression();
489 calculateExceptionsThrown(indexExpression
, exceptionTypes
);
492 private static void calculateExceptionsThrownForPrefixException(
493 PsiPrefixExpression prefixExpression
,
494 Set
<PsiType
> exceptionTypes
){
495 final PsiExpression operand
= prefixExpression
.getOperand();
496 calculateExceptionsThrown(operand
, exceptionTypes
);
499 private static void calculateExceptionsThrownForPostixExpression(
500 PsiPostfixExpression postfixExpression
,
501 Set
<PsiType
> exceptionTypes
){
502 final PsiExpression operand
= postfixExpression
.getOperand();
503 calculateExceptionsThrown(operand
, exceptionTypes
);
506 public static void calculateExceptionsThrownForCodeBlock(
507 PsiCodeBlock codeBlock
, Set
<PsiType
> exceptionTypes
){
508 if(codeBlock
== null){
511 final PsiStatement
[] statements
= codeBlock
.getStatements();
512 for(PsiStatement statement
: statements
){
513 calculateExceptionsThrownForStatement(statement
, exceptionTypes
);