FoldInitializerAndIfToElvisInspection: don't report when 'var' variable has no explicit type and it's used as not nullable type
#KT-38349 Fixed
This commit is contained in:
committed by
Yan Zhulanow
parent
db140b2815
commit
915dc6ce91
+14
@@ -29,14 +29,19 @@ import org.jetbrains.kotlin.idea.util.hasComments
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiChildRange
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.siblings
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.isError
|
||||
import org.jetbrains.kotlin.types.isNullable
|
||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class FoldInitializerAndIfToElvisInspection : AbstractApplicabilityBasedInspection<KtIfExpression>(KtIfExpression::class.java) {
|
||||
override fun inspectionText(element: KtIfExpression): String = KotlinBundle.message("if.null.return.break.foldable.to")
|
||||
@@ -137,6 +142,15 @@ class FoldInitializerAndIfToElvisInspection : AbstractApplicabilityBasedInspecti
|
||||
val checkedType = ifExpression.analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, typeReference]
|
||||
val variableType = (prevStatement.resolveToDescriptorIfAny() as? VariableDescriptor)?.type
|
||||
if (checkedType != null && variableType != null && !checkedType.isSubtypeOf(variableType)) return null
|
||||
} else if (prevStatement.isVar && operationExpression is KtBinaryExpression) {
|
||||
val ifEndOffset = ifExpression.endOffset
|
||||
val context = ifExpression.analyze()
|
||||
val isUsedAsNotNullable = ReferencesSearch.search(prevStatement, LocalSearchScope(prevStatement.parent)).any {
|
||||
if (it.element.startOffset <= ifEndOffset) return@any false
|
||||
val type = it.element.safeAs<KtExpression>()?.getType(context) ?: return@any false
|
||||
!type.isNullable()
|
||||
}
|
||||
if (isUsedAsNotNullable) return null
|
||||
}
|
||||
|
||||
val statement = if (then is KtBlockExpression) then.statements.singleOrNull() else then
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// PROBLEM: none
|
||||
fun test(foo: Int?, bar: Int): Int {
|
||||
var i = foo
|
||||
<caret>if (i == null) {
|
||||
return bar
|
||||
}
|
||||
return i
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// PROBLEM: none
|
||||
fun test(foo: Int?, bar: Int): Int {
|
||||
var i = foo
|
||||
<caret>if (i == null) {
|
||||
return bar
|
||||
}
|
||||
baz(i)
|
||||
val j = i + 1
|
||||
return j
|
||||
}
|
||||
|
||||
fun baz(i: Int?) {}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
fun test(foo: Int?, bar: Int): Int? {
|
||||
var i = foo
|
||||
<caret>if (i == null) {
|
||||
return bar
|
||||
}
|
||||
return i
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
fun test(foo: Int?, bar: Int): Int? {
|
||||
var i: Int? = foo ?: return bar
|
||||
return i
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
fun test(foo: Int?, bar: Int): Int {
|
||||
var i = foo
|
||||
<caret>if (i == null) {
|
||||
return bar
|
||||
}
|
||||
return baz(i)
|
||||
}
|
||||
|
||||
fun baz(i: Int?) = 1
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
fun test(foo: Int?, bar: Int): Int {
|
||||
var i: Int? = foo ?: return bar
|
||||
return baz(i)
|
||||
}
|
||||
|
||||
fun baz(i: Int?) = 1
|
||||
+20
@@ -4923,6 +4923,26 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
||||
public void testVar() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/foldInitializerAndIfToElvis/Var.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("VarUsedAsNotNullable.kt")
|
||||
public void testVarUsedAsNotNullable() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/foldInitializerAndIfToElvis/VarUsedAsNotNullable.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("VarUsedAsNotNullable2.kt")
|
||||
public void testVarUsedAsNotNullable2() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/foldInitializerAndIfToElvis/VarUsedAsNotNullable2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("VarUsedAsNullable.kt")
|
||||
public void testVarUsedAsNullable() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/foldInitializerAndIfToElvis/VarUsedAsNullable.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("VarUsedAsNullable2.kt")
|
||||
public void testVarUsedAsNullable2() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/foldInitializerAndIfToElvis/VarUsedAsNullable2.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/inspectionsLocal/forEachParameterNotUsed")
|
||||
|
||||
Reference in New Issue
Block a user