fix KT-2481: no bridge for supercall

This commit is contained in:
Alex Tkachman
2012-07-28 14:17:42 +03:00
parent eaee4e9cc7
commit 0b327d29bc
4 changed files with 37 additions and 3 deletions
@@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
@@ -212,7 +213,7 @@ public abstract class CodegenContext {
if (descriptor instanceof SimpleFunctionDescriptor) {
SimpleFunctionDescriptorImpl myAccessor = new SimpleFunctionDescriptorImpl(contextDescriptor,
Collections.<AnnotationDescriptor>emptyList(),
Name.identifier(descriptor.getName() + "$bridge$" + accessors.size()),
Name.identifier(descriptor.getName() + "$b$" + getHierarchyCount() + "$" + accessors.size()),
CallableMemberDescriptor.Kind.DECLARATION);
FunctionDescriptor fd = (SimpleFunctionDescriptor) descriptor;
myAccessor.initialize(fd.getReceiverParameter().exists() ? fd.getReceiverParameter().getType() : null,
@@ -259,6 +260,18 @@ public abstract class CodegenContext {
return accessor;
}
private int getHierarchyCount() {
ClassifierDescriptor descriptor = getThisDescriptor();
int c = 0;
while(true) {
Collection<? extends JetType> supertypes = descriptor.getDefaultType().getConstructor().getSupertypes();
if(supertypes.isEmpty())
return c;
c++;
descriptor = supertypes.iterator().next().getConstructor().getDeclarationDescriptor();
}
}
public StackValue getReceiverExpression(JetTypeMapper typeMapper) {
assert getReceiverDescriptor() != null;
Type asmType = typeMapper.mapType(getReceiverDescriptor().getReceiverParameter().getType(), MapTypeMode.VALUE);
@@ -1363,9 +1363,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
PsiElement enclosingElement = bindingContext.get(BindingContext.LABEL_TARGET, superExpression.getTargetLabel());
ClassDescriptor enclosed = (ClassDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, enclosingElement);
if (!CodegenUtil.isInterface(fd.getContainingDeclaration())) {
if (enclosed != null && enclosed != context.getThisDescriptor()) {
if(enclosed == null) {
enclosed = (ClassDescriptor) fd.getContainingDeclaration();
}
if (enclosed != context.getThisDescriptor()) {
CodegenContext c = context;
while(c.getContextDescriptor() != enclosed) {
while(!(c instanceof CodegenContexts.ClassContext) || !DescriptorUtils.isSubclass(c.getThisDescriptor(), enclosed)) {
c = c.getParentContext();
}
fd = (FunctionDescriptor) c.getAccessor(fd);
@@ -0,0 +1,14 @@
fun box() =
B().method()
public open class A(){
public open fun method() : String = "OK"
}
public class B(): A(){
public override fun method() : String {
return ({
super.method()
})()
}
}
@@ -121,6 +121,10 @@ public class FunctionGenTest extends CodegenTestCase {
blackBoxFile("functions/invoke.kt");
}
public void test2481() {
blackBoxFile("regressions/kt2481.kt");
}
public static class WithJavaFunctionGenTest extends CodegenTestCase {
private void blackBoxFileWithJava(@NotNull String ktFile) throws Exception {
File javaClassesTempDirectory = new File(FileUtil.getTempDirectory(), "java-classes");