From 0b282e2fa6b1e77580f275505dc102bbcb05a078 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 6 Apr 2022 12:17:49 +0200 Subject: [PATCH] IG: ignore expression when it is the only expression in the method (IDEA-175157) for "Overly complex boolean expression" and "Overly complex arithmetic expression" inspections GitOrigin-RevId: 6d5bc797ba206650809135c0b5f28712968b0464 --- .../siyeh/ig/psiutils/ExpressionUtils.java | 53 +++++-------------- ...rlyComplexBooleanExpressionInspection.java | 8 ++- ...ComplexArithmeticExpressionInspection.java | 52 +++++++----------- .../OverlyComplexBooleanExpression.java | 2 + 4 files changed, 42 insertions(+), 73 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java index f2d00a97b8a7..cb39ee8d3f1a 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ExpressionUtils.java @@ -3,7 +3,6 @@ package com.siyeh.ig.psiutils; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.CodeInsightUtilCore; -import com.intellij.codeInsight.NullableNotNullManager; import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil; import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil; import com.intellij.codeInspection.dataFlow.ContractReturnValue; @@ -40,7 +39,7 @@ import static com.intellij.util.ObjectUtils.tryCast; public final class ExpressionUtils { private static final @NonNls Set IMPLICIT_TO_STRING_METHOD_NAMES = Set.of("append", "format", "print", "printf", "println", "valueOf"); - @NonNls static final Set convertableBoxedClassNames = new HashSet<>(3); + @NonNls private static final Set convertableBoxedClassNames = new HashSet<>(3); static { convertableBoxedClassNames.add(CommonClassNames.JAVA_LANG_BYTE); @@ -434,19 +433,6 @@ public final class ExpressionUtils { return false; } - public static boolean isVariableGreaterThanComparison(@Nullable PsiExpression expression, @NotNull PsiVariable variable) { - PsiBinaryExpression binaryExpression = tryCast(PsiUtil.skipParenthesizedExprDown(expression), PsiBinaryExpression.class); - if (binaryExpression == null) return false; - final IElementType tokenType = binaryExpression.getOperationTokenType(); - if (tokenType.equals(JavaTokenType.GT) || tokenType.equals(JavaTokenType.GE)) { - return isReferenceTo(binaryExpression.getLOperand(), variable); - } - else if (tokenType.equals(JavaTokenType.LT) || tokenType.equals(JavaTokenType.LE)) { - return isReferenceTo(binaryExpression.getROperand(), variable); - } - return false; - } - /** * Returns true if given expression is an operand of String concatenation. * Also works if expression parent is {@link PsiParenthesizedExpression}. @@ -734,30 +720,6 @@ public final class ExpressionUtils { return type != null && type.equalsToText(CommonClassNames.JAVA_LANG_STRING); } - public static boolean isAnnotatedNotNull(PsiExpression expression) { - return isAnnotated(expression, false); - } - - public static boolean isAnnotatedNullable(PsiExpression expression) { - return isAnnotated(expression, true); - } - - private static boolean isAnnotated(PsiExpression expression, boolean nullable) { - expression = PsiUtil.skipParenthesizedExprDown(expression); - if (!(expression instanceof PsiReferenceExpression)) { - return false; - } - final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression; - final PsiElement target = referenceExpression.resolve(); - if (!(target instanceof PsiModifierListOwner)) { - return false; - } - final PsiModifierListOwner modifierListOwner = (PsiModifierListOwner)target; - return nullable ? - NullableNotNullManager.isNullable(modifierListOwner): - NullableNotNullManager.isNotNull(modifierListOwner); - } - /** * Returns true if the expression can be moved to earlier point in program order without possible semantic change or * notable performance handicap. Examples of simple expressions are: @@ -1758,4 +1720,17 @@ public final class ExpressionUtils { } return true; } + + public static boolean isOnlyExpressionInMethod(PsiExpression expression) { + final PsiElement parent = expression.getParent(); + if (!(parent instanceof PsiReturnStatement)) { + return false; + } + final PsiElement grandParent = parent.getParent(); + if (!(grandParent instanceof PsiCodeBlock) || !(grandParent.getParent() instanceof PsiMethod)) { + return false; + } + final PsiCodeBlock codeBlock = (PsiCodeBlock)grandParent; + return codeBlock.getStatementCount() == 1; + } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/controlflow/OverlyComplexBooleanExpressionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/controlflow/OverlyComplexBooleanExpressionInspection.java index 350618852bc5..be9bc1d3cfa3 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/controlflow/OverlyComplexBooleanExpressionInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/controlflow/OverlyComplexBooleanExpressionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2020 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2022 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. @@ -23,6 +23,7 @@ import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.fixes.ExtractMethodFix; +import com.siyeh.ig.psiutils.ExpressionUtils; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -31,7 +32,7 @@ import java.util.HashSet; import java.util.Set; public class OverlyComplexBooleanExpressionInspection extends BaseInspection { - protected static final Set s_booleanOperators = new HashSet<>(5); + private static final Set s_booleanOperators = new HashSet<>(5); static { s_booleanOperators.add(JavaTokenType.ANDAND); s_booleanOperators.add(JavaTokenType.OROR); @@ -119,6 +120,9 @@ public class OverlyComplexBooleanExpressionInspection extends BaseInspection { if (m_ignorePureConjunctionsDisjunctions && isPureConjunctionDisjunction(expression)) { return; } + if (ExpressionUtils.isOnlyExpressionInMethod(expression)) { + return; + } registerError(expression, Integer.valueOf(numTerms)); } diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/numeric/OverlyComplexArithmeticExpressionInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/numeric/OverlyComplexArithmeticExpressionInspection.java index 704aa508c79f..7937958d8577 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/numeric/OverlyComplexArithmeticExpressionInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/numeric/OverlyComplexArithmeticExpressionInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2011 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2022 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. @@ -23,6 +23,7 @@ import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.fixes.ExtractMethodFix; +import com.siyeh.ig.psiutils.ExpressionUtils; import com.siyeh.ig.psiutils.TypeUtils; import org.jetbrains.annotations.NotNull; @@ -30,11 +31,9 @@ import javax.swing.*; import java.util.HashSet; import java.util.Set; -public class OverlyComplexArithmeticExpressionInspection - extends BaseInspection { +public class OverlyComplexArithmeticExpressionInspection extends BaseInspection { - protected static final Set arithmeticTokens = - new HashSet<>(5); + private static final Set arithmeticTokens = new HashSet<>(5); private static final int TERM_LIMIT = 6; static { @@ -53,8 +52,7 @@ public class OverlyComplexArithmeticExpressionInspection @Override public JComponent createOptionsPanel() { return new SingleIntegerFieldOptionsPanel( - InspectionGadgetsBundle.message( - "overly.complex.arithmetic.expression.max.number.option"), + InspectionGadgetsBundle.message("overly.complex.arithmetic.expression.max.number.option"), this, "m_limit"); } @@ -66,8 +64,7 @@ public class OverlyComplexArithmeticExpressionInspection @Override @NotNull protected String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "overly.complex.arithmetic.expression.problem.descriptor"); + return InspectionGadgetsBundle.message("overly.complex.arithmetic.expression.problem.descriptor"); } @Override @@ -80,8 +77,7 @@ public class OverlyComplexArithmeticExpressionInspection return new OverlyComplexArithmeticExpressionVisitor(); } - private class OverlyComplexArithmeticExpressionVisitor - extends BaseInspectionVisitor { + private class OverlyComplexArithmeticExpressionVisitor extends BaseInspectionVisitor { @Override public void visitPolyadicExpression(PsiPolyadicExpression expression) { @@ -90,30 +86,32 @@ public class OverlyComplexArithmeticExpressionInspection } @Override - public void visitPrefixExpression( - @NotNull PsiPrefixExpression expression) { + public void visitPrefixExpression(@NotNull PsiPrefixExpression expression) { super.visitPrefixExpression(expression); checkExpression(expression); } @Override - public void visitParenthesizedExpression( - PsiParenthesizedExpression expression) { + public void visitParenthesizedExpression(PsiParenthesizedExpression expression) { super.visitParenthesizedExpression(expression); checkExpression(expression); } private void checkExpression(PsiExpression expression) { - if (isParentArithmetic(expression)) { + if (!isArithmetic(expression)) { return; } - if (!isArithmetic(expression)) { + final PsiElement parent = expression.getParent(); + if (parent instanceof PsiExpression && isArithmetic((PsiExpression)parent)) { return; } final int numTerms = countTerms(expression); if (numTerms <= m_limit) { return; } + if (ExpressionUtils.isOnlyExpressionInMethod(expression)) { + return; + } registerError(expression); } @@ -130,25 +128,18 @@ public class OverlyComplexArithmeticExpressionInspection return count; } else if (expression instanceof PsiPrefixExpression) { - final PsiPrefixExpression prefixExpression = - (PsiPrefixExpression)expression; + final PsiPrefixExpression prefixExpression = (PsiPrefixExpression)expression; final PsiExpression operand = prefixExpression.getOperand(); return countTerms(operand); } else if (expression instanceof PsiParenthesizedExpression) { - final PsiParenthesizedExpression parenthesizedExpression = - (PsiParenthesizedExpression)expression; + final PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression)expression; final PsiExpression contents = parenthesizedExpression.getExpression(); return countTerms(contents); } return 1; } - private boolean isParentArithmetic(PsiExpression expression) { - final PsiElement parent = expression.getParent(); - return parent instanceof PsiExpression && isArithmetic((PsiExpression)parent); - } - private boolean isArithmetic(PsiExpression expression) { if (expression instanceof PsiPolyadicExpression) { final PsiType type = expression.getType(); @@ -159,15 +150,12 @@ public class OverlyComplexArithmeticExpressionInspection return arithmeticTokens.contains(binaryExpression.getOperationTokenType()); } else if (expression instanceof PsiPrefixExpression) { - final PsiPrefixExpression prefixExpression = - (PsiPrefixExpression)expression; + final PsiPrefixExpression prefixExpression = (PsiPrefixExpression)expression; return arithmeticTokens.contains(prefixExpression.getOperationTokenType()); } else if (expression instanceof PsiParenthesizedExpression) { - final PsiParenthesizedExpression parenthesizedExpression = - (PsiParenthesizedExpression)expression; - final PsiExpression contents = - parenthesizedExpression.getExpression(); + final PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression)expression; + final PsiExpression contents = parenthesizedExpression.getExpression(); return isArithmetic(contents); } return false; diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/overly_complex_boolean_expression/OverlyComplexBooleanExpression.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/overly_complex_boolean_expression/OverlyComplexBooleanExpression.java index 68731f4bdbab..485ca8e9a337 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/overly_complex_boolean_expression/OverlyComplexBooleanExpression.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/controlflow/overly_complex_boolean_expression/OverlyComplexBooleanExpression.java @@ -3,10 +3,12 @@ package com.siyeh.igtest.controlflow.overly_complex_boolean_expression; public class OverlyComplexBooleanExpression { boolean x(boolean b) { + System.out.println(); return b && b || b && b; } boolean ignore(boolean b) { + System.out.println(); return b || b || b || b; }