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
This commit is contained in:
Bas Leijdekkers
2022-04-06 14:11:27 +00:00
committed by intellij-monorepo-bot
parent 4cc6887377
commit 0b282e2fa6
4 changed files with 42 additions and 73 deletions
@@ -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<String> IMPLICIT_TO_STRING_METHOD_NAMES =
Set.of("append", "format", "print", "printf", "println", "valueOf");
@NonNls static final Set<String> convertableBoxedClassNames = new HashSet<>(3);
@NonNls private static final Set<String> 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;
}
}
@@ -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<IElementType> s_booleanOperators = new HashSet<>(5);
private static final Set<IElementType> 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));
}
@@ -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<IElementType> arithmeticTokens =
new HashSet<>(5);
private static final Set<IElementType> 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;
@@ -3,10 +3,12 @@ package com.siyeh.igtest.controlflow.overly_complex_boolean_expression;
public class OverlyComplexBooleanExpression {
boolean x(boolean b) {
System.out.println();
return <warning descr="Overly complex boolean expression (4 terms)">b && b || b && b</warning>;
}
boolean ignore(boolean b) {
System.out.println();
return b || b || b || b;
}