diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedFormatStringInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedFormatStringInspectionBase.java
index 907555f8a1b6..684d035efffc 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedFormatStringInspectionBase.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedFormatStringInspectionBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2016 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2017 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.FormatUtils;
+import com.siyeh.ig.psiutils.ParenthesesUtils;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -130,12 +131,13 @@ public class MalformedFormatStringInspectionBase extends BaseInspection {
return;
}
final PsiExpressionList argumentList = expression.getArgumentList();
- final PsiExpression[] arguments = argumentList.getExpressions();
- final int formatArgumentIndex = findFirstStringArgumentIndex(arguments);
+ PsiExpression[] arguments = argumentList.getExpressions();
+ int formatArgumentIndex = findFirstStringArgumentIndex(arguments);
if (formatArgumentIndex < 0) {
return;
}
final PsiExpression formatArgument = arguments[formatArgumentIndex];
+ formatArgumentIndex++;
if (!ExpressionUtils.hasStringType(formatArgument) || !PsiUtil.isConstantExpression(formatArgument)) {
return;
}
@@ -147,7 +149,7 @@ public class MalformedFormatStringInspectionBase extends BaseInspection {
if (value == null) {
return;
}
- final int argumentCount = arguments.length - (formatArgumentIndex + 1);
+ int argumentCount = arguments.length - (formatArgumentIndex);
final FormatDecode.Validator[] validators;
try {
validators = FormatDecode.decode(value, argumentCount);
@@ -156,20 +158,36 @@ public class MalformedFormatStringInspectionBase extends BaseInspection {
registerError(formatArgument, e);
return;
}
- if (validators.length != argumentCount) {
- if (argumentCount == 1) {
- final PsiExpression argument = arguments[formatArgumentIndex + 1];
- final PsiType argumentType = argument.getType();
- if (argumentType instanceof PsiArrayType) {
+ if (argumentCount == 1) {
+ final PsiExpression argument = resolveIfPossible(arguments[formatArgumentIndex]);
+ final PsiType argumentType = argument.getType();
+ if (argumentType instanceof PsiArrayType) {
+ final PsiArrayInitializerExpression arrayInitializer;
+ if (argument instanceof PsiNewExpression) {
+ final PsiNewExpression newExpression = (PsiNewExpression)argument;
+ arrayInitializer = newExpression.getArrayInitializer();
+ }
+ else if (argument instanceof PsiArrayInitializerExpression) {
+ arrayInitializer = (PsiArrayInitializerExpression)argument;
+ }
+ else {
return;
}
+ if (arrayInitializer == null) {
+ return;
+ }
+ arguments = arrayInitializer.getInitializers();
+ argumentCount = arguments.length;
+ formatArgumentIndex = 0;
}
+ }
+ if (validators.length != argumentCount) {
registerMethodCallError(expression, validators, Integer.valueOf(argumentCount));
return;
}
for (int i = 0; i < validators.length; i++) {
final FormatDecode.Validator validator = validators[i];
- final PsiExpression argument = arguments[i + formatArgumentIndex + 1];
+ final PsiExpression argument = arguments[i + formatArgumentIndex];
final PsiType argumentType = argument.getType();
if (argumentType == null) {
continue;
@@ -179,5 +197,21 @@ public class MalformedFormatStringInspectionBase extends BaseInspection {
}
}
}
+
+ private PsiExpression resolveIfPossible(PsiExpression expression) {
+ expression = ParenthesesUtils.stripParentheses(expression);
+ if (expression instanceof PsiReferenceExpression) {
+ final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression;
+ final PsiElement target = referenceExpression.resolve();
+ if (target instanceof PsiVariable && target.getContainingFile() == expression.getContainingFile()) {
+ final PsiVariable variable = (PsiVariable)target;
+ final PsiExpression initializer = variable.getInitializer();
+ if (initializer != null) {
+ return initializer;
+ }
+ }
+ }
+ return expression;
+ }
}
}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java
index 383176e969b8..ee50bbfe8df2 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java
@@ -124,6 +124,16 @@ public class MalformedFormatString {
public String highlightBothArguments() {
return String.format("count 1: %f, count 2: %f", count1, count2);
}
+
+ void arrayArguments() {
+ String.format("%c", new Object[]{'a'});
+ String.format("%c", new Object[]{'a', 'b'});
+ String.format("%c %c", new Object[]{'a'});
+ Object[] array = new Object[]{"the void"};
+ String.format("%#s", array);
+ Object[] array2 = {"the void"};
+ String.format("%#s", array2);
+ }
}
class A {
void m(Formattable f) {