diff options
Diffstat (limited to 'lint')
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"); |