mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
StringRepeatCanBeUsedInspection: use dataflow after Math.max replacement is performed to cover more cases
This commit is contained in:
+12
-16
@@ -4,7 +4,6 @@ package com.intellij.codeInspection;
|
||||
import com.intellij.codeInsight.ExpressionUtil;
|
||||
import com.intellij.codeInsight.Nullability;
|
||||
import com.intellij.codeInspection.dataFlow.CommonDataflow;
|
||||
import com.intellij.codeInspection.dataFlow.DfaFactType;
|
||||
import com.intellij.codeInspection.dataFlow.NullabilityUtil;
|
||||
import com.intellij.codeInspection.dataFlow.rangeSet.LongRangeSet;
|
||||
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
|
||||
@@ -105,12 +104,22 @@ public class StringRepeatCanBeUsedInspection extends AbstractBaseJavaLocalInspec
|
||||
CommentTracker ct = new CommentTracker();
|
||||
String repeatQualifier = getRepeatQualifier(arg, ct);
|
||||
String countText = getCountText(from, to, loop.isIncluding(), ct);
|
||||
if (myAddMathMax && canBeNegative(from, to)) {
|
||||
if (myAddMathMax) {
|
||||
countText = CommonClassNames.JAVA_LANG_MATH + ".max(0," + countText + ")";
|
||||
}
|
||||
String replacement = repeatQualifier + ".repeat(" + countText + ")";
|
||||
ct.replace(arg, replacement);
|
||||
ct.replaceAndRestoreComments(statement, call.getParent());
|
||||
PsiExpressionStatement result = (PsiExpressionStatement)ct.replaceAndRestoreComments(statement, call.getParent());
|
||||
if (myAddMathMax) {
|
||||
PsiMethodCallExpression appendCall = (PsiMethodCallExpression)result.getExpression();
|
||||
PsiMethodCallExpression repeatCall = (PsiMethodCallExpression)appendCall.getArgumentList().getExpressions()[0];
|
||||
PsiMethodCallExpression maxCall = (PsiMethodCallExpression)repeatCall.getArgumentList().getExpressions()[0];
|
||||
PsiExpression count = maxCall.getArgumentList().getExpressions()[1];
|
||||
LongRangeSet range = CommonDataflow.getExpressionRange(count);
|
||||
if (range != null && !range.isEmpty() && range.min() >= 0) {
|
||||
maxCall.replace(count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -137,19 +146,6 @@ public class StringRepeatCanBeUsedInspection extends AbstractBaseJavaLocalInspec
|
||||
return countText;
|
||||
}
|
||||
|
||||
private static boolean canBeNegative(PsiExpression from, PsiExpression to) {
|
||||
boolean canBeNegative = true;
|
||||
CommonDataflow.DataflowResult dataflow = CommonDataflow.getDataflowResult(from);
|
||||
if (dataflow != null) {
|
||||
LongRangeSet fromRange = dataflow.getExpressionFact(from, DfaFactType.RANGE);
|
||||
LongRangeSet toRange = dataflow.getExpressionFact(to, DfaFactType.RANGE);
|
||||
if (fromRange != null && !fromRange.isEmpty() && toRange != null && !toRange.isEmpty() && fromRange.max() <= toRange.min()) {
|
||||
canBeNegative = false;
|
||||
}
|
||||
}
|
||||
return canBeNegative;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getRepeatQualifier(PsiExpression arg, CommentTracker ct) {
|
||||
if (arg instanceof PsiLiteralExpression && !TypeUtils.isJavaLangString(arg.getType())) {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Replace with 'String.repeat()'" "true"
|
||||
class Test {
|
||||
String testRepeat(String s, StringBuilder sb, int digits) {
|
||||
if ((s.length() < digits) && (sb.length() > 0)) {
|
||||
sb.append("0".repeat(digits - s.length()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// "Replace with 'String.repeat()'" "true"
|
||||
class Test {
|
||||
public int pendingSpaces;
|
||||
|
||||
String testRepeat(StringBuilder buffer) {
|
||||
if (pendingSpaces > 0) {
|
||||
buffer.append(" ".repeat(pendingSpaces));
|
||||
pendingSpaces = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Replace with 'String.repeat()'" "true"
|
||||
class Test {
|
||||
String testRepeat(String s, StringBuilder sb, int digits) {
|
||||
if ((s.length() < digits) && (sb.length() > 0)) {
|
||||
f<caret>or (int i=s.length(); i < digits; i++) {
|
||||
sb.append('0');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// "Replace with 'String.repeat()'" "true"
|
||||
class Test {
|
||||
public int pendingSpaces;
|
||||
|
||||
String testRepeat(StringBuilder buffer) {
|
||||
if (pendingSpaces > 0) {
|
||||
fo<caret>r (int sp = 0; sp < pendingSpaces; sp++)
|
||||
buffer.append(' ');
|
||||
pendingSpaces = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-10
@@ -4,26 +4,22 @@ package com.intellij.java.codeInspection;
|
||||
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.StringRepeatCanBeUsedInspection;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class StringRepeatCanBeUsedInspectionTest extends LightQuickFixParameterizedTestCase {
|
||||
@Override
|
||||
protected LanguageLevel getDefaultLanguageLevel() {
|
||||
return LanguageLevel.JDK_11;
|
||||
}
|
||||
import static com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase.JAVA_11;
|
||||
|
||||
public class StringRepeatCanBeUsedInspectionTest extends LightQuickFixParameterizedTestCase {
|
||||
@NotNull
|
||||
@Override
|
||||
protected LocalInspectionTool[] configureLocalInspectionTools() {
|
||||
return new LocalInspectionTool[]{new StringRepeatCanBeUsedInspection()};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Sdk getProjectJDK() {
|
||||
return IdeaTestUtil.getMockJdk9();
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return JAVA_11;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user