diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties index 71600cc0c08e..bef04029bb60 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties @@ -1705,8 +1705,9 @@ if.may.be.conditional.problem.descriptor=#ref could be replaced wit if.may.be.conditional.quickfix=Replace with conditional expression if.may.be.conditional.report.method.calls.option=Report if statements containing method calls redundant.string.format.call.display.name=Redundant call to 'String.format()' -redundant.string.format.call.problem.descriptor=Redundant call to #ref #loc +redundant.string.format.call.problem.descriptor=Redundant call to #ref() #loc redundant.string.format.call.quickfix=Remove redundant call to 'String.format()' +replace.printf.with.print.quickfix=Replace 'printf()' with 'print()' junit4.test.method.in.class.extending.junit3.testcase.display.name=JUnit 4 test method in class extending JUnit 3 TestCase junit4.test.method.in.class.extending.junit3.testcase.problem.descriptor=Method #ref() annotated with '@Test' inside class extending JUnit 3 TestCase #loc ignore.test.method.in.class.extending.junit3.testcase.problem.descriptor=JUnit 3 test method #ref() annotated with '@Ignore' won't be ignored #loc diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/RedundantStringFormatCallInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/RedundantStringFormatCallInspection.java index b73de0d927df..ad572a146779 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/RedundantStringFormatCallInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/performance/RedundantStringFormatCallInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2013 Bas Leijdekkers + * Copyright 2008-2017 Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; +import com.siyeh.ig.PsiReplacementUtil; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -44,7 +45,8 @@ public class RedundantStringFormatCallInspection extends BaseInspection { @Override protected InspectionGadgetsFix buildFix(Object... infos) { - return new RedundantStringFormatCallFix(); + final Boolean printf = (Boolean)infos[0]; + return printf.booleanValue() ? new ReplaceWithPrintFix() : new RedundantStringFormatCallFix(); } @Override @@ -52,13 +54,12 @@ public class RedundantStringFormatCallInspection extends BaseInspection { return true; } - private static class RedundantStringFormatCallFix extends InspectionGadgetsFix { - - @Override + private static class ReplaceWithPrintFix extends InspectionGadgetsFix { + @Nls @NotNull + @Override public String getFamilyName() { - return InspectionGadgetsBundle.message( - "redundant.string.format.call.quickfix"); + return InspectionGadgetsBundle.message("replace.printf.with.print.quickfix"); } @Override @@ -70,10 +71,34 @@ public class RedundantStringFormatCallInspection extends BaseInspection { return; } final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)grandParent; - final PsiExpressionList argumentList = methodCallExpression.getArgumentList(); - final PsiExpression[] arguments = argumentList.getExpressions(); - final PsiExpression lastArgument = arguments[arguments.length - 1]; - methodCallExpression.replace(lastArgument); + final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); + @NonNls final StringBuilder newExpression = new StringBuilder(); + final PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); + if (qualifierExpression != null) { + newExpression.append(qualifierExpression.getText()).append('.'); + } + newExpression.append("print").append(methodCallExpression.getArgumentList().getText()); + PsiReplacementUtil.replaceExpression(methodCallExpression, newExpression.toString()); + } + } + + private static class RedundantStringFormatCallFix extends InspectionGadgetsFix { + + @Override + @NotNull + public String getFamilyName() { + return InspectionGadgetsBundle.message("redundant.string.format.call.quickfix"); + } + + @Override + protected void doFix(Project project, ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement().getParent().getParent(); + if (!(element instanceof PsiMethodCallExpression)) { + return; + } + final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)element; + final PsiExpression[] arguments = methodCallExpression.getArgumentList().getExpressions(); + methodCallExpression.replace(arguments[arguments.length - 1]); } } @@ -89,7 +114,14 @@ public class RedundantStringFormatCallInspection extends BaseInspection { super.visitMethodCallExpression(expression); final PsiReferenceExpression methodExpression = expression.getMethodExpression(); @NonNls final String methodName = methodExpression.getReferenceName(); - if (!"format".equals(methodName)) { + final boolean printf; + if ("format".equals(methodName)) { + printf = false; + } + else if ("printf".equals(methodName)) { + printf = true; + } + else { return; } final PsiExpressionList argumentList = expression.getArgumentList(); @@ -106,7 +138,12 @@ public class RedundantStringFormatCallInspection extends BaseInspection { return; } final String className = aClass.getQualifiedName(); - if (!CommonClassNames.JAVA_LANG_STRING.equals(className)) { + if (printf) { + if (!"java.io.PrintStream".equals(className)) { + return; + } + } + else if (!CommonClassNames.JAVA_LANG_STRING.equals(className)) { return; } final PsiExpression firstArgument = arguments[0]; @@ -116,7 +153,7 @@ public class RedundantStringFormatCallInspection extends BaseInspection { } if (firstType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) { if (arguments.length == 1 && !containsPercentN(firstArgument)) { - registerMethodCallError(expression); + registerMethodCallError(expression, Boolean.valueOf(printf)); } } else if (firstType.equalsToText("java.util.Locale")) { @@ -131,7 +168,7 @@ public class RedundantStringFormatCallInspection extends BaseInspection { if (containsPercentN(secondArgument)) { return; } - registerMethodCallError(expression); + registerMethodCallError(expression, Boolean.valueOf(printf)); } } diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantStringFormatCall.html b/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantStringFormatCall.html index 8e16d6353054..10f03d1d4fe3 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantStringFormatCall.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/RedundantStringFormatCall.html @@ -1,8 +1,8 @@ -Reports any calls to String.format() where only a format string is +Reports any calls to String.format() or PrintStream.printf() where only a format string is provided, but no arguments. Such a call is unnecessary and can be replaced with just -the string. +the string or a call to PrintStream.print() respectively.

diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/redundant_string_format_call/RedundantStringFormatCall.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/redundant_string_format_call/RedundantStringFormatCall.java index a3077ede82a9..63dd1632ec9a 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/redundant_string_format_call/RedundantStringFormatCall.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/performance/redundant_string_format_call/RedundantStringFormatCall.java @@ -16,5 +16,6 @@ public class RedundantStringFormatCall { void m() { System.out.println(String.format("string contains %%n%n")); // ok System.out.println(String.format(Locale.ENGLISH, "string contains %%n%n")); + System.out.printf("empty battery"); } } \ No newline at end of file