From 370622087b57621a2ed282ca0c475d48d6e5cb55 Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Fri, 11 Sep 2020 10:22:32 +0900 Subject: [PATCH] Redundant nullable return type: false negative with return expression in local function or lambda #KT-41817 Fixed --- .../RedundantNullableReturnTypeInspection.kt | 9 ++++++--- .../function/returnNullableForLambda.kt | 7 +++++++ .../function/returnNullableForLambda.kt.after | 7 +++++++ .../function/returnNullableForLocalFunction.kt | 6 ++++++ .../function/returnNullableForLocalFunction.kt.after | 6 ++++++ .../idea/inspections/LocalInspectionTestGenerated.java | 10 ++++++++++ 6 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLambda.kt create mode 100644 idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLambda.kt.after create mode 100644 idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLocalFunction.kt create mode 100644 idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLocalFunction.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantNullableReturnTypeInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantNullableReturnTypeInspection.kt index 33470bfc281..47083e37281 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantNullableReturnTypeInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantNullableReturnTypeInspection.kt @@ -22,6 +22,7 @@ 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.calls.smartcasts.DataFlowValueFactory import org.jetbrains.kotlin.types.KotlinType @@ -51,7 +52,7 @@ class RedundantNullableReturnTypeInspection : AbstractKotlinInspection() { is KtProperty -> declaration.initializer ?: declaration.accessors.singleOrNull { it.isGetter }?.bodyExpression else -> null } ?: return - val actualReturnTypes = body.actualReturnTypes() + val actualReturnTypes = body.actualReturnTypes(declaration) if (actualReturnTypes.isEmpty() || actualReturnTypes.any { it.isNullable() }) return val declarationName = declaration.nameAsSafeName.asString() @@ -69,12 +70,14 @@ class RedundantNullableReturnTypeInspection : AbstractKotlinInspection() { } } - private fun KtExpression.actualReturnTypes(): List { + private fun KtExpression.actualReturnTypes(declaration: KtDeclaration): List { val context = analyze() val dataFlowValueFactory = getResolutionFacade().getDataFlowValueFactory() val moduleDescriptor = findModuleDescriptor() val languageVersionSettings = languageVersionSettings - val returnTypes = collectDescendantsOfType().flatMap { + val returnTypes = collectDescendantsOfType { + it.labelQualifier == null && it.getParentOfTypes(true, KtNamedFunction::class.java, KtProperty::class.java) == declaration + }.flatMap { it.returnedExpression.types(context, dataFlowValueFactory, moduleDescriptor, languageVersionSettings) } return if (this is KtBlockExpression) { diff --git a/idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLambda.kt b/idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLambda.kt new file mode 100644 index 00000000000..87d46cfcbdb --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLambda.kt @@ -0,0 +1,7 @@ +// WITH_RUNTIME +fun test(list: List): Int? { + val x = list.mapNotNull { + return@mapNotNull null + } + return 1 +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLambda.kt.after b/idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLambda.kt.after new file mode 100644 index 00000000000..cc1f3dd617a --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLambda.kt.after @@ -0,0 +1,7 @@ +// WITH_RUNTIME +fun test(list: List): Int { + val x = list.mapNotNull { + return@mapNotNull null + } + return 1 +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLocalFunction.kt b/idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLocalFunction.kt new file mode 100644 index 00000000000..aa07dbd6558 --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLocalFunction.kt @@ -0,0 +1,6 @@ +fun test(): Int? { + fun f(): Int? { + return null + } + return 1 +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLocalFunction.kt.after b/idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLocalFunction.kt.after new file mode 100644 index 00000000000..185c8550030 --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableForLocalFunction.kt.after @@ -0,0 +1,6 @@ +fun test(): Int { + fun f(): Int? { + return null + } + return 1 +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index e1183f17a25..679a47e4731 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -8249,6 +8249,16 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { 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") public void testReturnNullableFromLambdaInBlockBody() throws Exception { runTest("idea/testData/inspectionsLocal/redundantNullableReturnType/function/returnNullableFromLambdaInBlockBody.kt");