Don't generate delegates on overriding jvm8 interfaces
This commit is contained in:
@@ -1326,7 +1326,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getNonPrivateTraitMethods(descriptor).entrySet()) {
|
||||
FunctionDescriptor traitFun = entry.getKey();
|
||||
//skip java 8 default methods
|
||||
if (!(traitFun instanceof JavaCallableMemberDescriptor)) {
|
||||
if (!(traitFun instanceof JavaCallableMemberDescriptor || isJvm8InterfaceMember(traitFun, state))) {
|
||||
generateDelegationToTraitImpl(traitFun, entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,11 +28,11 @@ import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||
import org.jetbrains.kotlin.codegen.context.FacadePartWithSourceFile;
|
||||
import org.jetbrains.kotlin.codegen.context.MethodContext;
|
||||
import org.jetbrains.kotlin.codegen.context.RootContext;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor;
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleMapping;
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityUtilsKt;
|
||||
import org.jetbrains.kotlin.load.kotlin.*;
|
||||
import org.jetbrains.kotlin.psi.Call;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.psi.KtFunction;
|
||||
@@ -43,7 +43,9 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@@ -58,6 +60,32 @@ public class JvmCodegenUtil {
|
||||
private JvmCodegenUtil() {
|
||||
}
|
||||
|
||||
public static boolean isJvm6Interface(@NotNull DeclarationDescriptor descriptor, @NotNull GenerationState state) {
|
||||
if (!DescriptorUtils.isInterface(descriptor)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (descriptor instanceof DeserializedClassDescriptor) {
|
||||
SourceElement source = ((DeserializedClassDescriptor) descriptor).getSource();
|
||||
if (source instanceof KotlinJvmBinarySourceElement) {
|
||||
KotlinJvmBinaryClass binaryClass = ((KotlinJvmBinarySourceElement) source).getBinaryClass();
|
||||
assert binaryClass instanceof FileBasedKotlinClass :
|
||||
"KotlinJvmBinaryClass should be subclass of FileBasedKotlinClass, but " + binaryClass;
|
||||
return ((FileBasedKotlinClass) binaryClass).getClassVersion() == Opcodes.V1_6;
|
||||
}
|
||||
}
|
||||
return !state.isJvm8Target();
|
||||
}
|
||||
|
||||
public static boolean isJvm8Interface(@NotNull DeclarationDescriptor descriptor, @NotNull GenerationState state) {
|
||||
return DescriptorUtils.isInterface(descriptor) && !isJvm6Interface(descriptor, state);
|
||||
}
|
||||
|
||||
public static boolean isJvm8InterfaceMember(@NotNull CallableMemberDescriptor descriptor, @NotNull GenerationState state) {
|
||||
DeclarationDescriptor declaration = descriptor.getContainingDeclaration();
|
||||
return DescriptorUtils.isInterface(declaration) && !isJvm6Interface(declaration, state);
|
||||
}
|
||||
|
||||
public static boolean isJvmInterface(DeclarationDescriptor descriptor) {
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
ClassKind kind = ((ClassDescriptor) descriptor).getKind();
|
||||
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
// KOTLIN_CONFIGURATION_FLAGS: +JVM.JVM_8_TARGET
|
||||
// WITH_RUNTIME
|
||||
// FULL_JDK
|
||||
interface Test {
|
||||
fun test() {
|
||||
}
|
||||
}
|
||||
|
||||
class TestClass : Test {
|
||||
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
try {
|
||||
TestClass::class.java.getDeclaredMethod("test")
|
||||
}
|
||||
catch (e: NoSuchMethodException) {
|
||||
return "OK"
|
||||
}
|
||||
return "fail"
|
||||
}
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
// KOTLIN_CONFIGURATION_FLAGS: +JVM.JVM_8_TARGET
|
||||
// WITH_RUNTIME
|
||||
// FULL_JDK
|
||||
interface Test {
|
||||
fun test() {
|
||||
}
|
||||
}
|
||||
|
||||
interface Test2 : Test {
|
||||
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
try {
|
||||
Test2::class.java.getDeclaredMethod("test")
|
||||
}
|
||||
catch (e: NoSuchMethodException) {
|
||||
return "OK"
|
||||
}
|
||||
return "fail"
|
||||
}
|
||||
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
// KOTLIN_CONFIGURATION_FLAGS: +JVM.JVM_8_TARGET
|
||||
// WITH_RUNTIME
|
||||
// FULL_JDK
|
||||
interface Test {
|
||||
fun test() {
|
||||
}
|
||||
}
|
||||
|
||||
interface Test2 : Test {
|
||||
|
||||
}
|
||||
|
||||
interface Test3 : Test2 {
|
||||
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
try {
|
||||
Test3::class.java.getDeclaredMethod("test")
|
||||
}
|
||||
catch (e: NoSuchMethodException) {
|
||||
return "OK"
|
||||
}
|
||||
return "fail"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// KOTLIN_CONFIGURATION_FLAGS: +JVM.JVM_8_TARGET
|
||||
interface Test {
|
||||
fun test(): String {
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
|
||||
class TestClass : Test {
|
||||
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return TestClass().test()
|
||||
}
|
||||
+42
@@ -119,6 +119,48 @@ public class BlackBoxWithJava8CodegenTestGenerated extends AbstractBlackBoxCodeg
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/java8/box/jvm8")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Jvm8 extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInJvm8() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/java8/box/jvm8"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("simpleCall.kt")
|
||||
public void testSimpleCall() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/jvm8/simpleCall.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/java8/box/jvm8/noDelegation")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class NoDelegation extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInNoDelegation() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/java8/box/jvm8/noDelegation"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("noDelegationToDefaultMethodInClass.kt")
|
||||
public void testNoDelegationToDefaultMethodInClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/jvm8/noDelegation/noDelegationToDefaultMethodInClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("noDelegationToDefaultMethodInInterface.kt")
|
||||
public void testNoDelegationToDefaultMethodInInterface() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/jvm8/noDelegation/noDelegationToDefaultMethodInInterface.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("noDelegationToDefaultMethodInInterface2.kt")
|
||||
public void testNoDelegationToDefaultMethodInInterface2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/jvm8/noDelegation/noDelegationToDefaultMethodInInterface2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/java8/box/mapRemove")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user