IDEA-230889 'Object allocation in a loop' doesn't detect concatenation of two constant Strings inside the loop

GitOrigin-RevId: 0952486abeb99ba108af82028dce126d01a8fcfa
This commit is contained in:
Tagir Valeev
2020-01-21 04:38:18 +00:00
committed by intellij-monorepo-bot
parent 395ea720e9
commit 87a2b2f6e1
3 changed files with 27 additions and 1 deletions
@@ -1029,6 +1029,7 @@ object.allocation.in.loop.new.descriptor=Object allocation <code>new #ref()</cod
object.allocation.in.loop.problem.call.descriptor=Object allocation via <code>#ref()</code> call in loop #loc
object.allocation.in.loop.problem.methodref.descriptor=Object allocation via instance-bound method reference <code>#ref()</code> in loop #loc
object.allocation.in.loop.problem.lambda.descriptor=Object allocation via capturing lambda in loop #loc
object.allocation.in.loop.problem.string.concat=Object allocation via string concatenation in loop #loc
instantiating.object.to.get.class.object.problem.descriptor=Instantiating object to get Class object #loc
field.may.be.static.problem.descriptor=Field <code>#ref</code> may be 'static' #loc
method.may.be.static.problem.descriptor=Method <code>#ref()</code> may be 'static' #loc
@@ -22,12 +22,15 @@ import com.intellij.codeInspection.dataFlow.JavaMethodContractUtil;
import com.intellij.codeInspection.dataFlow.NullabilityUtil;
import com.intellij.codeInspection.dataFlow.StandardMethodContract;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.ControlFlowUtils;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.PropertyKey;
@@ -40,7 +43,8 @@ public class ObjectAllocationInLoopInspection extends BaseInspection {
NEW_OPERATOR("object.allocation.in.loop.new.descriptor"),
METHOD_CALL("object.allocation.in.loop.problem.call.descriptor"),
METHOD_REFERENCE("object.allocation.in.loop.problem.methodref.descriptor"),
CAPTURING_LAMBDA("object.allocation.in.loop.problem.lambda.descriptor");
CAPTURING_LAMBDA("object.allocation.in.loop.problem.lambda.descriptor"),
STRING_CONCAT("object.allocation.in.loop.problem.string.concat");
private final String myMessage;
@@ -105,6 +109,16 @@ public class ObjectAllocationInLoopInspection extends BaseInspection {
}
}
@Override
public void visitPolyadicExpression(PsiPolyadicExpression expression) {
IElementType type = expression.getOperationTokenType();
if (JavaTokenType.PLUS.equals(type) && TypeUtils.isJavaLangString(expression.getType()) &&
!PsiUtil.isConstantExpression(expression) && isPerformedRepeatedlyInLoop(expression)) {
registerError(expression, Kind.STRING_CONCAT);
}
super.visitPolyadicExpression(expression);
}
private static boolean isPerformedRepeatedlyInLoop(@NotNull PsiExpression expression) {
if (!ControlFlowUtils.isInLoop(expression)) return false;
if (ControlFlowUtils.isInExitStatement(expression)) return false;
@@ -87,4 +87,15 @@ class ObjectAllocationInLoop {
}
static native Integer key();
final int CONST = 10;
void concat() {
for (int i = 0; i < 10; i++) {
String s = <warning descr="Object allocation via string concatenation in loop">"value: " + i</warning>;
String s2 = "value: " + CONST;
System.out.println(s);
System.out.println(s2);
}
}
}