Processing implicit extension receiver usages in outflow processing
This commit is contained in:
@@ -153,16 +153,32 @@ class OutflowSlicer(
|
||||
|
||||
private fun processExtensionReceiver(declaration: KtCallableDeclaration, declarationWithBody: KtDeclarationWithBody) {
|
||||
//TODO: overriders
|
||||
//TODO: implicit receivers
|
||||
val resolutionFacade = declaration.getResolutionFacade()
|
||||
val callableDescriptor = declaration.resolveToDescriptorIfAny(resolutionFacade) as? CallableDescriptor ?: return
|
||||
val extensionReceiver = callableDescriptor.extensionReceiverParameter ?: return
|
||||
declarationWithBody.bodyExpression?.forEachDescendantOfType<KtThisExpression> { thisExpression ->
|
||||
val body = declarationWithBody.bodyExpression ?: return
|
||||
|
||||
body.forEachDescendantOfType<KtThisExpression> { thisExpression ->
|
||||
val receiverDescriptor = thisExpression.resolveToCall(resolutionFacade)?.resultingDescriptor
|
||||
if (receiverDescriptor == extensionReceiver) {
|
||||
thisExpression.passToProcessor()
|
||||
}
|
||||
}
|
||||
|
||||
// process implicit receiver usages
|
||||
val pseudocode = pseudocodeCache[body]
|
||||
if (pseudocode != null) {
|
||||
for (instruction in pseudocode.instructions) {
|
||||
if (instruction is MagicInstruction && instruction.kind == MagicKind.IMPLICIT_RECEIVER) {
|
||||
val receiverPseudoValue = instruction.outputValue
|
||||
pseudocode.getUsages(receiverPseudoValue).forEach { receiverUseInstruction ->
|
||||
if (receiverUseInstruction is KtElementInstruction) {
|
||||
processIfReceiverValue(receiverUseInstruction, receiverPseudoValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun processExpression(expression: KtExpression) {
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// FLOW: OUT
|
||||
|
||||
fun Any.extensionFun(): Any {
|
||||
return this
|
||||
}
|
||||
|
||||
fun String.foo() {
|
||||
val v = extensionFun()
|
||||
}
|
||||
|
||||
fun main() {
|
||||
<caret>"A".foo()
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
12 <bold>"A"</bold>.foo()
|
||||
7 fun <bold>String</bold>.foo() {
|
||||
3 fun <bold>Any</bold>.extensionFun(): Any {
|
||||
4 return <bold>this</bold>
|
||||
3 fun Any.<bold>extensionFun(): Any {</bold>
|
||||
8 val v = <bold>extensionFun()</bold>
|
||||
8 val <bold>v = extensionFun()</bold>
|
||||
@@ -583,6 +583,11 @@ public class SlicerTreeTestGenerated extends AbstractSlicerTreeTest {
|
||||
runTest("idea/testData/slicer/outflow/ifExpression.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("implicitReceiver.kt")
|
||||
public void testImplicitReceiver() throws Exception {
|
||||
runTest("idea/testData/slicer/outflow/implicitReceiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("indexingDereferences.kt")
|
||||
public void testIndexingDereferences() throws Exception {
|
||||
runTest("idea/testData/slicer/outflow/indexingDereferences.kt");
|
||||
|
||||
Reference in New Issue
Block a user