diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java index e7a99f78b9ed..1c7b7a9d2ef9 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java @@ -37,8 +37,10 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.ArrayUtil; @@ -208,11 +210,17 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { } final Object value = pair.second.getValue(); - holder.registerProblem(ref, "Value #ref #loc is always '" + value + "'", new LocalQuickFix() { + final String presentableName = value instanceof PsiNamedElement ? ((PsiNamedElement)value).getName() : String.valueOf(value); + final String exprText = getConstantValueText(value); + if (exprText == null) { + continue; + } + + holder.registerProblem(ref, "Value #ref #loc is always '" + presentableName + "'", new LocalQuickFix() { @NotNull @Override public String getName() { - return "Replace with '" + value + "'"; + return "Replace with '" + presentableName + "'"; } @NotNull @@ -223,12 +231,28 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { - descriptor.getPsiElement().replace(JavaPsiFacade.getElementFactory(project).createExpressionFromText(String.valueOf(value), null)); + PsiElement newElement = + descriptor.getPsiElement().replace(JavaPsiFacade.getElementFactory(project).createExpressionFromText(exprText, null)); + JavaCodeStyleManager.getInstance(project).shortenClassReferences(newElement); } }); } } + private static String getConstantValueText(Object value) { + String exprText; + if (value instanceof String) { + exprText = "\"" + StringUtil.escapeStringCharacters((String)value) + "\""; + } else if (value instanceof PsiMember) { + exprText = PsiUtil.getMemberQualifiedName((PsiMember)value); + } else if (value instanceof PsiNamedElement) { + exprText = ((PsiNamedElement)value).getName(); + } else { + exprText = String.valueOf(value); + } + return exprText; + } + private void reportNullableArgumentsPassedToNonAnnotated(StandardDataFlowRunner runner, ProblemsHolder holder, Set reportedAnchors) { Set exprs = runner.getNullableArgumentsPassedToNonAnnotatedParam(); for (PsiExpression expr : exprs) { diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ReportConstantReferences_ReplaceWithEnum.java b/java/java-tests/testData/inspection/dataFlow/fixture/ReportConstantReferences_ReplaceWithEnum.java new file mode 100644 index 000000000000..2ed16ce0c6f5 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/ReportConstantReferences_ReplaceWithEnum.java @@ -0,0 +1,7 @@ +class Test { + private void test() { + foo.MyEnum s = foo.MyEnum.FOO; + System.out.println(s); + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ReportConstantReferences_ReplaceWithEnum_after.java b/java/java-tests/testData/inspection/dataFlow/fixture/ReportConstantReferences_ReplaceWithEnum_after.java new file mode 100644 index 000000000000..29552fa61615 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/ReportConstantReferences_ReplaceWithEnum_after.java @@ -0,0 +1,9 @@ +import foo.MyEnum; + +class Test { + private void test() { + foo.MyEnum s = foo.MyEnum.FOO; + System.out.println(MyEnum.FOO); + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ReportConstantReferences_ReplaceWithString.java b/java/java-tests/testData/inspection/dataFlow/fixture/ReportConstantReferences_ReplaceWithString.java new file mode 100644 index 000000000000..51b74fb5843c --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/ReportConstantReferences_ReplaceWithString.java @@ -0,0 +1,8 @@ +class Test { + public static final String CONST = "foo bar"; + private void test() { + String s = CONST; + System.out.println(s); + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/ReportConstantReferences_ReplaceWithString_after.java b/java/java-tests/testData/inspection/dataFlow/fixture/ReportConstantReferences_ReplaceWithString_after.java new file mode 100644 index 000000000000..b5075dd0c183 --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/ReportConstantReferences_ReplaceWithString_after.java @@ -0,0 +1,8 @@ +class Test { + public static final String CONST = "foo bar"; + private void test() { + String s = CONST; + System.out.println("foo bar"); + } + +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java index 83d7dafa3df1..17085495413b 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java @@ -142,11 +142,27 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase { } public void testReportConstantReferences() { + doTestReplaceConstantReferences(); + myFixture.launchAction(myFixture.findSingleIntention("Replace with 'null'")); + myFixture.checkResultByFile(getTestName(false) + "_after.java"); + } + + private void doTestReplaceConstantReferences() { DataFlowInspection inspection = new DataFlowInspection(); inspection.SUGGEST_NULLABLE_ANNOTATIONS = true; myFixture.enableInspections(inspection); myFixture.testHighlighting(true, false, true, getTestName(false) + ".java"); - myFixture.launchAction(myFixture.findSingleIntention("Replace with 'null'")); + } + + public void testReportConstantReferences_ReplaceWithString() { + doTestReplaceConstantReferences(); + myFixture.launchAction(myFixture.findSingleIntention("Replace with 'foo bar'")); + myFixture.checkResultByFile(getTestName(false) + "_after.java"); + } + public void testReportConstantReferences_ReplaceWithEnum() { + myFixture.addClass("package foo; public enum MyEnum { FOO }"); + doTestReplaceConstantReferences(); + myFixture.launchAction(myFixture.findSingleIntention("Replace with 'FOO'")); myFixture.checkResultByFile(getTestName(false) + "_after.java"); }