Handling implicit receivers in InflowSlicer

This commit is contained in:
Valentin Kipyatkov
2020-04-10 09:18:24 +03:00
parent 90188ef44f
commit b4b58d1d99
5 changed files with 41 additions and 15 deletions
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
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
@@ -164,24 +165,31 @@ class InflowSlicer(
} }
private fun processExtensionReceiver(declaration: KtCallableDeclaration, includeOverriders: Boolean) { private fun processExtensionReceiver(declaration: KtCallableDeclaration, includeOverriders: Boolean) {
fun extractReceiverExpression(refElement: PsiElement): PsiElement? { fun processReceiver(refElement: PsiElement) {
return when (refElement) { when (refElement) {
is KtExpression -> { is KtExpression -> {
val resolvedCall = refElement.resolveToCall() ?: return null val resolvedCall = refElement.resolveToCall() ?: return
//TODO: implicit receiver when (val receiver = resolvedCall.extensionReceiver) {
val expressionReceiver = resolvedCall.extensionReceiver as? ExpressionReceiver ?: return null is ExpressionReceiver -> {
return expressionReceiver.expression receiver.expression.passToProcessorAsValue()
}
is ImplicitReceiver -> {
val callableDeclaration = (receiver.declarationDescriptor as? CallableDescriptor)?.originalSource?.getPsi()
(callableDeclaration as? KtCallableDeclaration)?.receiverTypeReference?.passToProcessor()
}
}
} }
else -> { else -> {
(refElement.parent as? PsiCall)?.argumentList?.expressions?.getOrNull(0) (refElement.parent as? PsiCall)?.argumentList?.expressions?.getOrNull(0)?.passToProcessorAsValue()
} }
} }
} }
fun processCall(usageInfo: UsageInfo) { fun processCall(usageInfo: UsageInfo) {
usageInfo.element?.let { usageInfo.element?.let {
extractReceiverExpression(it)?.passToProcessorAsValue() processReceiver(it)
} }
} }
+8 -1
View File
@@ -7,7 +7,14 @@ import kotlin.jvm.JvmName
fun <caret>Any.extensionFun() { fun <caret>Any.extensionFun() {
} }
fun foo() { fun String.foo() {
"".extensionFun() "".extensionFun()
1.extensionFun() 1.extensionFun()
extensionFun()
}
fun main() {
"A".foo()
} }
@@ -2,11 +2,16 @@
7 fun <bold>Any</bold>.extensionFun() { 7 fun <bold>Any</bold>.extensionFun() {
11 <bold>""</bold>.extensionFun() 11 <bold>""</bold>.extensionFun()
19 <bold>"A"</bold>.foo()
7 fun <bold>Any</bold>.extensionFun() {
10 fun <bold>String</bold>.foo() {
19 <bold>"A"</bold>.foo()
3 KotlinUtil.extensionFun(<bold>"x"</bold>); 3 KotlinUtil.extensionFun(<bold>"x"</bold>);
7 fun <bold>Any</bold>.extensionFun() { 7 fun <bold>Any</bold>.extensionFun() {
3 KotlinUtil.extensionFun(<bold>"x"</bold>); 3 KotlinUtil.extensionFun(<bold>"x"</bold>);
12 <bold>1</bold>.extensionFun() 13 <bold>1</bold>.extensionFun()
7 fun <bold>Any</bold>.extensionFun() { 7 fun <bold>Any</bold>.extensionFun() {
12 <bold>1</bold>.extensionFun() 13 <bold>1</bold>.extensionFun()
@@ -2,9 +2,13 @@
11 <bold>""</bold>.extensionFun() 11 <bold>""</bold>.extensionFun()
7 fun <bold>Any</bold>.extensionFun() { 7 fun <bold>Any</bold>.extensionFun() {
11 <bold>""</bold>.extensionFun() 11 <bold>""</bold>.extensionFun()
12 <bold>1</bold>.extensionFun() 13 <bold>1</bold>.extensionFun()
7 fun <bold>Any</bold>.extensionFun() { 7 fun <bold>Any</bold>.extensionFun() {
12 <bold>1</bold>.extensionFun() 13 <bold>1</bold>.extensionFun()
19 <bold>"A"</bold>.foo()
7 fun <bold>Any</bold>.extensionFun() {
10 fun <bold>String</bold>.foo() {
19 <bold>"A"</bold>.foo()
[Other Values] [Other Values]
3 KotlinUtil.extensionFun(<bold>"x"</bold>); 3 KotlinUtil.extensionFun(<bold>"x"</bold>);
@@ -1,4 +1,6 @@
7 fun <bold>Any</bold>.extensionFun() { 7 fun <bold>Any</bold>.extensionFun() {
3 KotlinUtil.extensionFun(<bold>"x"</bold>); 3 KotlinUtil.extensionFun(<bold>"x"</bold>);
10 fun <bold>String</bold>.foo() {
19 <bold>"A"</bold>.foo()
11 <bold>""</bold>.extensionFun() 11 <bold>""</bold>.extensionFun()
12 <bold>1</bold>.extensionFun() 13 <bold>1</bold>.extensionFun()