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.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
|
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
import org.jetbrains.kotlin.psi.KtQualifiedExpression
|
import org.jetbrains.kotlin.psi.KtQualifiedExpression
|
||||||
@@ -36,9 +37,7 @@ abstract class AbstractCallChainChecker : AbstractKotlinInspection() {
|
|||||||
|
|
||||||
val context = expression.analyze()
|
val context = expression.analyze()
|
||||||
val firstResolvedCall = firstExpression.getResolvedCall(context) ?: return null
|
val firstResolvedCall = firstExpression.getResolvedCall(context) ?: return null
|
||||||
val conversion = actualConversions.firstOrNull {
|
val conversion = actualConversions.firstOrNull { firstResolvedCall.isCalling(FqName(it.firstFqName)) } ?: return null
|
||||||
firstResolvedCall.resultingDescriptor.fqNameOrNull()?.asString() == it.firstFqName
|
|
||||||
} ?: return null
|
|
||||||
val secondResolvedCall = expression.getResolvedCall(context) ?: return null
|
val secondResolvedCall = expression.getResolvedCall(context) ?: return null
|
||||||
|
|
||||||
if (!additionalCallCheck(conversion, firstResolvedCall, secondResolvedCall, context)) return null
|
if (!additionalCallCheck(conversion, firstResolvedCall, secondResolvedCall, context)) return null
|
||||||
@@ -47,8 +46,7 @@ abstract class AbstractCallChainChecker : AbstractKotlinInspection() {
|
|||||||
val lambdaArgument = firstCallExpression.lambdaArguments.firstOrNull()
|
val lambdaArgument = firstCallExpression.lambdaArguments.firstOrNull()
|
||||||
if (lambdaArgument?.anyDescendantOfType<KtReturnExpression>() == true) return null
|
if (lambdaArgument?.anyDescendantOfType<KtReturnExpression>() == true) return null
|
||||||
|
|
||||||
val secondResultingDescriptor = secondResolvedCall.resultingDescriptor
|
if (!secondResolvedCall.isCalling(FqName(conversion.secondFqName))) return null
|
||||||
if (secondResultingDescriptor.fqNameOrNull()?.asString() != conversion.secondFqName) return null
|
|
||||||
if (secondResolvedCall.valueArguments.any { (parameter, resolvedArgument) ->
|
if (secondResolvedCall.valueArguments.any { (parameter, resolvedArgument) ->
|
||||||
parameter.type.isFunctionOfAnyKind() &&
|
parameter.type.isFunctionOfAnyKind() &&
|
||||||
resolvedArgument !is DefaultValueArgument
|
resolvedArgument !is DefaultValueArgument
|
||||||
@@ -84,8 +82,6 @@ abstract class AbstractCallChainChecker : AbstractKotlinInspection() {
|
|||||||
|
|
||||||
fun getCallExpression(firstExpression: KtExpression) =
|
fun getCallExpression(firstExpression: KtExpression) =
|
||||||
(firstExpression as? KtQualifiedExpression)?.selectorExpression as? KtCallExpression
|
(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 {
|
private fun KtCallExpression.isTransformationOrTermination(context: BindingContext): Boolean {
|
||||||
val fqName = transformationAndTerminations[calleeExpression?.text] ?: return false
|
val fqName = transformationAndTerminations[calleeExpression?.text] ?: return false
|
||||||
return fqName == getResolvedCall(context)?.resultingDescriptor?.fqNameSafe
|
return isCalling(fqName, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtCallExpression.isTermination(context: BindingContext): Boolean {
|
private fun KtCallExpression.isTermination(context: BindingContext): Boolean {
|
||||||
val fqName = terminations[calleeExpression?.text] ?: return false
|
val fqName = terminations[calleeExpression?.text] ?: return false
|
||||||
return fqName == getResolvedCall(context)?.resultingDescriptor?.fqNameSafe
|
return isCalling(fqName, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtCallExpression.isLazyTermination(context: BindingContext): Boolean {
|
private fun KtCallExpression.isLazyTermination(context: BindingContext): Boolean {
|
||||||
val fqName = lazyTerminations[calleeExpression?.text] ?: return false
|
val fqName = lazyTerminations[calleeExpression?.text] ?: return false
|
||||||
return fqName == getResolvedCall(context)?.resultingDescriptor?.fqNameSafe
|
return isCalling(fqName, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val transformations = listOf(
|
private val transformations = listOf(
|
||||||
|
|||||||
+1
-3
@@ -23,9 +23,7 @@ class ConvertFlatMapToFlattenInspection : AbstractKotlinInspection() {
|
|||||||
qualifiedExpressionVisitor(fun(expression) {
|
qualifiedExpressionVisitor(fun(expression) {
|
||||||
val callExpression = expression.selectorExpression as? KtCallExpression ?: return
|
val callExpression = expression.selectorExpression as? KtCallExpression ?: return
|
||||||
val calleeExpression = callExpression.calleeExpression ?: return
|
val calleeExpression = callExpression.calleeExpression ?: return
|
||||||
if (calleeExpression.text != "flatMap") return
|
if (!callExpression.isCalling(FqName("kotlin.collections.flatMap"))) return
|
||||||
val context = expression.analyze(BodyResolveMode.PARTIAL)
|
|
||||||
if (FqName("kotlin.collections.flatMap") != callExpression.getResolvedCall(context)?.resultingDescriptor?.fqNameSafe) return
|
|
||||||
|
|
||||||
val argument = callExpression.valueArguments.singleOrNull() ?: return
|
val argument = callExpression.valueArguments.singleOrNull() ?: return
|
||||||
val lambdaExpression = (argument as? KtLambdaArgument)?.getLambdaExpression()
|
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.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.getFunctionalClassKind
|
import org.jetbrains.kotlin.builtins.getFunctionalClassKind
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
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.BindingContext
|
||||||
|
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.ResolvedCall
|
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.descriptorUtil.isSubclassOf
|
||||||
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
fun KotlinType.isFunctionOfAnyKind() = constructor.declarationDescriptor?.getFunctionalClassKind() != null
|
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)
|
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 {
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user