From 417ff281ee44b2dab4217742192477c8fdeb505f Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Fri, 4 Dec 2015 16:46:48 +0300 Subject: [PATCH] Split getOverriddenBuiltinWithJvmDescriptor into two extensions --- .../kotlin/codegen/FunctionCodegen.java | 4 ++-- .../kotlin/codegen/builtinSpecialBridges.kt | 8 ++++---- .../kotlin/codegen/state/JetTypeMapper.java | 4 ++-- .../kotlin/load/java/specialBuiltinMembers.kt | 18 +++++++++++++++++- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 32f99816f25..9b80e90ecc0 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -555,7 +555,7 @@ public class FunctionCodegen { // If the function doesn't have a physical declaration among super-functions, it's a SAM adapter or alike and doesn't need bridges if (CallResolverUtilKt.isOrOverridesSynthesized(descriptor)) return; - boolean isSpecial = SpecialBuiltinMembers.getOverriddenBuiltinWithDifferentJvmDescriptor(descriptor) != null; + boolean isSpecial = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor) != null; Set> bridgesToGenerate; if (!isSpecial) { @@ -589,7 +589,7 @@ public class FunctionCodegen { } if (!descriptor.getKind().isReal() && isAbstractMethod(descriptor, OwnerKind.IMPLEMENTATION)) { - CallableDescriptor overridden = SpecialBuiltinMembers.getOverriddenBuiltinWithDifferentJvmDescriptor(descriptor); + CallableDescriptor overridden = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor); assert overridden != null; Method method = typeMapper.mapSignature(descriptor).getAsmMethod(); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/builtinSpecialBridges.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/builtinSpecialBridges.kt index 97fd96a6ad5..887591c0985 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/builtinSpecialBridges.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/builtinSpecialBridges.kt @@ -25,7 +25,7 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.getSpecialSignatureInfo import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor -import org.jetbrains.kotlin.load.java.getOverriddenBuiltinWithDifferentJvmDescriptor +import org.jetbrains.kotlin.load.java.getOverriddenBuiltinReflectingJvmDescriptor import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtPsiUtil import org.jetbrains.kotlin.resolve.BindingContext @@ -51,7 +51,7 @@ object BuiltinSpecialBridgesUtil { val functionHandle = DescriptorBasedFunctionHandle(function) val fake = !functionHandle.isDeclaration - val overriddenBuiltin = function.getOverriddenBuiltinWithDifferentJvmDescriptor()!! + val overriddenBuiltin = function.getOverriddenBuiltinReflectingJvmDescriptor()!! val reachableDeclarations = findAllReachableDeclarations(function) @@ -99,7 +99,7 @@ object BuiltinSpecialBridgesUtil { ): Boolean { if (BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(this) == null) return false - val builtin = getOverriddenBuiltinWithDifferentJvmDescriptor()!! + val builtin = getOverriddenBuiltinReflectingJvmDescriptor()!! return signatureByDescriptor(this) == signatureByDescriptor(builtin) } } @@ -134,7 +134,7 @@ private fun needGenerateSpecialBridge( || originalOverridden.containingDeclaration is JavaClassDescriptor || DescriptorUtils.isInterface(originalOverridden.containingDeclaration)) return@firstOverridden false - val overriddenSpecial = originalOverridden.getOverriddenBuiltinWithDifferentJvmDescriptor()?.original ?: return@firstOverridden false + val overriddenSpecial = originalOverridden.getOverriddenBuiltinReflectingJvmDescriptor()?.original ?: return@firstOverridden false signatureByDescriptor(originalOverridden) != signatureByDescriptor(overriddenSpecial) } != null) return false diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java index 2ed5616d206..587df793e5c 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java @@ -788,7 +788,7 @@ public class JetTypeMapper { } FunctionDescriptor overriddenSpecialBuiltinFunction = - SpecialBuiltinMembers.getOverriddenBuiltinWithDifferentJvmDescriptor(functionDescriptor.getOriginal()); + SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(functionDescriptor.getOriginal()); FunctionDescriptor functionToCall = overriddenSpecialBuiltinFunction != null && !superCall ? overriddenSpecialBuiltinFunction.getOriginal() : functionDescriptor.getOriginal(); @@ -967,7 +967,7 @@ public class JetTypeMapper { public JvmMethodSignature mapSignature(@NotNull FunctionDescriptor f, @NotNull OwnerKind kind) { if (f.getInitialSignatureDescriptor() != null && f != f.getInitialSignatureDescriptor()) { // Overrides of special builtin in Kotlin classes always have special signature - if (SpecialBuiltinMembers.getOverriddenBuiltinWithDifferentJvmDescriptor(f) == null || + if (SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(f) == null || f.getContainingDeclaration().getOriginal() instanceof JavaClassDescriptor) { return mapSignature(f.getInitialSignatureDescriptor(), kind); } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/specialBuiltinMembers.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/specialBuiltinMembers.kt index 5a2720ab621..3700c1abd48 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/specialBuiltinMembers.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/specialBuiltinMembers.kt @@ -206,7 +206,23 @@ fun T.getOverriddenBuiltinWithDifferentJvmName(): fun CallableMemberDescriptor.doesOverrideBuiltinWithDifferentJvmName(): Boolean = getOverriddenBuiltinWithDifferentJvmName() != null @Suppress("UNCHECKED_CAST") -fun T.getOverriddenBuiltinWithDifferentJvmDescriptor(): T? { +fun T.getOverriddenSpecialBuiltin(): T? { + getOverriddenBuiltinWithDifferentJvmName()?.let { return it } + + if (!name.sameAsBuiltinMethodWithErasedValueParameters) return null + + return firstOverridden { + it.isFromBuiltins() && it.getSpecialSignatureInfo() != null + } as T? +} + +// The subtle difference between getOverriddenBuiltinReflectingJvmDescriptor and getOverriddenSpecialBuiltin +// is that first one return descriptor reflecting JVM signature (JVM descriptor) +// E.g. it returns `contains(e: E): Boolean` instead of `contains(e: String): Boolean` for implementation of Collection.contains +// Implementation differs by getting 'original' for collection methods with erased value parameters +// Also it ignores Collection.containsAll overrides because they have the same JVM descriptor +@Suppress("UNCHECKED_CAST") +fun T.getOverriddenBuiltinReflectingJvmDescriptor(): T? { getOverriddenBuiltinWithDifferentJvmName()?.let { return it } if (!name.sameAsBuiltinMethodWithErasedValueParameters) return null