Track anonymous function parameters in inbound data flow analysis as well
This commit is contained in:
@@ -131,12 +131,20 @@ class InflowSlicer(
|
||||
if (function is KtFunction) {
|
||||
val sliceTransformer = ArgumentExpressionTransformer(parameterDescriptor)
|
||||
|
||||
if (function is KtFunctionLiteral) {
|
||||
processFunctionLiteralCalls(function, sliceTransformer)
|
||||
} else {
|
||||
processCalls(function, analysisScope, includeOverriders) { usageInfo ->
|
||||
usageInfo.element?.let {
|
||||
sliceTransformer.extractArgumentExpression(it)?.passToProcessorAsValue()
|
||||
when {
|
||||
function is KtFunctionLiteral -> {
|
||||
processFunctionLiteralCalls(function, sliceTransformer)
|
||||
}
|
||||
|
||||
function is KtNamedFunction && function.name == null -> {
|
||||
processAnonymousFunctionCalls(function, sliceTransformer)
|
||||
}
|
||||
|
||||
else -> {
|
||||
processCalls(function, analysisScope, includeOverriders) { usageInfo ->
|
||||
usageInfo.element?.let {
|
||||
sliceTransformer.extractArgumentExpression(it)?.passToProcessorAsValue()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.search.SearchScope
|
||||
import com.intellij.slicer.JavaSliceUsage
|
||||
import com.intellij.slicer.SliceUsage
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import com.intellij.util.containers.addIfNotNull
|
||||
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
|
||||
@@ -70,10 +69,18 @@ abstract class Slicer(
|
||||
}
|
||||
|
||||
protected fun processFunctionLiteralCalls(
|
||||
callable: KtFunctionLiteral,
|
||||
functionLiteral: KtFunctionLiteral,
|
||||
sliceTransformer: KotlinSliceUsageTransformer,
|
||||
) {
|
||||
(callable.parent as KtLambdaExpression).passToProcessorAsValue(LambdaCallsBehaviour(sliceTransformer, behaviour))
|
||||
(functionLiteral.parent as KtLambdaExpression).passToProcessorAsValue(LambdaCallsBehaviour(sliceTransformer, behaviour))
|
||||
}
|
||||
|
||||
protected fun processAnonymousFunctionCalls(
|
||||
function: KtNamedFunction,
|
||||
sliceTransformer: KotlinSliceUsageTransformer,
|
||||
) {
|
||||
require(function.name == null)
|
||||
function.passToProcessorAsValue(LambdaCallsBehaviour(sliceTransformer, behaviour))
|
||||
}
|
||||
|
||||
protected fun processCalls(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
8 val x = foo(fun(<bold>n: Int</bold>) = n)
|
||||
4 return f(<bold>1</bold>)
|
||||
8 val <bold>x = foo(fun(n: Int) = n)</bold>
|
||||
8 val x = <bold>foo(fun(n: Int) = n)</bold>
|
||||
3 fun <bold>foo(f: (Int) -> Int): Int {</bold>
|
||||
@@ -9,4 +9,7 @@
|
||||
8 val x = foo(<bold>fun(n: Int) = n</bold>)
|
||||
8 val x = foo(fun(n: Int) = <bold>n</bold>)
|
||||
8 val x = foo(fun(<bold>n: Int</bold>) = n)
|
||||
8 [LAMBDA CALLS] val x = foo(<bold>fun(n: Int) = n</bold>)
|
||||
3 [LAMBDA CALLS] fun foo(<bold>f: (Int) -> Int</bold>): Int {
|
||||
4 return f(<bold>1</bold>)
|
||||
|
||||
|
||||
@@ -8,3 +8,6 @@
|
||||
8 val x = foo(<bold>fun(n: Int) = n</bold>)
|
||||
8 val x = foo(fun(n: Int) = <bold>n</bold>)
|
||||
8 val x = foo(fun(<bold>n: Int</bold>) = n)
|
||||
8 [LAMBDA CALLS] val x = foo(<bold>fun(n: Int) = n</bold>)
|
||||
3 [LAMBDA CALLS] fun foo(<bold>f: (Int) -> Int</bold>): Int {
|
||||
4 return f(<bold>1</bold>)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
8 val x = foo(fun(<bold>n: Int</bold>): Int { return n })
|
||||
4 return f(<bold>1</bold>)
|
||||
8 val <bold>x = foo(fun(n: Int): Int { return n })</bold>
|
||||
8 val x = <bold>foo(fun(n: Int): Int { return n })</bold>
|
||||
3 fun <bold>foo(f: (Int) -> Int): Int {</bold>
|
||||
@@ -9,4 +9,7 @@
|
||||
8 val x = foo(<bold>fun(n: Int): Int { return n }</bold>)
|
||||
8 val x = foo(fun(n: Int): Int { return <bold>n</bold> })
|
||||
8 val x = foo(fun(<bold>n: Int</bold>): Int { return n })
|
||||
8 [LAMBDA CALLS] val x = foo(<bold>fun(n: Int): Int { return n }</bold>)
|
||||
3 [LAMBDA CALLS] fun foo(<bold>f: (Int) -> Int</bold>): Int {
|
||||
4 return f(<bold>1</bold>)
|
||||
|
||||
|
||||
@@ -8,3 +8,6 @@
|
||||
8 val x = foo(<bold>fun(n: Int): Int { return n }</bold>)
|
||||
8 val x = foo(fun(n: Int): Int { return <bold>n</bold> })
|
||||
8 val x = foo(fun(<bold>n: Int</bold>): Int { return n })
|
||||
8 [LAMBDA CALLS] val x = foo(<bold>fun(n: Int): Int { return n }</bold>)
|
||||
3 [LAMBDA CALLS] fun foo(<bold>f: (Int) -> Int</bold>): Int {
|
||||
4 return f(<bold>1</bold>)
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// FLOW: IN
|
||||
|
||||
fun foo(f: (Int) -> Unit) {
|
||||
f(1)
|
||||
}
|
||||
|
||||
fun test() {
|
||||
foo(fun(value: Int) {
|
||||
val <caret>v = value
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
4 f(<bold>1</bold>)
|
||||
9 val <bold>v = value</bold>
|
||||
9 val v = <bold>value</bold>
|
||||
8 foo(fun(<bold>value: Int</bold>) {
|
||||
8 [LAMBDA CALLS] foo(<bold>fun(value: Int) {</bold>
|
||||
3 [LAMBDA CALLS] fun foo(<bold>f: (Int) -> Unit</bold>) {
|
||||
4 f(<bold>1</bold>)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
[NotNull Values]
|
||||
9 val <bold>v = value</bold>
|
||||
9 val <bold>v = value</bold>
|
||||
@@ -0,0 +1,6 @@
|
||||
9 val <bold>v = value</bold>
|
||||
9 val v = <bold>value</bold>
|
||||
8 foo(fun(<bold>value: Int</bold>) {
|
||||
8 [LAMBDA CALLS] foo(<bold>fun(value: Int) {</bold>
|
||||
3 [LAMBDA CALLS] fun foo(<bold>f: (Int) -> Unit</bold>) {
|
||||
4 f(<bold>1</bold>)
|
||||
+5
@@ -38,6 +38,11 @@ public class SlicerLeafGroupingTestGenerated extends AbstractSlicerLeafGroupingT
|
||||
runTest("idea/testData/slicer/inflow/anonymousFunBodyExpression.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("anonymousFunctionParameter.kt")
|
||||
public void testAnonymousFunctionParameter() throws Exception {
|
||||
runTest("idea/testData/slicer/inflow/anonymousFunctionParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("anonymousFunReturnExpression.kt")
|
||||
public void testAnonymousFunReturnExpression() throws Exception {
|
||||
runTest("idea/testData/slicer/inflow/anonymousFunReturnExpression.kt");
|
||||
|
||||
+5
@@ -38,6 +38,11 @@ public class SlicerNullnessGroupingTestGenerated extends AbstractSlicerNullnessG
|
||||
runTest("idea/testData/slicer/inflow/anonymousFunBodyExpression.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("anonymousFunctionParameter.kt")
|
||||
public void testAnonymousFunctionParameter() throws Exception {
|
||||
runTest("idea/testData/slicer/inflow/anonymousFunctionParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("anonymousFunReturnExpression.kt")
|
||||
public void testAnonymousFunReturnExpression() throws Exception {
|
||||
runTest("idea/testData/slicer/inflow/anonymousFunReturnExpression.kt");
|
||||
|
||||
@@ -55,6 +55,11 @@ public class SlicerTreeTestGenerated extends AbstractSlicerTreeTest {
|
||||
runTest("idea/testData/slicer/inflow/anonymousFunReturnExpression.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("anonymousFunctionParameter.kt")
|
||||
public void testAnonymousFunctionParameter() throws Exception {
|
||||
runTest("idea/testData/slicer/inflow/anonymousFunctionParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("cast.kt")
|
||||
public void testCast() throws Exception {
|
||||
runTest("idea/testData/slicer/inflow/cast.kt");
|
||||
|
||||
Reference in New Issue
Block a user