Redundant nullable return type: fix false positive with elvis return
#KT-41878 Fixed
This commit is contained in:
committed by
Vladimir Dolzhenko
parent
51d405e950
commit
0e4bd70c29
+19
-6
@@ -22,8 +22,8 @@ import org.jetbrains.kotlin.idea.resolve.getDataFlowValueFactory
|
||||
import org.jetbrains.kotlin.idea.util.textRangeIn
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
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.bindingContextUtil.getTargetFunctionDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.isNullable
|
||||
@@ -47,12 +47,24 @@ class RedundantNullableReturnTypeInspection : AbstractKotlinInspection() {
|
||||
|
||||
if (declaration.isOverridable()) return
|
||||
|
||||
val body = when (declaration) {
|
||||
is KtNamedFunction -> declaration.bodyExpression
|
||||
is KtProperty -> declaration.initializer ?: declaration.accessors.singleOrNull { it.isGetter }?.bodyExpression
|
||||
val (body, targetDeclaration) = when (declaration) {
|
||||
is KtNamedFunction -> {
|
||||
val body = declaration.bodyExpression
|
||||
if (body != null) body to declaration else null
|
||||
}
|
||||
is KtProperty -> {
|
||||
val initializer = declaration.initializer
|
||||
val getter = declaration.accessors.singleOrNull { it.isGetter }
|
||||
val getterBody = getter?.bodyExpression
|
||||
when {
|
||||
initializer != null -> initializer to declaration
|
||||
getterBody != null -> getterBody to getter
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
else -> null
|
||||
} ?: return
|
||||
val actualReturnTypes = body.actualReturnTypes(declaration)
|
||||
val actualReturnTypes = body.actualReturnTypes(targetDeclaration)
|
||||
if (actualReturnTypes.isEmpty() || actualReturnTypes.any { it.isNullable() }) return
|
||||
|
||||
val declarationName = declaration.nameAsSafeName.asString()
|
||||
@@ -72,11 +84,12 @@ class RedundantNullableReturnTypeInspection : AbstractKotlinInspection() {
|
||||
|
||||
private fun KtExpression.actualReturnTypes(declaration: KtDeclaration): List<KotlinType> {
|
||||
val context = analyze()
|
||||
val declarationDescriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration] ?: return emptyList()
|
||||
val dataFlowValueFactory = getResolutionFacade().getDataFlowValueFactory()
|
||||
val moduleDescriptor = findModuleDescriptor()
|
||||
val languageVersionSettings = languageVersionSettings
|
||||
val returnTypes = collectDescendantsOfType<KtReturnExpression> {
|
||||
it.labelQualifier == null && it.getParentOfTypes(true, KtNamedFunction::class.java, KtProperty::class.java) == declaration
|
||||
it.labelQualifier == null && it.getTargetFunctionDescriptor(context) == declarationDescriptor
|
||||
}.flatMap {
|
||||
it.returnedExpression.types(context, dataFlowValueFactory, moduleDescriptor, languageVersionSettings)
|
||||
}
|
||||
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
// PROBLEM: none
|
||||
fun elvisFun(str: String?): String?<caret> {
|
||||
val v = str?.length ?: return null
|
||||
return v.toString()
|
||||
}
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
// PROBLEM: none
|
||||
val foo: String?<caret>
|
||||
get() {
|
||||
val s = bar() ?: return null
|
||||
return s
|
||||
}
|
||||
|
||||
fun bar(): String? = null
|
||||
+10
@@ -8269,6 +8269,11 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
||||
runTest("idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableFromLambdaInSingleExpressionBody.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("returnNullableInElvis.kt")
|
||||
public void testReturnNullableInElvis() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableInElvis.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("singleExpressionBody.kt")
|
||||
public void testSingleExpressionBody() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/redundantNullableReturnType/function/singleExpressionBody.kt");
|
||||
@@ -8312,6 +8317,11 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
||||
runTest("idea/testData/inspectionsLocal/redundantNullableReturnType/property/returnNullableFromLambdaInGetter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("returnNullableInElvis.kt")
|
||||
public void testReturnNullableInElvis() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/redundantNullableReturnType/property/returnNullableInElvis.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("var.kt")
|
||||
public void testVar() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/redundantNullableReturnType/property/var.kt");
|
||||
|
||||
Reference in New Issue
Block a user