Java: Improve the inspection "Multiple occurrences of the same expression" (IDEA-207247)

This commit is contained in:
Pavel Dolgov
2019-02-14 11:20:06 +03:00
parent fb8a56f765
commit 86bc525ead
9 changed files with 69 additions and 6 deletions
@@ -172,12 +172,13 @@ class ComplexityCalculator {
/**
* Quick check to filter out the obvious things early
*/
static boolean isDefinitelySimple(@Nullable PsiExpression expression, int threshold) {
static boolean isDefinitelySimple(@Nullable PsiExpression expression) {
if (expression instanceof PsiLiteral) {
return CONSTANT < threshold;
return true;
}
if (expression instanceof PsiReferenceExpression && ((PsiReferenceExpression)expression).getQualifierExpression() == null) {
return REFERENCE < threshold;
PsiElement resolved = ((PsiReferenceExpression)expression).resolve();
return resolved instanceof PsiVariable || resolved instanceof PsiClass;
}
return false;
}
@@ -64,8 +64,9 @@ public class DuplicateExpressionsInspection extends LocalInspectionTool {
}
public void visitExpressionImpl(PsiExpression expression) {
if (ComplexityCalculator.isDefinitelySimple(expression, complexityThreshold) ||
SideEffectCalculator.isDefinitelyWithSideEffect(expression)) {
if (ComplexityCalculator.isDefinitelySimple(expression) ||
SideEffectCalculator.isDefinitelyWithSideEffect(expression) ||
expression instanceof PsiLambdaExpression) {
return;
}
DuplicateExpressionsContext context = DuplicateExpressionsContext.getOrCreateContext(expression, session);
@@ -92,7 +92,7 @@ class SideEffectCalculator {
return true;
}
PsiElement resolved = ref.resolve();
if (resolved instanceof PsiLocalVariable || resolved instanceof PsiParameter) {
if (resolved instanceof PsiLocalVariable || resolved instanceof PsiParameter || resolved instanceof PsiClass) {
return false;
}
if (resolved instanceof PsiField) {
@@ -0,0 +1,20 @@
class C {
void test() {
accept(n -> n * n);
accept(n -> n * n);
accept(n -> {
int a = <weak_warning descr="Multiple occurrences of 'n * n'">n * n</weak_warning>;
int b = <weak_warning descr="Multiple occurrences of 'n * n'">n * n</weak_warning>;
return a + b;
});
}
void accept(I i) {
i.f(0);
}
interface I {
int f(int n);
}
}
@@ -0,0 +1,6 @@
class C {
void test(int i, int j) {
int a = <weak_warning descr="Multiple occurrences of 'Math.max(i, j)'">Math.max(i, j)</weak_warning>;
int b = <weak_warning descr="Multiple occurrences of 'Math.max(i, j)'">Math.max(i, j)</weak_warning>;
}
}
@@ -0,0 +1,6 @@
class C {
void test() {
double x = Math.random();
double y = Math.random();
}
}
@@ -0,0 +1,6 @@
class C {
void test() {
double x = <weak_warning descr="Multiple occurrences of 'Math.sin(4)'">Math.sin(4)</weak_warning>;
double y = <weak_warning descr="Multiple occurrences of 'Math.sin(4)'">Math.sin(4)</weak_warning>;
}
}
@@ -0,0 +1,18 @@
class C {
final int field;
C(int i) {
field = i;
}
void test(int param) {
int a = field;
int b = field;
int c = param;
int d = param;
int e = <weak_warning descr="Multiple occurrences of 'field + param'">field + param</weak_warning>;
int f = <weak_warning descr="Multiple occurrences of 'field + param'">field + param</weak_warning>;
}
}
@@ -29,6 +29,11 @@ class DuplicateExpressionsTest : LightCodeInsightFixtureTestCase() {
fun testVariableNotModified() = doTest(50)
fun testCompositeQualifier() = doTest(40)
fun testMethodCallWithSideEffect() = doTest(70)
fun testMathSin() = doTest(40)
fun testMathMax() = doTest(60)
fun testMathRandom() = doTest(1)
fun testVariable() = doTest(1)
fun testLambda() = doTest(20)
private fun doTest(threshold: Int = 50) {
val oldThreshold = inspection.complexityThreshold