Call chain into sequence refactoring: introduce & use isIterable

Related to KT-26650
This commit is contained in:
Toshiaki Kameyama
2018-10-09 05:46:52 +03:00
committed by Mikhail Glukhikh
parent 416d33fc92
commit f22133be7e
2 changed files with 10 additions and 5 deletions
@@ -16,7 +16,6 @@ import com.intellij.openapi.ui.LabeledComponent
import com.intellij.psi.PsiWhiteSpace
import com.intellij.ui.EditorTextField
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
@@ -28,11 +27,8 @@ import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getImplicitReceiverValue
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.resolve.scopes.receivers.ImplicitReceiver
import org.jetbrains.kotlin.types.KotlinType
import java.awt.BorderLayout
import javax.swing.JPanel
@@ -154,7 +150,7 @@ private fun KtQualifiedExpression.findCallChain(): CallChain? {
val receiverType =
(lastCall.getQualifiedExpressionForSelector())?.receiverExpression?.getResolvedCall(context)?.resultingDescriptor?.returnType
?: lastCall.implicitReceiver(context)?.type
if (receiverType?.isMap(DefaultBuiltIns.Instance) == true) return null
if (receiverType?.isIterable(DefaultBuiltIns.Instance) != true) return null
val firstCall = calls.first()
val qualified = firstCall.getQualifiedExpressionForSelector() ?: firstCall.getQualifiedExpressionForReceiver() ?: return null
@@ -39,6 +39,15 @@ fun KotlinType?.isMap(builtIns: KotlinBuiltIns): Boolean {
return classDescriptor.name.asString().endsWith("Map") && classDescriptor.isSubclassOf(builtIns.map)
}
fun KotlinType?.isIterable(builtIns: KotlinBuiltIns): Boolean {
val classDescriptor = this?.constructor?.declarationDescriptor as? ClassDescriptor ?: return false
val className = classDescriptor.name.asString()
// First two lines are just to make things faster
return className.endsWith("List") && classDescriptor.isSubclassOf(builtIns.list)
|| className.endsWith("Set") && classDescriptor.isSubclassOf(builtIns.set)
|| classDescriptor.isSubclassOf(builtIns.iterable)
}
fun KtCallExpression.isCalling(fqName: FqName, context: BindingContext = analyze(BodyResolveMode.PARTIAL)): Boolean {
val function = fqName.asString().takeLastWhile { it != '.' }
if (calleeExpression?.text != function) return false