Support bridges in interfaces. Fix for KT-12416: Missed bridges in js backend
#KT-12416 Fixed
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user