Fix non local returns to functional expressions

This commit is contained in:
Michael Bogdanov
2015-04-23 17:15:33 +03:00
parent 012bc8f1db
commit 0854c601b4
7 changed files with 85 additions and 35 deletions
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
@@ -272,16 +273,27 @@ public class InlineCodegen extends CallGenerator {
final CallableMemberDescriptor descriptor = codegen.getContext().getContextDescriptor();
final boolean isLambda = isFunctionExpression(descriptor) || isFunctionLiteral(descriptor);
@Override
public boolean isMyLabel(@NotNull String name) {
if (InlineCodegenUtil.ROOT_LABEL.equals(name)) {
return !isLambda;
return !isFunctionLiteral(descriptor);
}
else {
return descriptor.getName().asString().equals(name);
//check function name if exists
if (descriptor.getName().asString().equals(name)) {
return true;
}
//check functional expression labels
if (isFunctionExpression(descriptor)) {
PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
if (element != null && element.getParent() instanceof JetLabeledExpression) {
String labelName = ((JetLabeledExpression) element.getParent()).getLabelName();
return name.equals(labelName);
}
}
return false;
}
};
List<MethodInliner.PointForExternalFinallyBlocks> infos = MethodInliner.processReturns(adapter, labelOwner, true, null);
@@ -0,0 +1,23 @@
//NO_CHECK_LAMBDA_INLINING
fun test(): String = fun (): String {
foo { return "OK" }
return "fail"
} ()
fun test2(): String = (@l fun (): String {
foo { return@l "OK" }
return "fail"
}) ()
fun test3(): String = (@l fun bar(): String {
foo { return@bar "OK" }
return "fail"
}) ()
fun box(): String {
if (test() != "OK") return "fail 1: ${test()}"
if (test2() != "OK") return "fail 2: ${test2()}"
return test3()
}
@@ -0,0 +1,3 @@
inline fun foo(f: () -> Unit) {
f()
}
@@ -287,6 +287,21 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
}
}
@TestMetadata("compiler/testData/codegen/boxInline/functionExpression")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionExpression extends AbstractBlackBoxInlineCodegenTest {
public void testAllFilesPresentInFunctionExpression() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/functionExpression"), Pattern.compile("^(.+)\\.1.kt$"), true);
}
@TestMetadata("extension.1.kt")
public void testExtension() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/functionExpression/extension.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
}
@TestMetadata("compiler/testData/codegen/boxInline/lambdaClassClash")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -362,21 +377,6 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
}
}
@TestMetadata("compiler/testData/codegen/boxInline/nameless")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Nameless extends AbstractBlackBoxInlineCodegenTest {
public void testAllFilesPresentInNameless() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/nameless"), Pattern.compile("^(.+)\\.1.kt$"), true);
}
@TestMetadata("extension.1.kt")
public void testExtension() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/nameless/extension.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
}
@TestMetadata("compiler/testData/codegen/boxInline/noInline")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -460,6 +460,12 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
doTestMultiFileWithInlineCheck(fileName);
}
@TestMetadata("returnFromFunctionExpr.1.kt")
public void testReturnFromFunctionExpr() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/nonLocalReturns/returnFromFunctionExpr.1.kt");
doTestMultiFileWithInlineCheck(fileName);
}
@TestMetadata("simple.1.kt")
public void testSimple() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/nonLocalReturns/simple.1.kt");
@@ -287,6 +287,21 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
}
}
@TestMetadata("compiler/testData/codegen/boxInline/functionExpression")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class FunctionExpression extends AbstractCompileKotlinAgainstInlineKotlinTest {
public void testAllFilesPresentInFunctionExpression() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/functionExpression"), Pattern.compile("^(.+)\\.1.kt$"), true);
}
@TestMetadata("extension.1.kt")
public void testExtension() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/functionExpression/extension.1.kt");
doBoxTestWithInlineCheck(fileName);
}
}
@TestMetadata("compiler/testData/codegen/boxInline/lambdaClassClash")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -362,21 +377,6 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
}
}
@TestMetadata("compiler/testData/codegen/boxInline/nameless")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Nameless extends AbstractCompileKotlinAgainstInlineKotlinTest {
public void testAllFilesPresentInNameless() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/nameless"), Pattern.compile("^(.+)\\.1.kt$"), true);
}
@TestMetadata("extension.1.kt")
public void testExtension() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/nameless/extension.1.kt");
doBoxTestWithInlineCheck(fileName);
}
}
@TestMetadata("compiler/testData/codegen/boxInline/noInline")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -460,6 +460,12 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
doBoxTestWithInlineCheck(fileName);
}
@TestMetadata("returnFromFunctionExpr.1.kt")
public void testReturnFromFunctionExpr() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/nonLocalReturns/returnFromFunctionExpr.1.kt");
doBoxTestWithInlineCheck(fileName);
}
@TestMetadata("simple.1.kt")
public void testSimple() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/nonLocalReturns/simple.1.kt");