diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/pseudocodeUtil.kt b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/pseudocodeUtil.kt index ab32f035953..5d4f12dcd11 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/pseudocodeUtil.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/pseudocodeUtil.kt @@ -161,4 +161,18 @@ private fun Instruction.calcSideEffectFree(): Boolean { else -> false } +} + +fun Pseudocode.getElementValuesRecursively(element: JetElement): List { + val results = ArrayList() + + fun Pseudocode.collectValues() { + getElementValue(element)?.let { results.add(it) } + for (localFunction in getLocalDeclarations()) { + localFunction.body.collectValues() + } + } + + collectValues() + return results } \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractableAnalysisUtil.kt b/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractableAnalysisUtil.kt index 8854488131b..41af055c18c 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractableAnalysisUtil.kt +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/extractFunction/extractableAnalysisUtil.kt @@ -556,7 +556,7 @@ private fun ExtractionData.inferParametersInfo( if (!parameterType.processTypeIfExtractable(info.typeParameters, info.nonDenotableTypes)) continue val parameterTypePredicate = - pseudocode.getElementValue(originalRef)?.let { getExpectedTypePredicate(it, bindingContext) } ?: AllTypes + and(pseudocode.getElementValuesRecursively(originalRef).map { getExpectedTypePredicate(it, bindingContext) }) val parameter = extractedDescriptorToParameter.getOrPut(descriptorToExtract) { val parameterName = diff --git a/idea/testData/refactoring/extractFunction/controlFlow/outputValues/outputValueWithSingleLineExpression.kt b/idea/testData/refactoring/extractFunction/controlFlow/outputValues/outputValueWithSingleLineExpression.kt new file mode 100644 index 00000000000..dceab27b2df --- /dev/null +++ b/idea/testData/refactoring/extractFunction/controlFlow/outputValues/outputValueWithSingleLineExpression.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME +// PARAM_TYPES: kotlin.Int +// PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: value-parameter val a: kotlin.Int defined in foo +// PARAM_DESCRIPTOR: var b: kotlin.Int defined in foo +// SIBLING: +fun foo(a: Int): Int { + var b: Int = 1 + + val t = { b += a; b }() + println(b) + + return t +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/controlFlow/outputValues/outputValueWithSingleLineExpression.kt.after b/idea/testData/refactoring/extractFunction/controlFlow/outputValues/outputValueWithSingleLineExpression.kt.after new file mode 100644 index 00000000000..58eda2ca8d1 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/controlFlow/outputValues/outputValueWithSingleLineExpression.kt.after @@ -0,0 +1,21 @@ +// WITH_RUNTIME +// PARAM_TYPES: kotlin.Int +// PARAM_TYPES: kotlin.Int +// PARAM_DESCRIPTOR: value-parameter val a: kotlin.Int defined in foo +// PARAM_DESCRIPTOR: var b: kotlin.Int defined in foo +// SIBLING: +fun foo(a: Int): Int { + var b: Int = 1 + + val pair = pair(a, b) + b = pair.second + val t = pair.first + println(b) + + return t +} + +private fun pair(a: Int, b: Int): Pair { + var b1 = b + return Pair({ b1 += a; b1 }(), b1) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java index 3a159a12730..b5e47ede5dd 100644 --- a/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/refactoring/introduce/introduceVariable/JetExtractionTestGenerated.java @@ -745,6 +745,11 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doExtractFunctionTest(fileName); } + @TestMetadata("outputValueWithSingleLineExpression.kt") + public void testOutputValueWithSingleLineExpression() throws Exception { + doExtractFunctionTest("idea/testData/refactoring/extractFunction/controlFlow/outputValues/outputValueWithSingleLineExpression.kt"); + } + @TestMetadata("outputValuesWithExpression.kt") public void testOutputValuesWithExpression() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/controlFlow/outputValues/outputValuesWithExpression.kt");