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:
@@ -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()
|
||||||
|
|
||||||
|
|||||||
+4
-14
@@ -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()) {
|
||||||
|
|||||||
+6
-6
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user