Add temporary hack for wildcards in Collections

By default we would render 'MutableCollection<String>.addAll(Collection<String>)' as
'(LCollection<String>;)' (without wildcard) because String is final and
effectively it's the same as '(LCollection<? extends String>;)'.

But that's wrong signature in a sense that java.util.Collection has different
signature: '(LCollection<? extends E>)'.

Actually the problem is much wider than collections,
it concerns any Java code that uses Kotlin classes with covariant
parameters without '? extends E' wildcards.

Temporary solution is just to hardcode/enumerate builtin methods
with special signature.
This commit is contained in:
Denis Zharkov
2015-11-24 13:42:46 +03:00
parent 0255be7deb
commit 20cbceb56d
9 changed files with 124 additions and 39 deletions
@@ -27,13 +27,8 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.descriptorUtil.*
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure
import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.addToStdlib.check
object BuiltinSpecialProperties {
private val PROPERTY_FQ_NAME_TO_JVM_GETTER_NAME_MAP = mapOf(
@@ -280,33 +275,6 @@ private fun CallableMemberDescriptor.isFromBuiltins(): Boolean {
this.module == this.builtIns.builtInsModule
}
private val CallableMemberDescriptor.propertyIfAccessor: CallableMemberDescriptor
get() = if (this is PropertyAccessorDescriptor) correspondingProperty else this
private fun CallableDescriptor.fqNameOrNull(): FqName? = fqNameUnsafe.check { it.isSafe }?.toSafe()
public fun CallableMemberDescriptor.firstOverridden(
predicate: (CallableMemberDescriptor) -> Boolean
): CallableMemberDescriptor? {
var result: CallableMemberDescriptor? = null
return DFS.dfs(listOf(this),
object : DFS.Neighbors<CallableMemberDescriptor> {
override fun getNeighbors(current: CallableMemberDescriptor?): Iterable<CallableMemberDescriptor> {
return current?.overriddenDescriptors ?: emptyList()
}
},
object : DFS.AbstractNodeHandler<CallableMemberDescriptor, CallableMemberDescriptor?>() {
override fun beforeChildren(current: CallableMemberDescriptor) = result == null
override fun afterChildren(current: CallableMemberDescriptor) {
if (result == null && predicate(current)) {
result = current
}
}
override fun result(): CallableMemberDescriptor? = result
}
)
}
public fun CallableMemberDescriptor.isFromJavaOrBuiltins() = isFromJava || isFromBuiltins()
private fun Map<FqName, Name>.getInversedShortNamesMap(): Map<Name, List<Name>> =