Fix AddTargetVersionCheckQuickFix, generate else branch with TODO
when surrounded statement used as expression #KT-17786 Fixed #KT-17788 Fixed
This commit is contained in:
+12
@@ -278,6 +278,12 @@ public class AndroidLintQuickfixTestGenerated extends AbstractAndroidLintQuickfi
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("destructuringDeclaration.kt")
|
||||||
|
public void testDestructuringDeclaration() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lintQuickfix/targetVersionCheck/destructuringDeclaration.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("expressionBody.kt")
|
@TestMetadata("expressionBody.kt")
|
||||||
public void testExpressionBody() throws Exception {
|
public void testExpressionBody() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lintQuickfix/targetVersionCheck/expressionBody.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lintQuickfix/targetVersionCheck/expressionBody.kt");
|
||||||
@@ -290,6 +296,12 @@ public class AndroidLintQuickfixTestGenerated extends AbstractAndroidLintQuickfi
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("getterWIthExpressionBody.kt")
|
||||||
|
public void testGetterWIthExpressionBody() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lintQuickfix/targetVersionCheck/getterWIthExpressionBody.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("if.kt")
|
@TestMetadata("if.kt")
|
||||||
public void testIf() throws Exception {
|
public void testIf() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lintQuickfix/targetVersionCheck/if.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/android/lintQuickfix/targetVersionCheck/if.kt");
|
||||||
|
|||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// INTENTION_TEXT: Surround with if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { ... }
|
||||||
|
// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.graphics.drawable.VectorDrawable
|
||||||
|
|
||||||
|
data class ValueProvider(var p1: VectorDrawable, val p2: Int)
|
||||||
|
|
||||||
|
val activity = Activity()
|
||||||
|
fun foo() {
|
||||||
|
val (v1, v2) = ValueProvider(<caret>VectorDrawable(), 0)
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
// INTENTION_TEXT: Surround with if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { ... }
|
||||||
|
// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.graphics.drawable.VectorDrawable
|
||||||
|
import android.os.Build
|
||||||
|
|
||||||
|
data class ValueProvider(var p1: VectorDrawable, val p2: Int)
|
||||||
|
|
||||||
|
val activity = Activity()
|
||||||
|
fun foo() {
|
||||||
|
val (v1, v2) = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
ValueProvider(VectorDrawable(), 0)
|
||||||
|
} else {
|
||||||
|
TODO("VERSION.SDK_INT < LOLLIPOP")
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -7,5 +7,7 @@ import android.os.Build
|
|||||||
class VectorDrawableProvider {
|
class VectorDrawableProvider {
|
||||||
fun getVectorDrawable(): VectorDrawable = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
fun getVectorDrawable(): VectorDrawable = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
VectorDrawable()
|
VectorDrawable()
|
||||||
|
} else {
|
||||||
|
TODO("VERSION.SDK_INT < LOLLIPOP")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-2
@@ -7,8 +7,10 @@ import android.os.Build
|
|||||||
class VectorDrawableProvider {
|
class VectorDrawableProvider {
|
||||||
fun getVectorDrawable(): VectorDrawable {
|
fun getVectorDrawable(): VectorDrawable {
|
||||||
with(this) {
|
with(this) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
return VectorDrawable()
|
VectorDrawable()
|
||||||
|
} else {
|
||||||
|
TODO("VERSION.SDK_INT < LOLLIPOP")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// INTENTION_TEXT: Surround with if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { ... }
|
||||||
|
// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
|
||||||
|
|
||||||
|
import android.graphics.drawable.VectorDrawable
|
||||||
|
|
||||||
|
val v: VectorDrawable
|
||||||
|
get() = <caret>VectorDrawable()
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// INTENTION_TEXT: Surround with if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { ... }
|
||||||
|
// INSPECTION_CLASS: org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintNewApiInspection
|
||||||
|
|
||||||
|
import android.graphics.drawable.VectorDrawable
|
||||||
|
import android.os.Build
|
||||||
|
|
||||||
|
val v: VectorDrawable
|
||||||
|
get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
VectorDrawable()
|
||||||
|
} else {
|
||||||
|
TODO("VERSION.SDK_INT < LOLLIPOP")
|
||||||
|
}
|
||||||
@@ -8,8 +8,10 @@ class VectorDrawableProvider {
|
|||||||
val flag = false
|
val flag = false
|
||||||
fun getVectorDrawable(): VectorDrawable {
|
fun getVectorDrawable(): VectorDrawable {
|
||||||
if (flag)
|
if (flag)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
return VectorDrawable()
|
VectorDrawable()
|
||||||
|
} else {
|
||||||
|
TODO("VERSION.SDK_INT < LOLLIPOP")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-2
@@ -8,8 +8,10 @@ class VectorDrawableProvider {
|
|||||||
val flag = false
|
val flag = false
|
||||||
fun getVectorDrawable(): VectorDrawable {
|
fun getVectorDrawable(): VectorDrawable {
|
||||||
if (flag) {
|
if (flag) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
return VectorDrawable()
|
VectorDrawable()
|
||||||
|
} else {
|
||||||
|
TODO("VERSION.SDK_INT < LOLLIPOP")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -5,8 +5,10 @@ import android.os.Build
|
|||||||
|
|
||||||
class Test {
|
class Test {
|
||||||
fun foo(): Int {
|
fun foo(): Int {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
return android.R.attr.windowTranslucentStatus
|
android.R.attr.windowTranslucentStatus
|
||||||
|
} else {
|
||||||
|
TODO("VERSION.SDK_INT < KITKAT")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,8 +6,10 @@ import android.os.Build
|
|||||||
|
|
||||||
class VectorDrawableProvider {
|
class VectorDrawableProvider {
|
||||||
fun getVectorDrawable(): VectorDrawable {
|
fun getVectorDrawable(): VectorDrawable {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
return VectorDrawable()
|
VectorDrawable()
|
||||||
|
} else {
|
||||||
|
TODO("VERSION.SDK_INT < LOLLIPOP")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,8 @@ class VectorDrawableProvider {
|
|||||||
return when (flag) {
|
return when (flag) {
|
||||||
true -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
true -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
VectorDrawable()
|
VectorDrawable()
|
||||||
|
} else {
|
||||||
|
TODO("VERSION.SDK_INT < LOLLIPOP")
|
||||||
}
|
}
|
||||||
else -> VectorDrawable()
|
else -> VectorDrawable()
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-8
@@ -20,18 +20,17 @@ import com.intellij.codeInsight.FileModificationService
|
|||||||
import com.intellij.psi.PsiDocumentManager
|
import com.intellij.psi.PsiDocumentManager
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.util.PsiTreeUtil
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.surroundWith.statement.KotlinIfSurrounder
|
import org.jetbrains.kotlin.idea.codeInsight.surroundWith.statement.KotlinIfSurrounder
|
||||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||||
import org.jetbrains.kotlin.idea.inspections.findExistingEditor
|
import org.jetbrains.kotlin.idea.inspections.findExistingEditor
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
|
||||||
|
|
||||||
class AddTargetVersionCheckQuickFix(val api: Int) : AndroidLintQuickFix {
|
class AddTargetVersionCheckQuickFix(val api: Int) : AndroidLintQuickFix {
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val IF_SURROUNDER = KotlinIfSurrounder()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun apply(startElement: PsiElement, endElement: PsiElement, context: AndroidQuickfixContexts.Context) {
|
override fun apply(startElement: PsiElement, endElement: PsiElement, context: AndroidQuickfixContexts.Context) {
|
||||||
val targetExpression = getTargetExpression(startElement)
|
val targetExpression = getTargetExpression(startElement)
|
||||||
val project = targetExpression?.project ?: return
|
val project = targetExpression?.project ?: return
|
||||||
@@ -45,7 +44,8 @@ class AddTargetVersionCheckQuickFix(val api: Int) : AndroidLintQuickFix {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val conditionRange = IF_SURROUNDER.surroundElements(project, editor, arrayOf(targetExpression)) ?: return
|
val surrounder = getSurrounder(targetExpression, "\"VERSION.SDK_INT < ${getVersionField(api, false)}\"")
|
||||||
|
val conditionRange = surrounder.surroundElements(project, editor, arrayOf(targetExpression)) ?: return
|
||||||
val conditionText = "android.os.Build.VERSION.SDK_INT >= ${getVersionField(api, true)}"
|
val conditionText = "android.os.Build.VERSION.SDK_INT >= ${getVersionField(api, true)}"
|
||||||
document.replaceString(conditionRange.startOffset, conditionRange.endOffset, conditionText)
|
document.replaceString(conditionRange.startOffset, conditionRange.endOffset, conditionText)
|
||||||
documentManager.commitDocument(document)
|
documentManager.commitDocument(document)
|
||||||
@@ -60,14 +60,17 @@ class AddTargetVersionCheckQuickFix(val api: Int) : AndroidLintQuickFix {
|
|||||||
|
|
||||||
override fun getName(): String = "Surround with if (VERSION.SDK_INT >= VERSION_CODES.${getVersionField(api, false)}) { ... }"
|
override fun getName(): String = "Surround with if (VERSION.SDK_INT >= VERSION_CODES.${getVersionField(api, false)}) { ... }"
|
||||||
|
|
||||||
// TODO: Delegated property, initializer, annotation parameter
|
private fun getTargetExpression(element: PsiElement): KtElement? {
|
||||||
private fun getTargetExpression(element: PsiElement): PsiElement? {
|
|
||||||
var current = PsiTreeUtil.getParentOfType(element, KtExpression::class.java)
|
var current = PsiTreeUtil.getParentOfType(element, KtExpression::class.java)
|
||||||
while (current != null) {
|
while (current != null) {
|
||||||
if (current.parent is KtBlockExpression ||
|
if (current.parent is KtBlockExpression ||
|
||||||
current.parent is KtContainerNode ||
|
current.parent is KtContainerNode ||
|
||||||
current.parent is KtWhenEntry ||
|
current.parent is KtWhenEntry ||
|
||||||
current.parent is KtFunction) {
|
current.parent is KtFunction ||
|
||||||
|
current.parent is KtPropertyAccessor ||
|
||||||
|
current.parent is KtProperty ||
|
||||||
|
current.parent is KtReturnExpression ||
|
||||||
|
current.parent is KtDestructuringDeclaration) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
current = PsiTreeUtil.getParentOfType(current, KtExpression::class.java, true)
|
current = PsiTreeUtil.getParentOfType(current, KtExpression::class.java, true)
|
||||||
@@ -75,4 +78,15 @@ class AddTargetVersionCheckQuickFix(val api: Int) : AndroidLintQuickFix {
|
|||||||
|
|
||||||
return current
|
return current
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getSurrounder(element: KtElement, todoText: String?): KotlinIfSurrounder {
|
||||||
|
val used = element.analyze(BodyResolveMode.PARTIAL)[BindingContext.USED_AS_EXPRESSION, element] ?: false
|
||||||
|
return if (used) {
|
||||||
|
object : KotlinIfSurrounder() {
|
||||||
|
override fun getCodeTemplate(): String = "if (a) { \n} else {\nTODO(${todoText ?: ""})\n}"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
KotlinIfSurrounder()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user