Refactor bridges generation for JVM

Make a separate subclass for DescriptorBasedFunctionHandle
to allow customize the behavior without complex abstract concepts
like `areDeclarationAndDefinitionSame`
This commit is contained in:
Denis Zharkov
2018-12-20 08:37:04 +03:00
parent 5cc242e878
commit 949214c10b
6 changed files with 85 additions and 70 deletions
@@ -25,10 +25,9 @@ import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesi
fun <Signature> generateBridgesForFunctionDescriptor(
descriptor: FunctionDescriptor,
signature: (FunctionDescriptor) -> Signature,
areDeclarationAndDefinitionSame: (CallableMemberDescriptor) -> Boolean
signature: (FunctionDescriptor) -> Signature
): Set<Bridge<Signature>> {
return generateBridges(DescriptorBasedFunctionHandle(descriptor, areDeclarationAndDefinitionSame), { signature(it.descriptor) })
return generateBridges(DescriptorBasedFunctionHandle(descriptor), { signature(it.descriptor) })
}
/**
@@ -48,34 +47,26 @@ 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.
*/
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 @JvmDefault JVM members they are placed in interface classes and
we need generate bridge for such function ('isAbstract' will return false).
For non-@JvmDefault function, its 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.
*/
areDeclarationAndDefinitionSame: (CallableMemberDescriptor) -> Boolean
) : FunctionHandle {
private val overridden = descriptor.overriddenDescriptors.map {
DescriptorBasedFunctionHandle(
it.original,
areDeclarationAndDefinitionSame
)
open class DescriptorBasedFunctionHandle(val descriptor: FunctionDescriptor) : FunctionHandle {
private val _overridden by lazy(LazyThreadSafetyMode.NONE) {
descriptor.overriddenDescriptors.map {
createHandleForOverridden(
it.original
)
}
}
protected open fun createHandleForOverridden(overridden: FunctionDescriptor) = DescriptorBasedFunctionHandle(overridden)
override val isDeclaration: Boolean = descriptor.kind.isReal || findInterfaceImplementation(descriptor) != null
override val isAbstract: Boolean =
descriptor.modality == Modality.ABSTRACT || !areDeclarationAndDefinitionSame(descriptor)
descriptor.modality == Modality.ABSTRACT
override val mayBeUsedAsSuperImplementation: Boolean =
!DescriptorUtils.isInterface(descriptor.containingDeclaration)
override fun getOverridden() = overridden
override fun getOverridden() = _overridden
override fun hashCode(): Int {
return descriptor.hashCode()