[java-inspections] IDEA-353938 Report ignored object allocations inside method references

GitOrigin-RevId: 1261b9bdb64bec0269fe7d0ffb2ac634e1494e81
This commit is contained in:
Tagir Valeev
2024-05-23 11:08:49 +00:00
committed by intellij-monorepo-bot
parent cbc1f20f8e
commit 5cc297d7ea
6 changed files with 44 additions and 2 deletions
@@ -148,6 +148,7 @@ octal.and.decimal.integers.in.same.array.display.name=Octal and decimal integers
octal.and.decimal.integers.in.same.array.problem.descriptor=Octal and decimal integers in the same array initializer #loc
result.of.object.allocation.ignored.display.name=Result of object allocation ignored
result.of.object.allocation.ignored.problem.descriptor=Result of <code>new #ref()</code> is ignored #loc
result.of.object.allocation.ignored.problem.descriptor.methodRef=Object allocated inside <code>#ref</code> is discarded #loc
result.of.object.allocation.ignored.options.chooserTitle=Choose Class for Which Object Allocation Can Be Ignored
result.of.object.allocation.fix.name=Ignore allocations of objects with type ''{0}''
use.0index.in.jdbc.resultset.display.name=Use of index 0 in JDBC ResultSet
@@ -212,8 +212,8 @@ public final class IgnoreResultOfCallInspection extends BaseInspection {
public void visitMethodReferenceExpression(@NotNull PsiMethodReferenceExpression expression) {
if (PsiTypes.voidType().equals(LambdaUtil.getFunctionalInterfaceReturnType(expression))) {
PsiElement resolve = expression.resolve();
if (resolve instanceof PsiMethod) {
visitCalledExpression(expression, (PsiMethod)resolve, null);
if (resolve instanceof PsiMethod method && !method.isConstructor()) {
visitCalledExpression(expression, method, null);
}
}
}
@@ -63,6 +63,9 @@ public final class ResultOfObjectAllocationIgnoredInspection extends BaseInspect
@Override
public @NotNull String buildErrorString(Object... infos) {
if (infos[0] instanceof PsiMethodReferenceExpression) {
return InspectionGadgetsBundle.message("result.of.object.allocation.ignored.problem.descriptor.methodRef");
}
return InspectionGadgetsBundle.message("result.of.object.allocation.ignored.problem.descriptor");
}
@@ -73,6 +76,23 @@ public final class ResultOfObjectAllocationIgnoredInspection extends BaseInspect
private class ResultOfObjectAllocationIgnoredVisitor extends BaseInspectionVisitor {
@Override
public void visitMethodReferenceExpression(@NotNull PsiMethodReferenceExpression expression) {
super.visitMethodReferenceExpression(expression);
if (PsiTypes.voidType().equals(LambdaUtil.getFunctionalInterfaceReturnType(expression))) {
if (expression.isConstructor()) {
PsiElement qualifier = expression.getQualifier();
if (qualifier instanceof PsiReferenceExpression ref && ref.resolve() instanceof PsiClass cls &&
!ignoredClasses.contains(cls.getQualifiedName())) {
registerError(expression, expression);
}
if (qualifier instanceof PsiTypeElement typeElement && typeElement.getType() instanceof PsiArrayType) {
registerError(expression, expression);
}
}
}
}
@Override
public void visitNewExpression(@NotNull PsiNewExpression expression) {
super.visitNewExpression(expression);
@@ -1,5 +1,7 @@
package com.siyeh.igtest.bugs.result_of_object_allocation_ignored;
import java.util.function.*;
public class ResultOfObjectAllocationIgnored {
private ResultOfObjectAllocationIgnored() {
@@ -25,4 +27,15 @@ public class ResultOfObjectAllocationIgnored {
default -> new Throwable();
};
}
void methodRef() {
Runnable simple = <warning descr="Object allocated inside 'Object::new' is discarded">Object::new</warning>;
Runnable impliciCtor = <warning descr="Object allocated inside 'Foo::new' is discarded">Foo::new</warning>;
Runnable qualified = <warning descr="Object allocated inside 'java.lang.Object::new' is discarded">java.lang.Object::new</warning>;
Runnable ignored = java.util.ArrayList::new;
IntConsumer primitiveArr = <warning descr="Object allocated inside 'int[]::new' is discarded">int[]::new</warning>;
IntConsumer objectArr = <warning descr="Object allocated inside 'Object[]::new' is discarded">Object[]::new</warning>;
}
class Foo {}
}
@@ -457,6 +457,7 @@ public class IgnoreResultOfCallInspectionTest extends LightJavaInspectionTestCas
static {
Runnable r = () -> Util./*Result of 'Util.util()' is ignored*/util/**/();
Runnable r1 = Util::/*Result of 'Util.util()' is ignored*/util/**/;
Runnable r2 = Object::new; // Reported by ResultOfObjectAllocationIgnoredInspection
}
}
""");
@@ -16,7 +16,9 @@
package com.siyeh.ig.bugs;
import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.testFramework.LightProjectDescriptor;
import com.siyeh.ig.LightJavaInspectionTestCase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -28,6 +30,11 @@ public class ResultOfObjectAllocationIgnoredInspectionTest extends LightJavaInsp
doTest();
}
@Override
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
return JAVA_21;
}
@Nullable
@Override
protected InspectionProfileEntry getInspection() {