All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jetbrains.kotlin.resolve.DelegationResolver.kt Maven / Gradle / Ivy
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DELEGATION
import org.jetbrains.kotlin.diagnostics.Errors.MANY_IMPL_MEMBER_NOT_IMPLEMENTED
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
import org.jetbrains.kotlin.psi.KtTypeReference
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
class DelegationResolver private constructor(
private val classOrObject: KtClassOrObject,
private val ownerDescriptor: ClassDescriptor,
private val existingMembers: Collection,
private val trace: BindingTrace,
private val memberExtractor: DelegationResolver.MemberExtractor,
private val typeResolver: DelegationResolver.TypeResolver
) {
private fun generateDelegatedMembers(): Collection {
val delegatedMembers = hashSetOf()
for (delegationSpecifier in classOrObject.getSuperTypeListEntries()) {
if (delegationSpecifier !is KtDelegatedSuperTypeEntry) {
continue
}
val typeReference = delegationSpecifier.typeReference ?: continue
val delegatedInterfaceType = typeResolver.resolve(typeReference)
if (delegatedInterfaceType == null || delegatedInterfaceType.isError) {
continue
}
val delegatesForInterface = generateDelegatesForInterface(delegatedMembers, delegatedInterfaceType)
delegatedMembers.addAll(delegatesForInterface)
}
return delegatedMembers
}
private fun generateDelegatesForInterface(existingDelegates: Collection, delegatedInterfaceType: KotlinType): Collection =
generateDelegationCandidates(delegatedInterfaceType).filter { candidate ->
!isOverridingAnyOf(candidate, existingMembers) &&
!checkClashWithOtherDelegatedMember(candidate, existingDelegates)
}
private fun generateDelegationCandidates(delegatedInterfaceType: KotlinType): Collection =
getDelegatableMembers(delegatedInterfaceType).map { memberDescriptor ->
val newModality = if (memberDescriptor.modality == Modality.ABSTRACT) Modality.OPEN else memberDescriptor.modality
@Suppress("UNCHECKED_CAST")
(memberDescriptor.copy(ownerDescriptor, newModality, Visibilities.INHERITED, DELEGATION, false) as T)
}
private fun checkClashWithOtherDelegatedMember(candidate: T, delegatedMembers: Collection): Boolean {
val alreadyDelegated = delegatedMembers.firstOrNull { isOverridableBy(it, candidate) }
if (alreadyDelegated != null) {
trace.report(MANY_IMPL_MEMBER_NOT_IMPLEMENTED.on(classOrObject, classOrObject, alreadyDelegated))
return true;
}
return false;
}
private fun getDelegatableMembers(interfaceType: KotlinType): Collection {
val classSupertypeMembers =
TypeUtils.getAllSupertypes(interfaceType).firstOrNull {
val typeConstructor = it.constructor.declarationDescriptor
typeConstructor is ClassDescriptor && typeConstructor.kind != ClassKind.INTERFACE
}?.let {
memberExtractor.getMembersByType(it)
} ?: emptyList()
return memberExtractor.getMembersByType(interfaceType).filter { descriptor ->
descriptor.isOverridable && !classSupertypeMembers.any { isOverridableBy(it, descriptor) }
}
}
interface MemberExtractor {
fun getMembersByType(type: KotlinType): Collection
}
interface TypeResolver {
fun resolve(reference: KtTypeReference): KotlinType?
}
companion object {
fun generateDelegatedMembers(
classOrObject: KtClassOrObject,
ownerDescriptor: ClassDescriptor,
existingMembers: Collection,
trace: BindingTrace,
memberExtractor: MemberExtractor,
typeResolver: TypeResolver
): Collection =
DelegationResolver(classOrObject, ownerDescriptor, existingMembers, trace, memberExtractor, typeResolver)
.generateDelegatedMembers()
private fun isOverridingAnyOf(
candidate: CallableMemberDescriptor,
possiblyOverriddenBy: Collection
): Boolean =
possiblyOverriddenBy.any { isOverridableBy(it, candidate) }
private fun isOverridableBy(memberOne: CallableDescriptor, memberTwo: CallableDescriptor): Boolean =
OverridingUtil.DEFAULT.isOverridableBy(memberOne, memberTwo, null).result == OVERRIDABLE
}
}