StringConcatenationInLoopsInspection: add null-check for unknown variables

IDEA-183139 "String to StringBuilder" quick fix may cause NPE
This commit is contained in:
Tagir Valeev
2017-12-06 11:57:10 +07:00
parent ab8419b387
commit f03d494538
5 changed files with 45 additions and 2 deletions
@@ -40,6 +40,9 @@ public class CommonDataflow {
if(existing != DfaFactMap.EMPTY) {
DfaValue value = memState.peek();
DfaFactMap newMap = memState.getFactMap(value);
if (!Boolean.FALSE.equals(newMap.get(DfaFactType.CAN_BE_NULL)) && memState.isNotNull(value)) {
newMap = newMap.with(DfaFactType.CAN_BE_NULL, false);
}
myFacts.put(expression, existing == null ? newMap : existing.union(newMap));
}
}
@@ -5,7 +5,7 @@ public class Main {
StringBuilder res = null;
for (String s : strings) {
if(res == null) {
res = new StringBuilder(s);
res = s == null ? null : new StringBuilder(s);
} else {
res.append(s);
}
@@ -0,0 +1,16 @@
// "Convert variable 'res' from String to StringBuilder" "true"
public class Main {
String test(String[] strings) {
StringBuilder res = null;
for (String s : strings) {
if (s == null) continue;
if(res == null) {
res = new StringBuilder(s);
} else {
res.append(s);
}
}
return res.toString();
}
}
@@ -0,0 +1,16 @@
// "Convert variable 'res' from String to StringBuilder" "true"
public class Main {
String test(String[] strings) {
String res = null;
for (String s : strings) {
if (s == null) continue;
if(res == null) {
res = s;
} else {
res<caret>+=s;
}
}
return res;
}
}
@@ -17,6 +17,8 @@ package com.siyeh.ig.performance;
import com.intellij.codeInsight.PsiEquivalenceUtil;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.dataFlow.CommonDataflow;
import com.intellij.codeInspection.dataFlow.DfaFactType;
import com.intellij.codeInspection.util.ChangeToAppendUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
@@ -329,7 +331,13 @@ public class StringConcatenationInLoopsInspection extends BaseInspection {
return ct.text(initializer);
}
String text = initializer == null || ExpressionUtils.isLiteral(initializer, "") ? "" : ct.text(initializer);
return "new " + myTargetType + "(" + text + ")";
String stringBuilderText = "new " + myTargetType + "(" + text + ")";
PsiReferenceExpression ref = ObjectUtils.tryCast(PsiUtil.skipParenthesizedExprDown(initializer), PsiReferenceExpression.class);
if (ref != null && ref.getQualifierExpression() == null &&
!Boolean.FALSE.equals(CommonDataflow.getExpressionFact(ref, DfaFactType.CAN_BE_NULL))) {
return ref.getText() + "==null?null:" + stringBuilderText;
}
return stringBuilderText;
}
void replaceAll(PsiVariable variable,