From 06fc344e1dd0a7b7df2de089e168b49c1ee86e1d Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 13 Jan 2005 15:55:55 +0300 Subject: [PATCH] merged CVS and Subversion versions --- .../ArrayContentsAssignedVisitor.java | 2 +- .../src/com/siyeh/ig/psiutils/BoolUtils.java | 2 +- .../src/com/siyeh/ig/psiutils/ClassUtils.java | 12 +- .../src/com/siyeh/ig/psiutils/CloneUtils.java | 13 +- .../com/siyeh/ig/psiutils/ExceptionUtils.java | 24 +- .../siyeh/ig/psiutils/ExpectedTypeUtils.java | 115 ++++++-- .../ExpressionEquivalenceChecker.java | 10 +- .../ig/psiutils/InitializationReadUtils.java | 3 +- .../ig/psiutils/InitializationUtils.java | 249 +++++++++++++----- .../siyeh/ig/psiutils/SideEffectChecker.java | 11 +- .../src/com/siyeh/ig/psiutils/TypeUtils.java | 7 +- .../ig/psiutils/VariableAssignedVisitor.java | 51 ++++ .../VariablePassedAsArgumentVisitor.java | 5 +- 13 files changed, 375 insertions(+), 129 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ArrayContentsAssignedVisitor.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ArrayContentsAssignedVisitor.java index b757febbaf2f..52425044a0d9 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ArrayContentsAssignedVisitor.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ArrayContentsAssignedVisitor.java @@ -25,7 +25,7 @@ public class ArrayContentsAssignedVisitor extends PsiRecursiveElementVisitor { public void visitAssignmentExpression(PsiAssignmentExpression assignment) { super.visitAssignmentExpression(assignment); final PsiJavaToken operationSign = assignment.getOperationSign(); - if (operationSign.getTokenType() != JavaTokenType.EQ) { + if (!(operationSign.getTokenType() == JavaTokenType.EQ)) { return; } final PsiExpression arg = assignment.getLExpression(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/BoolUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/BoolUtils.java index 8490e8cf7912..86c390d5963a 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/BoolUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/BoolUtils.java @@ -16,7 +16,7 @@ public class BoolUtils { } final PsiPrefixExpression prefixExp = (PsiPrefixExpression) exp; final PsiJavaToken sign = prefixExp.getOperationSign(); - return sign.getTokenType() == JavaTokenType.EXCL; + return !(sign.getTokenType() != JavaTokenType.EXCL); } private static PsiExpression getNegated(PsiExpression exp) { diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ClassUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ClassUtils.java index ddf0193f0d6d..341b276e0f98 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ClassUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ClassUtils.java @@ -75,7 +75,7 @@ public class ClassUtils { } public static boolean isPrimitive(PsiType type) { - return + return (type!=null) &&( type.equals(PsiType.BOOLEAN) || type.equals(PsiType.LONG) || type.equals(PsiType.INT) || @@ -83,16 +83,16 @@ public class ClassUtils { type.equals(PsiType.CHAR) || type.equals(PsiType.BYTE) || type.equals(PsiType.FLOAT) || - type.equals(PsiType.DOUBLE); + type.equals(PsiType.DOUBLE)); } public static boolean isIntegral(PsiType type) { - return + return (type != null) && ( type.equals(PsiType.LONG) || type.equals(PsiType.INT) || type.equals(PsiType.SHORT) || type.equals(PsiType.CHAR) || - type.equals(PsiType.BYTE); + type.equals(PsiType.BYTE)); } public static boolean isImmutable(PsiType type) { @@ -159,9 +159,7 @@ public class ClassUtils { } public static PsiClass getContainingClass(PsiElement aClass) { - final PsiClass parentClass = - (PsiClass) PsiTreeUtil.getParentOfType(aClass, PsiClass.class); - return parentClass; + return (PsiClass) PsiTreeUtil.getParentOfType(aClass, PsiClass.class); } public static PsiClass getOutermostContainingClass(PsiClass aClass) { diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/CloneUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/CloneUtils.java index b97df3898106..b9b851123854 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/CloneUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/CloneUtils.java @@ -1,6 +1,7 @@ package com.siyeh.ig.psiutils; import com.intellij.psi.*; +import com.intellij.pom.java.LanguageLevel; import java.util.HashSet; import java.util.Set; @@ -8,7 +9,6 @@ import java.util.Set; public class CloneUtils { private CloneUtils() { super(); - } public static boolean isCloneable(PsiClass aClass) { @@ -55,9 +55,14 @@ public class CloneUtils { if (parameters.length != 0) { return false; } - final PsiType returnType = method.getReturnType(); - if (!TypeUtils.isJavaLangObject(returnType)) { - return false; + final PsiManager manager = method.getManager(); + final LanguageLevel languageLevel = manager.getEffectiveLanguageLevel(); + if (languageLevel.equals(LanguageLevel.JDK_1_3) || + languageLevel.equals(LanguageLevel.JDK_1_4)) { //for 1.5 and after, clone may be covariant + final PsiType returnType = method.getReturnType(); + if (!TypeUtils.isJavaLangObject(returnType)) { + return false; + } } return true; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ExceptionUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ExceptionUtils.java index 581df980cacc..cf43f112b16c 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ExceptionUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ExceptionUtils.java @@ -83,16 +83,20 @@ public class ExceptionUtils { public void visitNewExpression(PsiNewExpression expression) { super.visitNewExpression(expression); final PsiMethod method = expression.resolveMethod(); - if (method != null) { - final PsiReferenceList throwsList = method.getThrowsList(); - final PsiJavaCodeReferenceElement[] list = throwsList.getReferenceElements(); - for (int i = 0; i < list.length; i++) { - final PsiJavaCodeReferenceElement referenceElement = list[i]; - final PsiClass exceptionClass = (PsiClass) referenceElement.resolve(); - if (exceptionClass != null) { - final PsiClassType exceptionType = m_factory.createType(exceptionClass); - m_exceptionsThrown.add(exceptionType); - } + if (method == null) { + return; + } + final PsiReferenceList throwsList = method.getThrowsList(); + if (throwsList == null) { + return; + } + final PsiJavaCodeReferenceElement[] list = throwsList.getReferenceElements(); + for (int i = 0; i < list.length; i++) { + final PsiJavaCodeReferenceElement referenceElement = list[i]; + final PsiClass exceptionClass = (PsiClass) referenceElement.resolve(); + if (exceptionClass != null) { + final PsiClassType exceptionType = m_factory.createType(exceptionClass); + m_exceptionsThrown.add(exceptionType); } } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ExpectedTypeUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ExpectedTypeUtils.java index e7061acf0038..83601a27cbc2 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ExpectedTypeUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ExpectedTypeUtils.java @@ -2,12 +2,13 @@ package com.siyeh.ig.psiutils; import com.intellij.openapi.project.Project; import com.intellij.psi.*; -import com.intellij.psi.tree.IElementType; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.tree.IElementType; public class ExpectedTypeUtils { private ExpectedTypeUtils() { + super(); } public static PsiType findExpectedType(PsiExpression exp) { @@ -43,30 +44,80 @@ public class ExpectedTypeUtils { } } + } else if (context instanceof PsiArrayInitializerExpression) { + final PsiArrayInitializerExpression initializer = (PsiArrayInitializerExpression) context; + final PsiArrayType arrayType = (PsiArrayType) initializer.getType(); + if(arrayType!=null) + { + return arrayType.getComponentType(); + } + }else if (context instanceof PsiArrayAccessExpression) { + final PsiArrayAccessExpression accessExpression = (PsiArrayAccessExpression) context; + if(accessExpression.getIndexExpression().equals(wrappedExp)) + { + return PsiType.INT; + } } else if (context instanceof PsiAssignmentExpression) { final PsiAssignmentExpression assignment = (PsiAssignmentExpression) context; final PsiExpression rExpression = assignment.getRExpression(); if (rExpression != null) { if (rExpression.equals(wrappedExp)) { final PsiExpression lExpression = assignment.getLExpression(); - PsiType lType = lExpression.getType(); - if (lType == null) return null; - // e.g. String += any type - if (TypeUtils.isJavaLangString(lType) && JavaTokenType.PLUSEQ.equals(assignment.getOperationSign().getTokenType())) { - return rExpression.getType(); - } - return lType; + PsiType lType = lExpression.getType(); + if (lType == null) return null; + // e.g. String += any type + if (TypeUtils.isJavaLangString(lType) && JavaTokenType.PLUSEQ.equals(assignment.getOperationSign().getTokenType())) { + return rExpression.getType(); + } + return lType; } } + } else if (context instanceof PsiDeclarationStatement) { + final PsiDeclarationStatement assignment = (PsiDeclarationStatement) context; + final PsiElement[] declaredElements = assignment.getDeclaredElements(); + for (int i = 0; i < declaredElements.length; i++) { + if (declaredElements[i] instanceof PsiVariable) { + final PsiVariable declaredElement = (PsiVariable) declaredElements[i]; + final PsiExpression initializer = declaredElement.getInitializer(); + if (wrappedExp.equals(initializer)) { + return declaredElement.getType(); + } + } + } + }else if (context instanceof PsiField) { + final PsiField field = (PsiField) context; + final PsiExpression initializer = field.getInitializer(); + if (wrappedExp.equals(initializer)) { + return field.getType(); + } } else if (context instanceof PsiBinaryExpression) { final PsiBinaryExpression binaryExp = (PsiBinaryExpression) context; final PsiJavaToken sign = binaryExp.getOperationSign(); + final IElementType tokenType = sign.getTokenType(); final PsiType type = binaryExp.getType(); if (TypeUtils.isJavaLangString(type)) { return null; } - if (isArithmeticOperation(sign)) { + if (isArithmeticOperation(tokenType)) { return type; + } else if (isEqualityOperation(tokenType)) { + final PsiExpression lhs = binaryExp.getLOperand(); + if (lhs == null) { + return null; + } + final PsiType lhsType = lhs.getType(); + if (ClassUtils.isPrimitive(lhsType)) { + return lhsType; + } + final PsiExpression rhs = binaryExp.getROperand(); + if (rhs == null) { + return null; + } + final PsiType rhsType = rhs.getType(); + if (ClassUtils.isPrimitive(rhsType)) { + return rhsType; + } + return null; } else { return null; } @@ -85,15 +136,15 @@ public class ExpectedTypeUtils { return conditional.getType(); } else if (context instanceof PsiExpressionList) { final PsiExpressionList expList = (PsiExpressionList) context; - final PsiMethod method = findCalledMethod(expList); + final PsiMethod method = ExpectedTypeUtils.findCalledMethod(expList); if (method == null) { return null; } - final int parameterPosition = getParameterPosition(expList, wrappedExp); - return getTypeOfParemeter(method, parameterPosition); + final int parameterPosition = ExpectedTypeUtils.getParameterPosition(expList, wrappedExp); + return ExpectedTypeUtils.getTypeOfParemeter(method, parameterPosition); } else if (context instanceof PsiReturnStatement) { final PsiReturnStatement psiReturnStatement = (PsiReturnStatement) context; - final PsiMethod method = findEnclosingPsiMethod(psiReturnStatement); + final PsiMethod method = ExpectedTypeUtils.findEnclosingPsiMethod(psiReturnStatement); if (method == null) { return null; } @@ -114,13 +165,18 @@ public class ExpectedTypeUtils { return null; } - private static boolean isArithmeticOperation(PsiJavaToken javaToken) { - IElementType sign = javaToken.getTokenType(); - return JavaTokenType.PLUS.equals(sign) - || JavaTokenType.MINUS.equals(sign) - || JavaTokenType.ASTERISK.equals(sign) - || JavaTokenType.DIV.equals(sign) || - JavaTokenType.PERC.equals(sign); + private static boolean isArithmeticOperation(IElementType sign) { + return sign.equals(JavaTokenType.PLUS) + || sign.equals(JavaTokenType.MINUS) + || sign.equals(JavaTokenType.ASTERISK) + || sign.equals(JavaTokenType.DIV) || + sign.equals(JavaTokenType.PERC); + } + + + private static boolean isEqualityOperation(IElementType sign) { + return sign.equals(JavaTokenType.EQEQ) + || sign.equals(JavaTokenType.NE); } private static int getParameterPosition(PsiExpressionList expressionList, PsiExpression exp) { @@ -136,11 +192,25 @@ public class ExpectedTypeUtils { private static PsiType getTypeOfParemeter(PsiMethod psiMethod, int parameterPosition) { final PsiParameterList paramList = psiMethod.getParameterList(); final PsiParameter[] parameters = paramList.getParameters(); - if (parameterPosition >= parameters.length || parameterPosition < 0) { + if(parameterPosition < 0) { return null; } + if (parameterPosition >= parameters.length) { + final int lastParamPosition = parameters.length - 1; + if(lastParamPosition<0) + return null; + final PsiParameter lastParameter = parameters[lastParamPosition]; + if(lastParameter.isVarArgs()) + { + return ((PsiArrayType)lastParameter.getType()).getComponentType(); + } + } final PsiParameter param = parameters[parameterPosition]; + if(param.isVarArgs()) + { + return ((PsiArrayType) param.getType()).getComponentType(); + } return param.getType(); } @@ -159,8 +229,7 @@ public class ExpectedTypeUtils { final PsiElement parent = expList.getParent(); if (parent instanceof PsiMethodCallExpression) { final PsiMethodCallExpression methodCall = (PsiMethodCallExpression) parent; - final PsiMethod method = methodCall.resolveMethod(); - return method; + return methodCall.resolveMethod(); } else if (parent instanceof PsiNewExpression) { final PsiNewExpression psiNewExpression = (PsiNewExpression) parent; return psiNewExpression.resolveMethod(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ExpressionEquivalenceChecker.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ExpressionEquivalenceChecker.java index a69e9ec75a05..e768a905c51c 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ExpressionEquivalenceChecker.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/ExpressionEquivalenceChecker.java @@ -180,7 +180,7 @@ public class ExpressionEquivalenceChecker { PsiPrefixExpression prefixExp2) { final PsiJavaToken sign1 = prefixExp1.getOperationSign(); final PsiJavaToken sign2 = prefixExp2.getOperationSign(); - if (sign1.getTokenType() != sign2.getTokenType()) { + if (!sign1.getTokenType().equals(sign2.getTokenType())) { return false; } final PsiExpression operand1 = prefixExp1.getOperand(); @@ -192,7 +192,7 @@ public class ExpressionEquivalenceChecker { PsiPostfixExpression postfixExp2) { final PsiJavaToken sign1 = postfixExp1.getOperationSign(); final PsiJavaToken sign2 = postfixExp2.getOperationSign(); - if (sign1.getTokenType() != sign2.getTokenType()) { + if (!sign1.getTokenType().equals(sign2.getTokenType())) { return false; } final PsiExpression operand1 = postfixExp1.getOperand(); @@ -204,8 +204,7 @@ public class ExpressionEquivalenceChecker { PsiBinaryExpression binaryExp2) { final PsiJavaToken sign1 = binaryExp1.getOperationSign(); final PsiJavaToken sign2 = binaryExp2.getOperationSign(); - if (sign1.getTokenType() != - sign2.getTokenType()) { + if (!sign1.getTokenType().equals(sign2.getTokenType())) { return false; } final PsiExpression lhs1 = binaryExp1.getLOperand(); @@ -220,8 +219,7 @@ public class ExpressionEquivalenceChecker { PsiAssignmentExpression assignExp2) { final PsiJavaToken sign1 = assignExp1.getOperationSign(); final PsiJavaToken sign2 = assignExp2.getOperationSign(); - if (sign1.getTokenType() != - sign2.getTokenType()) { + if (!sign1.getTokenType().equals(sign2.getTokenType())) { return false; } final PsiExpression lhs1 = assignExp1.getLExpression(); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/InitializationReadUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/InitializationReadUtils.java index 732ae9d8ee37..0192fc506209 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/InitializationReadUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/InitializationReadUtils.java @@ -181,8 +181,7 @@ public class InitializationReadUtils { if (expressionMustAssignVariable(field, condition, checkedMethods)) { return true; } - final PsiExpression test = condition; - if (BoolUtils.isTrue(test)) { + if (BoolUtils.isTrue(condition)) { final PsiStatement body = whileStatement.getBody(); if (statementMustAssignVariable(field, body, checkedMethods)) { return true; diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/InitializationUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/InitializationUtils.java index c00fdf3f9855..86ad33a4bb51 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/InitializationUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/InitializationUtils.java @@ -12,28 +12,33 @@ public class InitializationUtils { super(); } - public static boolean blockMustAssignVariable(PsiVariable field, PsiCodeBlock block) { - return cachingblockMustAssignVariable(field, block, new HashSet()); + public static boolean blockMustAssignVariableOrFail(PsiVariable field, PsiCodeBlock block) { + return cachingblockMustAssignVariableOrFail(field, block, new HashSet()); } - private static boolean cachingblockMustAssignVariable(PsiVariable field, PsiCodeBlock block, Set checkedMethods) { + private static boolean cachingblockMustAssignVariableOrFail(PsiVariable field, PsiCodeBlock block, Set checkedMethods) { if (block == null) { return false; } final PsiStatement[] statements = block.getStatements(); for (int i = 0; i < statements.length; i++) { final PsiStatement statement = statements[i]; - if (statementMustAssignVariable(field, statement, checkedMethods)) { + if (statementMustAssignVariableOrFail(field, statement, checkedMethods)) { return true; } } return false; } - private static boolean statementMustAssignVariable(PsiVariable field, PsiStatement statement, Set checkedMethods) { + + private static boolean statementMustAssignVariableOrFail(PsiVariable field, PsiStatement statement, Set checkedMethods) { if (statement == null) { return false; } + if(statementMustThrowException(statement)) + { + return true; + } if (statement instanceof PsiBreakStatement || statement instanceof PsiContinueStatement || statement instanceof PsiAssertStatement || @@ -42,18 +47,18 @@ public class InitializationUtils { } else if (statement instanceof PsiReturnStatement) { final PsiReturnStatement returnStatement = (PsiReturnStatement) statement; final PsiExpression returnValue = returnStatement.getReturnValue(); - return expressionMustAssignVariable(field, returnValue, checkedMethods); + return expressionMustAssignVariableOrFail(field, returnValue, checkedMethods); } else if (statement instanceof PsiThrowStatement) { final PsiThrowStatement throwStatement = (PsiThrowStatement) statement; final PsiExpression exception = throwStatement.getException(); - return expressionMustAssignVariable(field, exception, checkedMethods); + return expressionMustAssignVariableOrFail(field, exception, checkedMethods); } else if (statement instanceof PsiExpressionListStatement) { final PsiExpressionListStatement list = (PsiExpressionListStatement) statement; final PsiExpressionList expressionList = list.getExpressionList(); final PsiExpression[] expressions = expressionList.getExpressions(); for (int i = 0; i < expressions.length; i++) { final PsiExpression expression = expressions[i]; - if (expressionMustAssignVariable(field, expression, checkedMethods)) { + if (expressionMustAssignVariableOrFail(field, expression, checkedMethods)) { return true; } } @@ -61,31 +66,31 @@ public class InitializationUtils { } else if (statement instanceof PsiExpressionStatement) { final PsiExpressionStatement expressionStatement = (PsiExpressionStatement) statement; final PsiExpression expression = expressionStatement.getExpression(); - return expressionMustAssignVariable(field, expression, checkedMethods); + return expressionMustAssignVariableOrFail(field, expression, checkedMethods); } else if (statement instanceof PsiDeclarationStatement) { - return declarationStatementMustAssignVariable(field, (PsiDeclarationStatement) statement, checkedMethods); + return declarationStatementMustAssignVariableOrFail(field, (PsiDeclarationStatement) statement, checkedMethods); } else if (statement instanceof PsiForStatement) { - return forStatementMustAssignVariable(field, (PsiForStatement) statement, checkedMethods); + return forStatementMustAssignVariableOrFail(field, (PsiForStatement) statement, checkedMethods); } else if (statement instanceof PsiForeachStatement) { - return foreachStatementMustAssignVariable(field, (PsiForeachStatement) statement); + return foreachStatementMustAssignVariableOrFail(field, (PsiForeachStatement) statement); } else if (statement instanceof PsiWhileStatement) { - return whileStatementMustAssignVariable(field, (PsiWhileStatement) statement, checkedMethods); + return whileStatementMustAssignVariableOrFail(field, (PsiWhileStatement) statement, checkedMethods); } else if (statement instanceof PsiDoWhileStatement) { - return doWhileMustAssignVariable(field, (PsiDoWhileStatement) statement, checkedMethods); + return doWhileMustAssignVariableOrFail(field, (PsiDoWhileStatement) statement, checkedMethods); } else if (statement instanceof PsiSynchronizedStatement) { final PsiCodeBlock body = ((PsiSynchronizedStatement) statement).getBody(); - return cachingblockMustAssignVariable(field, body, checkedMethods); + return cachingblockMustAssignVariableOrFail(field, body, checkedMethods); } else if (statement instanceof PsiBlockStatement) { final PsiCodeBlock codeBlock = ((PsiBlockStatement) statement).getCodeBlock(); - return cachingblockMustAssignVariable(field, codeBlock, checkedMethods); + return cachingblockMustAssignVariableOrFail(field, codeBlock, checkedMethods); } else if (statement instanceof PsiLabeledStatement) { final PsiLabeledStatement labeledStatement = (PsiLabeledStatement) statement; final PsiStatement statementLabeled = labeledStatement.getStatement(); - return statementMustAssignVariable(field, statementLabeled, checkedMethods); + return statementMustAssignVariableOrFail(field, statementLabeled, checkedMethods); } else if (statement instanceof PsiIfStatement) { - return ifStatementMustAssignVariable(field, (PsiIfStatement) statement, checkedMethods); + return ifStatementMustAssignVariableOrFail(field, (PsiIfStatement) statement, checkedMethods); } else if (statement instanceof PsiTryStatement) { - return tryStatementMustAssignVariable(field, (PsiTryStatement) statement, checkedMethods); + return tryStatementMustAssignVariableOrFail(field, (PsiTryStatement) statement, checkedMethods); } else if (statement instanceof PsiSwitchStatement) { return false; } else // unknown statement type @@ -94,92 +99,91 @@ public class InitializationUtils { } } - private static boolean declarationStatementMustAssignVariable(PsiVariable field, + private static boolean declarationStatementMustAssignVariableOrFail(PsiVariable field, PsiDeclarationStatement declarationStatement, Set checkedMethods) { final PsiElement[] elements = declarationStatement.getDeclaredElements(); for (int i = 0; i < elements.length; i++) { final PsiVariable variable = (PsiVariable) elements[i]; final PsiExpression initializer = variable.getInitializer(); - if (expressionMustAssignVariable(field, initializer, checkedMethods)) { + if (expressionMustAssignVariableOrFail(field, initializer, checkedMethods)) { return true; } } return false; } - private static boolean tryStatementMustAssignVariable(PsiVariable field, PsiTryStatement tryStatement, Set checkedMethods) { + private static boolean tryStatementMustAssignVariableOrFail(PsiVariable field, PsiTryStatement tryStatement, Set checkedMethods) { final PsiCodeBlock[] catchBlocks = tryStatement.getCatchBlocks(); if (catchBlocks.length == 0) { final PsiCodeBlock tryBlock = tryStatement.getTryBlock(); - if (cachingblockMustAssignVariable(field, tryBlock, checkedMethods)) { + if (cachingblockMustAssignVariableOrFail(field, tryBlock, checkedMethods)) { return true; } } final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock(); - return cachingblockMustAssignVariable(field, finallyBlock, checkedMethods); + return cachingblockMustAssignVariableOrFail(field, finallyBlock, checkedMethods); } - private static boolean ifStatementMustAssignVariable(PsiVariable field, PsiIfStatement ifStatement, Set checkedMethods) { + private static boolean ifStatementMustAssignVariableOrFail(PsiVariable field, PsiIfStatement ifStatement, Set checkedMethods) { final PsiExpression condition = ifStatement.getCondition(); - if (expressionMustAssignVariable(field, condition, checkedMethods)) { + if (expressionMustAssignVariableOrFail(field, condition, checkedMethods)) { return true; } final PsiStatement thenBranch = ifStatement.getThenBranch(); final PsiStatement elseBranch = ifStatement.getElseBranch(); - return statementMustAssignVariable(field, thenBranch, checkedMethods) && - statementMustAssignVariable(field, elseBranch, checkedMethods); + return statementMustAssignVariableOrFail(field, thenBranch, checkedMethods) && + statementMustAssignVariableOrFail(field, elseBranch, checkedMethods); } - private static boolean doWhileMustAssignVariable(PsiVariable field, PsiDoWhileStatement doWhileStatement, Set checkedMethods) { + private static boolean doWhileMustAssignVariableOrFail(PsiVariable field, PsiDoWhileStatement doWhileStatement, Set checkedMethods) { final PsiExpression condition = doWhileStatement.getCondition(); final PsiStatement body = doWhileStatement.getBody(); - return expressionMustAssignVariable(field, condition, checkedMethods) || - statementMustAssignVariable(field, body, checkedMethods); + return expressionMustAssignVariableOrFail(field, condition, checkedMethods) || + statementMustAssignVariableOrFail(field, body, checkedMethods); } - private static boolean whileStatementMustAssignVariable(PsiVariable field, PsiWhileStatement whileStatement, Set checkedMethods) { + private static boolean whileStatementMustAssignVariableOrFail(PsiVariable field, PsiWhileStatement whileStatement, Set checkedMethods) { final PsiExpression condition = whileStatement.getCondition(); - if (expressionMustAssignVariable(field, condition, checkedMethods)) { + if (expressionMustAssignVariableOrFail(field, condition, checkedMethods)) { return true; } - final PsiExpression test = condition; - if (BoolUtils.isTrue(test)) { + if (BoolUtils.isTrue(condition)) { final PsiStatement body = whileStatement.getBody(); - if (statementMustAssignVariable(field, body, checkedMethods)) { + if (statementMustAssignVariableOrFail(field, body, checkedMethods)) { return true; } } return false; } - private static boolean forStatementMustAssignVariable(PsiVariable field, PsiForStatement forStatement, Set checkedMethods) { + private static boolean forStatementMustAssignVariableOrFail(PsiVariable field, PsiForStatement forStatement, Set checkedMethods) { final PsiStatement initialization = forStatement.getInitialization(); - if (statementMustAssignVariable(field, initialization, checkedMethods)) { + if (statementMustAssignVariableOrFail(field, initialization, checkedMethods)) { return true; } final PsiExpression test = forStatement.getCondition(); - if (expressionMustAssignVariable(field, test, checkedMethods)) { + if (expressionMustAssignVariableOrFail(field, test, checkedMethods)) { return true; } if (BoolUtils.isTrue(test)) { final PsiStatement body = forStatement.getBody(); - if (statementMustAssignVariable(field, body, checkedMethods)) { + if (statementMustAssignVariableOrFail(field, body, checkedMethods)) { return true; } final PsiStatement update = forStatement.getUpdate(); - if (statementMustAssignVariable(field, update, checkedMethods)) { + if (statementMustAssignVariableOrFail(field, update, checkedMethods)) { return true; } } return false; } - private static boolean foreachStatementMustAssignVariable(PsiVariable field, PsiForeachStatement forStatement) { + private static boolean foreachStatementMustAssignVariableOrFail(PsiVariable field, PsiForeachStatement forStatement) { return false; } - private static boolean expressionMustAssignVariable(PsiVariable field, PsiExpression expression, Set checkedMethods) { + private static boolean expressionMustAssignVariableOrFail(PsiVariable field, PsiExpression expression, Set checkedMethods) { if (expression == null) { return false; } @@ -191,16 +195,16 @@ public class InitializationUtils { } else if (expression instanceof PsiReferenceExpression) { return false; } else if (expression instanceof PsiMethodCallExpression) { - return methodCallMustAssignVariable(expression, field, checkedMethods); + return methodCallMustAssignVariableOrFail(expression, field, checkedMethods); } else if (expression instanceof PsiNewExpression) { - return newExpressionMustAssignVariable(expression, field, checkedMethods); + return newExpressionMustAssignVariableOrFail(expression, field, checkedMethods); } else if (expression instanceof PsiArrayInitializerExpression) { final PsiArrayInitializerExpression array = (PsiArrayInitializerExpression) expression; final PsiExpression[] initializers = array.getInitializers(); for (int i = 0; i < initializers.length; i++) { final PsiExpression initializer = initializers[i]; - if (expressionMustAssignVariable(field, initializer, checkedMethods)) { + if (expressionMustAssignVariableOrFail(field, initializer, checkedMethods)) { return true; } } @@ -208,45 +212,45 @@ public class InitializationUtils { } else if (expression instanceof PsiTypeCastExpression) { final PsiTypeCastExpression typeCast = (PsiTypeCastExpression) expression; final PsiExpression operand = typeCast.getOperand(); - return expressionMustAssignVariable(field, operand, checkedMethods); + return expressionMustAssignVariableOrFail(field, operand, checkedMethods); } else if (expression instanceof PsiArrayAccessExpression) { final PsiArrayAccessExpression accessExpression = (PsiArrayAccessExpression) expression; final PsiExpression arrayExpression = accessExpression.getArrayExpression(); final PsiExpression indexExpression = accessExpression.getIndexExpression(); - return expressionMustAssignVariable(field, arrayExpression, checkedMethods) || - expressionMustAssignVariable(field, indexExpression, checkedMethods); + return expressionMustAssignVariableOrFail(field, arrayExpression, checkedMethods) || + expressionMustAssignVariableOrFail(field, indexExpression, checkedMethods); } else if (expression instanceof PsiPrefixExpression) { final PsiPrefixExpression prefixExpression = (PsiPrefixExpression) expression; final PsiExpression operand = prefixExpression.getOperand(); - return expressionMustAssignVariable(field, operand, checkedMethods); + return expressionMustAssignVariableOrFail(field, operand, checkedMethods); } else if (expression instanceof PsiPostfixExpression) { final PsiPostfixExpression postfixExpression = (PsiPostfixExpression) expression; final PsiExpression operand = postfixExpression.getOperand(); - return expressionMustAssignVariable(field, operand, checkedMethods); + return expressionMustAssignVariableOrFail(field, operand, checkedMethods); } else if (expression instanceof PsiBinaryExpression) { final PsiBinaryExpression binaryExpression = (PsiBinaryExpression) expression; final PsiExpression lhs = binaryExpression.getLOperand(); final PsiExpression rhs = binaryExpression.getROperand(); - return expressionMustAssignVariable(field, lhs, checkedMethods) || - expressionMustAssignVariable(field, rhs, checkedMethods); + return expressionMustAssignVariableOrFail(field, lhs, checkedMethods) || + expressionMustAssignVariableOrFail(field, rhs, checkedMethods); } else if (expression instanceof PsiConditionalExpression) { final PsiConditionalExpression conditional = (PsiConditionalExpression) expression; final PsiExpression condition = conditional.getCondition(); - if (expressionMustAssignVariable(field, condition, checkedMethods)) { + if (expressionMustAssignVariableOrFail(field, condition, checkedMethods)) { return true; } final PsiExpression thenExpression = conditional.getThenExpression(); final PsiExpression elseExpression = conditional.getElseExpression(); - return expressionMustAssignVariable(field, thenExpression, checkedMethods) && - expressionMustAssignVariable(field, elseExpression, checkedMethods); + return expressionMustAssignVariableOrFail(field, thenExpression, checkedMethods) && + expressionMustAssignVariableOrFail(field, elseExpression, checkedMethods); } else if (expression instanceof PsiAssignmentExpression) { final PsiAssignmentExpression assignment = (PsiAssignmentExpression) expression; final PsiExpression lhs = assignment.getLExpression(); - if (expressionMustAssignVariable(field, lhs, checkedMethods)) { + if (expressionMustAssignVariableOrFail(field, lhs, checkedMethods)) { return true; } final PsiExpression rhs = assignment.getRExpression(); - if (expressionMustAssignVariable(field, rhs, checkedMethods)) { + if (expressionMustAssignVariableOrFail(field, rhs, checkedMethods)) { return true; } if (lhs instanceof PsiReferenceExpression) { @@ -263,7 +267,7 @@ public class InitializationUtils { } } - private static boolean newExpressionMustAssignVariable(PsiExpression expression, PsiVariable field, Set checkedMethods) { + private static boolean newExpressionMustAssignVariableOrFail(PsiExpression expression, PsiVariable field, Set checkedMethods) { final PsiNewExpression callExpression = (PsiNewExpression) expression; final PsiExpressionList argumentList = callExpression.getArgumentList(); @@ -271,20 +275,20 @@ public class InitializationUtils { final PsiExpression[] args = argumentList.getExpressions(); for (int i = 0; i < args.length; i++) { final PsiExpression arg = args[i]; - if (expressionMustAssignVariable(field, arg, checkedMethods)) { + if (expressionMustAssignVariableOrFail(field, arg, checkedMethods)) { return true; } } } final PsiArrayInitializerExpression arrayInitializer = callExpression.getArrayInitializer(); - if (expressionMustAssignVariable(field, arrayInitializer, checkedMethods)) { + if (expressionMustAssignVariableOrFail(field, arrayInitializer, checkedMethods)) { return true; } final PsiExpression[] arrayDimensions = callExpression.getArrayDimensions(); if (arrayDimensions != null) { for (int i = 0; i < arrayDimensions.length; i++) { final PsiExpression dim = arrayDimensions[i]; - if (expressionMustAssignVariable(field, dim, checkedMethods)) { + if (expressionMustAssignVariableOrFail(field, dim, checkedMethods)) { return true; } } @@ -292,19 +296,19 @@ public class InitializationUtils { return false; } - private static boolean methodCallMustAssignVariable(PsiExpression expression, PsiVariable field, Set checkedMethods) { + private static boolean methodCallMustAssignVariableOrFail(PsiExpression expression, PsiVariable field, Set checkedMethods) { final PsiMethodCallExpression callExpression = (PsiMethodCallExpression) expression; final PsiExpressionList argList = callExpression.getArgumentList(); final PsiExpression[] args = argList.getExpressions(); for (int i = 0; i < args.length; i++) { final PsiExpression arg = args[i]; - if (expressionMustAssignVariable(field, arg, checkedMethods)) { + if (expressionMustAssignVariableOrFail(field, arg, checkedMethods)) { return true; } } final PsiReferenceExpression methodExpression = callExpression.getMethodExpression(); - if (expressionMustAssignVariable(field, methodExpression, checkedMethods)) { + if (expressionMustAssignVariableOrFail(field, methodExpression, checkedMethods)) { return true; } final PsiMethod method = callExpression.resolveMethod(); @@ -331,8 +335,121 @@ public class InitializationUtils { || method.hasModifierProperty(PsiModifier.FINAL) || calledClass.hasModifierProperty(PsiModifier.FINAL)) { final PsiCodeBlock body = method.getBody(); - return cachingblockMustAssignVariable(field, body, checkedMethods); + return cachingblockMustAssignVariableOrFail(field, body, checkedMethods); } return false; } + + + private static boolean statementMustThrowException( PsiStatement statement) { + if (statement == null) { + return false; + } + if (statement instanceof PsiBreakStatement || + statement instanceof PsiContinueStatement || + statement instanceof PsiAssertStatement || + statement instanceof PsiReturnStatement || + statement instanceof PsiExpressionStatement || + statement instanceof PsiExpressionListStatement || + statement instanceof PsiForeachStatement || + statement instanceof PsiDeclarationStatement || + statement instanceof PsiEmptyStatement) { + return false; + } else if (statement instanceof PsiThrowStatement) { + return true; + } else if (statement instanceof PsiForStatement) { + return forStatementMustThrowException( (PsiForStatement) statement); + } else if (statement instanceof PsiWhileStatement) { + return whileStatementMustThrowException( (PsiWhileStatement) statement); + } else if (statement instanceof PsiDoWhileStatement) { + return doWhileMustThrowException( (PsiDoWhileStatement) statement); + } else if (statement instanceof PsiSynchronizedStatement) { + final PsiCodeBlock body = ((PsiSynchronizedStatement) statement).getBody(); + return blockMustThrowException( body); + } else if (statement instanceof PsiBlockStatement) { + final PsiCodeBlock codeBlock = ((PsiBlockStatement) statement).getCodeBlock(); + return blockMustThrowException( codeBlock); + } else if (statement instanceof PsiLabeledStatement) { + final PsiLabeledStatement labeledStatement = (PsiLabeledStatement) statement; + final PsiStatement statementLabeled = labeledStatement.getStatement(); + return statementMustThrowException( statementLabeled); + } else if (statement instanceof PsiIfStatement) { + return ifStatementMustThrowException( (PsiIfStatement) statement); + } else if (statement instanceof PsiTryStatement) { + return tryStatementMustThrowException( (PsiTryStatement) statement); + } else if (statement instanceof PsiSwitchStatement) { + return false; + } else // unknown statement type + { + return false; + } + } + + private static boolean blockMustThrowException(PsiCodeBlock block) { + if (block == null) { + return false; + } + final PsiStatement[] statements = block.getStatements(); + for (int i = 0; i < statements.length; i++) { + final PsiStatement statement = statements[i]; + if (statementMustThrowException(statement)) { + return true; + } + } + return false; + } + private static boolean tryStatementMustThrowException( PsiTryStatement tryStatement) { + final PsiCodeBlock[] catchBlocks = tryStatement.getCatchBlocks(); + if (catchBlocks.length == 0) { + final PsiCodeBlock tryBlock = tryStatement.getTryBlock(); + if (blockMustThrowException( tryBlock)) { + return true; + } + } + final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock(); + return blockMustThrowException( finallyBlock); + } + + private static boolean ifStatementMustThrowException( PsiIfStatement ifStatement) { + final PsiStatement thenBranch = ifStatement.getThenBranch(); + final PsiStatement elseBranch = ifStatement.getElseBranch(); + return statementMustThrowException( thenBranch) && + statementMustThrowException( elseBranch); + } + + private static boolean doWhileMustThrowException( PsiDoWhileStatement doWhileStatement) { + final PsiStatement body = doWhileStatement.getBody(); + return statementMustThrowException( body); + } + + private static boolean whileStatementMustThrowException( PsiWhileStatement whileStatement) { + final PsiExpression condition = whileStatement.getCondition(); + if (BoolUtils.isTrue(condition)) { + final PsiStatement body = whileStatement.getBody(); + if (statementMustThrowException( body)) { + return true; + } + } + return false; + } + + private static boolean forStatementMustThrowException( PsiForStatement forStatement) { + final PsiStatement initialization = forStatement.getInitialization(); + if (statementMustThrowException( initialization)) { + return true; + } + final PsiExpression test = forStatement.getCondition(); + if (BoolUtils.isTrue(test)) { + final PsiStatement body = forStatement.getBody(); + if (statementMustThrowException( body)) { + return true; + } + final PsiStatement update = forStatement.getUpdate(); + if (statementMustThrowException( update)) { + return true; + } + } + return false; + } + } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/SideEffectChecker.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/SideEffectChecker.java index d3640520f2c2..916c4848bd7d 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/SideEffectChecker.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/SideEffectChecker.java @@ -1,6 +1,7 @@ package com.siyeh.ig.psiutils; import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; public class SideEffectChecker { private SideEffectChecker() { @@ -50,8 +51,9 @@ public class SideEffectChecker { public void visitPostfixExpression(PsiPostfixExpression expression) { super.visitPostfixExpression(expression); final PsiJavaToken sign = expression.getOperationSign(); - if (sign.getTokenType() == JavaTokenType.PLUSPLUS || - sign.getTokenType() == JavaTokenType.PLUSPLUS) { + final IElementType tokenType = sign.getTokenType(); + if (tokenType.equals(JavaTokenType.PLUSPLUS) || + tokenType.equals(JavaTokenType.MINUSMINUS)) { m_mayHaveSideEffects = true; } } @@ -59,8 +61,9 @@ public class SideEffectChecker { public void visitPrefixExpression(PsiPrefixExpression expression) { super.visitPrefixExpression(expression); final PsiJavaToken sign = expression.getOperationSign(); - if (sign.getTokenType() == JavaTokenType.PLUSPLUS || - sign.getTokenType() == JavaTokenType.PLUSPLUS) { + final IElementType tokenType = sign.getTokenType(); + if (tokenType.equals(JavaTokenType.PLUSPLUS) || + tokenType.equals(JavaTokenType.MINUSMINUS)) { m_mayHaveSideEffects = true; } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/TypeUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/TypeUtils.java index 1a2fa6414366..0844485ea58b 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/TypeUtils.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/TypeUtils.java @@ -44,6 +44,10 @@ public class TypeUtils { if (type == null) { return false; } + return typeInherits(type, typeName); + } + + private static boolean typeInherits(final PsiType type, String typeName) { final String text = type.getCanonicalText(); if(typeName.equals(text)) { @@ -51,8 +55,7 @@ public class TypeUtils { } final PsiType[] superTypes = type.getSuperTypes(); for (int i = 0; i < superTypes.length; i++) { - final String superTypeName = superTypes[i].getCanonicalText(); - if (typeName.equals(superTypeName)) { + if (typeInherits(superTypes[i], typeName)) { return true; } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/VariableAssignedVisitor.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/VariableAssignedVisitor.java index b1a260e07d41..9e9581effff6 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/VariableAssignedVisitor.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/VariableAssignedVisitor.java @@ -1,6 +1,7 @@ package com.siyeh.ig.psiutils; import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; public class VariableAssignedVisitor extends PsiRecursiveElementVisitor { private boolean assigned = false; @@ -37,6 +38,56 @@ public class VariableAssignedVisitor extends PsiRecursiveElementVisitor { } } + public void visitPrefixExpression(PsiPrefixExpression prefixExpression) { + super.visitPrefixExpression(prefixExpression); + final PsiJavaToken operationSign = prefixExpression.getOperationSign(); + if(operationSign == null) + { + return; + } + final IElementType tokenType = operationSign.getTokenType(); + if (!tokenType.equals(JavaTokenType.PLUSPLUS) && + !tokenType.equals(JavaTokenType.MINUSMINUS)) { + return; + } + final PsiExpression operand = prefixExpression.getOperand(); + if (!(operand instanceof PsiReferenceExpression)) { + return; + } + final PsiElement referent = ((PsiReference) operand).resolve(); + if (referent == null) { + return; + } + if (referent.equals(variable)) { + assigned = true; + } + } + + public void visitPostfixExpression(PsiPostfixExpression postfixExpression) { + super.visitPostfixExpression(postfixExpression); + final PsiJavaToken operationSign = postfixExpression.getOperationSign(); + if(operationSign == null) + { + return; + } + final IElementType tokenType = operationSign.getTokenType(); + if (!tokenType.equals(JavaTokenType.PLUSPLUS) && + !tokenType.equals(JavaTokenType.MINUSMINUS)) { + return; + } + final PsiExpression operand = postfixExpression.getOperand(); + if (!(operand instanceof PsiReferenceExpression)) { + return; + } + final PsiElement referent = ((PsiReference) operand).resolve(); + if (referent == null) { + return; + } + if (referent.equals(variable)) { + assigned = true; + } + } + public boolean isAssigned() { return assigned; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/VariablePassedAsArgumentVisitor.java b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/VariablePassedAsArgumentVisitor.java index f682f9318eb2..eecaec637c05 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/VariablePassedAsArgumentVisitor.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/psiutils/VariablePassedAsArgumentVisitor.java @@ -56,14 +56,13 @@ public class VariablePassedAsArgumentVisitor extends PsiRecursiveElementVisitor } for (int i = 0; i < args.length; i++) { final PsiExpression arg = args[i]; - if (arg instanceof PsiReferenceExpression) { + if (arg!=null && arg instanceof PsiReferenceExpression) { final PsiElement referent = ((PsiReference) arg).resolve(); - if (referent.equals(variable)) { + if (referent!=null && referent.equals(variable)) { passed = true; } } } - } public boolean isPassed() {