diff options
author | Tor Norbye <tnorbye@google.com> | 2012-02-17 19:58:46 -0800 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2012-02-21 09:01:51 -0800 |
commit | a241a4dd5605b0986d63a973cd367e22c3083507 (patch) | |
tree | 4cc3854ecb6a5d939bf7912aa8b70ed98ada487a /lint | |
parent | 556b907792f0658a6c3f676e23469b83175e3431 (diff) | |
download | sdk-a241a4dd5605b0986d63a973cd367e22c3083507.tar.gz sdk-a241a4dd5605b0986d63a973cd367e22c3083507.tar.bz2 sdk-a241a4dd5605b0986d63a973cd367e22c3083507.zip |
Make API detector in XML files consider folder version
Take the folder version into account when checking the API level in
XML files. For example, even if minSdkVersion=5, it's okay to have a
<GridLayout> element in a layout if that layout is in a layout-v14 (or
higher) folder.
Change-Id: Idbd3647c1145e4b3d03f90626339ef7e6b10c827
Diffstat (limited to 'lint')
4 files changed, 55 insertions, 20 deletions
diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/XmlContext.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/XmlContext.java index a9de278b7..7733dc76a 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/XmlContext.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/XmlContext.java @@ -27,6 +27,8 @@ import org.w3c.dom.Document; import org.w3c.dom.Node; import java.io.File; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * A {@link Context} used when checking XML files. @@ -132,4 +134,25 @@ public class XmlContext extends Context { public ResourceFolderType getResourceFolderType() { return mFolderType; } + + + private final static Pattern sVersionPattern = Pattern.compile("^v(\\d+)$");//$NON-NLS-1$ + + /** + * Returns the folder version. For example, for the file values-v14/foo.xml, + * it returns 14. + * + * @return the folder version, or -1 if no specific version was specified + */ + public int getFolderVersion() { + String[] qualifiers = file.getParentFile().getName().split("-"); //$NON-NLS-1$ + for (String qualifier : qualifiers) { + Matcher matcher = sVersionPattern.matcher(qualifier); + if (matcher.matches()) { + return Integer.parseInt(matcher.group(1)); + } + } + + return -1; + } } diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiDetector.java index b0a3d6f71..7299fccc7 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiDetector.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiDetector.java @@ -141,7 +141,7 @@ public class ApiDetector extends ResourceXmlDetector implements Detector.ClassSc String name = value.substring(index + 1); int api = mApiDatabase.getFieldVersion(owner, name); int minSdk = getMinSdk(context); - if (api > minSdk) { + if (api > minSdk && api > context.getFolderVersion()) { Location location = context.getLocation(attribute); String message = String.format( "%1$s requires API level %2$d (current min is %3$d)", @@ -181,7 +181,7 @@ public class ApiDetector extends ResourceXmlDetector implements Detector.ClassSc String name = text.substring(index + 1); int api = mApiDatabase.getFieldVersion(owner, name); int minSdk = getMinSdk(context); - if (api > minSdk) { + if (api > minSdk && api > context.getFolderVersion()) { Location location = context.getLocation(textNode); String message = String.format( "%1$s requires API level %2$d (current min is %3$d)", @@ -207,7 +207,7 @@ public class ApiDetector extends ResourceXmlDetector implements Detector.ClassSc // "(Landroid/content/Context;Landroid/util/AttributeSet;I)V"); //$NON-NLS-1$ "(Landroid/content/Context;)"); //$NON-NLS-1$ int minSdk = getMinSdk(context); - if (api > minSdk) { + if (api > minSdk && api > context.getFolderVersion()) { Location location = context.getLocation(element); String message = String.format( "View requires API level %1$d (current min is %2$d): <%3$s>", diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ButtonDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ButtonDetector.java index 4adf60a1a..932156157 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ButtonDetector.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ButtonDetector.java @@ -62,8 +62,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * Check which looks at the order of buttons in dialogs and makes sure that @@ -78,8 +76,6 @@ import java.util.regex.Pattern; * Cancel/OK dialogs? Similarly, consider "Abort" a synonym for "Cancel" ? */ public class ButtonDetector extends ResourceXmlDetector { - private final static Pattern sVersionPattern = Pattern.compile("^v(\\d+)$");//$NON-NLS-1$ - /** Name of cancel value ("Cancel") */ private static final String CANCEL_LABEL = "Cancel"; /** Name of OK value ("Cancel") */ @@ -425,19 +421,7 @@ public class ButtonDetector extends ResourceXmlDetector { // // Therefore, we need to know if this layout is an ICS layout or // a pre-ICS layout. - String[] qualifiers = context.file.getParentFile().getName().split("-"); //$NON-NLS-1$ - boolean isIcsLayout = false; - for (String qualifier : qualifiers) { - Matcher matcher = sVersionPattern.matcher(qualifier); - if (matcher.matches()) { - int api = Integer.parseInt(matcher.group(1)); - if (api >= 14) { - isIcsLayout = true; - break; - } - } - } - + boolean isIcsLayout = context.getFolderVersion() >= 14; if (!isIcsLayout) { // This layout is not an ICS layout. However, there *must* also be // an ICS layout here, or this button order will be wrong: diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiDetectorTest.java index 02e714a85..797059ce3 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiDetectorTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiDetectorTest.java @@ -55,6 +55,34 @@ public class ApiDetectorTest extends AbstractCheckTest { )); } + public void testXmlApiFolderVersion11() throws Exception { + assertEquals( + "colors.xml:9: Error: @android:color/holo_red_light requires API level 14 (current min is 1)\n" + + "layout.xml:21: Error: View requires API level 14 (current min is 1): <GridLayout>\n" + + "layout.xml:22: Error: @android:attr/actionBarSplitStyle requires API level 14 (current min is 1)\n" + + "layout.xml:23: Error: @android:color/holo_red_light requires API level 14 (current min is 1)\n" + + "themes.xml:9: Error: @android:color/holo_red_light requires API level 14 (current min is 1)", + + lintProject( + "apicheck/minsdk1.xml=>AndroidManifest.xml", + "apicheck/layout.xml=>res/layout-v11/layout.xml", + "apicheck/themes.xml=>res/values-v11/themes.xml", + "apicheck/themes.xml=>res/color-v11/colors.xml" + )); + } + + public void testXmlApiFolderVersion14() throws Exception { + assertEquals( + "No warnings.", + + lintProject( + "apicheck/minsdk1.xml=>AndroidManifest.xml", + "apicheck/layout.xml=>res/layout-v14/layout.xml", + "apicheck/themes.xml=>res/values-v14/themes.xml", + "apicheck/themes.xml=>res/color-v14/colors.xml" + )); + } + public void testApi1() throws Exception { assertEquals( "ApiCallTest.java:20: Error: Call requires API level 11 (current min is 1): android.app.Activity#getActionBar\n" + |