diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 0385d709710..d89831cc1af 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -41,6 +41,7 @@ import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl; import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature; import org.jetbrains.kotlin.load.java.JvmAbi; import org.jetbrains.kotlin.load.java.SpecialBuiltinMembers; +import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.psi.KtElement; import org.jetbrains.kotlin.psi.KtFunction; @@ -85,8 +86,7 @@ import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBinding import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION; import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*; import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor; -import static org.jetbrains.kotlin.resolve.DescriptorUtils.getSuperClassDescriptor; -import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface; +import static org.jetbrains.kotlin.resolve.DescriptorUtils.*; import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE; import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*; import static org.jetbrains.org.objectweb.asm.Opcodes.*; @@ -699,13 +699,25 @@ public class FunctionCodegen { CallableDescriptor overridden = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor); assert overridden != null; - Method method = typeMapper.mapAsmMethod(descriptor); - int flags = ACC_ABSTRACT | getVisibilityAccessFlag(descriptor); - v.newMethod(JvmDeclarationOriginKt.OtherOrigin(overridden), flags, method.getName(), method.getDescriptor(), null, null); + if (!isThereOverriddenInKotlinClass(descriptor)) { + Method method = typeMapper.mapAsmMethod(descriptor); + int flags = ACC_ABSTRACT | getVisibilityAccessFlag(descriptor); + v.newMethod(JvmDeclarationOriginKt.OtherOrigin(overridden), flags, method.getName(), method.getDescriptor(), null, null); + } } } } + private static boolean isThereOverriddenInKotlinClass(@NotNull CallableMemberDescriptor descriptor) { + return CollectionsKt.any(getAllOverriddenDescriptors(descriptor), new Function1() { + @Override + public Boolean invoke(CallableMemberDescriptor descriptor) { + return !(descriptor.getContainingDeclaration() instanceof JavaClassDescriptor) && + isClass(descriptor.getContainingDeclaration()); + } + }); + } + @NotNull private static Function1 getSignatureMapper(final @NotNull KotlinTypeMapper typeMapper) { return new Function1() { diff --git a/compiler/testData/codegen/bytecodeListing/specialBridges/noSpecialBridgeIfPresentInSuperClass.kt b/compiler/testData/codegen/bytecodeListing/specialBridges/noSpecialBridgeIfPresentInSuperClass.kt new file mode 100644 index 00000000000..fdc81e4f175 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/specialBridges/noSpecialBridgeIfPresentInSuperClass.kt @@ -0,0 +1,2 @@ +abstract class A : List +abstract class B : A() diff --git a/compiler/testData/codegen/bytecodeListing/specialBridges/noSpecialBridgeIfPresentInSuperClass.txt b/compiler/testData/codegen/bytecodeListing/specialBridges/noSpecialBridgeIfPresentInSuperClass.txt new file mode 100644 index 00000000000..894d6dd2f31 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/specialBridges/noSpecialBridgeIfPresentInSuperClass.txt @@ -0,0 +1,29 @@ +@kotlin.Metadata +public abstract class A { + public method (): void + public method add(p0: int, p1: java.lang.Object): void + public method add(p0: java.lang.Object): boolean + public method addAll(p0: int, p1: java.util.Collection): boolean + public method addAll(p0: java.util.Collection): boolean + public method clear(): void + public abstract method contains(p0: java.lang.Object): boolean + public abstract method getSize(): int + public abstract method indexOf(p0: java.lang.Object): int + public abstract method lastIndexOf(p0: java.lang.Object): int + public method listIterator(): java.util.ListIterator + public method listIterator(p0: int): java.util.ListIterator + public method remove(p0: int): java.lang.Object + public method remove(p0: java.lang.Object): boolean + public method removeAll(p0: java.util.Collection): boolean + public method retainAll(p0: java.util.Collection): boolean + public method set(p0: int, p1: java.lang.Object): java.lang.Object + public final method size(): int + public method subList(p0: int, p1: int): java.util.List + public method toArray(): java.lang.Object[] + public method toArray(p0: java.lang.Object[]): java.lang.Object[] +} + +@kotlin.Metadata +public abstract class B { + public method (): void +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index 7a93b47f4aa..26316bd138b 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -187,6 +187,12 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { doTest(fileName); } + @TestMetadata("noSpecialBridgeIfPresentInSuperClass.kt") + public void testNoSpecialBridgeIfPresentInSuperClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/specialBridges/noSpecialBridgeIfPresentInSuperClass.kt"); + doTest(fileName); + } + @TestMetadata("redundantStubForSize.kt") public void testRedundantStubForSize() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/specialBridges/redundantStubForSize.kt");