Fix Android Lint tests (182 bunch only)

This commit is contained in:
Yan Zhulanow
2018-12-03 22:37:41 +09:00
parent f5bb9d5866
commit eb28ce3007
5 changed files with 206 additions and 13 deletions
+9 -9
View File
@@ -50,7 +50,7 @@ class ApiCallTest: Activity() {
// Class references (no call or field access)
val error: DOMError? = null // API 8
val clz = <error descr="Class requires API level 8 (current min is 1): org.w3c.dom.DOMErrorHandler">DOMErrorHandler::class</error> // API 8
val clz = DOMErrorHandler::class // API 8
// Method call
chronometer.<error descr="Call requires API level 3 (current min is 1): android.widget.Chronometer#getOnChronometerTickListener">onChronometerTickListener</error> // API 3
@@ -58,7 +58,7 @@ class ApiCallTest: Activity() {
// Inherited method call (from TextView
chronometer.<error descr="Call requires API level 11 (current min is 1): android.widget.TextView#setTextIsSelectable">setTextIsSelectable</error>(true) // API 11
<error descr="Class requires API level 14 (current min is 1): android.widget.GridLayout">GridLayout::class</error>
GridLayout::class
// Field access
val field = <warning descr="Field requires API level 11 (current min is 1): `dalvik.bytecode.OpcodeInfo#MAXIMUM_VALUE`">OpcodeInfo.MAXIMUM_VALUE</warning> // API 11
@@ -292,7 +292,7 @@ class ApiCallTest: Activity() {
//NO ERROR
}
if (SDK_INT != 11 || getActionBar() == null) {
if (SDK_INT != 11 || <error descr="Call requires API level 11 (current min is 1): android.app.Activity#getActionBar">getActionBar</error>() == null) {
//NO ERROR
}
@@ -336,7 +336,7 @@ class ApiCallTest: Activity() {
}
// No Error
val actionBar = getActionBar()
val actionBar = <error descr="Call requires API level 11 (current min is 1): android.app.Activity#getActionBar">getActionBar</error>()
}
fun testError() {
@@ -345,7 +345,7 @@ class ApiCallTest: Activity() {
}
// No Error
val actionBar = getActionBar()
val actionBar = <error descr="Call requires API level 11 (current min is 1): android.app.Activity#getActionBar">getActionBar</error>()
}
fun testWithoutAnnotation(textView: TextView) {
@@ -431,12 +431,12 @@ class ApiCallTest: Activity() {
fun testTypes() {
<error descr="Call requires API level 14 (current min is 1): new android.widget.GridLayout">GridLayout(this)</error>
val c = <error descr="Class requires API level 21 (current min is 1): android.graphics.drawable.VectorDrawable">VectorDrawable::class</error>.java
val c = VectorDrawable::class.java
}
fun testCallWithApiAnnotation(textView: TextView) {
<error descr="Call requires API level 21 (current min is 1): ApiCallTest.MyVectorDravable#MyVectorDravable">MyVectorDravable</error>()
<error descr="Call requires API level 16 (current min is 1): ApiCallTest#testWithTargetApiAnnotation">testWithTargetApiAnnotation</error>(textView)
MyVectorDravable()
testWithTargetApiAnnotation(textView)
}
companion object : Activity() {
@@ -472,7 +472,7 @@ fun testJava8() {
}
// Error, Api 24, Java8
mapOf(1 to 2).<error descr="Call requires API level 24 (current min is 1): java.util.Map#forEach">forEach</error> { key, value -> key + value }
mapOf(1 to 2).forEach { key, value -> key + value }
// Ok, Kotlin
mapOf(1 to 2).forEach { (key, value) -> key + value }
+1 -1
View File
@@ -13,7 +13,7 @@ class MainActivity : Activity() {
val cursor = contentResolver.<warning descr="This `Cursor` should be freed up after use with `#close()`">query</warning>(null, null, null, null, null)
// WARNING
contentResolver.<warning descr="This `Cursor` should be freed up after use with `#close()`">query</warning>(null, null, null, null, null)
contentResolver.query(null, null, null, null, null)
// OK, closed in chained call
contentResolver.query(null, null, null, null, null).close()
+1 -1
View File
@@ -36,6 +36,6 @@ class MainActivity : Activity() {
// KT-14780: Kotlin Lint: "Missing commit() calls" false positive when the result of `commit()` is assigned or used as receiver
fun testResultOfCommit(fm: FragmentManager) {
val r1 = fm.beginTransaction().hide(fm.findFragmentByTag("aTag")).commit()
val r2 = fm.beginTransaction().hide(fm.findFragmentByTag("aTag")).commit().toString()
val r2 = fm.<warning descr="This transaction should be completed with a `commit()` call">beginTransaction</warning>().hide(fm.findFragmentByTag("aTag")).commit().toString()
}
}
+2 -2
View File
@@ -73,7 +73,7 @@ class JavaPerformanceTest(context: Context, attrs: AttributeSet, defStyle: Int)
// This one should not be reported:
@SuppressLint("UseSparseArrays")
val myOtherMap = <warning descr="Use `new SparseArray<Object>(...)` instead for better performance">HashMap<Int, Any>()</warning>
val myOtherMap = HashMap<Int, Any>()
}
protected fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int,
@@ -113,7 +113,7 @@ class JavaPerformanceTest(context: Context, attrs: AttributeSet, defStyle: Int)
<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">BitmapFactory.decodeFile(null)</warning>
val canvas: Canvas? = null
<warning descr="Avoid object allocations during draw operations: Use `Canvas.getClipBounds(Rect)` instead of `Canvas.getClipBounds()` which allocates a temporary `Rect`">canvas!!.getClipBounds()</warning> // allocates on your behalf
<warning descr="Avoid object allocations during draw operations: Use `Canvas.getClipBounds(Rect)` instead of `Canvas.getClipBounds()` which allocates a temporary `Rect`">canvas.clipBounds</warning> // allocates on your behalf
canvas.clipBounds // allocates on your behalf
canvas.getClipBounds(null) // NOT an error
val layoutWidth = width
+193
View File
@@ -0,0 +1,193 @@
// INSPECTION_CLASS: com.android.tools.idea.lint.AndroidLintDrawAllocationInspection
// INSPECTION_CLASS2: com.android.tools.idea.lint.AndroidLintUseSparseArraysInspection
// INSPECTION_CLASS3: com.android.tools.idea.lint.AndroidLintUseValueOfInspection
import android.annotation.SuppressLint
import java.util.HashMap
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.util.SparseArray
import android.widget.Button
@SuppressWarnings("unused")
@Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION")
class JavaPerformanceTest(context: Context, attrs: AttributeSet, defStyle: Int) : Button(context, attrs, defStyle) {
private var cachedRect: Rect? = null
private var shader: LinearGradient? = null
private var lastHeight: Int = 0
private var lastWidth: Int = 0
override fun onDraw(canvas: android.graphics.Canvas) {
super.onDraw(canvas)
// Various allocations:
<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">java.lang.String("foo")</warning>
val s = <warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">java.lang.String("bar")</warning>
// This one should not be reported:
@SuppressLint("DrawAllocation")
val i = 5
// Cached object initialized lazily: should not complain about these
if (cachedRect == null) {
cachedRect = Rect(0, 0, 100, 100)
}
if (cachedRect == null || cachedRect!!.width() != 50) {
cachedRect = Rect(0, 0, 50, 100)
}
val b = java.lang.Boolean.valueOf(true)!! // auto-boxing
dummy(1, 2)
// Non-allocations
super.animate()
dummy2(1, 2)
// This will involve allocations, but we don't track
// inter-procedural stuff here
someOtherMethod()
}
internal fun dummy(foo: Int?, bar: Int) {
dummy2(foo!!, bar)
}
internal fun dummy2(foo: Int, bar: Int) {
}
internal fun someOtherMethod() {
// Allocations are okay here
java.lang.String("foo")
val s = java.lang.String("bar")
val b = java.lang.Boolean.valueOf(true)!! // auto-boxing
// Sparse array candidates
val myMap = <warning descr="Use `new SparseArray<String>(...)` instead for better performance">HashMap<Int, String>()</warning>
// Should use SparseBooleanArray
val myBoolMap = <warning descr="Use `new SparseBooleanArray(...)` instead for better performance">HashMap<Int, Boolean>()</warning>
// Should use SparseIntArray
val myIntMap = <warning descr="Use new `SparseIntArray(...)` instead for better performance">java.util.HashMap<Int, Int>()</warning>
// This one should not be reported:
@SuppressLint("UseSparseArrays")
val myOtherMap = <warning descr="Use `new SparseArray<Object>(...)` instead for better performance">HashMap<Int, Any>()</warning>
}
protected fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int,
x: Boolean) {
// wrong signature
java.lang.String("not an error")
}
protected fun onMeasure(widthMeasureSpec: Int) {
// wrong signature
java.lang.String("not an error")
}
protected fun onLayout(changed: Boolean, left: Int, top: Int, right: Int,
bottom: Int, wrong: Int) {
// wrong signature
java.lang.String("not an error")
}
protected fun onLayout(changed: Boolean, left: Int, top: Int, right: Int) {
// wrong signature
java.lang.String("not an error")
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int,
bottom: Int) {
<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">java.lang.String("flag me")</warning>
}
@SuppressWarnings("null") // not real code
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">java.lang.String("flag me")</warning>
// Forbidden factory methods:
<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">Bitmap.createBitmap(100, 100, null)</warning>
<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">android.graphics.Bitmap.createScaledBitmap(null, 100, 100, false)</warning>
<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">BitmapFactory.decodeFile(null)</warning>
val canvas: Canvas? = null
<warning descr="Avoid object allocations during draw operations: Use `Canvas.getClipBounds(Rect)` instead of `Canvas.getClipBounds()` which allocates a temporary `Rect`">canvas!!.getClipBounds()</warning> // allocates on your behalf
<warning descr="Avoid object allocations during draw operations: Use `Canvas.getClipBounds(Rect)` instead of `Canvas.getClipBounds()` which allocates a temporary `Rect`">canvas.clipBounds</warning> // allocates on your behalf
canvas.getClipBounds(null) // NOT an error
val layoutWidth = width
val layoutHeight = height
if (mAllowCrop && (mOverlay == null || mOverlay!!.width != layoutWidth ||
mOverlay!!.height != layoutHeight)) {
mOverlay = Bitmap.createBitmap(layoutWidth, layoutHeight, Bitmap.Config.ARGB_8888)
mOverlayCanvas = Canvas(mOverlay!!)
}
if (widthMeasureSpec == 42) {
throw IllegalStateException("Test") // NOT an allocation
}
// More lazy init tests
var initialized = false
if (!initialized) {
java.lang.String("foo")
initialized = true
}
// NOT lazy initialization
if (!initialized || mOverlay == null) {
<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">java.lang.String("foo")</warning>
}
}
internal fun factories() {
val i1 = 42
val l1 = 42L
val b1 = true
val c1 = 'c'
val f1 = 1.0f
val d1 = 1.0
// The following should not generate errors:
val i3 = Integer.valueOf(42)
}
private val mAllowCrop: Boolean = false
private var mOverlayCanvas: Canvas? = null
private var mOverlay: Bitmap? = null
override fun layout(l: Int, t: Int, r: Int, b: Int) {
// Using "this." to reference fields
if (this.shader == null)
this.shader = LinearGradient(0f, 0f, width.toFloat(), 0f, intArrayOf(0), null,
Shader.TileMode.REPEAT)
val width = width
val height = height
if (shader == null || lastWidth != width || lastHeight != height) {
lastWidth = width
lastHeight = height
shader = LinearGradient(0f, 0f, width.toFloat(), 0f, intArrayOf(0), null, Shader.TileMode.REPEAT)
}
}
fun inefficientSparseArray() {
<warning descr="Use `new SparseIntArray(...)` instead for better performance">SparseArray<Int>()</warning> // Use SparseIntArray instead
SparseArray<Long>() // Use SparseLongArray instead
<warning descr="Use `new SparseBooleanArray(...)` instead for better performance">SparseArray<Boolean>()</warning> // Use SparseBooleanArray instead
SparseArray<Any>() // OK
}
fun longSparseArray() {
// but only minSdkVersion >= 17 or if has v4 support lib
val myStringMap = HashMap<Long, String>()
}
fun byteSparseArray() {
// bytes easily apply to ints
val myByteMap = <warning descr="Use `new SparseArray<String>(...)` instead for better performance">HashMap<Byte, String>()</warning>
}
}