Support default method invocation via super

#KT-5970 Fixed
This commit is contained in:
Michael Bogdanov
2015-05-05 16:04:16 +03:00
parent 3fbdf05921
commit 99cad4b43f
4 changed files with 54 additions and 3 deletions
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
import org.jetbrains.kotlin.load.kotlin.nativeDeclarations.NativeDeclarationsPackage;
@@ -566,10 +567,17 @@ public class JetTypeMapper {
ownerForDefaultImpl = isInterface(ownerForDefault) ? mapTraitImpl(ownerForDefault) : ownerForDefaultParam;
if (isInterface && superCall) {
invokeOpcode = INVOKESTATIC;
signature = mapSignature(functionDescriptor, OwnerKind.TRAIT_IMPL);
owner = mapTraitImpl(currentOwner);
thisClass = mapClass(currentOwner);
if (declarationOwner instanceof JavaClassDescriptor) {
invokeOpcode = INVOKESPECIAL;
signature = mapSignature(functionDescriptor);
owner = thisClass;
}
else {
invokeOpcode = INVOKESTATIC;
signature = mapSignature(functionDescriptor, OwnerKind.TRAIT_IMPL);
owner = mapTraitImpl(currentOwner);
}
}
else {
if (isStaticDeclaration(functionDescriptor) ||
@@ -71,6 +71,12 @@ public class BlackBoxWithJava8CodegenTestGenerated extends AbstractBlackBoxCodeg
doTestWithJava(fileName);
}
@TestMetadata("invokeDefaultViaSuper")
public void testInvokeDefaultViaSuper() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/java8/boxWithJava/invokeDefaultViaSuper/");
doTestWithJava(fileName);
}
@TestMetadata("samOnInterfaceWithDefaultMethod")
public void testSamOnInterfaceWithDefaultMethod() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/java8/boxWithJava/samOnInterfaceWithDefaultMethod/");
@@ -0,0 +1,5 @@
public interface Test {
default String test() {
return "OK";
}
}
@@ -0,0 +1,32 @@
trait KTrait : Test {
}
class KClass : Test {
fun ktest(): String {
return super.test() + test()
}
}
class KTClass : KTrait {
fun ktest(): String {
return super.test() + test()
}
}
fun box(): String {
val p = object : KTrait {
fun ktest(): String {
return super.test() + test()
}
}.ktest()
if (p != "OKOK") return "fail1: $p"
if (KClass().ktest() != "OKOK") return "fail 2: ${KClass().ktest()}"
if (KTClass().ktest() != "OKOK") return "fail 3: ${KTClass().ktest()}"
return "OK"
}