mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-10 13:17:09 +07:00
enable suspicious collections method calls for method references (IDEA-165237)
This commit is contained in:
+19
-8
@@ -22,6 +22,9 @@ import com.intellij.codeInspection.InspectionsBundle;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.MethodSignature;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.IntArrayList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -54,17 +57,25 @@ public class SuspiciousCollectionsMethodCallsInspection extends BaseJavaBatchLoc
|
||||
final IntArrayList indices = new IntArrayList();
|
||||
return new JavaElementVisitor() {
|
||||
@Override
|
||||
public void visitReferenceExpression(final PsiReferenceExpression expression) {
|
||||
visitExpression(expression);
|
||||
public void visitMethodCallExpression(PsiMethodCallExpression methodCall) {
|
||||
final String message = getSuspiciousMethodCallMessage(methodCall, REPORT_CONVERTIBLE_METHOD_CALLS, patternMethods, indices);
|
||||
if (message != null) {
|
||||
holder.registerProblem(methodCall.getArgumentList().getExpressions()[0], message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodCallExpression(PsiMethodCallExpression methodCall) {
|
||||
super.visitMethodCallExpression(methodCall);
|
||||
final String message = getSuspiciousMethodCallMessage(methodCall, REPORT_CONVERTIBLE_METHOD_CALLS, patternMethods, indices
|
||||
);
|
||||
if (message != null) {
|
||||
holder.registerProblem(methodCall.getArgumentList().getExpressions()[0], message);
|
||||
public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) {
|
||||
final PsiType functionalInterfaceType = expression.getFunctionalInterfaceType();
|
||||
final PsiClassType.ClassResolveResult functionalInterfaceResolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
|
||||
final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType);
|
||||
if (interfaceMethod != null && interfaceMethod.getParameterList().getParametersCount() == 1) {
|
||||
final PsiSubstitutor psiSubstitutor = LambdaUtil.getSubstitutor(interfaceMethod, functionalInterfaceResolveResult);
|
||||
final MethodSignature signature = interfaceMethod.getSignature(psiSubstitutor);
|
||||
String message = SuspiciousMethodCallUtil.getSuspiciousMethodCallMessage(expression, signature.getParameterTypes()[0], REPORT_CONVERTIBLE_METHOD_CALLS, patternMethods, indices);
|
||||
if (message != null) {
|
||||
holder.registerProblem(ObjectUtils.notNull(expression.getReferenceNameElement(), expression), message);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
+20
-11
@@ -111,29 +111,38 @@ public class SuspiciousMethodCallUtil {
|
||||
@NotNull List<PsiMethod> patternMethods,
|
||||
@NotNull IntArrayList indices) {
|
||||
final PsiReferenceExpression methodExpression = methodCall.getMethodExpression();
|
||||
final PsiExpression qualifier = methodExpression.getQualifierExpression();
|
||||
if (qualifier == null || qualifier instanceof PsiThisExpression || qualifier instanceof PsiSuperExpression) return null;
|
||||
if (argType instanceof PsiPrimitiveType) {
|
||||
argType = ((PsiPrimitiveType)argType).getBoxedType(methodCall);
|
||||
}
|
||||
|
||||
if (argType == null) return null;
|
||||
|
||||
if (arg instanceof PsiConditionalExpression &&
|
||||
PsiPolyExpressionUtil.isPolyExpression(arg) &&
|
||||
argType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
|
||||
return null;
|
||||
}
|
||||
return getSuspiciousMethodCallMessage(methodExpression, argType, reportConvertibleMethodCalls, patternMethods, indices);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getSuspiciousMethodCallMessage(PsiReferenceExpression methodExpression,
|
||||
PsiType argType,
|
||||
boolean reportConvertibleMethodCalls,
|
||||
@NotNull List<PsiMethod> patternMethods,
|
||||
@NotNull IntArrayList indices) {
|
||||
final PsiExpression qualifier = methodExpression.getQualifierExpression();
|
||||
if (qualifier == null || qualifier instanceof PsiThisExpression || qualifier instanceof PsiSuperExpression) return null;
|
||||
if (argType instanceof PsiPrimitiveType) {
|
||||
argType = ((PsiPrimitiveType)argType).getBoxedType(methodExpression);
|
||||
}
|
||||
|
||||
if (argType == null) return null;
|
||||
|
||||
final JavaResolveResult resolveResult = methodExpression.advancedResolve(false);
|
||||
PsiMethod calleeMethod = (PsiMethod)resolveResult.getElement();
|
||||
if (calleeMethod == null) return null;
|
||||
PsiMethod contextMethod = PsiTreeUtil.getParentOfType(methodCall, PsiMethod.class);
|
||||
PsiMethod contextMethod = PsiTreeUtil.getParentOfType(methodExpression, PsiMethod.class);
|
||||
|
||||
//noinspection SynchronizationOnLocalVariableOrMethodParameter
|
||||
synchronized (patternMethods) {
|
||||
if (patternMethods.isEmpty()) {
|
||||
setupPatternMethods(methodCall.getManager(), methodCall.getResolveScope(), patternMethods, indices);
|
||||
setupPatternMethods(methodExpression.getManager(), methodExpression.getResolveScope(), patternMethods, indices);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,8 +180,8 @@ public class SuspiciousMethodCallUtil {
|
||||
final PsiType qualifierItemType = JavaGenericsUtil.getCollectionItemType(qualifierType, calleeMethod.getResolveScope());
|
||||
if (qualifierItemType != null && itemType != null && !qualifierItemType.isAssignableFrom(itemType)) {
|
||||
return InspectionsBundle.message("inspection.suspicious.collections.method.calls.problem.descriptor",
|
||||
PsiFormatUtil.formatType(qualifierType, 0, PsiSubstitutor.EMPTY),
|
||||
PsiFormatUtil.formatType(itemType, 0, PsiSubstitutor.EMPTY));
|
||||
PsiFormatUtil.formatType(qualifierType, 0, PsiSubstitutor.EMPTY),
|
||||
PsiFormatUtil.formatType(itemType, 0, PsiSubstitutor.EMPTY));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class JavaClass {
|
||||
{
|
||||
Map<String, String> key2name = new HashMap<>();
|
||||
List<BigDecimal> codes = Arrays.asList(BigDecimal.ONE, BigDecimal.TEN);
|
||||
List<String> codes1 = Arrays.asList("a", "b", "c");
|
||||
|
||||
final List<BigDecimal> list = codes.stream().filter(key2name::<warning descr="'Map<String, String>' may not contain objects of type 'BigDecimal'">containsKey</warning>).collect(Collectors.toList());
|
||||
final List<String> list1 = codes1.stream().filter(key2name::containsKey).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
+4
@@ -46,6 +46,10 @@ public class SuspiciousCollectionMethodCallsTest extends LightCodeInsightFixture
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testMethodReferenceWithCollectionCalls() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNonClassArgTypes() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user