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.incremental.components.NoLookupLocation;
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
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.load.kotlin.header.KotlinClassHeader;
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
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()) {
|
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getNonPrivateTraitMethods(descriptor).entrySet()) {
|
||||||
FunctionDescriptor interfaceFun = entry.getKey();
|
FunctionDescriptor interfaceFun = entry.getKey();
|
||||||
//skip java 8 default methods
|
//skip java 8 default methods
|
||||||
if (!(interfaceFun instanceof JavaCallableMemberDescriptor)) {
|
if (!CodegenUtilKt.isDefinitelyNotDefaultImplsMethod(interfaceFun)) {
|
||||||
generateDelegationToDefaultImpl(interfaceFun, entry.getValue());
|
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.diagnostics.JvmDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
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.MethodVisitor
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -77,8 +78,8 @@ class InterfaceImplBodyCodegen(
|
|||||||
|
|
||||||
val implementation = findImplementationFromInterface(memberDescriptor) ?: continue
|
val implementation = findImplementationFromInterface(memberDescriptor) ?: continue
|
||||||
|
|
||||||
// If implementation is located in a Java interface, it will be inherited via normal Java rules
|
// If implementation is a default interface method (JVM 8 only)
|
||||||
if (implementation is JavaMethodDescriptor) continue
|
if (implementation.isDefinitelyNotDefaultImplsMethod()) continue
|
||||||
|
|
||||||
// We create a copy of the function with kind = DECLARATION so that FunctionCodegen will generate its body
|
// 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,
|
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.signature.JvmSignatureWriter
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
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.descriptors.CallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo
|
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
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.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtProperty
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
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.ErrorUtils
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
@@ -182,4 +185,7 @@ fun sortTopLevelClassesAndPrepareContextForSealedClasses(
|
|||||||
}
|
}
|
||||||
sortedDescriptors.mapTo(result) { descriptorToPsi[it]!! }
|
sortedDescriptors.mapTo(result) { descriptorToPsi[it]!! }
|
||||||
return result
|
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);
|
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")
|
@TestMetadata("readOnlyMap.kt")
|
||||||
public void testReadOnlyMap() throws Exception {
|
public void testReadOnlyMap() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/mapRemove/readOnlyMap.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/mapRemove/readOnlyMap.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user