mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
redundant lambda code block: check applicability over replaced lambda
This commit is contained in:
+2
-2
@@ -284,8 +284,8 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
|
||||
.giveUniqueNames(project, elementFactory, lambdaExpression,
|
||||
usedLocalNames, variables.toArray(new PsiVariable[variables.size()]));
|
||||
|
||||
final PsiExpression singleExpr = RedundantLambdaCodeBlockInspection.isCodeBlockRedundant(lambdaExpression,
|
||||
lambdaExpression.getBody());
|
||||
final PsiExpression singleExpr = RedundantLambdaCodeBlockInspection.isCodeBlockRedundant(
|
||||
lambdaExpression.getBody());
|
||||
if (singleExpr != null) {
|
||||
lambdaExpression.getBody().replace(singleExpr);
|
||||
}
|
||||
|
||||
+13
-29
@@ -20,20 +20,13 @@ import com.intellij.codeInsight.daemon.GroupNames;
|
||||
import com.intellij.codeInsight.intention.HighPriorityAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.scope.conflictResolvers.JavaMethodsConflictResolver;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
@@ -75,7 +68,7 @@ public class RedundantLambdaCodeBlockInspection extends BaseJavaBatchLocalInspec
|
||||
super.visitLambdaExpression(expression);
|
||||
if (PsiUtil.isLanguageLevel8OrHigher(expression)) {
|
||||
final PsiElement body = expression.getBody();
|
||||
final PsiExpression psiExpression = isCodeBlockRedundant(expression, body);
|
||||
final PsiExpression psiExpression = isCodeBlockRedundant(body);
|
||||
if (psiExpression != null) {
|
||||
final PsiElement errorElement;
|
||||
final PsiElement parent = psiExpression.getParent();
|
||||
@@ -92,31 +85,22 @@ public class RedundantLambdaCodeBlockInspection extends BaseJavaBatchLocalInspec
|
||||
};
|
||||
}
|
||||
|
||||
public static PsiExpression isCodeBlockRedundant(PsiExpression expression, PsiElement body) {
|
||||
public static PsiExpression isCodeBlockRedundant(PsiElement body) {
|
||||
if (body instanceof PsiCodeBlock) {
|
||||
PsiExpression psiExpression = LambdaUtil.extractSingleExpressionFromBody(body);
|
||||
if (psiExpression != null && !findCommentsOutsideExpression(body, psiExpression)) {
|
||||
if (LambdaUtil.isExpressionStatementExpression(psiExpression)) {
|
||||
final PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent());
|
||||
if (parent instanceof PsiExpressionList) {
|
||||
final PsiElement gParent = parent.getParent();
|
||||
if (gParent instanceof PsiCallExpression) {
|
||||
final CandidateInfo[] candidates = PsiResolveHelper.SERVICE.getInstance(gParent.getProject())
|
||||
.getReferencedMethodCandidates((PsiCallExpression)gParent, false, true);
|
||||
if (candidates.length > 1) {
|
||||
final List<CandidateInfo> info = new ArrayList<CandidateInfo>(Arrays.asList(candidates));
|
||||
final LanguageLevel level = PsiUtil.getLanguageLevel(parent);
|
||||
final JavaMethodsConflictResolver conflictResolver = new JavaMethodsConflictResolver((PsiExpressionList)parent, level);
|
||||
final PsiExpressionList argumentList = ((PsiCallExpression)gParent).getArgumentList();
|
||||
if (argumentList == null) {
|
||||
return null;
|
||||
}
|
||||
final boolean atLeastOneMatchFound = conflictResolver.checkParametersNumber(info, argumentList.getExpressions().length, false);
|
||||
if (!atLeastOneMatchFound) {
|
||||
return null;
|
||||
}
|
||||
conflictResolver.checkSpecifics(info, MethodCandidateInfo.ApplicabilityLevel.VARARGS, level);
|
||||
if (info.size() > 1) {
|
||||
final PsiCall call = LambdaUtil.treeWalkUp(body);
|
||||
if (call != null && call.resolveMethod() != null) {
|
||||
final int offsetInTopCall = body.getTextRange().getStartOffset() - call.getTextRange().getStartOffset();
|
||||
PsiCall copyCall = LambdaUtil.copyTopLevelCall(call);
|
||||
if (copyCall == null) return null;
|
||||
final PsiCodeBlock codeBlock = PsiTreeUtil.getParentOfType(copyCall.findElementAt(offsetInTopCall), PsiCodeBlock.class);
|
||||
if (codeBlock != null) {
|
||||
final PsiElement parent = codeBlock.getParent();
|
||||
if (parent instanceof PsiLambdaExpression) {
|
||||
codeBlock.replace(psiExpression);
|
||||
if (copyCall.resolveMethod() == null || ((PsiLambdaExpression)parent).getFunctionalInterfaceType() == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.RedundantCastUtil;
|
||||
import com.intellij.refactoring.introduceField.ElementToWorkOn;
|
||||
import com.intellij.refactoring.introduceVariable.IntroduceVariableHandler;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.text.UniqueNameGenerator;
|
||||
import com.siyeh.ig.psiutils.SideEffectChecker;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -230,7 +229,7 @@ public class LambdaRefactoringUtil {
|
||||
|
||||
public static void simplifyToExpressionLambda(@NotNull final PsiLambdaExpression lambdaExpression) {
|
||||
final PsiElement body = lambdaExpression.getBody();
|
||||
final PsiExpression singleExpression = RedundantLambdaCodeBlockInspection.isCodeBlockRedundant(lambdaExpression, body);
|
||||
final PsiExpression singleExpression = RedundantLambdaCodeBlockInspection.isCodeBlockRedundant(body);
|
||||
if (singleExpression != null) {
|
||||
body.replace(singleExpression);
|
||||
}
|
||||
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// "Replace with lambda" "true"
|
||||
import java.util.Collection;
|
||||
import java.util.function.Function;
|
||||
|
||||
class Test {
|
||||
|
||||
public static <T, V> V[] map2Array( T[] array, Class<? super V> aClass, Function<T, V> mapper) {
|
||||
return null;
|
||||
}
|
||||
public static <T, V> V[] map2Array(Collection<T> array, Class<? super V> aClass, Function<T, V> mapper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
void m(String[] f, int i, FooBar manager){
|
||||
|
||||
map2Array(f, Integer.class, (NullableFunction<String, Integer>) s -> s.length());
|
||||
}
|
||||
|
||||
interface NullableFunction<A, B> extends Function<A, B> {
|
||||
|
||||
B apply(final A param);
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
// "Replace with lambda" "true"
|
||||
import java.util.Collection;
|
||||
import java.util.function.Function;
|
||||
|
||||
class Test {
|
||||
|
||||
public static <T, V> V[] map2Array( T[] array, Class<? super V> aClass, Function<T, V> mapper) {
|
||||
return null;
|
||||
}
|
||||
public static <T, V> V[] map2Array(Collection<T> array, Class<? super V> aClass, Function<T, V> mapper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
void m(String[] f, int i, FooBar manager){
|
||||
|
||||
map2Array(f, Integer.class, new Nullable<caret>Function<String, Integer>() {
|
||||
@Override
|
||||
public Integer apply(String s) {
|
||||
return s.length();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
interface NullableFunction<A, B> extends Function<A, B> {
|
||||
|
||||
B apply(final A param);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user