mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IG: check array argument to format call correctly (IDEA-171421)
This commit is contained in:
+44
-10
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -124,6 +124,16 @@ public class MalformedFormatString {
|
||||
public String highlightBothArguments() {
|
||||
return String.format("count 1: %f, count 2: %f", <warning descr="Argument type 'int' does not match the type of the format specifier '%f'">count1</warning>, <warning descr="Argument type 'int' does not match the type of the format specifier '%f'">count2</warning>);
|
||||
}
|
||||
|
||||
void arrayArguments() {
|
||||
String.format("%c", new Object[]{'a'});
|
||||
String.<warning descr="Too many arguments for format string (found: 2, expected: 1)">format</warning>("%c", new Object[]{'a', 'b'});
|
||||
String.<warning descr="Too few arguments for format string (found: 1, expected: 2)">format</warning>("%c %c", new Object[]{'a'});
|
||||
Object[] array = new Object[]{<warning descr="Argument type 'String' does not match the type of the format specifier '%#s'">"the void"</warning>};
|
||||
String.format("%#s", array);
|
||||
Object[] array2 = {<warning descr="Argument type 'String' does not match the type of the format specifier '%#s'">"the void"</warning>};
|
||||
String.format("%#s", array2);
|
||||
}
|
||||
}
|
||||
class A {
|
||||
void m(Formattable f) {
|
||||
|
||||
Reference in New Issue
Block a user