From 8084168cd5eb361b48579d39ba5eca95dd3193a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivo=20=C5=A0m=C3=ADd?= Date: Fri, 8 Nov 2019 11:11:36 +0100 Subject: [PATCH] IDEA-226374 Constant String field evaluation shows PsiType prefix GitOrigin-RevId: e4cfa8fbf4a20f2a2b8cfe63a30b0294274ca660 --- .../psi/impl/ConstantExpressionVisitor.java | 20 +++- .../constantValues/ClassWithConstants.java | 15 +++ .../intellij/java/psi/ConstantValuesTest.java | 112 +++++++++++++++++- 3 files changed, 144 insertions(+), 3 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/ConstantExpressionVisitor.java b/java/java-psi-impl/src/com/intellij/psi/impl/ConstantExpressionVisitor.java index e2ff1fe387af..e07f2ee1319a 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/ConstantExpressionVisitor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/ConstantExpressionVisitor.java @@ -21,6 +21,7 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.ClassUtil; import com.intellij.psi.util.ConstantEvaluationOverflowException; import com.intellij.psi.util.ConstantExpressionUtil; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.containers.Interner; import com.intellij.util.containers.StringInterner; import gnu.trove.THashSet; @@ -141,8 +142,8 @@ class ConstantExpressionVisitor extends JavaElementVisitor implements PsiConstan Object value = null; if (tokenType == JavaTokenType.PLUS) { if (lOperandValue instanceof String || rOperandValue instanceof String) { - String l = lOperandValue.toString(); - String r = rOperandValue.toString(); + String l = computeValueToString(lOperandValue); + String r = computeValueToString(rOperandValue); value = l + r; } else { @@ -394,6 +395,21 @@ class ConstantExpressionVisitor extends JavaElementVisitor implements PsiConstan return value; } + private static String computeValueToString(Object value) { + if (value instanceof PsiType) { + if (value instanceof PsiArrayType) { + return "class " + ClassUtil.getClassObjectPresentation((PsiType)value); + } + + PsiClass psiClass = PsiUtil.resolveClassInType((PsiType)value); + String prefix = psiClass == null ? "" : psiClass.isInterface() ? "interface " : "class "; + return prefix + ((PsiType)value).getCanonicalText(); + } + else { + return value.toString(); + } + } + @Nullable private static Boolean handleEqualityComparison(Object lOperandValue, Object rOperandValue, IElementType tokenType) { if (lOperandValue instanceof String && rOperandValue instanceof String || diff --git a/java/java-tests/testData/psi/constantValues/ClassWithConstants.java b/java/java-tests/testData/psi/constantValues/ClassWithConstants.java index 374c0cf3bd85..428c7c880d2d 100644 --- a/java/java-tests/testData/psi/constantValues/ClassWithConstants.java +++ b/java/java-tests/testData/psi/constantValues/ClassWithConstants.java @@ -12,8 +12,23 @@ public class ClassWithConstants { public static final float FLOAT_CONST = 1.234f; public static final double DOUBLE_CONST = 3.456; public static final java.lang.String STRING_CONST = "a\r\n\"bcd"; + public static final java.lang.String STRING_EXPRESSION_CONST1 = "a" + "b"; + public static final java.lang.String STRING_EXPRESSION_CONST2 = "a" + 123; + public static final java.lang.String STRING_EXPRESSION_CONST3 = 123 + "b"; + public static final java.lang.String STRING_EXPRESSION_CONST4 = INT_CONST1 + "aaa"; + + public static final java.lang.String STRING_EXPRESSION_CLASS = Integer.class + "xxx"; + public static final java.lang.String STRING_EXPRESSION_CLASS_ARRAY = Integer[].class + "xxx"; + public static final java.lang.String STRING_EXPRESSION_INTERFACE = Runnable.class + "xxx"; + public static final java.lang.String STRING_EXPRESSION_PRIMITIVE = int.class + "xxx"; + public static final java.lang.String STRING_EXPRESSION_PRIMITIVE_ARRAY = int[].class + "xxx"; + public static final java.lang.String STRING_EXPRESSION_METHOD = val() + "xxx"; public static final double d1 = Double.POSITIVE_INFINITY; public static final double d2 = Double.NEGATIVE_INFINITY; public static final double d3 = Double.NaN; + + public static int val() { + return 1; + } } diff --git a/java/java-tests/testSrc/com/intellij/java/psi/ConstantValuesTest.java b/java/java-tests/testSrc/com/intellij/java/psi/ConstantValuesTest.java index ef653b0c0145..466ef4c69425 100644 --- a/java/java-tests/testSrc/com/intellij/java/psi/ConstantValuesTest.java +++ b/java/java-tests/testSrc/com/intellij/java/psi/ConstantValuesTest.java @@ -236,4 +236,114 @@ public class ConstantValuesTest extends LightJavaCodeInsightFixtureTestCase { assertNotNull(field); assertEquals("", JavaConstantExpressionEvaluator.computeConstantExpression(field.getInitializer(), false)); } -} \ No newline at end of file + + public void testStringConstExpression1() { + PsiField field = myClass.findFieldByName("STRING_EXPRESSION_CONST1", false); + assertNotNull(field); + PsiBinaryExpression initializer = (PsiBinaryExpression)field.getInitializer(); + assertNotNull(initializer); + assertTrue(initializer.getType().equalsToText("java.lang.String")); + assertEquals("\"a\" + \"b\"", initializer.getText()); + + assertEquals("ab", field.computeConstantValue()); + } + + public void testStringConstExpression2() { + PsiField field = myClass.findFieldByName("STRING_EXPRESSION_CONST2", false); + assertNotNull(field); + PsiBinaryExpression initializer = (PsiBinaryExpression)field.getInitializer(); + assertNotNull(initializer); + assertTrue(initializer.getType().equalsToText("java.lang.String")); + assertEquals("\"a\" + 123", initializer.getText()); + + assertEquals("a123", field.computeConstantValue()); + } + + public void testStringConstExpression3() { + PsiField field = myClass.findFieldByName("STRING_EXPRESSION_CONST3", false); + assertNotNull(field); + PsiBinaryExpression initializer = (PsiBinaryExpression)field.getInitializer(); + assertNotNull(initializer); + assertTrue(initializer.getType().equalsToText("java.lang.String")); + assertEquals("123 + \"b\"", initializer.getText()); + + assertEquals("123b", field.computeConstantValue()); + } + + public void testStringConstExpression4() { + PsiField field = myClass.findFieldByName("STRING_EXPRESSION_CONST4", false); + assertNotNull(field); + PsiBinaryExpression initializer = (PsiBinaryExpression)field.getInitializer(); + assertNotNull(initializer); + assertTrue(initializer.getType().equalsToText("java.lang.String")); + assertEquals("INT_CONST1 + \"aaa\"", initializer.getText()); + + assertEquals("1aaa", field.computeConstantValue()); + } + + public void testStringExpressionClass() { + PsiField field = myClass.findFieldByName("STRING_EXPRESSION_CLASS", false); + assertNotNull(field); + PsiBinaryExpression initializer = (PsiBinaryExpression)field.getInitializer(); + assertNotNull(initializer); + assertTrue(initializer.getType().equalsToText("java.lang.String")); + assertEquals("Integer.class + \"xxx\"", initializer.getText()); + + assertEquals("class java.lang.Integerxxx", field.computeConstantValue()); + } + + public void testStringExpressionClassArray() { + PsiField field = myClass.findFieldByName("STRING_EXPRESSION_CLASS_ARRAY", false); + assertNotNull(field); + PsiBinaryExpression initializer = (PsiBinaryExpression)field.getInitializer(); + assertNotNull(initializer); + assertTrue(initializer.getType().equalsToText("java.lang.String")); + assertEquals("Integer[].class + \"xxx\"", initializer.getText()); + + assertEquals("class [Ljava.lang.Integer;xxx", field.computeConstantValue()); + } + + public void testStringExpressionInterface() { + PsiField field = myClass.findFieldByName("STRING_EXPRESSION_INTERFACE", false); + assertNotNull(field); + PsiBinaryExpression initializer = (PsiBinaryExpression)field.getInitializer(); + assertNotNull(initializer); + assertTrue(initializer.getType().equalsToText("java.lang.String")); + assertEquals("Runnable.class + \"xxx\"", initializer.getText()); + + assertEquals("interface java.lang.Runnablexxx", field.computeConstantValue()); + } + + public void testStringExpressionPrimitive() { + PsiField field = myClass.findFieldByName("STRING_EXPRESSION_PRIMITIVE", false); + assertNotNull(field); + PsiBinaryExpression initializer = (PsiBinaryExpression)field.getInitializer(); + assertNotNull(initializer); + assertTrue(initializer.getType().equalsToText("java.lang.String")); + assertEquals("int.class + \"xxx\"", initializer.getText()); + + assertEquals("intxxx", field.computeConstantValue()); + } + + public void testStringExpressionPrimitiveArray() { + PsiField field = myClass.findFieldByName("STRING_EXPRESSION_PRIMITIVE_ARRAY", false); + assertNotNull(field); + PsiBinaryExpression initializer = (PsiBinaryExpression)field.getInitializer(); + assertNotNull(initializer); + assertTrue(initializer.getType().equalsToText("java.lang.String")); + assertEquals("int[].class + \"xxx\"", initializer.getText()); + + assertEquals("class [Ixxx", field.computeConstantValue()); + } + + public void testStringExpressionMethod() { + PsiField field = myClass.findFieldByName("STRING_EXPRESSION_METHOD", false); + assertNotNull(field); + PsiBinaryExpression initializer = (PsiBinaryExpression)field.getInitializer(); + assertNotNull(initializer); + assertTrue(initializer.getType().equalsToText("java.lang.String")); + assertEquals("val() + \"xxx\"", initializer.getText()); + + assertNull(field.computeConstantValue()); + } +}