Moving declarations
This commit is contained in:
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.slicer
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiCall
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiMethod
|
||||||
|
import com.intellij.slicer.SliceUsage
|
||||||
|
import com.intellij.usageView.UsageInfo
|
||||||
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
||||||
|
import org.jetbrains.kotlin.psi.KtCallElement
|
||||||
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
|
import org.jetbrains.kotlin.psi.KtParameter
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
||||||
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
|
|
||||||
|
@Suppress("DataClassPrivateConstructor") // we have modifier data to get equals&hashCode only
|
||||||
|
data class ArgumentSliceProducer private constructor(
|
||||||
|
private val parameterIndex: Int,
|
||||||
|
private val isExtension: Boolean
|
||||||
|
) : SliceProducer
|
||||||
|
{
|
||||||
|
constructor(parameterDescriptor: ValueParameterDescriptor) : this(
|
||||||
|
parameterDescriptor.index,
|
||||||
|
parameterDescriptor.containingDeclaration.isExtension
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun produce(usage: UsageInfo, behaviour: KotlinSliceUsage.SpecialBehaviour?, parent: SliceUsage): Collection<SliceUsage>? {
|
||||||
|
val element = usage.element ?: return emptyList()
|
||||||
|
val argumentExpression = extractArgumentExpression(element) ?: return emptyList()
|
||||||
|
return listOf(KotlinSliceUsage(argumentExpression, parent, behaviour, forcedExpressionMode = true))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun extractArgumentExpression(refElement: PsiElement): PsiElement? {
|
||||||
|
val refParent = refElement.parent
|
||||||
|
return when {
|
||||||
|
refElement is KtExpression -> {
|
||||||
|
val callElement = refElement as? KtCallElement
|
||||||
|
?: refElement.getParentOfTypeAndBranch { calleeExpression }
|
||||||
|
?: return null
|
||||||
|
val resolvedCall = callElement.resolveToCall() ?: return null
|
||||||
|
val resultingDescriptor = resolvedCall.resultingDescriptor
|
||||||
|
val parameterIndexToUse = parameterIndex +
|
||||||
|
(if (isExtension && resultingDescriptor.extensionReceiverParameter == null) 1 else 0)
|
||||||
|
val parameterDescriptor = resultingDescriptor.valueParameters[parameterIndexToUse]
|
||||||
|
val resolvedArgument = resolvedCall.valueArguments[parameterDescriptor] ?: return null
|
||||||
|
when (resolvedArgument) {
|
||||||
|
is DefaultValueArgument -> (parameterDescriptor.source.getPsi() as? KtParameter)?.defaultValue
|
||||||
|
is ExpressionValueArgument -> resolvedArgument.valueArgument?.getArgumentExpression()
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
refParent is PsiCall -> refParent.argumentList?.expressions?.getOrNull(parameterIndex + (if (isExtension) 1 else 0))
|
||||||
|
|
||||||
|
refElement is PsiMethod -> refElement.parameterList.parameters.getOrNull(parameterIndex + (if (isExtension) 1 else 0))
|
||||||
|
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.slicer
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.impl.light.LightMemberReference
|
||||||
|
import com.intellij.slicer.SliceUsage
|
||||||
|
import com.intellij.usageView.UsageInfo
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||||
|
|
||||||
|
object CallSliceProducer : SliceProducer {
|
||||||
|
override fun produce(usage: UsageInfo, behaviour: KotlinSliceUsage.SpecialBehaviour?, parent: SliceUsage): Collection<SliceUsage>? {
|
||||||
|
when (val refElement = usage.element) {
|
||||||
|
null -> {
|
||||||
|
val element = (usage.reference as? LightMemberReference)?.element ?: return emptyList()
|
||||||
|
return listOf(KotlinSliceUsage(element, parent, behaviour, false))
|
||||||
|
}
|
||||||
|
|
||||||
|
is KtExpression -> {
|
||||||
|
return mutableListOf<SliceUsage>().apply {
|
||||||
|
refElement.getCallElementForExactCallee()
|
||||||
|
?.let { this += KotlinSliceUsage(it, parent, behaviour, false) }
|
||||||
|
refElement.getCallableReferenceForExactCallee()
|
||||||
|
?.let { this += KotlinSliceUsage(it, parent, LambdaCallsBehaviour(SliceProducer.Trivial, behaviour), false) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
return null // unknown type of usage - return null to process it "as is"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?) = other === this
|
||||||
|
override fun hashCode() = 0
|
||||||
|
|
||||||
|
private fun PsiElement.getCallElementForExactCallee(): PsiElement? {
|
||||||
|
if (this is KtArrayAccessExpression) return this
|
||||||
|
|
||||||
|
val operationRefExpr = getNonStrictParentOfType<KtOperationReferenceExpression>()
|
||||||
|
if (operationRefExpr != null) return operationRefExpr.parent as? KtOperationExpression
|
||||||
|
|
||||||
|
val parentCall = getParentOfTypeAndBranch<KtCallElement> { calleeExpression } ?: return null
|
||||||
|
val callee = parentCall.calleeExpression?.let { KtPsiUtil.safeDeparenthesize(it) }
|
||||||
|
if (callee == this || callee is KtConstructorCalleeExpression && callee.isAncestor(this, strict = true)) return parentCall
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun PsiElement.getCallableReferenceForExactCallee(): KtCallableReferenceExpression? {
|
||||||
|
val callableRef = getParentOfTypeAndBranch<KtCallableReferenceExpression> { callableReference } ?: return null
|
||||||
|
val callee = KtPsiUtil.safeDeparenthesize(callableRef.callableReference)
|
||||||
|
return if (callee == this) callableRef else null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,11 +7,9 @@ package org.jetbrains.kotlin.idea.slicer
|
|||||||
|
|
||||||
import com.intellij.psi.PsiCall
|
import com.intellij.psi.PsiCall
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiMethod
|
|
||||||
import com.intellij.psi.search.LocalSearchScope
|
import com.intellij.psi.search.LocalSearchScope
|
||||||
import com.intellij.psi.search.SearchScope
|
import com.intellij.psi.search.SearchScope
|
||||||
import com.intellij.psi.search.searches.ReferencesSearch
|
import com.intellij.psi.search.searches.ReferencesSearch
|
||||||
import com.intellij.slicer.SliceUsage
|
|
||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
||||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
||||||
@@ -37,15 +35,10 @@ import org.jetbrains.kotlin.idea.util.isExpectDeclaration
|
|||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
|
import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
|
|
||||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
@@ -327,101 +320,4 @@ class InflowSlicer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@Suppress("DataClassPrivateConstructor") // we have modifier data to get equals&hashCode only
|
|
||||||
private data class ArgumentSliceProducer private constructor(
|
|
||||||
private val parameterIndex: Int,
|
|
||||||
private val isExtension: Boolean
|
|
||||||
) : SliceProducer
|
|
||||||
{
|
|
||||||
constructor(parameterDescriptor: ValueParameterDescriptor) : this(
|
|
||||||
parameterDescriptor.index,
|
|
||||||
parameterDescriptor.containingDeclaration.isExtension
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun produce(
|
|
||||||
usage: UsageInfo,
|
|
||||||
behaviour: KotlinSliceUsage.SpecialBehaviour?,
|
|
||||||
parent: SliceUsage
|
|
||||||
): Collection<SliceUsage>? {
|
|
||||||
val element = usage.element ?: return emptyList()
|
|
||||||
val argumentExpression = extractArgumentExpression(element) ?: return emptyList()
|
|
||||||
return listOf(KotlinSliceUsage(argumentExpression, parent, behaviour, forcedExpressionMode = true))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun extractArgumentExpression(refElement: PsiElement): PsiElement? {
|
|
||||||
val refParent = refElement.parent
|
|
||||||
return when {
|
|
||||||
refElement is KtExpression -> {
|
|
||||||
val callElement = refElement as? KtCallElement
|
|
||||||
?: refElement.getParentOfTypeAndBranch { calleeExpression }
|
|
||||||
?: return null
|
|
||||||
val resolvedCall = callElement.resolveToCall() ?: return null
|
|
||||||
val resultingDescriptor = resolvedCall.resultingDescriptor
|
|
||||||
val parameterIndexToUse = parameterIndex +
|
|
||||||
(if (isExtension && resultingDescriptor.extensionReceiverParameter == null) 1 else 0)
|
|
||||||
val parameterDescriptor = resultingDescriptor.valueParameters[parameterIndexToUse]
|
|
||||||
val resolvedArgument = resolvedCall.valueArguments[parameterDescriptor] ?: return null
|
|
||||||
when (resolvedArgument) {
|
|
||||||
is DefaultValueArgument -> (parameterDescriptor.source.getPsi() as? KtParameter)?.defaultValue
|
|
||||||
is ExpressionValueArgument -> resolvedArgument.valueArgument?.getArgumentExpression()
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
refParent is PsiCall -> refParent.argumentList?.expressions?.getOrNull(parameterIndex + (if (isExtension) 1 else 0))
|
|
||||||
|
|
||||||
refElement is PsiMethod -> refElement.parameterList.parameters.getOrNull(parameterIndex + (if (isExtension) 1 else 0))
|
|
||||||
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private object ReceiverSliceProducer : SliceProducer {
|
|
||||||
override fun produce(
|
|
||||||
usage: UsageInfo,
|
|
||||||
behaviour: KotlinSliceUsage.SpecialBehaviour?,
|
|
||||||
parent: SliceUsage
|
|
||||||
): Collection<SliceUsage>? {
|
|
||||||
val refElement = usage.element ?: return emptyList()
|
|
||||||
when (refElement) {
|
|
||||||
is KtExpression -> {
|
|
||||||
val resolvedCall = refElement.resolveToCall() ?: return emptyList()
|
|
||||||
when (val receiver = resolvedCall.extensionReceiver) {
|
|
||||||
is ExpressionReceiver -> {
|
|
||||||
return listOf(KotlinSliceUsage(receiver.expression, parent, behaviour, forcedExpressionMode = true))
|
|
||||||
}
|
|
||||||
|
|
||||||
is ImplicitReceiver -> {
|
|
||||||
val callableDescriptor = receiver.declarationDescriptor as? CallableDescriptor ?: return emptyList()
|
|
||||||
when (val callableDeclaration = callableDescriptor.originalSource.getPsi()) {
|
|
||||||
is KtFunctionLiteral -> {
|
|
||||||
val newBehaviour = LambdaCallsBehaviour(ReceiverSliceProducer, behaviour)
|
|
||||||
return listOf(KotlinSliceUsage(callableDeclaration, parent, newBehaviour, forcedExpressionMode = true))
|
|
||||||
}
|
|
||||||
|
|
||||||
is KtCallableDeclaration -> {
|
|
||||||
val receiverTypeReference = callableDeclaration.receiverTypeReference ?: return emptyList()
|
|
||||||
return listOf(KotlinSliceUsage(receiverTypeReference, parent, behaviour, false))
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> return emptyList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> return emptyList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
|
||||||
val argument = (refElement.parent as? PsiCall)?.argumentList?.expressions?.getOrNull(0) ?: return emptyList()
|
|
||||||
return listOf(KotlinSliceUsage(argument, parent, behaviour, true))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun equals(other: Any?) = other === this
|
|
||||||
override fun hashCode() = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,10 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.idea.slicer
|
package org.jetbrains.kotlin.idea.slicer
|
||||||
|
|
||||||
import com.intellij.codeInsight.highlighting.ReadWriteAccessDetector.Access
|
import com.intellij.codeInsight.highlighting.ReadWriteAccessDetector.Access
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import com.intellij.psi.PsiMethod
|
import com.intellij.psi.PsiMethod
|
||||||
import com.intellij.psi.impl.light.LightMemberReference
|
|
||||||
import com.intellij.slicer.SliceUsage
|
|
||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue
|
import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
|
||||||
@@ -27,7 +24,8 @@ import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReadWriteAccessDete
|
|||||||
import org.jetbrains.kotlin.idea.util.actualsForExpected
|
import org.jetbrains.kotlin.idea.util.actualsForExpected
|
||||||
import org.jetbrains.kotlin.idea.util.isExpectDeclaration
|
import org.jetbrains.kotlin.idea.util.isExpectDeclaration
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.parameterIndex
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
|
|
||||||
@@ -267,54 +265,4 @@ class OutflowSlicer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private object CallSliceProducer : SliceProducer {
|
|
||||||
override fun produce(
|
|
||||||
usage: UsageInfo,
|
|
||||||
behaviour: KotlinSliceUsage.SpecialBehaviour?,
|
|
||||||
parent: SliceUsage
|
|
||||||
): Collection<SliceUsage>? {
|
|
||||||
when (val refElement = usage.element) {
|
|
||||||
null -> {
|
|
||||||
val element = (usage.reference as? LightMemberReference)?.element ?: return emptyList()
|
|
||||||
return listOf(KotlinSliceUsage(element, parent, behaviour, false))
|
|
||||||
}
|
|
||||||
|
|
||||||
is KtExpression -> {
|
|
||||||
return mutableListOf<SliceUsage>().apply {
|
|
||||||
refElement.getCallElementForExactCallee()
|
|
||||||
?.let { this += KotlinSliceUsage(it, parent, behaviour, false) }
|
|
||||||
refElement.getCallableReferenceForExactCallee()
|
|
||||||
?.let { this += KotlinSliceUsage(it, parent, LambdaCallsBehaviour(SliceProducer.Trivial, behaviour), false) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
|
||||||
return null // unknown type of usage - return null to process it "as is"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun equals(other: Any?) = other === this
|
|
||||||
override fun hashCode() = 0
|
|
||||||
|
|
||||||
private fun PsiElement.getCallElementForExactCallee(): PsiElement? {
|
|
||||||
if (this is KtArrayAccessExpression) return this
|
|
||||||
|
|
||||||
val operationRefExpr = getNonStrictParentOfType<KtOperationReferenceExpression>()
|
|
||||||
if (operationRefExpr != null) return operationRefExpr.parent as? KtOperationExpression
|
|
||||||
|
|
||||||
val parentCall = getParentOfTypeAndBranch<KtCallElement> { calleeExpression } ?: return null
|
|
||||||
val callee = parentCall.calleeExpression?.let { KtPsiUtil.safeDeparenthesize(it) }
|
|
||||||
if (callee == this || callee is KtConstructorCalleeExpression && callee.isAncestor(this, strict = true)) return parentCall
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun PsiElement.getCallableReferenceForExactCallee(): KtCallableReferenceExpression? {
|
|
||||||
val callableRef = getParentOfTypeAndBranch<KtCallableReferenceExpression> { callableReference } ?: return null
|
|
||||||
val callee = KtPsiUtil.safeDeparenthesize(callableRef.callableReference)
|
|
||||||
return if (callee == this) callableRef else null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.slicer
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiCall
|
||||||
|
import com.intellij.slicer.SliceUsage
|
||||||
|
import com.intellij.usageView.UsageInfo
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
||||||
|
import org.jetbrains.kotlin.psi.KtCallableDeclaration
|
||||||
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
|
import org.jetbrains.kotlin.psi.KtFunctionLiteral
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
|
||||||
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
|
|
||||||
|
object ReceiverSliceProducer : SliceProducer {
|
||||||
|
override fun produce(usage: UsageInfo, behaviour: KotlinSliceUsage.SpecialBehaviour?, parent: SliceUsage): Collection<SliceUsage>? {
|
||||||
|
val refElement = usage.element ?: return emptyList()
|
||||||
|
when (refElement) {
|
||||||
|
is KtExpression -> {
|
||||||
|
val resolvedCall = refElement.resolveToCall() ?: return emptyList()
|
||||||
|
when (val receiver = resolvedCall.extensionReceiver) {
|
||||||
|
is ExpressionReceiver -> {
|
||||||
|
return listOf(KotlinSliceUsage(receiver.expression, parent, behaviour, forcedExpressionMode = true))
|
||||||
|
}
|
||||||
|
|
||||||
|
is ImplicitReceiver -> {
|
||||||
|
val callableDescriptor = receiver.declarationDescriptor as? CallableDescriptor
|
||||||
|
?: return emptyList()
|
||||||
|
when (val callableDeclaration = callableDescriptor.originalSource.getPsi()) {
|
||||||
|
is KtFunctionLiteral -> {
|
||||||
|
val newBehaviour = LambdaCallsBehaviour(ReceiverSliceProducer, behaviour)
|
||||||
|
return listOf(KotlinSliceUsage(callableDeclaration, parent, newBehaviour, forcedExpressionMode = true))
|
||||||
|
}
|
||||||
|
|
||||||
|
is KtCallableDeclaration -> {
|
||||||
|
val receiverTypeReference = callableDeclaration.receiverTypeReference ?: return emptyList()
|
||||||
|
return listOf(KotlinSliceUsage(receiverTypeReference, parent, behaviour, false))
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> return emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> return emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
val argument = (refElement.parent as? PsiCall)?.argumentList?.expressions?.getOrNull(0) ?: return emptyList()
|
||||||
|
return listOf(KotlinSliceUsage(argument, parent, behaviour, true))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?) = other === this
|
||||||
|
override fun hashCode() = 0
|
||||||
|
}
|
||||||
@@ -178,15 +178,14 @@ abstract class Slicer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected fun canProcessParameter(parameter: KtParameter) = !parameter.isVarArg
|
protected fun canProcessParameter(parameter: KtParameter) = !parameter.isVarArg
|
||||||
|
|
||||||
protected companion object {
|
|
||||||
val DeclarationDescriptorWithSource.originalSource: SourceElement
|
|
||||||
get() {
|
|
||||||
var descriptor = this
|
|
||||||
while (descriptor.original != descriptor) {
|
|
||||||
descriptor = descriptor.original
|
|
||||||
}
|
|
||||||
return descriptor.source
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val DeclarationDescriptorWithSource.originalSource: SourceElement
|
||||||
|
get() {
|
||||||
|
var descriptor = this
|
||||||
|
while (descriptor.original != descriptor) {
|
||||||
|
descriptor = descriptor.original
|
||||||
|
}
|
||||||
|
return descriptor.source
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user