IDEA-127029 (Log format inspection should highlight whole statement if args are missing)

This commit is contained in:
Bas Leijdekkers
2014-08-13 21:55:42 +02:00
parent 03f0231eff
commit 40bb111b79
3 changed files with 25 additions and 15 deletions
@@ -2018,8 +2018,8 @@ string.concatenation.argument.to.log.call.display.name=Non-constant string conca
string.concatenation.argument.to.log.call.problem.descriptor=Non-constant string concatenation as argument to <code>#ref()</code> logging call #loc
string.concatenation.argument.to.log.call.quickfix=Replace concatenation with parameterized log message
placeholder.count.matches.argument.count.display.name=Number of placeholders does not match number of arguments in logging call
placeholder.count.matches.argument.count.more.problem.descriptor=<code>#ref()</code> call has more arguments ({0}) than placeholders ({1}) #loc
placeholder.count.matches.argument.count.fewer.problem.descriptor=<code>#ref()</code> call has fewer arguments ({0}) than placeholders ({1}) #loc
placeholder.count.matches.argument.count.more.problem.descriptor=More arguments provided ({0}) than placeholders specified ({1}) in ''{2}'' #loc
placeholder.count.matches.argument.count.fewer.problem.descriptor=Fewer arguments provided ({0}) than placeholders specified ({1}) in ''{2}'' #loc
assignment.to.superclass.field.display.name=Constructor assigns value to field defined in superclass
assignment.to.superclass.field.problem.descriptor=Assignment to field ''{0}'' defined in superclass ''{1}'' #loc
junit.rule.display.name=Malformed @Rule/@ClassRule field
@@ -45,13 +45,14 @@ public class PlaceholderCountMatchesArgumentCountInspection extends BaseInspecti
protected String buildErrorString(Object... infos) {
final Integer argumentCount = (Integer)infos[0];
final Integer placeholderCount = (Integer)infos[1];
final Object value = infos[2];
if (argumentCount.intValue() > placeholderCount.intValue()) {
return InspectionGadgetsBundle.message("placeholder.count.matches.argument.count.more.problem.descriptor",
argumentCount, placeholderCount);
argumentCount, placeholderCount, value);
}
else {
return InspectionGadgetsBundle.message("placeholder.count.matches.argument.count.fewer.problem.descriptor",
argumentCount, placeholderCount);
argumentCount, placeholderCount, value);
}
}
@@ -83,25 +84,24 @@ public class PlaceholderCountMatchesArgumentCountInspection extends BaseInspecti
if (arguments.length == 0) {
return;
}
final PsiExpression firstArgument = arguments[0];
final int placeholderCount;
PsiExpression logStringArgument = arguments[0];
final int argumentCount;
if (InheritanceUtil.isInheritor(firstArgument.getType(), "org.slf4j.Marker")) {
if (InheritanceUtil.isInheritor(logStringArgument.getType(), "org.slf4j.Marker")) {
if (arguments.length < 2) {
return;
}
final PsiExpression secondArgument = arguments[1];
placeholderCount = countPlaceholders(secondArgument);
logStringArgument = arguments[1];
argumentCount = countArguments(arguments, 2);
}
else {
placeholderCount = countPlaceholders(firstArgument);
argumentCount = countArguments(arguments, 1);
}
final Object value = ExpressionUtils.computeConstantExpression(logStringArgument);
final int placeholderCount = countPlaceholders(value);
if (placeholderCount < 0 || argumentCount < 0 || placeholderCount == argumentCount) {
return;
}
registerMethodCallError(expression, Integer.valueOf(argumentCount), Integer.valueOf(placeholderCount));
registerError(logStringArgument, Integer.valueOf(argumentCount), Integer.valueOf(placeholderCount), value);
}
private static boolean hasThrowableType(PsiExpression lastArgument) {
@@ -118,8 +118,7 @@ public class PlaceholderCountMatchesArgumentCountInspection extends BaseInspecti
return InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_LANG_THROWABLE);
}
public static int countPlaceholders(PsiExpression argument) {
final Object value = ExpressionUtils.computeConstantExpression(argument);
public static int countPlaceholders(Object value) {
if (!(value instanceof String)) {
return -1;
}
@@ -32,7 +32,7 @@ public class PlaceholderCountMatchesArgumentCountInspectionTest extends LightIns
"class X {\n" +
" void foo() {\n" +
" Logger logger = LoggerFactory.getLogger(X.class);\n" +
" logger./*'info()' call has fewer arguments (1) than placeholders (2)*/info/**/(\"string {}{}\", 1);\n" +
" logger.info(/*Fewer arguments provided (1) than placeholders specified (2) in 'string {}{}'*/\"string {}{}\"/**/, 1);\n" +
" }\n" +
"}"
);
@@ -43,7 +43,7 @@ public class PlaceholderCountMatchesArgumentCountInspectionTest extends LightIns
"class X {\n" +
" void foo() {\n" +
" Logger logger = LoggerFactory.getLogger(X.class);\n" +
" logger./*'info()' call has more arguments (1) than placeholders (0)*/info/**/(\"string\", 1);\n" +
" logger.info(/*More arguments provided (1) than placeholders specified (0) in 'string'*/\"string\"/**/, 1);\n" +
" }\n" +
"}"
);
@@ -107,4 +107,15 @@ public class PlaceholderCountMatchesArgumentCountInspectionTest extends LightIns
" }" +
"}");
}
public void testConstant() {
doTest("import org.slf4j.*;" +
"class X {" +
" Logger LOG = LoggerFactory.getLogger(X.class);" +
" private static final String message = \"HELLO {}\";" +
" void m() {" +
" LOG.info(/*Fewer arguments provided (0) than placeholders specified (1) in 'HELLO {}'*/message/**/);" +
" }" +
"}");
}
}