Change resolution priority level for SAM adapters
After this change SAM adapters are being resolved in the same group as members, thus their overload resolution happens simultaneously. But in the case of overload resolution ambiguity try to filter out all synthetic members and run the process again. See the issue and new test for clarification #KT-11128 In Progress
This commit is contained in:
+2
@@ -34,6 +34,8 @@ object ProtectedSyntheticExtensionCallChecker : CallChecker {
|
||||
|
||||
val sourceFunction = when (descriptor) {
|
||||
is SyntheticJavaPropertyDescriptor -> descriptor.getMethod
|
||||
// TODO: this branch becomes unnecessary, because common checks are applied to SAM adapters being resolved as common members
|
||||
// But this part may be still useful when we enable backward compatibility mode and SAM adapters become extensions again
|
||||
is SamAdapterExtensionFunctionDescriptor -> descriptor.baseDescriptorForSynthetic
|
||||
else -> return
|
||||
}
|
||||
|
||||
+2
-2
@@ -291,7 +291,7 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
|
||||
companion object {
|
||||
fun create(ownerClass: ClassDescriptor, getMethod: FunctionDescriptor, setMethod: FunctionDescriptor?, name: Name, type: KotlinType): MyPropertyDescriptor {
|
||||
val visibility = syntheticExtensionVisibility(getMethod)
|
||||
val visibility = syntheticVisibility(getMethod, isUsedForExtension = true)
|
||||
val descriptor = MyPropertyDescriptor(DescriptorUtils.getContainingModule(ownerClass),
|
||||
null,
|
||||
Annotations.EMPTY,
|
||||
@@ -328,7 +328,7 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
PropertySetterDescriptorImpl(descriptor,
|
||||
setMethod.annotations,
|
||||
Modality.FINAL,
|
||||
syntheticExtensionVisibility(setMethod),
|
||||
syntheticVisibility(setMethod, isUsedForExtension = true),
|
||||
false,
|
||||
setMethod.isExternal,
|
||||
false,
|
||||
|
||||
+16
-18
@@ -25,8 +25,7 @@ import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.wrapWithCapturingSubstitution
|
||||
import org.jetbrains.kotlin.resolve.isHiddenInResolution
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScope
|
||||
@@ -59,8 +58,10 @@ class SamAdapterFunctionsScope(
|
||||
override fun getSyntheticExtensionFunctions(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||
var result: SmartList<FunctionDescriptor>? = null
|
||||
for (type in receiverTypes) {
|
||||
val substitutorForType by lazy { buildMemberScopeSubstitutorForType(type) }
|
||||
|
||||
for (function in type.memberScope.getContributedFunctions(name, location)) {
|
||||
val extension = extensionForFunction(function.original)
|
||||
val extension = extensionForFunction(function.original)?.substitute(substitutorForType)
|
||||
if (extension != null) {
|
||||
if (result == null) {
|
||||
result = SmartList()
|
||||
@@ -76,11 +77,16 @@ class SamAdapterFunctionsScope(
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildMemberScopeSubstitutorForType(type: KotlinType) =
|
||||
TypeConstructorSubstitution.create(type).wrapWithCapturingSubstitution(needApproximation = true).buildSubstitutor()
|
||||
|
||||
override fun getSyntheticExtensionFunctions(receiverTypes: Collection<KotlinType>): Collection<FunctionDescriptor> {
|
||||
return receiverTypes.flatMapTo(LinkedHashSet<FunctionDescriptor>()) { type ->
|
||||
type.memberScope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS)
|
||||
.filterIsInstance<FunctionDescriptor>()
|
||||
.mapNotNull { extensionForFunction(it.original) }
|
||||
.mapNotNull {
|
||||
extensionForFunction(it.original)?.substitute(buildMemberScopeSubstitutorForType(type))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,11 +106,13 @@ class SamAdapterFunctionsScope(
|
||||
override var baseDescriptorForSynthetic: FunctionDescriptor by Delegates.notNull()
|
||||
private set
|
||||
|
||||
private lateinit var fromSourceFunctionTypeParameters: Map<TypeParameterDescriptor, TypeParameterDescriptor>
|
||||
private val fromSourceFunctionTypeParameters: Map<TypeParameterDescriptor, TypeParameterDescriptor> by lazy {
|
||||
baseDescriptorForSynthetic.typeParameters.zip(typeParameters).toMap()
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun create(sourceFunction: FunctionDescriptor): MyFunctionDescriptor {
|
||||
val descriptor = MyFunctionDescriptor(DescriptorUtils.getContainingModule(sourceFunction),
|
||||
val descriptor = MyFunctionDescriptor(sourceFunction.containingDeclaration,
|
||||
null,
|
||||
sourceFunction.annotations,
|
||||
sourceFunction.name,
|
||||
@@ -114,26 +122,16 @@ class SamAdapterFunctionsScope(
|
||||
|
||||
val sourceTypeParams = (sourceFunction.typeParameters).toMutableList()
|
||||
val ownerClass = sourceFunction.containingDeclaration as ClassDescriptor
|
||||
//TODO: should we go up parents for getters/setters too?
|
||||
//TODO: non-inner classes
|
||||
for (parent in ownerClass.parentsWithSelf) {
|
||||
if (parent !is ClassDescriptor) break
|
||||
sourceTypeParams += parent.declaredTypeParameters
|
||||
}
|
||||
//TODO: duplicated parameter names
|
||||
|
||||
val typeParameters = ArrayList<TypeParameterDescriptor>(sourceTypeParams.size)
|
||||
val typeSubstitutor = DescriptorSubstitutor.substituteTypeParameters(sourceTypeParams, TypeSubstitution.EMPTY, descriptor, typeParameters)
|
||||
|
||||
descriptor.fromSourceFunctionTypeParameters = sourceTypeParams.zip(typeParameters).toMap()
|
||||
|
||||
val returnType = typeSubstitutor.safeSubstitute(sourceFunction.returnType!!, Variance.INVARIANT)
|
||||
val receiverType = typeSubstitutor.safeSubstitute(ownerClass.defaultType, Variance.INVARIANT)
|
||||
val valueParameters = SingleAbstractMethodUtils.createValueParametersForSamAdapter(sourceFunction, descriptor, typeSubstitutor)
|
||||
|
||||
val visibility = syntheticExtensionVisibility(sourceFunction)
|
||||
val visibility = syntheticVisibility(sourceFunction, isUsedForExtension = false)
|
||||
|
||||
descriptor.initialize(receiverType, null, typeParameters, valueParameters, returnType,
|
||||
descriptor.initialize(null, ownerClass.thisAsReceiverParameter, typeParameters, valueParameters, returnType,
|
||||
Modality.FINAL, visibility)
|
||||
|
||||
descriptor.isOperator = sourceFunction.isOperator
|
||||
|
||||
+8
-4
@@ -30,14 +30,18 @@ fun FunctionDescriptor.hasJavaOriginInHierarchy(): Boolean {
|
||||
|
||||
fun Visibility.isVisibleOutside() = this != Visibilities.PRIVATE && this != Visibilities.PRIVATE_TO_THIS && this != Visibilities.INVISIBLE_FAKE
|
||||
|
||||
fun syntheticExtensionVisibility(originalDescriptor: DeclarationDescriptorWithVisibility): Visibility {
|
||||
fun syntheticVisibility(originalDescriptor: DeclarationDescriptorWithVisibility, isUsedForExtension: Boolean): Visibility {
|
||||
val originalVisibility = originalDescriptor.visibility
|
||||
return when (originalVisibility) {
|
||||
Visibilities.PUBLIC -> Visibilities.PUBLIC
|
||||
|
||||
else -> object : Visibility(originalVisibility.name, originalVisibility.isPublicAPI) {
|
||||
override fun isVisible(receiver: ReceiverValue?, what: DeclarationDescriptorWithVisibility, from: DeclarationDescriptor)
|
||||
= originalVisibility.isVisible(Visibilities.ALWAYS_SUITABLE_RECEIVER, originalDescriptor, from)
|
||||
override fun isVisible(
|
||||
receiver: ReceiverValue?,
|
||||
what: DeclarationDescriptorWithVisibility,
|
||||
from: DeclarationDescriptor
|
||||
) = originalVisibility.isVisible(
|
||||
if (isUsedForExtension) Visibilities.ALWAYS_SUITABLE_RECEIVER else receiver, originalDescriptor, from)
|
||||
|
||||
override fun mustCheckInImports()
|
||||
= throw UnsupportedOperationException("Should never be called for this visibility")
|
||||
@@ -50,4 +54,4 @@ fun syntheticExtensionVisibility(originalDescriptor: DeclarationDescriptorWithVi
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user