mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Stream API migration: ignore mutable variables in nested lambdas/anonymous classes; add type argument to map/mapToObj calls where necessary
This commit is contained in:
+31
@@ -25,6 +25,7 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.controlFlow.*;
|
||||
import com.intellij.psi.impl.PsiDiamondTypeUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import one.util.streamex.StreamEx;
|
||||
@@ -109,9 +110,39 @@ abstract class MigrateToStreamFix implements LocalQuickFix {
|
||||
static void simplifyAndFormat(@NotNull Project project, PsiElement result) {
|
||||
if (result == null) return;
|
||||
LambdaCanBeMethodReferenceInspection.replaceAllLambdasWithMethodReferences(result);
|
||||
removeRedundantTypeArguments(project, result);
|
||||
CodeStyleManager.getInstance(project).reformat(JavaCodeStyleManager.getInstance(project).shortenClassReferences(result));
|
||||
}
|
||||
|
||||
private static void removeRedundantTypeArguments(@NotNull Project project, PsiElement result) {
|
||||
PsiElement[] typedCalls = PsiTreeUtil.collectElements(result, e -> {
|
||||
if (!(e instanceof PsiMethodCallExpression)) return false;
|
||||
PsiMethodCallExpression call = (PsiMethodCallExpression)e;
|
||||
if (call.getTypeArguments().length == 0) return false;
|
||||
PsiMethod method = call.resolveMethod();
|
||||
if (method == null) return false;
|
||||
PsiClass aClass = method.getContainingClass();
|
||||
if (aClass == null) return false;
|
||||
String className = aClass.getQualifiedName();
|
||||
// We remove only those which related to Stream API calls trying to preserve ones which were originally in code
|
||||
return className != null && className.startsWith("java.util.stream.");
|
||||
});
|
||||
for(PsiElement typedCall : typedCalls) {
|
||||
PsiMethodCallExpression call = (PsiMethodCallExpression)typedCall;
|
||||
PsiType[] arguments = call.getTypeArguments();
|
||||
PsiMethod method = call.resolveMethod();
|
||||
if(method != null) {
|
||||
PsiTypeParameter[] parameters = method.getTypeParameters();
|
||||
if(arguments.length == parameters.length &&
|
||||
PsiDiamondTypeUtil.areTypeArgumentsRedundant(arguments, call, false, method, parameters)) {
|
||||
PsiMethodCallExpression expr =
|
||||
(PsiMethodCallExpression)JavaPsiFacade.getInstance(project).getElementFactory().createExpressionFromText("foo()", null);
|
||||
call.getTypeArgumentList().replace(expr.getTypeArgumentList());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void restoreComments(PsiLoopStatement loopStatement, PsiStatement body) {
|
||||
final PsiElement parent = loopStatement.getParent();
|
||||
for (PsiElement comment : PsiTreeUtil.findChildrenOfType(body, PsiComment.class)) {
|
||||
|
||||
+5
@@ -572,7 +572,9 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
PsiBreakStatement.class, PsiReturnStatement.class, PsiThrowStatement.class);
|
||||
int startOffset = controlFlow.getStartOffset(body);
|
||||
int endOffset = controlFlow.getEndOffset(body);
|
||||
PsiElement surrounder = PsiTreeUtil.getParentOfType(statement, PsiLambdaExpression.class, PsiClass.class);
|
||||
final List<PsiVariable> nonFinalVariables = StreamEx.of(ControlFlowUtil.getUsedVariables(controlFlow, startOffset, endOffset))
|
||||
.remove(variable -> PsiTreeUtil.getParentOfType(variable, PsiLambdaExpression.class, PsiClass.class) != surrounder)
|
||||
.remove(variable -> isVariableSuitableForStream(variable, statement, tb)).toList();
|
||||
|
||||
if (exitPoints.isEmpty()) {
|
||||
@@ -978,6 +980,9 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
operationName = "mapToObj";
|
||||
}
|
||||
PsiExpression expression = myType == null ? myExpression : RefactoringUtil.convertInitializerToNormalExpression(myExpression, myType);
|
||||
if(myType != null && !(myType instanceof PsiPrimitiveType)) {
|
||||
operationName = "<"+myType.getCanonicalText()+">"+operationName;
|
||||
}
|
||||
return "." + operationName + "(" + LambdaUtil.createLambda(myVariable, expression) + ")";
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
class Test {
|
||||
public static <T> List<TokenFilter<T>> fromString(final T src, Function<T, List<String>> extractor) {
|
||||
final List<TokenFilter<T>> result = extractor.apply(src).stream().map((Function<String, TokenFilter<T>>) TokenFilter::new).collect(Collectors.toList());
|
||||
final List<TokenFilter<T>> result = extractor.apply(src).stream().<TokenFilter<T>>map(TokenFilter::new).collect(Collectors.toList());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// "Replace with collect" "true"
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Main {
|
||||
public List<Runnable> test(List<String> list) {
|
||||
List<Runnable> result = list.stream().<Runnable>map(s -> new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String str = s;
|
||||
if (str.isEmpty()) str = "none";
|
||||
System.out.println(str);
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// "Replace with collect" "true"
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class Main {
|
||||
public List<Runnable> test(List<String> list) {
|
||||
List<Runnable> result = list.stream().<Runnable>map(s -> () -> {
|
||||
String str = s;
|
||||
if (str.isEmpty()) str = "none";
|
||||
System.out.println(str);
|
||||
}).collect(Collectors.toList());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// "Replace with collect" "true"
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
public List<Runnable> test(List<String> list) {
|
||||
List<Runnable> result = new ArrayList<>();
|
||||
for(String s : l<caret>ist) {
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String str = s;
|
||||
if (str.isEmpty()) str = "none";
|
||||
System.out.println(str);
|
||||
}
|
||||
};
|
||||
result.add(r);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// "Replace with collect" "true"
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
public List<Runnable> test(List<String> list) {
|
||||
List<Runnable> result = new ArrayList<>();
|
||||
for(String s : li<caret>st) {
|
||||
Runnable r = () -> {
|
||||
String str = s;
|
||||
if (str.isEmpty()) str = "none";
|
||||
System.out.println(str);
|
||||
};
|
||||
result.add(r);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user