Pseudocode: Bind nondeterministic jump caused by local declaration to declaration iself instead of its parent element

#KT-6261 Fixed
 #KT-6416 Fixed
This commit is contained in:
Alexey Sedunov
2015-01-12 14:15:34 +03:00
parent 81715d1fca
commit 9278dee1a4
13 changed files with 145 additions and 4 deletions
@@ -114,12 +114,9 @@ public class JetControlFlowProcessor {
}
private void processLocalDeclaration(@NotNull JetDeclaration subroutine) {
JetElement parent = PsiTreeUtil.getParentOfType(subroutine, JetElement.class);
assert parent != null;
Label afterDeclaration = builder.createUnboundLabel("after local declaration");
builder.nondeterministicJump(afterDeclaration, parent, null);
builder.nondeterministicJump(afterDeclaration, subroutine, null);
generate(subroutine);
builder.bindLabel(afterDeclaration);
}
@@ -0,0 +1,40 @@
== test ==
fun test(): Int {
val j = 1
fun local() = 1
return local()
}
---------------------
L0:
1 <START>
2 mark({ val j = 1 fun local() = 1 return local() })
v(val j = 1)
r(1) -> <v0>
w(j|<v0>)
jmp?(L2) NEXT:[mark(local()), d(fun local() = 1)]
d(fun local() = 1) NEXT:[<SINK>]
L2 [after local declaration]:
mark(local()) PREV:[jmp?(L2)]
call(local(), local) -> <v1>
ret(*|<v1>) L1
L1:
1 <END> NEXT:[<SINK>]
error:
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>, d(fun local() = 1)]
=====================
== local ==
fun local() = 1
---------------------
L3:
3 <START>
r(1) -> <v0>
ret(*|<v0>) L4
L4:
<END> NEXT:[<SINK>]
error:
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
=====================
@@ -0,0 +1,5 @@
fun test(): Int {
val j = 1
fun local() = 1
return local()
}
@@ -0,0 +1,17 @@
== test ==
fun test(): Int {
val j = 1
fun local() = 1
return local()
}
---------------------
1 <v0>: Int NEW: r(1) -> <v0>
local() <v1>: Int NEW: call(local(), local) -> <v1>
return local() !<v2>: *
{ val j = 1 fun local() = 1 return local() } !<v2>: * COPY
=====================
== local ==
fun local() = 1
---------------------
1 <v0>: Int NEW: r(1) -> <v0>
=====================
@@ -369,6 +369,12 @@ public class ControlFlowTestGenerated extends AbstractControlFlowTest {
doTest(fileName);
}
@TestMetadata("localFunction.kt")
public void testLocalFunction() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/cfg/declarations/local/localFunction.kt");
doTest(fileName);
}
@TestMetadata("localProperty.kt")
public void testLocalProperty() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/cfg/declarations/local/localProperty.kt");
@@ -372,6 +372,12 @@ public class PseudoValueTestGenerated extends AbstractPseudoValueTest {
doTest(fileName);
}
@TestMetadata("localFunction.kt")
public void testLocalFunction() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/cfg/declarations/local/localFunction.kt");
doTest(fileName);
}
@TestMetadata("localProperty.kt")
public void testLocalProperty() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/cfg/declarations/local/localProperty.kt");
@@ -0,0 +1,6 @@
fun test1(): Int {
<selection>val foo = 1
fun bar() = 2
return 3</selection>
}
@@ -0,0 +1,10 @@
fun test1(): Int {
return i()
}
private fun i(): Int {
val foo = 1
fun bar() = 2
return 3
}
@@ -0,0 +1,5 @@
fun test(): Int {
<selection>val j = 1
fun local() = 1
return local()</selection>
}
@@ -0,0 +1,9 @@
fun test(): Int {
return i()
}
private fun i(): Int {
val j = 1
fun local() = 1
return local()
}
@@ -0,0 +1,9 @@
fun test(): Int {
<selection>val foo = 1
fun bar() = 2
return when (foo) {
1 -> 1
else -> 2
}</selection>
}
@@ -0,0 +1,13 @@
fun test(): Int {
return i()
}
private fun i(): Int {
val foo = 1
fun bar() = 2
return when (foo) {
1 -> 1
else -> 2
}
}
@@ -414,6 +414,24 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest {
doExtractFunctionTest(fileName);
}
@TestMetadata("localFunctionInTheMiddleSimpleControlFlow.kt")
public void testLocalFunctionInTheMiddleSimpleControlFlow() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/basic/localFunctionInTheMiddleSimpleControlFlow.kt");
doExtractFunctionTest(fileName);
}
@TestMetadata("localFunctionInTheMiddleUnusedVar.kt")
public void testLocalFunctionInTheMiddleUnusedVar() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/basic/localFunctionInTheMiddleUnusedVar.kt");
doExtractFunctionTest(fileName);
}
@TestMetadata("localFunctionInTheMiddleUsedVar.kt")
public void testLocalFunctionInTheMiddleUsedVar() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/basic/localFunctionInTheMiddleUsedVar.kt");
doExtractFunctionTest(fileName);
}
@TestMetadata("localFunctionRef.kt")
public void testLocalFunctionRef() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/basic/localFunctionRef.kt");