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( fun <Signature> generateBridgesForFunctionDescriptor(
descriptor: FunctionDescriptor, descriptor: FunctionDescriptor,
signature: (FunctionDescriptor) -> Signature, signature: (FunctionDescriptor) -> Signature
areDeclarationAndDefinitionSame: (CallableMemberDescriptor) -> Boolean
): Set<Bridge<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 * 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. * eases the process of determining what bridges are already generated in our supertypes and need to be inherited, not regenerated.
*/ */
class DescriptorBasedFunctionHandle( open class DescriptorBasedFunctionHandle(val descriptor: FunctionDescriptor) : FunctionHandle {
val descriptor: FunctionDescriptor, private val _overridden by lazy(LazyThreadSafetyMode.NONE) {
/* descriptor.overriddenDescriptors.map {
To generate proper bridges for non-abstract function createHandleForOverridden(
we should know if the function declaration and its definition in the target platform are the same or not. it.original
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
)
} }
protected open fun createHandleForOverridden(overridden: FunctionDescriptor) = DescriptorBasedFunctionHandle(overridden)
override val isDeclaration: Boolean = descriptor.kind.isReal || findInterfaceImplementation(descriptor) != null override val isDeclaration: Boolean = descriptor.kind.isReal || findInterfaceImplementation(descriptor) != null
override val isAbstract: Boolean = override val isAbstract: Boolean =
descriptor.modality == Modality.ABSTRACT || !areDeclarationAndDefinitionSame(descriptor) descriptor.modality == Modality.ABSTRACT
override val mayBeUsedAsSuperImplementation: Boolean = override val mayBeUsedAsSuperImplementation: Boolean =
!DescriptorUtils.isInterface(descriptor.containingDeclaration) !DescriptorUtils.isInterface(descriptor.containingDeclaration)
override fun getOverridden() = overridden override fun getOverridden() = _overridden
override fun hashCode(): Int { override fun hashCode(): Int {
return descriptor.hashCode() return descriptor.hashCode()
@@ -9,13 +9,11 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.util.ArrayUtil; import com.intellij.util.ArrayUtil;
import kotlin.collections.CollectionsKt; import kotlin.collections.CollectionsKt;
import kotlin.jvm.functions.Function1;
import kotlin.text.StringsKt; import kotlin.text.StringsKt;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.CodegenUtil; import org.jetbrains.kotlin.backend.common.CodegenUtil;
import org.jetbrains.kotlin.backend.common.bridges.Bridge; import org.jetbrains.kotlin.backend.common.bridges.Bridge;
import org.jetbrains.kotlin.backend.common.bridges.ImplKt;
import org.jetbrains.kotlin.codegen.binding.CodegenBinding; import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
import org.jetbrains.kotlin.codegen.context.*; import org.jetbrains.kotlin.codegen.context.*;
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt; import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
@@ -25,7 +23,6 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper; import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.codegen.state.TypeMapperUtilsKt; import org.jetbrains.kotlin.codegen.state.TypeMapperUtilsKt;
import org.jetbrains.kotlin.config.JvmDefaultMode; import org.jetbrains.kotlin.config.JvmDefaultMode;
import org.jetbrains.kotlin.config.JvmTarget;
import org.jetbrains.kotlin.config.LanguageFeature; import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotated; import org.jetbrains.kotlin.descriptors.annotations.Annotated;
@@ -92,15 +89,6 @@ public class FunctionCodegen {
private final ClassBuilder v; private final ClassBuilder v;
private final MemberCodegen<?> memberCodegen; private final MemberCodegen<?> memberCodegen;
private final Function1<CallableMemberDescriptor, Boolean> DECLARATION_AND_DEFINITION_CHECKER = new Function1<CallableMemberDescriptor, Boolean>() {
@Override
public Boolean invoke(CallableMemberDescriptor descriptor) {
return !isInterface(descriptor.getContainingDeclaration()) ||
(state.getTarget() != JvmTarget.JVM_1_6 &&
hasJvmDefaultAnnotation(descriptor));
}
};
public FunctionCodegen( public FunctionCodegen(
@NotNull CodegenContext owner, @NotNull CodegenContext owner,
@NotNull ClassBuilder v, @NotNull ClassBuilder v,
@@ -1069,14 +1057,14 @@ public class FunctionCodegen {
private boolean hasSpecialBridgeMethod(@NotNull FunctionDescriptor descriptor) { private boolean hasSpecialBridgeMethod(@NotNull FunctionDescriptor descriptor) {
if (SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor) == null) return false; if (SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor) == null) return false;
return !BuiltinSpecialBridgesUtil.generateBridgesForBuiltinSpecial( return !BuiltinSpecialBridgesUtil.generateBridgesForBuiltinSpecial(
descriptor, typeMapper::mapAsmMethod, DECLARATION_AND_DEFINITION_CHECKER descriptor, typeMapper::mapAsmMethod, state.getTarget()
).isEmpty(); ).isEmpty();
} }
public void generateBridges(@NotNull FunctionDescriptor descriptor) { public void generateBridges(@NotNull FunctionDescriptor descriptor) {
if (descriptor instanceof ConstructorDescriptor) return; if (descriptor instanceof ConstructorDescriptor) return;
if (owner.getContextKind() == OwnerKind.DEFAULT_IMPLS) return; if (owner.getContextKind() == OwnerKind.DEFAULT_IMPLS) return;
if (!DECLARATION_AND_DEFINITION_CHECKER.invoke(descriptor)) return; if (JvmBridgesImplKt.isAbstractOnJvmIgnoringActualModality(state.getTarget(), descriptor)) return;
// equals(Any?), hashCode(), toString() never need bridges // equals(Any?), hashCode(), toString() never need bridges
if (isMethodOfAny(descriptor)) return; if (isMethodOfAny(descriptor)) return;
@@ -1086,7 +1074,7 @@ public class FunctionCodegen {
Set<Bridge<Method>> bridgesToGenerate; Set<Bridge<Method>> bridgesToGenerate;
if (!isSpecial) { if (!isSpecial) {
bridgesToGenerate = bridgesToGenerate =
ImplKt.generateBridgesForFunctionDescriptor(descriptor, typeMapper::mapAsmMethod, DECLARATION_AND_DEFINITION_CHECKER); JvmBridgesImplKt.generateBridgesForFunctionDescriptorForJvm(descriptor, typeMapper::mapAsmMethod, state.getTarget());
if (!bridgesToGenerate.isEmpty()) { if (!bridgesToGenerate.isEmpty()) {
PsiElement origin = descriptor.getKind() == DECLARATION ? getSourceFromDescriptor(descriptor) : null; PsiElement origin = descriptor.getKind() == DECLARATION ? getSourceFromDescriptor(descriptor) : null;
boolean isSpecialBridge = boolean isSpecialBridge =
@@ -1099,7 +1087,7 @@ public class FunctionCodegen {
} }
else { else {
Set<BridgeForBuiltinSpecial<Method>> specials = BuiltinSpecialBridgesUtil.generateBridgesForBuiltinSpecial( Set<BridgeForBuiltinSpecial<Method>> specials = BuiltinSpecialBridgesUtil.generateBridgesForBuiltinSpecial(
descriptor, typeMapper::mapAsmMethod, DECLARATION_AND_DEFINITION_CHECKER descriptor, typeMapper::mapAsmMethod, state.getTarget()
); );
if (!specials.isEmpty()) { if (!specials.isEmpty()) {
@@ -0,0 +1,46 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.backend.common.bridges.Bridge
import org.jetbrains.kotlin.backend.common.bridges.DescriptorBasedFunctionHandle
import org.jetbrains.kotlin.backend.common.bridges.generateBridges
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmDefaultAnnotation
class DescriptorBasedFunctionHandleForJvm(
descriptor: FunctionDescriptor,
private val jvmTarget: JvmTarget
) : DescriptorBasedFunctionHandle(descriptor) {
override fun createHandleForOverridden(overridden: FunctionDescriptor) =
DescriptorBasedFunctionHandleForJvm(overridden, jvmTarget)
/*
For @JvmDefault JVM members they are placed in interface classes and
we need generate bridge for such function ('isAbstract' will return false).
For non-@JvmDefault interfaces 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.
*/
override val isAbstract: Boolean = super.isAbstract || isAbstractOnJvmIgnoringActualModality(jvmTarget, descriptor)
}
/**
* @return return true for interface method not annotated with @JvmDefault
*/
fun isAbstractOnJvmIgnoringActualModality(jvmTarget: JvmTarget, descriptor: FunctionDescriptor): Boolean {
if (!DescriptorUtils.isInterface(descriptor.containingDeclaration)) return false
return jvmTarget == JvmTarget.JVM_1_6 || !descriptor.hasJvmDefaultAnnotation()
}
fun <Signature> generateBridgesForFunctionDescriptorForJvm(
descriptor: FunctionDescriptor,
signature: (FunctionDescriptor) -> Signature,
jvmTarget: JvmTarget
): Set<Bridge<Signature>> {
return generateBridges(DescriptorBasedFunctionHandleForJvm(descriptor, jvmTarget)) { signature(it.descriptor) }
}
@@ -16,9 +16,9 @@
package org.jetbrains.kotlin.codegen package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.backend.common.bridges.DescriptorBasedFunctionHandle
import org.jetbrains.kotlin.backend.common.bridges.findAllReachableDeclarations import org.jetbrains.kotlin.backend.common.bridges.findAllReachableDeclarations
import org.jetbrains.kotlin.backend.common.bridges.findConcreteSuperDeclaration import org.jetbrains.kotlin.backend.common.bridges.findConcreteSuperDeclaration
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
@@ -47,14 +47,14 @@ object BuiltinSpecialBridgesUtil {
fun <Signature : Any> generateBridgesForBuiltinSpecial( fun <Signature : Any> generateBridgesForBuiltinSpecial(
function: FunctionDescriptor, function: FunctionDescriptor,
signatureByDescriptor: (FunctionDescriptor) -> Signature, signatureByDescriptor: (FunctionDescriptor) -> Signature,
areDeclarationAndDefinitionSame: (CallableMemberDescriptor) -> Boolean jvmTarget: JvmTarget
): Set<BridgeForBuiltinSpecial<Signature>> { ): Set<BridgeForBuiltinSpecial<Signature>> {
val functionHandle = DescriptorBasedFunctionHandle(function, areDeclarationAndDefinitionSame) val functionHandle = DescriptorBasedFunctionHandleForJvm(function, jvmTarget)
val fake = !functionHandle.isDeclaration val fake = !functionHandle.isDeclaration
val overriddenBuiltin = function.getOverriddenBuiltinReflectingJvmDescriptor()!! val overriddenBuiltin = function.getOverriddenBuiltinReflectingJvmDescriptor()!!
val reachableDeclarations = findAllReachableDeclarations(function, areDeclarationAndDefinitionSame) val reachableDeclarations = findAllReachableDeclarations(function, jvmTarget)
// e.g. `getSize()I` // e.g. `getSize()I`
val methodItself = signatureByDescriptor(function) val methodItself = signatureByDescriptor(function)
@@ -78,11 +78,11 @@ object BuiltinSpecialBridgesUtil {
if (fake) { if (fake) {
for (overridden in function.overriddenDescriptors.map { it.original }) { for (overridden in function.overriddenDescriptors.map { it.original }) {
if (!DescriptorBasedFunctionHandle(overridden, areDeclarationAndDefinitionSame).isAbstract) { if (!DescriptorBasedFunctionHandleForJvm(overridden, jvmTarget).isAbstract) {
commonBridges.removeAll( commonBridges.removeAll(
findAllReachableDeclarations( findAllReachableDeclarations(
overridden, overridden,
areDeclarationAndDefinitionSame jvmTarget
).map(signatureByDescriptor) ).map(signatureByDescriptor)
) )
} }
@@ -93,7 +93,7 @@ object BuiltinSpecialBridgesUtil {
val superImplementationDescriptor = val superImplementationDescriptor =
if (specialBridge != null && fake && !functionHandle.isAbstract) if (specialBridge != null && fake && !functionHandle.isAbstract)
findSuperImplementationForStubDelegation(function, areDeclarationAndDefinitionSame, signatureByDescriptor) findSuperImplementationForStubDelegation(function, jvmTarget, signatureByDescriptor)
else else
null null
@@ -150,10 +150,10 @@ object BuiltinSpecialBridgesUtil {
*/ */
private fun <Signature> findSuperImplementationForStubDelegation( private fun <Signature> findSuperImplementationForStubDelegation(
function: FunctionDescriptor, function: FunctionDescriptor,
areDeclarationAndDefinitionSame: (CallableMemberDescriptor) -> Boolean, jvmTarget: JvmTarget,
signatureByDescriptor: (FunctionDescriptor) -> Signature signatureByDescriptor: (FunctionDescriptor) -> Signature
): FunctionDescriptor? { ): FunctionDescriptor? {
val implementation = findConcreteSuperDeclaration(DescriptorBasedFunctionHandle(function, areDeclarationAndDefinitionSame)) val implementation = findConcreteSuperDeclaration(DescriptorBasedFunctionHandleForJvm(function, jvmTarget))
// Implementation from interface will be generated by common mechanism // Implementation from interface will be generated by common mechanism
if (!implementation.mayBeUsedAsSuperImplementation) return null if (!implementation.mayBeUsedAsSuperImplementation) return null
@@ -170,12 +170,12 @@ private fun <Signature> findSuperImplementationForStubDelegation(
private fun findAllReachableDeclarations( private fun findAllReachableDeclarations(
functionDescriptor: FunctionDescriptor, functionDescriptor: FunctionDescriptor,
areDeclarationAndDefinitionSame: (CallableMemberDescriptor) -> Boolean jvmTarget: JvmTarget
): MutableSet<FunctionDescriptor> = ): MutableSet<FunctionDescriptor> =
findAllReachableDeclarations( findAllReachableDeclarations(
DescriptorBasedFunctionHandle( DescriptorBasedFunctionHandleForJvm(
functionDescriptor, functionDescriptor,
areDeclarationAndDefinitionSame jvmTarget
) )
).map { it.descriptor }.toMutableSet() ).map { it.descriptor }.toMutableSet()
@@ -9,14 +9,11 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.bridges.Bridge import org.jetbrains.kotlin.backend.common.bridges.Bridge
import org.jetbrains.kotlin.backend.common.bridges.findInterfaceImplementation import org.jetbrains.kotlin.backend.common.bridges.findInterfaceImplementation
import org.jetbrains.kotlin.backend.common.bridges.generateBridgesForFunctionDescriptor
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irBlockBody import org.jetbrains.kotlin.backend.common.lower.irBlockBody
import org.jetbrains.kotlin.backend.common.lower.irNot import org.jetbrains.kotlin.backend.common.lower.irNot
import org.jetbrains.kotlin.backend.common.makePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.descriptors.DefaultImplsClassDescriptor
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmFunctionDescriptorImpl import org.jetbrains.kotlin.backend.jvm.descriptors.JvmFunctionDescriptorImpl
import org.jetbrains.kotlin.codegen.AsmUtil.isAbstractMethod import org.jetbrains.kotlin.codegen.AsmUtil.isAbstractMethod
import org.jetbrains.kotlin.codegen.BuiltinSpecialBridgesUtil import org.jetbrains.kotlin.codegen.BuiltinSpecialBridgesUtil
@@ -24,9 +21,9 @@ import org.jetbrains.kotlin.codegen.FunctionCodegen.isMethodOfAny
import org.jetbrains.kotlin.codegen.FunctionCodegen.isThereOverriddenInKotlinClass import org.jetbrains.kotlin.codegen.FunctionCodegen.isThereOverriddenInKotlinClass
import org.jetbrains.kotlin.codegen.JvmCodegenUtil.getDirectMember import org.jetbrains.kotlin.codegen.JvmCodegenUtil.getDirectMember
import org.jetbrains.kotlin.codegen.OwnerKind import org.jetbrains.kotlin.codegen.OwnerKind
import org.jetbrains.kotlin.codegen.generateBridgesForFunctionDescriptorForJvm
import org.jetbrains.kotlin.codegen.isToArrayFromCollection import org.jetbrains.kotlin.codegen.isToArrayFromCollection
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
@@ -44,7 +41,6 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
import org.jetbrains.kotlin.ir.expressions.typeParametersCount import org.jetbrains.kotlin.ir.expressions.typeParametersCount
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
import org.jetbrains.kotlin.ir.types.toIrType import org.jetbrains.kotlin.ir.types.toIrType
import org.jetbrains.kotlin.ir.util.createParameterDeclarations import org.jetbrains.kotlin.ir.util.createParameterDeclarations
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature
@@ -53,10 +49,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils.getSuperClassDescriptor import org.jetbrains.kotlin.resolve.DescriptorUtils.getSuperClassDescriptor
import org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmDefaultAnnotation
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.org.objectweb.asm.Opcodes.* import org.jetbrains.org.objectweb.asm.Opcodes.*
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
@@ -68,9 +61,6 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
private val typeMapper = state.typeMapper private val typeMapper = state.typeMapper
private val DECLARATION_AND_DEFINITION_CHECKER = fun(descriptor: CallableMemberDescriptor): Boolean =
!isInterface(descriptor.containingDeclaration) || state.target !== JvmTarget.JVM_1_6 && descriptor.hasJvmDefaultAnnotation()
override fun lower(irClass: IrClass) { override fun lower(irClass: IrClass) {
val classDescriptor = irClass.descriptor val classDescriptor = irClass.descriptor
if (irClass.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) { if (irClass.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) {
@@ -122,10 +112,10 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
val bridgesToGenerate: Set<Bridge<SignatureAndDescriptor>> val bridgesToGenerate: Set<Bridge<SignatureAndDescriptor>>
if (!isSpecial) { if (!isSpecial) {
bridgesToGenerate = generateBridgesForFunctionDescriptor( bridgesToGenerate = generateBridgesForFunctionDescriptorForJvm(
descriptor, descriptor,
getSignatureMapper(typeMapper), getSignatureMapper(typeMapper),
DECLARATION_AND_DEFINITION_CHECKER state.target
) )
if (!bridgesToGenerate.isEmpty()) { if (!bridgesToGenerate.isEmpty()) {
val origin = if (descriptor.kind == DECLARATION) getSourceFromDescriptor(descriptor) else null val origin = if (descriptor.kind == DECLARATION) getSourceFromDescriptor(descriptor) else null
@@ -140,7 +130,7 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
val specials = BuiltinSpecialBridgesUtil.generateBridgesForBuiltinSpecial( val specials = BuiltinSpecialBridgesUtil.generateBridgesForBuiltinSpecial(
descriptor, descriptor,
getSignatureMapper(typeMapper), getSignatureMapper(typeMapper),
DECLARATION_AND_DEFINITION_CHECKER state.target
) )
if (!specials.isEmpty()) { if (!specials.isEmpty()) {
@@ -28,7 +28,10 @@ import org.jetbrains.kotlin.js.translate.utils.*
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.prototypeOf import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.prototypeOf
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.* import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.utils.identity import org.jetbrains.kotlin.utils.identity
@@ -241,10 +244,7 @@ class ClassModelGenerator(val context: TranslationContext) {
private fun generateOtherBridges(descriptor: ClassDescriptor, model: JsClassModel) { private fun generateOtherBridges(descriptor: ClassDescriptor, model: JsClassModel) {
for (memberDescriptor in descriptor.defaultType.memberScope.getContributedDescriptors()) { for (memberDescriptor in descriptor.defaultType.memberScope.getContributedDescriptors()) {
if (memberDescriptor is FunctionDescriptor) { if (memberDescriptor is FunctionDescriptor) {
val bridgesToGenerate = generateBridgesForFunctionDescriptor(memberDescriptor, identity()) { val bridgesToGenerate = generateBridgesForFunctionDescriptor(memberDescriptor, identity())
//There is no DefaultImpls in js backend so if method non-abstract it should be recognized as non-abstract on bridges calculation
true
}
for (bridge in bridgesToGenerate) { for (bridge in bridgesToGenerate) {
generateBridge(descriptor, model, bridge) generateBridge(descriptor, model, bridge)
@@ -304,4 +304,4 @@ class ClassModelGenerator(val context: TranslationContext) {
block.statements += defineProperty.makeStmt() block.statements += defineProperty.makeStmt()
} }
} }