Refactor DelegationChecker and related code

- move getDelegates from CodegenUtil to DelegationResolver, reuse it in
  DelegationChecker
- use getAllOverriddenDescriptors + filterOutOverridden instead of a manual DFS
This commit is contained in:
Alexander Udalov
2016-12-19 12:34:26 +03:00
parent 2dd7d89048
commit 482b43631c
8 changed files with 122 additions and 109 deletions
@@ -24,51 +24,10 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.MemberComparator
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.isDynamic
import org.jetbrains.kotlin.utils.keysToMapExceptNulls
object CodegenUtil {
// class Foo : Bar by baz
// descriptor = Foo
// toInterface = Bar
// delegateExpressionType = typeof(baz)
// return Map<member of Foo, corresponding member of typeOf(baz)>
@JvmStatic
fun getDelegates(
descriptor: ClassDescriptor,
toInterface: ClassDescriptor,
delegateExpressionType: KotlinType? = null
): Map<CallableMemberDescriptor, CallableDescriptor> {
if (delegateExpressionType?.isDynamic() ?: false) return emptyMap()
return descriptor.defaultType.memberScope.getContributedDescriptors().asSequence()
.filterIsInstance<CallableMemberDescriptor>()
.filter { it.kind == CallableMemberDescriptor.Kind.DELEGATION }
.asIterable()
.sortedWith(MemberComparator.INSTANCE)
.keysToMapExceptNulls { delegatingMember ->
val actualDelegates = DescriptorUtils.getAllOverriddenDescriptors(delegatingMember)
.filter { it.containingDeclaration == toInterface }
.map { overriddenDescriptor ->
val scope = (delegateExpressionType ?: toInterface.defaultType).memberScope
val name = overriddenDescriptor.name
// this is the actual member of delegateExpressionType that we are delegating to
(scope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND) +
scope.getContributedVariables(name, NoLookupLocation.FROM_BACKEND))
.firstOrNull { it == overriddenDescriptor || OverridingUtil.overrides(it, overriddenDescriptor) }
}
assert(actualDelegates.size <= 1) { "Many delegates found for $delegatingMember: $actualDelegates" }
actualDelegates.firstOrNull()
}
}
@JvmStatic
fun getDelegatePropertyIfAny(
expression: KtExpression, classDescriptor: ClassDescriptor, bindingContext: BindingContext