From f78bed2794ecbfe7bb1cea2c3f5faf57a88ea2ba Mon Sep 17 00:00:00 2001 From: Tor Norbye Date: Fri, 17 Feb 2012 11:51:48 -0800 Subject: Lint rule to catch edit-usage of TextViews (should be EditText) TextView provides a number of attributes related to text editing. However, these are generally intended for the EditText subclass of EditText. This lint check looks for elements in layouts where one or more of the edit-related attributes (such as inputType) are defined. It also updates the deprecation detector to check various deprecated attributes (it only checked for deprecated elements before this.) Change-Id: I1b94902d906cd0bee6a6564368125a68b3c9bb2a --- .../tools/lint/client/api/DefaultSdkInfo.java | 6 +- .../tools/lint/detector/api/LintConstants.java | 23 ++- .../tools/lint/checks/BuiltinIssueRegistry.java | 3 +- .../tools/lint/checks/DeprecationDetector.java | 89 ++++++++++ .../tools/lint/checks/TextViewDetector.java | 193 +++++++++++++++++++++ .../tools/lint/checks/DeprecationDetectorTest.java | 28 ++- .../tools/lint/checks/TextViewDetectorTest.java | 54 ++++++ .../lint/checks/data/res/layout/deprecation.xml | 12 ++ .../lint/checks/data/res/layout/edit_textview.xml | 83 +++++++++ 9 files changed, 485 insertions(+), 6 deletions(-) create mode 100644 lint/libs/lint_checks/src/com/android/tools/lint/checks/TextViewDetector.java create mode 100644 lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TextViewDetectorTest.java create mode 100644 lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/edit_textview.xml diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultSdkInfo.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultSdkInfo.java index 1c8b74c..930f7a7 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultSdkInfo.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/DefaultSdkInfo.java @@ -22,6 +22,7 @@ import static com.android.tools.lint.detector.api.LintConstants.ABS_SEEK_BAR; import static com.android.tools.lint.detector.api.LintConstants.ABS_SPINNER; import static com.android.tools.lint.detector.api.LintConstants.ADAPTER_VIEW; import static com.android.tools.lint.detector.api.LintConstants.BUTTON; +import static com.android.tools.lint.detector.api.LintConstants.CHECKED_TEXT_VIEW; import static com.android.tools.lint.detector.api.LintConstants.CHECK_BOX; import static com.android.tools.lint.detector.api.LintConstants.COMPOUND_BUTTON; import static com.android.tools.lint.detector.api.LintConstants.EDIT_TEXT; @@ -42,6 +43,7 @@ import static com.android.tools.lint.detector.api.LintConstants.SCROLL_VIEW; import static com.android.tools.lint.detector.api.LintConstants.SEEK_BAR; import static com.android.tools.lint.detector.api.LintConstants.SPINNER; import static com.android.tools.lint.detector.api.LintConstants.SURFACE_VIEW; +import static com.android.tools.lint.detector.api.LintConstants.SWITCH; import static com.android.tools.lint.detector.api.LintConstants.TABLE_LAYOUT; import static com.android.tools.lint.detector.api.LintConstants.TABLE_ROW; import static com.android.tools.lint.detector.api.LintConstants.TAB_HOST; @@ -126,7 +128,7 @@ class DefaultSdkInfo extends SdkInfo { return false; } - private static final int CLASS_COUNT = 57; + private static final int CLASS_COUNT = 59; @NonNull private static final Map PARENTS = new HashMap(CLASS_COUNT); @@ -140,6 +142,7 @@ class DefaultSdkInfo extends SdkInfo { PARENTS.put(VIEW_GROUP, VIEW); PARENTS.put(TEXT_VIEW, VIEW); + PARENTS.put(CHECKED_TEXT_VIEW, TEXT_VIEW); PARENTS.put(RADIO_BUTTON, COMPOUND_BUTTON); PARENTS.put(SPINNER, ABS_SPINNER); PARENTS.put(IMAGE_BUTTON, IMAGE_VIEW); @@ -151,6 +154,7 @@ class DefaultSdkInfo extends SdkInfo { PARENTS.put(BUTTON, TEXT_VIEW); PARENTS.put(SEEK_BAR, ABS_SEEK_BAR); PARENTS.put(CHECK_BOX, COMPOUND_BUTTON); + PARENTS.put(SWITCH, COMPOUND_BUTTON); PARENTS.put(GALLERY, ABS_SPINNER); PARENTS.put(SURFACE_VIEW, VIEW); PARENTS.put(ABSOLUTE_LAYOUT, VIEW_GROUP); diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java index 7d2c35a..b3eb1b7 100644 --- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java +++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/LintConstants.java @@ -78,9 +78,11 @@ public class LintConstants { public static final String TAB_HOST = "TabHost"; //$NON-NLS-1$ public static final String RADIO_GROUP = "RadioGroup"; //$NON-NLS-1$ public static final String RADIO_BUTTON = "RadioButton"; //$NON-NLS-1$ + public static final String SWITCH = "Switch"; //$NON-NLS-1$ public static final String EDIT_TEXT = "EditText"; //$NON-NLS-1$ public static final String LIST_VIEW = "ListView"; //$NON-NLS-1$ public static final String TEXT_VIEW = "TextView"; //$NON-NLS-1$ + public static final String CHECKED_TEXT_VIEW = "CheckedTextView"; //$NON-NLS-1$ public static final String IMAGE_VIEW = "ImageView"; //$NON-NLS-1$ public static final String SURFACE_VIEW = "SurfaceView"; //$NON-NLS-1$ public static final String ABSOLUTE_LAYOUT = "AbsoluteLayout"; //$NON-NLS-1$ @@ -153,8 +155,26 @@ public class LintConstants { public static final String ATTR_LAYOUT = "layout"; //$NON-NLS-1$ public static final String ATTR_ROW_COUNT = "rowCount"; //$NON-NLS-1$ public static final String ATTR_COLUMN_COUNT = "columnCount"; //$NON-NLS-1$ - public static final String ATTR_BASELINE_ALIGNED = "baselineAligned"; //$NON-NLS-1$ + public static final String ATTR_BASELINE_ALIGNED = "baselineAligned"; //$NON-NLS-1$ public static final String ATTR_CONTENT_DESCRIPTION = "contentDescription"; //$NON-NLS-1$ + public static final String ATTR_IME_ACTION_LABEL = "imeActionLabel"; //$NON-NLS-1$ + public static final String ATTR_PRIVATE_IME_OPTIONS = "privateImeOptions"; //$NON-NLS-1$ + public static final String VALUE_NONE = "none"; //$NON-NLS-1$ + public static final String ATTR_NUMERIC = "numeric"; //$NON-NLS-1$ + public static final String ATTR_IME_ACTION_ID = "imeActionId"; //$NON-NLS-1$ + public static final String ATTR_IME_OPTIONS = "imeOptions"; //$NON-NLS-1$ + public static final String ATTR_FREEZES_TEXT = "freezesText"; //$NON-NLS-1$ + public static final String ATTR_EDITOR_EXTRAS = "editorExtras"; //$NON-NLS-1$ + public static final String ATTR_EDITABLE = "editable"; //$NON-NLS-1$ + public static final String ATTR_DIGITS = "digits"; //$NON-NLS-1$ + public static final String ATTR_CURSOR_VISIBLE = "cursorVisible"; //$NON-NLS-1$ + public static final String ATTR_CAPITALIZE = "capitalize"; //$NON-NLS-1$ + public static final String ATTR_PHONE_NUMBER = "phoneNumber"; //$NON-NLS-1$ + public static final String ATTR_PASSWORD = "password"; //$NON-NLS-1$ + public static final String ATTR_BUFFER_TYPE = "bufferType"; //$NON-NLS-1$ + public static final String ATTR_AUTO_TEXT = "autoText"; //$NON-NLS-1$ + public static final String ATTR_ENABLED = "enabled"; //$NON-NLS-1$ + public static final String ATTR_SINGLE_LINE = "singleLine"; //$NON-NLS-1$ // AbsoluteLayout layout params public static final String ATTR_LAYOUT_Y = "layout_y"; //$NON-NLS-1$ @@ -203,6 +223,7 @@ public class LintConstants { public static final String VALUE_MATCH_PARENT = "match_parent"; //$NON-NLS-1$ public static final String VALUE_VERTICAL = "vertical"; //$NON-NLS-1$ public static final String VALUE_TRUE = "true"; //$NON-NLS-1$ + public static final String VALUE_EDITABLE = "editable"; //$NON-NLS-1$ // Values: Resources diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java index cdb4c12..6f8f19b 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/BuiltinIssueRegistry.java @@ -53,7 +53,7 @@ public class BuiltinIssueRegistry extends IssueRegistry { private static final List sIssues; static { - final int initialCapacity = 79; + final int initialCapacity = 80; List issues = new ArrayList(initialCapacity); issues.add(AccessibilityDetector.ISSUE); @@ -92,6 +92,7 @@ public class BuiltinIssueRegistry extends IssueRegistry { issues.add(ProguardDetector.ISSUE); issues.add(PxUsageDetector.ISSUE); issues.add(TextFieldDetector.ISSUE); + issues.add(TextViewDetector.ISSUE); issues.add(UnusedResourceDetector.ISSUE); issues.add(UnusedResourceDetector.ISSUE_IDS); issues.add(ExtraTextDetector.ISSUE); diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/DeprecationDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/DeprecationDetector.java index 883afc7..c60c8e0 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/DeprecationDetector.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/DeprecationDetector.java @@ -17,6 +17,16 @@ package com.android.tools.lint.checks; import static com.android.tools.lint.detector.api.LintConstants.ABSOLUTE_LAYOUT; +import static com.android.tools.lint.detector.api.LintConstants.ANDROID_URI; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_AUTO_TEXT; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_CAPITALIZE; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_EDITABLE; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_ENABLED; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_INPUT_METHOD; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_NUMERIC; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_PASSWORD; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_PHONE_NUMBER; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_SINGLE_LINE; import com.android.tools.lint.detector.api.Category; import com.android.tools.lint.detector.api.Issue; @@ -26,8 +36,10 @@ import com.android.tools.lint.detector.api.Severity; import com.android.tools.lint.detector.api.Speed; import com.android.tools.lint.detector.api.XmlContext; +import org.w3c.dom.Attr; import org.w3c.dom.Element; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -64,8 +76,85 @@ public class DeprecationDetector extends LayoutDetector { } @Override + public Collection getApplicableAttributes() { + return Arrays.asList( + // TODO: fill_parent is deprecated as of API 8. + // We could warn about it, but it will probably be very noisy + // and make people disable the deprecation check; let's focus on + // some older flags for now + //"fill_parent", + + ATTR_EDITABLE, + ATTR_INPUT_METHOD, + ATTR_AUTO_TEXT, + ATTR_CAPITALIZE, + + // This flag is still used a lot and is still properly handled by TextView + // so in the interest of not being too noisy and make people ignore all the + // output, keep quiet about this one -for now-. + //ATTR_SINGLE_LINE, + + ATTR_ENABLED, + ATTR_NUMERIC, + ATTR_PHONE_NUMBER, + ATTR_PASSWORD + + // These attributes are also deprecated; not yet enabled until we + // know the API level to apply the deprecation for: + + // "ignored as of ICS (but deprecated earlier)" + //"fadingEdge", + + // "This attribute is not used by the Android operating system." + //"restoreNeedsApplication", + + // "This will create a non-standard UI appearance, because the search bar UI is + // changing to use only icons for its buttons." + //"searchButtonText", + + ); + } + + @Override public void visitElement(XmlContext context, Element element) { context.report(ISSUE, element, context.getLocation(element), String.format("%1$s is deprecated", element.getTagName()), null); } + + @Override + public void visitAttribute(XmlContext context, Attr attribute) { + if (!ANDROID_URI.equals(attribute.getNamespaceURI())) { + return; + } + + String name = attribute.getLocalName(); + String fix; + int minSdk = 1; + if (name.equals(ATTR_EDITABLE)) { + fix = "Use an to make it editable"; + } else if (name.equals(ATTR_ENABLED)) { + fix = "Use state_enabled instead"; + } else if (name.equals(ATTR_SINGLE_LINE)) { + fix = "Use maxLines=\"1\" instead"; + } else { + assert name.equals(ATTR_INPUT_METHOD) + || name.equals(ATTR_CAPITALIZE) + || name.equals(ATTR_NUMERIC) + || name.equals(ATTR_PHONE_NUMBER) + || name.equals(ATTR_PASSWORD) + || name.equals(ATTR_AUTO_TEXT); + fix = "Use inputType instead"; + // The inputType attribute was introduced in API 3 so don't warn about + // deprecation if targeting older platforms + minSdk = 3; + } + + if (context.getProject().getMinSdk() < minSdk) { + return; + } + + context.report(ISSUE, attribute, context.getLocation(attribute), + String.format("%1$s is deprecated: %2$s", + attribute.getName(), fix), null); + } } diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TextViewDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TextViewDetector.java new file mode 100644 index 0000000..09608b1 --- /dev/null +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TextViewDetector.java @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.tools.lint.checks; + +import static com.android.tools.lint.detector.api.LintConstants.ANDROID_URI; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_AUTO_TEXT; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_BUFFER_TYPE; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_CAPITALIZE; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_CURSOR_VISIBLE; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_DIGITS; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_EDITABLE; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_EDITOR_EXTRAS; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_IME_ACTION_ID; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_IME_ACTION_LABEL; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_IME_OPTIONS; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_INPUT_METHOD; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_INPUT_TYPE; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_NUMERIC; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_PASSWORD; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_PHONE_NUMBER; +import static com.android.tools.lint.detector.api.LintConstants.ATTR_PRIVATE_IME_OPTIONS; +import static com.android.tools.lint.detector.api.LintConstants.BUTTON; +import static com.android.tools.lint.detector.api.LintConstants.CHECKED_TEXT_VIEW; +import static com.android.tools.lint.detector.api.LintConstants.CHECK_BOX; +import static com.android.tools.lint.detector.api.LintConstants.RADIO_BUTTON; +import static com.android.tools.lint.detector.api.LintConstants.SWITCH; +import static com.android.tools.lint.detector.api.LintConstants.TEXT_VIEW; +import static com.android.tools.lint.detector.api.LintConstants.TOGGLE_BUTTON; +import static com.android.tools.lint.detector.api.LintConstants.VALUE_EDITABLE; +import static com.android.tools.lint.detector.api.LintConstants.VALUE_NONE; +import static com.android.tools.lint.detector.api.LintConstants.VALUE_TRUE; + +import com.android.tools.lint.detector.api.Category; +import com.android.tools.lint.detector.api.Issue; +import com.android.tools.lint.detector.api.LayoutDetector; +import com.android.tools.lint.detector.api.Location; +import com.android.tools.lint.detector.api.Scope; +import com.android.tools.lint.detector.api.Severity; +import com.android.tools.lint.detector.api.Speed; +import com.android.tools.lint.detector.api.XmlContext; + +import org.w3c.dom.Attr; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; + +import java.util.Arrays; +import java.util.Collection; + +/** + * Checks for cases where a TextView should probably be an EditText instead + */ +public class TextViewDetector extends LayoutDetector { + /** The main issue discovered by this detector */ + public static final Issue ISSUE = Issue.create( + "TextViewEdits", //$NON-NLS-1$ + "Looks for TextViews being used for input", + + "Using a to input text is generally an error, you should be " + + "using instead. EditText is a subclass of TextView, and some " + + "of the editing support is provided by TextView, so it's possible to set " + + "some input-related properties on a TextView. However, using a TextView " + + "along with input attributes is usually a cut & paste error. To input " + + "text you should be using ." + + "\n" + + "This check also checks subclasses of TextView, such as Button and CheckBox, " + + "since these have the same issue: they should not be used with editable " + + "attributes.", + + Category.CORRECTNESS, + 7, + Severity.WARNING, + TextViewDetector.class, + Scope.RESOURCE_FILE_SCOPE); + + /** Constructs a new {@link TextViewDetector} */ + public TextViewDetector() { + } + + @Override + public Speed getSpeed() { + return Speed.FAST; + } + + @Override + public Collection getApplicableElements() { + return Arrays.asList( + TEXT_VIEW, + BUTTON, + TOGGLE_BUTTON, + CHECK_BOX, + RADIO_BUTTON, + CHECKED_TEXT_VIEW, + SWITCH + ); + } + + @Override + public void visitElement(XmlContext context, Element element) { + NamedNodeMap attributes = element.getAttributes(); + for (int i = 0, n = attributes.getLength(); i < n; i++) { + Attr attribute = (Attr) attributes.item(i); + String name = attribute.getLocalName(); + if (name == null) { + // Attribute not in a namespace; we only care about the android: ones + continue; + } + + boolean isEditAttribute = false; + switch (name.charAt(0)) { + case 'a': { + isEditAttribute = name.equals(ATTR_AUTO_TEXT); + break; + } + case 'b': { + isEditAttribute = name.equals(ATTR_BUFFER_TYPE) && + attribute.getValue().equals(VALUE_EDITABLE); + break; + } + case 'p': { + isEditAttribute = name.equals(ATTR_PASSWORD) + || name.equals(ATTR_PHONE_NUMBER) + || name.equals(ATTR_PRIVATE_IME_OPTIONS); + break; + } + case 'c': { + isEditAttribute = name.equals(ATTR_CAPITALIZE) + || name.equals(ATTR_CURSOR_VISIBLE); + break; + } + case 'd': { + isEditAttribute = name.equals(ATTR_DIGITS); + break; + } + case 'e': { + if (name.equals(ATTR_EDITABLE)) { + isEditAttribute = attribute.getValue().equals(VALUE_TRUE); + } else { + isEditAttribute = name.equals(ATTR_EDITOR_EXTRAS); + } + break; + } + case 'i': { + if (name.equals(ATTR_INPUT_TYPE)) { + String value = attribute.getValue(); + isEditAttribute = !value.isEmpty() && !value.equals(VALUE_NONE); + } else { + isEditAttribute = name.equals(ATTR_INPUT_TYPE) + || name.equals(ATTR_IME_OPTIONS) + || name.equals(ATTR_IME_ACTION_LABEL) + || name.equals(ATTR_IME_ACTION_ID) + || name.equals(ATTR_INPUT_METHOD); + } + break; + } + case 'n': { + isEditAttribute = name.equals(ATTR_NUMERIC); + break; + } + } + + if (isEditAttribute && ANDROID_URI.equals(attribute.getNamespaceURI())) { + Location location = context.getLocation(attribute); + String message; + String view = element.getTagName(); + if (view.equals(TEXT_VIEW)) { + message = String.format( + "Attribute %1$s should not be used with : " + + "Change element type to ?", attribute.getName()); + } else { + message = String.format( + "Attribute %1$s should not be used with <%2$s>: " + + "intended for editable text widgets", + attribute.getName(), view); + } + context.report(ISSUE, attribute, location, message, null); + } + } + } +} diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/DeprecationDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/DeprecationDetectorTest.java index b0adceb..88c5f60 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/DeprecationDetectorTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/DeprecationDetectorTest.java @@ -25,9 +25,31 @@ public class DeprecationDetectorTest extends AbstractCheckTest { return new DeprecationDetector(); } - public void testAbsoluteLayout() throws Exception { + public void testApi1() throws Exception { assertEquals( - "deprecation.xml:2: Warning: AbsoluteLayout is deprecated", - lintProject("res/layout/deprecation.xml")); + "deprecation.xml:18: Warning: android:editable is deprecated: Use an to make it editable\n" + + "deprecation.xml:19: Warning: android:enabled is deprecated: Use state_enabled instead\n" + + "deprecation.xml:2: Warning: AbsoluteLayout is deprecated", + + lintProject( + "apicheck/minsdk1.xml=>AndroidManifest.xml", + "res/layout/deprecation.xml")); + } + + public void testApi4() throws Exception { + assertEquals( + "deprecation.xml:16: Warning: android:autoText is deprecated: Use inputType instead\n" + + "deprecation.xml:17: Warning: android:capitalize is deprecated: Use inputType instead\n" + + "deprecation.xml:18: Warning: android:editable is deprecated: Use an to make it editable\n" + + "deprecation.xml:19: Warning: android:enabled is deprecated: Use state_enabled instead\n" + + "deprecation.xml:20: Warning: android:inputMethod is deprecated: Use inputType instead\n" + + "deprecation.xml:21: Warning: android:numeric is deprecated: Use inputType instead\n" + + "deprecation.xml:22: Warning: android:password is deprecated: Use inputType instead\n" + + "deprecation.xml:23: Warning: android:phoneNumber is deprecated: Use inputType instead\n" + + "deprecation.xml:2: Warning: AbsoluteLayout is deprecated", + + lintProject( + "apicheck/minsdk4.xml=>AndroidManifest.xml", + "res/layout/deprecation.xml")); } } diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TextViewDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TextViewDetectorTest.java new file mode 100644 index 0000000..a0bbb50 --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/TextViewDetectorTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.tools.lint.checks; + +import com.android.tools.lint.detector.api.Detector; + +@SuppressWarnings("javadoc") +public class TextViewDetectorTest extends AbstractCheckTest { + @Override + protected Detector getDetector() { + return new TextViewDetector(); + } + + public void test() throws Exception { + assertEquals( + "edit_textview.xml:13: Warning: Attribute android:autoText should not be used with : Change element type to ?\n" + + "edit_textview.xml:14: Warning: Attribute android:bufferType should not be used with : Change element type to ?\n" + + "edit_textview.xml:15: Warning: Attribute android:capitalize should not be used with : Change element type to ?\n" + + "edit_textview.xml:16: Warning: Attribute android:cursorVisible should not be used with : Change element type to ?\n" + + "edit_textview.xml:17: Warning: Attribute android:digits should not be used with : Change element type to ?\n" + + "edit_textview.xml:18: Warning: Attribute android:editable should not be used with : Change element type to ?\n" + + "edit_textview.xml:19: Warning: Attribute android:editorExtras should not be used with : Change element type to ?\n" + + "edit_textview.xml:22: Warning: Attribute android:imeActionId should not be used with : Change element type to ?\n" + + "edit_textview.xml:23: Warning: Attribute android:imeActionLabel should not be used with : Change element type to ?\n" + + "edit_textview.xml:24: Warning: Attribute android:imeOptions should not be used with : Change element type to ?\n" + + "edit_textview.xml:25: Warning: Attribute android:inputMethod should not be used with : Change element type to ?\n" + + "edit_textview.xml:26: Warning: Attribute android:inputType should not be used with : Change element type to ?\n" + + "edit_textview.xml:27: Warning: Attribute android:numeric should not be used with : Change element type to ?\n" + + "edit_textview.xml:28: Warning: Attribute android:password should not be used with : Change element type to ?\n" + + "edit_textview.xml:29: Warning: Attribute android:phoneNumber should not be used with : Change element type to ?\n" + + "edit_textview.xml:30: Warning: Attribute android:privateImeOptions should not be used with : Change element type to ?\n" + + "edit_textview.xml:38: Warning: Attribute android:cursorVisible should not be used with