diff options
author | Tor Norbye <tnorbye@google.com> | 2012-11-26 12:02:32 -0800 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2012-11-28 15:38:39 -0800 |
commit | f9fc58b23f66470ec01054cd07c50146f8ac8dce (patch) | |
tree | 5ac73807aac6a7279d16197d8f56afcf6fdd07e7 /lint/libs | |
parent | 67d9a2817d520e178143d3ee97f55ef823766638 (diff) | |
download | sdk-f9fc58b23f66470ec01054cd07c50146f8ac8dce.zip sdk-f9fc58b23f66470ec01054cd07c50146f8ac8dce.tar.gz sdk-f9fc58b23f66470ec01054cd07c50146f8ac8dce.tar.bz2 |
Add support for specifying default language in res/values
This changeset adds support for a tools:locale attribute in
resource files where you can declare which language is actually
the default. This is used both by the missing translation
detector (such that it won't complain if for example values-en-rUS
is intended to supplement res/values/), as well as the typo
detector (to allow you to specify which language's dictionary
should be used to look for typos in the default resource file.)
This addresses 33845: lint is wrong about translation regions
Change-Id: Icb16cf11407c333845b56b6d105c99a8661430b0
Diffstat (limited to 'lint/libs')
10 files changed, 131 insertions, 11 deletions
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/IconDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/IconDetector.java index f435810..011c291 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/IconDetector.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/IconDetector.java @@ -1222,7 +1222,7 @@ public class IconDetector extends ResourceXmlDetector implements Detector.JavaSc // Look up launcher icon name for (File file : files) { String name = file.getName(); - if (isLauncherIcon(name) + if (isLauncherIcon(getBaseName(name)) && !endsWith(name, DOT_XML) && !endsWith(name, DOT_9PNG)) { checkLauncherShape(context, file); diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TranslationDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TranslationDetector.java index eecb0c7..6b63ffc 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TranslationDetector.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TranslationDetector.java @@ -17,12 +17,14 @@ package com.android.tools.lint.checks; import static com.android.SdkConstants.ANDROID_PREFIX; +import static com.android.SdkConstants.ATTR_LOCALE; import static com.android.SdkConstants.ATTR_NAME; import static com.android.SdkConstants.ATTR_TRANSLATABLE; import static com.android.SdkConstants.STRING_PREFIX; import static com.android.SdkConstants.TAG_ITEM; import static com.android.SdkConstants.TAG_STRING; import static com.android.SdkConstants.TAG_STRING_ARRAY; +import static com.android.SdkConstants.TOOLS_URI; import com.android.annotations.NonNull; import com.android.annotations.VisibleForTesting; @@ -36,6 +38,7 @@ import com.android.tools.lint.detector.api.ResourceXmlDetector; import com.android.tools.lint.detector.api.Scope; import com.android.tools.lint.detector.api.Severity; import com.android.tools.lint.detector.api.XmlContext; +import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.w3c.dom.Attr; @@ -83,7 +86,12 @@ public class TranslationDetector extends ResourceXmlDetector { "By default this detector allows regions of a language to just provide a " + "subset of the strings and fall back to the standard language strings. " + "You can require all regions to provide a full translation by setting the " + - "environment variable `ANDROID_LINT_COMPLETE_REGIONS`.", + "environment variable `ANDROID_LINT_COMPLETE_REGIONS`.\n" + + "\n" + + "You can tell lint (and other tools) which language is the default language " + + "in your `res/values/` folder by specifying `tools:locale=\"languageCode\"` for " + + "the root `<resources>` element in your resource file. (The `tools` prefix refers " + + "to the namespace declaration `http://schemas.android.com/tools`.)", Category.MESSAGES, 8, Severity.FATAL, @@ -112,6 +120,7 @@ public class TranslationDetector extends ResourceXmlDetector { private Set<String> mNonTranslatable; private boolean mIgnoreFile; private Map<File, Set<String>> mFileToNames; + private Map<File, String> mFileToLocale; /** Locations for each untranslated string name. Populated during phase 2, if necessary */ private Map<String, Location> mMissingLocations; @@ -164,8 +173,19 @@ public class TranslationDetector extends ResourceXmlDetector { public void afterCheckFile(@NonNull Context context) { if (context.getPhase() == 1) { // Store this layout's set of ids for full project analysis in afterCheckProject - if (context.getProject().getReportIssues()) { + if (context.getProject().getReportIssues() && mNames != null) { mFileToNames.put(context.file, mNames); + + Element root = ((XmlContext) context).document.getDocumentElement(); + if (root != null) { + String locale = root.getAttributeNS(TOOLS_URI, ATTR_LOCALE); + if (locale != null && !locale.isEmpty()) { + if (mFileToLocale == null) { + mFileToLocale = Maps.newHashMap(); + } + mFileToLocale.put(context.file, locale); + } + } } mNames = null; @@ -258,7 +278,20 @@ public class TranslationDetector extends ResourceXmlDetector { new HashMap<String, Set<String>>(languageCount); Set<String> allStrings = new HashSet<String>(200); for (File file : files) { - String language = parentFolderToLanguage.get(file.getParentFile()); + String language = null; + if (mFileToLocale != null) { + String locale = mFileToLocale.get(file); + if (locale != null) { + int index = locale.indexOf('-'); + if (index != -1) { + locale = locale.substring(0, index); + } + language = locale; + } + } + if (language == null) { + language = parentFolderToLanguage.get(file.getParentFile()); + } assert language != null : file.getParent(); Set<String> fileStrings = mFileToNames.get(file); diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypoDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypoDetector.java index 7a38d97..d0cf366 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypoDetector.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypoDetector.java @@ -16,7 +16,10 @@ package com.android.tools.lint.checks; +import static com.android.SdkConstants.ATTR_LOCALE; +import static com.android.SdkConstants.FD_RES_VALUES; import static com.android.SdkConstants.TAG_STRING; +import static com.android.SdkConstants.TOOLS_URI; import static com.android.tools.lint.checks.TypoLookup.isLetter; import static com.google.common.base.Objects.equal; @@ -110,7 +113,7 @@ public class TypoDetector extends ResourceXmlDetector { mLanguage = null; mRegion = null; - if (parent.equals("values")) { //$NON-NLS-1$ + if (parent.equals(FD_RES_VALUES)) { return; } @@ -137,7 +140,21 @@ public class TypoDetector extends ResourceXmlDetector { public void beforeCheckFile(@NonNull Context context) { initLocale(context.file.getParentFile().getName()); if (mLanguage == null) { - mLanguage = "en"; //$NON-NLS-1$ + // Check to see if the user has specified the language for this folder + // using a tools:locale attribute + if (context instanceof XmlContext) { + Element root = ((XmlContext) context).document.getDocumentElement(); + if (root != null) { + String locale = root.getAttributeNS(TOOLS_URI, ATTR_LOCALE); + if (locale != null && !locale.isEmpty()) { + initLocale(FD_RES_VALUES + '-' + locale); + } + } + } + + if (mLanguage == null) { + mLanguage = "en"; //$NON-NLS-1$ + } } if (!equal(mLastLanguage, mLanguage) || !equal(mLastRegion, mRegion)) { diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AccessibilityDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AccessibilityDetectorTest.java index b78455d..fe24446 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AccessibilityDetectorTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AccessibilityDetectorTest.java @@ -38,6 +38,6 @@ public class AccessibilityDetectorTest extends AbstractCheckTest { " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + "0 errors, 3 warnings\n", - lintProject("res/layout/accessibility.xml")); + lintProject("res/layout/accessibility2.xml=>res/layout/accessibility.xml")); } } diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TranslationDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TranslationDetectorTest.java index f0284fd..7a9830b 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TranslationDetectorTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TranslationDetectorTest.java @@ -189,4 +189,24 @@ public class TranslationDetectorTest extends AbstractCheckTest { lintProject("res/values/nontranslatable.xml=>res/values-nb/nontranslatable.xml")); } + + public void testSpecifiedLanguageOk() throws Exception { + TranslationDetector.COMPLETE_REGIONS = false; + assertEquals( + "No warnings.", + + lintProject( + "res/values-es/strings.xml=>res/values-es/strings.xml", + "res/values-es-rUS/strings.xml")); + } + + public void testSpecifiedLanguage() throws Exception { + TranslationDetector.COMPLETE_REGIONS = false; + assertEquals( + "No warnings.", + + lintProject( + "res/values-es/strings_locale.xml=>res/values/strings.xml", + "res/values-es-rUS/strings.xml")); + } } diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TypoDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TypoDetectorTest.java index 2b266f7..3c49b3a 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TypoDetectorTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TypoDetectorTest.java @@ -139,4 +139,17 @@ public class TypoDetectorTest extends AbstractCheckTest { assertEquals(Arrays.asList("thought", "through", "throughout"), TypoDetector.getSuggestions(s)); } + + public void testNorwegianDefault() throws Exception { + assertEquals( + "res/values/typos.xml:5: Warning: \"altid\" is a common misspelling; did you mean \"alltid\" ? [Typos]\n" + + " <string name=\"s4\"><b>altid</b></string>\n" + + " ^\n" + + "res/values/typos.xml:7: Warning: \"Altid\" is a common misspelling; did you mean \"Alltid\" ? [Typos]\n" + + " <string name=\"s5\">Altid</string>\n" + + " ^\n" + + "0 errors, 2 warnings\n", + + lintProject("res/values-nb/typos_locale.xml=>res/values/typos.xml")); + } } diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/accessibility.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/accessibility.xml index 3f45c26..c00a880 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/accessibility.xml +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/accessibility.xml @@ -1,12 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/newlinear" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/newlinear" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:text="Button" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> <ImageView android:id="@+id/android_logo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" /> <ImageButton android:importantForAccessibility="yes" android:id="@+id/android_logo2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" /> <Button android:text="Button" android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> <Button android:id="@+android:id/summary" android:contentDescription="@string/label" /> <ImageButton android:importantForAccessibility="no" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" /> - <EditText android:hint="@string/label" android:id="@+android:id/summary" android:contentDescription="@string/label" /> - <EditText android:id="@+android:id/summary" android:contentDescription="@string/label" /> - <EditText tools:ignore="ContentDescription" android:hint="@string/label" android:id="@+android:id/summary" android:contentDescription="@string/label" /> </LinearLayout> diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/accessibility2.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/accessibility2.xml new file mode 100644 index 0000000..3f45c26 --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/accessibility2.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/newlinear" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> + <Button android:text="Button" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> + <ImageView android:id="@+id/android_logo" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" /> + <ImageButton android:importantForAccessibility="yes" android:id="@+id/android_logo2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" /> + <Button android:text="Button" android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> + <Button android:id="@+android:id/summary" android:contentDescription="@string/label" /> + <ImageButton android:importantForAccessibility="no" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/android_button" android:focusable="false" android:clickable="false" android:layout_weight="1.0" /> + <EditText android:hint="@string/label" android:id="@+android:id/summary" android:contentDescription="@string/label" /> + <EditText android:id="@+android:id/summary" android:contentDescription="@string/label" /> + <EditText tools:ignore="ContentDescription" android:hint="@string/label" android:id="@+android:id/summary" android:contentDescription="@string/label" /> +</LinearLayout> diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values-es/strings_locale.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values-es/strings_locale.xml new file mode 100644 index 0000000..b485dee --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values-es/strings_locale.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2" + xmlns:tools="http://schemas.android.com/tools" + tools:locale="es"> + <string name="home_title">"Casa"</string> + <string name="show_all_apps">"Todo"</string> + <string name="menu_wallpaper">"Papel tapiz"</string> + <string name="menu_search">"Búsqueda"</string> + <!-- no translation found for menu_settings (1769059051084007158) --> + <skip /> + <string name="wallpaper_instructions">"Puntee en la imagen para establecer papel tapiz vertical"</string> + + <string-array name="security_questions"> + <item>"Comida favorita"</item> + <item>"Ciudad de nacimiento"</item> + <item>"Nombre de tu mejor amigo/a de la infancia"</item> + <item>"Nombre de tu colegio"</item> + </string-array> +</resources> diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values-nb/typos_locale.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values-nb/typos_locale.xml new file mode 100644 index 0000000..ed1edd1 --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values-nb/typos_locale.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources xmlns:tools="http://schemas.android.com/tools" + tools:locale="nb"> + <!-- Markup indirection --> + <string name="s4"><b>altid</b></string> + <!-- Typo, match capitalized --> + <string name="s5">Altid</string> +</resources>
\ No newline at end of file |