Do not generate DefaultImpl method for MutableMap.remove(K;V)Z
#KT-13069 Fixed
This commit is contained in:
@@ -41,7 +41,6 @@ import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
@@ -1326,7 +1325,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getNonPrivateTraitMethods(descriptor).entrySet()) {
|
||||
FunctionDescriptor interfaceFun = entry.getKey();
|
||||
//skip java 8 default methods
|
||||
if (!(interfaceFun instanceof JavaCallableMemberDescriptor)) {
|
||||
if (!CodegenUtilKt.isDefinitelyNotDefaultImplsMethod(interfaceFun)) {
|
||||
generateDelegationToDefaultImpl(interfaceFun, entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.DelegationToDefaultImpls
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.serialization.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import java.util.*
|
||||
@@ -77,8 +78,8 @@ class InterfaceImplBodyCodegen(
|
||||
|
||||
val implementation = findImplementationFromInterface(memberDescriptor) ?: continue
|
||||
|
||||
// If implementation is located in a Java interface, it will be inherited via normal Java rules
|
||||
if (implementation is JavaMethodDescriptor) continue
|
||||
// If implementation is a default interface method (JVM 8 only)
|
||||
if (implementation.isDefinitelyNotDefaultImplsMethod()) continue
|
||||
|
||||
// We create a copy of the function with kind = DECLARATION so that FunctionCodegen will generate its body
|
||||
val copy = memberDescriptor.copy(memberDescriptor.containingDeclaration, Modality.OPEN, memberDescriptor.visibility,
|
||||
|
||||
@@ -23,16 +23,19 @@ import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
|
||||
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.serialization.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
@@ -182,4 +185,7 @@ fun sortTopLevelClassesAndPrepareContextForSealedClasses(
|
||||
}
|
||||
sortedDescriptors.mapTo(result) { descriptorToPsi[it]!! }
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
fun CallableMemberDescriptor.isDefinitelyNotDefaultImplsMethod() =
|
||||
this is JavaCallableMemberDescriptor || this.annotations.hasAnnotation(PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME)
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// JVM_TARGET: 1.8
|
||||
// FULL_JDK
|
||||
|
||||
// There should be no DefaultImpls method for MutableMap.remove(K;V)
|
||||
interface A<K, V> : MutableMap<K, V>
|
||||
|
||||
class B : A<String, String>, java.util.AbstractMap<String, String>() {
|
||||
override val entries: MutableSet<MutableMap.MutableEntry<String, String>>
|
||||
get() = java.util.HashSet()
|
||||
}
|
||||
|
||||
interface C<K, V> : MutableMap<K, V> {
|
||||
override fun remove(key: K, value: V) = true
|
||||
}
|
||||
|
||||
class D : A<String, String>, java.util.AbstractMap<String, String>() {
|
||||
override val entries: MutableSet<MutableMap.MutableEntry<String, String>>
|
||||
get() = java.util.HashSet()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val x1 = B().remove("1", "2")
|
||||
if (x1) return "fail 1"
|
||||
|
||||
val x2 = D().remove("3", "4")
|
||||
if (x1) return "fail 2"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+6
@@ -187,6 +187,12 @@ public class BlackBoxWithJava8CodegenTestGenerated extends AbstractBlackBoxCodeg
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/java8/box/mapRemove"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("noDefaultImpls.kt")
|
||||
public void testNoDefaultImpls() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/mapRemove/noDefaultImpls.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("readOnlyMap.kt")
|
||||
public void testReadOnlyMap() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/mapRemove/readOnlyMap.kt");
|
||||
|
||||
Reference in New Issue
Block a user