Properly capture local functions
Local functions in local classed wasn't captured properly
This commit is contained in:
@@ -255,7 +255,7 @@ public class ClosureCodegen extends GenerationStateAware {
|
|||||||
: typeMapper.mapType((VariableDescriptor) descriptor);
|
: typeMapper.mapType((VariableDescriptor) descriptor);
|
||||||
args.add(FieldInfo.createForHiddenField(ownerType, type, "$" + descriptor.getName().getName()));
|
args.add(FieldInfo.createForHiddenField(ownerType, type, "$" + descriptor.getName().getName()));
|
||||||
}
|
}
|
||||||
else if (isLocalNamedFun(state.getBindingContext(), descriptor)) {
|
else if (isLocalNamedFun(descriptor)) {
|
||||||
Type type =
|
Type type =
|
||||||
classNameForAnonymousClass(bindingContext,
|
classNameForAnonymousClass(bindingContext,
|
||||||
(JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor))
|
(JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor))
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ import java.util.*;
|
|||||||
import static org.jetbrains.asm4.Opcodes.*;
|
import static org.jetbrains.asm4.Opcodes.*;
|
||||||
import static org.jetbrains.jet.codegen.AsmUtil.*;
|
import static org.jetbrains.jet.codegen.AsmUtil.*;
|
||||||
import static org.jetbrains.jet.codegen.CodegenUtil.*;
|
import static org.jetbrains.jet.codegen.CodegenUtil.*;
|
||||||
import static org.jetbrains.jet.codegen.binding.CodegenBinding.isLocalFun;
|
import static org.jetbrains.jet.codegen.binding.CodegenBinding.isLocalNamedFun;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.callableDescriptorToDeclaration;
|
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.callableDescriptorToDeclaration;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
|
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
|
||||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
||||||
@@ -152,7 +152,7 @@ public class FunctionCodegen extends GenerationStateAware {
|
|||||||
if (expectedThisObject != null) {
|
if (expectedThisObject != null) {
|
||||||
thisType = typeMapper.mapType(expectedThisObject.getType());
|
thisType = typeMapper.mapType(expectedThisObject.getType());
|
||||||
}
|
}
|
||||||
else if (declaration instanceof JetFunctionLiteral || isLocalFun(bindingContext, functionDescriptor)) {
|
else if (declaration instanceof JetFunctionLiteral || isLocalNamedFun(functionDescriptor)) {
|
||||||
thisType = typeMapper.mapType(context.getThisDescriptor());
|
thisType = typeMapper.mapType(context.getThisDescriptor());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -1233,7 +1233,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
constructorContext.lookupInContext(descriptor, null, state, true);
|
constructorContext.lookupInContext(descriptor, null, state, true);
|
||||||
} else if (descriptor instanceof CallableMemberDescriptor) {
|
} else if (isLocalNamedFun(descriptor)) {
|
||||||
MutableClassDescriptor classDescriptor =
|
MutableClassDescriptor classDescriptor =
|
||||||
(MutableClassDescriptor) constructorContext.getParentContext().getContextDescriptor();
|
(MutableClassDescriptor) constructorContext.getParentContext().getContextDescriptor();
|
||||||
|
|
||||||
|
|||||||
@@ -295,19 +295,10 @@ public class CodegenBinding {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isLocalFun(BindingContext bindingContext, DeclarationDescriptor fd) {
|
public static boolean isLocalNamedFun(DeclarationDescriptor fd) {
|
||||||
PsiElement psiElement = descriptorToDeclaration(bindingContext, fd);
|
if (fd instanceof FunctionDescriptor) {
|
||||||
if (psiElement instanceof JetNamedFunction && psiElement.getParent() instanceof JetBlockExpression) {
|
FunctionDescriptor descriptor = (FunctionDescriptor) fd;
|
||||||
return true;
|
return descriptor.getVisibility() == Visibilities.LOCAL && !descriptor.getName().isSpecial();
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isLocalNamedFun(BindingContext bindingContext, DeclarationDescriptor fd) {
|
|
||||||
PsiElement psiElement = descriptorToDeclaration(bindingContext, fd);
|
|
||||||
if (psiElement instanceof JetNamedFunction) {
|
|
||||||
DeclarationDescriptor declaration = fd.getContainingDeclaration();
|
|
||||||
return declaration instanceof FunctionDescriptor || declaration instanceof PropertyDescriptor;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public interface LocalLookup {
|
|||||||
LOCAL_NAMED_FUNCTION {
|
LOCAL_NAMED_FUNCTION {
|
||||||
@Override
|
@Override
|
||||||
public boolean isCase(DeclarationDescriptor d, GenerationState state) {
|
public boolean isCase(DeclarationDescriptor d, GenerationState state) {
|
||||||
return isLocalNamedFun(state.getBindingContext(), d);
|
return isLocalNamedFun(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -85,7 +85,7 @@ public interface LocalLookup {
|
|||||||
) {
|
) {
|
||||||
FunctionDescriptor vd = (FunctionDescriptor) d;
|
FunctionDescriptor vd = (FunctionDescriptor) d;
|
||||||
|
|
||||||
boolean idx = localLookup.lookupLocal(vd);
|
boolean idx = localLookup != null && localLookup.lookupLocal(vd);
|
||||||
if (!idx) return null;
|
if (!idx) return null;
|
||||||
|
|
||||||
JetElement expression = (JetElement) callableDescriptorToDeclaration(state.getBindingContext(), vd);
|
JetElement expression = (JetElement) callableDescriptorToDeclaration(state.getBindingContext(), vd);
|
||||||
|
|||||||
@@ -816,7 +816,7 @@ public class JetTypeMapper extends BindingTraceAware {
|
|||||||
signatureWriter.writeAsmType(sharedVarType, false);
|
signatureWriter.writeAsmType(sharedVarType, false);
|
||||||
signatureWriter.writeParameterTypeEnd();
|
signatureWriter.writeParameterTypeEnd();
|
||||||
}
|
}
|
||||||
else if (isLocalNamedFun(bindingContext, variableDescriptor)) {
|
else if (isLocalNamedFun(variableDescriptor)) {
|
||||||
Type type = classNameForAnonymousClass(
|
Type type = classNameForAnonymousClass(
|
||||||
bindingContext,
|
bindingContext,
|
||||||
(JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, variableDescriptor)
|
(JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, variableDescriptor)
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
//adopted snippet from kdoc
|
||||||
|
open class KModel {
|
||||||
|
val sourcesInfo: String
|
||||||
|
;{
|
||||||
|
fun relativePath(psiFile: String): String {
|
||||||
|
return psiFile;
|
||||||
|
}
|
||||||
|
sourcesInfo = relativePath("OK")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box():String {
|
||||||
|
return KModel().sourcesInfo;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
trait Named {
|
||||||
|
abstract fun getName() : String;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait MemberDescriptor : Named {}
|
||||||
|
|
||||||
|
trait ClassifierDescriptor : Named {}
|
||||||
|
|
||||||
|
trait ClassDescriptor : MemberDescriptor, ClassifierDescriptor {}
|
||||||
|
|
||||||
|
class ClassDescriptorImpl : ClassDescriptor {
|
||||||
|
override fun getName(): String {
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class A(val descriptor : ClassDescriptor) {
|
||||||
|
val result : String = descriptor.getName()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return A(ClassDescriptorImpl()).result
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
class Test {
|
||||||
|
|
||||||
|
val property:Int
|
||||||
|
;{
|
||||||
|
fun local():Int {
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
property = local();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return if (Test().property == 10) "OK" else "fail"
|
||||||
|
}
|
||||||
+31
-1
@@ -916,6 +916,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/closures"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/closures"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("closureInsideConstrucor.kt")
|
||||||
|
public void testClosureInsideConstrucor() throws Exception {
|
||||||
|
doTest("compiler/testData/codegen/box/closures/closureInsideConstrucor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("closureWithParameter.kt")
|
@TestMetadata("closureWithParameter.kt")
|
||||||
public void testClosureWithParameter() throws Exception {
|
public void testClosureWithParameter() throws Exception {
|
||||||
doTest("compiler/testData/codegen/box/closures/closureWithParameter.kt");
|
doTest("compiler/testData/codegen/box/closures/closureWithParameter.kt");
|
||||||
@@ -1683,6 +1688,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/functions")
|
@TestMetadata("compiler/testData/codegen/box/functions")
|
||||||
|
@InnerTestClasses({Functions.LocalFunctions.class})
|
||||||
public static class Functions extends AbstractBlackBoxCodegenTest {
|
public static class Functions extends AbstractBlackBoxCodegenTest {
|
||||||
public void testAllFilesPresentInFunctions() throws Exception {
|
public void testAllFilesPresentInFunctions() throws Exception {
|
||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/functions"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/functions"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
@@ -1733,6 +1739,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest("compiler/testData/codegen/box/functions/ea33909.kt");
|
doTest("compiler/testData/codegen/box/functions/ea33909.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("fakeDescriptorWithSeveralOverridenOne.kt")
|
||||||
|
public void testFakeDescriptorWithSeveralOverridenOne() throws Exception {
|
||||||
|
doTest("compiler/testData/codegen/box/functions/fakeDescriptorWithSeveralOverridenOne.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("functionExpression.kt")
|
@TestMetadata("functionExpression.kt")
|
||||||
public void testFunctionExpression() throws Exception {
|
public void testFunctionExpression() throws Exception {
|
||||||
doTest("compiler/testData/codegen/box/functions/functionExpression.kt");
|
doTest("compiler/testData/codegen/box/functions/functionExpression.kt");
|
||||||
@@ -1838,6 +1849,25 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
doTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/functions/localFunctions")
|
||||||
|
public static class LocalFunctions extends AbstractBlackBoxCodegenTest {
|
||||||
|
public void testAllFilesPresentInLocalFunctions() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/functions/localFunctions"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("localFunctionInConstructor.kt")
|
||||||
|
public void testLocalFunctionInConstructor() throws Exception {
|
||||||
|
doTest("compiler/testData/codegen/box/functions/localFunctions/localFunctionInConstructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Test innerSuite() {
|
||||||
|
TestSuite suite = new TestSuite("Functions");
|
||||||
|
suite.addTestSuite(Functions.class);
|
||||||
|
suite.addTestSuite(LocalFunctions.class);
|
||||||
|
return suite;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/innerNested")
|
@TestMetadata("compiler/testData/codegen/box/innerNested")
|
||||||
@@ -3464,7 +3494,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
suite.addTestSuite(ExclExcl.class);
|
suite.addTestSuite(ExclExcl.class);
|
||||||
suite.addTestSuite(ExtensionFunctions.class);
|
suite.addTestSuite(ExtensionFunctions.class);
|
||||||
suite.addTestSuite(ExtensionProperties.class);
|
suite.addTestSuite(ExtensionProperties.class);
|
||||||
suite.addTestSuite(Functions.class);
|
suite.addTest(Functions.innerSuite());
|
||||||
suite.addTestSuite(InnerNested.class);
|
suite.addTestSuite(InnerNested.class);
|
||||||
suite.addTest(Instructions.innerSuite());
|
suite.addTest(Instructions.innerSuite());
|
||||||
suite.addTestSuite(Intrinsics.class);
|
suite.addTestSuite(Intrinsics.class);
|
||||||
|
|||||||
Reference in New Issue
Block a user