Skip to content

Commit

Permalink
Processing implicit extension receiver usages in outflow processing
Browse files Browse the repository at this point in the history
  • Loading branch information
valentinkip committed Apr 17, 2020
1 parent 5040d37 commit 269420a
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 2 deletions.
20 changes: 18 additions & 2 deletions idea/src/org/jetbrains/kotlin/idea/slicer/OutflowSlicer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
13 changes: 13 additions & 0 deletions idea/testData/slicer/outflow/implicitReceiver.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// FLOW: OUT

fun Any.extensionFun(): Any {
return this
}

fun String.foo() {
val v = extensionFun()
}

fun main() {
<caret>"A".foo()
}
7 changes: 7 additions & 0 deletions idea/testData/slicer/outflow/implicitReceiver.results.txt
Original file line number Diff line number Diff line change
@@ -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>

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 269420a

Please sign in to comment.