Function and property descriptors imported from object should keep track of the original imported descriptor,
otherwise they break an assumption that 'getOriginal()' chain would eventually converge on some callable descriptor.
This commit is contained in:
@@ -257,12 +257,15 @@ class QualifiedExpressionResolver {
|
|||||||
descriptors.addAll(staticClassScope.getContributedVariables(lastName, location))
|
descriptors.addAll(staticClassScope.getContributedVariables(lastName, location))
|
||||||
|
|
||||||
if (packageOrClassDescriptor.kind == ClassKind.OBJECT) {
|
if (packageOrClassDescriptor.kind == ClassKind.OBJECT) {
|
||||||
descriptors.addAll(packageOrClassDescriptor.unsubstitutedMemberScope.getContributedFunctions(lastName, location).map {
|
descriptors.addAll(
|
||||||
FunctionImportedFromObject(it)
|
packageOrClassDescriptor.unsubstitutedMemberScope.getContributedFunctions(lastName, location)
|
||||||
})
|
.map { it.asImportedFromObject() }
|
||||||
val properties = packageOrClassDescriptor.unsubstitutedMemberScope.getContributedVariables(lastName, location)
|
)
|
||||||
.filterIsInstance<PropertyDescriptor>().map { PropertyImportedFromObject(it) }
|
descriptors.addAll(
|
||||||
descriptors.addAll(properties)
|
packageOrClassDescriptor.unsubstitutedMemberScope.getContributedVariables(lastName, location)
|
||||||
|
.filterIsInstance<PropertyDescriptor>()
|
||||||
|
.map { it.asImportedFromObject() }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,55 +19,61 @@ package org.jetbrains.kotlin.resolve
|
|||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||||
|
|
||||||
|
fun FunctionDescriptor.asImportedFromObject(original: FunctionImportedFromObject? = null) =
|
||||||
|
FunctionImportedFromObject(this, original)
|
||||||
|
|
||||||
|
fun PropertyDescriptor.asImportedFromObject(original: PropertyImportedFromObject? = null) =
|
||||||
|
PropertyImportedFromObject(this, original)
|
||||||
|
|
||||||
abstract class ImportedFromObjectCallableDescriptor<out TCallable : CallableMemberDescriptor>(
|
abstract class ImportedFromObjectCallableDescriptor<out TCallable : CallableMemberDescriptor>(
|
||||||
val callableFromObject: TCallable
|
val callableFromObject: TCallable,
|
||||||
|
originalOrNull: TCallable?
|
||||||
) : CallableDescriptor {
|
) : CallableDescriptor {
|
||||||
|
|
||||||
val containingObject = callableFromObject.containingDeclaration as ClassDescriptor
|
val containingObject = callableFromObject.containingDeclaration as ClassDescriptor
|
||||||
|
|
||||||
|
protected val _original = originalOrNull ?: this
|
||||||
}
|
}
|
||||||
|
|
||||||
// members imported from object should be wrapped to not require dispatch receiver
|
// members imported from object should be wrapped to not require dispatch receiver
|
||||||
class FunctionImportedFromObject(functionFromObject: FunctionDescriptor) :
|
class FunctionImportedFromObject(
|
||||||
FunctionDescriptor by functionFromObject,
|
functionFromObject: FunctionDescriptor,
|
||||||
ImportedFromObjectCallableDescriptor<FunctionDescriptor>(functionFromObject) {
|
originalOrNull: FunctionDescriptor? = null
|
||||||
|
) : ImportedFromObjectCallableDescriptor<FunctionDescriptor>(functionFromObject, originalOrNull),
|
||||||
|
FunctionDescriptor by functionFromObject {
|
||||||
|
|
||||||
override fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? = null
|
override fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? = null
|
||||||
|
|
||||||
override fun substitute(substitutor: TypeSubstitutor) = callableFromObject.substitute(substitutor)?.wrap()
|
override fun substitute(substitutor: TypeSubstitutor) =
|
||||||
|
callableFromObject.substitute(substitutor)?.asImportedFromObject(this)
|
||||||
|
|
||||||
private val _original by lazy {
|
override fun getOriginal() = _original as FunctionDescriptor
|
||||||
functionFromObject.original.wrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getOriginal() = _original
|
|
||||||
|
|
||||||
override fun copy(
|
override fun copy(
|
||||||
newOwner: DeclarationDescriptor?, modality: Modality?, visibility: Visibility?,
|
newOwner: DeclarationDescriptor?, modality: Modality?, visibility: Visibility?,
|
||||||
kind: CallableMemberDescriptor.Kind?, copyOverrides: Boolean
|
kind: CallableMemberDescriptor.Kind?, copyOverrides: Boolean
|
||||||
): FunctionDescriptor {
|
): FunctionDescriptor {
|
||||||
throw IllegalStateException("copy() should not be called on ${this.javaClass.simpleName}, was called for $this")
|
throw UnsupportedOperationException("copy() should not be called on ${this.javaClass.simpleName}, was called for $this")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PropertyImportedFromObject(propertyFromObject: PropertyDescriptor) :
|
class PropertyImportedFromObject(
|
||||||
PropertyDescriptor by propertyFromObject,
|
propertyFromObject: PropertyDescriptor,
|
||||||
ImportedFromObjectCallableDescriptor<PropertyDescriptor>(propertyFromObject) {
|
originalOrNull: PropertyDescriptor? = null
|
||||||
|
) : ImportedFromObjectCallableDescriptor<PropertyDescriptor>(propertyFromObject, originalOrNull),
|
||||||
|
PropertyDescriptor by propertyFromObject {
|
||||||
|
|
||||||
override fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? = null
|
override fun getDispatchReceiverParameter(): ReceiverParameterDescriptor? = null
|
||||||
|
|
||||||
override fun substitute(substitutor: TypeSubstitutor) = callableFromObject.substitute(substitutor)?.wrap()
|
override fun substitute(substitutor: TypeSubstitutor) = callableFromObject.substitute(substitutor)?.asImportedFromObject(this)
|
||||||
|
|
||||||
private val _original by lazy {
|
override fun getOriginal() = _original as PropertyDescriptor
|
||||||
propertyFromObject.original.wrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getOriginal() = _original
|
|
||||||
|
|
||||||
override fun copy(
|
override fun copy(
|
||||||
newOwner: DeclarationDescriptor?, modality: Modality?, visibility: Visibility?,
|
newOwner: DeclarationDescriptor?, modality: Modality?, visibility: Visibility?,
|
||||||
kind: CallableMemberDescriptor.Kind?, copyOverrides: Boolean
|
kind: CallableMemberDescriptor.Kind?, copyOverrides: Boolean
|
||||||
): FunctionDescriptor {
|
): FunctionDescriptor {
|
||||||
throw IllegalStateException("copy() should not be called on ${this.javaClass.simpleName}, was called for $this")
|
throw UnsupportedOperationException("copy() should not be called on ${this.javaClass.simpleName}, was called for $this")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FunctionDescriptor.wrap() = FunctionImportedFromObject(this)
|
|
||||||
private fun PropertyDescriptor.wrap() = PropertyImportedFromObject(this)
|
|
||||||
Reference in New Issue
Block a user