diff options
4 files changed, 78 insertions, 10 deletions
diff --git a/common/src/com/android/SdkConstants.java b/common/src/com/android/SdkConstants.java index 1a8a61c..adbc3c8 100644 --- a/common/src/com/android/SdkConstants.java +++ b/common/src/com/android/SdkConstants.java @@ -681,6 +681,7 @@ public final class SdkConstants { public static final String ATTR_TARGET_SDK_VERSION = "targetSdkVersion"; //$NON-NLS-1$ public static final String ATTR_ICON = "icon"; //$NON-NLS-1$ public static final String ATTR_PACKAGE = "package"; //$NON-NLS-1$ + public static final String ATTR_CORE_APP = "coreApp"; //$NON-NLS-1$ public static final String ATTR_THEME = "theme"; //$NON-NLS-1$ public static final String ATTR_PATH = "path"; //$NON-NLS-1$ public static final String ATTR_PATH_PREFIX = "pathPrefix"; //$NON-NLS-1$ diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/DetectMissingPrefix.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/DetectMissingPrefix.java index e6234f3..6ce22f7 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/DetectMissingPrefix.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/DetectMissingPrefix.java @@ -18,12 +18,22 @@ package com.android.tools.lint.checks; import static com.android.SdkConstants.ANDROID_PKG_PREFIX; import static com.android.SdkConstants.ATTR_CLASS; +import static com.android.SdkConstants.ATTR_CORE_APP; import static com.android.SdkConstants.ATTR_LAYOUT; +import static com.android.SdkConstants.ATTR_PACKAGE; import static com.android.SdkConstants.ATTR_STYLE; import static com.android.SdkConstants.VIEW_TAG; import static com.android.SdkConstants.XMLNS_PREFIX; +import static com.android.resources.ResourceFolderType.ANIM; +import static com.android.resources.ResourceFolderType.ANIMATOR; +import static com.android.resources.ResourceFolderType.COLOR; +import static com.android.resources.ResourceFolderType.DRAWABLE; +import static com.android.resources.ResourceFolderType.INTERPOLATOR; +import static com.android.resources.ResourceFolderType.LAYOUT; +import static com.android.resources.ResourceFolderType.MENU; import com.android.annotations.NonNull; +import com.android.resources.ResourceFolderType; import com.android.tools.lint.detector.api.Category; import com.android.tools.lint.detector.api.Issue; import com.android.tools.lint.detector.api.LayoutDetector; @@ -36,6 +46,7 @@ import org.w3c.dom.Attr; import org.w3c.dom.Element; import java.util.Collection; +import java.util.EnumSet; import java.util.HashSet; import java.util.Set; @@ -51,19 +62,26 @@ public class DetectMissingPrefix extends LayoutDetector { "Detect XML attributes not using the Android namespace", "Most Android views have attributes in the Android namespace. When referencing " + "these attributes you *must* include the namespace prefix, or your attribute will " + - "be interpreted by aapt as just a custom attribute.", + "be interpreted by `aapt` as just a custom attribute.\n" + + "\n" + + "Similarly, in manifest files, nearly all attributes should be in the `android:` " + + "namespace.", Category.CORRECTNESS, - 8, - Severity.WARNING, + 6, + Severity.ERROR, DetectMissingPrefix.class, - Scope.RESOURCE_FILE_SCOPE); + EnumSet.of(Scope.MANIFEST, Scope.RESOURCE_FILE)) + .addAnalysisScope(Scope.MANIFEST_SCOPE) + .addAnalysisScope(Scope.RESOURCE_FILE_SCOPE); private static final Set<String> NO_PREFIX_ATTRS = new HashSet<String>(); static { NO_PREFIX_ATTRS.add(ATTR_CLASS); NO_PREFIX_ATTRS.add(ATTR_STYLE); NO_PREFIX_ATTRS.add(ATTR_LAYOUT); + NO_PREFIX_ATTRS.add(ATTR_PACKAGE); + NO_PREFIX_ATTRS.add(ATTR_CORE_APP); } /** Constructs a new {@link DetectMissingPrefix} */ @@ -71,6 +89,17 @@ public class DetectMissingPrefix extends LayoutDetector { } @Override + public boolean appliesTo(@NonNull ResourceFolderType folderType) { + return folderType == LAYOUT + || folderType == MENU + || folderType == DRAWABLE + || folderType == ANIM + || folderType == ANIMATOR + || folderType == COLOR + || folderType == INTERPOLATOR; + } + + @Override public @NonNull Speed getSpeed() { return Speed.FAST; } @@ -93,7 +122,7 @@ public class DetectMissingPrefix extends LayoutDetector { } Element element = attribute.getOwnerElement(); - if (isCustomView(element)) { + if (isCustomView(element) && context.getResourceFolderType() != null) { return; } diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/DetectMissingPrefixTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/DetectMissingPrefixTest.java index 8a4f6b0..944fe4f 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/DetectMissingPrefixTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/DetectMissingPrefixTest.java @@ -27,13 +27,13 @@ public class DetectMissingPrefixTest extends AbstractCheckTest { public void test() throws Exception { assertEquals( - "res/layout/namespace.xml:2: Warning: Attribute is missing the Android namespace prefix [MissingPrefix]\n" + + "res/layout/namespace.xml:2: Error: Attribute is missing the Android namespace prefix [MissingPrefix]\n" + "<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\" orientation=\"true\">\n" + " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + - "res/layout/namespace.xml:3: Warning: Attribute is missing the Android namespace prefix [MissingPrefix]\n" + + "res/layout/namespace.xml:3: Error: Attribute is missing the Android namespace prefix [MissingPrefix]\n" + " <Button style=\"@style/setupWizardOuterFrame\" android.text=\"Button\" android:id=\"@+id/button1\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\"></Button>\n" + " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + - "0 errors, 2 warnings\n" + + "2 errors, 0 warnings\n" + "", lintFiles("res/layout/namespace.xml")); @@ -41,13 +41,28 @@ public class DetectMissingPrefixTest extends AbstractCheckTest { public void testCustomNamespace() throws Exception { assertEquals( - "res/layout/namespace2.xml:8: Warning: Attribute is missing the Android namespace prefix [MissingPrefix]\n" + + "res/layout/namespace2.xml:8: Error: Attribute is missing the Android namespace prefix [MissingPrefix]\n" + " customprefix:orientation=\"vertical\"\n" + " ~~~~~~~~~~~~~~~~~~~~~~\n" + - "0 errors, 1 warnings\n" + + "1 errors, 0 warnings\n" + "", lintFiles("res/layout/namespace2.xml")); } + public void testManifest() throws Exception { + assertEquals( + "AndroidManifest.xml:4: Error: Attribute is missing the Android namespace prefix [MissingPrefix]\n" + + " versionCode=\"1\"\n" + + " ~~~~~~~~~~~~~~~\n" + + "AndroidManifest.xml:11: Error: Attribute is missing the Android namespace prefix [MissingPrefix]\n" + + " android.label=\"@string/app_name\" >\n" + + " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + + "AndroidManifest.xml:18: Error: Attribute is missing the Android namespace prefix [MissingPrefix]\n" + + " <category name=\"android.intent.category.LAUNCHER\" />\n" + + " ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" + + "3 errors, 0 warnings\n", + + lintFiles("missingprefix.xml=>AndroidManifest.xml")); + } } diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/missingprefix.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/missingprefix.xml new file mode 100644 index 0000000..2bb6824 --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/missingprefix.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="foo.bar2" + versionCode="1" + android:versionName="1.0" > + + <uses-sdk android:minSdkVersion="14" /> + + <application + android:icon="@drawable/ic_launcher" + android.label="@string/app_name" > + <activity + android:label="@string/app_name" + android:name=".Foo2Activity" > + <intent-filter > + <action android:name="android.intent.action.MAIN" /> + + <category name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> + +</manifest> |