Generate common bridges for final builtin declaration

#KT-9596 Fixed
This commit is contained in:
Denis Zharkov
2015-10-16 19:32:41 +03:00
parent cc94acdabc
commit fafca76ac5
4 changed files with 45 additions and 22 deletions
@@ -69,7 +69,11 @@ object BuiltinSpecialBridgesUtil {
val bridgesToGenerate = reachableDeclarations.mapTo(LinkedHashSet<Signature>(), signatureByDescriptor)
bridgesToGenerate.remove(overriddenBuiltinSignature)
bridgesToGenerate.remove(methodItself)
val superImplementationDescriptor = findSuperImplementationForStubDelegation(function, fake)
if (superImplementationDescriptor != null || !fake) {
bridgesToGenerate.remove(methodItself)
}
if (fake) {
for (overridden in function.overriddenDescriptors.map { it.original }) {
@@ -80,19 +84,25 @@ object BuiltinSpecialBridgesUtil {
}
val bridges: MutableSet<BridgeForBuiltinSpecial<Signature>> =
(bridgesToGenerate.map { BridgeForBuiltinSpecial(it, methodItself) } + specialBridge.singletonOrEmptyList()).toMutableSet()
(bridgesToGenerate.map { BridgeForBuiltinSpecial(it, overriddenBuiltinSignature) } + specialBridge.singletonOrEmptyList()).toMutableSet()
if (function.modality == Modality.OPEN && fake) {
val implementation = findConcreteSuperDeclaration(DescriptorBasedFunctionHandle(function)).descriptor
if (!DescriptorUtils.isInterface(implementation.containingDeclaration)) {
bridges.add(BridgeForBuiltinSpecial(methodItself, signatureByDescriptor(implementation), isDelegateToSuper = true))
}
if (superImplementationDescriptor != null) {
bridges.add(BridgeForBuiltinSpecial(methodItself, signatureByDescriptor(superImplementationDescriptor), isDelegateToSuper = true))
}
return bridges
}
}
private fun findSuperImplementationForStubDelegation(function: FunctionDescriptor, fake: Boolean): FunctionDescriptor? {
if (function.modality != Modality.OPEN || !fake) return null
val implementation = findConcreteSuperDeclaration(DescriptorBasedFunctionHandle(function)).descriptor
if (DescriptorUtils.isInterface(implementation.containingDeclaration)) return null
return implementation
}
private fun findAllReachableDeclarations(functionDescriptor: FunctionDescriptor): MutableSet<FunctionDescriptor> =
findAllReachableDeclarations(DescriptorBasedFunctionHandle(functionDescriptor)).map { it.descriptor }.toMutableSet()
@@ -0,0 +1,16 @@
interface Ordinaled {
val ordinal: Int
}
enum class A : Ordinaled {
X
}
fun box(): String {
val result = (A.X as Ordinaled).ordinal
if (result != 0) return "fail 1: $result"
return "OK"
}
@@ -90,27 +90,18 @@ fun box(
}
/*
9 public final bridge remove\(I\) -> Bridges for removeAt from A1-A10, but no in A9 (interface)
7 public synthetic bridge remove\(I\)Ljava/lang/Object; -> Synthetic bridges from A2-A7 + A10. None for A9 (interface) and A8 (inherited from ArrayList)
16 INVOKEVIRTUAL A[0-9]+.removeAt \(I\) -> calls in bridges
1 public remove\(Ljava/lang/Integer;\)Z -> implementation in A10
3 public abstract removeAt\(I\) -> A4, A6, A7
9 INVOKEVIRTUAL A[0-9]+.removeAt \(I\) -> calls in bridges with signature `public final bridge remove\(I\)`
16 INVOKEVIRTUAL A[0-9]+\.remove \(I\) -> calls to A1-A9.removeAt + 7 calls from `public synthetic bridge remove\(I\)Ljava/lang/Object;`
1 INVOKEINTERFACE A9\.remove \(I\) -> call A9.removeAt
1 INVOKEINTERFACE A9\.remove \(Ljava/lang/Object;\) -> call A9.remove
9 INVOKEVIRTUAL A[0-9]+\.remove \(I\) -> calls to A1-A9.removeAt
2 INVOKEVIRTUAL A10\.remove \(I\) -> one call in function and one from `public synthetic bridge remove(I)Ljava/lang/Object;` bridge in A10
*/
// 9 public final bridge remove\(I\)
// 7 public synthetic bridge remove\(I\)Ljava/lang/Object;
// 1 public remove\(Ljava/lang/Integer;\)Z
// 3 public abstract removeAt\(I\)
// 16 INVOKEVIRTUAL A[0-9]+.removeAt \(I\)
// 9 INVOKEVIRTUAL A[0-9]+.removeAt \(I\)
// 16 INVOKEVIRTUAL A[0-9]+\.remove \(I\)
// 1 INVOKEINTERFACE A9\.remove \(I\)
// 1 INVOKEINTERFACE A9\.remove \(Ljava/lang/Object;\)
// 9 INVOKEVIRTUAL A[0-9]+\.remove \(I\)
// 1 INVOKEVIRTUAL A10\.remove \(I\)
// 9 INVOKEVIRTUAL A[0-9]+\.remove \(I\)
// 1 INVOKEVIRTUAL A10\.remove \(I\)
// 2 INVOKEVIRTUAL A10\.remove \(I\)
// 2 INVOKEINTERFACE java\/util\/List.remove \(I\)
// 2 INVOKEINTERFACE java\/util\/List.remove \(Ljava/lang/Object;\)
@@ -910,6 +910,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName);
}
@TestMetadata("enumAsOrdinaled.kt")
public void testEnumAsOrdinaled() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/builtinsProperties/enumAsOrdinaled.kt");
doTest(fileName);
}
@TestMetadata("explicitSuperCall.kt")
public void testExplicitSuperCall() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/builtinsProperties/explicitSuperCall.kt");