Refine method's contract and rename it

Basically what's it checked before is that
receiver is a valid override of raw version of builtinWithErasedParameters

While we need to check that method has the same JVM descriptor as builtinWithErasedParameters,
but it's not a valid override of latter

It's important for 'getOrDefault(Object k, V value)' ('getOrDefault(K k, V value)' in Kotlin):
'getOrDefault(Object k, V value)' is not override of 'getOrDefault(Object k, Object value)',
that leads to incorrect loading of former method (like it's not an override of declaration in Map)
This commit is contained in:
Denis Zharkov
2016-07-25 16:15:50 +03:00
parent 15b94bb8df
commit 169acf2f31
2 changed files with 15 additions and 26 deletions
@@ -39,17 +39,16 @@ import org.jetbrains.kotlin.load.java.descriptors.copyValueParameters
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.lazy.child
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
import org.jetbrains.kotlin.load.java.lazy.types.RawSubstitution
import org.jetbrains.kotlin.load.java.lazy.types.toAttributes
import org.jetbrains.kotlin.load.java.structure.JavaArrayType
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.JavaConstructor
import org.jetbrains.kotlin.load.java.structure.JavaMethod
import org.jetbrains.kotlin.load.java.typeEnhancement.enhanceSignatures
import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
@@ -132,7 +131,7 @@ class LazyJavaClassMemberScope(
return candidatesToOverride.any {
candidate ->
doesOverrideBuiltinFunctionWithErasedValueParameters(candidate)
hasSameJvmDescriptorButDoesNotOverride(candidate)
}
}
@@ -355,7 +354,7 @@ class LazyJavaClassMemberScope(
functions: (Name) -> Collection<SimpleFunctionDescriptor>
): SimpleFunctionDescriptor? {
return functions(overridden.name).firstOrNull {
it.doesOverrideBuiltinFunctionWithErasedValueParameters(overridden)
it.hasSameJvmDescriptorButDoesNotOverride(overridden)
}?.let {
override ->
override.newCopyBuilder().apply {
@@ -496,24 +495,12 @@ class LazyJavaClassMemberScope(
)
}
private fun SimpleFunctionDescriptor.doesOverrideBuiltinFunctionWithErasedValueParameters(
private fun SimpleFunctionDescriptor.hasSameJvmDescriptorButDoesNotOverride(
builtinWithErasedParameters: FunctionDescriptor
): Boolean {
if (this.valueParameters.size != builtinWithErasedParameters.valueParameters.size) return false
if (!this.typeParameters.isEmpty() || !builtinWithErasedParameters.typeParameters.isEmpty()) return false
if (this.extensionReceiverParameter != null || builtinWithErasedParameters.extensionReceiverParameter != null) return false
return this.valueParameters.indices.all {
index ->
val currentType = valueParameters[index].type
val overriddenCandidate = RawSubstitution.eraseType(
builtinWithErasedParameters.original.valueParameters[index].type)
KotlinTypeChecker.DEFAULT.equalTypes(currentType, overriddenCandidate)
} && returnType.isSubtypeOf(builtinWithErasedParameters.returnType)
}
private fun KotlinType?.isSubtypeOf(other: KotlinType?): Boolean {
return KotlinTypeChecker.DEFAULT.isSubtypeOf(this ?: return false, other ?: return false)
return computeJvmDescriptor(withReturnType = false) ==
builtinWithErasedParameters.original.computeJvmDescriptor(withReturnType = false)
&& !doesOverride(builtinWithErasedParameters)
}
private fun resolveConstructor(constructor: JavaConstructor): JavaConstructorDescriptor {
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.kotlin.types.KotlinType
fun FunctionDescriptor.computeJvmDescriptor()
fun FunctionDescriptor.computeJvmDescriptor(withReturnType: Boolean = true)
= StringBuilder().apply {
append(if (this@computeJvmDescriptor is ConstructorDescriptor) "<init>" else name.asString())
append("(")
@@ -40,11 +40,13 @@ fun FunctionDescriptor.computeJvmDescriptor()
append(")")
if (hasVoidReturnType(this@computeJvmDescriptor)) {
append("V")
}
else {
appendErasedType(returnType!!)
if (withReturnType) {
if (hasVoidReturnType(this@computeJvmDescriptor)) {
append("V")
}
else {
appendErasedType(returnType!!)
}
}
}.toString()