aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/client/api/JavaVisitor.java1
-rw-r--r--lint/libs/lint_api/src/com/android/tools/lint/detector/api/ClassContext.java7
-rw-r--r--lint/libs/lint_checks/src/com/android/tools/lint/checks/ApiDetector.java51
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/ApiDetectorTest.java15
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2$1$1.class.databin0 -> 704 bytes
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2$1$2.class.databin0 -> 704 bytes
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2$1.class.databin0 -> 1059 bytes
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2.class.databin0 -> 556 bytes
-rw-r--r--lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2.java.txt39
9 files changed, 108 insertions, 5 deletions
diff --git a/lint/libs/lint_api/src/com/android/tools/lint/client/api/JavaVisitor.java b/lint/libs/lint_api/src/com/android/tools/lint/client/api/JavaVisitor.java
index fcf58f4..fc7e03b 100644
--- a/lint/libs/lint_api/src/com/android/tools/lint/client/api/JavaVisitor.java
+++ b/lint/libs/lint_api/src/com/android/tools/lint/client/api/JavaVisitor.java
@@ -198,6 +198,7 @@ public class JavaVisitor {
// with details, location, etc.
return;
}
+ context.compilationUnit = compilationUnit;
for (VisitingDetector v : mAllDetectors) {
v.setContext(context);
diff --git a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/ClassContext.java b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/ClassContext.java
index ff05270..f4f4efa 100644
--- a/lint/libs/lint_api/src/com/android/tools/lint/detector/api/ClassContext.java
+++ b/lint/libs/lint_api/src/com/android/tools/lint/detector/api/ClassContext.java
@@ -259,15 +259,16 @@ public class ClassContext extends Context {
}
ClassNode curr = mClassNode;
while (curr != null) {
+ ClassNode prev = curr;
curr = mDriver.getOuterClassNode(curr);
if (curr != null) {
- if (mClassNode.outerMethod != null) {
+ if (prev.outerMethod != null) {
@SuppressWarnings("rawtypes") // ASM API
List methods = curr.methods;
for (Object m : methods) {
MethodNode method = (MethodNode) m;
- if (method.name.equals(mClassNode.outerMethod)
- && method.desc.equals(mClassNode.outerMethodDesc)) {
+ if (method.name.equals(prev.outerMethod)
+ && method.desc.equals(prev.outerMethodDesc)) {
// Found the outer method for this anonymous class; continue
// reporting on it (which will also work its way up the parent
// class hierarchy)
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 7c8154e..c670952 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
@@ -21,6 +21,7 @@ import static com.android.tools.lint.detector.api.LintConstants.TARGET_API;
import com.android.annotations.NonNull;
import com.android.resources.ResourceFolderType;
+import com.android.tools.lint.client.api.LintDriver;
import com.android.tools.lint.detector.api.Category;
import com.android.tools.lint.detector.api.ClassContext;
import com.android.tools.lint.detector.api.Context;
@@ -238,8 +239,7 @@ public class ApiDetector extends ResourceXmlDetector implements Detector.ClassSc
return;
}
- // Workaround for the fact that beforeCheckProject is too early
- int classMinSdk = getLocalMinSdk(classNode.invisibleAnnotations);
+ int classMinSdk = getClassMinSdk(context, classNode);
if (classMinSdk == -1) {
classMinSdk = getMinSdk(context);
}
@@ -367,6 +367,53 @@ public class ApiDetector extends ResourceXmlDetector implements Detector.ClassSc
}
/**
+ * Return the {@code @TargeTApi} level to use for the given {@code classNode};
+ * this will be the {@code @TargetApi} annotation on the class, or any outer
+ * methods (for anonymous inner classes) or outer classes (for inner classes)
+ * of the given class.
+ */
+ private int getClassMinSdk(ClassContext context, ClassNode classNode) {
+ int classMinSdk = getLocalMinSdk(classNode.invisibleAnnotations);
+ if (classMinSdk != -1) {
+ return classMinSdk;
+ }
+
+ LintDriver driver = context.getDriver();
+ while (classNode != null) {
+ ClassNode prev = classNode;
+ classNode = driver.getOuterClassNode(classNode);
+ if (classNode != null) {
+ // TODO: Should this be "curr" instead?
+ if (prev.outerMethod != null) {
+ @SuppressWarnings("rawtypes") // ASM API
+ List methods = classNode.methods;
+ for (Object m : methods) {
+ MethodNode method = (MethodNode) m;
+ if (method.name.equals(prev.outerMethod)
+ && method.desc.equals(prev.outerMethodDesc)) {
+ // Found the outer method for this anonymous class; check method
+ // annotations on it, then continue up the class hierarchy
+ int methodMinSdk = getLocalMinSdk(method.invisibleAnnotations);
+ if (methodMinSdk != -1) {
+ return methodMinSdk;
+ }
+
+ break;
+ }
+ }
+ }
+
+ classMinSdk = getLocalMinSdk(classNode.invisibleAnnotations);
+ if (classMinSdk != -1) {
+ return classMinSdk;
+ }
+ }
+ }
+
+ return -1;
+ }
+
+ /**
* Returns the minimum SDK to use according to the given annotation list, or
* -1 if no annotation was found.
*
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 eb35e1d..39a1e4f 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
@@ -271,6 +271,21 @@ public class ApiDetectorTest extends AbstractCheckTest {
));
}
+ public void testTargetAnnotationInner() throws Exception {
+ assertEquals(
+ "ApiTargetTest2.java:32: Error: Call requires API level 14 (current min is 3): android.widget.GridLayout#<init>",
+
+ lintProject(
+ "apicheck/classpath=>.classpath",
+ "apicheck/minsdk1.xml=>AndroidManifest.xml",
+ "apicheck/ApiTargetTest2.java.txt=>src/test/pkg/ApiTargetTest2.java",
+ "apicheck/ApiTargetTest2.class.data=>bin/classes/test/pkg/ApiTargetTest2.class",
+ "apicheck/ApiTargetTest2$1.class.data=>bin/classes/test/pkg/ApiTargetTest2$1.class",
+ "apicheck/ApiTargetTest2$1$2.class.data=>bin/classes/test/pkg/ApiTargetTest2$1$2.class",
+ "apicheck/ApiTargetTest2$1$1.class.data=>bin/classes/test/pkg/ApiTargetTest2$1$1.class"
+ ));
+ }
+
public void testSkipAndroidSupportInAospHalf() throws Exception {
String expected;
if (System.getenv("ANDROID_BUILD_TOP") != null) {
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2$1$1.class.data b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2$1$1.class.data
new file mode 100644
index 0000000..f18f226
--- /dev/null
+++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2$1$1.class.data
Binary files differ
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2$1$2.class.data b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2$1$2.class.data
new file mode 100644
index 0000000..ac3863e
--- /dev/null
+++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2$1$2.class.data
Binary files differ
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2$1.class.data b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2$1.class.data
new file mode 100644
index 0000000..f51c54b
--- /dev/null
+++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2$1.class.data
Binary files differ
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2.class.data b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2.class.data
new file mode 100644
index 0000000..defae98
--- /dev/null
+++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2.class.data
Binary files differ
diff --git a/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2.java.txt b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2.java.txt
new file mode 100644
index 0000000..7574805
--- /dev/null
+++ b/lint/libs/lint_checks/tests/src/com/android/tools/lint/checks/data/apicheck/ApiTargetTest2.java.txt
@@ -0,0 +1,39 @@
+package test.pkg;
+
+import android.annotation.TargetApi;
+import android.widget.GridLayout;
+
+// Test using the @TargetApi annotation on inner classes and anonymous inner classes
+@SuppressWarnings("unused")
+public class ApiTargetTest2 {
+ @TargetApi(value=14)
+ void foo2() {
+ new Runnable() {
+ @Override
+ public void run() {
+ new GridLayout(null, null, 0);
+ }
+
+ void foo3() {
+ new Runnable() {
+ @Override
+ public void run() {
+ new GridLayout(null, null, 0);
+ }
+ };
+ }
+
+ @TargetApi(value=3)
+ void foo4() {
+ new Runnable() {
+ @Override
+ public void run() {
+ // This should be marked as an error since the effective target API is 3 here
+ new GridLayout(null, null, 0);
+ }
+ };
+ }
+
+ };
+ }
+}