aboutsummaryrefslogtreecommitdiffstats
path: root/lint/libs
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2012-11-26 12:02:32 -0800
committerTor Norbye <tnorbye@google.com>2012-11-28 15:38:39 -0800
commitf9fc58b23f66470ec01054cd07c50146f8ac8dce (patch)
tree5ac73807aac6a7279d16197d8f56afcf6fdd07e7 /lint/libs
parent67d9a2817d520e178143d3ee97f55ef823766638 (diff)
downloadsdk-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')
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/IconDetector.java2
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/TranslationDetector.java39
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/TypoDetector.java21
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/AccessibilityDetectorTest.java2
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TranslationDetectorTest.java20
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TypoDetectorTest.java13
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/accessibility.xml5
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/accessibility2.xml12
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values-es/strings_locale.xml20
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/values-nb/typos_locale.xml8
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