Pseudocode: Fix type predicate inference for values used inside of lambda

This commit is contained in:
Alexey Sedunov
2014-09-09 17:07:16 +04:00
parent 76433571f8
commit b59da7686c
5 changed files with 55 additions and 1 deletions
@@ -161,4 +161,18 @@ private fun Instruction.calcSideEffectFree(): Boolean {
else -> false
}
}
fun Pseudocode.getElementValuesRecursively(element: JetElement): List<PseudoValue> {
val results = ArrayList<PseudoValue>()
fun Pseudocode.collectValues() {
getElementValue(element)?.let { results.add(it) }
for (localFunction in getLocalDeclarations()) {
localFunction.body.collectValues()
}
}
collectValues()
return results
}
@@ -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 =
@@ -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 = <selection> { b += a; b }() </selection>
println(b)
return t
}
@@ -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<Int, Int> {
var b1 = b
return Pair({ b1 += a; b1 }(), b1)
}
@@ -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");