Do not generate DefaultImpl method for MutableMap.remove(K;V)Z

#KT-13069 Fixed
This commit is contained in:
Denis Zharkov
2016-07-11 19:26:42 +03:00
parent 2d42ba23b3
commit 3845ea863c
5 changed files with 46 additions and 5 deletions
@@ -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"
}
@@ -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");