Redundant nullable return type: false negative with return expression in local function or lambda
#KT-41817 Fixed
This commit is contained in:
committed by
Vladimir Dolzhenko
parent
de3907e8cc
commit
370622087b
+6
-3
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.idea.resolve.getDataFlowValueFactory
|
|||||||
import org.jetbrains.kotlin.idea.util.textRangeIn
|
import org.jetbrains.kotlin.idea.util.textRangeIn
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypes
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -51,7 +52,7 @@ class RedundantNullableReturnTypeInspection : AbstractKotlinInspection() {
|
|||||||
is KtProperty -> declaration.initializer ?: declaration.accessors.singleOrNull { it.isGetter }?.bodyExpression
|
is KtProperty -> declaration.initializer ?: declaration.accessors.singleOrNull { it.isGetter }?.bodyExpression
|
||||||
else -> null
|
else -> null
|
||||||
} ?: return
|
} ?: return
|
||||||
val actualReturnTypes = body.actualReturnTypes()
|
val actualReturnTypes = body.actualReturnTypes(declaration)
|
||||||
if (actualReturnTypes.isEmpty() || actualReturnTypes.any { it.isNullable() }) return
|
if (actualReturnTypes.isEmpty() || actualReturnTypes.any { it.isNullable() }) return
|
||||||
|
|
||||||
val declarationName = declaration.nameAsSafeName.asString()
|
val declarationName = declaration.nameAsSafeName.asString()
|
||||||
@@ -69,12 +70,14 @@ class RedundantNullableReturnTypeInspection : AbstractKotlinInspection() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtExpression.actualReturnTypes(): List<KotlinType> {
|
private fun KtExpression.actualReturnTypes(declaration: KtDeclaration): List<KotlinType> {
|
||||||
val context = analyze()
|
val context = analyze()
|
||||||
val dataFlowValueFactory = getResolutionFacade().getDataFlowValueFactory()
|
val dataFlowValueFactory = getResolutionFacade().getDataFlowValueFactory()
|
||||||
val moduleDescriptor = findModuleDescriptor()
|
val moduleDescriptor = findModuleDescriptor()
|
||||||
val languageVersionSettings = languageVersionSettings
|
val languageVersionSettings = languageVersionSettings
|
||||||
val returnTypes = collectDescendantsOfType<KtReturnExpression>().flatMap {
|
val returnTypes = collectDescendantsOfType<KtReturnExpression> {
|
||||||
|
it.labelQualifier == null && it.getParentOfTypes(true, KtNamedFunction::class.java, KtProperty::class.java) == declaration
|
||||||
|
}.flatMap {
|
||||||
it.returnedExpression.types(context, dataFlowValueFactory, moduleDescriptor, languageVersionSettings)
|
it.returnedExpression.types(context, dataFlowValueFactory, moduleDescriptor, languageVersionSettings)
|
||||||
}
|
}
|
||||||
return if (this is KtBlockExpression) {
|
return if (this is KtBlockExpression) {
|
||||||
|
|||||||
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
fun test(list: List<Int>): Int?<caret> {
|
||||||
|
val x = list.mapNotNull {
|
||||||
|
return@mapNotNull null
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLambda.kt.after
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
fun test(list: List<Int>): Int {
|
||||||
|
val x = list.mapNotNull {
|
||||||
|
return@mapNotNull null
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
fun test(): Int?<caret> {
|
||||||
|
fun f(): Int? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
fun test(): Int {
|
||||||
|
fun f(): Int? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
+10
@@ -8249,6 +8249,16 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
|||||||
runTest("idea/testData/inspectionsLocal/redundantNullableReturnType/function/overridable.kt");
|
runTest("idea/testData/inspectionsLocal/redundantNullableReturnType/function/overridable.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnNullableForLambda.kt")
|
||||||
|
public void testReturnNullableForLambda() throws Exception {
|
||||||
|
runTest("idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLambda.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("returnNullableForLocalFunction.kt")
|
||||||
|
public void testReturnNullableForLocalFunction() throws Exception {
|
||||||
|
runTest("idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLocalFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("returnNullableFromLambdaInBlockBody.kt")
|
@TestMetadata("returnNullableFromLambdaInBlockBody.kt")
|
||||||
public void testReturnNullableFromLambdaInBlockBody() throws Exception {
|
public void testReturnNullableFromLambdaInBlockBody() throws Exception {
|
||||||
runTest("idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableFromLambdaInBlockBody.kt");
|
runTest("idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableFromLambdaInBlockBody.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user