Refactoring: extract KtCallExpression.isCall(FqName) function
This commit is contained in:
committed by
Mikhail Glukhikh
parent
9a725b99b2
commit
416d33fc92
+4
-8
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.inspections.collections
|
||||
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtQualifiedExpression
|
||||
@@ -36,9 +37,7 @@ abstract class AbstractCallChainChecker : AbstractKotlinInspection() {
|
||||
|
||||
val context = expression.analyze()
|
||||
val firstResolvedCall = firstExpression.getResolvedCall(context) ?: return null
|
||||
val conversion = actualConversions.firstOrNull {
|
||||
firstResolvedCall.resultingDescriptor.fqNameOrNull()?.asString() == it.firstFqName
|
||||
} ?: return null
|
||||
val conversion = actualConversions.firstOrNull { firstResolvedCall.isCalling(FqName(it.firstFqName)) } ?: return null
|
||||
val secondResolvedCall = expression.getResolvedCall(context) ?: return null
|
||||
|
||||
if (!additionalCallCheck(conversion, firstResolvedCall, secondResolvedCall, context)) return null
|
||||
@@ -47,8 +46,7 @@ abstract class AbstractCallChainChecker : AbstractKotlinInspection() {
|
||||
val lambdaArgument = firstCallExpression.lambdaArguments.firstOrNull()
|
||||
if (lambdaArgument?.anyDescendantOfType<KtReturnExpression>() == true) return null
|
||||
|
||||
val secondResultingDescriptor = secondResolvedCall.resultingDescriptor
|
||||
if (secondResultingDescriptor.fqNameOrNull()?.asString() != conversion.secondFqName) return null
|
||||
if (!secondResolvedCall.isCalling(FqName(conversion.secondFqName))) return null
|
||||
if (secondResolvedCall.valueArguments.any { (parameter, resolvedArgument) ->
|
||||
parameter.type.isFunctionOfAnyKind() &&
|
||||
resolvedArgument !is DefaultValueArgument
|
||||
@@ -84,8 +82,6 @@ abstract class AbstractCallChainChecker : AbstractKotlinInspection() {
|
||||
|
||||
fun getCallExpression(firstExpression: KtExpression) =
|
||||
(firstExpression as? KtQualifiedExpression)?.selectorExpression as? KtCallExpression
|
||||
?: firstExpression as? KtCallExpression
|
||||
|
||||
|
||||
?: firstExpression as? KtCallExpression
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -199,17 +199,17 @@ private fun KtCallExpression.hasReturn(): Boolean = valueArguments.any { arg ->
|
||||
|
||||
private fun KtCallExpression.isTransformationOrTermination(context: BindingContext): Boolean {
|
||||
val fqName = transformationAndTerminations[calleeExpression?.text] ?: return false
|
||||
return fqName == getResolvedCall(context)?.resultingDescriptor?.fqNameSafe
|
||||
return isCalling(fqName, context)
|
||||
}
|
||||
|
||||
private fun KtCallExpression.isTermination(context: BindingContext): Boolean {
|
||||
val fqName = terminations[calleeExpression?.text] ?: return false
|
||||
return fqName == getResolvedCall(context)?.resultingDescriptor?.fqNameSafe
|
||||
return isCalling(fqName, context)
|
||||
}
|
||||
|
||||
private fun KtCallExpression.isLazyTermination(context: BindingContext): Boolean {
|
||||
val fqName = lazyTerminations[calleeExpression?.text] ?: return false
|
||||
return fqName == getResolvedCall(context)?.resultingDescriptor?.fqNameSafe
|
||||
return isCalling(fqName, context)
|
||||
}
|
||||
|
||||
private val transformations = listOf(
|
||||
|
||||
+1
-3
@@ -23,9 +23,7 @@ class ConvertFlatMapToFlattenInspection : AbstractKotlinInspection() {
|
||||
qualifiedExpressionVisitor(fun(expression) {
|
||||
val callExpression = expression.selectorExpression as? KtCallExpression ?: return
|
||||
val calleeExpression = callExpression.calleeExpression ?: return
|
||||
if (calleeExpression.text != "flatMap") return
|
||||
val context = expression.analyze(BodyResolveMode.PARTIAL)
|
||||
if (FqName("kotlin.collections.flatMap") != callExpression.getResolvedCall(context)?.resultingDescriptor?.fqNameSafe) return
|
||||
if (!callExpression.isCalling(FqName("kotlin.collections.flatMap"))) return
|
||||
|
||||
val argument = callExpression.valueArguments.singleOrNull() ?: return
|
||||
val lambdaExpression = (argument as? KtLambdaArgument)?.getLambdaExpression()
|
||||
|
||||
@@ -18,11 +18,18 @@ package org.jetbrains.kotlin.idea.inspections.collections
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.getFunctionalClassKind
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
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.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
fun KotlinType.isFunctionOfAnyKind() = constructor.declarationDescriptor?.getFunctionalClassKind() != null
|
||||
@@ -32,6 +39,16 @@ fun KotlinType?.isMap(builtIns: KotlinBuiltIns): Boolean {
|
||||
return classDescriptor.name.asString().endsWith("Map") && classDescriptor.isSubclassOf(builtIns.map)
|
||||
}
|
||||
|
||||
fun KtCallExpression.isCalling(fqName: FqName, context: BindingContext = analyze(BodyResolveMode.PARTIAL)): Boolean {
|
||||
val function = fqName.asString().takeLastWhile { it != '.' }
|
||||
if (calleeExpression?.text != function) return false
|
||||
return getResolvedCall(context)?.isCalling(fqName) == true
|
||||
}
|
||||
|
||||
fun ResolvedCall<out CallableDescriptor>.isCalling(fqName: FqName): Boolean {
|
||||
return resultingDescriptor.fqNameSafe == fqName
|
||||
}
|
||||
|
||||
fun ResolvedCall<*>.hasLastFunctionalParameterWithResult(context: BindingContext, predicate: (KotlinType) -> Boolean): Boolean {
|
||||
val lastParameter = resultingDescriptor.valueParameters.lastOrNull() ?: return false
|
||||
val lastArgument = valueArguments[lastParameter]?.arguments?.singleOrNull() ?: return false
|
||||
|
||||
Reference in New Issue
Block a user