diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/collections/FunctionUtils.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/collections/FunctionUtils.kt index b85d4b27eea..495aee6dbc5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/collections/FunctionUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/collections/FunctionUtils.kt @@ -27,12 +27,14 @@ import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getType +import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableTypeConstructor import org.jetbrains.kotlin.resolve.calls.model.ReceiverKotlinCallArgument import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedLambdaAtom import org.jetbrains.kotlin.resolve.calls.model.unwrap import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getImplicitReceiverValue import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl +import org.jetbrains.kotlin.resolve.calls.tower.SubKotlinCallArgumentImpl import org.jetbrains.kotlin.resolve.calls.tower.receiverValue import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf @@ -78,7 +80,13 @@ fun ResolvedCall<*>.hasLastFunctionalParameterWithResult(context: BindingContext // TODO: looks like hack resolvedCallAtom.subResolvedAtoms?.firstOrNull { it is ResolvedLambdaAtom }.safeAs()?.let { lambdaAtom -> return lambdaAtom.unwrap().resultArgumentsInfo!!.nonErrorArguments.filterIsInstance().all { - val type = it.receiverValue?.type ?: return@all false + val type = it.receiverValue?.type?.let { type -> + if (type.constructor is TypeVariableTypeConstructor) { + it.safeAs()?.valueArgument?.getArgumentExpression()?.getType(context) ?: type + } else { + type + } + } ?: return@all false predicate(type) } } diff --git a/idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullWithLambda5.kt b/idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullWithLambda5.kt new file mode 100644 index 00000000000..b6cdd372fac --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullWithLambda5.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME +// FIX: Change call to 'map' + +fun test(): List { + return listOf(1, 2, 3).mapNotNull { i -> + foo { + bar(i) + } + } +} + +fun foo(f: () -> T): T = f() + +fun bar(i: Int): String = "" \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullWithLambda5.kt.after b/idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullWithLambda5.kt.after new file mode 100644 index 00000000000..a1ad429c747 --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullWithLambda5.kt.after @@ -0,0 +1,14 @@ +// WITH_RUNTIME +// FIX: Change call to 'map' + +fun test(): List { + return listOf(1, 2, 3).map { i -> + foo { + bar(i) + } + } +} + +fun foo(f: () -> T): T = f() + +fun bar(i: Int): String = "" \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullWithLambdaFake2.kt b/idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullWithLambdaFake2.kt new file mode 100644 index 00000000000..c1313090532 --- /dev/null +++ b/idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullWithLambdaFake2.kt @@ -0,0 +1,13 @@ +// PROBLEM: none +// WITH_RUNTIME +fun test(): List { + return listOf(1, 2, 3).mapNotNull { i -> + foo { + bar(i) + } + } +} + +fun foo(f: () -> T): T = f() + +fun bar(i: Int): String? = null \ 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 43063af4200..a2b6c8481e2 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -2058,11 +2058,21 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { runTest("idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullWithLambda4.kt"); } + @TestMetadata("MapNotNullWithLambda5.kt") + public void testMapNotNullWithLambda5() throws Exception { + runTest("idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullWithLambda5.kt"); + } + @TestMetadata("MapNotNullWithLambdaFake.kt") public void testMapNotNullWithLambdaFake() throws Exception { runTest("idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullWithLambdaFake.kt"); } + @TestMetadata("MapNotNullWithLambdaFake2.kt") + public void testMapNotNullWithLambdaFake2() throws Exception { + runTest("idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullWithLambdaFake2.kt"); + } + @TestMetadata("MapNotNullWithReference.kt") public void testMapNotNullWithReference() throws Exception { runTest("idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullWithReference.kt");