diff options
author | Tor Norbye <tnorbye@google.com> | 2012-03-06 17:50:42 -0800 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2012-03-06 17:50:42 -0800 |
commit | 9a654c3e45ec87e29d0644ab6fb3c830fa73e5ba (patch) | |
tree | b144195ee457671ec3b9d077b11bc9a4d530c462 /lint/libs | |
parent | cd3617b0c4d32a23f0dbe71cfaed40fdba5f9865 (diff) | |
download | sdk-9a654c3e45ec87e29d0644ab6fb3c830fa73e5ba.zip sdk-9a654c3e45ec87e29d0644ab6fb3c830fa73e5ba.tar.gz sdk-9a654c3e45ec87e29d0644ab6fb3c830fa73e5ba.tar.bz2 |
Misc Lint Fixes
This changeset contains fixes for several unrelated reported lint
bugs:
26505: Default disabled rules that are explicitly enabled do not
activate
26467: Lint says ByteBuffer.array is API 9+ but it's really API 1+
26501: Warning "This tag and its children can be replaced by one
<TextView/> and a compound drawable" is not always correct
(Partially fixed)
It also fixes the following bugs:
- The quickfix for the typography detector did not work for the
fraction warning (replacing 1/2 with the half unicode symbol etc)
- A couple of XML detectors did not check for SuppressLint on the
associated root node
- Add a --exitcode flag, and only set the exit code to non-zero if
that flag is specified. Also fix the code such that non-fatal errors
also contribute to the exit code.
- Make the HTML reporter classes public to help Maven integration.
Change-Id: I60f5fdcb2a465d51fa58bb918a195b373096d54b
Diffstat (limited to 'lint/libs')
8 files changed, 117 insertions, 15 deletions
diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiClass.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiClass.java index 7223670..8c35b74 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiClass.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiClass.java @@ -172,6 +172,17 @@ public class ApiClass { } public void addMethod(String name, int since) { + // Strip off the method type at the end to ensure that the code which + // produces inherited methods doesn't get confused and end up multiple entries. + // For example, java/nio/Buffer has the method "array()Ljava/lang/Object;", + // and the subclass java/nio/ByteBuffer has the method "array()[B". We want + // the lookup on mMethods to associate the ByteBuffer array method to be + // considered overriding the Buffer method. + int index = name.indexOf(')'); + if (index != -1) { + name = name.substring(0, index + 1); + } + Integer i = mMethods.get(name); if (i == null || i.intValue() > since) { mMethods.put(name, Integer.valueOf(since)); @@ -204,23 +215,47 @@ public class ApiClass { } /** - * Returns the set of all members (method and fields), including inherited + * Returns the set of all methods, including inherited * ones. * * @param info the api to look up super classes from - * @return a set containing all the members (methods and fields) + * @return a set containing all the members fields */ - public Set<String> getAllMembers(Api info) { + public Set<String> getAllMethods(Api info) { Set<String> members = new HashSet<String>(100); - addAllMembers(info, members); + addAllMethods(info, members); return members; } - private void addAllMembers(Api info, Set<String> set) { + private void addAllMethods(Api info, Set<String> set) { for (String method : mMethods.keySet()) { set.add(method); } + for (Pair<String, Integer> superClass : mSuperClasses) { + ApiClass clz = info.getClass(superClass.getFirst()); + assert clz != null : superClass.getSecond(); + if (clz != null) { + clz.addAllMethods(info, set); + } + } + } + + /** + * Returns the set of all fields, including inherited + * ones. + * + * @param info the api to look up super classes from + * @return a set containing all the fields + */ + public Set<String> getAllFields(Api info) { + Set<String> members = new HashSet<String>(100); + addAllFields(info, members); + + return members; + } + + private void addAllFields(Api info, Set<String> set) { for (String field : mFields.keySet()) { set.add(field); } @@ -228,8 +263,9 @@ public class ApiClass { ApiClass clz = info.getClass(superClass.getFirst()); assert clz != null : superClass.getSecond(); if (clz != null) { - clz.addAllMembers(info, set); + clz.addAllFields(info, set); } } } + } diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiLookup.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiLookup.java index 5f9a1e3..306e6a2 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiLookup.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiLookup.java @@ -73,7 +73,7 @@ public class ApiLookup { /** Relative path to the api-versions.xml database file within the Lint installation */ private static final String XML_FILE_PATH = "platform-tools/api/api-versions.xml"; //$NON-NLS-1$ private static final String FILE_HEADER = "API database used by Android lint\000"; - private static final int BINARY_FORMAT_VERSION = 1; + private static final int BINARY_FORMAT_VERSION = 2; private static final boolean DEBUG_FORCE_REGENERATE_BINARY = false; private static final boolean DEBUG_SEARCH = false; private static final boolean WRITE_STATS = false; @@ -336,7 +336,8 @@ public class ApiLookup { String className = entry.getKey(); ApiClass apiClass = entry.getValue(); - Set<String> allMembers = apiClass.getAllMembers(info); + Set<String> allMethods = apiClass.getAllMethods(info); + Set<String> allFields = apiClass.getAllFields(info); // Strip out all members that have been supported since version 1. // This makes the database *much* leaner (down from about 4M to about @@ -345,14 +346,27 @@ public class ApiLookup { // requires a version *higher* than the minimum. If in the future the // database needs to answer queries about whether a method is public // or not, then we'd need to put this data back in. - List<String> members = new ArrayList<String>(allMembers.size()); - for (String member : allMembers) { - Integer since; - if (member.indexOf('(') != -1) { - since = apiClass.getMethod(member, info); - } else { - since = apiClass.getField(member, info); + List<String> members = new ArrayList<String>(allMethods.size() + allFields.size()); + for (String member : allMethods) { + Integer since = apiClass.getMethod(member, info); + assert since != null : className + ':' + member; + if (since == null) { + since = 1; + } + if (since != 1) { + members.add(member); } + } + + // Strip out all members that have been supported since version 1. + // This makes the database *much* leaner (down from about 4M to about + // 1.7M), and this just fills the table with entries that ultimately + // don't help the API checker since it just needs to know if something + // requires a version *higher* than the minimum. If in the future the + // database needs to answer queries about whether a method is public + // or not, then we'd need to put this data back in. + for (String member : allFields) { + Integer since = apiClass.getField(member, info); assert since != null : className + ':' + member; if (since == null) { since = 1; diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/InefficientWeightDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/InefficientWeightDetector.java index 4dd7eb1..dc65f26 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/InefficientWeightDetector.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/InefficientWeightDetector.java @@ -157,6 +157,7 @@ public class InefficientWeightDetector extends LayoutDetector { } if (allChildrenAreLayouts) { context.report(BASELINE_WEIGHTS, + element, context.getLocation(element), "Set android:baselineAligned=\"false\" on this element for better performance", null); @@ -178,6 +179,7 @@ public class InefficientWeightDetector extends LayoutDetector { "Use a %1$s of 0dip instead of %2$s for better performance", dimension, size); context.report(INEFFICIENT_WEIGHT, + element, context.getLocation(sizeNode != null ? sizeNode : weightChild), msg, null); } diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypographyDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypographyDetector.java index bda828d..c5a9302 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypographyDetector.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/TypographyDetector.java @@ -178,6 +178,9 @@ public class TypographyDetector extends ResourceXmlDetector { private static final String FRACTION_MESSAGE = "Use fraction character %1$c (%2$s) instead of %3$s ?"; + private static final String FRACTION_MESSAGE_PATTERN = + "Use fraction character (.+) \\((.+)\\) instead of (.+) \\?"; + private boolean mCheckDashes; private boolean mCheckQuotes; private boolean mCheckFractions; @@ -477,6 +480,17 @@ public class TypographyDetector extends ResourceXmlDetector { edits.add(new ReplaceEdit(endOffset, 1, "\u2019")); //$NON-NLS-1$ } } + } else { + Matcher matcher = Pattern.compile(FRACTION_MESSAGE_PATTERN).matcher(message); + if (matcher.find()) { + // "Use fraction character %1$c (%2$s) instead of %3$s ?"; + String replace = matcher.group(3); + int offset = text.indexOf(replace); + if (offset != -1) { + String replaceWith = matcher.group(2); + edits.add(new ReplaceEdit(offset, replace.length(), replaceWith)); + } + } } return edits; diff --git a/lint/libs/lint_checks/src/com/android/tools/lint/checks/UseCompoundDrawableDetector.java b/lint/libs/lint_checks/src/com/android/tools/lint/checks/UseCompoundDrawableDetector.java index 8ded0e6..540a0f1 100644 --- a/lint/libs/lint_checks/src/com/android/tools/lint/checks/UseCompoundDrawableDetector.java +++ b/lint/libs/lint_checks/src/com/android/tools/lint/checks/UseCompoundDrawableDetector.java @@ -17,6 +17,7 @@ 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_BACKGROUND; import static com.android.tools.lint.detector.api.LintConstants.ATTR_LAYOUT_WEIGHT; import static com.android.tools.lint.detector.api.LintConstants.IMAGE_VIEW; import static com.android.tools.lint.detector.api.LintConstants.LINEAR_LAYOUT; @@ -86,6 +87,12 @@ public class UseCompoundDrawableDetector extends LayoutDetector { ((second.getTagName().equals(IMAGE_VIEW) && first.getTagName().equals(TEXT_VIEW) && !second.hasAttributeNS(ANDROID_URI, ATTR_LAYOUT_WEIGHT)))) { + // If the layout has a background, ignore since it would disappear from + // the TextView + if (element.hasAttributeNS(ANDROID_URI, ATTR_BACKGROUND)) { + return; + } + context.report(ISSUE, element, context.getLocation(element), "This tag and its children can be replaced by one <TextView/> and " + "a compound drawable", null); diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiLookupTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiLookupTest.java index a7c2de9..044778f 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiLookupTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiLookupTest.java @@ -57,6 +57,11 @@ public class ApiLookupTest extends AbstractCheckTest { assertTrue(mDb.getCallVersion("java/lang/Object", "getClass", "()") <= 1); } + public void testIssue26467() { + assertTrue(mDb.getCallVersion("java/nio/ByteBuffer", "array", "()") <= 1); + assertEquals(9, mDb.getCallVersion("java/nio/Buffer", "array", "()")); + } + @Override protected Detector getDetector() { fail("This is not used in the ApiDatabase test"); diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/UseCompoundDrawableDetectorTest.java b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/UseCompoundDrawableDetectorTest.java index 16aee19..6abfa71 100644 --- a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/UseCompoundDrawableDetectorTest.java +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/UseCompoundDrawableDetectorTest.java @@ -31,4 +31,11 @@ public class UseCompoundDrawableDetectorTest extends AbstractCheckTest { "<TextView/> and a compound drawable", lintFiles("res/layout/compound.xml")); } + + public void testCompound2() throws Exception { + // Ignore layouts that set a custom background + assertEquals( + "No warnings.", + lintFiles("res/layout/compound2.xml")); + } } diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/compound2.xml b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/compound2.xml new file mode 100644 index 0000000..24f45dc --- /dev/null +++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/res/layout/compound2.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:background="@android:drawable/ic_dialog_alert" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <ImageView + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + +</LinearLayout> |