[NI] Fix determining return type of lambda in IDEA
UselessCallOnCollection tests fixed
This commit is contained in:
committed by
Mikhail Zarechenskiy
parent
956f27cc2d
commit
6f51415b4d
@@ -26,11 +26,16 @@ import org.jetbrains.kotlin.psi.KtCallExpression
|
|||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.ReceiverKotlinCallArgument
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedLambdaAtom
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tower.receiverValue
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
fun KotlinType.isFunctionOfAnyKind() = constructor.declarationDescriptor?.getFunctionalClassKind() != null
|
fun KotlinType.isFunctionOfAnyKind() = constructor.declarationDescriptor?.getFunctionalClassKind() != null
|
||||||
|
|
||||||
@@ -65,6 +70,16 @@ fun ResolvedCall<out CallableDescriptor>.isCalling(fqName: FqName): Boolean {
|
|||||||
fun ResolvedCall<*>.hasLastFunctionalParameterWithResult(context: BindingContext, predicate: (KotlinType) -> Boolean): Boolean {
|
fun ResolvedCall<*>.hasLastFunctionalParameterWithResult(context: BindingContext, predicate: (KotlinType) -> Boolean): Boolean {
|
||||||
val lastParameter = resultingDescriptor.valueParameters.lastOrNull() ?: return false
|
val lastParameter = resultingDescriptor.valueParameters.lastOrNull() ?: return false
|
||||||
val lastArgument = valueArguments[lastParameter]?.arguments?.singleOrNull() ?: return false
|
val lastArgument = valueArguments[lastParameter]?.arguments?.singleOrNull() ?: return false
|
||||||
|
if (this is NewResolvedCallImpl<*>) {
|
||||||
|
// TODO: looks like hack
|
||||||
|
resolvedCallAtom.subResolvedAtoms.firstOrNull { it is ResolvedLambdaAtom }.safeAs<ResolvedLambdaAtom>()?.let { lambdaAtom ->
|
||||||
|
return lambdaAtom.resultArguments.filterIsInstance<ReceiverKotlinCallArgument>().all {
|
||||||
|
val type = it.receiverValue?.type ?: return@all false
|
||||||
|
predicate(type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val functionalType = lastArgument.getArgumentExpression()?.getType(context) ?: return false
|
val functionalType = lastArgument.getArgumentExpression()?.getType(context) ?: return false
|
||||||
// Both Function & KFunction must pass here
|
// Both Function & KFunction must pass here
|
||||||
if (!functionalType.isFunctionOfAnyKind()) return false
|
if (!functionalType.isFunctionOfAnyKind()) return false
|
||||||
|
|||||||
Reference in New Issue
Block a user