Wrap parentCodegen before generating from inline

This commit is contained in:
Denis Zharkov
2014-11-21 11:45:38 +04:00
parent 538a2172e5
commit 080610c208
4 changed files with 82 additions and 6 deletions
@@ -86,6 +86,10 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
this.propertyCodegen = new PropertyCodegen(context, v, functionCodegen, this);
}
protected MemberCodegen(@NotNull MemberCodegen<T> wrapped) {
this(wrapped.state, wrapped.getParentCodegen(), wrapped.getContext(), wrapped.element, wrapped.v);
}
public void generate() {
generateDeclaration();
@@ -192,11 +192,7 @@ public class InlineCodegen implements CallGenerator {
);
}
else {
FunctionCodegen.generateMethodBody(
maxCalcAdapter, functionDescriptor, methodContext, jvmSignature,
new FunctionGenerationStrategy.FunctionDefault(state, functionDescriptor, (JetDeclarationWithBody) element),
parentCodegen
);
generateMethodBody(maxCalcAdapter, functionDescriptor, methodContext, (JetDeclarationWithBody) element, jvmSignature);
}
maxCalcAdapter.visitMaxs(-1, -1);
maxCalcAdapter.visitEnd();
@@ -277,13 +273,55 @@ public class InlineCodegen implements CallGenerator {
MethodVisitor adapter = InlineCodegenUtil.wrapWithMaxLocalCalc(methodNode);
FunctionCodegen.generateMethodBody(adapter, descriptor, context, jvmMethodSignature, new FunctionGenerationStrategy.FunctionDefault(state, descriptor, declaration), codegen.getParentCodegen());
generateMethodBody(adapter, descriptor, context, declaration, jvmMethodSignature);
adapter.visitMaxs(-1, -1);
return methodNode;
}
private void generateMethodBody(
@NotNull MethodVisitor adapter,
@NotNull FunctionDescriptor descriptor,
@NotNull MethodContext context,
@NotNull JetDeclarationWithBody declaration,
@NotNull JvmMethodSignature jvmMethodSignature
) {
FunctionCodegen.generateMethodBody(
adapter, descriptor, context, jvmMethodSignature,
new FunctionGenerationStrategy.FunctionDefault(state, descriptor, declaration),
// Wrapping for preventing marking actual parent codegen as containing reifier markers
new FakeMemberCodegen(codegen.getParentCodegen())
);
}
private static class FakeMemberCodegen extends MemberCodegen {
private final MemberCodegen delegate;
public FakeMemberCodegen(@NotNull MemberCodegen wrapped) {
super(wrapped);
delegate = wrapped;
}
@Override
protected void generateDeclaration() {
throw new IllegalStateException();
}
@Override
protected void generateBody() {
throw new IllegalStateException();
}
@Override
protected void generateKotlinAnnotation() {
throw new IllegalStateException();
}
@NotNull
@Override
public NameGenerator getInlineNameGenerator() {
return delegate.getInlineNameGenerator();
}
}
@Override
public void afterParameterPut(@NotNull Type type, @Nullable StackValue stackValue, @Nullable ValueParameterDescriptor valueParameterDescriptor) {
@@ -0,0 +1,28 @@
import kotlin.test.assertEquals
fun foo(block: () -> String) = block()
inline fun<reified T> className(): String = javaClass<T>().getName()
trait A {
fun f(): String
fun g(): String
}
fun box(): String {
val x = foo() {
className<String>()
}
assertEquals("java.lang.String", x)
val y: A = object : A {
override fun f(): String = foo { className<String>() }
override fun g(): String = foo { className<Int>() }
}
assertEquals("java.lang.String", y.f())
assertEquals("java.lang.Integer", y.g())
return "OK"
}
@@ -2718,6 +2718,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
doTestWithStdlib(fileName);
}
@TestMetadata("reifiedInlineIntoNonInlineableLambda.kt")
public void testReifiedInlineIntoNonInlineableLambda() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/reifiedInlineIntoNonInlineableLambda.kt");
doTestWithStdlib(fileName);
}
@TestMetadata("safecast.kt")
public void testSafecast() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reified/safecast.kt");