diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/CollectionStubMethodGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/CollectionStubMethodGenerator.kt index e8784d78602..ad36175f77c 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/CollectionStubMethodGenerator.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/CollectionStubMethodGenerator.kt @@ -20,7 +20,9 @@ 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.annotations.Annotations -import org.jetbrains.kotlin.codegen.MutableClassDescriptor +import org.jetbrains.kotlin.load.java.SpecialSignatureInfo +import org.jetbrains.kotlin.load.java.getSpecialSignatureInfo +import org.jetbrains.kotlin.load.java.isBuiltinWithSpecialDescriptorInJvm import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.OverrideResolver import org.jetbrains.kotlin.resolve.OverridingUtil @@ -29,9 +31,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.JetTypeChecker -import org.jetbrains.org.objectweb.asm.Opcodes.ACC_ABSTRACT -import org.jetbrains.org.objectweb.asm.Opcodes.ACC_PUBLIC -import org.jetbrains.org.objectweb.asm.Opcodes.ACC_SYNTHETIC +import org.jetbrains.org.objectweb.asm.Opcodes.* import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import java.util.ArrayList import java.util.HashSet @@ -97,8 +97,40 @@ class CollectionStubMethodGenerator( // errors when compiling Java against such classes because one of them doesn't seem to override the generic method // declared in the Java Collection interface (can't override generic with erased). So we maintain an additional set of // methods which need to be generated with the ACC_SYNTHETIC flag - val originalSignature = method.findOverriddenFromDirectSuperClass(mutableClass)!!.getOriginal().signature() - if (originalSignature.getAsmMethod() != signature.getAsmMethod()) { + val overriddenMethod = method.findOverriddenFromDirectSuperClass(mutableClass)!! + val originalSignature = overriddenMethod.original.signature() + var specialSignature: JvmMethodSignature? = null + + if (overriddenMethod.isBuiltinWithSpecialDescriptorInJvm()) { + // Stubs for remove(Ljava/lang/Object;)Z and remove(I) should not be synthetic + // Otherwise Javac will not see it + val overriddenMethodSignature = overriddenMethod.signature() + val genericSignatureInfo = overriddenMethod.getSpecialSignatureInfo() + + val specialGenericSignature = + if (genericSignatureInfo != null) + genericSignatureInfo.signature + else + overriddenMethodSignature.genericsSignature + + val (asmMethod, valueParameters) = + // if remove(E) in Kotlin -> remove(Object) in Java + // so choose original signature + if (genericSignatureInfo == SpecialSignatureInfo.GENERIC_PARAMETER) + Pair(originalSignature.asmMethod, originalSignature.valueParameters) + else + Pair(overriddenMethodSignature.asmMethod, overriddenMethodSignature.valueParameters) + + specialSignature = JvmMethodSignature( + asmMethod, + specialGenericSignature, + valueParameters + ) + + methodStubsToGenerate.add(specialSignature) + } + + if (originalSignature.asmMethod != signature.asmMethod && originalSignature.asmMethod != specialSignature?.asmMethod) { syntheticStubsToGenerate.add(originalSignature) } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/builtinsPropertiesUtil.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/builtinsPropertiesUtil.kt index b734f452da2..e88e85b7c77 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/builtinsPropertiesUtil.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/builtinsPropertiesUtil.kt @@ -138,7 +138,7 @@ private val CallableMemberDescriptor.isFromJava: Boolean private val CallableMemberDescriptor.propertyIfAccessor: CallableMemberDescriptor get() = if (this is PropertyAccessorDescriptor) correspondingProperty else this -val CallableMemberDescriptor.hasErasedValueParametersInJava: Boolean +private val CallableMemberDescriptor.hasErasedValueParametersInJava: Boolean get() = fqNameOrNull() in BUILTIN_METHODS_ERASED_VALUE_PARAMETERS_FQ_NAMES val Name.sameAsRenamedInJvmBuiltin: Boolean @@ -189,3 +189,8 @@ fun CallableMemberDescriptor.getSpecialSignatureInfo(): SpecialSignatureInfo? { else -> error("Unexpected kind of special builtin: $builtinFqName") } } + +fun CallableMemberDescriptor.isBuiltinWithSpecialDescriptorInJvm(): Boolean { + if (!isFromBuiltins()) return false + return getSpecialSignatureInfo() == SpecialSignatureInfo.GENERIC_PARAMETER || overridesBuiltinSpecialDeclaration() +}