Support bridges in interfaces. Fix for KT-12416: Missed bridges in js backend

#KT-12416 Fixed
This commit is contained in:
Mikhael Bogdanov
2016-05-19 15:55:18 +03:00
parent c778af518b
commit bb59638039
12 changed files with 235 additions and 22 deletions
@@ -17,7 +17,7 @@
package org.jetbrains.kotlin.backend.common.bridges
import org.jetbrains.kotlin.utils.DFS
import java.util.HashSet
import java.util.*
interface FunctionHandle {
val isDeclaration: Boolean
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.backend.common.bridges
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.resolve.DescriptorUtils
@@ -25,9 +26,10 @@ import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesi
fun <Signature> generateBridgesForFunctionDescriptor(
descriptor: FunctionDescriptor,
signature: (FunctionDescriptor) -> Signature
signature: (FunctionDescriptor) -> Signature,
isBodyOwner: (DeclarationDescriptor) -> Boolean
): Set<Bridge<Signature>> {
return generateBridges(DescriptorBasedFunctionHandle(descriptor), { signature(it.descriptor) })
return generateBridges(DescriptorBasedFunctionHandle(descriptor, isBodyOwner), { signature(it.descriptor) })
}
/**
@@ -47,8 +49,19 @@ fun <Signature> generateBridgesForFunctionDescriptor(
* can generate a bridge near an implementation (of course, in case it has a super-declaration with a different signature). Ultimately this
* eases the process of determining what bridges are already generated in our supertypes and need to be inherited, not regenerated.
*/
data class DescriptorBasedFunctionHandle(val descriptor: FunctionDescriptor) : FunctionHandle {
private val overridden = descriptor.overriddenDescriptors.map { DescriptorBasedFunctionHandle(it.original) }
class DescriptorBasedFunctionHandle(
val descriptor: FunctionDescriptor,
/*
To generate proper bridges for non-abstract function
we should know if the function declaration and its definition in the target platform are the same or not.
For JS and JVM8 they are placed in interface classes and we need generate bridge for such function ('isAbstract' will return false).
For JVM6 target function body generated in separate place (DefaultImpl) and method in interface is abstract
For JVM6 target function body is generated in a separate place (DefaultImpls) and
the method in the interface is abstract so we must not generate bridges for such cases.
*/
isBodyOwner: (DeclarationDescriptor) -> Boolean
) : FunctionHandle {
private val overridden = descriptor.overriddenDescriptors.map { DescriptorBasedFunctionHandle(it.original, isBodyOwner) }
override val isDeclaration: Boolean =
descriptor.kind.isReal ||
@@ -56,9 +69,17 @@ data class DescriptorBasedFunctionHandle(val descriptor: FunctionDescriptor) : F
override val isAbstract: Boolean =
descriptor.modality == Modality.ABSTRACT ||
DescriptorUtils.isInterface(descriptor.containingDeclaration)
isBodyOwner(descriptor.containingDeclaration)
override fun getOverridden() = overridden
override fun hashCode(): Int {
return descriptor.hashCode()
}
override fun equals(other: Any?): Boolean {
return other is DescriptorBasedFunctionHandle && descriptor == other.descriptor
}
}