Avoid generation of redundant abstract special stubs

#KT-13698 Fixed
This commit is contained in:
Denis Zharkov
2016-10-05 16:24:54 +03:00
parent 6e838f0adc
commit dfb9b323ff
4 changed files with 54 additions and 5 deletions
@@ -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<CallableMemberDescriptor, Boolean>() {
@Override
public Boolean invoke(CallableMemberDescriptor descriptor) {
return !(descriptor.getContainingDeclaration() instanceof JavaClassDescriptor) &&
isClass(descriptor.getContainingDeclaration());
}
});
}
@NotNull
private static Function1<FunctionDescriptor, Method> getSignatureMapper(final @NotNull KotlinTypeMapper typeMapper) {
return new Function1<FunctionDescriptor, Method>() {
@@ -0,0 +1,2 @@
abstract class A<T> : List<T>
abstract class B<E> : A<E>()
@@ -0,0 +1,29 @@
@kotlin.Metadata
public abstract class A {
public method <init>(): 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 <init>(): void
}
@@ -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");