Support overload ambiguity resolution for callable references by expected type.

Resolve callable references taking into account expected callable types.

This affects call resolution procedure (resolve 'foo' in for 'foo(::bar)') similar to the approach used for function literals:

* During "shape arguments" phase of call resolution, callable references are resolved in independent context without expected type. If the callable reference is ambiguous, its shape type is a function placeholder type without parameter types and return type information. Otherwise, it is a reflection type for the resolved function or property. Upper-level call is resolved without taking into account ambiguous callable references.

* During "complete call" phase of call resolution, resolve callable reference arguments to actual descriptors (if possible), and update constraint system for the given call accordingly.

 #KT-6982 Fixed
 #KT-5780 Fixed
This commit is contained in:
Dmitry Petrov
2015-07-14 17:53:12 +03:00
parent b3a2ee2148
commit 6437a4bdc6
51 changed files with 1057 additions and 247 deletions
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
import java.util.ArrayList
val KOTLIN_REFLECT_FQ_NAME = FqName("kotlin.reflect")
@@ -112,5 +113,33 @@ public class ReflectionTypes(private val module: ModuleDescriptor) {
val containingPackage = DescriptorUtils.getParentOfType(descriptor, javaClass<PackageFragmentDescriptor>())
return containingPackage != null && containingPackage.fqName == KOTLIN_REFLECT_FQ_NAME
}
private val PROPERTY_CLASS_NAMES = hashSetOf(
"KProperty", "KMutableProperty",
"KProperty0", "KMutableProperty0",
"KProperty1", "KMutableProperty1",
"KProperty2", "KMutableProperty2"
)
public fun isCallableType(type: JetType): Boolean =
KotlinBuiltIns.isFunctionOrExtensionFunctionType(type) ||
isPropertyType(type)
public fun isPropertyType(type: JetType): Boolean =
isExactPropertyType(type) ||
type.getConstructor().getSupertypes().any { isPropertyType(it) }
public fun isExactPropertyType(type: JetType): Boolean {
val descriptor = type.getConstructor().getDeclarationDescriptor()
if (descriptor is ClassDescriptor) {
val fqName = DescriptorUtils.getFqName(descriptor)
val parentName = fqName.parent().asString()
if (parentName != KOTLIN_REFLECT_FQ_NAME.asString())
return false
val shortName = fqName.shortName().asString()
return PROPERTY_CLASS_NAMES.contains(shortName)
}
return false
}
}
}