Add MutableMap.remove(K, V) as built-in declaration
Use PlatformDependent annotation to guarantee it's only be available for JDK8 Also adjust type-safe bridges and mutable collection stubs generation
This commit is contained in:
@@ -19,14 +19,16 @@ package org.jetbrains.kotlin.codegen
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERRIDE
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.getSpecialSignatureInfo
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.isBuiltinWithSpecialDescriptorInJvm
|
||||
import org.jetbrains.kotlin.load.java.isFromBuiltins
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy
|
||||
import org.jetbrains.kotlin.resolve.OverrideResolver
|
||||
import org.jetbrains.kotlin.resolve.OverridingStrategy
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.overriddenTreeUniqueAsSequence
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
@@ -80,7 +82,7 @@ class CollectionStubMethodGenerator(
|
||||
// Bind fake overrides and for each fake override originated from the MutableCollection, save its signature to generate a stub
|
||||
// or save its descriptor to generate all the needed bridges
|
||||
for (method in findFakeOverridesForMethodsFromMutableCollection(child, mutableClass)) {
|
||||
if (method.modality == Modality.ABSTRACT) {
|
||||
if (method.modality == Modality.ABSTRACT || isDefaultInJdk(method)) {
|
||||
// If the fake override is abstract and it's _declared_ as abstract in the class, skip it because the method is already
|
||||
// present in the bytecode (abstract) and we don't want a duplicate signature error
|
||||
if (method.findOverriddenFromDirectSuperClass(descriptor)?.kind == DECLARATION) continue
|
||||
@@ -149,6 +151,12 @@ class CollectionStubMethodGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
private fun isDefaultInJdk(method: FunctionDescriptor) =
|
||||
method.modality != Modality.ABSTRACT &&
|
||||
method.original.overriddenTreeUniqueAsSequence(useOriginal = true).all {
|
||||
(it as FunctionDescriptor).kind == FAKE_OVERRIDE || it.isFromBuiltins()
|
||||
}
|
||||
|
||||
private data class CollectionClassPair(
|
||||
val readOnlyClass: ClassDescriptor,
|
||||
val mutableClass: ClassDescriptor
|
||||
|
||||
@@ -344,7 +344,7 @@ public class FunctionCodegen {
|
||||
KotlinTypeMapper typeMapper = parentCodegen.typeMapper;
|
||||
if (BuiltinSpecialBridgesUtil.shouldHaveTypeSafeBarrier(functionDescriptor, getSignatureMapper(typeMapper))) {
|
||||
generateTypeCheckBarrierIfNeeded(
|
||||
new InstructionAdapter(mv), functionDescriptor, signature.getReturnType(), /* delegateParameterType = */null);
|
||||
new InstructionAdapter(mv), functionDescriptor, signature.getReturnType(), /* delegateParameterTypes = */null);
|
||||
}
|
||||
|
||||
Label methodEnd;
|
||||
@@ -890,8 +890,8 @@ public class FunctionCodegen {
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
MemberCodegen.markLineNumberForDescriptor(owner.getThisDescriptor(), iv);
|
||||
|
||||
if (delegateTo.getArgumentTypes().length == 1 && isSpecialBridge) {
|
||||
generateTypeCheckBarrierIfNeeded(iv, descriptor, bridge.getReturnType(), delegateTo.getArgumentTypes()[0]);
|
||||
if (delegateTo.getArgumentTypes().length > 0 && isSpecialBridge) {
|
||||
generateTypeCheckBarrierIfNeeded(iv, descriptor, bridge.getReturnType(), delegateTo.getArgumentTypes());
|
||||
}
|
||||
|
||||
iv.load(0, OBJECT_TYPE);
|
||||
@@ -921,37 +921,42 @@ public class FunctionCodegen {
|
||||
@NotNull InstructionAdapter iv,
|
||||
@NotNull FunctionDescriptor descriptor,
|
||||
@NotNull Type returnType,
|
||||
@Nullable final Type delegateParameterType
|
||||
@Nullable Type[] delegateParameterTypes
|
||||
) {
|
||||
BuiltinMethodsWithSpecialGenericSignature.DefaultValue defaultValue =
|
||||
BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(descriptor);
|
||||
if (defaultValue == null) return;
|
||||
|
||||
assert descriptor.getValueParameters().size() == 1 : "Should be descriptor with one value parameter, but found: " + descriptor;
|
||||
Label defaultBranch = new Label();
|
||||
|
||||
boolean isCheckForAny = delegateParameterType == null || OBJECT_TYPE.equals(delegateParameterType);
|
||||
for (int i = 0; i < descriptor.getValueParameters().size(); i++) {
|
||||
boolean isCheckForAny = delegateParameterTypes == null || OBJECT_TYPE.equals(delegateParameterTypes[i]);
|
||||
|
||||
final KotlinType kotlinType = descriptor.getValueParameters().get(0).getType();
|
||||
KotlinType kotlinType = descriptor.getValueParameters().get(i).getType();
|
||||
|
||||
if (isCheckForAny && TypeUtils.isNullableType(kotlinType)) return;
|
||||
if (isCheckForAny && TypeUtils.isNullableType(kotlinType)) continue;
|
||||
|
||||
iv.load(1, OBJECT_TYPE);
|
||||
iv.load(1 + i, OBJECT_TYPE);
|
||||
|
||||
Label afterBarrier = new Label();
|
||||
|
||||
if (isCheckForAny) {
|
||||
assert !TypeUtils.isNullableType(kotlinType) : "Only bridges for not-nullable types are necessary";
|
||||
iv.ifnonnull(afterBarrier);
|
||||
}
|
||||
else {
|
||||
CodegenUtilKt.generateIsCheck(iv, kotlinType, boxType(delegateParameterType));
|
||||
iv.ifne(afterBarrier);
|
||||
if (isCheckForAny) {
|
||||
assert !TypeUtils.isNullableType(kotlinType) : "Only bridges for not-nullable types are necessary";
|
||||
iv.ifnull(defaultBranch);
|
||||
}
|
||||
else {
|
||||
CodegenUtilKt.generateIsCheck(iv, kotlinType, boxType(delegateParameterTypes[i]));
|
||||
iv.ifeq(defaultBranch);
|
||||
}
|
||||
}
|
||||
|
||||
Label afterDefaultBranch = new Label();
|
||||
|
||||
iv.goTo(afterDefaultBranch);
|
||||
|
||||
iv.visitLabel(defaultBranch);
|
||||
StackValue.constant(defaultValue.getValue(), returnType).put(returnType, iv);
|
||||
iv.areturn(returnType);
|
||||
|
||||
iv.visitLabel(afterBarrier);
|
||||
iv.visitLabel(afterDefaultBranch);
|
||||
}
|
||||
|
||||
public void genSamDelegate(@NotNull FunctionDescriptor functionDescriptor, FunctionDescriptor overriddenDescriptor, StackValue field) {
|
||||
|
||||
Reference in New Issue
Block a user