[java-inspections] fixes after review IDEA-262786

GitOrigin-RevId: a28742b2b55d66e0ffbcc964782f24bd4197abf6
This commit is contained in:
Andrey.Cherkasov
2021-06-22 19:51:46 +00:00
committed by intellij-monorepo-bot
parent e531adb8d6
commit 722cfa69cb
4 changed files with 42 additions and 37 deletions
@@ -1,12 +1,15 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.codeInspection.bulkOperation;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.containers.ContainerUtil;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
@@ -16,11 +19,13 @@ public final class BulkMethodInfo {
private final String myClassName;
private final String mySimpleName;
private final String myBulkName;
private final String myBulkParameterType;
public BulkMethodInfo(String className, String simpleName, String bulkName) {
public BulkMethodInfo(String className, String simpleName, String bulkName, String bulkParameterType) {
myClassName = className;
mySimpleName = simpleName;
myBulkName = bulkName;
myBulkParameterType = bulkParameterType;
}
public boolean isMyMethod(PsiReferenceExpression ref) {
@@ -29,13 +34,15 @@ public final class BulkMethodInfo {
if (!(element instanceof PsiMethod)) return false;
PsiMethod method = (PsiMethod)element;
PsiParameterList parameters = method.getParameterList();
if (parameters.getParametersCount() != (myClassName.equals(JAVA_UTIL_MAP) ? 2 : 1)) return false;
PsiParameter parameter = Objects.requireNonNull(parameters.getParameter(0));
PsiClass parameterClass = PsiUtil.resolveClassInClassTypeOnly(parameter.getType());
if (parameterClass == null ||
JAVA_LANG_ITERABLE.equals(parameterClass.getQualifiedName()) ||
JAVA_UTIL_COLLECTION.equals(parameterClass.getQualifiedName())) {
return false;
if (parameters.getParametersCount() != getSimpleParametersCount()) return false;
if (getSimpleParametersCount() == 1) {
PsiParameter parameter = Objects.requireNonNull(parameters.getParameter(0));
PsiClass parameterClass = PsiUtil.resolveClassInClassTypeOnly(parameter.getType());
if (parameterClass == null ||
JAVA_LANG_ITERABLE.equals(parameterClass.getQualifiedName()) ||
JAVA_UTIL_COLLECTION.equals(parameterClass.getQualifiedName())) {
return false;
}
}
PsiClass methodClass = method.getContainingClass();
if (methodClass == null || !InheritanceUtil.isInheritor(methodClass, myClassName)) return false;
@@ -46,11 +53,7 @@ public final class BulkMethodInfo {
return ContainerUtil.or(aClass.findMethodsByName(myBulkName, true), method -> {
PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameters.length != 1) return false;
PsiParameter parameter = parameters[0];
if (myClassName.equals(JAVA_UTIL_MAP)) {
return TypeUtils.variableHasTypeOrSubtype(parameter, JAVA_UTIL_MAP);
}
return TypeUtils.variableHasTypeOrSubtype(parameter, JAVA_LANG_ITERABLE, JAVA_UTIL_COLLECTION);
return TypeUtils.variableHasTypeOrSubtype(parameters[0], getBulkParameterType(aClass.getProject()));
});
}
@@ -78,16 +81,8 @@ public final class BulkMethodInfo {
}
PsiClass aClass = PsiUtil.resolveClassInType(type);
if (aClass == null) return false;
PsiClass commonParent;
if (myClassName.equals(JAVA_UTIL_MAP)) {
commonParent = psiFacade.findClass(JAVA_UTIL_MAP, aClass.getResolveScope());
} else {
commonParent = psiFacade.findClass(JAVA_LANG_ITERABLE, aClass.getResolveScope());
if (commonParent == null) {
// No Iterable class in Java 1.4
commonParent = psiFacade.findClass(JAVA_UTIL_COLLECTION, aClass.getResolveScope());
}
}
String bulkParameterType = getBulkParameterType(aClass.getProject());
PsiClass commonParent = psiFacade.findClass(bulkParameterType, aClass.getResolveScope());
if (!InheritanceUtil.isInheritorOrSelf(aClass, commonParent, true)) return false;
PsiExpression expression = factory.createExpressionFromText(qualifier.getText() + "." + myBulkName + "(" + text + ")", iterable);
if (!(expression instanceof PsiMethodCallExpression)) return false;
@@ -101,10 +96,7 @@ public final class BulkMethodInfo {
PsiClass parameterClass = PsiUtil.resolveClassInClassTypeOnly(parameterType);
if (parameterClass == null) return false;
String qualifiedName = parameterClass.getQualifiedName();
return (myClassName.equals(JAVA_UTIL_MAP)
? JAVA_UTIL_MAP.equals(qualifiedName)
: (JAVA_LANG_ITERABLE.equals(qualifiedName) || JAVA_UTIL_COLLECTION.equals(qualifiedName))) &&
parameterType.isAssignableFrom(type);
return bulkParameterType.equals(qualifiedName) && parameterType.isAssignableFrom(type);
}
public String getClassName() {
@@ -115,10 +107,22 @@ public final class BulkMethodInfo {
return mySimpleName;
}
public int getSimpleParametersCount() {
return myBulkParameterType.equals(JAVA_UTIL_MAP) ? 2 : 1;
}
public String getBulkName() {
return myBulkName;
}
public String getBulkParameterType(@NotNull Project project) {
if (myBulkParameterType.equals(JAVA_LANG_ITERABLE) &&
PsiUtil.getLanguageLevel(project).isLessThan(LanguageLevel.JDK_1_5)) {
return JAVA_UTIL_COLLECTION;
}
return myBulkParameterType;
}
public String getReplacementName() {
return StringUtil.getShortName(myClassName) + "." + myBulkName;
}
@@ -9,8 +9,8 @@ import java.util.stream.Stream;
public class JdkBulkMethodInfoProvider implements BulkMethodInfoProvider {
private static final BulkMethodInfo[] INFOS = {
new BulkMethodInfo(CommonClassNames.JAVA_UTIL_COLLECTION, "add", "addAll"),
new BulkMethodInfo(CommonClassNames.JAVA_UTIL_MAP, "put", "putAll")
new BulkMethodInfo(CommonClassNames.JAVA_UTIL_COLLECTION, "add", "addAll", CommonClassNames.JAVA_UTIL_COLLECTION),
new BulkMethodInfo(CommonClassNames.JAVA_UTIL_MAP, "put", "putAll", CommonClassNames.JAVA_UTIL_MAP),
};
@NotNull
@@ -55,8 +55,7 @@ public class UseBulkOperationInspection extends AbstractBaseJavaLocalInspectionT
@Nullable
private static PsiExpression findIterable(PsiMethodCallExpression expression, BulkMethodInfo info) {
PsiExpression[] args = expression.getArgumentList().getExpressions();
int simpleMethodParametersCount = info.getClassName().equals(CommonClassNames.JAVA_UTIL_MAP) ? 2 : 1;
if (args.length != simpleMethodParametersCount) return null;
if (args.length != info.getSimpleParametersCount()) return null;
PsiElement parent = expression.getParent();
if (parent instanceof PsiLambdaExpression) {
return findIterableForLambda((PsiLambdaExpression)parent, args, info);
@@ -78,7 +77,7 @@ public class UseBulkOperationInspection extends AbstractBaseJavaLocalInspectionT
if (args.length == 1 && ExpressionUtils.isReferenceTo(args[0], declaration.getNextElementVariable(statements[0]))) {
return declaration.getIterable();
} else if (args.length == 2) {
if (isGetValueAndGetKey(args, declaration.getNextElementVariable(statements[0]))) {
if (isGetKeyAndGetValue(args, declaration.getNextElementVariable(statements[0]))) {
PsiMethodCallExpression entrySetCandidate = ObjectUtils.tryCast(declaration.getIterable(), PsiMethodCallExpression.class);
if (MAP_ENTRY_SET.test(entrySetCandidate)) {
return entrySetCandidate.getMethodExpression().getQualifierExpression();
@@ -115,7 +114,7 @@ public class UseBulkOperationInspection extends AbstractBaseJavaLocalInspectionT
int lambdaParametersCount = parameterList.getParametersCount();
if (info.getClassName().equals(CommonClassNames.JAVA_UTIL_MAP)) {
if (lambdaParametersCount == 1) {
if (!isGetValueAndGetKey(args, parameters[0])) return null;
if (!isGetKeyAndGetValue(args, parameters[0])) return null;
} else if (lambdaParametersCount == 2) {
if (!ExpressionUtils.isReferenceTo(args[0], parameters[0]) ||
!ExpressionUtils.isReferenceTo(args[1], parameters[1])) return null;
@@ -124,7 +123,7 @@ public class UseBulkOperationInspection extends AbstractBaseJavaLocalInspectionT
return findIterableForFunction(lambda);
}
private static boolean isGetValueAndGetKey(PsiExpression[] args, PsiVariable variable) {
private static boolean isGetKeyAndGetValue(PsiExpression[] args, PsiVariable variable) {
PsiMethodCallExpression getKeyCandidate = ObjectUtils.tryCast(args[0], PsiMethodCallExpression.class);
PsiMethodCallExpression getValueCandidate = ObjectUtils.tryCast(args[1], PsiMethodCallExpression.class);
if (!ENTRY_GET_KEY.test(getKeyCandidate) || !ENTRY_GET_VALUE.test(getValueCandidate)) return false;
@@ -135,12 +134,13 @@ public class UseBulkOperationInspection extends AbstractBaseJavaLocalInspectionT
@Nullable
private static PsiExpression findIterableForSingleStatement(PsiStatement statement, PsiExpression[] args) {
assert args.length == 1 || args.length == 2 : "The number of arguments must be either 1 or 2";
PsiElement parent = statement.getParent();
if (parent instanceof PsiForeachStatement) {
PsiForeachStatement foreachStatement = (PsiForeachStatement)parent;
PsiExpression iteratedValue = foreachStatement.getIteratedValue();
if (args.length == 2) {
if (isGetValueAndGetKey(args, foreachStatement.getIterationParameter())) {
if (isGetKeyAndGetValue(args, foreachStatement.getIterationParameter())) {
PsiMethodCallExpression entrySetCandidate = ObjectUtils.tryCast(iteratedValue, PsiMethodCallExpression.class);
if (MAP_ENTRY_SET.test(entrySetCandidate)) {
return entrySetCandidate.getMethodExpression().getQualifierExpression();
@@ -1,4 +1,4 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.java.codeInsight.daemon.quickFix;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
@@ -7,6 +7,7 @@ import com.intellij.codeInspection.bulkOperation.BulkMethodInfo;
import com.intellij.codeInspection.bulkOperation.BulkMethodInfoProvider;
import com.intellij.codeInspection.bulkOperation.UseBulkOperationInspection;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.psi.CommonClassNames;
import com.intellij.testFramework.ServiceContainerUtil;
import org.jetbrains.annotations.NotNull;
@@ -19,7 +20,7 @@ public class UseBulkOperationInspectionTest extends LightQuickFixParameterizedTe
@NotNull
@Override
public Stream<BulkMethodInfo> consumers() {
return Stream.of(new BulkMethodInfo("testpackage.TestClass", "test", "test"));
return Stream.of(new BulkMethodInfo("testpackage.TestClass", "test", "test", CommonClassNames.JAVA_LANG_ITERABLE));
}
};