[codeInsight] IDEA-240288 Inspection for StringBuilder.toString().substring()

This patch simplifies the `RedundantStringOperationInspection#isOperandOfStringType` method by checking if the type of the passed operand is java.lang.String. The check is the same for any passed operand since they are of the `PsiExpression` type and hence poses the `PsiExpression#getType` method.

Signed-off-by: Nikita Eshkeev <nikita.eshkeev@jetbrains.com>

GitOrigin-RevId: bcd489d41d1272877a1bbf6032ef837a228a18e1
This commit is contained in:
Nikita Eshkeev
2020-05-13 00:55:37 +00:00
committed by intellij-monorepo-bot
parent d936b545a5
commit 06fbc3bdd2
5 changed files with 72 additions and 38 deletions
@@ -3,7 +3,9 @@
class StringBuilderToStringArgs {
private static final String CONST_STRING_VAL = "Hello";
static String str() { return ""; }
static <T> T gen(T a) { return a; }
static void stringBuilderToStringArgs(StringBuilder sb) {
/* 2 */
@@ -83,6 +85,24 @@ class StringBuilderToStringArgs {
System.out.println(("Hello" + sb + (sb.toString() + ((sb.toString())))));
System.out.println(("Hello" + sb + (sb + ((sb) + "Hello"))));
System.out.println(("Hello" + sb + (sb + ((sb.toString()) + 42))));
}
System.out.println((("Hello")) + sb + (sb + ((sb.toString()) + 42))));
/* 2 */
/* 3 */
/* 4 */
System.out.println(gen("Hello") + /* 1 */sb/* 5 */);
/* 2 */
/* 3 */
/* 4 */
System.out.println(/* 1 */sb/* 5 */ + gen("Hello"));
/* 2 */
/* 3 */
/* 4 */
System.out.println(gen("Hello") + /* 1 */sb/* 5 */ + gen("Hello"));
System.out.println(gen(42) + /* 1 */sb./* 2 */toString/* 3 */(/* 4 */)/* 5 */);
System.out.println(/* 1 */sb./* 2 */toString/* 3 */(/* 4 */)/* 5 */ + gen(42));
System.out.println(gen(42) + /* 1 */sb./* 2 */toString/* 3 */(/* 4 */)/* 5 */ + gen(42));
}
}
@@ -5,6 +5,7 @@ class StringBuilderToStringAssign {
public static final String CONST_STRING_VAL = "Hello";
static String str() { return ""; }
static <T> T gen(T a) { return a; }
static void stringBuilderToStringAssign(StringBuilder sb) {
String s1 = sb + "Hello";
@@ -83,7 +84,24 @@ class StringBuilderToStringAssign {
String s104 = ("Hello" + sb + (sb.toString() + ((sb.toString()))));
String s105 = ("Hello" + sb + (sb + ((sb) + "Hello")));
String s106 = ("Hello" + sb + (sb + ((sb.toString()) + 42)));
String s107 = ((("Hello")) + sb + (sb + ((sb.toString()) + 42)));
/* 2 */
/* 3 */
/* 4 */
String s181 = gen("Hello") + /* 1 */sb/* 5 */;
/* 2 */
/* 3 */
/* 4 */
String s182 = /* 1 */sb/* 5 */ + gen("Hello");
/* 2 */
/* 3 */
/* 4 */
String s183 = gen("Hello") + /* 1 */sb/* 5 */ + gen("Hello");
String s191 = gen(42) + /* 1 */sb./* 2 */toString/* 3 */(/* 4 */)/* 5 */;
String s192 = /* 1 */sb./* 2 */toString/* 3 */(/* 4 */)/* 5 */ + gen(42);
String s193 = gen(42) + /* 1 */sb./* 2 */toString/* 3 */(/* 4 */)/* 5 */ + gen(42);
}
}
@@ -3,7 +3,9 @@
class StringBuilderToStringArgs {
private static final String CONST_STRING_VAL = "Hello";
static String str() { return ""; }
static <T> T gen(T a) { return a; }
static void stringBuilderToStringArgs(StringBuilder sb) {
System.out.println(/* 1 */sb./* 2 */to<caret>String/* 3 */(/* 4 */)/* 5 */ + "Hello");
@@ -44,6 +46,15 @@ class StringBuilderToStringArgs {
System.out.println(("Hello" + sb.toString() + (sb.toString() + ((sb.toString())))));
System.out.println(("Hello" + sb.toString() + (sb.toString() + ((sb.toString()) + "Hello"))));
System.out.println(("Hello" + sb.toString() + (sb.toString() + ((sb.toString()) + 42))));
}
System.out.println((("Hello")) + sb.toString() + (sb.toString() + ((sb.toString()) + 42))));
System.out.println(gen("Hello") + /* 1 */sb./* 2 */toString/* 3 */(/* 4 */)/* 5 */);
System.out.println(/* 1 */sb./* 2 */toString/* 3 */(/* 4 */)/* 5 */ + gen("Hello"));
System.out.println(gen("Hello") + /* 1 */sb./* 2 */toString/* 3 */(/* 4 */)/* 5 */ + gen("Hello"));
System.out.println(gen(42) + /* 1 */sb./* 2 */toString/* 3 */(/* 4 */)/* 5 */);
System.out.println(/* 1 */sb./* 2 */toString/* 3 */(/* 4 */)/* 5 */ + gen(42));
System.out.println(gen(42) + /* 1 */sb./* 2 */toString/* 3 */(/* 4 */)/* 5 */ + gen(42));
}
}
@@ -5,6 +5,7 @@ class StringBuilderToStringAssign {
public static final String CONST_STRING_VAL = "Hello";
static String str() { return ""; }
static <T> T gen(T a) { return a; }
static void stringBuilderToStringAssign(StringBuilder sb) {
String s1 = sb.<caret>toString() + "Hello";
@@ -47,7 +48,15 @@ class StringBuilderToStringAssign {
String s104 = ("Hello" + sb.toString() + (sb.toString() + ((sb.toString()))));
String s105 = ("Hello" + sb.toString() + (sb.toString() + ((sb.toString()) + "Hello")));
String s106 = ("Hello" + sb.toString() + (sb.toString() + ((sb.toString()) + 42)));
String s107 = ((("Hello")) + sb.toString() + (sb.toString() + ((sb.toString()) + 42)));
String s181 = gen("Hello") + /* 1 */sb./* 2 */toString/* 3 */(/* 4 */)/* 5 */;
String s182 = /* 1 */sb./* 2 */toString/* 3 */(/* 4 */)/* 5 */ + gen("Hello");
String s183 = gen("Hello") + /* 1 */sb./* 2 */toString/* 3 */(/* 4 */)/* 5 */ + gen("Hello");
String s191 = gen(42) + /* 1 */sb./* 2 */toString/* 3 */(/* 4 */)/* 5 */;
String s192 = /* 1 */sb./* 2 */toString/* 3 */(/* 4 */)/* 5 */ + gen(42);
String s193 = gen(42) + /* 1 */sb./* 2 */toString/* 3 */(/* 4 */)/* 5 */ + gen(42);
}
}
@@ -284,7 +284,7 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
if (((PsiPolyadicExpression)parent).getOperationTokenType() != JavaTokenType.PLUS) return null;
final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)parent;
final PsiExpression[] operands = polyadicExpression.getOperands();
final PsiExpression @NotNull[] operands = polyadicExpression.getOperands();
final boolean hasStringOperand = Arrays.stream(operands)
.filter(operand -> operand != call)
@@ -301,39 +301,15 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
return getProblem(call, "inspection.redundant.string.call.message");
}
@Contract("null -> false")
private static boolean isOperandOfStringType(final PsiExpression op) {
final PsiExpression operand = PsiUtil.skipParenthesizedExprDown(op);
private static boolean isOperandOfStringType(@NotNull final PsiExpression operand) {
if (STRING_BUILDER_TO_STRING.matches(operand)) return false;
if (operand == null) return false;
if (operand.getType() != null && operand.getType().equalsToText(String.class.getName())) {
return true;
}
if (operand instanceof PsiReferenceExpression) {
if (operand.getType() != null && operand.getType().equalsToText(String.class.getName())) {
return true;
}
}
else if (operand instanceof PsiMethodCallExpression) {
if (STRING_BUILDER_TO_STRING.matches(operand)) return false;
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)operand;
final PsiMethod method = methodCallExpression.resolveMethod();
if (method != null && method.getReturnType() != null && method.getReturnType().equalsToText(String.class.getName())) {
return true;
}
}
else if (operand instanceof PsiPolyadicExpression) {
final PsiPolyadicExpression expression = (PsiPolyadicExpression)operand;
if (expression.getType() != null && expression.getType().equalsToText(String.class.getName())) {
return true;
}
}
else {
final String value = tryCast(ExpressionUtils.computeConstantExpression(operand), String.class);
if (value != null) {
return true;
}
}
return false;
final String value = tryCast(ExpressionUtils.computeConstantExpression(operand), String.class);
return value != null;
}
@Nullable