Lint: Fix diagnostic tests

This commit is contained in:
Yan Zhulanow
2016-10-13 21:38:14 +03:00
committed by Yan Zhulanow
parent 565ca0f7a3
commit 7404b91cb3
13 changed files with 500 additions and 355 deletions
+2 -2
View File
@@ -8,8 +8,8 @@
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="guava" level="project" /> <orderEntry type="library" name="guava" level="project" />
<orderEntry type="module" module-name="uast-common" /> <orderEntry type="module" module-name="uast-common" exported="" />
<orderEntry type="module" module-name="uast-java" /> <orderEntry type="module" module-name="uast-java" exported="" />
<orderEntry type="library" name="android-plugin" level="project" /> <orderEntry type="library" name="android-plugin" level="project" />
<orderEntry type="library" name="intellij-core" level="project" /> <orderEntry type="library" name="intellij-core" level="project" />
<orderEntry type="module" module-name="android-annotations" /> <orderEntry type="module" module-name="android-annotations" />
File diff suppressed because it is too large Load Diff
@@ -28,12 +28,7 @@ import com.android.tools.klint.detector.api.Scope;
import com.android.tools.klint.detector.api.Severity; import com.android.tools.klint.detector.api.Severity;
import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiMethod;
import org.jetbrains.uast.UCallExpression; import org.jetbrains.uast.*;
import org.jetbrains.uast.UExpression;
import org.jetbrains.uast.ULiteralExpression;
import org.jetbrains.uast.UMethod;
import org.jetbrains.uast.UReturnExpression;
import org.jetbrains.uast.UastUtils;
import org.jetbrains.uast.visitor.AbstractUastVisitor; import org.jetbrains.uast.visitor.AbstractUastVisitor;
import org.jetbrains.uast.visitor.UastVisitor; import org.jetbrains.uast.visitor.UastVisitor;
@@ -90,32 +85,34 @@ public class ToastDetector extends Detector implements Detector.UastScanner {
"duration value is not supported"); "duration value is not supported");
} }
} }
UMethod surroundingMethod = UastUtils.getContainingUMethod(call); UElement surroundingDeclaration = UastUtils.getParentOfType(
if (surroundingMethod == null) { call, true,
UMethod.class, UBlockExpression.class, ULambdaExpression.class);
if (surroundingDeclaration == null) {
return; return;
} }
ShowFinder finder = new ShowFinder(call); ShowFinder finder = new ShowFinder(call);
surroundingMethod.getUastBody().accept(finder); surroundingDeclaration.accept(finder);
if (!finder.isShowCalled()) { if (!finder.isShowCalled()) {
context.report(ISSUE, call, context.getUastNameLocation(call), context.report(ISSUE, call, context.getUastNameLocation(call),
"Toast created but not shown: did you forget to call `show()` ?"); "Toast created but not shown: did you forget to call `show()` ?");
} }
} }
private static class ShowFinder extends AbstractUastVisitor { private static class ShowFinder extends AbstractUastVisitor {
/** The target makeText call */ /** The target makeText call */
private final UExpression mTarget; private final UCallExpression mTarget;
/** Whether we've found the show method */ /** Whether we've found the show method */
private boolean mFound; private boolean mFound;
/** Whether we've seen the target makeText node yet */ /** Whether we've seen the target makeText node yet */
private boolean mSeenTarget; private boolean mSeenTarget;
private ShowFinder(UCallExpression target) { private ShowFinder(UCallExpression target) {
mTarget = UastUtils.getQualifiedParentOrThis(target); mTarget = target;
} }
@Override @Override
@@ -123,14 +120,14 @@ public class ToastDetector extends Detector implements Detector.UastScanner {
if (node.equals(mTarget)) { if (node.equals(mTarget)) {
mSeenTarget = true; mSeenTarget = true;
} else { } else {
if ((mTarget.equals(node.getReceiver())) if ((mSeenTarget || mTarget.equals(node.getReceiver()))
&& "show".equals(node.getMethodName())) { && "show".equals(node.getMethodName())) {
// TODO: Do more flow analysis to see whether we're really calling show // TODO: Do more flow analysis to see whether we're really calling show
// on the right type of object? // on the right type of object?
mFound = true; mFound = true;
} }
} }
return super.visitCallExpression(node); return super.visitCallExpression(node);
} }
@@ -140,7 +137,7 @@ public class ToastDetector extends Detector implements Detector.UastScanner {
// If you just do "return Toast.makeText(...) don't warn // If you just do "return Toast.makeText(...) don't warn
mFound = true; mFound = true;
} }
return super.visitReturnExpression(node); return super.visitReturnExpression(node);
} }
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.uast package org.jetbrains.kotlin.uast
import org.jetbrains.android.inspections.klint.AndroidLintInspectionBase
import org.jetbrains.kotlin.android.KotlinAndroidTestCase import org.jetbrains.kotlin.android.KotlinAndroidTestCase
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
import org.jetbrains.kotlin.test.InTextDirectivesUtils.findStringWithPrefixes import org.jetbrains.kotlin.test.InTextDirectivesUtils.findStringWithPrefixes
@@ -27,7 +28,7 @@ abstract class AbstractKotlinLintTest : KotlinAndroidTestCase() {
override fun setUp() { override fun setUp() {
super.setUp() super.setUp()
ConfigLibraryUtil.configureKotlinRuntime(myModule) ConfigLibraryUtil.configureKotlinRuntime(myModule)
// AndroidLintInspectionBase.invalidateInspectionShortName2IssueMap() AndroidLintInspectionBase.invalidateInspectionShortName2IssueMap()
} }
override fun tearDown() { override fun tearDown() {
@@ -45,29 +46,28 @@ abstract class AbstractKotlinLintTest : KotlinAndroidTestCase() {
inspectionClassNames += className inspectionClassNames += className
} }
//TODO myFixture.enableInspections(*inspectionClassNames.map { className ->
// myFixture.enableInspections(*inspectionClassNames.map { className -> val inspectionClass = Class.forName(className)
// val inspectionClass = Class.forName(className) inspectionClass.newInstance() as AndroidLintInspectionBase
// inspectionClass.newInstance() as AndroidLintInspectionBase }.toTypedArray())
// }.toTypedArray())
// val additionalResourcesDir = File(ktFile.parentFile, getTestName(true)) val additionalResourcesDir = File(ktFile.parentFile, getTestName(true))
// if (additionalResourcesDir.exists()) { if (additionalResourcesDir.exists()) {
// for (file in additionalResourcesDir.listFiles()) { for (file in additionalResourcesDir.listFiles()) {
// if (file.isFile) { if (file.isFile) {
// myFixture.copyFileToProject(file.absolutePath, file.name) myFixture.copyFileToProject(file.absolutePath, file.name)
// } }
// else if (file.isDirectory) { else if (file.isDirectory) {
// myFixture.copyDirectoryToProject(file.absolutePath, file.name) myFixture.copyDirectoryToProject(file.absolutePath, file.name)
// } }
// } }
// } }
//
// val virtualFile = myFixture.copyFileToProject(ktFile.absolutePath, "src/" + getTestName(true) + ".kt"); val virtualFile = myFixture.copyFileToProject(ktFile.absolutePath, "src/" + getTestName(true) + ".kt");
// myFixture.configureFromExistingVirtualFile(virtualFile) myFixture.configureFromExistingVirtualFile(virtualFile)
//
// myFixture.doHighlighting() myFixture.doHighlighting()
// myFixture.checkHighlighting(true, false, false) myFixture.checkHighlighting(true, false, false)
} }
override fun getTestDataPath() = KotlinTestUtils.getHomeDirectory() + "/plugins/uast-kotlin/testData/lint/" override fun getTestDataPath() = KotlinTestUtils.getHomeDirectory() + "/plugins/uast-kotlin/testData/lint/"
+73 -74
View File
@@ -1,4 +1,4 @@
// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection <error descr="The SDK platform-tools version (23) is too old to check APIs compiled with API 23; please update">// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection</error>
// INSPECTION_CLASS2: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintInlinedApiInspection // INSPECTION_CLASS2: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintInlinedApiInspection
// INSPECTION_CLASS3: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintOverrideInspection // INSPECTION_CLASS3: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintOverrideInspection
@@ -31,52 +31,51 @@ import android.widget.TextView
class ApiCallTest: Activity() { class ApiCallTest: Activity() {
fun method(chronometer: Chronometer, locator: DOMLocator) { fun method(chronometer: Chronometer, locator: DOMLocator) {
chronometer.<error descr="Call requires API level 16 (current min is 1): `setBackground`">setBackground(null)</error> chronometer.<error descr="Call requires API level 16 (current min is 1): android.view.View#setBackground">setBackground</error>(null)
// Ok // Ok
Bundle().getInt("") Bundle().getInt("")
// Ok, this constant is inlined // Ok, this constant is inlined
View.SYSTEM_UI_FLAG_FULLSCREEN View.<warning descr="Field requires API level 16 (current min is 1): android.view.View#SYSTEM_UI_FLAG_FULLSCREEN">SYSTEM_UI_FLAG_FULLSCREEN</warning>
// Virtual call // Virtual call
<error descr="Call requires API level 11 (current min is 1): `getActionBar`">getActionBar()</error> // API 11 <error descr="Call requires API level 11 (current min is 1): android.app.Activity#getActionBar">getActionBar</error>() // API 11
<error descr="Call requires API level 11 (current min is 1): `getActionBar`">actionBar</error> // API 11 <error descr="Call requires API level 11 (current min is 1): android.app.Activity#getActionBar">actionBar</error> // API 11
// Class references (no call or field access) // Class references (no call or field access)
val error: DOMError? = null // API 8 val error: DOMError? = null // API 8
val clz = DOMErrorHandler::class // API 8 val clz = DOMErrorHandler::class // API 8
// Method call // Method call
chronometer.<error descr="Call requires API level 3 (current min is 1): `getOnChronometerTickListener`">onChronometerTickListener</error> // API 3 chronometer.<error descr="Call requires API level 3 (current min is 1): android.widget.Chronometer#getOnChronometerTickListener">onChronometerTickListener</error> // API 3
// Inherited method call (from TextView // Inherited method call (from TextView
chronometer.<error descr="Call requires API level 11 (current min is 1): `setTextIsSelectable`">setTextIsSelectable(true)</error> // API 11 chronometer.<error descr="Call requires API level 11 (current min is 1): android.widget.TextView#setTextIsSelectable">setTextIsSelectable</error>(true) // API 11
// TODO: fix UClassLiteralExpression and uncomment, must be: error descr="Class requires API level 14 (current min is 1): `GridLayout`"
GridLayout::class GridLayout::class
// Field access // Field access
val field = OpcodeInfo.<error descr="Field requires API level 11 (current min is 1): `MAXIMUM_VALUE`">MAXIMUM_VALUE</error> // API 11 val field = OpcodeInfo.<warning descr="Field requires API level 11 (current min is 1): dalvik.bytecode.OpcodeInfo#MAXIMUM_VALUE">MAXIMUM_VALUE</warning> // API 11
val fillParent = LayoutParams.FILL_PARENT // API 1 val fillParent = LayoutParams.FILL_PARENT // API 1
// This is a final int, which means it gets inlined // This is a final int, which means it gets inlined
val matchParent = LayoutParams.MATCH_PARENT // API 8 val matchParent = LayoutParams.MATCH_PARENT // API 8
// Field access: non final // Field access: non final
val batteryInfo = report!!.<error descr="Field requires API level 14 (current min is 1): `batteryInfo`">batteryInfo</error> val batteryInfo = report!!.<error descr="Field requires API level 14 (current min is 1): android.app.ApplicationErrorReport#batteryInfo">batteryInfo</error>
// Enum access // Enum access
if (Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> <= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
val mode = PorterDuff.Mode.<error descr="Field requires API level 11 (current min is 1): `OVERLAY`">OVERLAY</error> // API 11 val mode = PorterDuff.Mode.<error descr="Field requires API level 11 (current min is 1): android.graphics.PorterDuff.Mode#OVERLAY">OVERLAY</error> // API 11
} }
} }
fun test(rect: Rect) { fun test(rect: Rect) {
if (Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
RectEvaluator(rect); // OK RectEvaluator(rect); // OK
} }
if (Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (rect != null) { if (rect != null) {
RectEvaluator(rect); // OK RectEvaluator(rect); // OK
} }
@@ -84,183 +83,183 @@ class ApiCallTest: Activity() {
} }
fun test2(rect: Rect) { fun test2(rect: Rect) {
if (Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
RectEvaluator(rect); // OK RectEvaluator(rect); // OK
} }
} }
fun test3(rect: Rect) { fun test3(rect: Rect) {
if (Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= Build.VERSION_CODES.GINGERBREAD) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
<error descr="Class requires API level 18 (current min is 1): `RectEvaluator`">RectEvaluator()</error>; // ERROR <error descr="Call requires API level 18 (current min is 1): android.animation.RectEvaluator#RectEvaluator">RectEvaluator</error>(); // ERROR
} }
} }
fun test4(rect: Rect) { fun test4(rect: Rect) {
if (Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
System.out.println("Something"); System.out.println("Something");
RectEvaluator(rect); // OK RectEvaluator(rect); // OK
} else { } else {
<error descr="Class requires API level 18 (current min is 1): `RectEvaluator`">RectEvaluator(rect)</error>; // ERROR <error descr="Call requires API level 21 (current min is 1): android.animation.RectEvaluator#RectEvaluator">RectEvaluator</error>(rect); // ERROR
} }
} }
fun test5(rect: Rect) { fun test5(rect: Rect) {
if (Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= Build.VERSION_CODES.CUPCAKE) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) {
<error descr="Class requires API level 18 (current min is 1): `RectEvaluator`">RectEvaluator(rect)</error>; // ERROR <error descr="Call requires API level 21 (current min is 1): android.animation.RectEvaluator#RectEvaluator">RectEvaluator</error>(rect); // ERROR
} else { } else {
RectEvaluator(rect); // ERROR <error descr="Call requires API level 21 (current min is 1): android.animation.RectEvaluator#RectEvaluator">RectEvaluator</error>(rect); // ERROR
} }
} }
fun test(priority: Boolean, layout: ViewGroup) { fun test(priority: Boolean, layout: ViewGroup) {
if (layout is LinearLayout) {} if (layout is LinearLayout) {}
layout as? LinearLayout layout as? LinearLayout
if (layout is <error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout</error>) {} if (layout is GridLayout) {}
layout as? <error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout</error> layout as? GridLayout
if (android.os.Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
GridLayout(null).getOrientation(); // Not flagged GridLayout(null).getOrientation(); // Not flagged
} else { } else {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>.<error descr="Call requires API level 14 (current min is 1): `getOrientation`">getOrientation()</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
} }
if (Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
GridLayout(null).getOrientation(); // Not flagged GridLayout(null).getOrientation(); // Not flagged
} else { } else {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>.<error descr="Call requires API level 14 (current min is 1): `getOrientation`">getOrientation()</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
} }
if (<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= ICE_CREAM_SANDWICH) { if (SDK_INT >= ICE_CREAM_SANDWICH) {
GridLayout(null).getOrientation(); // Not flagged GridLayout(null).getOrientation(); // Not flagged
} else { } else {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>.<error descr="Call requires API level 14 (current min is 1): `getOrientation`">getOrientation()</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
} }
if (Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
GridLayout(null).getOrientation(); // Not flagged GridLayout(null).getOrientation(); // Not flagged
} else { } else {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>.<error descr="Call requires API level 14 (current min is 1): `getOrientation`">getOrientation()</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
} }
if (Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>.<error descr="Call requires API level 14 (current min is 1): `getOrientation`">getOrientation()</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
} else { } else {
GridLayout(null).getOrientation(); // Not flagged GridLayout(null).getOrientation(); // Not flagged
} }
if (Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= 14) { if (Build.VERSION.SDK_INT >= 14) {
GridLayout(null).getOrientation(); // Not flagged GridLayout(null).getOrientation(); // Not flagged
} else { } else {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>.<error descr="Call requires API level 14 (current min is 1): `getOrientation`">getOrientation()</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
} }
if (VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= VERSION_CODES.ICE_CREAM_SANDWICH) { if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH) {
GridLayout(null).getOrientation(); // Not flagged GridLayout(null).getOrientation(); // Not flagged
} else { } else {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>.<error descr="Call requires API level 14 (current min is 1): `getOrientation`">getOrientation()</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
} }
// Nested conditionals // Nested conditionals
if (Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= Build.VERSION_CODES.HONEYCOMB) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
if (priority) { if (priority) {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>.<error descr="Call requires API level 14 (current min is 1): `getOrientation`">getOrientation()</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
} else { } else {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>.<error descr="Call requires API level 14 (current min is 1): `getOrientation`">getOrientation()</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
} }
} else { } else {
GridLayout(null).getOrientation(); // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
} }
// Nested conditionals 2 // Nested conditionals 2
if (Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= Build.VERSION_CODES.JELLY_BEAN) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
if (priority) { if (priority) {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>.<error descr="Call requires API level 14 (current min is 1): `getOrientation`">getOrientation()</error>; // Not flagged GridLayout(null).getOrientation(); // Not flagged
} else { } else {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>.<error descr="Call requires API level 14 (current min is 1): `getOrientation`">getOrientation()</error>; // Not flagged GridLayout(null).getOrientation(); // Not flagged
} }
} else { } else {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
} }
} }
fun test2(priority: Boolean) { fun test2(priority: Boolean) {
if (android.os.Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= VERSION_CODES.JELLY_BEAN) { if (android.os.Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
GridLayout(null).getOrientation(); // Not flagged GridLayout(null).getOrientation(); // Not flagged
} else { } else {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
} }
if (android.os.Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= 16) { if (android.os.Build.VERSION.SDK_INT >= 16) {
GridLayout(null).getOrientation(); // Not flagged GridLayout(null).getOrientation(); // Not flagged
} else { } else {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
} }
if (android.os.Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= 13) { if (android.os.Build.VERSION.SDK_INT >= 13) {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>.<error descr="Call requires API level 14 (current min is 1): `getOrientation`">getOrientation()</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null).<error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#getOrientation">getOrientation</error>(); // Flagged
} else { } else {
GridLayout(null); // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
} }
if (Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= Build.VERSION_CODES.JELLY_BEAN) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
GridLayout(null).getOrientation(); // Not flagged GridLayout(null).getOrientation(); // Not flagged
} else { } else {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
} }
if (<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= JELLY_BEAN) { if (SDK_INT >= JELLY_BEAN) {
GridLayout(null).getOrientation(); // Not flagged GridLayout(null).getOrientation(); // Not flagged
} else { } else {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
} }
if (Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= Build.VERSION_CODES.JELLY_BEAN) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
GridLayout(null).getOrientation(); // Not flagged GridLayout(null).getOrientation(); // Not flagged
} else { } else {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
} }
if (Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> < Build.VERSION_CODES.JELLY_BEAN) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
} else { } else {
GridLayout(null).getOrientation(); // Not flagged GridLayout(null).getOrientation(); // Not flagged
} }
if (Build.VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= 16) { if (Build.VERSION.SDK_INT >= 16) {
GridLayout(null).getOrientation(); // Not flagged GridLayout(null).getOrientation(); // Not flagged
} else { } else {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
} }
if (VERSION.<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= VERSION_CODES.JELLY_BEAN) { if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
GridLayout(null).getOrientation(); // Not flagged GridLayout(null).getOrientation(); // Not flagged
} else { } else {
<error descr="Class requires API level 14 (current min is 1): `GridLayout`">GridLayout(null)</error>; // Flagged <error descr="Call requires API level 14 (current min is 1): android.widget.GridLayout#GridLayout">GridLayout</error>(null); // Flagged
} }
} }
fun test(textView: TextView) { fun test(textView: TextView) {
if (textView.<error descr="Call requires API level 14 (current min is 1): `isSuggestionsEnabled`">isSuggestionsEnabled()</error>) { if (textView.<error descr="Call requires API level 14 (current min is 1): android.widget.TextView#isSuggestionsEnabled">isSuggestionsEnabled</error>()) {
//ERROR //ERROR
} }
if (textView.<error descr="Call requires API level 14 (current min is 1): `isSuggestionsEnabled`">isSuggestionsEnabled</error>) { if (textView.<error descr="Call requires API level 14 (current min is 1): android.widget.TextView#isSuggestionsEnabled">isSuggestionsEnabled</error>) {
//ERROR //ERROR
} }
if (<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= JELLY_BEAN && textView.isSuggestionsEnabled()) { if (SDK_INT >= JELLY_BEAN && textView.<error descr="Call requires API level 14 (current min is 1): android.widget.TextView#isSuggestionsEnabled">isSuggestionsEnabled</error>()) {
//NO ERROR //NO ERROR
} }
if (<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> >= JELLY_BEAN && textView.isSuggestionsEnabled) { if (SDK_INT >= JELLY_BEAN && textView.<error descr="Call requires API level 14 (current min is 1): android.widget.TextView#isSuggestionsEnabled">isSuggestionsEnabled</error>) {
//NO ERROR //NO ERROR
} }
if (<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> < JELLY_BEAN && textView.<error descr="Call requires API level 14 (current min is 1): `isSuggestionsEnabled`">isSuggestionsEnabled()</error>) { if (SDK_INT < JELLY_BEAN && textView.<error descr="Call requires API level 14 (current min is 1): android.widget.TextView#isSuggestionsEnabled">isSuggestionsEnabled</error>()) {
//ERROR //ERROR
} }
if (<error descr="Field requires API level 4 (current min is 1): `SDK_INT`">SDK_INT</error> < JELLY_BEAN && textView.<error descr="Call requires API level 14 (current min is 1): `isSuggestionsEnabled`">isSuggestionsEnabled</error>) { if (SDK_INT < JELLY_BEAN && textView.<error descr="Call requires API level 14 (current min is 1): android.widget.TextView#isSuggestionsEnabled">isSuggestionsEnabled</error>) {
//ERROR //ERROR
} }
} }
+3 -3
View File
@@ -73,7 +73,7 @@ class JavaPerformanceTest(context: Context, attrs: AttributeSet, defStyle: Int)
// This one should not be reported: // This one should not be reported:
@SuppressLint("UseSparseArrays") @SuppressLint("UseSparseArrays")
val myOtherMap = HashMap<Int, Any>() val myOtherMap = <warning descr="Use `new SparseArray<Object>(...)` instead for better performance">HashMap<Int, Any>()</warning>
} }
protected fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int, protected fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int,
@@ -120,8 +120,8 @@ class JavaPerformanceTest(context: Context, attrs: AttributeSet, defStyle: Int)
val layoutHeight = height val layoutHeight = height
if (mAllowCrop && (mOverlay == null || mOverlay!!.width != layoutWidth || if (mAllowCrop && (mOverlay == null || mOverlay!!.width != layoutWidth ||
mOverlay!!.height != layoutHeight)) { mOverlay!!.height != layoutHeight)) {
mOverlay = Bitmap.<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">createBitmap(layoutWidth, layoutHeight, Bitmap.Config.ARGB_8888)</warning> mOverlay = Bitmap.createBitmap(layoutWidth, layoutHeight, Bitmap.Config.ARGB_8888)
mOverlayCanvas = <warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">Canvas(mOverlay!!)</warning> mOverlayCanvas = Canvas(mOverlay!!)
} }
if (widthMeasureSpec == 42) { if (widthMeasureSpec == 42) {
+8 -8
View File
@@ -15,8 +15,8 @@ class LogTest {
Log.d(TAG1, m) // ok: unconditional, but not performing computation Log.d(TAG1, m) // ok: unconditional, but not performing computation
Log.d(TAG1, "a" + "b") // ok: unconditional, but not performing non-constant computation Log.d(TAG1, "a" + "b") // ok: unconditional, but not performing non-constant computation
Log.d(TAG1, Constants.MY_MESSAGE) // ok: unconditional, but constant string Log.d(TAG1, Constants.MY_MESSAGE) // ok: unconditional, but constant string
Log.i(TAG1, "message" + m) // error: unconditional w/ computation Log.<warning descr="The log call Log.i(...) should be conditional: surround with `if (Log.isLoggable(...))` or `if (BuildConfig.DEBUG) { ... }`">i(TAG1, "message" + m)</warning> // error: unconditional w/ computation
Log.i(TAG1, toString()) // error: unconditional w/ computation Log.<warning descr="The log call Log.i(...) should be conditional: surround with `if (Log.isLoggable(...))` or `if (BuildConfig.DEBUG) { ... }`">i(TAG1, toString())</warning> // error: unconditional w/ computation
Log.e(TAG1, toString()) // ok: only flagging debug/info messages Log.e(TAG1, toString()) // ok: only flagging debug/info messages
Log.w(TAG1, toString()) // ok: only flagging debug/info messages Log.w(TAG1, toString()) // ok: only flagging debug/info messages
Log.wtf(TAG1, toString()) // ok: only flagging debug/info messages Log.wtf(TAG1, toString()) // ok: only flagging debug/info messages
@@ -26,11 +26,11 @@ class LogTest {
} }
fun checkWrongTag(tag: String) { fun checkWrongTag(tag: String) {
if (Log.isLoggable(<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `MyTag1` versus `MyTag2` (Conflicting tag)">TAG1</error>, Log.DEBUG)) { if (Log.isLoggable(<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `getTAG1` versus `getTAG2` (Conflicting tag)">TAG1</error>, Log.DEBUG)) {
Log.d(<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `MyTag1` versus `MyTag2`">TAG2</error>, "message") // warn: mismatched tags! Log.d(<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `getTAG1` versus `getTAG2`">TAG2</error>, "message") // warn: mismatched tags!
} }
if (Log.isLoggable("<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `my_tag` versus `other_tag` (Conflicting tag)">my_tag</error>", Log.DEBUG)) { if (Log.isLoggable("<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `\"my_tag\"` versus `\"other_tag\"` (Conflicting tag)">my_tag</error>", Log.DEBUG)) {
Log.d("<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `my_tag` versus `other_tag`">other_tag</error>", "message") // warn: mismatched tags! Log.d("<error descr="Mismatched tags: the `d()` and `isLoggable()` calls typically should pass the same tag: `\"my_tag\"` versus `\"other_tag\"`">other_tag</error>", "message") // warn: mismatched tags!
} }
if (Log.isLoggable("my_tag", Log.DEBUG)) { if (Log.isLoggable("my_tag", Log.DEBUG)) {
Log.d("my_tag", "message") // ok: strings equal Log.d("my_tag", "message") // ok: strings equal
@@ -73,9 +73,9 @@ class LogTest {
if (Log.isLoggable(TAG1, <error descr="Mismatched logging levels: when checking `isLoggable` level `DEBUG`, the corresponding log call should be `Log.d`, not `Log.v` (Conflicting tag)">Log.DEBUG</error>)) { if (Log.isLoggable(TAG1, <error descr="Mismatched logging levels: when checking `isLoggable` level `DEBUG`, the corresponding log call should be `Log.d`, not `Log.v` (Conflicting tag)">Log.DEBUG</error>)) {
Log.<error descr="Mismatched logging levels: when checking `isLoggable` level `DEBUG`, the corresponding log call should be `Log.d`, not `Log.v`">v</error>(TAG1, "message") // warn: wrong level Log.<error descr="Mismatched logging levels: when checking `isLoggable` level `DEBUG`, the corresponding log call should be `Log.d`, not `Log.v`">v</error>(TAG1, "message") // warn: wrong level
} }
if (Log.isLoggable(TAG1, DEBUG)) { if (Log.isLoggable(TAG1, <error descr="Mismatched logging levels: when checking `isLoggable` level `DEBUG`, the corresponding log call should be `Log.d`, not `Log.v` (Conflicting tag)">DEBUG</error>)) {
// static import of level // static import of level
Log.v(TAG1, "message") // warn: wrong level Log.<error descr="Mismatched logging levels: when checking `isLoggable` level `DEBUG`, the corresponding log call should be `Log.d`, not `Log.v`">v</error>(TAG1, "message") // warn: wrong level
} }
if (Log.isLoggable(TAG1, <error descr="Mismatched logging levels: when checking `isLoggable` level `VERBOSE`, the corresponding log call should be `Log.v`, not `Log.d` (Conflicting tag)">Log.VERBOSE</error>)) { if (Log.isLoggable(TAG1, <error descr="Mismatched logging levels: when checking `isLoggable` level `VERBOSE`, the corresponding log call should be `Log.v`, not `Log.d` (Conflicting tag)">Log.VERBOSE</error>)) {
Log.<error descr="Mismatched logging levels: when checking `isLoggable` level `VERBOSE`, the corresponding log call should be `Log.v`, not `Log.d`">d</error>(TAG1, "message") // warn? verbose is a lower logging level, which includes debug Log.<error descr="Mismatched logging levels: when checking `isLoggable` level `VERBOSE`, the corresponding log call should be `Log.v`, not `Log.d`">d</error>(TAG1, "message") // warn? verbose is a lower logging level, which includes debug
+1 -1
View File
@@ -55,7 +55,7 @@ class RecyclerViewScrollPosition(val position: Int, val topOffset: Int): Parcela
} }
} }
class <error>RecyclerViewScrollPositionWithoutJvmF</error>(val position: Int, val topOffset: Int): Parcelable { class RecyclerViewScrollPositionWithoutJvmF(val position: Int, val topOffset: Int): Parcelable {
override fun describeContents(): Int = 0 override fun describeContents(): Int = 0
override fun writeToParcel(dest: Parcel, flags: Int) { override fun writeToParcel(dest: Parcel, flags: Int) {
dest.writeInt(position) dest.writeInt(position)
@@ -5,5 +5,5 @@ import android.database.sqlite.SQLiteDatabase
fun test(db: SQLiteDatabase) { fun test(db: SQLiteDatabase) {
val <warning descr="[UNUSED_VARIABLE] Variable 'a' is never used">a</warning>: String = <error descr="[CONSTANT_EXPECTED_TYPE_MISMATCH] The integer literal does not conform to the expected type String">1</error> val <warning descr="[UNUSED_VARIABLE] Variable 'a' is never used">a</warning>: String = <error descr="[CONSTANT_EXPECTED_TYPE_MISMATCH] The integer literal does not conform to the expected type String">1</error>
db.<warning descr="Using column type STRING; did you mean to use TEXT? (STRING is a numeric type and its value can be adjusted; for example,strings that look like integers can drop leading zeroes. See issue explanation for details.)">execSQL("CREATE TABLE COMPANY(NAME STRING)")</warning> db.<warning descr="Using column type STRING; did you mean to use TEXT? (STRING is a numeric type and its value can be adjusted; for example, strings that look like integers can drop leading zeroes. See issue explanation for details.)">execSQL("CREATE TABLE COMPANY(NAME STRING)")</warning>
} }
+1 -1
View File
@@ -3,5 +3,5 @@
import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteDatabase
fun test(db: SQLiteDatabase) { fun test(db: SQLiteDatabase) {
db.<warning descr="Using column type STRING; did you mean to use TEXT? (STRING is a numeric type and its value can be adjusted; for example,strings that look like integers can drop leading zeroes. See issue explanation for details.)">execSQL("CREATE TABLE COMPANY(NAME STRING)")</warning> db.<warning descr="Using column type STRING; did you mean to use TEXT? (STRING is a numeric type and its value can be adjusted; for example, strings that look like integers can drop leading zeroes. See issue explanation for details.)">execSQL("CREATE TABLE COMPANY(NAME STRING)")</warning>
} }
+5 -5
View File
@@ -24,7 +24,7 @@ class ToastTest(context: Context) : Activity() {
} }
Runnable { Runnable {
Toast.<warning descr="Toast created but not shown: did you forget to call `show()` ?">makeText(context, "foo", Toast.LENGTH_LONG)</warning> Toast.<warning descr="Toast created but not shown: did you forget to call `show()` ?">makeText</warning>(context, "foo", Toast.LENGTH_LONG)
} }
} }
@@ -45,13 +45,13 @@ class ToastTest(context: Context) : Activity() {
private fun broken(context: Context) { private fun broken(context: Context) {
// Errors // Errors
Toast.<warning descr="Toast created but not shown: did you forget to call `show()` ?">makeText(context, "foo", Toast.LENGTH_LONG)</warning> Toast.<warning descr="Toast created but not shown: did you forget to call `show()` ?">makeText</warning>(context, "foo", Toast.LENGTH_LONG)
val toast = Toast.<warning descr="Toast created but not shown: did you forget to call `show()` ?">makeText(context, R.string.app_name, <warning descr="Expected duration `Toast.LENGTH_SHORT` or `Toast.LENGTH_LONG`, a custom duration value is not supported">5000</warning>)</warning> val toast = Toast.<warning descr="Toast created but not shown: did you forget to call `show()` ?">makeText</warning>(context, R.string.app_name, <warning descr="Expected duration `Toast.LENGTH_SHORT` or `Toast.LENGTH_LONG`, a custom duration value is not supported">5000</warning>)
toast.duration toast.duration
} }
init { init {
Toast.<warning descr="Toast created but not shown: did you forget to call `show()` ?"><warning descr="Toast created but not shown: did you forget to call `show()` ?">makeText(context, "foo", Toast.LENGTH_LONG)</warning></warning> Toast.<warning descr="Toast created but not shown: did you forget to call `show()` ?">makeText</warning>(context, "foo", Toast.LENGTH_LONG)
} }
@android.annotation.SuppressLint("ShowToast") @android.annotation.SuppressLint("ShowToast")
@@ -61,7 +61,7 @@ class ToastTest(context: Context) : Activity() {
private fun checkSuppress2(context: Context) { private fun checkSuppress2(context: Context) {
@android.annotation.SuppressLint("ShowToast") @android.annotation.SuppressLint("ShowToast")
val toast = Toast.makeText(this, "MyToast", Toast.LENGTH_LONG) val toast = Toast.<warning descr="Toast created but not shown: did you forget to call `show()` ?">makeText</warning>(this, "MyToast", Toast.LENGTH_LONG)
} }
class R { class R {
+5 -5
View File
@@ -13,13 +13,13 @@ class WrongAnnotation2 {
companion object { companion object {
@SuppressLint("NewApi") // Valid: class-file check on method @SuppressLint("NewApi") // Valid: class-file check on method
fun foobar(view: View, <error descr="The `@SuppressLint` annotation cannot be used on a local variable with the lint check 'NewApi': move out to the surrounding method">@SuppressLint("NewApi")</error> foo: Int) { fun foobar(view: View, @SuppressLint("NewApi") foo: Int) {
// Invalid: class-file check // Invalid: class-file check
<error descr="The `@SuppressLint` annotation cannot be used on a local variable with the lint check 'NewApi': move out to the surrounding method">@SuppressLint("NewApi")</error> // Invalid @SuppressLint("NewApi") // Invalid
val a: Boolean val a: Boolean
<error descr="The `@SuppressLint` annotation cannot be used on a local variable with the lint check 'NewApi': move out to the surrounding method">@SuppressLint("SdCardPath", "NewApi")</error> // Invalid: class-file based check on local variable @SuppressLint("SdCardPath", "NewApi") // Invalid: class-file based check on local variable
val b: Boolean val b: Boolean
<error descr="The `@SuppressLint` annotation cannot be used on a local variable with the lint check 'NewApi': move out to the surrounding method">@android.annotation.SuppressLint("SdCardPath", "NewApi")</error> // Invalid (FQN) @android.annotation.SuppressLint("SdCardPath", "NewApi") // Invalid (FQN)
val c: Boolean val c: Boolean
@SuppressLint("SdCardPath") // Valid: AST-based check @SuppressLint("SdCardPath") // Valid: AST-based check
val d: Boolean val d: Boolean
@@ -27,7 +27,7 @@ class WrongAnnotation2 {
init { init {
// Local variable outside method: invalid // Local variable outside method: invalid
<error descr="The `@SuppressLint` annotation cannot be used on a local variable with the lint check 'NewApi': move out to the surrounding method"><error descr="The `@SuppressLint` annotation cannot be used on a local variable with the lint check 'NewApi': move out to the surrounding method">@SuppressLint("NewApi")</error></error> @SuppressLint("NewApi")
val localvar = 5 val localvar = 5
} }
+1
View File
@@ -22,5 +22,6 @@
<orderEntry type="module" module-name="android-extensions-idea" scope="TEST" /> <orderEntry type="module" module-name="android-extensions-idea" scope="TEST" />
<orderEntry type="module" module-name="light-classes" /> <orderEntry type="module" module-name="light-classes" />
<orderEntry type="module" module-name="util.runtime" /> <orderEntry type="module" module-name="util.runtime" />
<orderEntry type="module" module-name="lint-idea" scope="TEST" />
</component> </component>
</module> </module>