Fixed local return inside function expression.
This commit is contained in:
@@ -1820,7 +1820,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
@Nullable
|
@Nullable
|
||||||
private NonLocalReturnInfo getNonLocalReturnInfo(@NotNull CallableMemberDescriptor descriptor, @NotNull JetReturnExpression expression) {
|
private NonLocalReturnInfo getNonLocalReturnInfo(@NotNull CallableMemberDescriptor descriptor, @NotNull JetReturnExpression expression) {
|
||||||
//call inside lambda
|
//call inside lambda
|
||||||
if (isLocalFunOrLambda(descriptor) && descriptor.getName().isSpecial()) {
|
if (isLambda(descriptor)) {
|
||||||
if (expression.getLabelName() == null) {
|
if (expression.getLabelName() == null) {
|
||||||
//non labeled return couldn't be local in lambda
|
//non labeled return couldn't be local in lambda
|
||||||
FunctionDescriptor containingFunction =
|
FunctionDescriptor containingFunction =
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.codegen.SamType;
|
|||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping;
|
import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl;
|
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl;
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
@@ -264,6 +265,10 @@ public class CodegenBinding {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isLambda(@Nullable DeclarationDescriptor fd) {
|
||||||
|
return fd instanceof AnonymousFunctionDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static Type getAsmType(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor klass) {
|
public static Type getAsmType(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor klass) {
|
||||||
Type type = bindingContext.get(ASM_TYPE, klass);
|
Type type = bindingContext.get(ASM_TYPE, klass);
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
fun Int.thisRef1() = fun () = this
|
||||||
|
fun Int.thisRef2() = fun (): Int {return this}
|
||||||
|
|
||||||
|
fun <T> T.genericThisRef1() = fun () = this
|
||||||
|
fun <T> T.genericThisRef2() = fun (): T {return this}
|
||||||
|
|
||||||
|
val Int.valThisRef1: () -> Int get() = fun () = this
|
||||||
|
val Int.valThisRef2: () -> Int get() = fun (): Int {return this}
|
||||||
|
|
||||||
|
val <T> T.valGenericThisRef1: ()->T get() = fun () = this
|
||||||
|
val <T> T.valGenericThisRef2: ()->T get() = fun (): T {return this}
|
||||||
|
|
||||||
|
val <T> T.withLabel1: ()->T get() = fun () = this@withLabel1
|
||||||
|
val <T> T.withLabel2: ()->T get() = fun (): T {return this@withLabel2}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
if (1.thisRef1()() != 1) return "Test 1 failed"
|
||||||
|
if (2.thisRef2()() != 2) return "Test 2 failed"
|
||||||
|
|
||||||
|
if (3.genericThisRef1()() != 3) return "Test 3 failed"
|
||||||
|
if (4.genericThisRef2()() != 4) return "Test 4 failed"
|
||||||
|
|
||||||
|
if (5.valThisRef1() != 5) return "Test 5 failed"
|
||||||
|
if (6.valThisRef2() != 6) return "Test 6 failed"
|
||||||
|
|
||||||
|
if (7.valGenericThisRef1() != 7) return "Test 7 failed"
|
||||||
|
if (8.valGenericThisRef2() != 8) return "Test 8 failed"
|
||||||
|
|
||||||
|
if ("bar".withLabel1() != "bar") return "Test 9 failed"
|
||||||
|
if ("bar".withLabel2() != "bar") return "Test 10 failed"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
fun simple() = fun (): Boolean { return true }
|
||||||
|
|
||||||
|
fun simpleNamed() = fun name(): Boolean { return true }
|
||||||
|
fun simpleNamed2() = fun name(): Boolean { return@name true }
|
||||||
|
|
||||||
|
fun withLabel() = @l fun (): Boolean { return@l true }
|
||||||
|
fun withLabelNamed() = @l fun name(): Boolean { return@l true }
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
if (!simple()()) return "Test simple failed"
|
||||||
|
if (!simpleNamed()()) return "Test simpleNamed failed"
|
||||||
|
if (!simpleNamed2()()) return "Test simpleNamed2 failed"
|
||||||
|
if (!withLabel()()) return "Test withLabel failed"
|
||||||
|
if (!withLabelNamed()()) return "Test withLabelNamed failed"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+12
@@ -3704,6 +3704,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("functionExpressionWithThisReference.kt")
|
||||||
|
public void testFunctionExpressionWithThisReference() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/functionExpressionWithThisReference.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("functionLiteralExpression.kt")
|
@TestMetadata("functionLiteralExpression.kt")
|
||||||
public void testFunctionLiteralExpression() throws Exception {
|
public void testFunctionLiteralExpression() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/functionLiteralExpression.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/functionLiteralExpression.kt");
|
||||||
@@ -3848,6 +3854,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localReturnInsideFunctionExpression.kt")
|
||||||
|
public void testLocalReturnInsideFunctionExpression() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localReturnInsideFunctionExpression.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("nothisnoclosure.kt")
|
@TestMetadata("nothisnoclosure.kt")
|
||||||
public void testNothisnoclosure() throws Exception {
|
public void testNothisnoclosure() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user