mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-182623 Replace with collect swallows comments
This commit is contained in:
+17
-32
@@ -17,7 +17,7 @@ package com.intellij.codeInspection.streamMigration;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import com.siyeh.ig.psiutils.ControlFlowUtils;
|
||||
import com.siyeh.ig.psiutils.ControlFlowUtils.InitializerUsageStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -53,74 +53,59 @@ abstract class BaseStreamApiMigration {
|
||||
PsiVariable var,
|
||||
String streamText,
|
||||
PsiType expressionType,
|
||||
OperationReductionMigration.ReductionOperation reductionOperation) {
|
||||
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(loopStatement.getProject());
|
||||
restoreComments(loopStatement, loopStatement instanceof PsiLoopStatement? ((PsiLoopStatement)loopStatement).getBody(): loopStatement);
|
||||
OperationReductionMigration.ReductionOperation reductionOperation,
|
||||
CommentTracker ct) {
|
||||
InitializerUsageStatus status = ControlFlowUtils.getInitializerUsageStatus(var, loopStatement);
|
||||
if (status != InitializerUsageStatus.UNKNOWN) {
|
||||
PsiExpression initializer = var.getInitializer();
|
||||
if (initializer != null && reductionOperation.getInitializerExpressionRestriction().test(initializer)) {
|
||||
PsiType type = var.getType();
|
||||
String replacement = (type.isAssignableFrom(expressionType) ? "" : "(" + type.getCanonicalText() + ") ") + streamText;
|
||||
return replaceInitializer(loopStatement, var, initializer, replacement, status);
|
||||
return replaceInitializer(loopStatement, var, initializer, replacement, status, ct);
|
||||
}
|
||||
}
|
||||
return loopStatement
|
||||
.replace(elementFactory.createStatementFromText(var.getName() + reductionOperation.getOperation() + "=" + streamText + ";",
|
||||
loopStatement));
|
||||
return ct.replaceAndRestoreComments(loopStatement, var.getName() + reductionOperation.getOperation() + "=" + streamText + ";");
|
||||
}
|
||||
|
||||
static PsiElement replaceInitializer(PsiStatement loopStatement,
|
||||
PsiVariable var,
|
||||
PsiExpression initializer,
|
||||
String replacement,
|
||||
InitializerUsageStatus status) {
|
||||
Project project = loopStatement.getProject();
|
||||
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
InitializerUsageStatus status,
|
||||
CommentTracker ct) {
|
||||
if (status == ControlFlowUtils.InitializerUsageStatus.DECLARED_JUST_BEFORE) {
|
||||
initializer.replace(elementFactory.createExpressionFromText(replacement, loopStatement));
|
||||
removeLoop(loopStatement);
|
||||
ct.replace(initializer, replacement);
|
||||
removeLoop(ct, loopStatement);
|
||||
return var;
|
||||
}
|
||||
else {
|
||||
if (status == ControlFlowUtils.InitializerUsageStatus.AT_WANTED_PLACE_ONLY) {
|
||||
initializer.delete();
|
||||
ct.delete(initializer);
|
||||
}
|
||||
return
|
||||
loopStatement.replace(elementFactory.createStatementFromText(var.getName() + " = " + replacement + ";", loopStatement));
|
||||
return ct.replaceAndRestoreComments(loopStatement, var.getName() + " = " + replacement + ";");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
static PsiElement replaceWithFindExtremum(@NotNull PsiStatement loopStatement,
|
||||
static PsiElement replaceWithFindExtremum(@NotNull CommentTracker ct, @NotNull PsiStatement loopStatement,
|
||||
@NotNull PsiVariable extremumHolder,
|
||||
@NotNull String streamText,
|
||||
@Nullable PsiVariable keyExtremum) {
|
||||
restoreComments(loopStatement, loopStatement instanceof PsiLoopStatement? ((PsiLoopStatement)loopStatement).getBody(): loopStatement);
|
||||
if(keyExtremum != null) {
|
||||
keyExtremum.delete();
|
||||
ct.delete(keyExtremum);
|
||||
}
|
||||
InitializerUsageStatus status = ControlFlowUtils.getInitializerUsageStatus(extremumHolder, loopStatement);
|
||||
return replaceInitializer(loopStatement, extremumHolder, extremumHolder.getInitializer(), streamText, status);
|
||||
return replaceInitializer(loopStatement, extremumHolder, extremumHolder.getInitializer(), streamText, status, ct);
|
||||
}
|
||||
|
||||
static void restoreComments(PsiStatement statement, PsiElement body) {
|
||||
if(statement instanceof PsiLoopStatement || statement instanceof PsiExpressionStatement) {
|
||||
final PsiElement parent = statement.getParent();
|
||||
for (PsiElement comment : PsiTreeUtil.findChildrenOfType(body, PsiComment.class)) {
|
||||
parent.addBefore(comment, statement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void removeLoop(@NotNull PsiStatement statement) {
|
||||
static void removeLoop(CommentTracker ct, @NotNull PsiStatement statement) {
|
||||
PsiElement parent = statement.getParent();
|
||||
if (parent instanceof PsiLabeledStatement) {
|
||||
parent.delete();
|
||||
ct.deleteAndRestoreComments(parent);
|
||||
}
|
||||
else {
|
||||
statement.delete();
|
||||
ct.deleteAndRestoreComments(statement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+38
-39
@@ -79,21 +79,20 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
@Override
|
||||
PsiElement migrate(@NotNull Project project, @NotNull PsiElement body, @NotNull TerminalBlock tb) {
|
||||
PsiStatement loopStatement = tb.getStreamSourceStatement();
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
CollectTerminal terminal = extractCollectTerminal(tb, null);
|
||||
if (terminal == null) return null;
|
||||
String stream = tb.generate() + terminal.generateIntermediate() + terminal.generateTerminal();
|
||||
CommentTracker ct = new CommentTracker();
|
||||
String stream = tb.generate(ct) + terminal.generateIntermediate(ct) + terminal.generateTerminal(ct);
|
||||
PsiElement toReplace = terminal.getElementToReplace();
|
||||
restoreComments(loopStatement, body);
|
||||
PsiElement result;
|
||||
if (toReplace != null) {
|
||||
result = toReplace.replace(factory.createExpressionFromText(stream, toReplace));
|
||||
removeLoop(loopStatement);
|
||||
result = ct.replace(toReplace, stream);
|
||||
removeLoop(ct, loopStatement);
|
||||
}
|
||||
else {
|
||||
PsiVariable variable = terminal.getTargetVariable();
|
||||
LOG.assertTrue(variable != null);
|
||||
result = replaceInitializer(loopStatement, variable, variable.getInitializer(), stream, terminal.getStatus());
|
||||
result = replaceInitializer(loopStatement, variable, variable.getInitializer(), stream, terminal.getStatus(), ct);
|
||||
}
|
||||
terminal.cleanUp();
|
||||
return result;
|
||||
@@ -193,7 +192,7 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
@Nullable
|
||||
PsiLocalVariable getTargetVariable() { return myTargetVariable; }
|
||||
|
||||
abstract String generateIntermediate();
|
||||
abstract String generateIntermediate(CommentTracker ct);
|
||||
|
||||
StreamEx<? extends PsiExpression> targetReferences() {
|
||||
List<PsiElement> usedElements = usedElements().toList();
|
||||
@@ -215,7 +214,7 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
return INTERMEDIATE_STEPS.get(aClass.getQualifiedName());
|
||||
}
|
||||
|
||||
abstract String generateTerminal();
|
||||
abstract String generateTerminal(CommentTracker ct);
|
||||
|
||||
StreamEx<PsiElement> usedElements() {
|
||||
return StreamEx.ofNullable(myLoop);
|
||||
@@ -230,7 +229,7 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
void cleanUp() {}
|
||||
|
||||
boolean isTrivial() {
|
||||
return generateIntermediate().isEmpty();
|
||||
return generateIntermediate(new CommentTracker()).isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,20 +271,20 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateIntermediate() {
|
||||
public String generateIntermediate(CommentTracker ct) {
|
||||
PsiType addedType = getAddedElementType(myAddCall);
|
||||
PsiExpression mapping = getMapping();
|
||||
if (addedType == null) addedType = mapping.getType();
|
||||
return StreamRefactoringUtil.generateMapOperation(myElement, addedType, mapping);
|
||||
return StreamRefactoringUtil.generateMapOperation(myElement, addedType, ct.markUnchanged(mapping));
|
||||
}
|
||||
|
||||
public String generateCollector() {
|
||||
return getCollectionCollector(myInitializer, myTargetType);
|
||||
public String generateCollector(CommentTracker ct) {
|
||||
return getCollectionCollector(ct.markUnchanged(myInitializer), myTargetType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTerminal() {
|
||||
return ".collect(" + generateCollector() + ")";
|
||||
public String generateTerminal(CommentTracker ct) {
|
||||
return ".collect(" + generateCollector(ct) + ")";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -361,7 +360,7 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateIntermediate() {
|
||||
public String generateIntermediate(CommentTracker ct) {
|
||||
PsiType[] typeParameters = myAddAllCall.getMethodExpression().getTypeParameters();
|
||||
String generic = "";
|
||||
if(typeParameters.length == 1) {
|
||||
@@ -370,7 +369,7 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
String method = MethodCallUtils.isVarArgCall(myAddAllCall) ? CommonClassNames.JAVA_UTIL_STREAM_STREAM + "." + generic + "of"
|
||||
: CommonClassNames.JAVA_UTIL_ARRAYS + "." + generic + "stream";
|
||||
String lambda = myElement.getName() + "->" + method + "(" +
|
||||
StreamEx.of(myAddAllCall.getArgumentList().getExpressions()).skip(1).map(PsiExpression::getText).joining(",") + ")";
|
||||
StreamEx.of(myAddAllCall.getArgumentList().getExpressions()).skip(1).map(ct::text).joining(",") + ")";
|
||||
return myElement.getType() instanceof PsiPrimitiveType ?
|
||||
".mapToObj(" + lambda + ").flatMap("+ CommonClassNames.JAVA_UTIL_FUNCTION_FUNCTION+".identity())" :
|
||||
".flatMap(" + lambda + ")";
|
||||
@@ -416,27 +415,27 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
}
|
||||
|
||||
@Override
|
||||
String generateIntermediate() {
|
||||
String generateIntermediate(CommentTracker ct) {
|
||||
return myDownstream.myElement.getType() instanceof PsiPrimitiveType ? ".boxed()" : "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTerminal() {
|
||||
String downstreamCollector = myDownstream.generateCollector();
|
||||
public String generateTerminal(CommentTracker ct) {
|
||||
String downstreamCollector = myDownstream.generateCollector(ct);
|
||||
PsiVariable elementVariable = myDownstream.getElementVariable();
|
||||
if (!ExpressionUtils.isReferenceTo(myDownstream.getMapping(), myDownstream.getElementVariable())) {
|
||||
downstreamCollector = CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS + ".mapping(" +
|
||||
myDownstream.getElementVariable().getName() + "->" + myDownstream.getMapping().getText() + "," +
|
||||
myDownstream.getElementVariable().getName() + "->" + ct.text(myDownstream.getMapping()) + "," +
|
||||
downstreamCollector + ")";
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(".collect(" + CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS + ".groupingBy(")
|
||||
.append(LambdaUtil.createLambda(elementVariable, myKeyExpression));
|
||||
.append(ct.lambdaText(elementVariable, myKeyExpression));
|
||||
PsiLocalVariable variable = Objects.requireNonNull(getTargetVariable());
|
||||
PsiExpression initializer = variable.getInitializer();
|
||||
LOG.assertTrue(initializer != null);
|
||||
if (!isHashMap(variable)) {
|
||||
builder.append(",()->").append(initializer.getText()).append(",").append(downstreamCollector);
|
||||
builder.append(",()->").append(ct.text(initializer)).append(",").append(downstreamCollector);
|
||||
}
|
||||
else if (!(CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS + "." + "toList()").equals(downstreamCollector)) {
|
||||
builder.append(",").append(downstreamCollector);
|
||||
@@ -592,12 +591,12 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
}
|
||||
|
||||
@Override
|
||||
String generateIntermediate() {
|
||||
String generateIntermediate(CommentTracker ct) {
|
||||
return myElementVariable.getType() instanceof PsiPrimitiveType ? ".boxed()" : "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTerminal() {
|
||||
public String generateTerminal(CommentTracker ct) {
|
||||
PsiExpression[] args = myMapUpdateCall.getArgumentList().getExpressions();
|
||||
LOG.assertTrue(args.length >= 2);
|
||||
String methodName = myMapUpdateCall.getMethodExpression().getReferenceName();
|
||||
@@ -616,20 +615,20 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
break;
|
||||
case "merge":
|
||||
LOG.assertTrue(args.length == 3);
|
||||
merger = args[2].getText();
|
||||
merger = ct.text(args[2]);
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
StringBuilder collector = new StringBuilder(".collect(" + CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS + ".toMap(");
|
||||
collector.append(LambdaUtil.createLambda(myElementVariable, args[0])).append(',')
|
||||
.append(LambdaUtil.createLambda(myElementVariable, args[1])).append(',')
|
||||
collector.append(ct.lambdaText(myElementVariable, args[0])).append(',')
|
||||
.append(ct.lambdaText(myElementVariable, args[1])).append(',')
|
||||
.append(merger);
|
||||
PsiLocalVariable variable = Objects.requireNonNull(getTargetVariable());
|
||||
PsiExpression initializer = variable.getInitializer();
|
||||
LOG.assertTrue(initializer != null);
|
||||
if (!isHashMap(variable)) {
|
||||
collector.append(",()->").append(initializer.getText());
|
||||
collector.append(",()->").append(ct.text(initializer));
|
||||
}
|
||||
collector.append("))");
|
||||
return collector.toString();
|
||||
@@ -665,14 +664,14 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateIntermediate() {
|
||||
return myDownstream.generateIntermediate() + ".sorted("
|
||||
+ (myComparator == null ? "" : myComparator.getText()) + ")";
|
||||
public String generateIntermediate(CommentTracker ct) {
|
||||
return myDownstream.generateIntermediate(ct) + ".sorted("
|
||||
+ (myComparator == null ? "" : ct.text(myComparator)) + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTerminal() {
|
||||
return myDownstream.generateTerminal();
|
||||
public String generateTerminal(CommentTracker ct) {
|
||||
return myDownstream.generateTerminal(ct);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -760,8 +759,8 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateIntermediate() {
|
||||
return myUpstream.generateIntermediate() + myIntermediate;
|
||||
public String generateIntermediate(CommentTracker ct) {
|
||||
return myUpstream.generateIntermediate(ct) + myIntermediate;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -792,7 +791,7 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTerminal() {
|
||||
public String generateTerminal(CommentTracker ct) {
|
||||
return ".toArray(" + mySupplier + ")";
|
||||
}
|
||||
|
||||
@@ -865,8 +864,8 @@ class CollectMigration extends BaseStreamApiMigration {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateTerminal() {
|
||||
return ".collect(" + getCollectionCollector(myCreateExpression, myResultType) + ")";
|
||||
public String generateTerminal(CommentTracker ct) {
|
||||
return ".collect(" + getCollectionCollector(ct.markUnchanged(myCreateExpression), myResultType) + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.codeInspection.streamMigration;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.codeInspection.streamMigration.OperationReductionMigration.SUM_OPERATION;
|
||||
@@ -41,6 +42,7 @@ class CountMigration extends BaseStreamApiMigration {
|
||||
PsiElement element = ((PsiReferenceExpression)operand).resolve();
|
||||
if (!(element instanceof PsiLocalVariable)) return null;
|
||||
PsiLocalVariable var = (PsiLocalVariable)element;
|
||||
return replaceWithOperation(tb.getStreamSourceStatement(), var, tb.generate() + ".count()", PsiType.LONG, SUM_OPERATION);
|
||||
CommentTracker ct = new CommentTracker();
|
||||
return replaceWithOperation(tb.getStreamSourceStatement(), var, tb.generate(ct) + ".count()", PsiType.LONG, SUM_OPERATION, ct);
|
||||
}
|
||||
}
|
||||
|
||||
+15
-16
@@ -22,10 +22,7 @@ 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.siyeh.ig.psiutils.ControlFlowUtils;
|
||||
import com.siyeh.ig.psiutils.EquivalenceChecker;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import com.siyeh.ig.psiutils.VariableAccessUtils;
|
||||
import com.siyeh.ig.psiutils.*;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -288,13 +285,14 @@ class FindExtremumMigration extends BaseStreamApiMigration {
|
||||
String inFilterOperation = myMax ? ">=" : "<=";
|
||||
PsiStatement loop = myTerminalBlock.getStreamSourceStatement();
|
||||
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(loop.getProject());
|
||||
String extremumInitializer = myExtremumKeyInitializer.getText();
|
||||
CommentTracker ct = new CommentTracker();
|
||||
String extremumInitializer = ct.text(myExtremumKeyInitializer);
|
||||
PsiExpression condition =
|
||||
elementFactory.createExpressionFromText(myExtremumKeyExpr.getText() + inFilterOperation + extremumInitializer, loop);
|
||||
elementFactory.createExpressionFromText(ct.text(myExtremumKeyExpr) + inFilterOperation + extremumInitializer, loop);
|
||||
TerminalBlock blockWithFilter =
|
||||
myTerminalBlock.add(new StreamApiMigrationInspection.FilterOp(condition, myTerminalBlock.getVariable(), false));
|
||||
|
||||
String lambdaText = LambdaUtil.createLambda(myTerminalBlock.getVariable(), myExtremumKeyExpr);
|
||||
String lambdaText = ct.lambdaText(myTerminalBlock.getVariable(), myExtremumKeyExpr);
|
||||
String comparator;
|
||||
if(myComparator == null) {
|
||||
comparator = CommonClassNames.JAVA_UTIL_COMPARATOR + "." + method + "(" + lambdaText + ")";
|
||||
@@ -303,8 +301,8 @@ class FindExtremumMigration extends BaseStreamApiMigration {
|
||||
if(comparatorName == null) return null;
|
||||
comparator = comparatorName;
|
||||
}
|
||||
String stream = blockWithFilter.generate() + "." + getOperation(myMax) + "(" + comparator + ").orElse(null)";
|
||||
return replaceWithFindExtremum(myTerminalBlock.getStreamSourceStatement(), myExtremum, stream, myExtremumKey);
|
||||
String stream = blockWithFilter.generate(ct) + "." + getOperation(myMax) + "(" + comparator + ").orElse(null)";
|
||||
return replaceWithFindExtremum(ct, myTerminalBlock.getStreamSourceStatement(), myExtremum, stream, myExtremumKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -472,10 +470,11 @@ class FindExtremumMigration extends BaseStreamApiMigration {
|
||||
} else {
|
||||
terminalBlock = blockWithMap;
|
||||
}
|
||||
CommentTracker ct = new CommentTracker();
|
||||
String inFilterOperation = myMax ? ">=" : "<=";
|
||||
PsiStatement loop = terminalBlock.getStreamSourceStatement();
|
||||
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(loop.getProject());
|
||||
String extremumInitializer = myExtremumInitializer.getText();
|
||||
String extremumInitializer = ct.text(myExtremumInitializer);
|
||||
Object nonFilterableInitialValue = getNonFilterableInitialValue(type, myMax);
|
||||
final TerminalBlock filteredTerminalBlock;
|
||||
if (nonFilterableInitialValue != null && !nonFilterableInitialValue.equals(initializerValue)) {
|
||||
@@ -488,9 +487,8 @@ class FindExtremumMigration extends BaseStreamApiMigration {
|
||||
filteredTerminalBlock = terminalBlock;
|
||||
}
|
||||
|
||||
|
||||
String stream = filteredTerminalBlock.generate() + "." + getOperation(myMax) + "().orElse(" + extremumInitializer + ")";
|
||||
return replaceWithFindExtremum(loop, myExtremum, stream, null);
|
||||
String stream = filteredTerminalBlock.generate(ct) + "." + getOperation(myMax) + "().orElse(" + extremumInitializer + ")";
|
||||
return replaceWithFindExtremum(ct, loop, myExtremum, stream, null);
|
||||
}
|
||||
|
||||
|
||||
@@ -558,13 +556,14 @@ class FindExtremumMigration extends BaseStreamApiMigration {
|
||||
PsiType loopVarExpressionType = myLoopVarExpression.getType();
|
||||
if (loopVarExpressionType == null) return null;
|
||||
final String comparator;
|
||||
CommentTracker ct = new CommentTracker();
|
||||
if(myComparator == null) {
|
||||
if(ExpressionUtils.isReferenceTo(myLoopVarExpression, myTerminalBlock.getVariable())) {
|
||||
comparator = CommonClassNames.JAVA_UTIL_COMPARATOR + ".naturalOrder()";
|
||||
} else {
|
||||
String method = getComparingMethod(loopVarExpressionType);
|
||||
if (method == null) return null;
|
||||
String lambdaText = LambdaUtil.createLambda(myTerminalBlock.getVariable(), myLoopVarExpression);
|
||||
String lambdaText = ct.lambdaText(myTerminalBlock.getVariable(), myLoopVarExpression);
|
||||
comparator = CommonClassNames.JAVA_UTIL_COMPARATOR + "." + method + "(" + lambdaText + ")";
|
||||
}
|
||||
} else {
|
||||
@@ -572,8 +571,8 @@ class FindExtremumMigration extends BaseStreamApiMigration {
|
||||
if(comparatorName == null) return null;
|
||||
comparator = comparatorName;
|
||||
}
|
||||
String stream = myTerminalBlock.generate() + "." + getOperation(myMax) + "(" + comparator + ").orElse(null)";
|
||||
return replaceWithFindExtremum(myTerminalBlock.getStreamSourceStatement(), myExtremum, stream, null);
|
||||
String stream = myTerminalBlock.generate(ct) + "." + getOperation(myMax) + "(" + comparator + ").orElse(null)";
|
||||
return replaceWithFindExtremum(ct, myTerminalBlock.getStreamSourceStatement(), myExtremum, stream, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+14
-15
@@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import com.siyeh.ig.psiutils.ControlFlowUtils;
|
||||
import com.siyeh.ig.psiutils.ControlFlowUtils.InitializerUsageStatus;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
@@ -36,8 +37,8 @@ class FindFirstMigration extends BaseStreamApiMigration {
|
||||
@Override
|
||||
PsiElement migrate(@NotNull Project project, @NotNull PsiElement body, @NotNull TerminalBlock tb) {
|
||||
PsiStatement statement = tb.getSingleStatement();
|
||||
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
PsiStatement loopStatement = tb.getStreamSourceStatement();
|
||||
CommentTracker ct = new CommentTracker();
|
||||
if (statement instanceof PsiReturnStatement) {
|
||||
PsiReturnStatement returnStatement = (PsiReturnStatement)statement;
|
||||
PsiExpression value = returnStatement.getReturnValue();
|
||||
@@ -46,12 +47,11 @@ class FindFirstMigration extends BaseStreamApiMigration {
|
||||
if (nextReturnStatement == null) return null;
|
||||
PsiExpression orElseExpression = nextReturnStatement.getReturnValue();
|
||||
if (!ExpressionUtils.isSimpleExpression(orElseExpression)) return null;
|
||||
String stream = generateOptionalUnwrap(tb, value, orElseExpression, PsiTypesUtil.getMethodReturnType(returnStatement));
|
||||
restoreComments(loopStatement, body);
|
||||
String stream = generateOptionalUnwrap(ct, tb, value, orElseExpression, PsiTypesUtil.getMethodReturnType(returnStatement));
|
||||
boolean sibling = nextReturnStatement.getParent() == loopStatement.getParent();
|
||||
PsiElement replacement = loopStatement.replace(elementFactory.createStatementFromText("return " + stream + ";", loopStatement));
|
||||
PsiElement replacement = ct.replaceAndRestoreComments(loopStatement, "return " + stream + ";");
|
||||
if(sibling || !ControlFlowUtils.isReachable(nextReturnStatement)) {
|
||||
nextReturnStatement.delete();
|
||||
new CommentTracker().deleteAndRestoreComments(nextReturnStatement);
|
||||
}
|
||||
return replacement;
|
||||
}
|
||||
@@ -62,9 +62,8 @@ class FindFirstMigration extends BaseStreamApiMigration {
|
||||
if (assignment == null) {
|
||||
if(!(statements[0] instanceof PsiExpressionStatement)) return null;
|
||||
PsiExpression expression = ((PsiExpressionStatement)statements[0]).getExpression();
|
||||
restoreComments(loopStatement, body);
|
||||
return loopStatement.replace(elementFactory.createStatementFromText(
|
||||
tb.generate() + ".findFirst().ifPresent(" + LambdaUtil.createLambda(tb.getVariable(), expression) + ");", loopStatement));
|
||||
return ct.replaceAndRestoreComments(
|
||||
loopStatement, tb.generate(ct) + ".findFirst().ifPresent(" + ct.lambdaText(tb.getVariable(), expression) + ");");
|
||||
}
|
||||
PsiReferenceExpression lValue = tryCast(assignment.getLExpression(), PsiReferenceExpression.class);
|
||||
if (lValue == null) return null;
|
||||
@@ -72,7 +71,6 @@ class FindFirstMigration extends BaseStreamApiMigration {
|
||||
if (var == null) return null;
|
||||
PsiExpression value = assignment.getRExpression();
|
||||
if (value == null) return null;
|
||||
restoreComments(loopStatement, body);
|
||||
InitializerUsageStatus status = ControlFlowUtils.getInitializerUsageStatus(var, loopStatement);
|
||||
PsiExpression initializer = var.getInitializer();
|
||||
PsiExpression falseExpression = lValue;
|
||||
@@ -83,19 +81,20 @@ class FindFirstMigration extends BaseStreamApiMigration {
|
||||
PsiElement maybeAssignment = PsiTreeUtil.skipWhitespacesAndCommentsBackward(loopStatement);
|
||||
PsiExpression prevRValue = ExpressionUtils.getAssignmentTo(maybeAssignment, var);
|
||||
if (prevRValue != null) {
|
||||
maybeAssignment.delete();
|
||||
ct.delete(maybeAssignment);
|
||||
falseExpression = prevRValue;
|
||||
}
|
||||
}
|
||||
String replacementText = generateOptionalUnwrap(tb, value, falseExpression, var.getType());
|
||||
return replaceInitializer(loopStatement, var, initializer, replacementText, status);
|
||||
String replacementText = generateOptionalUnwrap(ct, tb, value, falseExpression, var.getType());
|
||||
return replaceInitializer(loopStatement, var, initializer, replacementText, status, ct);
|
||||
}
|
||||
}
|
||||
|
||||
private static String generateOptionalUnwrap(TerminalBlock tb,
|
||||
private static String generateOptionalUnwrap(CommentTracker ct, TerminalBlock tb,
|
||||
PsiExpression trueExpression, PsiExpression falseExpression,
|
||||
PsiType targetType) {
|
||||
String qualifier = tb.generate() + ".findFirst()";
|
||||
return OptionalUtil.generateOptionalUnwrap(qualifier, tb.getVariable(), trueExpression, falseExpression, targetType, false);
|
||||
String qualifier = tb.generate(ct) + ".findFirst()";
|
||||
return OptionalUtil.generateOptionalUnwrap(
|
||||
qualifier, tb.getVariable(), ct.markUnchanged(trueExpression), ct.markUnchanged(falseExpression), targetType, false);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-9
@@ -22,6 +22,7 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.SuggestedNameInfo;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import com.siyeh.ig.psiutils.VariableAccessUtils;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
@@ -59,7 +60,7 @@ class ForEachMigration extends BaseStreamApiMigration {
|
||||
@Override
|
||||
PsiElement migrate(@NotNull Project project, @NotNull PsiElement body, @NotNull TerminalBlock tb) {
|
||||
PsiStatement loopStatement = tb.getStreamSourceStatement();
|
||||
restoreComments(loopStatement, body);
|
||||
CommentTracker ct = new CommentTracker();
|
||||
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
|
||||
@@ -78,21 +79,20 @@ class ForEachMigration extends BaseStreamApiMigration {
|
||||
}
|
||||
String varName = codeStyleManager.suggestUniqueVariableName(suggestedNameInfo, call, false).names[0];
|
||||
|
||||
String streamText = tb.add(new StreamApiMigrationInspection.MapOp(mapExpression, tb.getVariable(), addedType)).generate();
|
||||
String forEachBody = varName + "->" + call.getMethodExpression().getText() + "(" + varName + ")";
|
||||
String streamText = tb.add(new StreamApiMigrationInspection.MapOp(mapExpression, tb.getVariable(), addedType)).generate(ct);
|
||||
String forEachBody = varName + "->" + ct.text(call.getMethodExpression()) + "(" + varName + ")";
|
||||
String callText = streamText + "." + getReplacement() + "(" + forEachBody + ");";
|
||||
return loopStatement.replace(factory.createStatementFromText(callText, loopStatement));
|
||||
return ct.replaceAndRestoreComments(loopStatement, callText);
|
||||
}
|
||||
|
||||
tb.replaceContinueWithReturn(factory);
|
||||
|
||||
String stream = tb.generate(true) + "." + getReplacement() + "(";
|
||||
PsiElement block = tb.convertToElement(factory);
|
||||
String stream = tb.generate(ct, true) + "." + getReplacement() + "(";
|
||||
PsiElement block = tb.convertToElement(ct, factory);
|
||||
|
||||
final String functionalExpressionText = tb.getVariable().getName() + " -> " + wrapInBlock(block);
|
||||
PsiExpressionStatement callStatement = (PsiExpressionStatement)factory
|
||||
.createStatementFromText(stream + functionalExpressionText + ");", loopStatement);
|
||||
callStatement = (PsiExpressionStatement)loopStatement.replace(callStatement);
|
||||
PsiExpressionStatement callStatement =
|
||||
(PsiExpressionStatement)ct.replaceAndRestoreComments(loopStatement, stream + functionalExpressionText + ");");
|
||||
|
||||
final PsiExpressionList argumentList = ((PsiCallExpression)callStatement.getExpression()).getArgumentList();
|
||||
LOG.assertTrue(argumentList != null, callStatement.getText());
|
||||
|
||||
+9
-8
@@ -10,6 +10,7 @@ import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.siyeh.ig.callMatcher.CallMatcher;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import com.siyeh.ig.psiutils.ControlFlowUtils;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
@@ -42,14 +43,14 @@ public class FuseStreamOperationsInspection extends AbstractBaseJavaLocalInspect
|
||||
}
|
||||
|
||||
@Override
|
||||
String generateIntermediate() {
|
||||
String generateIntermediate(CommentTracker ct) {
|
||||
PsiExpression qualifier = myChain.getMethodExpression().getQualifierExpression();
|
||||
return Objects.requireNonNull(qualifier).getText();
|
||||
return ct.text(Objects.requireNonNull(qualifier));
|
||||
}
|
||||
|
||||
@Override
|
||||
String generateTerminal() {
|
||||
return ".collect(" + myCollector.getText() + ")";
|
||||
String generateTerminal(CommentTracker ct) {
|
||||
return ".collect(" + ct.text(myCollector) + ")";
|
||||
}
|
||||
|
||||
private static PsiClass resolveClassCreatedByFunction(PsiExpression function) {
|
||||
@@ -184,19 +185,19 @@ public class FuseStreamOperationsInspection extends AbstractBaseJavaLocalInspect
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PsiMethodCallExpression chain = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiMethodCallExpression.class);
|
||||
if (chain == null) return;
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
CollectTerminal terminal = extractTerminal(chain);
|
||||
if (terminal == null) return;
|
||||
String stream = terminal.generateIntermediate() + terminal.generateTerminal();
|
||||
CommentTracker ct = new CommentTracker();
|
||||
String stream = terminal.generateIntermediate(ct) + terminal.generateTerminal(ct);
|
||||
PsiElement toReplace = terminal.getElementToReplace();
|
||||
PsiElement result;
|
||||
if (toReplace != null) {
|
||||
result = toReplace.replace(factory.createExpressionFromText(stream, toReplace));
|
||||
result = ct.replaceAndRestoreComments(toReplace, stream);
|
||||
}
|
||||
else {
|
||||
PsiVariable variable = Objects.requireNonNull(terminal.getTargetVariable());
|
||||
PsiExpression initializer = Objects.requireNonNull(variable.getInitializer());
|
||||
result = initializer.replace(factory.createExpressionFromText(stream, initializer));
|
||||
result = ct.replaceAndRestoreComments(initializer, stream);
|
||||
}
|
||||
terminal.cleanUp();
|
||||
LambdaCanBeMethodReferenceInspection.replaceAllLambdasWithMethodReferences(result);
|
||||
|
||||
+45
-42
@@ -61,13 +61,13 @@ public class JoiningMigration extends BaseStreamApiMigration {
|
||||
|
||||
TerminalBlock block = terminal.getTerminalBlock();
|
||||
PsiStatement loopStatement = block.getStreamSourceStatement();
|
||||
String stream = terminal.generateStreamCode();
|
||||
restoreComments(loopStatement, body);
|
||||
CommentTracker ct = new CommentTracker();
|
||||
String stream = terminal.generateStreamCode(ct);
|
||||
PsiVariable builder = terminal.getBuilder();
|
||||
terminal.preCleanUp();
|
||||
terminal.preCleanUp(ct);
|
||||
ControlFlowUtils.InitializerUsageStatus status = getInitializerUsageStatus(builder, loopStatement);
|
||||
if(builder instanceof PsiLocalVariable) {
|
||||
PsiElement result = replaceInitializer(loopStatement, builder, builder.getInitializer(), stream, status);
|
||||
PsiElement result = replaceInitializer(loopStatement, builder, builder.getInitializer(), stream, status, ct);
|
||||
terminal.cleanUp((PsiLocalVariable)builder);
|
||||
JoiningTerminal.replaceUsages((PsiLocalVariable)terminal.getBuilder());
|
||||
return result;
|
||||
@@ -157,14 +157,14 @@ public class JoiningMigration extends BaseStreamApiMigration {
|
||||
replaceUsages(target);
|
||||
}
|
||||
|
||||
void preCleanUp() {
|
||||
cleanUpCall(myBeforeLoopAppend);
|
||||
cleanUpCall(myAfterLoopAppend);
|
||||
void preCleanUp(CommentTracker ct) {
|
||||
cleanUpCall(ct, myBeforeLoopAppend);
|
||||
cleanUpCall(ct, myAfterLoopAppend);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
String generateStreamCode() {
|
||||
return myTerminalBlock.generate() + generateIntermediate() + generateTerminal();
|
||||
String generateStreamCode(CommentTracker ct) {
|
||||
return myTerminalBlock.generate(ct) + generateIntermediate(ct) + generateTerminal(ct);
|
||||
}
|
||||
|
||||
private static void replaceInitializer(@NotNull PsiLocalVariable target) {
|
||||
@@ -195,33 +195,33 @@ public class JoiningMigration extends BaseStreamApiMigration {
|
||||
FinalUtils.canBeFinal(variable);
|
||||
}
|
||||
|
||||
String generateTerminal() {
|
||||
String generateTerminal(CommentTracker ct) {
|
||||
final String collectArguments;
|
||||
if (myDelimiterJoinParts.isEmpty() && myPrefixJoinParts.isEmpty() && mySuffixJoinParts.isEmpty()) {
|
||||
collectArguments = "";
|
||||
}
|
||||
else {
|
||||
String delimiter = myDelimiterJoinParts.isEmpty() ? "\"\"" : getExpressionText(myDelimiterJoinParts);
|
||||
String delimiter = myDelimiterJoinParts.isEmpty() ? "\"\"" : getExpressionText(ct, myDelimiterJoinParts);
|
||||
if (mySuffixJoinParts.isEmpty() && myPrefixJoinParts.isEmpty()) {
|
||||
collectArguments = delimiter;
|
||||
}
|
||||
else {
|
||||
String suffix = mySuffixJoinParts.isEmpty() ? "\"\"" : getExpressionText(mySuffixJoinParts);
|
||||
String prefix = myPrefixJoinParts.isEmpty() ? "\"\"" : getExpressionText(myPrefixJoinParts);
|
||||
String suffix = mySuffixJoinParts.isEmpty() ? "\"\"" : getExpressionText(ct, mySuffixJoinParts);
|
||||
String prefix = myPrefixJoinParts.isEmpty() ? "\"\"" : getExpressionText(ct, myPrefixJoinParts);
|
||||
collectArguments = delimiter + "," + prefix + "," + suffix;
|
||||
}
|
||||
}
|
||||
return ".collect(" + CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS + ".joining(" + collectArguments + "))";
|
||||
}
|
||||
|
||||
String generateIntermediate() {
|
||||
String generateIntermediate(CommentTracker ct) {
|
||||
if (TypeUtils.isJavaLangString(myLoopVariable.getType()) &&
|
||||
myMainJoinParts.size() == 1 &&
|
||||
myMainJoinParts.get(0) instanceof PsiReferenceExpression) {
|
||||
return "";
|
||||
}
|
||||
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myLoopVariable.getProject());
|
||||
String joinTransformation = getExpressionText(myMainJoinParts);
|
||||
String joinTransformation = getExpressionText(ct, myMainJoinParts);
|
||||
PsiExpression mapping = elementFactory.createExpressionFromText(joinTransformation, myLoopVariable);
|
||||
return StreamRefactoringUtil.generateMapOperation(myLoopVariable, null, mapping);
|
||||
}
|
||||
@@ -240,23 +240,23 @@ public class JoiningMigration extends BaseStreamApiMigration {
|
||||
}
|
||||
}
|
||||
|
||||
private static void cleanUpCall(PsiMethodCallExpression call) {
|
||||
private static void cleanUpCall(CommentTracker ct, PsiMethodCallExpression call) {
|
||||
if (call != null) {
|
||||
if (call.getParent() instanceof PsiExpressionStatement) {
|
||||
call.delete();
|
||||
ct.delete(call);
|
||||
}
|
||||
else {
|
||||
PsiMethodCallExpression nextCall = ExpressionUtils.getCallForQualifier(call);
|
||||
PsiExpression qualifier = call.getMethodExpression().getQualifierExpression();
|
||||
if (nextCall != null && qualifier != null) {
|
||||
nextCall.replace(qualifier);
|
||||
ct.replace(nextCall, ct.markUnchanged(qualifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String getExpressionText(@NotNull List<PsiExpression> joinParts) {
|
||||
private static String getExpressionText(CommentTracker ct, @NotNull List<PsiExpression> joinParts) {
|
||||
StringJoiner joiner = new StringJoiner("+");
|
||||
int size = joinParts.size();
|
||||
for (int i = 0; i < joinParts.size(); i++) {
|
||||
@@ -270,10 +270,10 @@ public class JoiningMigration extends BaseStreamApiMigration {
|
||||
neighborIsString = true;
|
||||
}
|
||||
}
|
||||
partText = expressionToCharSequence(joinPart, size, neighborIsString);
|
||||
partText = expressionToCharSequence(ct, joinPart, size, neighborIsString);
|
||||
}
|
||||
else {
|
||||
partText = expressionToCharSequence(joinPart, size, true);
|
||||
partText = expressionToCharSequence(ct, joinPart, size, true);
|
||||
}
|
||||
joiner.add(partText);
|
||||
}
|
||||
@@ -310,7 +310,10 @@ public class JoiningMigration extends BaseStreamApiMigration {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String expressionToCharSequence(@NotNull PsiExpression expression, int expressionCount, boolean neighborIsString) {
|
||||
private static String expressionToCharSequence(CommentTracker ct,
|
||||
@NotNull PsiExpression expression,
|
||||
int expressionCount,
|
||||
boolean neighborIsString) {
|
||||
PsiType type = expression.getType();
|
||||
if(expression instanceof PsiMethodCallExpression) {
|
||||
PsiMethodCallExpression callExpression = (PsiMethodCallExpression)expression;
|
||||
@@ -324,7 +327,7 @@ public class JoiningMigration extends BaseStreamApiMigration {
|
||||
Object constantExpression = ExpressionUtils.computeConstantExpression(first);
|
||||
if(constantExpression instanceof Integer) {
|
||||
String endIndex = String.valueOf((int)constantExpression + 1);
|
||||
return qualifierExpression.getText() + ".substring(" + first.getText() + "," + endIndex + ")";
|
||||
return ct.text(qualifierExpression) + ".substring(" + ct.text(first) + "," + endIndex + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -336,22 +339,22 @@ public class JoiningMigration extends BaseStreamApiMigration {
|
||||
if (literalExpression != null) {
|
||||
Object value = literalExpression.getValue();
|
||||
if (value instanceof Character) {
|
||||
String text = literalExpression.getText();
|
||||
String text = ct.text(literalExpression);
|
||||
if ("'\"'".equals(text)) return "\"\\\"\"";
|
||||
return "\"" + text.substring(1, text.length() - 1) + "\"";
|
||||
}
|
||||
}
|
||||
return CommonClassNames.JAVA_LANG_STRING + ".valueOf(" + expression.getText() + ")";
|
||||
return CommonClassNames.JAVA_LANG_STRING + ".valueOf(" + ct.text(expression) + ")";
|
||||
}
|
||||
if (ParenthesesUtils.getPrecedence(expression) > ParenthesesUtils.ADDITIVE_PRECEDENCE ||
|
||||
(expression.getType() instanceof PsiPrimitiveType &&
|
||||
ParenthesesUtils.getPrecedence(expression) == ParenthesesUtils.ADDITIVE_PRECEDENCE) ||
|
||||
expressionCount == 1) {
|
||||
return "(" + expression.getText() + ")";
|
||||
return "(" + ct.text(expression) + ")";
|
||||
}
|
||||
return expression.getText();
|
||||
return ct.text(expression);
|
||||
}
|
||||
String expressionText = expression.getText();
|
||||
String expressionText = ct.text(expression);
|
||||
if(ParenthesesUtils.getPrecedence(expression) > ParenthesesUtils.ADDITIVE_PRECEDENCE && expressionCount > 1) {
|
||||
expressionText = "(" + expressionText + ")";
|
||||
}
|
||||
@@ -860,9 +863,9 @@ List<PsiExpression> builderStrInitializers = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
void preCleanUp() {
|
||||
super.preCleanUp();
|
||||
myBoolVariable.delete();
|
||||
void preCleanUp(CommentTracker ct) {
|
||||
super.preCleanUp(ct);
|
||||
ct.delete(myBoolVariable);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -919,9 +922,9 @@ List<PsiExpression> builderStrInitializers = null;
|
||||
myTruncateIfStatement = truncateIfStatement;
|
||||
}
|
||||
|
||||
void preCleanUp() {
|
||||
super.preCleanUp();
|
||||
myTruncateIfStatement.delete();
|
||||
void preCleanUp(CommentTracker ct) {
|
||||
super.preCleanUp(ct);
|
||||
ct.delete(myTruncateIfStatement);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1032,9 +1035,9 @@ List<PsiExpression> builderStrInitializers = null;
|
||||
myDelimiterVariable = delimiterVariable;
|
||||
}
|
||||
|
||||
void preCleanUp() {
|
||||
super.preCleanUp();
|
||||
myDelimiterVariable.delete();
|
||||
void preCleanUp(CommentTracker ct) {
|
||||
super.preCleanUp(ct);
|
||||
ct.delete(myDelimiterVariable);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1182,9 +1185,9 @@ List<PsiExpression> builderStrInitializers = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
void preCleanUp() {
|
||||
super.preCleanUp();
|
||||
myBeforeLoopAppend.delete();
|
||||
void preCleanUp(CommentTracker ct) {
|
||||
super.preCleanUp(ct);
|
||||
ct.delete(myBeforeLoopAppend);
|
||||
}
|
||||
|
||||
private static List<PsiExpression> copyReplacingVar(@NotNull List<PsiExpression> joinParts,
|
||||
@@ -1201,8 +1204,8 @@ List<PsiExpression> builderStrInitializers = null;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
String generateStreamCode() {
|
||||
return mySource.createReplacement() + generateIntermediate() + generateTerminal();
|
||||
String generateStreamCode(CommentTracker ct) {
|
||||
return mySource.createReplacement(ct) + generateIntermediate(ct) + generateTerminal(ct);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+21
-22
@@ -18,11 +18,8 @@ package com.intellij.codeInspection.streamMigration;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.ig.psiutils.BoolUtils;
|
||||
import com.siyeh.ig.psiutils.ControlFlowUtils;
|
||||
import com.siyeh.ig.psiutils.*;
|
||||
import com.siyeh.ig.psiutils.ControlFlowUtils.InitializerUsageStatus;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -38,7 +35,7 @@ class MatchMigration extends BaseStreamApiMigration {
|
||||
@Override
|
||||
PsiElement migrate(@NotNull Project project, @NotNull PsiElement body, @NotNull TerminalBlock tb) {
|
||||
PsiStatement sourceStatement = tb.getStreamSourceStatement();
|
||||
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
CommentTracker ct = new CommentTracker();
|
||||
if(tb.getSingleStatement() instanceof PsiReturnStatement) {
|
||||
PsiReturnStatement returnStatement = (PsiReturnStatement)tb.getSingleStatement();
|
||||
PsiExpression value = returnStatement.getReturnValue();
|
||||
@@ -49,30 +46,29 @@ class MatchMigration extends BaseStreamApiMigration {
|
||||
PsiExpression returnValue = nextReturnStatement.getReturnValue();
|
||||
if(returnValue == null) return null;
|
||||
String methodName = foundResult ? "anyMatch" : "noneMatch";
|
||||
String streamText = addTerminalOperation(methodName, sourceStatement, tb);
|
||||
restoreComments(sourceStatement, body);
|
||||
String streamText = addTerminalOperation(ct, methodName, sourceStatement, tb);
|
||||
if (nextReturnStatement.getParent() == sourceStatement.getParent()) {
|
||||
if(!ExpressionUtils.isLiteral(returnValue, !foundResult)) {
|
||||
streamText+= (foundResult ? "||" : "&&") + ParenthesesUtils.getText(returnValue, ParenthesesUtils.AND_PRECEDENCE);
|
||||
streamText += (foundResult ? "||" : "&&") + ct.text(returnValue, ParenthesesUtils.BINARY_OR_PRECEDENCE);
|
||||
}
|
||||
removeLoop(sourceStatement);
|
||||
return returnValue.replace(elementFactory.createExpressionFromText(streamText, nextReturnStatement));
|
||||
removeLoop(ct, sourceStatement);
|
||||
return new CommentTracker().replaceAndRestoreComments(returnValue, streamText);
|
||||
}
|
||||
PsiElement result = sourceStatement.replace(elementFactory.createStatementFromText("return " + streamText + ";", sourceStatement));
|
||||
PsiElement result = ct.replaceAndRestoreComments(sourceStatement, "return " + streamText + ";");
|
||||
if(!ControlFlowUtils.isReachable(nextReturnStatement)) {
|
||||
nextReturnStatement.delete();
|
||||
new CommentTracker().deleteAndRestoreComments(nextReturnStatement);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
PsiStatement[] statements = tb.getStatements();
|
||||
if (!(statements.length == 1 || (sourceStatement instanceof PsiLoopStatement && statements.length == 2 && ControlFlowUtils.statementBreaksLoop(statements[1],
|
||||
(PsiLoopStatement)sourceStatement)))) {
|
||||
if (!(statements.length == 1 ||
|
||||
(sourceStatement instanceof PsiLoopStatement && statements.length == 2 &&
|
||||
ControlFlowUtils.statementBreaksLoop(statements[1], (PsiLoopStatement)sourceStatement)))) {
|
||||
return null;
|
||||
}
|
||||
restoreComments(sourceStatement, body);
|
||||
String streamText = addTerminalOperation("anyMatch", sourceStatement, tb);
|
||||
String streamText = addTerminalOperation(ct, "anyMatch", sourceStatement, tb);
|
||||
PsiStatement statement = statements[0];
|
||||
PsiAssignmentExpression assignment = ExpressionUtils.getAssignment(statement);
|
||||
if(assignment != null) {
|
||||
@@ -98,19 +94,22 @@ class MatchMigration extends BaseStreamApiMigration {
|
||||
replacement = "!" + streamText;
|
||||
}
|
||||
else {
|
||||
replacement = streamText + "?" + rValue.getText() + ":" + initializer.getText();
|
||||
replacement = streamText + "?" + ct.text(rValue) + ":" + ct.text(initializer);
|
||||
}
|
||||
return replaceInitializer(sourceStatement, var, initializer, replacement, status);
|
||||
return replaceInitializer(sourceStatement, var, initializer, replacement, status, ct);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
String replacement = "if(" + streamText + "){" + statement.getText() + "}";
|
||||
return sourceStatement.replace(elementFactory.createStatementFromText(replacement, sourceStatement));
|
||||
String replacement = "if(" + streamText + "){" + ct.text(statement) + "}";
|
||||
return ct.replaceAndRestoreComments(sourceStatement, replacement);
|
||||
}
|
||||
|
||||
private static String addTerminalOperation(String methodName, @NotNull PsiElement contextElement, @NotNull TerminalBlock tb) {
|
||||
String origStream = tb.generate();
|
||||
private static String addTerminalOperation(CommentTracker ct,
|
||||
String methodName,
|
||||
@NotNull PsiElement contextElement,
|
||||
@NotNull TerminalBlock tb) {
|
||||
String origStream = tb.generate(ct);
|
||||
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(contextElement.getProject());
|
||||
PsiExpression stream = elementFactory.createExpressionFromText(origStream, contextElement);
|
||||
LOG.assertTrue(stream instanceof PsiMethodCallExpression);
|
||||
|
||||
+6
-4
@@ -20,6 +20,7 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -46,6 +47,7 @@ public class OperationReductionMigration extends BaseStreamApiMigration {
|
||||
PsiVariable var = StreamApiMigrationInspection.extractAccumulator(assignment, myReductionOperation.getCompoundAssignmentOp());
|
||||
if (var == null) return null;
|
||||
|
||||
CommentTracker ct = new CommentTracker();
|
||||
PsiExpression operand = StreamApiMigrationInspection.extractOperand(assignment, myReductionOperation.getCompoundAssignmentOp());
|
||||
if (operand == null) return null;
|
||||
PsiType type = var.getType();
|
||||
@@ -53,7 +55,7 @@ public class OperationReductionMigration extends BaseStreamApiMigration {
|
||||
PsiType operandType = operand.getType();
|
||||
if (operandType != null && !TypeConversionUtil.isAssignable(type, operandType)) {
|
||||
operand = JavaPsiFacade.getElementFactory(project).createExpressionFromText(
|
||||
"(" + type.getCanonicalText() + ")" + ParenthesesUtils.getText(operand, ParenthesesUtils.MULTIPLICATIVE_PRECEDENCE), operand);
|
||||
"(" + type.getCanonicalText() + ")" + ct.text(operand, ParenthesesUtils.TYPE_CAST_PRECEDENCE), operand);
|
||||
}
|
||||
JavaCodeStyleManager javaStyle = JavaCodeStyleManager.getInstance(project);
|
||||
String leftOperand = javaStyle.suggestUniqueVariableName("a", body, true);
|
||||
@@ -65,13 +67,13 @@ public class OperationReductionMigration extends BaseStreamApiMigration {
|
||||
|
||||
PsiExpression initializer = var.getInitializer();
|
||||
String identity = initializer != null && myReductionOperation.getInitializerExpressionRestriction().test(initializer)
|
||||
? initializer.getText()
|
||||
? ct.text(initializer)
|
||||
: myReductionOperation.getIdentity();
|
||||
String stream = tb.add(new StreamApiMigrationInspection.MapOp(operand, tb.getVariable(), type)).generate()
|
||||
String stream = tb.add(new StreamApiMigrationInspection.MapOp(operand, tb.getVariable(), type)).generate(ct)
|
||||
+ String.format(Locale.ENGLISH, ".reduce(%s, (%s, %s) -> %s %s %s)",
|
||||
identity, leftOperand, rightOperand, leftOperand,
|
||||
myReductionOperation.getOperation(), rightOperand);
|
||||
return replaceWithOperation(tb.getStreamSourceStatement(), var, stream, type, myReductionOperation);
|
||||
return replaceWithOperation(tb.getStreamSourceStatement(), var, stream, type, myReductionOperation, ct);
|
||||
}
|
||||
|
||||
static class ReductionOperation {
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.siyeh.ig.callMatcher.CallMatcher;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -137,7 +138,7 @@ public class SimplifyForEachInspection extends AbstractBaseJavaLocalInspectionTo
|
||||
}
|
||||
|
||||
@Override
|
||||
String createReplacement() {
|
||||
String createReplacement(CommentTracker ct) {
|
||||
return myExpression.getText() + (myIsCollectionForEach? ".stream()" : "");
|
||||
}
|
||||
|
||||
|
||||
+35
-35
@@ -665,7 +665,7 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
return StreamEx.ofNullable(myExpression);
|
||||
}
|
||||
|
||||
abstract String createReplacement();
|
||||
abstract String createReplacement(CommentTracker ct);
|
||||
|
||||
boolean isWriteAllowed(PsiVariable variable, PsiExpression reference) {
|
||||
return false;
|
||||
@@ -689,11 +689,11 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createReplacement() {
|
||||
public String createReplacement(CommentTracker ct) {
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(myExpression.getProject());
|
||||
PsiExpression intermediate = makeIntermediateExpression(factory);
|
||||
PsiExpression intermediate = makeIntermediateExpression(ct, factory);
|
||||
PsiExpression expression =
|
||||
myNegated ? factory.createExpressionFromText(BoolUtils.getNegatedExpressionText(intermediate), myExpression) : intermediate;
|
||||
myNegated ? factory.createExpressionFromText(BoolUtils.getNegatedExpressionText(intermediate, ct), myExpression) : intermediate;
|
||||
return "." + getOpName() + "(" + LambdaUtil.createLambda(myVariable, expression) + ")";
|
||||
}
|
||||
|
||||
@@ -702,8 +702,8 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
return "filter";
|
||||
}
|
||||
|
||||
PsiExpression makeIntermediateExpression(PsiElementFactory factory) {
|
||||
return myExpression;
|
||||
PsiExpression makeIntermediateExpression(CommentTracker ct, PsiElementFactory factory) {
|
||||
return ct.markUnchanged(myExpression);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -731,9 +731,9 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
|
||||
|
||||
@Override
|
||||
PsiExpression makeIntermediateExpression(PsiElementFactory factory) {
|
||||
return factory.createExpressionFromText(mySource.createReplacement() + ".anyMatch(" +
|
||||
LambdaUtil.createLambda(myMatchVariable, myExpression) + ")", myExpression);
|
||||
PsiExpression makeIntermediateExpression(CommentTracker ct, PsiElementFactory factory) {
|
||||
return factory.createExpressionFromText(mySource.createReplacement(ct) + ".anyMatch(" +
|
||||
ct.lambdaText(myMatchVariable, myExpression) + ")", myExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -756,8 +756,8 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createReplacement() {
|
||||
return StreamRefactoringUtil.generateMapOperation(myVariable, myType, myExpression);
|
||||
public String createReplacement(CommentTracker ct) {
|
||||
return StreamRefactoringUtil.generateMapOperation(myVariable, myType, ct.markUnchanged(myExpression));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -775,11 +775,11 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createReplacement() {
|
||||
public String createReplacement(CommentTracker ct) {
|
||||
String operation = "flatMap";
|
||||
PsiType inType = myVariable.getType();
|
||||
PsiType outType = mySource.getVariable().getType();
|
||||
String lambda = myVariable.getName() + " -> " + getStreamExpression();
|
||||
String lambda = myVariable.getName() + " -> " + getStreamExpression(ct);
|
||||
if (outType instanceof PsiPrimitiveType && !outType.equals(inType)) {
|
||||
if (outType.equals(PsiType.INT)) {
|
||||
operation = "flatMapToInt";
|
||||
@@ -802,8 +802,8 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
}
|
||||
|
||||
@NotNull
|
||||
String getStreamExpression() {
|
||||
return mySource.createReplacement();
|
||||
String getStreamExpression(CommentTracker ct) {
|
||||
return mySource.createReplacement(ct);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -839,8 +839,8 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
}
|
||||
|
||||
@Override
|
||||
String createReplacement() {
|
||||
return ".limit(" + getLimitExpression() + ")";
|
||||
String createReplacement(CommentTracker ct) {
|
||||
return ".limit(" + getLimitExpression(ct) + ")";
|
||||
}
|
||||
|
||||
PsiLocalVariable getCounterVariable() {
|
||||
@@ -863,9 +863,9 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
return variable == myCounterVariable && PsiTreeUtil.isAncestor(myCounter, reference, false);
|
||||
}
|
||||
|
||||
private String getLimitExpression() {
|
||||
private String getLimitExpression(CommentTracker ct) {
|
||||
if (myDelta == 0) {
|
||||
return myExpression.getText();
|
||||
return ct.text(myExpression);
|
||||
}
|
||||
if (myExpression instanceof PsiLiteralExpression) {
|
||||
Object value = ((PsiLiteralExpression)myExpression).getValue();
|
||||
@@ -873,7 +873,7 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
return String.valueOf(((Number)value).longValue() + myDelta);
|
||||
}
|
||||
}
|
||||
return ParenthesesUtils.getText(myExpression, ParenthesesUtils.ADDITIVE_PRECEDENCE) + "+" + myDelta;
|
||||
return ct.text(myExpression, ParenthesesUtils.ADDITIVE_PRECEDENCE) + "+" + myDelta;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -883,7 +883,7 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
}
|
||||
|
||||
@Override
|
||||
String createReplacement() {
|
||||
String createReplacement(CommentTracker ct) {
|
||||
return ".distinct()";
|
||||
}
|
||||
}
|
||||
@@ -930,8 +930,8 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
}
|
||||
|
||||
@Override
|
||||
String createReplacement() {
|
||||
return myExpression.getText() + ".lines()";
|
||||
String createReplacement(CommentTracker ct) {
|
||||
return ct.text(myExpression) + ".lines()";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1068,13 +1068,13 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
}
|
||||
|
||||
@Override
|
||||
String createReplacement() {
|
||||
String createReplacement(CommentTracker ct) {
|
||||
if (myExpression instanceof PsiNewExpression) {
|
||||
PsiArrayInitializerExpression initializer = ((PsiNewExpression)myExpression).getArrayInitializer();
|
||||
if (initializer != null) {
|
||||
PsiElement[] children = initializer.getChildren();
|
||||
if (children.length > 2) {
|
||||
String initializerText = StreamEx.of(children, 1, children.length - 1).map(PsiElement::getText).joining();
|
||||
String initializerText = StreamEx.of(children, 1, children.length - 1).map(ct::text).joining();
|
||||
PsiType type = myExpression.getType();
|
||||
if (type instanceof PsiArrayType) {
|
||||
PsiType componentType = ((PsiArrayType)type).getComponentType();
|
||||
@@ -1094,7 +1094,7 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
}
|
||||
}
|
||||
}
|
||||
return CommonClassNames.JAVA_UTIL_ARRAYS + ".stream(" + myExpression.getText() + ")";
|
||||
return CommonClassNames.JAVA_UTIL_ARRAYS + ".stream(" + ct.text(myExpression) + ")";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1120,8 +1120,8 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
}
|
||||
|
||||
@Override
|
||||
String createReplacement() {
|
||||
return ParenthesesUtils.getText(myExpression, ParenthesesUtils.POSTFIX_PRECEDENCE) + ".stream()" + tryUnbox(myVariable);
|
||||
String createReplacement(CommentTracker ct) {
|
||||
return ct.text(myExpression, ParenthesesUtils.METHOD_CALL_PRECEDENCE) + ".stream()" + tryUnbox(myVariable);
|
||||
}
|
||||
|
||||
@Contract("null, _ -> false")
|
||||
@@ -1170,10 +1170,10 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createReplacement() {
|
||||
public String createReplacement(CommentTracker ct) {
|
||||
String className = myVariable.getType().equals(PsiType.LONG) ? "java.util.stream.LongStream" : "java.util.stream.IntStream";
|
||||
String methodName = myIncluding ? "rangeClosed" : "range";
|
||||
return className + "." + methodName + "(" + myExpression.getText() + ", " + myBound.getText() + ")";
|
||||
return className + "." + methodName + "(" + ct.text(myExpression) + ", " + ct.text(myBound) + ")";
|
||||
}
|
||||
|
||||
CountingLoopSource withBound(PsiExpression bound) {
|
||||
@@ -1277,12 +1277,12 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
}
|
||||
|
||||
@Override
|
||||
String createReplacement() {
|
||||
String createReplacement(CommentTracker ct) {
|
||||
String lambda;
|
||||
if (myOpType != null) {
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(myVariable.getProject());
|
||||
PsiExpression expression = myUnaryExpression == null ? myExpression : factory.createExpressionFromText("1", null);
|
||||
String expressionText = ParenthesesUtils.getText(expression, ParenthesesUtils.getPrecedenceForOperator(myOpType));
|
||||
String expressionText = ParenthesesUtils.getText(ct.markUnchanged(expression), ParenthesesUtils.getPrecedenceForOperator(myOpType));
|
||||
String lambdaBody = myVariable.getName() + getOperationSign(myOpType) + expressionText;
|
||||
if (!myVariable.getType().equals(expression.getType())) {
|
||||
lambdaBody = ("(" + myVariable.getType().getCanonicalText() + ")") + "(" + lambdaBody + ")";
|
||||
@@ -1290,11 +1290,11 @@ public class StreamApiMigrationInspection extends AbstractBaseJavaLocalInspectio
|
||||
lambda = myVariable.getName() + "->" + lambdaBody;
|
||||
}
|
||||
else {
|
||||
lambda = LambdaUtil.createLambda(myVariable, myExpression);
|
||||
lambda = ct.lambdaText(myVariable, myExpression);
|
||||
}
|
||||
String maybeCondition = myCondition != null ? LambdaUtil.createLambda(myVariable, myCondition) + "," : "";
|
||||
String maybeCondition = myCondition != null ? ct.lambdaText(myVariable, myCondition) + "," : "";
|
||||
|
||||
return getStreamClass(myVariable.getType()) + ".iterate(" + myInitializer.getText() + "," + maybeCondition + lambda + ")";
|
||||
return getStreamClass(myVariable.getType()) + ".iterate(" + ct.text(myInitializer) + "," + maybeCondition + lambda + ")";
|
||||
}
|
||||
|
||||
@Contract(value = "null -> null", pure = true)
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -46,11 +47,12 @@ class SumMigration extends BaseStreamApiMigration {
|
||||
type = PsiType.INT;
|
||||
}
|
||||
PsiType addendType = addend.getType();
|
||||
CommentTracker ct = new CommentTracker();
|
||||
if(addendType != null && !TypeConversionUtil.isAssignable(type, addendType)) {
|
||||
addend = JavaPsiFacade.getElementFactory(project).createExpressionFromText(
|
||||
"(" + type.getCanonicalText() + ")" + ParenthesesUtils.getText(addend, ParenthesesUtils.MULTIPLICATIVE_PRECEDENCE), addend);
|
||||
"(" + type.getCanonicalText() + ")" + ct.text(addend, ParenthesesUtils.TYPE_CAST_PRECEDENCE), addend);
|
||||
}
|
||||
String stream = tb.add(new MapOp(addend, tb.getVariable(), type)).generate()+".sum()";
|
||||
return replaceWithOperation(tb.getStreamSourceStatement(), var, stream, type, SUM_OPERATION);
|
||||
String stream = tb.add(new MapOp(addend, tb.getVariable(), type)).generate(ct)+".sum()";
|
||||
return replaceWithOperation(tb.getStreamSourceStatement(), var, stream, type, SUM_OPERATION, ct);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,10 @@ import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.*;
|
||||
import static com.intellij.util.ObjectUtils.tryCast;
|
||||
@@ -460,16 +463,17 @@ class TerminalBlock {
|
||||
/**
|
||||
* Converts this TerminalBlock to PsiElement (either PsiStatement or PsiCodeBlock)
|
||||
*
|
||||
* @param ct CommentTracker to mark statements as unchanged
|
||||
* @param factory factory to use to create new element if necessary
|
||||
* @return the PsiElement
|
||||
*/
|
||||
PsiElement convertToElement(PsiElementFactory factory) {
|
||||
PsiElement convertToElement(CommentTracker ct, PsiElementFactory factory) {
|
||||
if (myStatements.length == 1) {
|
||||
return myStatements[0];
|
||||
return ct.markUnchanged(myStatements[0]);
|
||||
}
|
||||
PsiCodeBlock block = factory.createCodeBlock();
|
||||
for (PsiStatement statement : myStatements) {
|
||||
block.add(statement);
|
||||
block.add(ct.markUnchanged(statement));
|
||||
}
|
||||
return block;
|
||||
}
|
||||
@@ -492,15 +496,15 @@ class TerminalBlock {
|
||||
}
|
||||
}
|
||||
|
||||
String generate() {
|
||||
return generate(false);
|
||||
String generate(CommentTracker ct) {
|
||||
return generate(ct, false);
|
||||
}
|
||||
|
||||
String generate(boolean noStreamForEmpty) {
|
||||
String generate(CommentTracker ct, boolean noStreamForEmpty) {
|
||||
if(noStreamForEmpty && myOperations.length == 1 && myOperations[0] instanceof CollectionStream) {
|
||||
return ParenthesesUtils.getText(myOperations[0].getExpression(), ParenthesesUtils.POSTFIX_PRECEDENCE);
|
||||
}
|
||||
return StreamEx.of(myOperations).map(Operation::createReplacement).joining();
|
||||
return StreamEx.of(myOperations).map(operation -> operation.createReplacement(ct)).joining();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+4
-2
@@ -20,6 +20,7 @@ import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import com.siyeh.ig.psiutils.ControlFlowUtils;
|
||||
import com.siyeh.ig.psiutils.ControlFlowUtils.InitializerUsageStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -59,8 +60,9 @@ public class ToArrayMigration extends BaseStreamApiMigration {
|
||||
} else {
|
||||
supplier = arrayType.getCanonicalText()+"::new";
|
||||
}
|
||||
CommentTracker ct = new CommentTracker();
|
||||
MapOp mapping = new MapOp(rValue, tb.getVariable(), assignment.getType());
|
||||
String replacementText = loop.withBound(dimension).createReplacement() + mapping.createReplacement() + ".toArray(" + supplier + ")";
|
||||
return replaceInitializer(tb.getStreamSourceStatement(), arrayVariable, initializer, replacementText, status);
|
||||
String replacementText = loop.withBound(dimension).createReplacement(ct) + mapping.createReplacement(ct) + ".toArray(" + supplier + ")";
|
||||
return replaceInitializer(tb.getStreamSourceStatement(), arrayVariable, initializer, replacementText, status, ct);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -4,6 +4,12 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class Main {
|
||||
public void test(List<Set<String>> nested) {
|
||||
List<String> result = nested.stream().filter(Objects::nonNull).flatMap(Collection::stream).filter(str -> str.startsWith("xyz")).map(String::trim).collect(Collectors.toList());
|
||||
/*non-equal*//*empty*/
|
||||
List<String> result = nested.stream().filter(Objects::nonNull).flatMap(Collection::stream).filter(str -> str./*startswith*/startsWith("xyz")).map(String::trim).collect(Collectors.toList());
|
||||
// 1
|
||||
/*target is here*/
|
||||
// 2
|
||||
// 3
|
||||
// 4
|
||||
}
|
||||
}
|
||||
+8
-8
@@ -6,15 +6,15 @@ import java.util.Set;
|
||||
public class Main {
|
||||
public void test(List<Set<String>> nested) {
|
||||
List<String> result = new ArrayList<>();
|
||||
for (Set<String> element : nes<caret>ted) {
|
||||
if (element != null) {
|
||||
for (Set<String> element : nes<caret>ted) { // 1
|
||||
if (element /*non-equal*/!= null) {
|
||||
for (String str : element) {
|
||||
if (str.startsWith("xyz")) {
|
||||
String target = str.trim();
|
||||
result.add(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (str./*startswith*/startsWith("xyz")) {
|
||||
String target = str.trim(/*empty*/);
|
||||
result.add(/*target is here*/target);
|
||||
} // 2
|
||||
} // 3
|
||||
} // 4
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -6,8 +6,8 @@ import java.util.List;
|
||||
public class Main {
|
||||
public static String find(List<List<String>> list) {
|
||||
/*
|
||||
Block comment
|
||||
*/
|
||||
Block comment
|
||||
*/
|
||||
return list.stream().flatMap(Collection::stream).filter(string -> string.startsWith("ABC")).findFirst().map(string -> string.substring(3)).orElse("");
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -6,8 +6,8 @@ import java.util.List;
|
||||
public class Main {
|
||||
public static boolean find(List<List<String>> list) {
|
||||
/*
|
||||
Block comment
|
||||
*/
|
||||
Block comment
|
||||
*/
|
||||
return list.stream().flatMap(Collection::stream).filter(string -> string.startsWith("ABC")).findFirst().filter(string -> string.substring(3).equals("xyz")).isPresent();
|
||||
}
|
||||
}
|
||||
+1
@@ -8,6 +8,7 @@ import java.util.Optional;
|
||||
public class Main {
|
||||
private static String test(List<String> list) {
|
||||
Optional<String> found = list.stream().filter(Objects::nonNull).findFirst();
|
||||
// optional!
|
||||
return found.orElse(null);
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -4,6 +4,7 @@ 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);
|
||||
/*ten*/
|
||||
return data.stream().filter(str -> str.startsWith("xyz")).mapToInt(String::length).filter(len -> len /*bigger*/ > 10).findFirst().orElse(0);
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -5,10 +5,10 @@ import java.util.Map;
|
||||
|
||||
public class Main {
|
||||
public void testMap(Map<String, List<String>> map) throws Exception {
|
||||
int bigSize = 0;
|
||||
int bigSize = 0; // initial
|
||||
for(List<String> list : map.valu<caret>es()) {
|
||||
int size = list.size();
|
||||
if(size > 10) {
|
||||
int size = list.size(); // size
|
||||
if(size/*bigger*/ > 10) {
|
||||
bigSize = size*2;
|
||||
break;
|
||||
}
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ public class Main {
|
||||
Optional<String> found = Optional.empty();
|
||||
for (String s : li<caret>st) {
|
||||
if (Objects.nonNull(s)) {
|
||||
found = Optional.of(s);
|
||||
found = Optional.of(s); // optional!
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ public class Main {
|
||||
for(String str : dat<caret>a) {
|
||||
if(str.startsWith("xyz")) {
|
||||
int len = str.length();
|
||||
if(len > 10) {
|
||||
if(len /*bigger*/> 10 /*ten*/) {
|
||||
return len;
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -6,6 +6,9 @@ import java.util.stream.Collectors;
|
||||
public class Test {
|
||||
private static String work2(List<String> strs) {
|
||||
String sb = strs.stream().collect(Collectors.joining(",", "{", "}"));
|
||||
// before
|
||||
// after
|
||||
// inside
|
||||
return sb;
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -5,14 +5,14 @@ import java.util.List;
|
||||
public class Test {
|
||||
private static String work2(List<String> strs) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{");
|
||||
sb.append("{"); // before
|
||||
String separator = "";
|
||||
for <caret> (String str : strs) {
|
||||
sb.append(separator);
|
||||
sb.append(separator); // inside
|
||||
sb.append(str);
|
||||
separator = ",";
|
||||
}
|
||||
sb.append("}");
|
||||
sb.append("}"); // after
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -27,7 +27,9 @@ public class Main {
|
||||
new Person("James", 25),
|
||||
new Person("Kelly", 12)
|
||||
);
|
||||
Person maxPerson = personList.stream().filter(p -> p.getAge() > 13).max(Comparator.comparingInt(Person::getAge)).orElse(null);
|
||||
/*age*/
|
||||
Person maxPerson = personList.stream().filter(p -> p.getAge() > /*thirteen*/ 13).max(Comparator.comparingInt(Person::getAge)).orElse(null);
|
||||
// max!
|
||||
|
||||
return maxPerson;
|
||||
}
|
||||
|
||||
+3
-3
@@ -29,9 +29,9 @@ public class Main {
|
||||
);
|
||||
Person maxPerson = null;
|
||||
for <caret>(Person p : personList) {
|
||||
if(p.getAge() > 13) {
|
||||
if (maxPerson == null || p.getAge() > maxPerson.getAge()) {
|
||||
maxPerson = p;
|
||||
if(p.getAge() > /*thirteen*/ 13) {
|
||||
if (maxPerson == null || p./*age*/getAge() > maxPerson.getAge()) {
|
||||
maxPerson = p; // max!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+32
@@ -51,6 +51,35 @@ public class CommentTracker {
|
||||
return element.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the expression as unchanged and returns its text, adding parentheses if necessary.
|
||||
* The unchanged elements are assumed to be preserved in the resulting code as is,
|
||||
* so the comments from them will not be extracted.
|
||||
*
|
||||
* @param element expression to return the text
|
||||
* @param precedence precedence of surrounding operation
|
||||
* @return a text to be inserted into refactored code
|
||||
* @see ParenthesesUtils#getText(PsiExpression, int)
|
||||
*/
|
||||
@NotNull
|
||||
public String text(@NotNull PsiExpression element, int precedence) {
|
||||
checkState();
|
||||
addIgnored(element);
|
||||
return ParenthesesUtils.getText(element, precedence + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the expression as unchanged and returns a single-parameter lambda text which parameter
|
||||
* is the name of supplied variable and body is the supplied expression
|
||||
*
|
||||
* @param variable a variable to use as lambda parameter
|
||||
* @param expression an expression to use as lambda body
|
||||
* @return a string representation of lambda
|
||||
*/
|
||||
public String lambdaText(@NotNull PsiVariable variable, @NotNull PsiExpression expression) {
|
||||
return variable.getName() + " -> " + text(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the element as unchanged and returns it. The unchanged elements are assumed to be preserved
|
||||
* in the resulting code as is, so the comments from them will not be extracted.
|
||||
@@ -71,6 +100,9 @@ public class CommentTracker {
|
||||
* @param element element to delete
|
||||
*/
|
||||
public void delete(@NotNull PsiElement element) {
|
||||
if (element instanceof PsiExpression && element.getParent() instanceof PsiExpressionStatement) {
|
||||
element = element.getParent();
|
||||
}
|
||||
grabComments(element);
|
||||
element.delete();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user