Check method abstractness during bridge generation per method not interface

This commit is contained in:
Mikhael Bogdanov
2018-03-06 12:13:19 +01:00
parent f290b325ee
commit 2a8041e77e
19 changed files with 490 additions and 80 deletions
@@ -17,20 +17,18 @@
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.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized
fun <Signature> generateBridgesForFunctionDescriptor(
descriptor: FunctionDescriptor,
signature: (FunctionDescriptor) -> Signature,
isBodyOwner: (DeclarationDescriptor) -> Boolean
descriptor: FunctionDescriptor,
signature: (FunctionDescriptor) -> Signature,
areDeclarationAndDefinitionSame: (CallableMemberDescriptor) -> Boolean
): Set<Bridge<Signature>> {
return generateBridges(DescriptorBasedFunctionHandle(descriptor, isBodyOwner), { signature(it.descriptor) })
return generateBridges(DescriptorBasedFunctionHandle(descriptor, areDeclarationAndDefinitionSame), { signature(it.descriptor) })
}
/**
@@ -51,26 +49,28 @@ fun <Signature> generateBridgesForFunctionDescriptor(
* 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 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
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, isBodyOwner) }
private val overridden = descriptor.overriddenDescriptors.map {
DescriptorBasedFunctionHandle(
it.original,
areDeclarationAndDefinitionSame
)
}
override val isDeclaration: Boolean =
descriptor.kind.isReal ||
findInterfaceImplementation(descriptor) != null
override val isDeclaration: Boolean = descriptor.kind.isReal || findInterfaceImplementation(descriptor) != null
override val isAbstract: Boolean =
descriptor.modality == Modality.ABSTRACT ||
isBodyOwner(descriptor.containingDeclaration)
descriptor.modality == Modality.ABSTRACT || !areDeclarationAndDefinitionSame(descriptor)
override val isInterfaceDeclaration: Boolean
get() = DescriptorUtils.isInterface(descriptor.containingDeclaration)