mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-05 01:50:56 +07:00
IDEA-162694 Improve "Merge filter chain" intention
This commit is contained in:
@@ -73,7 +73,7 @@ public class InlineStreamMapAction extends PsiElementBaseIntentionAction {
|
||||
final PsiExpression[] expressions = argumentList.getExpressions();
|
||||
if (!name.startsWith("map") && expressions.length == 0) return true;
|
||||
if (expressions.length != 1) return false;
|
||||
if (!isSupportedForConversion(expressions[0], true)) return false;
|
||||
if (!StreamRefactoringUtil.isRefactoringCandidate(expressions[0], true)) return false;
|
||||
|
||||
final PsiMethod method = methodCallExpression.resolveMethod();
|
||||
if (method == null) return false;
|
||||
@@ -81,17 +81,6 @@ public class InlineStreamMapAction extends PsiElementBaseIntentionAction {
|
||||
return InheritanceUtil.isInheritor(containingClass, CommonClassNames.JAVA_UTIL_STREAM_BASE_STREAM);
|
||||
}
|
||||
|
||||
private static boolean isSupportedForConversion(PsiExpression expression, boolean requireExpressionLambda) {
|
||||
if(expression instanceof PsiLambdaExpression) {
|
||||
PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)expression;
|
||||
return lambdaExpression.getParameterList().getParametersCount() == 1 &&
|
||||
(!requireExpressionLambda || LambdaUtil.extractSingleExpressionFromBody(lambdaExpression.getBody()) != null);
|
||||
} else if(expression instanceof PsiMethodReferenceExpression) {
|
||||
return LambdaRefactoringUtil.canConvertToLambda((PsiMethodReferenceExpression)expression);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiMethodCallExpression getNextExpressionToMerge(PsiMethodCallExpression methodCallExpression) {
|
||||
PsiElement parent = methodCallExpression.getParent();
|
||||
@@ -107,7 +96,7 @@ public class InlineStreamMapAction extends PsiElementBaseIntentionAction {
|
||||
if (!nextName.equals("boxed") && !nextName.equals("asLongStream") && !nextName.equals("asDoubleStream")) return null;
|
||||
return nextCall;
|
||||
}
|
||||
if (expressions.length != 1 || !isSupportedForConversion(expressions[0], false)) return null;
|
||||
if (expressions.length != 1 || !StreamRefactoringUtil.isRefactoringCandidate(expressions[0], false)) return null;
|
||||
|
||||
return nextCall;
|
||||
}
|
||||
|
||||
@@ -27,9 +27,11 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.util.LambdaRefactoringUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@@ -49,6 +51,7 @@ public class MergeFilterChainAction extends PsiElementBaseIntentionAction {
|
||||
return getFilterToMerge((PsiMethodCallExpression)gParent) != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiMethodCallExpression getFilterToMerge(PsiMethodCallExpression methodCallExpression) {
|
||||
final PsiExpression qualifierExpression = methodCallExpression.getMethodExpression().getQualifierExpression();
|
||||
if (qualifierExpression instanceof PsiMethodCallExpression && isFilterCall((PsiMethodCallExpression)qualifierExpression)) {
|
||||
@@ -67,26 +70,20 @@ public class MergeFilterChainAction extends PsiElementBaseIntentionAction {
|
||||
}
|
||||
|
||||
public static boolean isFilterCall(PsiMethodCallExpression methodCallExpression) {
|
||||
if (!"filter".equals(methodCallExpression.getMethodExpression().getReferenceName())) return false;
|
||||
String name = methodCallExpression.getMethodExpression().getReferenceName();
|
||||
if (!"filter".equals(name) && !"anyMatch".equals(name)) return false;
|
||||
|
||||
final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
|
||||
final PsiExpression[] expressions = argumentList.getExpressions();
|
||||
if (expressions.length != 1) return false;
|
||||
if (!(expressions[0] instanceof PsiLambdaExpression)) return false;
|
||||
final PsiElement lambdaBody = ((PsiLambdaExpression)expressions[0]).getBody();
|
||||
if (!(lambdaBody instanceof PsiExpression)) return false;
|
||||
if (!StreamRefactoringUtil.isRefactoringCandidate(expressions[0], true)) return false;
|
||||
|
||||
final PsiMethod method = methodCallExpression.resolveMethod();
|
||||
if (method == null) return false;
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
final PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
if (parameters.length == 1 &&
|
||||
InheritanceUtil.isInheritor(containingClass, false, CommonClassNames.JAVA_UTIL_STREAM_STREAM) &&
|
||||
InheritanceUtil.isInheritor(parameters[0].getType(), CommonClassNames.JAVA_UTIL_FUNCTION_PREDICATE)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return parameters.length == 1 &&
|
||||
InheritanceUtil.isInheritor(containingClass, false, CommonClassNames.JAVA_UTIL_STREAM_BASE_STREAM);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -101,6 +98,19 @@ public class MergeFilterChainAction extends PsiElementBaseIntentionAction {
|
||||
return CodeInsightBundle.message("intention.merge.filter.family");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiLambdaExpression getLambda(PsiMethodCallExpression call) {
|
||||
PsiExpression[] expressions = call.getArgumentList().getExpressions();
|
||||
if(expressions.length != 1) return null;
|
||||
PsiExpression expression = expressions[0];
|
||||
if(expression instanceof PsiLambdaExpression) return (PsiLambdaExpression)expression;
|
||||
if (expression instanceof PsiMethodReferenceExpression) {
|
||||
return LambdaRefactoringUtil
|
||||
.convertMethodReferenceToLambda((PsiMethodReferenceExpression)expression, false, true);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
|
||||
try {
|
||||
@@ -115,11 +125,16 @@ public class MergeFilterChainAction extends PsiElementBaseIntentionAction {
|
||||
final PsiMethodCallExpression callToStay = filterCall.getTextLength() < filterToMerge.getTextLength() ? filterCall : filterToMerge;
|
||||
final PsiMethodCallExpression callToEliminate = callToStay == filterCall ? filterToMerge : filterCall;
|
||||
|
||||
final PsiLambdaExpression targetLambda = (PsiLambdaExpression)callToStay.getArgumentList().getExpressions()[0];
|
||||
String resultingOperation = callToEliminate.getMethodExpression().getReferenceName();
|
||||
LOG.assertTrue(resultingOperation != null);
|
||||
|
||||
final PsiLambdaExpression targetLambda = getLambda(callToStay);
|
||||
LOG.assertTrue(targetLambda != null, callToStay);
|
||||
final PsiParameter[] parameters = targetLambda.getParameterList().getParameters();
|
||||
final String name = parameters.length > 0 ? parameters[0].getName() : null;
|
||||
|
||||
final PsiLambdaExpression sourceLambda = (PsiLambdaExpression)callToEliminate.getArgumentList().getExpressions()[0];
|
||||
final PsiLambdaExpression sourceLambda = getLambda(callToEliminate);
|
||||
LOG.assertTrue(sourceLambda != null, callToEliminate);
|
||||
if (name != null) {
|
||||
final PsiParameter[] sourceLambdaParams = sourceLambda.getParameterList().getParameters();
|
||||
if (sourceLambdaParams.length > 0 && !name.equals(sourceLambdaParams[0].getName())) {
|
||||
@@ -132,14 +147,20 @@ public class MergeFilterChainAction extends PsiElementBaseIntentionAction {
|
||||
}
|
||||
}
|
||||
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
PsiElement nameElement = callToStay.getMethodExpression().getReferenceNameElement();
|
||||
LOG.assertTrue(nameElement != null);
|
||||
if(!resultingOperation.equals(nameElement.getText())) {
|
||||
nameElement.replace(factory.createIdentifier(resultingOperation));
|
||||
}
|
||||
|
||||
PsiElement targetBody = targetLambda.getBody();
|
||||
LOG.assertTrue(targetBody instanceof PsiExpression);
|
||||
final PsiElement sourceLambdaBody = sourceLambda.getBody();
|
||||
|
||||
LOG.assertTrue(sourceLambdaBody instanceof PsiExpression);
|
||||
|
||||
|
||||
final PsiExpression compoundExpression = JavaPsiFacade.getElementFactory(project)
|
||||
final PsiExpression compoundExpression = factory
|
||||
.createExpressionFromText(
|
||||
ParenthesesUtils.getText((PsiExpression)targetBody, ParenthesesUtils.OR_PRECEDENCE) + " && " +
|
||||
ParenthesesUtils.getText((PsiExpression)sourceLambdaBody, ParenthesesUtils.OR_PRECEDENCE), sourceLambda);
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.intention.impl;
|
||||
|
||||
import com.intellij.psi.LambdaUtil;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.psi.PsiLambdaExpression;
|
||||
import com.intellij.psi.PsiMethodReferenceExpression;
|
||||
import com.intellij.refactoring.util.LambdaRefactoringUtil;
|
||||
|
||||
/**
|
||||
* @author Tagir Valeev
|
||||
*/
|
||||
public class StreamRefactoringUtil {
|
||||
static boolean isRefactoringCandidate(PsiExpression expression, boolean requireExpressionLambda) {
|
||||
if(expression instanceof PsiLambdaExpression) {
|
||||
PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)expression;
|
||||
return lambdaExpression.getParameterList().getParametersCount() == 1 &&
|
||||
(!requireExpressionLambda || LambdaUtil.extractSingleExpressionFromBody(lambdaExpression.getBody()) != null);
|
||||
} else if(expression instanceof PsiMethodReferenceExpression) {
|
||||
return LambdaRefactoringUtil.canConvertToLambda((PsiMethodReferenceExpression)expression);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Merge filter's chain" "true"
|
||||
|
||||
import java.util.stream.LongStream;
|
||||
|
||||
public class Main {
|
||||
void test() {
|
||||
System.out.println(LongStream.range(0, 100).anyMatch(x -> x > 20 && x < 50));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Merge filter's chain" "true"
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Main {
|
||||
void test(List<String> list) {
|
||||
list.stream().filter((o) -> Objects.nonNull(o) && o.isEmpty()).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Merge filter's chain" "true"
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class Main {
|
||||
void test() {
|
||||
System.out.println(IntStream.range(0, 100).filter(x -> x > 20 && x < 50).count());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Merge filter's chain" "true"
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
void test(List<String> list) {
|
||||
list.stream().filter(s -> s.trim().isEmpty() && s.isEmpty()).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Merge filter's chain" "true"
|
||||
|
||||
import java.util.stream.LongStream;
|
||||
|
||||
public class Main {
|
||||
void test() {
|
||||
System.out.println(LongStream.range(0, 100).filter(x -> x > 20).anyM<caret>atch(x -> x < 50));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Merge filter's chain" "true"
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Main {
|
||||
void test(List<String> list) {
|
||||
list.stream().filter(Objects::nonNull).filt<caret>er(String::isEmpty).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Merge filter's chain" "true"
|
||||
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class Main {
|
||||
void test() {
|
||||
System.out.println(IntStream.range(0, 100).filter(x -> x > 20).fil<caret>ter(x -> x < 50).count());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Merge filter's chain" "true"
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
void test(List<String> list) {
|
||||
list.stream().filte<caret>r(s -> s.trim().isEmpty()).filter(String::isEmpty).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user