improve conversion to stream api for joining cases

This commit is contained in:
Roman Ivanov
2017-08-17 10:21:31 +07:00
parent d562896618
commit fa416812fc
79 changed files with 2551 additions and 236 deletions
@@ -53,6 +53,9 @@ public class AddMethodQualifierFix implements IntentionAction {
@Override
public String getText() {
if (myCandidates == null || myCandidates.isEmpty()) {
if(ApplicationManager.getApplication().isUnitTestMode()) {
return "";
}
throw new IllegalStateException();
}
if (myCandidates.size() == 1) {
@@ -16,22 +16,18 @@
package com.intellij.codeInspection.streamMigration;
import com.intellij.codeInsight.intention.impl.StreamRefactoringUtil;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.CountingLoopSource;
import com.intellij.codeInspection.util.LambdaGenerationUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
import com.siyeh.ig.callMatcher.CallMatcher;
import com.siyeh.ig.psiutils.*;
import com.siyeh.ig.psiutils.ControlFlowUtils.InitializerUsageStatus;
import one.util.streamex.EntryStream;
@@ -82,7 +78,7 @@ class CollectMigration extends BaseStreamApiMigration {
PsiElement migrate(@NotNull Project project, @NotNull PsiStatement body, @NotNull TerminalBlock tb) {
PsiLoopStatement loopStatement = tb.getMainLoop();
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
CollectTerminal terminal = extractCollectTerminal(tb);
CollectTerminal terminal = extractCollectTerminal(tb, null);
if (terminal == null) return null;
String stream = tb.generate() + terminal.generateIntermediate() + terminal.generateTerminal();
PsiElement toReplace = terminal.getElementToReplace();
@@ -124,30 +120,21 @@ class CollectMigration extends BaseStreamApiMigration {
}
@Nullable
static CollectTerminal extractCollectTerminal(TerminalBlock tb) {
static CollectTerminal extractCollectTerminal(@NotNull TerminalBlock tb, @Nullable List<PsiVariable> nonFinalVariables) {
if(nonFinalVariables != null && !nonFinalVariables.isEmpty()) {
return null;
}
PsiMethodCallExpression call;
PsiMethodCallExpression delimiterAppend;
PsiStatement[] statements = tb.getStatements();
if (statements.length == 2) {
// Check for delimiter append like: if(sb.length() > 0) sb.append(", ")
if (!(statements[1] instanceof PsiExpressionStatement)) return null;
call = tryCast(((PsiExpressionStatement)statements[1]).getExpression(), PsiMethodCallExpression.class);
if (!(statements[0] instanceof PsiIfStatement)) return null;
delimiterAppend = StringBuilderTerminal.extractDelimiterAppend(tb, (PsiIfStatement)statements[0]);
if (delimiterAppend == null || VariableAccessUtils.variableIsUsed(tb.getVariable(), delimiterAppend)) return null;
}
else {
delimiterAppend = null;
call = tb.getSingleMethodCall();
}
call = tb.getSingleMethodCall();
if (call == null) return null;
PsiReferenceExpression methodExpression = call.getMethodExpression();
PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
if (tb.dependsOn(qualifierExpression)) return null;
List<BiFunction<TerminalBlock, PsiMethodCallExpression, CollectTerminal>> extractors = Arrays
.asList(AddingTerminal::tryExtract, GroupingTerminal::tryExtract, ToMapTerminal::tryExtract, AddingAllTerminal::tryExtractAddAll,
(t, c) -> StringBuilderTerminal.tryExtract(t, c, delimiterAppend));
.asList(AddingTerminal::tryExtract, GroupingTerminal::tryExtract, ToMapTerminal::tryExtract, AddingAllTerminal::tryExtractAddAll);
CollectTerminal terminal = StreamEx.of(extractors).map(extractor -> extractor.apply(tb, call)).nonNull().findFirst().orElse(null);
if (terminal != null) {
@@ -535,217 +522,6 @@ class CollectMigration extends BaseStreamApiMigration {
}
}
static class StringBuilderTerminal extends CollectTerminal {
private static final CallMatcher APPEND = CallMatcher.anyOf(
CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING_BUILDER, "append").parameterCount(1),
CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_STRING_BUFFER, "append").parameterCount(1)
);
private final PsiVariable myElement;
private final PsiMethodCallExpression myAppendCall;
private final PsiMethodCallExpression myFinalAppendCall;
private final PsiExpression myDelimiter;
StringBuilderTerminal(PsiLocalVariable variable,
PsiLoopStatement loop,
PsiVariable element,
PsiMethodCallExpression appendCall,
PsiExpression delimiter,
PsiMethodCallExpression finalAppend) {
super(variable, loop, getInitializerUsageStatus(variable, loop));
myElement = element;
myAppendCall = appendCall;
myFinalAppendCall = finalAppend;
myDelimiter = delimiter;
}
@Override
public String generateIntermediate() {
PsiExpression mapping = myAppendCall.getArgumentList().getExpressions()[0];
mapping = JavaPsiFacade.getElementFactory(mapping.getProject()).createExpressionFromText(expressionToCharSequence(mapping), mapping);
return StreamRefactoringUtil.generateMapOperation(myElement, null, mapping);
}
@NotNull
private static String expressionToCharSequence(@NotNull PsiExpression expression) {
PsiType type = expression.getType();
if (!InheritanceUtil.isInheritor(type, "java.lang.CharSequence")) {
if (expression instanceof PsiLiteralExpression) {
Object value = ((PsiLiteralExpression)expression).getValue();
if (value instanceof Character) {
return "\"" + StringUtil.escapeStringCharacters(value.toString()) + "\"";
}
}
return CommonClassNames.JAVA_LANG_STRING + ".valueOf(" + expression.getText() + ")";
}
return expression.getText();
}
@Override
String generateTerminal() {
String delimiter = myDelimiter == null ? "" : expressionToCharSequence(myDelimiter);
PsiExpression initializer = getTargetVariable().getInitializer();
String initialText = ConstructionUtils.getStringBuilderInitializerText(initializer);
String finalText = "\"\"";
if (myFinalAppendCall != null) {
finalText = expressionToCharSequence(myFinalAppendCall.getArgumentList().getExpressions()[0]);
}
String args;
if ("\"\"".equals(initialText) && "\"\"".equals(finalText)) {
args = delimiter;
}
else {
args = (delimiter.isEmpty() ? "\"\"" : delimiter) + "," + initialText + "," + finalText;
}
return ".collect(" + CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS + ".joining(" + args + "))";
}
@Override
boolean isTrivial() {
return myDelimiter == null;
}
@Override
void cleanUp() {
PsiLocalVariable target = getTargetVariable();
PsiElementFactory factory = JavaPsiFacade.getElementFactory(target.getProject());
target.getTypeElement().replace(factory.createTypeElementFromText(CommonClassNames.JAVA_LANG_STRING, target));
if (getStatus() == ControlFlowUtils.InitializerUsageStatus.AT_WANTED_PLACE) {
PsiExpression initializer = target.getInitializer();
String initialText = ConstructionUtils.getStringBuilderInitializerText(initializer);
if (initialText != null) {
initializer.replace(factory.createExpressionFromText(initialText, target));
}
}
if (myFinalAppendCall != null) {
if (myFinalAppendCall.getParent() instanceof PsiExpressionStatement) {
myFinalAppendCall.delete();
} else {
PsiMethodCallExpression nextCall = ExpressionUtils.getCallForQualifier(myFinalAppendCall);
PsiExpression qualifier = myFinalAppendCall.getMethodExpression().getQualifierExpression();
if (nextCall != null && qualifier != null) {
nextCall.replace(qualifier);
}
}
}
Collection<PsiReference> usages = ReferencesSearch.search(target).findAll();
for (PsiReference usage : usages) {
PsiElement element = usage.getElement();
if (element.isValid() && element instanceof PsiExpression) {
PsiMethodCallExpression call = ExpressionUtils.getCallForQualifier((PsiExpression)element);
if (call != null && "toString".equals(call.getMethodExpression().getReferenceName())) {
call.replace(element);
}
}
}
}
static PsiMethodCallExpression getAfterLoopAppend(PsiLoopStatement loop, PsiVariable target) {
PsiElement next = PsiTreeUtil.skipWhitespacesAndCommentsForward(loop);
if (!(next instanceof PsiExpressionStatement)) return null;
PsiExpression expression = ((PsiExpressionStatement)next).getExpression();
if (!(expression instanceof PsiMethodCallExpression)) return null;
PsiMethodCallExpression call = (PsiMethodCallExpression)expression;
if (APPEND.test(call) && ExpressionUtils.isReferenceTo(call.getMethodExpression().getQualifierExpression(), target)) return call;
return null;
}
static PsiExpression getExpressionComparedToZero(PsiBinaryExpression condition) {
if (condition == null) return null;
IElementType tokenType = condition.getOperationTokenType();
PsiExpression left = condition.getLOperand();
PsiExpression right = condition.getROperand();
if (ExpressionUtils.isZero(right)) {
if (tokenType.equals(JavaTokenType.NE) || tokenType.equals(JavaTokenType.GT)) return left;
}
else if (ExpressionUtils.isZero(left)) {
if (tokenType.equals(JavaTokenType.NE) || tokenType.equals(JavaTokenType.LT)) return right;
}
return null;
}
static PsiMethodCallExpression extractDelimiterAppend(TerminalBlock tb, PsiIfStatement ifStatement) {
if (ifStatement.getElseBranch() != null) return null;
PsiExpressionStatement thenBranch = tryCast(ControlFlowUtils.stripBraces(ifStatement.getThenBranch()), PsiExpressionStatement.class);
if (thenBranch == null) return null;
PsiBinaryExpression condition = tryCast(PsiUtil.skipParenthesizedExprDown(ifStatement.getCondition()), PsiBinaryExpression.class);
PsiExpression comparedToZero = getExpressionComparedToZero(condition);
if (comparedToZero == null) return null;
PsiMethodCallExpression maybeLength = tryCast(PsiUtil.skipParenthesizedExprDown(comparedToZero), PsiMethodCallExpression.class);
PsiLocalVariable builder = null;
if (isCallOf(maybeLength, CommonClassNames.JAVA_LANG_ABSTRACT_STRING_BUILDER, "length")) {
builder = extractQualifierVariable(tb, maybeLength);
if (builder == null) return null;
}
else {
CountingLoopSource source = tb.getLastOperation(CountingLoopSource.class);
if (source == null ||
!ExpressionUtils.isZero(source.getExpression()) ||
!ExpressionUtils.isReferenceTo(comparedToZero, source.getVariable())) {
return null;
}
}
PsiMethodCallExpression call = tryCast(thenBranch.getExpression(), PsiMethodCallExpression.class);
if (!APPEND.test(call)) return null;
return builder == null || extractQualifierVariable(tb, call) == builder ? call : null;
}
static StringBuilderTerminal tryExtract(TerminalBlock tb, PsiMethodCallExpression call, PsiMethodCallExpression delimiterAppend) {
if (tb.getCountExpression() != null) return null;
if (!APPEND.test(call)) return null;
PsiLocalVariable targetBuilder = extractQualifierVariable(tb, call);
if (targetBuilder == null) return null;
if (delimiterAppend != null &&
!ExpressionUtils.isReferenceTo(delimiterAppend.getMethodExpression().getQualifierExpression(), targetBuilder)) {
return null;
}
String initialText = ConstructionUtils.getStringBuilderInitializerText(targetBuilder.getInitializer());
if (initialText == null) return null;
PsiMethodCallExpression finalAppend = getAfterLoopAppend(tb.getMainLoop(), targetBuilder);
List<PsiElement> refs = StreamEx.of(ReferencesSearch.search(targetBuilder).findAll())
.map(PsiReference::getElement)
.remove(e -> PsiTreeUtil.isAncestor(targetBuilder, e, false) || PsiTreeUtil.isAncestor(tb.getMainLoop(), e, false))
.toList();
if (!refs.stream().allMatch(PsiExpression.class::isInstance)) return null;
boolean allowed = areReferencesAllowed(finalAppend, refs);
if (!allowed && refs.size() == 1 && finalAppend == null) {
PsiMethodCallExpression usage = ExpressionUtils.getCallForQualifier((PsiExpression)refs.get(0));
if (APPEND.test(usage)) {
PsiMethodCallExpression nextCall = ExpressionUtils.getCallForQualifier(usage);
if (nextCall != null && "toString".equals(nextCall.getMethodExpression().getReferenceName())) {
finalAppend = usage;
allowed = true;
}
}
}
if (!allowed) return null;
PsiExpression delimiter = delimiterAppend == null ? null : delimiterAppend.getArgumentList().getExpressions()[0];
return new StringBuilderTerminal(targetBuilder, tb.getMainLoop(), tb.getVariable(), call, delimiter, finalAppend);
}
private static boolean areReferencesAllowed(PsiMethodCallExpression finalAppend, List<PsiElement> refs) {
return StreamEx.of(refs).select(PsiExpression.class).allMatch(expression -> {
PsiMethodCallExpression usage = ExpressionUtils.getCallForQualifier(expression);
if (usage != null) {
if (usage == finalAppend) return true;
PsiExpression[] usageArgs = usage.getArgumentList().getExpressions();
String name = usage.getMethodExpression().getReferenceName();
if (usageArgs.length == 0 && ("toString".equals(name) || "length".equals(name))) return true;
}
PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression.getParent());
if (parent instanceof PsiPolyadicExpression &&
((PsiPolyadicExpression)parent).getOperationTokenType().equals(JavaTokenType.PLUS)) {
return true;
}
if (parent instanceof PsiAssignmentExpression &&
((PsiAssignmentExpression)parent).getOperationTokenType().equals(JavaTokenType.PLUSEQ)) {
return true;
}
return false;
});
}
}
static class SortingTerminal extends CollectTerminal {
private final CollectTerminal myDownstream;
private final PsiExpression myComparator;
@@ -0,0 +1,329 @@
/*
* Copyright 2000-2017 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.codeInspection.streamMigration;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ThreeState;
import com.intellij.util.containers.ContainerUtil;
import com.siyeh.ig.psiutils.BoolUtils;
import com.siyeh.ig.psiutils.ExpressionUtils;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
import static com.intellij.util.ObjectUtils.tryCast;
import static com.siyeh.ig.psiutils.ExpressionUtils.resolveLocalVariable;
class SpecialFirstIterationLoop {
private final @NotNull List<PsiStatement> myFirstIterationStatements;
private final @NotNull List<PsiStatement> myOtherIterationStatements;
private final @Nullable PsiLocalVariable myVariable;
public SpecialFirstIterationLoop(@NotNull List<PsiStatement> firstIterationStatements,
@NotNull List<PsiStatement> otherIterationStatements,
@Nullable PsiLocalVariable variable) {
myFirstIterationStatements = firstIterationStatements;
myOtherIterationStatements = otherIterationStatements;
myVariable = variable;
}
@NotNull
public List<PsiStatement> getOtherIterationStatements() {
return myOtherIterationStatements;
}
@NotNull
public List<PsiStatement> getFirstIterationStatements() {
return myFirstIterationStatements;
}
@Nullable
public PsiLocalVariable getVariable() {
return myVariable;
}
@Nullable
private static PsiExpression getExpressionComparedEqWithZero(@NotNull PsiBinaryExpression binaryExpression) {
if (!binaryExpression.getOperationTokenType().equals(JavaTokenType.EQEQ)) return null;
PsiExpression rOperand = binaryExpression.getROperand();
if (rOperand == null) return null;
PsiExpression lOperand = binaryExpression.getLOperand();
if (ExpressionUtils.isZero(lOperand)) return rOperand;
if (ExpressionUtils.isZero(rOperand)) return lOperand;
return null;
}
@Contract("null -> null")
@Nullable
static PsiExpression getExpressionComparedToZero(@Nullable PsiBinaryExpression condition) {
if (condition == null) return null;
IElementType tokenType = condition.getOperationTokenType();
PsiExpression left = condition.getLOperand();
PsiExpression right = condition.getROperand();
if (ExpressionUtils.isZero(right)) {
if (tokenType.equals(JavaTokenType.NE) || tokenType.equals(JavaTokenType.GT)) return left;
}
else if (ExpressionUtils.isZero(left)) {
if (tokenType.equals(JavaTokenType.NE) || tokenType.equals(JavaTokenType.LT)) return right;
}
return null;
}
@Nullable
private static SpecialFirstIterationLoop extract(boolean firstIterationThen,
int index,
@NotNull List<PsiStatement> statements,
@NotNull PsiLocalVariable checkVar) {
PsiStatement statement = statements.get(index);
PsiIfStatement ifStatement = tryCast(statement, PsiIfStatement.class);
if (ifStatement == null) return null;
List<PsiStatement> thenStatements = unwrapBlock(ifStatement.getThenBranch());
List<PsiStatement> elseStatements = unwrapBlock(ifStatement.getElseBranch());
return extract(firstIterationThen, index, thenStatements, elseStatements, statements, checkVar);
}
@Nullable
private static SpecialFirstIterationLoop extract(boolean firstIterationThen,
int index,
@NotNull List<PsiStatement> thenStatements,
@NotNull List<PsiStatement> elseStatements,
@NotNull List<PsiStatement> statements,
@NotNull PsiLocalVariable checkVar) {
PsiStatement statement = statements.get(index);
PsiIfStatement ifStatement = tryCast(statement, PsiIfStatement.class);
if (ifStatement == null) return null;
List<PsiStatement> beforeStatements = statements.subList(0, index);
List<PsiStatement> afterStatements = statements.subList(index + 1, statements.size());
ArrayList<PsiStatement> firstIteration = new ArrayList<>(beforeStatements);
ArrayList<PsiStatement> otherIterations = new ArrayList<>(beforeStatements);
firstIteration.addAll(firstIterationThen ? thenStatements : elseStatements);
firstIteration.addAll(afterStatements);
otherIterations.addAll(firstIterationThen ? elseStatements : thenStatements);
otherIterations.addAll(afterStatements);
return new SpecialFirstIterationLoop(firstIteration, otherIterations, checkVar);
}
/**
* @return index of PsiStatement if it is the only statement, matches predicate or -1 otherwise
*/
private static int getSingleStatementIndex(@NotNull List<PsiStatement> statements, @NotNull Predicate<PsiStatement> predicate) {
int index = -1;
for (int i = 0; i < statements.size(); i++) {
PsiStatement statement = statements.get(i);
if (!predicate.test(statement)) continue;
if (index != -1) return -1;
index = i;
}
return index;
}
private static int getSingleAssignmentIndex(@NotNull List<PsiStatement> statements) {
return getSingleStatementIndex(statements, statement -> ExpressionUtils.getAssignment(statement) != null);
}
static class BoolFlagLoop {
private BoolFlagLoop(){}
/*
Cases:
if(first) { ... } else { ... }
if(!first) ...
if(notFirst) ...
*/
@Nullable
static SpecialFirstIterationLoop extract(TerminalBlock terminalBlock) {
ArrayList<PsiStatement> statements = ContainerUtil.newArrayList(terminalBlock.getStatements());
int index = getSingleStatementIndex(statements, PsiIfStatement.class::isInstance);
if (index == -1) return null;
PsiStatement statement = statements.get(index);
PsiIfStatement ifStatement = tryCast(statement, PsiIfStatement.class);
if (ifStatement == null) return null;
ThreeState firstIterationThen = isFirstIterationThen(statement);
if (firstIterationThen.equals(ThreeState.UNSURE)) return null;
final ConditionData conditionData = ConditionData.extract(ifStatement, firstIterationThen.toBoolean());
if(conditionData == null) return null;
PsiAssignmentExpression assignment = conditionData.getAssignment();
PsiExpression expression = assignment.getLExpression();
PsiLocalVariable boolFlag = resolveLocalVariable(expression);
if(boolFlag == null) return null;
PsiExpression rExpression = assignment.getRExpression();
if (rExpression == null) return null;
if (!assignmentNegatesInitializer(boolFlag, rExpression)) return null;
PsiExpression condition = ifStatement.getCondition();
boolean referencesAllowed =
ReferencesSearch.search(boolFlag).forEach(reference -> PsiTreeUtil.isAncestor(condition, reference.getElement(), false) ||
PsiTreeUtil.isAncestor(assignment, reference.getElement(), false) ||
PsiTreeUtil.isAncestor(boolFlag, reference.getElement(), false));
if (!referencesAllowed) return null;
return SpecialFirstIterationLoop
.extract(firstIterationThen.toBoolean(), index, conditionData.getThenStatements(), conditionData.getElseStatements(), statements,
boolFlag);
}
private static boolean assignmentNegatesInitializer(@NotNull PsiVariable boolFlag, @NotNull PsiExpression expression) {
Object constantExpression = ExpressionUtils.computeConstantExpression(expression);
if (!(constantExpression instanceof Boolean)) return false;
boolean assignmentValue = (boolean)constantExpression;
return ExpressionUtils.isLiteral(PsiUtil.skipParenthesizedExprDown(boolFlag.getInitializer()), !assignmentValue);
}
@NotNull
private static ThreeState isFirstIterationThen(@NotNull PsiStatement statement) {
PsiIfStatement ifStatement = tryCast(statement, PsiIfStatement.class);
if (ifStatement == null) return ThreeState.UNSURE;
PsiExpression condition = ifStatement.getCondition();
if (condition == null) return ThreeState.UNSURE;
boolean negated = BoolUtils.isNegation(condition);
condition = PsiUtil.skipParenthesizedExprDown(condition);
PsiExpression expression = negated ? BoolUtils.getNegated(condition) : condition;
PsiLocalVariable boolFlagVar = resolveLocalVariable(expression);
if(boolFlagVar == null) return ThreeState.UNSURE;
return ThreeState.fromBoolean(ExpressionUtils.isLiteral(PsiUtil.skipParenthesizedExprDown(boolFlagVar.getInitializer()), !negated));
}
private static class ConditionData {
private final @NotNull List<PsiStatement> myThenStatements;
private final @NotNull List<PsiStatement> myElseStatements;
private final @NotNull PsiAssignmentExpression myAssignment;
private ConditionData(@NotNull List<PsiStatement> thenStatements,
@NotNull List<PsiStatement> elseStatements,
@NotNull PsiAssignmentExpression assignment) {
myThenStatements = thenStatements;
myElseStatements = elseStatements;
myAssignment = assignment;
}
@NotNull
public PsiAssignmentExpression getAssignment() {
return myAssignment;
}
@NotNull
public List<PsiStatement> getElseStatements() {
return myElseStatements;
}
@NotNull
public List<PsiStatement> getThenStatements() {
return myThenStatements;
}
@Nullable
static ConditionData extract(@NotNull PsiIfStatement ifStatement, boolean firstIterationThen) {
PsiStatement block = firstIterationThen ? ifStatement.getThenBranch() : ifStatement.getElseBranch();
ArrayList<PsiStatement> firstIterationStatements = new ArrayList<>(unwrapBlock(block));
int index = getSingleAssignmentIndex(firstIterationStatements);
if (index == -1) return null;
PsiStatement assignment = firstIterationStatements.remove(index);
PsiExpressionStatement expressionStatement = tryCast(assignment, PsiExpressionStatement.class);
if(expressionStatement == null) return null;
PsiAssignmentExpression assignmentExpression = tryCast(expressionStatement.getExpression(), PsiAssignmentExpression.class);
if(assignmentExpression == null) return null;
PsiStatement otherBlock = firstIterationThen ? ifStatement.getElseBranch() : ifStatement.getThenBranch();
List<PsiStatement> otherIterationStatements = unwrapBlock(otherBlock);
return firstIterationThen
? new ConditionData(firstIterationStatements, otherIterationStatements, assignmentExpression)
: new ConditionData(otherIterationStatements, firstIterationStatements, assignmentExpression);
}
}
}
static class IndexBasedLoop{
private IndexBasedLoop(){}
/*
if(i == 0) {
sb.append(mainPart);
} else {
sb.append(",").append(mainPart);
}
if(i > 0) {
sb.append(",");
}
sb.append(mainPart)
if(i != 0) {
sb.append(",");
}
sb.append(mainPart)
*/
@Nullable
static SpecialFirstIterationLoop extract(@NotNull TerminalBlock terminalBlock) {
StreamApiMigrationInspection.CountingLoopSource countingLoopSource =
terminalBlock.getLastOperation(StreamApiMigrationInspection.CountingLoopSource.class);
if (countingLoopSource == null) return null;
PsiVariable loopVar = countingLoopSource.getVariable();
PsiLocalVariable loopLocalVar = tryCast(loopVar, PsiLocalVariable.class);
if (loopLocalVar == null) return null;
ArrayList<PsiStatement> statements = ContainerUtil.newArrayList(terminalBlock.getStatements());
int index = getSingleStatementIndex(statements, statement -> statement instanceof PsiIfStatement);
if (index == -1) return null;
ThreeState firstIterationThen = isFirstIterationThen(statements.get(index), loopVar);
if (firstIterationThen.equals(ThreeState.UNSURE)) return null;
return SpecialFirstIterationLoop.extract(firstIterationThen.toBoolean(), index, statements, loopLocalVar);
}
@NotNull
private static ThreeState isFirstIterationThen(@NotNull PsiStatement statement, @NotNull PsiVariable loopVar) {
PsiIfStatement ifStatement = tryCast(statement, PsiIfStatement.class);
if (ifStatement == null) return ThreeState.UNSURE;
PsiExpression condition = ifStatement.getCondition();
if (condition == null) return ThreeState.UNSURE;
PsiBinaryExpression binaryExpression = tryCast(condition, PsiBinaryExpression.class);
if (binaryExpression == null) return ThreeState.UNSURE;
PsiExpression comparedEqWithZero = getExpressionComparedEqWithZero(binaryExpression);
if (comparedEqWithZero != null) {
if (!ExpressionUtils.isReferenceTo(comparedEqWithZero, loopVar)) return ThreeState.UNSURE;
return ThreeState.YES;
}
PsiExpression notEqWithZero = getExpressionComparedToZero(binaryExpression);
if (notEqWithZero == null || !ExpressionUtils.isReferenceTo(notEqWithZero, loopVar)) return ThreeState.UNSURE;
return ThreeState.NO;
}
}
@NotNull
private static List<PsiStatement> unwrapBlock(@Nullable PsiStatement statement) {
if(statement == null) return Collections.emptyList();
PsiBlockStatement blockStatement = tryCast(statement, PsiBlockStatement.class);
if(blockStatement == null) return Collections.singletonList(statement);
return ContainerUtil.newArrayList(blockStatement.getCodeBlock().getStatements());
}
}
@@ -473,8 +473,8 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
if (isCountOperation(nonFinalVariables, tb)) {
return new CountMigration(true);
}
if (nonFinalVariables.isEmpty()) {
CollectMigration.CollectTerminal terminal = CollectMigration.extractCollectTerminal(tb);
if (nonFinalVariables.size() == 0) {
CollectMigration.CollectTerminal terminal = CollectMigration.extractCollectTerminal(tb, nonFinalVariables);
if (terminal != null) {
boolean addAll = loop instanceof PsiForeachStatement && !tb.hasOperations() && isAddAllCall(tb);
// Don't suggest to convert the loop which can be trivially replaced via addAll:
@@ -487,6 +487,9 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
return new CollectMigration(shouldWarn, terminal.getMethodName());
}
}
if(JoiningMigration.extractTerminal(tb, nonFinalVariables) != null) {
return new JoiningMigration(true);
}
if (tb.getCountExpression() != null || tb.isEmpty()) return null;
if (nonFinalVariables.isEmpty() && extractArray(tb) != null) {
return new ToArrayMigration(true);
@@ -1102,6 +1105,10 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
return new CountingLoopSource(getLoop(), getVariable(), getExpression(), bound, myIncluding);
}
CountingLoopSource withInitializer(PsiExpression expression) {
return new CountingLoopSource(getLoop(), getVariable(), expression, myBound, myIncluding);
}
@Override
boolean isWriteAllowed(PsiVariable variable, PsiExpression reference) {
if (variable == myVariable) {
@@ -0,0 +1,11 @@
// "Replace with collect" "true"
import java.util.List;
import java.util.stream.Collectors;
public class Test {
private static String work2(List<String> strs) {
String sb = strs.stream().collect(Collectors.joining(",", "{", "}"));
return sb;
}
}
@@ -0,0 +1,13 @@
// "Replace with collect" "true"
import java.util.List;
import java.util.stream.Collectors;
public class Test {
static String test(List<String> list) {
String sb;
System.out.println("hello");
sb = list.stream().filter(s -> !s.isEmpty()).map(s -> s.trim() + String.valueOf(new char[]{'a', 'c'}) + (5 + 6)).collect(Collectors.joining());
return sb.length() == 0 ? null : sb;
}
}
@@ -0,0 +1,13 @@
// "Replace with collect" "true"
import java.util.List;
import java.util.stream.Collectors;
public class Test {
static String test(List<String> list) {
String sb;
System.out.println("hello");
sb = list.stream().filter(s -> !s.isEmpty()).map(s -> s.substring(0, 1)).collect(Collectors.joining());
return sb.length() == 0 ? null : sb;
}
}
@@ -0,0 +1,13 @@
// "Replace with collect" "true"
import java.util.List;
import java.util.stream.Collectors;
public class Test {
static String test(List<String> list) {
String sb;
System.out.println("hello");
sb = list.stream().filter(s -> !s.isEmpty()).map(s -> s.trim() + 12 + "asd" + s + 1).collect(Collectors.joining());
return sb.length() == 0 ? null : sb;
}
}
@@ -0,0 +1,14 @@
// "Replace with collect" "true"
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Test {
static String test(List<String> list) {
int BUFLENGTH = 42;
char CH = 'a';
String sb = IntStream.range(0, BUFLENGTH >> 1).mapToObj(i -> "\u041b" + CH + 'i').collect(Collectors.joining());
}
}
@@ -0,0 +1,19 @@
// "Replace with collect" "true"
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Test {
static String test(List<String> list) {
String sb = "";
if (!list.isEmpty()) {
sb = list.stream().filter(s -> !s.isEmpty()).map(s -> String.valueOf(s.length())).collect(Collectors.joining("\""));
}
return sb.trim();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList("abc", "", "xyz", "argh")));
}
}
@@ -0,0 +1,19 @@
// "Replace with collect" "true"
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Test {
static String test(List<String> list) {
String sb = "";
if (!list.isEmpty()) {
sb = list.stream().filter(s -> !s.isEmpty()).map(s -> s.length() + "!").collect(Collectors.joining("\""));
}
return sb.trim();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList("abc", "", "xyz", "argh")));
}
}
@@ -0,0 +1,19 @@
// "Replace with collect" "true"
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Test {
static String test(List<String> list) {
String sb = "";
if (!list.isEmpty()) {
sb = list.stream().filter(s -> !s.isEmpty()).map(s -> String.valueOf(s.length())).collect(Collectors.joining("\""));
}
return sb.trim();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList("abc", "", "xyz", "argh")));
}
}
@@ -0,0 +1,19 @@
// "Replace with collect" "true"
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Test {
static String test(List<String> list) {
String sb = "";
if (!list.isEmpty()) {
sb = list.stream().filter(s -> !s.isEmpty()).map(s -> String.valueOf(s.length())).collect(Collectors.joining("\""));
}
return sb.trim();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList("abc", "", "xyz", "argh")));
}
}
@@ -0,0 +1,19 @@
// "Replace with collect" "true"
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Test {
static String test(List<String> list) {
String sb = "";
if (!list.isEmpty()) {
sb = list.stream().filter(s -> !s.isEmpty()).map(s -> String.valueOf(s.length())).collect(Collectors.joining("\"", "{", ""));
}
return sb.trim();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList("abc", "", "xyz", "argh")));
}
}
@@ -0,0 +1,20 @@
// "Replace with collect" "true"
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Test {
static String test(List<String> list) {
char CONST_DELIMITER = '"';
String sb = "";
if (!list.isEmpty()) {
sb = list.stream().filter(s -> !s.isEmpty()).map(s -> String.valueOf(s.length())).collect(Collectors.joining(String.valueOf(CONST_DELIMITER)));
}
return sb.trim();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList("abc", "", "xyz", "argh")));
}
}
@@ -0,0 +1,16 @@
// "Replace with collect" "true"
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Test {
static String test(List<String> list) {
String sb = list.stream().filter(s -> !s.isEmpty()).map(s -> String.valueOf(s.length())).collect(Collectors.joining("\""));
return sb.trim();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList("abc", "", "xyz", "argh")));
}
}
@@ -0,0 +1,11 @@
// "Replace with collect" "true"
import java.util.List;
import java.util.stream.Collectors;
public class Test {
private static String work2(List<String> strs) {
String sb = strs.stream().collect(Collectors.joining(",", "{", "}"));
return sb;
}
}
@@ -0,0 +1,11 @@
// "Replace with collect" "true"
import java.util.List;
import java.util.stream.Collectors;
public class Test {
static String test(List<String> list) {
final String sb = list.stream().filter(s -> !s.isEmpty()).map(String::trim).collect(Collectors.joining("", "ctor" + "first", ""));
return sb.length() == 0 ? null : sb;
}
}
@@ -0,0 +1,11 @@
// "Replace with collect" "true"
import java.util.List;
import java.util.stream.Collectors;
public class Test {
public void test(List<String> list) {
String sb = list.stream().limit(10).collect(Collectors.joining(","));
System.out.println(sb);
}
}
@@ -0,0 +1,11 @@
// "Replace with collect" "true"
import java.util.List;
import java.util.stream.Collectors;
public class Test {
public void test(List<String> list) {
String sb = list.stream().limit(10).collect(Collectors.joining(","));
System.out.println(sb);
}
}
@@ -0,0 +1,11 @@
// "Replace with collect" "true"
import java.util.List;
import java.util.stream.Collectors;
public class Test {
public void test(List<String> list) {
String sb = list.stream().limit(10).collect(Collectors.joining(",", "prefix", ""));
System.out.println(sb);
}
}
@@ -0,0 +1,11 @@
// "Replace with collect" "true"
import java.util.List;
import java.util.stream.Collectors;
public class Test {
public void test(List<String> list) {
String sb = list.stream().limit(10).collect(Collectors.joining(","));
System.out.println(sb);
}
}
@@ -0,0 +1,11 @@
// "Replace with collect" "true"
import java.util.List;
import java.util.stream.Collectors;
public class Test {
public void test(List<String> list) {
String sb = list.stream().limit(10).collect(Collectors.joining(","));
System.out.println(sb);
}
}
@@ -0,0 +1,13 @@
// "Replace with collect" "true"
import java.util.List;
import java.util.stream.Collectors;
public class Test {
static String test(List<String> list) {
String sb;
System.out.println("hello");
sb = list.stream().filter(s -> !s.isEmpty()).map(s -> s.trim() + "foo" + 3 + (5 + 6)).collect(Collectors.joining());
return sb.length() == 0 ? null : sb;
}
}
@@ -0,0 +1,13 @@
// "Replace with collect" "true"
import java.util.List;
import java.util.stream.Collectors;
public class Test {
static String test(List<String> list) {
String sb;
boolean first = true;
sb = list.stream().map(s -> ", " + s.trim()).collect(Collectors.joining());
return sb.length() == 0 ? null : sb;
}
}
@@ -0,0 +1,12 @@
// "Replace with collect" "true"
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Test {
static String test(List<String> list) {
int BUFLENGTH = 42;
String sb = IntStream.range(0, BUFLENGTH >> 1).mapToObj(i -> true ? "a" : "b").collect(Collectors.joining());
}
}
@@ -0,0 +1,18 @@
// "Replace with collect" "true"
import java.util.List;
public class Test {
private static String work2(List<String> strs) {
StringBuilder sb = new StringBuilder();
sb.append("{");
String separator = "";
for <caret> (String str : strs) {
sb.append(separator);
sb.append(str);
separator = ",";
}
sb.append("}");
return sb.toString();
}
}
@@ -0,0 +1,17 @@
// "Replace with collect" "false"
import java.util.List;
public class Test {
static String test(List<String> list) {
StringBuilder sb = new StringBuilder();
System.out.println("hello");
for(String s : li<caret>st) {
if(!s.isEmpty()) {
sb.append(s.trim());
}
}
sb.append(sb.length());
return sb.length() == 0 ? null : sb.toString();
}
}
@@ -0,0 +1,16 @@
// "Replace with collect" "true"
import java.util.List;
public class Test {
static String test(List<String> list) {
StringBuilder sb = new StringBuilder();
System.out.println("hello");
for(String s : li<caret>st) {
if(!s.isEmpty()) {
sb.append(s.trim()).append(new char[]{'a', 'c'}).append(5 + 6);
}
}
return sb.length() == 0 ? null : sb.toString();
}
}
@@ -0,0 +1,16 @@
// "Replace with collect" "true"
import java.util.List;
public class Test {
static String test(List<String> list) {
StringBuilder sb = new StringBuilder();
System.out.println("hello");
for(String s : li<caret>st) {
if(!s.isEmpty()) {
sb.append(s.charAt(0));
}
}
return sb.length() == 0 ? null : sb.toString();
}
}
@@ -0,0 +1,16 @@
// "Replace with collect" "true"
import java.util.List;
public class Test {
static String test(List<String> list) {
StringBuilder sb = new StringBuilder();
System.out.println("hello");
for(String s : li<caret>st) {
if(!s.isEmpty()) {
sb.append(s.trim()).append(12 + "asd" + s).append(1);
}
}
return sb.length() == 0 ? null : sb.toString();
}
}
@@ -0,0 +1,17 @@
// "Replace with collect" "true"
import java.util.List;
public class Test {
static String test(List<String> list) {
int BUFLENGTH = 42;
char CH = 'a';
StringBuffer sb = new StringBuffer(BUFLENGTH);
for<caret> (int i = 0; i < BUFLENGTH >> 1; i++) {
sb.append('\u041b');
sb.append(CH);
sb.append('i');
}
}
}
@@ -0,0 +1,23 @@
// "Replace with collect" "false"
import java.util.Arrays;
import java.util.List;
public class Test {
static String test(List<String> list) {
StringBuilder sb = new StringBuilder();
for<caret> (String s : list) {
if (!s.isEmpty()) {
sb.append(s.length()).append('"');
}
}
if (sb.length() > 0) {
sb.setLength(sb.length() - 2);
}
return sb.toString().trim();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList("abc", "", "xyz", "argh")));
}
}
@@ -0,0 +1,28 @@
// "Replace with collect" "true"
import java.util.Arrays;
import java.util.List;
public class Test {
static String test(List<String> list) {
StringBuilder sb = new StringBuilder();
boolean first = true;
if (!list.isEmpty()) {
for (String s : li<caret>st) {
if (!s.isEmpty()) {
if (first) {
sb.append(s.length());
first = false;
} else {
sb.append('"').append(s.length());
}
}
}
}
return sb.toString().trim();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList("abc", "", "xyz", "argh")));
}
}
@@ -0,0 +1,29 @@
// "Replace with collect" "true"
import java.util.Arrays;
import java.util.List;
public class Test {
static String test(List<String> list) {
StringBuilder sb = new StringBuilder();
boolean first = true;
if (!list.isEmpty()) {
for (String s : li<caret>st) {
if (!s.isEmpty()) {
if (first) {
sb.append(s.length());
first = false;
} else {
sb.append('"').append(s.length());
}
sb.append("!");
}
}
}
return sb.toString().trim();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList("abc", "", "xyz", "argh")));
}
}
@@ -0,0 +1,28 @@
// "Replace with collect" "false"
import java.util.Arrays;
import java.util.List;
public class Test {
static String test(List<String> list) {
StringBuilder sb = new StringBuilder();
boolean first = true;
if (!list.isEmpty()) {
for (String s : li<caret>st) {
if (!s.isEmpty()) {
if (first) {
sb.append(s);
first = false;
} else {
sb.append('"').append(s.length());
}
}
}
}
return sb.toString().trim();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList("abc", "", "xyz", "argh")));
}
}
@@ -0,0 +1,29 @@
// "Replace with collect" "true"
import java.util.Arrays;
import java.util.List;
public class Test {
static String test(List<String> list) {
StringBuilder sb = new StringBuilder();
boolean first = true;
if (!list.isEmpty()) {
for (String s : li<caret>st) {
if (!s.isEmpty()) {
if (!first) {
sb.append('"').append(s.length());
}
else {
sb.append(s.length());
first = false;
}
}
}
}
return sb.toString().trim();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList("abc", "", "xyz", "argh")));
}
}
@@ -0,0 +1,27 @@
// "Replace with collect" "false"
import java.util.Arrays;
import java.util.List;
public class Test {
static String test(List<String> list) {
StringBuilder sb = new StringBuilder();
boolean first = true;
if (!list.isEmpty()) {
for (String s : li<caret>st) {
if (!s.isEmpty()) {
if (first) {
sb.append(s.length());
} else {
sb.append('"').append(s.length());
}
}
}
}
return sb.toString().trim();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList("abc", "", "xyz", "argh")));
}
}
@@ -0,0 +1,28 @@
// "Replace with collect" "true"
import java.util.Arrays;
import java.util.List;
public class Test {
static String test(List<String> list) {
StringBuilder sb = new StringBuilder();
boolean notFirst = false;
if (!list.isEmpty()) {
for (String s : li<caret>st) {
if (!s.isEmpty()) {
if (!notFirst) {
sb.append(s.length());
notFirst = true;
} else {
sb.append('"').append(s.length());
}
}
}
}
return sb.toString().trim();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList("abc", "", "xyz", "argh")));
}
}
@@ -0,0 +1,29 @@
// "Replace with collect" "true"
import java.util.Arrays;
import java.util.List;
public class Test {
static String test(List<String> list) {
StringBuilder sb = new StringBuilder();
boolean first = true;
if (!list.isEmpty()) {
sb.append("{")
for (String s : li<caret>st) {
if (!s.isEmpty()) {
if (first) {
sb.append(s.length());
first = false;
} else {
sb.append('"').append(s.length());
}
}
}
}
return sb.toString().trim();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList("abc", "", "xyz", "argh")));
}
}
@@ -0,0 +1,26 @@
// "Replace with collect" "true"
import java.util.Arrays;
import java.util.List;
public class Test {
static String test(List<String> list) {
char CONST_DELIMITER = '"';
StringBuilder sb = new StringBuilder();
if (!list.isEmpty()) {
for (String s : li<caret>st) {
if (!s.isEmpty()) {
if (sb.length() > 0) {
sb.append(CONST_DELIMITER);
}
sb.append(s.length());
}
}
}
return sb.toString().trim();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList("abc", "", "xyz", "argh")));
}
}
@@ -0,0 +1,23 @@
// "Replace with collect" "true"
import java.util.Arrays;
import java.util.List;
public class Test {
static String test(List<String> list) {
StringBuilder sb = new StringBuilder();
for<caret> (String s : list) {
if (!s.isEmpty()) {
sb.append(s.length()).append('"');
}
}
if (sb.length() > 0) {
sb.setLength(sb.length() - 1);
}
return sb.toString().trim();
}
public static void main(String[] args) {
System.out.println(test(Arrays.asList("abc", "", "xyz", "argh")));
}
}
@@ -0,0 +1,18 @@
// "Replace with collect" "true"
import java.util.List;
public class Test {
private static String work2(List<String> strs) {
StringBuilder sb = new StringBuilder();
String separator = "";
sb.append("{");
for <caret> (String str : strs) {
sb.append(separator);
sb.append(str);
separator = ",";
}
sb.append("}");
return sb.toString();
}
}
@@ -0,0 +1,18 @@
// "Replace with collect" "false"
import java.util.List;
public class Test {
private static String work2(List<String> strs) {
StringBuilder sb = new StringBuilder();
String separator = "!!!!";
sb.append("{");
for <caret> (String str : strs) {
sb.append(separator);
sb.append(str);
separator = ",";
}
sb.append("}");
return sb.toString();
}
}
@@ -0,0 +1,16 @@
// "Replace with collect" "true"
import java.util.List;
public class Test {
static String test(List<String> list) {
final StringBuilder sb = new StringBuilder("ctor");
sb.append("first")
for(String s : li<caret>st) {
if(!s.isEmpty()) {
sb.append(s.trim());
}
}
return sb.length() == 0 ? null : sb.toString();
}
}
@@ -7,7 +7,7 @@ public class Test {
StringBuilder sb = new StringBuilder("[");
for (String s : li<caret>st) {
if (!s.isEmpty()) {
if(sb.length() > 0) sb.append(',');
if(sb.length() > 1) sb.append(',');
sb.append(s);
}
}
@@ -0,0 +1,17 @@
// "Replace with collect" "true"
import java.util.List;
public class Test {
public void test(List<String> list) {
StringBuilder sb = new StringBuilder();
for (int <caret>i=0; i<Math.min(10, list.size()); i++) {
if(i == 0) {
sb.append(list.get(i);
} else {
sb.append(",").append(list.get(i));
}
}
System.out.println(sb.toString());
}
}
@@ -0,0 +1,14 @@
// "Replace with collect" "true"
import java.util.List;
public class Test {
public void test(List<String> list) {
StringBuilder sb = new StringBuilder();
sb.append(list.get(0));
for (int <caret>i=1; i<Math.min(10, list.size()); i++) {
sb.append(",").append(list.get(i));
}
System.out.println(sb.toString());
}
}
@@ -0,0 +1,15 @@
// "Replace with collect" "true"
import java.util.List;
public class Test {
public void test(List<String> list) {
StringBuilder sb = new StringBuilder();
sb.append("prefix");
sb.append(list.get(0));
for (int <caret>i=1; i<Math.min(10, list.size()); i++) {
sb.append(",").append(list.get(i));
}
System.out.println(sb.toString());
}
}
@@ -0,0 +1,14 @@
// "Replace with collect" "true"
import java.util.List;
public class Test {
public void test(List<String> list) {
StringBuilder sb = new StringBuilder();
for (int <caret>i=0; i<Math.min(10, list.size()); i++) {
if(i != 0) sb.append(",");
sb.append(list.get(i));
}
System.out.println(sb.toString());
}
}
@@ -0,0 +1,17 @@
// "Replace with collect" "true"
import java.util.List;
public class Test {
public void test(List<String> list) {
StringBuilder sb = new StringBuilder();
for (int <caret>i=0; i<Math.min(10, list.size()); i++) {
if(i != 0) {
sb.append(",").append(list.get(i));
} else {
sb.append(list.get(i));
}
}
System.out.println(sb.toString());
}
}
@@ -0,0 +1,18 @@
// "Replace with collect" "false"
import java.util.List;
public class Test {
static String test(List<String> list) {
StringBuilder sb = new StringBuilder();
System.out.println("hello");
Runnable r = () -> {
for(String s : li<caret>st) {
if(!s.isEmpty()) {
sb.append(s.trim());
}
}
}
return sb.length() == 0 ? null : sb.toString();
}
}
@@ -0,0 +1,16 @@
// "Replace with collect" "false"
import java.util.List;
public class Test {
public static void test(List<String> list) {
StringBuilder sb = new StringBuilder();
if(!list.isEmpty()) {
for<caret> (String s : list) {
sb.append(s);
}
}
Runnable r = () -> System.out.println(sb.toString());
r.run();
}
}
@@ -0,0 +1,16 @@
// "Replace with collect" "true"
import java.util.List;
public class Test {
static String test(List<String> list) {
StringBuilder sb = new StringBuilder();
System.out.println("hello");
for(String s : li<caret>st) {
if(!s.isEmpty()) {
sb.append(s.trim()).append("foo" + 3).append(5 + 6);
}
}
return sb.length() == 0 ? null : sb.toString();
}
}
@@ -0,0 +1,14 @@
// "Replace with collect" "true"
import java.util.List;
public class Test {
static String test(List<String> list) {
StringBuilder sb = new StringBuilder();
boolean first = true;
for(String s : li<caret>st) {
sb.append(", ").append(s.trim());
}
return sb.length() == 0 ? null : sb.toString();
}
}
@@ -0,0 +1,13 @@
// "Replace with collect" "true"
import java.util.List;
public class Test {
static String test(List<String> list) {
int BUFLENGTH = 42;
StringBuffer sb = new StringBuffer(BUFLENGTH);
for<caret> (int i = 0; i < BUFLENGTH >> 1; i++) {
sb.append(true? "a" : "b");
}
}
}
@@ -157,6 +157,14 @@ public class StreamApiMigrationInspectionTest {
}
}
public static class JoiningTest extends StreamApiMigrationInspectionBaseTest {
@Override
String getFolder() {
return "joining";
}
}
public static class LimitTest extends StreamApiMigrationInspectionBaseTest {
@Override
String getFolder() {
@@ -80,6 +80,7 @@ public class ObjectUtils {
}
@Contract("null, _ -> null")
@Nullable
public static <T> T tryCast(@Nullable Object obj, @NotNull Class<T> clazz) {
if (clazz.isInstance(obj)) {
return clazz.cast(obj);
@@ -397,6 +397,16 @@ public class ControlFlowUtils {
}
}
@NotNull
public static PsiStatement[] unwrapBlock(@Nullable PsiStatement statement) {
PsiBlockStatement block = ObjectUtils.tryCast(statement, PsiBlockStatement.class);
if (block != null) {
return block.getCodeBlock().getStatements();
}
return statement == null ? PsiStatement.EMPTY_ARRAY : new PsiStatement[]{statement};
}
public static boolean statementCompletesWithStatement(@NotNull PsiStatement containingStatement, @NotNull PsiStatement statement) {
PsiElement statementToCheck = statement;
while (true) {
@@ -1004,6 +1004,14 @@ public class ExpressionUtils {
return expression;
}
@Contract(value = "null -> null")
@Nullable
public static PsiLocalVariable resolveLocalVariable(@Nullable PsiExpression expression) {
PsiReferenceExpression referenceExpression = ObjectUtils.tryCast(expression, PsiReferenceExpression.class);
if(referenceExpression == null) return null;
return ObjectUtils.tryCast(referenceExpression.resolve(), PsiLocalVariable.class);
}
public static boolean isOctalLiteral(PsiLiteralExpression literal) {
final PsiType type = literal.getType();
if (!PsiType.INT.equals(type) && !PsiType.LONG.equals(type)) {