IDEA-161706 Migration to Stream API: support primitive types int/long/double

This commit is contained in:
Tagir Valeev
2016-09-26 13:05:05 +07:00
parent 66db09af76
commit 16e8ad126e
29 changed files with 373 additions and 90 deletions
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInspection.LambdaCanBeMethodReferenceInspection;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
@@ -50,9 +51,8 @@ abstract class MigrateToStreamFix implements LocalQuickFix {
final PsiParameter parameter = foreachStatement.getIterationParameter();
StreamApiMigrationInspection.TerminalBlock tb = StreamApiMigrationInspection.TerminalBlock.from(parameter, body);
if (!FileModificationService.getInstance().preparePsiElementForWrite(foreachStatement)) return;
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
List<String> replacements = tb.extractOperationReplacements(factory);
migrate(project, descriptor, foreachStatement, iteratedValue, body, tb, replacements);
List<Operation> operations = tb.extractOperations();
migrate(project, descriptor, foreachStatement, iteratedValue, body, tb, operations);
}
}
}
@@ -63,20 +63,20 @@ abstract class MigrateToStreamFix implements LocalQuickFix {
@NotNull PsiExpression iteratedValue,
@NotNull PsiStatement body,
@NotNull StreamApiMigrationInspection.TerminalBlock tb,
@NotNull List<String> replacements);
@NotNull List<Operation> operations);
static void replaceWithNumericAddition(@NotNull Project project,
PsiForeachStatement foreachStatement,
PsiVariable var,
StringBuilder builder,
String expressionType) {
PsiType expressionType) {
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
restoreComments(foreachStatement, foreachStatement.getBody());
if (StreamApiMigrationInspection.isDeclarationJustBefore(var, foreachStatement)) {
PsiExpression initializer = var.getInitializer();
if (ExpressionUtils.isZero(initializer)) {
String typeStr = var.getType().getCanonicalText();
String replacement = (typeStr.equals(expressionType) ? "" : "(" + typeStr + ") ") + builder;
PsiType type = var.getType();
String replacement = (type.equals(expressionType) ? "" : "(" + type.getCanonicalText() + ") ") + builder;
initializer.replace(elementFactory.createExpressionFromText(replacement, foreachStatement));
removeLoop(foreachStatement);
simplifyAndFormat(project, var);
@@ -102,7 +102,12 @@ abstract class MigrateToStreamFix implements LocalQuickFix {
}
@NotNull
static StringBuilder generateStream(PsiExpression iteratedValue, List<String> intermediateOps) {
static StringBuilder generateStream(PsiExpression iteratedValue, List<Operation> intermediateOps) {
return generateStream(iteratedValue, intermediateOps, false);
}
@NotNull
static StringBuilder generateStream(PsiExpression iteratedValue, List<Operation> intermediateOps, boolean noStreamForEmpty) {
StringBuilder buffer = new StringBuilder();
final PsiType iteratedValueType = iteratedValue.getType();
if (iteratedValueType instanceof PsiArrayType) {
@@ -110,11 +115,12 @@ abstract class MigrateToStreamFix implements LocalQuickFix {
}
else {
buffer.append(getIteratedValueText(iteratedValue));
if (!intermediateOps.isEmpty()) {
if (!(noStreamForEmpty && intermediateOps.isEmpty())) {
buffer.append(".stream()");
}
}
intermediateOps.forEach(buffer::append);
PsiElementFactory factory = JavaPsiFacade.getElementFactory(iteratedValue.getProject());
intermediateOps.stream().map(op -> op.createReplacement(factory)).forEach(buffer::append);
return buffer;
}
@@ -16,6 +16,7 @@
package com.intellij.codeInspection.streamMigration;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
@@ -23,6 +24,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.SuggestedNameInfo;
import com.intellij.psi.codeStyle.VariableKind;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -42,6 +44,16 @@ class ReplaceWithCollectFix extends MigrateToStreamFix {
return "Replace with " + myMethodName;
}
@Nullable
PsiType getAddedElementType(PsiMethodCallExpression call) {
JavaResolveResult resolveResult = call.resolveMethodGenerics();
PsiMethod method = call.resolveMethod();
if(method == null) return null;
PsiParameter[] parameters = method.getParameterList().getParameters();
if(parameters.length != 1) return null;
return resolveResult.getSubstitutor().substitute(parameters[0].getType());
}
@Override
void migrate(@NotNull Project project,
@NotNull ProblemDescriptor descriptor,
@@ -49,7 +61,7 @@ class ReplaceWithCollectFix extends MigrateToStreamFix {
@NotNull PsiExpression iteratedValue,
@NotNull PsiStatement body,
@NotNull StreamApiMigrationInspection.TerminalBlock tb,
@NotNull List<String> intermediateOps) {
@NotNull List<Operation> operations) {
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
final PsiType iteratedValueType = iteratedValue.getType();
final PsiMethodCallExpression methodCallExpression = tb.getSingleMethodCall();
@@ -57,7 +69,7 @@ class ReplaceWithCollectFix extends MigrateToStreamFix {
if (methodCallExpression == null) return;
restoreComments(foreachStatement, body);
if (intermediateOps.isEmpty() && StreamApiMigrationInspection.isAddAllCall(tb)) {
if (operations.isEmpty() && StreamApiMigrationInspection.isAddAllCall(tb)) {
final PsiExpression qualifierExpression = methodCallExpression.getMethodExpression().getQualifierExpression();
final String qualifierText = qualifierExpression != null ? qualifierExpression.getText() : "";
final String collectionText =
@@ -69,8 +81,10 @@ class ReplaceWithCollectFix extends MigrateToStreamFix {
return;
}
PsiExpression itemToAdd = methodCallExpression.getArgumentList().getExpressions()[0];
intermediateOps.add(createMapperFunctionalExpressionText(tb.getVariable(), itemToAdd));
final StringBuilder builder = generateStream(iteratedValue, intermediateOps);
PsiType addedType = getAddedElementType(methodCallExpression);
if (addedType == null) addedType = itemToAdd.getType();
operations.add(new StreamApiMigrationInspection.MapOp(itemToAdd, tb.getVariable(), addedType));
final StringBuilder builder = generateStream(iteratedValue, operations);
final PsiExpression qualifierExpression = methodCallExpression.getMethodExpression().getQualifierExpression();
final PsiExpression initializer = StreamApiMigrationInspection
@@ -88,7 +102,7 @@ class ReplaceWithCollectFix extends MigrateToStreamFix {
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
SuggestedNameInfo suggestedNameInfo =
codeStyleManager.suggestVariableName(VariableKind.LOCAL_VARIABLE, null, null, itemToAdd.getType(), false);
codeStyleManager.suggestVariableName(VariableKind.LOCAL_VARIABLE, null, null, addedType, false);
if (suggestedNameInfo.names.length == 0) {
suggestedNameInfo = codeStyleManager.suggestVariableName(VariableKind.LOCAL_VARIABLE, "item", null, itemToAdd.getType(), false);
}
@@ -124,11 +138,4 @@ class ReplaceWithCollectFix extends MigrateToStreamFix {
return "toCollection(() -> " + initializer.getText() + ")";
}
}
private static String createMapperFunctionalExpressionText(PsiVariable variable, PsiExpression expression) {
if (!StreamApiMigrationInspection.isIdentityMapping(variable, expression)) {
return new StreamApiMigrationInspection.MapOp(expression, variable).createReplacement(null);
}
return "";
}
}
@@ -16,6 +16,7 @@
package com.intellij.codeInspection.streamMigration;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
@@ -40,14 +41,14 @@ class ReplaceWithCountFix extends MigrateToStreamFix {
@NotNull PsiExpression iteratedValue,
@NotNull PsiStatement body,
@NotNull StreamApiMigrationInspection.TerminalBlock tb,
@NotNull List<String> intermediateOps) {
@NotNull List<Operation> operations) {
PsiExpression operand = StreamApiMigrationInspection.extractIncrementedLValue(tb.getSingleExpression(PsiExpression.class));
if (!(operand instanceof PsiReferenceExpression)) return;
PsiElement element = ((PsiReferenceExpression)operand).resolve();
if (!(element instanceof PsiLocalVariable)) return;
PsiLocalVariable var = (PsiLocalVariable)element;
final StringBuilder builder = generateStream(iteratedValue, intermediateOps);
final StringBuilder builder = generateStream(iteratedValue, operations);
builder.append(".count()");
replaceWithNumericAddition(project, foreachStatement, var, builder, "long");
replaceWithNumericAddition(project, foreachStatement, var, builder, PsiType.LONG);
}
}
@@ -16,6 +16,7 @@
package com.intellij.codeInspection.streamMigration;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.siyeh.ig.psiutils.ExpressionUtils;
@@ -40,10 +41,9 @@ class ReplaceWithFindFirstFix extends MigrateToStreamFix {
@NotNull PsiExpression iteratedValue,
@NotNull PsiStatement body,
@NotNull StreamApiMigrationInspection.TerminalBlock tb,
@NotNull List<String> intermediateOps) {
@NotNull List<Operation> operations) {
PsiStatement statement = tb.getSingleStatement();
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
intermediateOps.add("");
if (statement instanceof PsiReturnStatement) {
PsiReturnStatement returnStatement = (PsiReturnStatement)statement;
PsiExpression value = returnStatement.getReturnValue();
@@ -52,7 +52,7 @@ class ReplaceWithFindFirstFix extends MigrateToStreamFix {
if (nextReturnStatement == null) return;
PsiExpression orElseExpression = nextReturnStatement.getReturnValue();
if (!ExpressionUtils.isSimpleExpression(orElseExpression)) return;
StringBuilder builder = generateStream(iteratedValue, intermediateOps).append(".findFirst()");
StringBuilder builder = generateStream(iteratedValue, operations).append(".findFirst()");
if (!(value instanceof PsiReferenceExpression) || ((PsiReferenceExpression)value).resolve() != tb.getVariable()) {
builder.append(".map(").append(tb.getVariable().getName()).append(" -> ").append(value.getText()).append(")");
}
@@ -77,7 +77,7 @@ class ReplaceWithFindFirstFix extends MigrateToStreamFix {
PsiVariable var = (PsiVariable)element;
PsiExpression value = assignment.getRExpression();
if (value == null) return;
StringBuilder builder = generateStream(iteratedValue, intermediateOps).append(".findFirst()");
StringBuilder builder = generateStream(iteratedValue, operations).append(".findFirst()");
if (!(value instanceof PsiReferenceExpression) || ((PsiReferenceExpression)value).resolve() != tb.getVariable()) {
builder.append(".map(").append(tb.getVariable().getName()).append(" -> ").append(value.getText()).append(")");
}
@@ -16,6 +16,7 @@
package com.intellij.codeInspection.streamMigration;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -48,12 +49,12 @@ class ReplaceWithForeachCallFix extends MigrateToStreamFix {
@NotNull PsiExpression iteratedValue,
@NotNull PsiStatement body,
@NotNull StreamApiMigrationInspection.TerminalBlock tb,
@NotNull List<String> intermediateOps) {
@NotNull List<Operation> operations) {
restoreComments(foreachStatement, body);
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
StringBuilder buffer = generateStream(iteratedValue, intermediateOps);
StringBuilder buffer = generateStream(iteratedValue, operations, true);
PsiElement block = tb.convertToElement(elementFactory);
buffer.append(".").append(myForEachMethodName).append("(");
@@ -16,6 +16,7 @@
package com.intellij.codeInspection.streamMigration;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -49,18 +50,17 @@ class ReplaceWithMatchFix extends MigrateToStreamFix {
@NotNull PsiExpression iteratedValue,
@NotNull PsiStatement body,
@NotNull StreamApiMigrationInspection.TerminalBlock tb,
@NotNull List<String> intermediateOps) {
@NotNull List<Operation> operations) {
PsiReturnStatement returnStatement = (PsiReturnStatement)tb.getSingleStatement();
PsiExpression value = returnStatement.getReturnValue();
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
intermediateOps.add("");
restoreComments(foreachStatement, body);
if (StreamApiMigrationInspection.isLiteral(value, Boolean.TRUE) || StreamApiMigrationInspection.isLiteral(value, Boolean.FALSE)) {
boolean foundResult = (boolean)((PsiLiteralExpression)value).getValue();
PsiReturnStatement nextReturnStatement = StreamApiMigrationInspection.getNextReturnStatement(foreachStatement);
if (nextReturnStatement != null && StreamApiMigrationInspection.isLiteral(nextReturnStatement.getReturnValue(), !foundResult)) {
String methodName = foundResult ? "anyMatch" : "noneMatch";
String streamText = generateStream(iteratedValue, intermediateOps).toString();
String streamText = generateStream(iteratedValue, operations).toString();
streamText = addTerminalOperation(streamText, methodName, foreachStatement, tb);
boolean siblings = nextReturnStatement.getParent() == foreachStatement.getParent();
PsiElement result =
@@ -73,7 +73,7 @@ class ReplaceWithMatchFix extends MigrateToStreamFix {
}
}
if (!StreamApiMigrationInspection.isVariableReferenced(tb.getVariable(), value)) {
String streamText = generateStream(iteratedValue, intermediateOps).toString();
String streamText = generateStream(iteratedValue, operations).toString();
streamText = addTerminalOperation(streamText, "anyMatch", foreachStatement, tb);
String replacement = "if(" + streamText + "){" + returnStatement.getText() + "}";
PsiElement result = foreachStatement.replace(elementFactory.createStatementFromText(replacement, foreachStatement));
@@ -16,12 +16,12 @@
package com.intellij.codeInspection.streamMigration;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Locale;
/**
* @author Tagir Valeev
@@ -41,7 +41,7 @@ class ReplaceWithSumFix extends MigrateToStreamFix {
@NotNull PsiExpression iteratedValue,
@NotNull PsiStatement body,
@NotNull StreamApiMigrationInspection.TerminalBlock tb,
@NotNull List<String> intermediateOps) {
@NotNull List<Operation> operations) {
PsiAssignmentExpression assignment = tb.getSingleExpression(PsiAssignmentExpression.class);
if (assignment == null) return;
PsiVariable var = StreamApiMigrationInspection.extractAccumulator(assignment);
@@ -50,22 +50,13 @@ class ReplaceWithSumFix extends MigrateToStreamFix {
PsiExpression addend = StreamApiMigrationInspection.extractAddend(assignment);
if (addend == null) return;
PsiType type = var.getType();
if (!(type instanceof PsiPrimitiveType)) return;
PsiPrimitiveType primitiveType = (PsiPrimitiveType)type;
if (primitiveType.equalsToText("float")) return;
String typeName;
if (primitiveType.equalsToText("double")) {
typeName = "Double";
if (!(type instanceof PsiPrimitiveType) || type.equals(PsiType.FLOAT)) return;
if (!type.equals(PsiType.DOUBLE) && !type.equals(PsiType.LONG)) {
type = PsiType.INT;
}
else if (primitiveType.equalsToText("long")) {
typeName = "Long";
}
else {
typeName = "Int";
}
intermediateOps.add(".mapTo" + typeName + "(" + StreamApiMigrationInspection.createLambda(tb.getVariable(), addend) + ")");
final StringBuilder builder = generateStream(iteratedValue, intermediateOps);
operations.add(new StreamApiMigrationInspection.MapOp(addend, tb.getVariable(), type));
final StringBuilder builder = generateStream(iteratedValue, operations);
builder.append(".sum()");
replaceWithNumericAddition(project, foreachStatement, var, builder, typeName.toLowerCase(Locale.ENGLISH));
replaceWithNumericAddition(project, foreachStatement, var, builder, type);
}
}
@@ -111,8 +111,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
PsiClass collectionClass = null;
final boolean isArray;
if(iteratedValueType instanceof PsiArrayType) {
// Do not handle primitive types now
if(((PsiArrayType)iteratedValueType).getComponentType() instanceof PsiPrimitiveType) return;
if(!isSupported(((PsiArrayType)iteratedValueType).getComponentType())) return;
isArray = true;
} else {
collectionClass = JavaPsiFacade.getInstance(body.getProject()).findClass(CommonClassNames.JAVA_UTIL_COLLECTION, statement.getResolveScope());
@@ -199,6 +198,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
if(!(var instanceof PsiVariable) || !nonFinalVariables.contains(var)) return;
PsiExpression rValue = assignment.getRExpression();
if(rValue == null || isVariableReferenced((PsiVariable)var, rValue)) return;
if(tb.getVariable() instanceof PsiPrimitiveType && !isIdentityMapping(tb.getVariable(), rValue)) return;
registerProblem(holder, isOnTheFly, statement, "findFirst", new ReplaceWithFindFirstFix());
}
}
@@ -240,7 +240,8 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
if (!isVariableReferenced(tb.getVariable(), value)) {
registerProblem(holder, isOnTheFly, statement, "anyMatch", new ReplaceWithMatchFix("anyMatch"));
}
if(nextReturnStatement != null && ExpressionUtils.isSimpleExpression(nextReturnStatement.getReturnValue())) {
if(nextReturnStatement != null && ExpressionUtils.isSimpleExpression(nextReturnStatement.getReturnValue())
&& (!(tb.getVariable().getType() instanceof PsiPrimitiveType) || isIdentityMapping(tb.getVariable(), value))) {
registerProblem(holder, isOnTheFly, statement, "findFirst", new ReplaceWithFindFirstFix());
}
}
@@ -541,6 +542,13 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
return method != null && isThrowsCompatible(method);
}
static boolean isSupported(PsiType type) {
if(type instanceof PsiPrimitiveType) {
return type.equals(PsiType.INT) || type.equals(PsiType.LONG) || type.equals(PsiType.DOUBLE);
}
return true;
}
private static boolean isThrowsCompatible(PsiMethod method) {
return ContainerUtil.find(method.getThrowsList().getReferencedTypes(), type -> !ExceptionUtil.isUncheckedException(type)) != null;
}
@@ -633,13 +641,48 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
}
static class MapOp extends Operation {
MapOp(PsiExpression expression, PsiVariable variable) {
private final @Nullable PsiType myType;
MapOp(PsiExpression expression, PsiVariable variable, @Nullable PsiType targetType) {
super(expression, variable);
myType = targetType;
}
MapOp(PsiExpression expression, PsiVariable variable) {
this(expression, variable, expression.getType());
}
@Override
public String createReplacement(PsiElementFactory factory) {
return ".map(" + createLambda(myVariable, myExpression) + ")";
if (isIdentityMapping(myVariable, myExpression)) {
if (!(myType instanceof PsiPrimitiveType)) {
return myVariable.getType() instanceof PsiPrimitiveType ? ".boxed()" : "";
}
if(myType.equals(myVariable.getType())) {
return "";
}
if (PsiType.LONG.equals(myType) && PsiType.INT.equals(myVariable.getType())) {
return ".asLongStream()";
}
if (PsiType.DOUBLE.equals(myType) && (PsiType.LONG.equals(myVariable.getType()) || PsiType.INT.equals(myVariable.getType()))) {
return ".asDoubleStream()";
}
}
String operationName = "map";
if(myType instanceof PsiPrimitiveType) {
if(!myType.equals(myVariable.getType())) {
if(PsiType.INT.equals(myType)) {
operationName = "mapToInt";
} else if(PsiType.LONG.equals(myType)) {
operationName = "mapToLong";
} else if(PsiType.DOUBLE.equals(myType)) {
operationName = "mapToDouble";
}
}
} else if(myVariable.getType() instanceof PsiPrimitiveType) {
operationName = "mapToObj";
}
return "."+operationName+"(" + createLambda(myVariable, myExpression) + ")";
}
}
@@ -663,7 +706,21 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
@Override
public String createReplacement(PsiElementFactory factory) {
PsiExpression replacement = factory.createExpressionFromText("java.util.Arrays.stream("+myExpression.getText() + ")", myExpression);
return ".flatMap(" + createLambda(myVariable, replacement) + ")";
String operation = "flatMap";
PsiType type = myExpression.getType();
if(type instanceof PsiArrayType) {
PsiType componentType = ((PsiArrayType)type).getComponentType();
if(componentType instanceof PsiPrimitiveType) {
if(componentType.equals(PsiType.INT)) {
operation = "flatMapToInt";
} else if(componentType.equals(PsiType.LONG)) {
operation = "flatMapToLong";
} else if(componentType.equals(PsiType.DOUBLE)) {
operation = "flatMapToDouble";
}
}
}
return "."+operation+"(" + createLambda(myVariable, replacement) + ")";
}
}
@@ -740,6 +797,8 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
}
// extract flatMap
if(getSingleStatement() instanceof PsiForeachStatement) {
// flatMapping of primitive variable is not supported yet
if(myVariable.getType() instanceof PsiPrimitiveType) return null;
PsiForeachStatement foreachStatement = (PsiForeachStatement)getSingleStatement();
final PsiExpression iteratedValue = foreachStatement.getIteratedValue();
final PsiStatement body = foreachStatement.getBody();
@@ -747,9 +806,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
final PsiType iteratedValueType = iteratedValue.getType();
Operation op = null;
if(iteratedValueType instanceof PsiArrayType) {
// do not handle flatMapToPrimitive
if (((PsiArrayType)iteratedValueType).getComponentType() instanceof PsiPrimitiveType)
return null;
if (!isSupported(((PsiArrayType)iteratedValueType).getComponentType())) return null;
op = new ArrayFlatMapOp(iteratedValue, myVariable);
} else {
final PsiClass iteratorClass = PsiUtil.resolveClassInClassTypeOnly(iteratedValueType);
@@ -777,14 +834,13 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
PsiElement element = elements[0];
if(element instanceof PsiLocalVariable) {
PsiLocalVariable declaredVar = (PsiLocalVariable)element;
// do not handle mapToPrimitive
if(!(declaredVar.getType() instanceof PsiPrimitiveType)) {
if(isSupported(declaredVar.getType())) {
PsiExpression initializer = declaredVar.getInitializer();
PsiStatement[] leftOver = Arrays.copyOfRange(myStatements, 1, myStatements.length);
if (initializer != null &&
ReferencesSearch.search(myVariable, new LocalSearchScope(leftOver))
.findFirst() == null) {
MapOp op = new MapOp(initializer, myVariable);
MapOp op = new MapOp(initializer, myVariable, declaredVar.getType());
myVariable = declaredVar;
myStatements = leftOver;
flatten();
@@ -845,18 +901,6 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
return new TerminalBlock(variable, new PsiStatement[] {statement});
}
@NotNull
List<String> extractOperationReplacements(PsiElementFactory factory) {
List<String> intermediateOps = new ArrayList<>();
while(true) {
Operation operation = extractOperation();
if(operation == null)
break;
intermediateOps.add(operation.createReplacement(factory));
}
return intermediateOps;
}
/**
* Converts this TerminalBlock to PsiElement (either PsiStatement or PsiCodeBlock)
*
@@ -0,0 +1,9 @@
// "Replace with anyMatch()" "true"
import java.util.List;
public class Main {
public boolean testPrimitiveMap(List<String> data) {
return data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).anyMatch(len -> len > 10);
}
}
@@ -0,0 +1,11 @@
// "Replace with collect" "true"
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public void testPrimitiveMap(List<String> data) {
List<Integer> list = data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).filter(len -> len > 10).boxed().collect(Collectors.toList());
}
}
@@ -0,0 +1,11 @@
// "Replace with collect" "true"
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public void testPrimitiveMap(List<String> data) {
List<String> list = data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).filter(len -> len > 10).mapToObj(String::valueOf).collect(Collectors.toList());
}
}
@@ -0,0 +1,10 @@
// "Replace with count()" "true"
import java.util.Arrays;
public class Main {
public int testPrimitiveArray(int[] data) {
int count = (int) Arrays.stream(data).mapToLong(val -> val * val).filter(square -> square > 100).count();
return count;
}
}
@@ -0,0 +1,9 @@
// "Replace with findFirst()" "true"
import java.util.List;
public class Main {
public int testPrimitiveMap(List<String> data) {
return data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).filter(len -> len > 10).findFirst().orElse(0);
}
}
@@ -1,17 +1,13 @@
// "Replace with forEach" "true"
// "Replace with collect" "true"
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class Main {
public List<Integer> test(int[][] arr) {
List<Integer> result = new ArrayList<>();
Arrays.stream(arr).filter(Objects::nonNull).forEach(subArr -> {
for (int str : subArr) {
result.add(str);
}
});
return result;
List<Integer> result = Arrays.stream(arr).filter(Objects::nonNull).flatMapToInt(Arrays::stream).boxed().collect(Collectors.toList());
return result;
}
}
@@ -6,9 +6,9 @@ import java.util.Objects;
class Sample {
List<String> foo = new ArrayList<>();
String foo(){
foo.stream().filter(Objects::isNull).forEach(s -> {
int i = 0;
});
foo.stream().filter(Objects::isNull).forEach(s -> bar());
return null;
}
bar() {}
}
@@ -0,0 +1,9 @@
// "Replace with sum()" "true"
import java.util.List;
public class Main {
public void testPrimitiveMap(List<String> data) {
int sum = data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).filter(len -> len > 10).map(len -> len * 2).sum();
}
}
@@ -0,0 +1,9 @@
// "Replace with sum()" "true"
import java.util.List;
public class Main {
public void testPrimitiveMap(List<String> data) {
long sum = data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).filter(len -> len > 10).asLongStream().sum();
}
}
@@ -0,0 +1,17 @@
// "Replace with anyMatch()" "false"
import java.util.List;
public class Main {
public boolean testPrimitiveMap(List<String> data) {
for(String str : d<caret>ata) {
if(str.startsWith("xyz")) {
float len = str.length();
if(len > 10) {
return true;
}
}
}
return false;
}
}
@@ -0,0 +1,17 @@
// "Replace with anyMatch()" "true"
import java.util.List;
public class Main {
public boolean testPrimitiveMap(List<String> data) {
for(String str : d<caret>ata) {
if(str.startsWith("xyz")) {
int len = str.length();
if(len > 10) {
return true;
}
}
}
return false;
}
}
@@ -0,0 +1,18 @@
// "Replace with collect" "true"
import java.util.ArrayList;
import java.util.List;
public class Main {
public void testPrimitiveMap(List<String> data) {
List<Integer> list = new ArrayList<>();
for(String str : d<caret>ata) {
if(str.startsWith("xyz")) {
int len = str.length();
if(len > 10) {
list.add(len);
}
}
}
}
}
@@ -0,0 +1,18 @@
// "Replace with collect" "true"
import java.util.ArrayList;
import java.util.List;
public class Main {
public void testPrimitiveMap(List<String> data) {
List<String> list = new ArrayList<>();
for(String str : d<caret>ata) {
if(str.startsWith("xyz")) {
int len = str.length();
if(len > 10) {
list.add(String.valueOf(len));
}
}
}
}
}
@@ -0,0 +1,14 @@
// "Replace with count()" "true"
public class Main {
public int testPrimitiveArray(int[] data) {
int count = 0;
for(int val : dat<caret>a) {
long square = val*val;
if(square > 100) {
count++;
}
}
return count;
}
}
@@ -0,0 +1,14 @@
// "Replace with count()" "false"
public class Main {
public int testPrimitiveArray(short[] data) {
int count = 0;
for(int val : dat<caret>a) {
long square = val*val;
if(square > 100) {
count++;
}
}
return count;
}
}
@@ -0,0 +1,17 @@
// "Replace with findFirst()" "true"
import java.util.List;
public class Main {
public int testPrimitiveMap(List<String> data) {
for(String str : dat<caret>a) {
if(str.startsWith("xyz")) {
int len = str.length();
if(len > 10) {
return len;
}
}
}
return 0;
}
}
@@ -0,0 +1,18 @@
// "Replace with findFirst()" "false"
import java.util.List;
// Not supported as OptionalInt lacks mapping method
public class Main {
public int testPrimitiveMap(List<String> data) {
for(String str : dat<caret>a) {
if(str.startsWith("xyz")) {
int len = str.length();
if(len > 10) {
return len * 2;
}
}
}
return 0;
}
}
@@ -1,6 +1,6 @@
// "Replace with forEach" "true"
// "Replace with collect" "true"
import java.util.ArrayList;
import java.util.List;
import java.util.List;
public class Main {
public List<Integer> test(int[][] arr) {
@@ -6,8 +6,10 @@ class Sample {
List<String> foo = new ArrayList<>();
String foo(){
for (String s : fo<caret>o) {
if (s == null) int i = 0;
if (s == null) bar();
}
return null;
}
bar() {}
}
@@ -0,0 +1,17 @@
// "Replace with sum()" "true"
import java.util.List;
public class Main {
public void testPrimitiveMap(List<String> data) {
int sum = 0;
for(String str : dat<caret>a) {
if(str.startsWith("xyz")) {
int len = str.length();
if(len > 10) {
sum += len*2;
}
}
}
}
}
@@ -0,0 +1,17 @@
// "Replace with sum()" "true"
import java.util.List;
public class Main {
public void testPrimitiveMap(List<String> data) {
long sum = 0;
for(String str : da<caret>ta) {
if(str.startsWith("xyz")) {
int len = str.length();
if(len > 10) {
sum += len;
}
}
}
}
}