CCE: 17256
[fedora-idea.git] / plugins / IntentionPowerPak / src / com / siyeh / ipp / exceptions / ExceptionUtils.java
blobd8fea8fc772b3ffea7964f98f23adf8d53db5545
1 /*
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;
21 import java.util.Set;
23 class ExceptionUtils{
25 private ExceptionUtils(){
26 super();
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();
35 out.add(type);
37 return out;
40 private static void calculateExceptionsThrownForStatement(
41 PsiStatement statement,
42 Set<PsiType> exceptionTypes){
43 if(statement == null){
44 return;
46 if(statement instanceof PsiBreakStatement ||
47 statement instanceof PsiContinueStatement){
48 // don't do anything
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,
60 exceptionTypes);
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,
76 exceptionTypes);
77 } else if(statement instanceof PsiDeclarationStatement){
78 final PsiDeclarationStatement declarationStatement =
79 (PsiDeclarationStatement) statement;
80 calculateExceptionsThrownForDeclarationStatemt(declarationStatement,
81 exceptionTypes);
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,
95 exceptionTypes);
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,
108 exceptionTypes);
109 } else if(statement instanceof PsiIfStatement){
110 final PsiIfStatement ifStatement = (PsiIfStatement) statement;
111 calculateExceptionsThrownForIfStatement(ifStatement,
112 exceptionTypes);
113 } else if(statement instanceof PsiTryStatement){
114 final PsiTryStatement tryStatement = (PsiTryStatement) statement;
115 calculateExceptionsThrownForTryStatement(tryStatement,
116 exceptionTypes);
117 } else if(statement instanceof PsiSwitchStatement){
118 final PsiSwitchStatement switchStatement =
119 (PsiSwitchStatement) statement;
120 calculateExceptionsThrownForSwitchStatement(switchStatement,
121 exceptionTypes);
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){
175 return;
177 final PsiType type = exception.getType();
178 if (type != null) {
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)){
205 found = true;
206 break;
209 if(!found){
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){
287 return;
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,
297 exceptionTypes);
298 } else if(expression instanceof PsiInstanceOfExpression){
299 final PsiInstanceOfExpression instanceOfExpression =
300 (PsiInstanceOfExpression)expression;
301 calculateExceptionsThrownForInstanceOf(instanceOfExpression,
302 exceptionTypes);
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,
315 exceptionTypes);
316 } else if(expression instanceof PsiNewExpression){
317 final PsiNewExpression newExpression = (PsiNewExpression)expression;
318 calculateExceptionsThrownForNewExpression(newExpression,
319 exceptionTypes);
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,
334 exceptionTypes);
335 } else if(expression instanceof PsiPostfixExpression){
336 final PsiPostfixExpression postfixExpression =
337 (PsiPostfixExpression)expression;
338 calculateExceptionsThrownForPostixExpression(postfixExpression,
339 exceptionTypes);
340 } else if(expression instanceof PsiBinaryExpression){
341 final PsiBinaryExpression binaryExpression =
342 (PsiBinaryExpression)expression;
343 calculateExceptionsThrownForBinaryExpression(binaryExpression,
344 exceptionTypes);
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();
391 if(method != null){
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();
422 if(method != null){
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){
509 return;
511 final PsiStatement[] statements = codeBlock.getStatements();
512 for(PsiStatement statement : statements){
513 calculateExceptionsThrownForStatement(statement, exceptionTypes);