diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsIntention.java index b139c3d86272..e7645c9685a5 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,16 +26,16 @@ import java.util.*; public class DetailExceptionsIntention extends Intention { + @Override @NotNull public PsiElementPredicate getElementPredicate() { return new DetailExceptionsPredicate(); } - public void processIntention(PsiElement element) - throws IncorrectOperationException { + @Override + public void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { final PsiJavaToken token = (PsiJavaToken)element; - final PsiTryStatement tryStatement = - (PsiTryStatement)token.getParent(); + final PsiTryStatement tryStatement = (PsiTryStatement)token.getParent(); if (tryStatement == null) { return; } @@ -43,26 +43,28 @@ public class DetailExceptionsIntention extends Intention { final int length = text.length(); @NonNls final StringBuilder newTryStatement = new StringBuilder(length); newTryStatement.append("try"); + final Set exceptionsThrown = new HashSet(); + final PsiResourceList resourceList = tryStatement.getResourceList(); + if (resourceList != null) { + newTryStatement.append(resourceList.getText()); + ExceptionUtils.calculateExceptionsThrownForResourceList(resourceList, exceptionsThrown); + } final PsiCodeBlock tryBlock = tryStatement.getTryBlock(); if (tryBlock == null) { return; } final String tryBlockText = tryBlock.getText(); newTryStatement.append(tryBlockText); - final Set exceptionsThrown = new HashSet(); - ExceptionUtils.calculateExceptionsThrownForCodeBlock(tryBlock, - exceptionsThrown); - final Comparator comparator = new HeirarchicalTypeComparator(); - final List exceptionsAlreadyEmitted = - new ArrayList(); + ExceptionUtils.calculateExceptionsThrownForCodeBlock(tryBlock, exceptionsThrown); + final Comparator comparator = new HierarchicalTypeComparator(); + final List exceptionsAlreadyEmitted = new ArrayList(); final PsiCatchSection[] catchSections = tryStatement.getCatchSections(); for (PsiCatchSection catchSection : catchSections) { - final PsiParameter param = catchSection.getParameter(); + final PsiParameter parameter = catchSection.getParameter(); final PsiCodeBlock block = catchSection.getCatchBlock(); - if (param != null && block != null) { - final PsiType caughtType = param.getType(); - final List exceptionsToExpand = - new ArrayList(10); + if (parameter != null && block != null) { + final PsiType caughtType = parameter.getType(); + final List exceptionsToExpand = new ArrayList(10); for (Object aExceptionsThrown : exceptionsThrown) { final PsiType thrownType = (PsiType)aExceptionsThrown; if (caughtType.isAssignableFrom(thrownType)) { @@ -73,11 +75,10 @@ public class DetailExceptionsIntention extends Intention { Collections.sort(exceptionsToExpand, comparator); for (PsiType thrownType : exceptionsToExpand) { newTryStatement.append("catch("); - final String exceptionType = - thrownType.getCanonicalText(); + final String exceptionType = thrownType.getCanonicalText(); newTryStatement.append(exceptionType); newTryStatement.append(' '); - final String parameterName = param.getName(); + final String parameterName = parameter.getName(); newTryStatement.append(parameterName); newTryStatement.append(')'); final String blockText = block.getText(); diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsPredicate.java index 25fe91053a3d..6281ba230e73 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/DetailExceptionsPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2005 Dave Griffith + * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import java.util.Set; class DetailExceptionsPredicate implements PsiElementPredicate { + @Override public boolean satisfiedBy(PsiElement element) { if (!(element instanceof PsiJavaToken)) { return false; @@ -43,16 +44,19 @@ class DetailExceptionsPredicate implements PsiElementPredicate { } final Set exceptionsThrown = new HashSet(10); final PsiCodeBlock tryBlock = tryStatement.getTryBlock(); - ExceptionUtils.calculateExceptionsThrownForCodeBlock(tryBlock, - exceptionsThrown); - final Set exceptionsCaught = - ExceptionUtils.getExceptionTypesHandled(tryStatement); + final PsiResourceList resourceList = tryStatement.getResourceList(); + if (resourceList != null) { + ExceptionUtils.calculateExceptionsThrownForResourceList(resourceList, exceptionsThrown); + } + ExceptionUtils.calculateExceptionsThrownForCodeBlock(tryBlock, exceptionsThrown); + final Set exceptionsCaught = ExceptionUtils.getExceptionTypesHandled(tryStatement); for (PsiType typeThrown : exceptionsThrown) { - if (!exceptionsCaught.contains(typeThrown)) { - for (PsiType typeCaught : exceptionsCaught) { - if (typeCaught.isAssignableFrom(typeThrown)) { - return true; - } + if (exceptionsCaught.contains(typeThrown)) { + continue; + } + for (PsiType typeCaught : exceptionsCaught) { + if (typeCaught.isAssignableFrom(typeThrown)) { + return true; } } } diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/ExceptionUtils.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/ExceptionUtils.java index a7a471b4eef4..2cf500c07020 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/ExceptionUtils.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/ExceptionUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,174 +17,144 @@ package com.siyeh.ipp.exceptions; import com.intellij.psi.*; +import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; class ExceptionUtils { - private ExceptionUtils() { - super(); - } + private ExceptionUtils() {} - public static Set getExceptionTypesHandled( - PsiTryStatement statement) { + public static Set getExceptionTypesHandled(PsiTryStatement statement) { final Set out = new HashSet(10); - final PsiParameter[] params = statement.getCatchBlockParameters(); - for (PsiParameter param : params) { - final PsiType type = param.getType(); - out.add(type); + final PsiParameter[] parameters = statement.getCatchBlockParameters(); + for (PsiParameter parameter : parameters) { + final PsiType type = parameter.getType(); + if (type instanceof PsiDisjunctionType) { + final PsiDisjunctionType disjunctionType = (PsiDisjunctionType)type; + final List disjunctions = disjunctionType.getDisjunctions(); + out.addAll(disjunctions); + } else { + out.add(type); + } } return out; } - private static void calculateExceptionsThrownForStatement( - PsiStatement statement, - Set exceptionTypes) { + private static void calculateExceptionsThrownForStatement(PsiStatement statement, Set exceptionTypes) { if (statement == null) { return; } - if (statement instanceof PsiBreakStatement || - statement instanceof PsiContinueStatement) { + if (statement instanceof PsiBreakStatement || statement instanceof PsiContinueStatement) { // don't do anything } else if (statement instanceof PsiReturnStatement) { - final PsiReturnStatement returnStatement = - (PsiReturnStatement)statement; + final PsiReturnStatement returnStatement = (PsiReturnStatement)statement; final PsiExpression returnValue = returnStatement.getReturnValue(); if (returnValue != null) { - calculateExceptionsThrown(returnValue, exceptionTypes); + calculateExceptionsThrownForExpression(returnValue, exceptionTypes); } } else if (statement instanceof PsiThrowStatement) { - final PsiThrowStatement throwStatement = - (PsiThrowStatement)statement; - calculateExceptionsThrownForThrowStatement(throwStatement, - exceptionTypes); + final PsiThrowStatement throwStatement = (PsiThrowStatement)statement; + calculateExceptionsThrownForThrowStatement(throwStatement, exceptionTypes); } else if (statement instanceof PsiExpressionListStatement) { - final PsiExpressionListStatement expressionListStatement = - (PsiExpressionListStatement)statement; - calculateExceptionsThrownForExpressionListStatement( - expressionListStatement, exceptionTypes); + final PsiExpressionListStatement expressionListStatement = (PsiExpressionListStatement)statement; + calculateExceptionsThrownForExpressionListStatement(expressionListStatement, exceptionTypes); } else if (statement instanceof PsiExpressionStatement) { - final PsiExpressionStatement expressionStatement = - (PsiExpressionStatement)statement; - final PsiExpression expression = - expressionStatement.getExpression(); - calculateExceptionsThrown(expression, exceptionTypes); + final PsiExpressionStatement expressionStatement = (PsiExpressionStatement)statement; + final PsiExpression expression = expressionStatement.getExpression(); + calculateExceptionsThrownForExpression(expression, exceptionTypes); } else if (statement instanceof PsiAssertStatement) { - final PsiAssertStatement assertStatement = - (PsiAssertStatement)statement; - calculateExceptionsThrownForAssertStatement(assertStatement, - exceptionTypes); + final PsiAssertStatement assertStatement = (PsiAssertStatement)statement; + calculateExceptionsThrownForAssertStatement(assertStatement, exceptionTypes); } else if (statement instanceof PsiDeclarationStatement) { - final PsiDeclarationStatement declarationStatement = - (PsiDeclarationStatement)statement; - calculateExceptionsThrownForDeclarationStatemt(declarationStatement, - exceptionTypes); + final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)statement; + calculateExceptionsThrownForDeclarationStatement(declarationStatement, exceptionTypes); } else if (statement instanceof PsiForStatement) { final PsiForStatement forStatement = (PsiForStatement)statement; - calculateExceptionsThrownForForExpression( - forStatement, exceptionTypes); + calculateExceptionsThrownForForStatement(forStatement, exceptionTypes); + } + else if (statement instanceof PsiForeachStatement) { + final PsiForeachStatement foreachStatement = (PsiForeachStatement)statement; + calculateExceptionsThrownForForeachStatement(foreachStatement, exceptionTypes); } else if (statement instanceof PsiWhileStatement) { - final PsiWhileStatement whileStatement = - (PsiWhileStatement)statement; - calculateExceptionsThrownForWhileStatement( - whileStatement, exceptionTypes); + final PsiWhileStatement whileStatement = (PsiWhileStatement)statement; + calculateExceptionsThrownForWhileStatement(whileStatement, exceptionTypes); } else if (statement instanceof PsiDoWhileStatement) { - final PsiDoWhileStatement doWhileStatement = - (PsiDoWhileStatement)statement; - calculateExceptionsThrownForDoWhileStatement(doWhileStatement, - exceptionTypes); + final PsiDoWhileStatement doWhileStatement = (PsiDoWhileStatement)statement; + calculateExceptionsThrownForDoWhileStatement(doWhileStatement, exceptionTypes); } else if (statement instanceof PsiSynchronizedStatement) { - final PsiSynchronizedStatement synchronizedStatement = - (PsiSynchronizedStatement)statement; - calculateExceptionsThrownForSynchronizedStatement( - synchronizedStatement, exceptionTypes); + final PsiSynchronizedStatement synchronizedStatement = (PsiSynchronizedStatement)statement; + calculateExceptionsThrownForSynchronizedStatement(synchronizedStatement, exceptionTypes); } else if (statement instanceof PsiBlockStatement) { final PsiBlockStatement block = (PsiBlockStatement)statement; calculateExceptionsThrownForBlockStatement(block, exceptionTypes); } else if (statement instanceof PsiLabeledStatement) { - final PsiLabeledStatement labeledStatement = - (PsiLabeledStatement)statement; - calculateExceptionsThrownForLabeledStatement(labeledStatement, - exceptionTypes); + final PsiLabeledStatement labeledStatement = (PsiLabeledStatement)statement; + calculateExceptionsThrownForLabeledStatement(labeledStatement, exceptionTypes); } else if (statement instanceof PsiIfStatement) { final PsiIfStatement ifStatement = (PsiIfStatement)statement; - calculateExceptionsThrownForIfStatement(ifStatement, - exceptionTypes); + calculateExceptionsThrownForIfStatement(ifStatement, exceptionTypes); } else if (statement instanceof PsiTryStatement) { final PsiTryStatement tryStatement = (PsiTryStatement)statement; - calculateExceptionsThrownForTryStatement(tryStatement, - exceptionTypes); + calculateExceptionsThrownForTryStatement(tryStatement, exceptionTypes); } else if (statement instanceof PsiSwitchStatement) { - final PsiSwitchStatement switchStatement = - (PsiSwitchStatement)statement; - calculateExceptionsThrownForSwitchStatement(switchStatement, - exceptionTypes); + final PsiSwitchStatement switchStatement = (PsiSwitchStatement)statement; + calculateExceptionsThrownForSwitchStatement(switchStatement, exceptionTypes); } } - private static void calculateExceptionsThrownForLabeledStatement( - PsiLabeledStatement labeledStatement, - Set exceptionTypes) { + private static void calculateExceptionsThrownForLabeledStatement(PsiLabeledStatement labeledStatement, Set exceptionTypes) { final PsiStatement statement = labeledStatement.getStatement(); calculateExceptionsThrownForStatement(statement, exceptionTypes); } - private static void calculateExceptionsThrownForExpressionListStatement( - PsiExpressionListStatement listStatement, - Set exceptionTypes) { - final PsiExpressionList expressionList = - listStatement.getExpressionList(); + private static void calculateExceptionsThrownForExpressionListStatement(PsiExpressionListStatement listStatement, + Set exceptionTypes) { + final PsiExpressionList expressionList = listStatement.getExpressionList(); final PsiExpression[] expressions = expressionList.getExpressions(); for (PsiExpression expression : expressions) { - calculateExceptionsThrown(expression, exceptionTypes); + calculateExceptionsThrownForExpression(expression, exceptionTypes); } } - private static void calculateExceptionsThrownForDeclarationStatemt( - PsiDeclarationStatement declarationStatement, - Set exceptionTypes) { - final PsiElement[] elements = - declarationStatement.getDeclaredElements(); + private static void calculateExceptionsThrownForDeclarationStatement(PsiDeclarationStatement declarationStatement, + Set exceptionTypes) { + final PsiElement[] elements = declarationStatement.getDeclaredElements(); for (PsiElement element : elements) { if (element instanceof PsiVariable) { - final PsiVariable var = (PsiVariable)element; - final PsiExpression initializer = var.getInitializer(); + final PsiVariable variable = (PsiVariable)element; + final PsiExpression initializer = variable.getInitializer(); if (initializer != null) { - calculateExceptionsThrown(initializer, exceptionTypes); + calculateExceptionsThrownForExpression(initializer, exceptionTypes); } } } } - private static void calculateExceptionsThrownForAssertStatement( - PsiAssertStatement assertStatement, - Set exceptionTypes) { - final PsiExpression assertCondition = - assertStatement.getAssertCondition(); - calculateExceptionsThrown(assertCondition, exceptionTypes); - final PsiExpression assertDescription = - assertStatement.getAssertDescription(); - calculateExceptionsThrown(assertDescription, exceptionTypes); + private static void calculateExceptionsThrownForAssertStatement(PsiAssertStatement assertStatement, Set exceptionTypes) { + final PsiExpression assertCondition = assertStatement.getAssertCondition(); + calculateExceptionsThrownForExpression(assertCondition, exceptionTypes); + final PsiExpression assertDescription = assertStatement.getAssertDescription(); + calculateExceptionsThrownForExpression(assertDescription, exceptionTypes); } - private static void calculateExceptionsThrownForThrowStatement( - PsiThrowStatement throwStatement, - Set exceptionTypes) { + private static void calculateExceptionsThrownForThrowStatement(PsiThrowStatement throwStatement, Set exceptionTypes) { final PsiExpression exception = throwStatement.getException(); if (exception == null) { return; @@ -193,26 +163,25 @@ class ExceptionUtils { if (type != null) { exceptionTypes.add(type); } - calculateExceptionsThrown(exception, exceptionTypes); + calculateExceptionsThrownForExpression(exception, exceptionTypes); } - private static void calculateExceptionsThrownForSwitchStatement( - PsiSwitchStatement switchStatement, - Set exceptionTypes) { + private static void calculateExceptionsThrownForSwitchStatement(PsiSwitchStatement switchStatement, Set exceptionTypes) { final PsiExpression switchExpression = switchStatement.getExpression(); - calculateExceptionsThrown(switchExpression, exceptionTypes); + calculateExceptionsThrownForExpression(switchExpression, exceptionTypes); final PsiCodeBlock body = switchStatement.getBody(); calculateExceptionsThrownForCodeBlock(body, exceptionTypes); } - private static void calculateExceptionsThrownForTryStatement( - PsiTryStatement tryStatement, - Set exceptionTypes) { + private static void calculateExceptionsThrownForTryStatement(PsiTryStatement tryStatement, Set exceptionTypes) { final Set exceptionThrown = new HashSet(10); + final PsiResourceList resourceList = tryStatement.getResourceList(); + if (resourceList != null) { + calculateExceptionsThrownForResourceList(resourceList, exceptionTypes); + } final PsiCodeBlock tryBlock = tryStatement.getTryBlock(); calculateExceptionsThrownForCodeBlock(tryBlock, exceptionThrown); - final Set exceptionHandled = - getExceptionTypesHandled(tryStatement); + final Set exceptionHandled = getExceptionTypesHandled(tryStatement); for (PsiType thrownType : exceptionThrown) { boolean found = false; for (PsiType handledType : exceptionHandled) { @@ -235,299 +204,255 @@ class ExceptionUtils { } } - private static void calculateExceptionsThrownForIfStatement( - PsiIfStatement ifStatement, - Set exceptionTypes) { + public static void calculateExceptionsThrownForResourceList(PsiResourceList resourceList, Set exceptionTypes) { + final List resourceVariables = resourceList.getResourceVariables(); + for (PsiResourceVariable variable : resourceVariables) { + final PsiExpression initializer = variable.getInitializer(); + if (initializer != null) { + calculateExceptionsThrownForExpression(initializer, exceptionTypes); + } + final PsiType type = variable.getType(); + final PsiClassType autoCloseable = getJavaLangAutoCloseable(resourceList); + if (!(type instanceof PsiClassType) || !autoCloseable.isAssignableFrom(type)) { + continue; + } + final PsiClassType classType = (PsiClassType)type; + final PsiClass aClass = classType.resolve(); + if (aClass == null) { + continue; + } + final PsiMethod[] closeMethods = aClass.findMethodsByName("close", true); + for (PsiMethod method : closeMethods) { + final PsiParameterList list = method.getParameterList(); + if (list.getParametersCount() == 0) { + calculateExceptionsDeclaredForMethod(method, exceptionTypes); + break; + } + } + } + } + + private static PsiClassType getJavaLangAutoCloseable(PsiElement context) { + final PsiElementFactory factory = JavaPsiFacade.getInstance(context.getProject()).getElementFactory(); + return factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE, context.getResolveScope()); + } + + private static void calculateExceptionsThrownForIfStatement(PsiIfStatement ifStatement, Set exceptionTypes) { final PsiExpression condition = ifStatement.getCondition(); + calculateExceptionsThrownForExpression(condition, exceptionTypes); final PsiStatement thenBranch = ifStatement.getThenBranch(); - final PsiStatement elseBranch = ifStatement.getElseBranch(); - calculateExceptionsThrown(condition, exceptionTypes); calculateExceptionsThrownForStatement(thenBranch, exceptionTypes); + final PsiStatement elseBranch = ifStatement.getElseBranch(); calculateExceptionsThrownForStatement(elseBranch, exceptionTypes); } - private static void calculateExceptionsThrownForBlockStatement( - PsiBlockStatement block, - Set exceptionTypes) { + private static void calculateExceptionsThrownForBlockStatement(PsiBlockStatement block, Set exceptionTypes) { final PsiCodeBlock codeBlock = block.getCodeBlock(); calculateExceptionsThrownForCodeBlock(codeBlock, exceptionTypes); } - private static void calculateExceptionsThrownForSynchronizedStatement( - PsiSynchronizedStatement synchronizedStatement, - Set exceptionTypes) { - final PsiExpression lockExpression = - synchronizedStatement.getLockExpression(); + private static void calculateExceptionsThrownForSynchronizedStatement(PsiSynchronizedStatement synchronizedStatement, + Set exceptionTypes) { + final PsiExpression lockExpression = synchronizedStatement.getLockExpression(); if (lockExpression != null) { - calculateExceptionsThrown(lockExpression, exceptionTypes); + calculateExceptionsThrownForExpression(lockExpression, exceptionTypes); } final PsiCodeBlock body = synchronizedStatement.getBody(); calculateExceptionsThrownForCodeBlock(body, exceptionTypes); } - private static void calculateExceptionsThrownForDoWhileStatement( - PsiDoWhileStatement loopStatement, - Set exceptionTypes) { - final PsiExpression condition = loopStatement.getCondition(); - calculateExceptionsThrown(condition, exceptionTypes); - final PsiStatement body = loopStatement.getBody(); + private static void calculateExceptionsThrownForDoWhileStatement(PsiDoWhileStatement doWhileStatement, Set exceptionTypes) { + final PsiExpression condition = doWhileStatement.getCondition(); + calculateExceptionsThrownForExpression(condition, exceptionTypes); + final PsiStatement body = doWhileStatement.getBody(); calculateExceptionsThrownForStatement(body, exceptionTypes); } - private static void calculateExceptionsThrownForWhileStatement( - PsiWhileStatement loopStatement, - Set exceptionTypes) { - final PsiExpression condition = loopStatement.getCondition(); - calculateExceptionsThrown(condition, exceptionTypes); - final PsiStatement body = loopStatement.getBody(); + private static void calculateExceptionsThrownForWhileStatement(PsiWhileStatement whileStatement, Set exceptionTypes) { + final PsiExpression condition = whileStatement.getCondition(); + calculateExceptionsThrownForExpression(condition, exceptionTypes); + final PsiStatement body = whileStatement.getBody(); calculateExceptionsThrownForStatement(body, exceptionTypes); } - private static void calculateExceptionsThrownForForExpression( - PsiForStatement loopStatement, - Set exceptionTypes) { - final PsiStatement initialization = loopStatement.getInitialization(); - final PsiExpression condition = loopStatement.getCondition(); - final PsiStatement update = loopStatement.getUpdate(); - final PsiStatement body = loopStatement.getBody(); + private static void calculateExceptionsThrownForForStatement(PsiForStatement forStatement, Set exceptionTypes) { + final PsiStatement initialization = forStatement.getInitialization(); calculateExceptionsThrownForStatement(initialization, exceptionTypes); - calculateExceptionsThrown(condition, exceptionTypes); + final PsiExpression condition = forStatement.getCondition(); + calculateExceptionsThrownForExpression(condition, exceptionTypes); + final PsiStatement update = forStatement.getUpdate(); calculateExceptionsThrownForStatement(update, exceptionTypes); + final PsiStatement body = forStatement.getBody(); calculateExceptionsThrownForStatement(body, exceptionTypes); } - private static void calculateExceptionsThrown(PsiExpression expression, - Set exceptionTypes) { + private static void calculateExceptionsThrownForForeachStatement(PsiForeachStatement foreachStatement, Set exceptionTypes) { + final PsiExpression iteratedValue = foreachStatement.getIteratedValue(); + calculateExceptionsThrownForExpression(iteratedValue, exceptionTypes); + final PsiStatement body = foreachStatement.getBody(); + calculateExceptionsThrownForStatement(body, exceptionTypes); + } + + private static void calculateExceptionsThrownForExpression(PsiExpression expression, Set exceptionTypes) { if (expression == null) { return; } - if (expression instanceof PsiThisExpression || - expression instanceof PsiLiteralExpression || - expression instanceof PsiSuperExpression || - expression instanceof PsiClassObjectAccessExpression) { + if (expression instanceof PsiThisExpression || expression instanceof PsiLiteralExpression || + expression instanceof PsiSuperExpression || expression instanceof PsiClassObjectAccessExpression) { } else if (expression instanceof PsiTypeCastExpression) { - final PsiTypeCastExpression typeCastExpression = - (PsiTypeCastExpression)expression; - calculateExceptionsThrownForTypeCast(typeCastExpression, - exceptionTypes); + final PsiTypeCastExpression typeCastExpression = (PsiTypeCastExpression)expression; + calculateExceptionsThrownForTypeCast(typeCastExpression, exceptionTypes); } else if (expression instanceof PsiInstanceOfExpression) { - final PsiInstanceOfExpression instanceOfExpression = - (PsiInstanceOfExpression)expression; - calculateExceptionsThrownForInstanceOf(instanceOfExpression, - exceptionTypes); + final PsiInstanceOfExpression instanceOfExpression = (PsiInstanceOfExpression)expression; + calculateExceptionsThrownForInstanceOf(instanceOfExpression, exceptionTypes); } else if (expression instanceof PsiReferenceExpression) { - final PsiReferenceExpression referenceExpression = - (PsiReferenceExpression)expression; - final PsiExpression qualifier = - referenceExpression.getQualifierExpression(); + final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression; + final PsiExpression qualifier = referenceExpression.getQualifierExpression(); if (qualifier != null) { - calculateExceptionsThrown(qualifier, exceptionTypes); + calculateExceptionsThrownForExpression(qualifier, exceptionTypes); } } else if (expression instanceof PsiMethodCallExpression) { - final PsiMethodCallExpression methodCallExpression = - (PsiMethodCallExpression)expression; - calculateExceptionsThrownForMethodCall(methodCallExpression, - exceptionTypes); + final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression; + calculateExceptionsThrownForMethodCall(methodCallExpression, exceptionTypes); } else if (expression instanceof PsiNewExpression) { final PsiNewExpression newExpression = (PsiNewExpression)expression; - calculateExceptionsThrownForNewExpression(newExpression, - exceptionTypes); + calculateExceptionsThrownForNewExpression(newExpression, exceptionTypes); } else if (expression instanceof PsiArrayInitializerExpression) { - final PsiArrayInitializerExpression arrayInitializerExpression = - (PsiArrayInitializerExpression)expression; - calculateExceptionsThrownForArrayInitializerExpression( - arrayInitializerExpression, exceptionTypes); + final PsiArrayInitializerExpression arrayInitializerExpression = (PsiArrayInitializerExpression)expression; + calculateExceptionsThrownForArrayInitializerExpression(arrayInitializerExpression, exceptionTypes); } else if (expression instanceof PsiArrayAccessExpression) { - final PsiArrayAccessExpression arrayAccessExpression = - (PsiArrayAccessExpression)expression; - calculateExceptionsThrownForArrayAccessExpression( - arrayAccessExpression, exceptionTypes); + final PsiArrayAccessExpression arrayAccessExpression = (PsiArrayAccessExpression)expression; + calculateExceptionsThrownForArrayAccessExpression(arrayAccessExpression, exceptionTypes); } else if (expression instanceof PsiPrefixExpression) { - final PsiPrefixExpression prefixExpression = - (PsiPrefixExpression)expression; - calculateExceptionsThrownForPrefixException(prefixExpression, - exceptionTypes); + final PsiPrefixExpression prefixExpression = (PsiPrefixExpression)expression; + calculateExceptionsThrownForPrefixException(prefixExpression, exceptionTypes); } else if (expression instanceof PsiPostfixExpression) { - final PsiPostfixExpression postfixExpression = - (PsiPostfixExpression)expression; - calculateExceptionsThrownForPostixExpression(postfixExpression, - exceptionTypes); + final PsiPostfixExpression postfixExpression = (PsiPostfixExpression)expression; + calculateExceptionsThrownForPostfixExpression(postfixExpression, exceptionTypes); } else if (expression instanceof PsiBinaryExpression) { - final PsiBinaryExpression binaryExpression = - (PsiBinaryExpression)expression; - calculateExceptionsThrownForBinaryExpression(binaryExpression, - exceptionTypes); + final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)expression; + calculateExceptionsThrownForBinaryExpression(binaryExpression, exceptionTypes); } else if (expression instanceof PsiAssignmentExpression) { - final PsiAssignmentExpression assignmentExpression = - (PsiAssignmentExpression)expression; - calculateExceptionsThrownForAssignmentExpression( - assignmentExpression, exceptionTypes); + final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)expression; + calculateExceptionsThrownForAssignmentExpression(assignmentExpression, exceptionTypes); } else if (expression instanceof PsiConditionalExpression) { - final PsiConditionalExpression conditionalExpression = - (PsiConditionalExpression)expression; - calculateExceptionsThrownForConditionalExcpression( - conditionalExpression, exceptionTypes); + final PsiConditionalExpression conditionalExpression = (PsiConditionalExpression)expression; + calculateExceptionsThrownForConditionalExpression(conditionalExpression, exceptionTypes); } } - private static void calculateExceptionsThrownForTypeCast( - PsiTypeCastExpression typeCastExpression, - Set exceptionTypes) { + private static void calculateExceptionsThrownForTypeCast(PsiTypeCastExpression typeCastExpression, Set exceptionTypes) { final PsiExpression operand = typeCastExpression.getOperand(); - calculateExceptionsThrown(operand, exceptionTypes); + calculateExceptionsThrownForExpression(operand, exceptionTypes); } - private static void calculateExceptionsThrownForInstanceOf( - PsiInstanceOfExpression instanceOfExpression, - Set exceptionTypes) { + private static void calculateExceptionsThrownForInstanceOf(PsiInstanceOfExpression instanceOfExpression, Set exceptionTypes) { final PsiExpression operand = instanceOfExpression.getOperand(); - calculateExceptionsThrown(operand, exceptionTypes); + calculateExceptionsThrownForExpression(operand, exceptionTypes); } - private static void calculateExceptionsThrownForNewExpression( - PsiNewExpression newExpression, Set exceptionTypes) { + private static void calculateExceptionsThrownForNewExpression(PsiNewExpression newExpression, Set exceptionTypes) { final PsiExpressionList argumentList = newExpression.getArgumentList(); if (argumentList != null) { - final PsiExpression[] args = argumentList.getExpressions(); - for (PsiExpression arg : args) { - calculateExceptionsThrown(arg, exceptionTypes); + final PsiExpression[] arguments = argumentList.getExpressions(); + for (PsiExpression argument : arguments) { + calculateExceptionsThrownForExpression(argument, exceptionTypes); } } - final PsiExpression[] arrayDims = newExpression.getArrayDimensions(); - for (PsiExpression arrayDim : arrayDims) { - calculateExceptionsThrown(arrayDim, exceptionTypes); + final PsiExpression[] arrayDimensions = newExpression.getArrayDimensions(); + for (PsiExpression arrayDimension : arrayDimensions) { + calculateExceptionsThrownForExpression(arrayDimension, exceptionTypes); } final PsiExpression qualifier = newExpression.getQualifier(); - calculateExceptionsThrown(qualifier, exceptionTypes); - final PsiArrayInitializerExpression arrayInitializer = - newExpression.getArrayInitializer(); - calculateExceptionsThrown(arrayInitializer, exceptionTypes); + calculateExceptionsThrownForExpression(qualifier, exceptionTypes); + final PsiArrayInitializerExpression arrayInitializer = newExpression.getArrayInitializer(); + calculateExceptionsThrownForExpression(arrayInitializer, exceptionTypes); final PsiMethod method = newExpression.resolveMethod(); - if (method != null) { - final PsiReferenceList throwsList = method.getThrowsList(); - final PsiJavaCodeReferenceElement[] list = - throwsList.getReferenceElements(); - for (final PsiJavaCodeReferenceElement referenceElement : list) { - final PsiClass exceptionClass = - (PsiClass)referenceElement.resolve(); - if (exceptionClass != null) { - final PsiManager psiManager = exceptionClass.getManager(); - final PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory(); - final PsiClassType exceptionType = - factory.createType(exceptionClass); - exceptionTypes.add(exceptionType); - } - } - } + calculateExceptionsDeclaredForMethod(method, exceptionTypes); } - private static void calculateExceptionsThrownForMethodCall( - PsiMethodCallExpression methodCallExpression, - Set exceptionTypes) { - final PsiExpressionList argumentList = - methodCallExpression.getArgumentList(); + private static void calculateExceptionsThrownForMethodCall(PsiMethodCallExpression methodCallExpression, Set exceptionTypes) { + final PsiExpressionList argumentList = methodCallExpression.getArgumentList(); final PsiExpression[] expressions = argumentList.getExpressions(); for (PsiExpression expression : expressions) { - calculateExceptionsThrown(expression, exceptionTypes); + calculateExceptionsThrownForExpression(expression, exceptionTypes); } - final PsiReferenceExpression methodExpression = - methodCallExpression.getMethodExpression(); - calculateExceptionsThrown(methodExpression, exceptionTypes); + final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); + calculateExceptionsThrownForExpression(methodExpression, exceptionTypes); final PsiMethod method = methodCallExpression.resolveMethod(); - if (method != null) { - final PsiReferenceList throwsList = method.getThrowsList(); - final PsiJavaCodeReferenceElement[] list = - throwsList.getReferenceElements(); - for (final PsiJavaCodeReferenceElement referenceElement : list) { - final PsiClass exceptionClass = - (PsiClass)referenceElement.resolve(); - if (exceptionClass != null) { - final PsiManager psiManager = exceptionClass.getManager(); - final PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory(); - final PsiClassType exceptionType = - factory.createType(exceptionClass); - exceptionTypes.add(exceptionType); - } - } - } + calculateExceptionsDeclaredForMethod(method, exceptionTypes); } - private static void calculateExceptionsThrownForConditionalExcpression( - PsiConditionalExpression conditionalExpression, - Set exceptionTypes) { + public static void calculateExceptionsDeclaredForMethod(PsiMethod method, Set exceptionTypes) { + if (method == null) { + return; + } + final PsiReferenceList throwsList = method.getThrowsList(); + final PsiClassType[] types = throwsList.getReferencedTypes(); + Collections.addAll(exceptionTypes, types); + } + + private static void calculateExceptionsThrownForConditionalExpression(PsiConditionalExpression conditionalExpression, + Set exceptionTypes) { final PsiExpression condition = conditionalExpression.getCondition(); - final PsiExpression elseExpression = - conditionalExpression.getElseExpression(); - final PsiExpression thenExpression = - conditionalExpression.getThenExpression(); - calculateExceptionsThrown(condition, exceptionTypes); - calculateExceptionsThrown(elseExpression, exceptionTypes); - calculateExceptionsThrown(thenExpression, exceptionTypes); + final PsiExpression elseExpression = conditionalExpression.getElseExpression(); + final PsiExpression thenExpression = conditionalExpression.getThenExpression(); + calculateExceptionsThrownForExpression(condition, exceptionTypes); + calculateExceptionsThrownForExpression(elseExpression, exceptionTypes); + calculateExceptionsThrownForExpression(thenExpression, exceptionTypes); } - private static void calculateExceptionsThrownForBinaryExpression( - PsiBinaryExpression binaryExpression, - Set exceptionTypes) { + private static void calculateExceptionsThrownForBinaryExpression(PsiBinaryExpression binaryExpression, Set exceptionTypes) { final PsiExpression lOperand = binaryExpression.getLOperand(); - calculateExceptionsThrown(lOperand, exceptionTypes); + calculateExceptionsThrownForExpression(lOperand, exceptionTypes); final PsiExpression rhs = binaryExpression.getROperand(); - calculateExceptionsThrown(rhs, exceptionTypes); + calculateExceptionsThrownForExpression(rhs, exceptionTypes); } - private static void calculateExceptionsThrownForAssignmentExpression( - PsiAssignmentExpression assignmentExpression, - Set exceptionTypes) { + private static void calculateExceptionsThrownForAssignmentExpression(PsiAssignmentExpression assignmentExpression, + Set exceptionTypes) { final PsiExpression lOperand = assignmentExpression.getLExpression(); - calculateExceptionsThrown(lOperand, exceptionTypes); + calculateExceptionsThrownForExpression(lOperand, exceptionTypes); final PsiExpression rhs = assignmentExpression.getRExpression(); - calculateExceptionsThrown(rhs, exceptionTypes); + calculateExceptionsThrownForExpression(rhs, exceptionTypes); } - private static void calculateExceptionsThrownForArrayInitializerExpression( - PsiArrayInitializerExpression arrayInitializerExpression, - Set exceptionTypes) { - final PsiExpression[] initializers = - arrayInitializerExpression.getInitializers(); + private static void calculateExceptionsThrownForArrayInitializerExpression(PsiArrayInitializerExpression arrayInitializerExpression, + Set exceptionTypes) { + final PsiExpression[] initializers = arrayInitializerExpression.getInitializers(); for (PsiExpression initializer : initializers) { - calculateExceptionsThrown(initializer, exceptionTypes); + calculateExceptionsThrownForExpression(initializer, exceptionTypes); } } - private static void calculateExceptionsThrownForArrayAccessExpression( - PsiArrayAccessExpression arrayAccessExpression, - Set exceptionTypes) { - final PsiExpression arrayExpression = - arrayAccessExpression.getArrayExpression(); - calculateExceptionsThrown(arrayExpression, exceptionTypes); - final PsiExpression indexExpression = - arrayAccessExpression.getIndexExpression(); - calculateExceptionsThrown(indexExpression, exceptionTypes); + private static void calculateExceptionsThrownForArrayAccessExpression(PsiArrayAccessExpression arrayAccessExpression, + Set exceptionTypes) { + final PsiExpression arrayExpression = arrayAccessExpression.getArrayExpression(); + calculateExceptionsThrownForExpression(arrayExpression, exceptionTypes); + final PsiExpression indexExpression = arrayAccessExpression.getIndexExpression(); + calculateExceptionsThrownForExpression(indexExpression, exceptionTypes); } - private static void calculateExceptionsThrownForPrefixException( - PsiPrefixExpression prefixExpression, - Set exceptionTypes) { + private static void calculateExceptionsThrownForPrefixException(PsiPrefixExpression prefixExpression, Set exceptionTypes) { final PsiExpression operand = prefixExpression.getOperand(); - calculateExceptionsThrown(operand, exceptionTypes); + calculateExceptionsThrownForExpression(operand, exceptionTypes); } - private static void calculateExceptionsThrownForPostixExpression( - PsiPostfixExpression postfixExpression, - Set exceptionTypes) { + private static void calculateExceptionsThrownForPostfixExpression(PsiPostfixExpression postfixExpression, Set exceptionTypes) { final PsiExpression operand = postfixExpression.getOperand(); - calculateExceptionsThrown(operand, exceptionTypes); + calculateExceptionsThrownForExpression(operand, exceptionTypes); } public static void calculateExceptionsThrownForCodeBlock( diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/HeirarchicalTypeComparator.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/HierarchicalTypeComparator.java similarity index 88% rename from plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/HeirarchicalTypeComparator.java rename to plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/HierarchicalTypeComparator.java index 3c974cc5394a..d85f42719e0d 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/HeirarchicalTypeComparator.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/exceptions/HierarchicalTypeComparator.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,9 @@ import com.intellij.psi.PsiType; import java.util.Comparator; -class HeirarchicalTypeComparator implements Comparator { +class HierarchicalTypeComparator implements Comparator { + @Override public int compare(PsiType type1, PsiType type2) { if (type1.isAssignableFrom(type2)) { return 1; diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/DetailExceptionTestCase.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/DetailExceptionTestCase.java deleted file mode 100644 index d3df23ac467c..000000000000 --- a/plugins/IntentionPowerPak/test/com/siyeh/ipp/DetailExceptionTestCase.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.siyeh.ipp; - -import java.sql.DriverManager; -import java.sql.Connection; - -public class DetailExceptionTestCase{ - public void foo() - { - Connection conn; - try{ - Class.forName("logon.name"); - DriverManager - .getConnection("jdbc:mysql://localhost/test", "root", ""); - } catch(ClassNotFoundException e){ - - } catch(Exception e){ - - } - } -} diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/Disjunction.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/Disjunction.java new file mode 100644 index 000000000000..d7851e7d48be --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/Disjunction.java @@ -0,0 +1,16 @@ +package com.siyeh.ipp.exceptions.detail; + +class Disjunction { + + void foo() { + try{ + if (true) { + throw new IllegalArgumentException(); + } else { + throw new NullPointerException(); + } + } catch (IllegalArgumentException | NullPointerException e) { + + } + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/Foreach.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/Foreach.java new file mode 100644 index 000000000000..b96729a02336 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/Foreach.java @@ -0,0 +1,14 @@ +package com.siyeh.ipp.exceptions.detail; + +import java.util.List; + +class Foreach { + + void foo(List list) { + try { + for (String s : list) { + throw new IllegalArgumentException(); + } + } catch (RuntimeException e) {} + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/Foreach_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/Foreach_after.java new file mode 100644 index 000000000000..6c8c4a91eb9b --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/Foreach_after.java @@ -0,0 +1,15 @@ +package com.siyeh.ipp.exceptions.detail; + +import java.util.List; + +class Foreach { + + void foo(List list) { + try { + for (String s : list) { + throw new IllegalArgumentException(); + } + } catch (IllegalArgumentException e) { + } + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/Simple.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/Simple.java new file mode 100644 index 000000000000..4c11cfc2ac4b --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/Simple.java @@ -0,0 +1,16 @@ +package com.siyeh.ipp.exceptions.detail; + +class Simple { + + void foo() { + try{ + if (true) { + throw new IllegalArgumentException(); + } else { + throw new NullPointerException(); + } + } catch (RuntimeException e) { + + } + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/Simple_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/Simple_after.java new file mode 100644 index 000000000000..20ddfdd17acb --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/Simple_after.java @@ -0,0 +1,18 @@ +package com.siyeh.ipp.exceptions.detail; + +class Simple { + + void foo() { + try { + if (true) { + throw new IllegalArgumentException(); + } else { + throw new NullPointerException(); + } + } catch (IllegalArgumentException e) { + + } catch (NullPointerException e) { + + } + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/TryWithResources.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/TryWithResources.java new file mode 100644 index 000000000000..4db567fde2c4 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/TryWithResources.java @@ -0,0 +1,14 @@ +package com.siyeh.ipp.exceptions.detail; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; + +class TryWithResources { + + void foo(File file1, File file2) { + try (FileInputStream in = new FileInputStream(file1); FileOutputStream out = new FileOutputStream(file2)) { + throw new IllegalArgumentException(); + } catch (Exception e) {} + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/TryWithResources_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/TryWithResources_after.java new file mode 100644 index 000000000000..ebdb5a4f3b65 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/exceptions/detail/TryWithResources_after.java @@ -0,0 +1,15 @@ +package com.siyeh.ipp.exceptions.detail; + +import java.io.*; + +class TryWithResources { + + void foo(File file1, File file2) { + try (FileInputStream in = new FileInputStream(file1); FileOutputStream out = new FileOutputStream(file2)) { + throw new IllegalArgumentException(); + } catch (FileNotFoundException e) { + } catch (IOException e) { + } catch (IllegalArgumentException e) { + } + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/DetailExceptionsIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/DetailExceptionsIntentionTest.java new file mode 100644 index 000000000000..57dd548f5d15 --- /dev/null +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/exceptions/DetailExceptionsIntentionTest.java @@ -0,0 +1,25 @@ +package com.siyeh.ipp.exceptions; + +import com.siyeh.IntentionPowerPackBundle; +import com.siyeh.ipp.IPPTestCase; + +/** + * @author Bas Leijdekkers + */ +public class DetailExceptionsIntentionTest extends IPPTestCase { + + public void testDisjunction() { assertIntentionNotAvailable(); } + public void testSimple() { doTest(); } + public void testForeach() { doTest(); } + public void testTryWithResources() { doTest(); } + + @Override + protected String getIntentionName() { + return IntentionPowerPackBundle.message("detail.exceptions.intention.name"); + } + + @Override + protected String getRelativePath() { + return "exceptions/detail"; + } +}