aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lint/cli/src/test/java/com/android/tools/lint/checks/StringFormatDetectorTest.java19
-rw-r--r--lint/cli/src/test/java/com/android/tools/lint/checks/data/res/values/formatstrings5.xml4
-rw-r--r--lint/cli/src/test/java/com/android/tools/lint/checks/data/src/test/pkg/StringFormat3.java.txt20
-rw-r--r--lint/libs/lint_checks/src/main/java/com/android/tools/lint/checks/StringFormatDetector.java17
4 files changed, 57 insertions, 3 deletions
diff --git a/lint/cli/src/test/java/com/android/tools/lint/checks/StringFormatDetectorTest.java b/lint/cli/src/test/java/com/android/tools/lint/checks/StringFormatDetectorTest.java
index a49955b..47fbea1 100644
--- a/lint/cli/src/test/java/com/android/tools/lint/checks/StringFormatDetectorTest.java
+++ b/lint/cli/src/test/java/com/android/tools/lint/checks/StringFormatDetectorTest.java
@@ -163,6 +163,25 @@ public class StringFormatDetectorTest extends AbstractCheckTest {
"src/test/pkg/StringFormatActivity2.java.txt=>src/test/pkg/StringFormatActivity2.java"));
}
+ public void testIssue42798() throws Exception {
+ // http://code.google.com/p/android/issues/detail?id=42798
+ // String playsCount = String.format(Locale.FRANCE, this.context.getString(R.string.gridview_views_count), article.playsCount);
+ assertEquals(""
+ + "src/test/pkg/StringFormat3.java:12: Error: Wrong argument type for formatting argument '#1' in gridview_views_count: conversion is 'd', received String [StringFormatMatches]\n"
+ + " context.getString(R.string.gridview_views_count), \"wrong\");\n"
+ + " ~~~~~~~\n"
+ + " res/values/formatstrings5.xml:3: Conflicting argument declaration here\n"
+ + "src/test/pkg/StringFormat3.java:13: Error: Wrong argument type for formatting argument '#1' in gridview_views_count: conversion is 'd', received String [StringFormatMatches]\n"
+ + " String s4 = String.format(context.getString(R.string.gridview_views_count), \"wrong\");\n"
+ + " ~~~~~~~\n"
+ + " res/values/formatstrings5.xml:3: Conflicting argument declaration here\n"
+ + "2 errors, 0 warnings\n",
+
+ lintProject(
+ "res/values/formatstrings5.xml",
+ "src/test/pkg/StringFormat3.java.txt=>src/test/pkg/StringFormat3.java"));
+ }
+
public void testIsLocaleSpecific() throws Exception {
assertFalse(isLocaleSpecific(""));
assertFalse(isLocaleSpecific("Hello World!"));
diff --git a/lint/cli/src/test/java/com/android/tools/lint/checks/data/res/values/formatstrings5.xml b/lint/cli/src/test/java/com/android/tools/lint/checks/data/res/values/formatstrings5.xml
new file mode 100644
index 0000000..6b14570
--- /dev/null
+++ b/lint/cli/src/test/java/com/android/tools/lint/checks/data/res/values/formatstrings5.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="gridview_views_count">%d vues</string>
+</resources>
diff --git a/lint/cli/src/test/java/com/android/tools/lint/checks/data/src/test/pkg/StringFormat3.java.txt b/lint/cli/src/test/java/com/android/tools/lint/checks/data/src/test/pkg/StringFormat3.java.txt
new file mode 100644
index 0000000..d1bfe44
--- /dev/null
+++ b/lint/cli/src/test/java/com/android/tools/lint/checks/data/src/test/pkg/StringFormat3.java.txt
@@ -0,0 +1,20 @@
+package test.pkg;
+
+import android.app.Activity;
+
+public class StringFormat3 extends Activity {
+ public final void test(Context context) {
+ String s1 = String.format(Locale.FRANCE,
+ context.getString(R.string.gridview_views_count), article.playsCount);
+ String s2 = String.format(Locale.FRANCE,
+ context.getString(R.string.gridview_views_count), 5);
+ String s3 = String.format(Locale.FRANCE,
+ context.getString(R.string.gridview_views_count), "wrong");
+ String s4 = String.format(context.getString(R.string.gridview_views_count), "wrong");
+ String s5 = String.format(context.getString(R.string.gridview_views_count), 5); // OK
+ String s6 = String.format(Locale.getDefault(),
+ context.getString(R.string.gridview_views_count), 5);
+ String s7 = String.format(null,
+ context.getString(R.string.gridview_views_count), 5);
+ }
+}
diff --git a/lint/libs/lint_checks/src/main/java/com/android/tools/lint/checks/StringFormatDetector.java b/lint/libs/lint_checks/src/main/java/com/android/tools/lint/checks/StringFormatDetector.java
index e8780a1..7bb07f2 100644
--- a/lint/libs/lint_checks/src/main/java/com/android/tools/lint/checks/StringFormatDetector.java
+++ b/lint/libs/lint_checks/src/main/java/com/android/tools/lint/checks/StringFormatDetector.java
@@ -931,13 +931,23 @@ public class StringFormatDetector extends ResourceXmlDetector implements Detecto
return;
}
+ // TODO: Need type information in the AST
+ Iterator<Expression> argIterator = args.iterator();
+ Expression first = argIterator.next();
+ Expression second = argIterator.hasNext() ? argIterator.next() : null;
+ String firstName = first.toString();
+ boolean specifiesLocale = firstName.startsWith("Locale.") //$NON-NLS-1$
+ || firstName.contains("locale") //$NON-NLS-1$
+ || firstName.equals("null") //$NON-NLS-1$
+ || second != null && second.toString().contains("getString"); //$NON-NLS-1$
+
List<Pair<Handle, String>> list = mFormatStrings.get(name);
if (list != null) {
for (Pair<Handle, String> pair : list) {
String s = pair.getSecond();
int count = getFormatArgumentCount(s, null);
Handle handle = pair.getFirst();
- if (count != args.size() - 1) {
+ if (count != args.size() - 1 - (specifiesLocale ? 1 : 0)) {
Location location = context.parser.getLocation(context, call);
Location secondary = handle.resolve();
secondary.setMessage(String.format("This definition requires %1$d arguments",
@@ -950,7 +960,8 @@ public class StringFormatDetector extends ResourceXmlDetector implements Detecto
context.report(ARG_TYPES, method, location, message, null);
} else {
for (int i = 1; i <= count; i++) {
- Class<?> type = tracker.getArgumentType(i);
+ int argumentIndex = i + (specifiesLocale ? 1 : 0);
+ Class<?> type = tracker.getArgumentType(argumentIndex);
if (type != null) {
boolean valid = true;
String formatType = getFormatArgumentType(s, i);
@@ -1006,7 +1017,7 @@ public class StringFormatDetector extends ResourceXmlDetector implements Detecto
if (!valid) {
IJavaParser parser = context.parser;
- Expression argument = tracker.getArgument(i);
+ Expression argument = tracker.getArgument(argumentIndex);
Location location = parser.getLocation(context, argument);
Location secondary = handle.resolve();
secondary.setMessage("Conflicting argument declaration here");