From 177684337a00bf773fa798d28e47d6abb70fa330 Mon Sep 17 00:00:00 2001 From: Dave Griffith Date: Thu, 3 Mar 2005 19:22:51 +0300 Subject: [PATCH] (no message) --- plugins/InspectionGadgets/Leftovers.txt | 2 +- .../ig/bugs/EmptyStatementBodyInspection.java | 1 - .../bugs/FloatingPointEqualityInspection.java | 4 +- ...ableMethodCallInConstructorInspection.java | 9 +- ...ableHasSerializationMethodsInspection.java | 4 +- .../siyeh/ig/verbose/ConditionalUtils.java | 75 +++ .../siyeh/ig/verbose/TrivialIfInspection.java | 513 +++++++++++++++--- .../igtest/verbose/TrivialIfInspection.java | 14 + 8 files changed, 539 insertions(+), 83 deletions(-) create mode 100644 plugins/InspectionGadgets/src/com/siyeh/ig/verbose/ConditionalUtils.java diff --git a/plugins/InspectionGadgets/Leftovers.txt b/plugins/InspectionGadgets/Leftovers.txt index 3957291d9625..3fd9ddc428b1 100644 --- a/plugins/InspectionGadgets/Leftovers.txt +++ b/plugins/InspectionGadgets/Leftovers.txt @@ -28,9 +28,9 @@ Encapsulatable use of field While loop replaceable by for-each Acceptable name for type (Exceptions always e, Iterators always i) - Expand "Trivial If" inspection to cover same cases as the intention Flag inspections with default on-off and default warning level Inheritance as type def (change the EmptyClass inspection) + Fix damn "Instanceof Incompatible Interface" inspection Fix the "variable accessed in synchronized and unsynchronized contexts" to deal with unsynchronized private methods called only from synchronized contexts SerialVersionUID calculation diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java index d0a2d15ac752..a76e96fc49ac 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java @@ -104,7 +104,6 @@ public class EmptyStatementBodyInspection extends StatementInspection { if (isEmpty(elseBranch)) { final PsiElement elseToken = statement.getElseElement(); registerError(elseToken); - return; } } } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/FloatingPointEqualityInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/FloatingPointEqualityInspection.java index 5a1ea2c0c6f3..7317ee99eeb7 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/FloatingPointEqualityInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/FloatingPointEqualityInspection.java @@ -50,10 +50,10 @@ public class FloatingPointEqualityInspection extends ExpressionInspection { return; } final PsiExpression rhs = expression.getROperand(); - if (isFloatingPointType(rhs)) { - registerError(expression); + if(!isFloatingPointType(rhs)){ return; } + registerError(expression); } private static boolean isFloatingPointType(PsiExpression expression) { diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/initialization/OverridableMethodCallInConstructorInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/initialization/OverridableMethodCallInConstructorInspection.java index 0e5f65f4c269..7ba39e8c8e29 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/initialization/OverridableMethodCallInConstructorInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/initialization/OverridableMethodCallInConstructorInspection.java @@ -3,6 +3,7 @@ package com.siyeh.ig.initialization; import com.intellij.codeInspection.InspectionManager; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.InheritanceUtil; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.GroupNames; @@ -44,6 +45,11 @@ public class OverridableMethodCallInConstructorInspection extends MethodInspecti if (methodExpression == null) { return; } + if (methodExpression.isQualified() && + !(methodExpression.getQualifierExpression() instanceof PsiThisExpression)) + { + return; + } final PsiClass containingClass = method.getContainingClass(); if (containingClass == null) { return; @@ -59,7 +65,8 @@ public class OverridableMethodCallInConstructorInspection extends MethodInspecti return; } final PsiClass calledMethodClass = calledMethod.getContainingClass(); - if (!calledMethodClass.equals(containingClass)) { + if (!InheritanceUtil.isInheritorOrSelf(containingClass, calledMethodClass, true)) + { return; } registerMethodCallError(call); diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableHasSerializationMethodsInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableHasSerializationMethodsInspection.java index 03443879335e..0c1167e0c8ae 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableHasSerializationMethodsInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/serialization/SerializableHasSerializationMethodsInspection.java @@ -13,7 +13,7 @@ import com.siyeh.ig.ui.SingleCheckboxOptionsPanel; import javax.swing.*; public class SerializableHasSerializationMethodsInspection extends ClassInspection { - public boolean m_ignoreSerializableDueToInheritance = false; + public boolean m_ignoreSerializableDueToInheritance = true; public String getDisplayName() { return "Serializable class without 'readObject()' and 'writeObject()'"; @@ -67,7 +67,7 @@ public class SerializableHasSerializationMethodsInspection extends ClassInspecti } final boolean hasReadObject = SerializationUtils.hasReadObject(aClass); final boolean hasWriteObject = SerializationUtils.hasWriteObject(aClass); - + if (hasWriteObject && hasReadObject) { return; } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/verbose/ConditionalUtils.java b/plugins/InspectionGadgets/src/com/siyeh/ig/verbose/ConditionalUtils.java new file mode 100644 index 000000000000..b1fbffc3005e --- /dev/null +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/verbose/ConditionalUtils.java @@ -0,0 +1,75 @@ +package com.siyeh.ig.verbose; + +import com.intellij.psi.*; + +public class ConditionalUtils{ + private ConditionalUtils(){ + super(); + } + + public static PsiStatement stripBraces(PsiStatement branch){ + if(branch instanceof PsiBlockStatement){ + final PsiBlockStatement block = (PsiBlockStatement) branch; + final PsiCodeBlock codeBlock = block.getCodeBlock(); + final PsiStatement[] statements = codeBlock.getStatements(); + if(statements.length == 1){ + return statements[0]; + } else{ + return block; + } + } else{ + return branch; + } + } + + public static boolean isReturn(PsiStatement statement, String value){ + if(statement == null){ + return false; + } + if(!(statement instanceof PsiReturnStatement)){ + return false; + } + final PsiReturnStatement returnStatement = + (PsiReturnStatement) statement; + if(returnStatement.getReturnValue() == null){ + return false; + } + final PsiExpression returnValue = returnStatement.getReturnValue(); + final String returnValueText = returnValue.getText(); + return value.equals(returnValueText); + } + + public static boolean isAssignment(PsiStatement statement, String value){ + if(statement == null){ + return false; + } + if(!(statement instanceof PsiExpressionStatement)){ + return false; + } + final PsiExpressionStatement expressionStatement = + (PsiExpressionStatement) statement; + final PsiExpression expression = expressionStatement.getExpression(); + if(!(expression instanceof PsiAssignmentExpression)){ + return false; + } + final PsiAssignmentExpression assignment = + (PsiAssignmentExpression) expression; + final PsiExpression rhs = assignment.getRExpression(); + final PsiExpression lhs = assignment.getLExpression(); + if(lhs == null || rhs == null){ + return false; + } + final String rhsText = rhs.getText(); + return value.equals(rhsText); + } + + public static boolean isAssignment(PsiStatement statement){ + if(!(statement instanceof PsiExpressionStatement)){ + return false; + } + final PsiExpressionStatement expressionStatement = + (PsiExpressionStatement) statement; + final PsiExpression expression = expressionStatement.getExpression(); + return expression instanceof PsiAssignmentExpression; + } +} diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/verbose/TrivialIfInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/verbose/TrivialIfInspection.java index 01f8561fe482..71d41a1f24c3 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/verbose/TrivialIfInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/verbose/TrivialIfInspection.java @@ -6,56 +6,58 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.ReadonlyStatusHandler; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; import com.siyeh.ig.*; import com.siyeh.ig.psiutils.BoolUtils; import com.siyeh.ig.psiutils.ControlFlowUtils; import com.siyeh.ig.psiutils.ExpressionEquivalenceChecker; -public class TrivialIfInspection extends ExpressionInspection { +public class TrivialIfInspection extends ExpressionInspection{ private final TrivialIfFix fix = new TrivialIfFix(); - public String getDisplayName() { + public String getDisplayName(){ return "Unnecessary 'if' statement"; } - public String getGroupDisplayName() { + public String getGroupDisplayName(){ return GroupNames.VERBOSE_GROUP_NAME; } - protected BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, boolean onTheFly) { + protected BaseInspectionVisitor createVisitor(InspectionManager inspectionManager, + boolean onTheFly){ return new TrivialIfVisitor(this, inspectionManager, onTheFly); } - public String buildErrorString(PsiElement location) { - final PsiIfStatement ifStatement = (PsiIfStatement) location.getParent(); - final PsiExpression condition = ifStatement.getCondition(); - return "'if(" + condition.getText() + ")...' can be simplified to '" + - calculateReplacementStatement(ifStatement) + - "' #loc"; + public String buildErrorString(PsiElement location){ + return "#ref statement can be simplified #loc"; } - private static String calculateReplacementStatement(PsiIfStatement statement) { + private static String calculateReplacementStatement(PsiIfStatement statement){ PsiStatement thenBranch = statement.getThenBranch(); thenBranch = ControlFlowUtils.stripBraces(thenBranch); final PsiExpression condition = statement.getCondition(); final String replacementString; - if (thenBranch instanceof PsiReturnStatement) { - if (isReturn(thenBranch, "true")) { + if(thenBranch instanceof PsiReturnStatement){ + if(isReturn(thenBranch, "true")){ replacementString = "return " + condition.getText() + ';'; - } else { + } else{ replacementString = - "return " + BoolUtils.getNegatedExpressionText(condition) + ';'; + "return " + + BoolUtils.getNegatedExpressionText(condition) + ';'; } - } else { - final PsiExpressionStatement expressionStatement = (PsiExpressionStatement) thenBranch; - final PsiAssignmentExpression assignment = (PsiAssignmentExpression) expressionStatement.getExpression(); + } else{ + final PsiExpressionStatement expressionStatement = + (PsiExpressionStatement) thenBranch; + final PsiAssignmentExpression assignment = + (PsiAssignmentExpression) expressionStatement.getExpression(); final PsiExpression lhs = assignment.getLExpression(); final PsiJavaToken sign = assignment.getOperationSign(); - if (isAssignment(thenBranch, "true")) { + if(isAssignment(thenBranch, "true")){ replacementString = lhs.getText() + ' ' + sign.getText() + ' ' + condition.getText() + ';'; - } else { + } else{ replacementString = lhs.getText() + ' ' + sign.getText() + ' ' + BoolUtils.getNegatedExpressionText(condition) + ';'; @@ -64,124 +66,483 @@ public class TrivialIfInspection extends ExpressionInspection { return replacementString; } - public InspectionGadgetsFix buildFix(PsiElement location) { + public InspectionGadgetsFix buildFix(PsiElement location){ return fix; } - private static class TrivialIfFix extends InspectionGadgetsFix { - public String getName() { + private class TrivialIfFix extends InspectionGadgetsFix{ + public String getName(){ return "Simplify"; } - public void applyFix(Project project, ProblemDescriptor descriptor) { - if (ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(new VirtualFile[]{descriptor.getPsiElement().getContainingFile().getVirtualFile()}).hasReadonlyFiles()) return; + public void applyFix(Project project, ProblemDescriptor descriptor){ + if(ReadonlyStatusHandler.getInstance(project) + .ensureFilesWritable(new VirtualFile[]{descriptor.getPsiElement() + .getContainingFile() + .getVirtualFile()}) + .hasReadonlyFiles()){ + return; + } final PsiElement ifKeywordElement = descriptor.getPsiElement(); - final PsiIfStatement ifStatement = (PsiIfStatement) ifKeywordElement.getParent(); - final String newStatement = calculateReplacementStatement(ifStatement); - replaceStatement(project, ifStatement, newStatement); + final PsiIfStatement statement = + (PsiIfStatement) ifKeywordElement.getParent(); + try{ + if(isSimplifiableAssignment(statement)){ + replaceSimplifiableAssignment(statement, project); + } else if(isSimplifiableReturn(statement)){ + repaceSimplifiableReturn(statement, project); + } else if(isSimplifiableImplicitReturn(statement)){ + replaceSimplifiableImplicitReturn(statement, project); + } else if(isSimplifiableAssignmentNegated(statement)){ + replaceSimplifiableAssignmentNegated(statement, project); + } else if(isSimplifiableReturnNegated(statement)){ + repaceSimplifiableReturnNegated(statement, project); + } else if(isSimplifiableImplicitReturnNegated(statement)){ + replaceSimplifiableImplicitReturnNegated(statement, + project); + } else if(isSimplifiableImplicitAssignment(statement)){ + replaceSimplifiableImplicitAssignment(statement, project); + } else if(isSimplifiableImplicitAssignmentNegated(statement)){ + replaceSimplifiableImplicitAssignmentNegated(statement, + project); + } + } catch(IncorrectOperationException e){ + } + } + + private void replaceSimplifiableImplicitReturn(PsiIfStatement statement, + Project project) + throws IncorrectOperationException{ + final PsiExpression condition = statement.getCondition(); + final String conditionText = condition.getText(); + final PsiElement nextStatement = + PsiTreeUtil.skipSiblingsForward(statement, + new Class[]{PsiWhiteSpace.class}); + final String newStatement = "return " + conditionText + ';'; + replaceStatement(project, statement, newStatement); + nextStatement.delete(); + } + + private void repaceSimplifiableReturn(PsiIfStatement statement, + Project project) + throws IncorrectOperationException{ + final PsiExpression condition = statement.getCondition(); + final String conditionText = condition.getText(); + final String newStatement = "return " + conditionText + ';'; + replaceStatement(project, statement, newStatement); + } + + private void replaceSimplifiableAssignment(PsiIfStatement statement, + Project project) + throws IncorrectOperationException{ + final PsiExpression condition = statement.getCondition(); + final String conditionText = condition.getText(); + final PsiStatement thenBranch = statement.getThenBranch(); + final PsiExpressionStatement assignmentStatement = + (PsiExpressionStatement) ConditionalUtils.stripBraces(thenBranch); + final PsiAssignmentExpression assignmentExpression = + (PsiAssignmentExpression) assignmentStatement.getExpression(); + final PsiJavaToken operator = + assignmentExpression.getOperationSign(); + final String operand = operator.getText(); + final PsiExpression lhs = assignmentExpression.getLExpression(); + final String lhsText = lhs.getText(); + replaceStatement(project, + statement, + lhsText + operand + conditionText + ';'); + } + + private void replaceSimplifiableImplicitAssignment(PsiIfStatement statement, + Project project) + throws IncorrectOperationException{ + final PsiElement prevStatement = + PsiTreeUtil.skipSiblingsBackward(statement, + new Class[]{PsiWhiteSpace.class}); + + final PsiExpression condition = statement.getCondition(); + final String conditionText = condition.getText(); + final PsiStatement thenBranch = statement.getThenBranch(); + final PsiExpressionStatement assignmentStatement = + (PsiExpressionStatement) ConditionalUtils.stripBraces(thenBranch); + final PsiAssignmentExpression assignmentExpression = + (PsiAssignmentExpression) assignmentStatement.getExpression(); + final PsiJavaToken operator = + assignmentExpression.getOperationSign(); + final String operand = operator.getText(); + final PsiExpression lhs = assignmentExpression.getLExpression(); + final String lhsText = lhs.getText(); + replaceStatement(project, + statement, + lhsText + operand + conditionText + ';'); + prevStatement.delete(); + } + + private void replaceSimplifiableImplicitAssignmentNegated(PsiIfStatement statement, + Project project) + throws IncorrectOperationException{ + final PsiElement prevStatement = + PsiTreeUtil.skipSiblingsBackward(statement, + new Class[]{PsiWhiteSpace.class}); + + final PsiExpression condition = statement.getCondition(); + final String conditionText = + BoolUtils.getNegatedExpressionText(condition); + final PsiStatement thenBranch = statement.getThenBranch(); + final PsiExpressionStatement assignmentStatement = + (PsiExpressionStatement) ConditionalUtils.stripBraces(thenBranch); + final PsiAssignmentExpression assignmentExpression = + (PsiAssignmentExpression) assignmentStatement.getExpression(); + final PsiJavaToken operator = + assignmentExpression.getOperationSign(); + final String operand = operator.getText(); + final PsiExpression lhs = assignmentExpression.getLExpression(); + final String lhsText = lhs.getText(); + replaceStatement(project, + statement, + lhsText + operand + conditionText + ';'); + prevStatement.delete(); + } + + private void replaceSimplifiableImplicitReturnNegated(PsiIfStatement statement, + Project project) + throws IncorrectOperationException{ + final PsiExpression condition = statement.getCondition(); + + final String conditionText = + BoolUtils.getNegatedExpressionText(condition); + final PsiElement nextStatement = + PsiTreeUtil.skipSiblingsForward(statement, + new Class[]{PsiWhiteSpace.class}); + final String newStatement = "return " + conditionText + ';'; + replaceStatement(project, statement, newStatement); + nextStatement.delete(); + } + + private void repaceSimplifiableReturnNegated(PsiIfStatement statement, + Project project) + throws IncorrectOperationException{ + final PsiExpression condition = statement.getCondition(); + final String conditionText = + BoolUtils.getNegatedExpressionText(condition); + final String newStatement = "return " + conditionText + ';'; + replaceStatement(project, statement, newStatement); + } + + private void replaceSimplifiableAssignmentNegated(PsiIfStatement statement, + Project project) + throws IncorrectOperationException{ + final PsiExpression condition = statement.getCondition(); + final String conditionText = + BoolUtils.getNegatedExpressionText(condition); + final PsiStatement thenBranch = statement.getThenBranch(); + final PsiExpressionStatement assignmentStatement = + (PsiExpressionStatement) ConditionalUtils.stripBraces(thenBranch); + final PsiAssignmentExpression assignmentExpression = + (PsiAssignmentExpression) assignmentStatement.getExpression(); + final PsiJavaToken operator = + assignmentExpression.getOperationSign(); + final String operand = operator.getText(); + final PsiExpression lhs = assignmentExpression.getLExpression(); + final String lhsText = lhs.getText(); + replaceStatement(project, + statement, + lhsText + operand + conditionText + ';'); } } - private static class TrivialIfVisitor extends BaseInspectionVisitor { - private TrivialIfVisitor(BaseInspection inspection, InspectionManager inspectionManager, boolean isOnTheFly) { + private static class TrivialIfVisitor extends BaseInspectionVisitor{ + private TrivialIfVisitor(BaseInspection inspection, + InspectionManager inspectionManager, + boolean isOnTheFly){ super(inspection, inspectionManager, isOnTheFly); } - public void visitIfStatement(PsiIfStatement statement) { - super.visitIfStatement(statement); - if (statement.getCondition() == null) { + public void visitIfStatement(PsiIfStatement ifStatement){ + super.visitIfStatement(ifStatement); + if(isSimplifiableAssignment(ifStatement)){ + registerStatementError(ifStatement); return; } - PsiStatement thenBranch = statement.getThenBranch(); - if (thenBranch == null) { - return; - } - thenBranch = ControlFlowUtils.stripBraces(thenBranch); - PsiStatement elseBranch = statement.getElseBranch(); - if (elseBranch == null) { - return; - } - elseBranch = ControlFlowUtils.stripBraces(elseBranch); - if (isReturn(thenBranch, "true") && isReturn(elseBranch, "false")) { - registerStatementError(statement); + if(isSimplifiableReturn(ifStatement)){ + registerStatementError(ifStatement); return; } - if (isReturn(thenBranch, "false") && isReturn(elseBranch, "true")) { - registerStatementError(statement); + + if(isSimplifiableImplicitReturn(ifStatement)){ + registerStatementError(ifStatement); return; } - if (isAssignment(thenBranch, "true") && isAssignment(elseBranch, "false") && - areCompatibleAssignments(thenBranch, elseBranch)) { - registerStatementError(statement); + if(isSimplifiableAssignmentNegated(ifStatement)){ + registerStatementError(ifStatement); return; } - if (isAssignment(thenBranch, "false") && isAssignment(elseBranch, "true") && - areCompatibleAssignments(thenBranch, elseBranch)) { - registerStatementError(statement); + + if(isSimplifiableReturnNegated(ifStatement)){ + registerStatementError(ifStatement); + return; + } + + if(isSimplifiableImplicitReturnNegated(ifStatement)){ + registerStatementError(ifStatement); + return; + } + if(isSimplifiableImplicitAssignment(ifStatement)){ + registerStatementError(ifStatement); + return; + } + + if(isSimplifiableImplicitAssignmentNegated(ifStatement)){ + registerStatementError(ifStatement); return; } } - } - private static boolean isReturn(PsiStatement statement, String value) { - if (statement == null) { + public static boolean isSimplifiableImplicitReturn(PsiIfStatement ifStatement){ + PsiStatement thenBranch = ifStatement.getThenBranch(); + thenBranch = ConditionalUtils.stripBraces(thenBranch); + final PsiElement nextStatement = + PsiTreeUtil.skipSiblingsForward(ifStatement, + new Class[]{PsiWhiteSpace.class}); + if(!(nextStatement instanceof PsiStatement)){ return false; } - if (!(statement instanceof PsiReturnStatement)) { + final PsiStatement elseBranch = (PsiStatement) nextStatement; + if(ConditionalUtils.isReturn(thenBranch, "true") + && ConditionalUtils.isReturn(elseBranch, "false")){ + return true; + } + return false; + } + + public static boolean isSimplifiableImplicitReturnNegated(PsiIfStatement ifStatement){ + PsiStatement thenBranch = ifStatement.getThenBranch(); + thenBranch = ConditionalUtils.stripBraces(thenBranch); + + final PsiElement nextStatement = + PsiTreeUtil.skipSiblingsForward(ifStatement, + new Class[]{PsiWhiteSpace.class}); + if(!(nextStatement instanceof PsiStatement)){ return false; } - final PsiReturnStatement returnStatement = (PsiReturnStatement) statement; + final PsiStatement elseBranch = (PsiStatement) nextStatement; + if(ConditionalUtils.isReturn(thenBranch, "false") + && ConditionalUtils.isReturn(elseBranch, "true")){ + return true; + } + return false; + } + + public static boolean isSimplifiableReturn(PsiIfStatement ifStatement){ + PsiStatement thenBranch = ifStatement.getThenBranch(); + thenBranch = ConditionalUtils.stripBraces(thenBranch); + PsiStatement elseBranch = ifStatement.getElseBranch(); + elseBranch = ConditionalUtils.stripBraces(elseBranch); + if(ConditionalUtils.isReturn(thenBranch, "true") + && ConditionalUtils.isReturn(elseBranch, "false")){ + return true; + } + return false; + } + + public static boolean isSimplifiableReturnNegated(PsiIfStatement ifStatement){ + PsiStatement thenBranch = ifStatement.getThenBranch(); + thenBranch = ConditionalUtils.stripBraces(thenBranch); + PsiStatement elseBranch = ifStatement.getElseBranch(); + elseBranch = ConditionalUtils.stripBraces(elseBranch); + if(ConditionalUtils.isReturn(thenBranch, "false") + && ConditionalUtils.isReturn(elseBranch, "true")){ + return true; + } + return false; + } + + public static boolean isSimplifiableAssignment(PsiIfStatement ifStatement){ + PsiStatement thenBranch = ifStatement.getThenBranch(); + thenBranch = ConditionalUtils.stripBraces(thenBranch); + PsiStatement elseBranch = ifStatement.getElseBranch(); + elseBranch = ConditionalUtils.stripBraces(elseBranch); + if(ConditionalUtils.isAssignment(thenBranch, "true") && + ConditionalUtils.isAssignment(elseBranch, "false")){ + final PsiAssignmentExpression thenExpression = + (PsiAssignmentExpression) ((PsiExpressionStatement) thenBranch).getExpression(); + final PsiAssignmentExpression elseExpression = + (PsiAssignmentExpression) ((PsiExpressionStatement) elseBranch).getExpression(); + final PsiJavaToken thenSign = thenExpression.getOperationSign(); + final PsiJavaToken elseSign = elseExpression.getOperationSign(); + if(!thenSign.getTokenType().equals(elseSign.getTokenType())){ + return false; + } + final PsiExpression thenLhs = thenExpression.getLExpression(); + final PsiExpression elseLhs = elseExpression.getLExpression(); + return ExpressionEquivalenceChecker.expressionsAreEquivalent(thenLhs, + elseLhs); + } else{ + return false; + } + } + + public static boolean isSimplifiableAssignmentNegated(PsiIfStatement ifStatement){ + PsiStatement thenBranch = ifStatement.getThenBranch(); + thenBranch = ConditionalUtils.stripBraces(thenBranch); + PsiStatement elseBranch = ifStatement.getElseBranch(); + elseBranch = ConditionalUtils.stripBraces(elseBranch); + if(ConditionalUtils.isAssignment(thenBranch, "false") && + ConditionalUtils.isAssignment(elseBranch, "true")){ + final PsiAssignmentExpression thenExpression = + (PsiAssignmentExpression) ((PsiExpressionStatement) thenBranch).getExpression(); + final PsiAssignmentExpression elseExpression = + (PsiAssignmentExpression) ((PsiExpressionStatement) elseBranch).getExpression(); + final PsiJavaToken thenSign = thenExpression.getOperationSign(); + final PsiJavaToken elseSign = elseExpression.getOperationSign(); + if(!thenSign.getTokenType().equals(elseSign.getTokenType())){ + return false; + } + final PsiExpression thenLhs = thenExpression.getLExpression(); + final PsiExpression elseLhs = elseExpression.getLExpression(); + return ExpressionEquivalenceChecker.expressionsAreEquivalent(thenLhs, + elseLhs); + } else{ + return false; + } + } + + public static boolean isSimplifiableImplicitAssignment(PsiIfStatement ifStatement){ + if(ifStatement.getElseBranch() != null){ + return false; + } + PsiStatement thenBranch = ifStatement.getThenBranch(); + thenBranch = ConditionalUtils.stripBraces(thenBranch); + final PsiElement nextStatement = + PsiTreeUtil.skipSiblingsBackward(ifStatement, + new Class[]{PsiWhiteSpace.class}); + if(!(nextStatement instanceof PsiStatement)){ + return false; + } + PsiStatement elseBranch = (PsiStatement) nextStatement; + + elseBranch = ConditionalUtils.stripBraces(elseBranch); + if(ConditionalUtils.isAssignment(thenBranch, "true") && + ConditionalUtils.isAssignment(elseBranch, "false")){ + final PsiAssignmentExpression thenExpression = + (PsiAssignmentExpression) ((PsiExpressionStatement) thenBranch).getExpression(); + final PsiAssignmentExpression elseExpression = + (PsiAssignmentExpression) ((PsiExpressionStatement) elseBranch).getExpression(); + final PsiJavaToken thenSign = thenExpression.getOperationSign(); + final PsiJavaToken elseSign = elseExpression.getOperationSign(); + if(!thenSign.getTokenType().equals(elseSign.getTokenType())){ + return false; + } + final PsiExpression thenLhs = thenExpression.getLExpression(); + final PsiExpression elseLhs = elseExpression.getLExpression(); + return ExpressionEquivalenceChecker.expressionsAreEquivalent(thenLhs, + elseLhs); + } else{ + return false; + } + } + + public static boolean isSimplifiableImplicitAssignmentNegated(PsiIfStatement ifStatement){ + if(ifStatement.getElseBranch() != null){ + return false; + } + PsiStatement thenBranch = ifStatement.getThenBranch(); + thenBranch = ConditionalUtils.stripBraces(thenBranch); + final PsiElement nextStatement = + PsiTreeUtil.skipSiblingsBackward(ifStatement, + new Class[]{PsiWhiteSpace.class}); + if(!(nextStatement instanceof PsiStatement)){ + return false; + } + PsiStatement elseBranch = (PsiStatement) nextStatement; + + elseBranch = ConditionalUtils.stripBraces(elseBranch); + if(ConditionalUtils.isAssignment(thenBranch, "false") && + ConditionalUtils.isAssignment(elseBranch, "true")){ + final PsiAssignmentExpression thenExpression = + (PsiAssignmentExpression) ((PsiExpressionStatement) thenBranch).getExpression(); + final PsiAssignmentExpression elseExpression = + (PsiAssignmentExpression) ((PsiExpressionStatement) elseBranch).getExpression(); + final PsiJavaToken thenSign = thenExpression.getOperationSign(); + final PsiJavaToken elseSign = elseExpression.getOperationSign(); + if(!thenSign.getTokenType().equals(elseSign.getTokenType())){ + return false; + } + final PsiExpression thenLhs = thenExpression.getLExpression(); + final PsiExpression elseLhs = elseExpression.getLExpression(); + return ExpressionEquivalenceChecker.expressionsAreEquivalent(thenLhs, + elseLhs); + } else{ + return false; + } + } + + private static boolean isReturn(PsiStatement statement, String value){ + if(statement == null){ + return false; + } + if(!(statement instanceof PsiReturnStatement)){ + return false; + } + final PsiReturnStatement returnStatement = + (PsiReturnStatement) statement; final PsiExpression returnValue = returnStatement.getReturnValue(); - if (returnValue == null) { + if(returnValue == null){ return false; } final String returnValueString = returnValue.getText(); return value.equals(returnValueString); } - private static boolean isAssignment(PsiStatement statement, String value) { - if (statement == null) { + private static boolean isAssignment(PsiStatement statement, String value){ + if(statement == null){ return false; } - if (!(statement instanceof PsiExpressionStatement)) { + if(!(statement instanceof PsiExpressionStatement)){ return false; } - final PsiExpression expression = ((PsiExpressionStatement) statement).getExpression(); - if (!(expression instanceof PsiAssignmentExpression)) { + final PsiExpression expression = + ((PsiExpressionStatement) statement).getExpression(); + if(!(expression instanceof PsiAssignmentExpression)){ return false; } - final PsiExpression rhs = ((PsiAssignmentExpression) expression).getRExpression(); - if (rhs == null) { + final PsiExpression rhs = + ((PsiAssignmentExpression) expression).getRExpression(); + if(rhs == null){ return false; } final String rhsText = rhs.getText(); return value.equals(rhsText); } - private static boolean areCompatibleAssignments(PsiStatement statement1, PsiStatement statement2) { - final PsiExpressionStatement expressionStatement1 = (PsiExpressionStatement) statement1; - final PsiAssignmentExpression expression1 = (PsiAssignmentExpression) expressionStatement1.getExpression(); - final PsiExpressionStatement expressionStatement2 = (PsiExpressionStatement) statement2; - final PsiAssignmentExpression expression2 = (PsiAssignmentExpression) expressionStatement2.getExpression(); + private static boolean areCompatibleAssignments(PsiStatement statement1, + PsiStatement statement2){ + final PsiExpressionStatement expressionStatement1 = + (PsiExpressionStatement) statement1; + final PsiAssignmentExpression expression1 = + (PsiAssignmentExpression) expressionStatement1.getExpression(); + final PsiExpressionStatement expressionStatement2 = + (PsiExpressionStatement) statement2; + final PsiAssignmentExpression expression2 = + (PsiAssignmentExpression) expressionStatement2.getExpression(); final PsiJavaToken sign2 = expression2.getOperationSign(); - if (sign2 == null) { + if(sign2 == null){ return false; } final String operand2 = sign2.getText(); final PsiJavaToken sign1 = expression1.getOperationSign(); - if (sign1 == null) { + if(sign1 == null){ return false; } final String operand1 = sign1.getText(); - if (!operand2.equals(operand1)) { + if(!operand2.equals(operand1)){ return false; } final PsiExpression lhs1 = expression1.getLExpression(); final PsiExpression lhs2 = expression2.getLExpression(); - return ExpressionEquivalenceChecker.expressionsAreEquivalent(lhs1, lhs2); + return ExpressionEquivalenceChecker.expressionsAreEquivalent(lhs1, + lhs2); } - } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/verbose/TrivialIfInspection.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/verbose/TrivialIfInspection.java index 134908084d29..988d602b2201 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/verbose/TrivialIfInspection.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/verbose/TrivialIfInspection.java @@ -34,6 +34,20 @@ public class TrivialIfInspection } } + public boolean foo2() + { + boolean x; + x = true; + if(bar()) + { + x = false; + } + if(bar()) + { + return true; + } + return false; + } private boolean bar() { return true;