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.
/*
* 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 com.intellij.util.containers.MultiMap
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.INCOMPATIBLE
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeIntersector
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.oneMoreSpecificThanAnother
object OverloadUtil {
/**
* Does not check names.
*/
public @JvmStatic fun isOverloadable(a: CallableDescriptor, b: CallableDescriptor): Boolean {
val abc = braceCount(a)
val bbc = braceCount(b)
if (abc != bbc) {
return true
}
val receiverAndParameterResult = OverridingUtil.checkReceiverAndParameterCount(a, b)
if (receiverAndParameterResult != null) {
return receiverAndParameterResult.result == INCOMPATIBLE
}
val aValueParameters = OverridingUtil.compiledValueParameters(a)
val bValueParameters = OverridingUtil.compiledValueParameters(b)
for ((aType, bType) in aValueParameters.zip(bValueParameters)) {
// TODO: check type parameters, create a substitution and compare parameter types according to it, like in OverridingUtil
val superValueParameterType = aType.upperBound
val subValueParameterType = bType.upperBound
if (!KotlinTypeChecker.DEFAULT.equalTypes(superValueParameterType, subValueParameterType) ||
oneMoreSpecificThanAnother(subValueParameterType, superValueParameterType)) {
return true
}
}
return false
}
private fun braceCount(a: CallableDescriptor): Int =
when (a) {
is PropertyDescriptor -> 0
is SimpleFunctionDescriptor -> 1
is ConstructorDescriptor -> 1
else -> throw IllegalStateException()
}
private val KotlinType.upperBound: KotlinType
get() {
val classifier = constructor.declarationDescriptor
return when (classifier) {
is ClassDescriptor -> this
is TypeParameterDescriptor -> TypeIntersector.getUpperBoundsAsType(classifier)
else -> error("Unknown type constructor: $this")
}
}
public @JvmStatic fun groupModulePackageMembersByFqName(
c: BodiesResolveContext,
constructorsInPackages: MultiMap,
overloadFilter: OverloadFilter
): MultiMap {
val packageMembersByName = MultiMap()
collectModulePackageMembersWithSameName(packageMembersByName, c.functions.values, overloadFilter) {
scope, name ->
scope.getContributedFunctions(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS)
}
collectModulePackageMembersWithSameName(packageMembersByName, c.properties.values, overloadFilter) {
scope, name ->
scope.getContributedVariables(name, NoLookupLocation.WHEN_CHECK_REDECLARATIONS).filterIsInstance()
}
// TODO handle constructor redeclarations in modules. See also: https://youtrack.jetbrains.com/issue/KT-3632
packageMembersByName.putAllValues(constructorsInPackages)
return packageMembersByName
}
private inline fun collectModulePackageMembersWithSameName(
packageMembersByName: MultiMap,
interestingDescriptors: Collection,
overloadFilter: OverloadFilter,
getMembersByName: (MemberScope, Name) -> Collection
) {
val observedFQNs = hashSetOf()
for (descriptor in interestingDescriptors) {
if (descriptor.containingDeclaration !is PackageFragmentDescriptor) continue
val descriptorFQN = DescriptorUtils.getFqName(descriptor)
if (observedFQNs.contains(descriptorFQN)) continue
observedFQNs.add(descriptorFQN)
val packageMembersWithSameName = getModulePackageMembersWithSameName(descriptor, overloadFilter, getMembersByName)
packageMembersByName.putValues(descriptorFQN, packageMembersWithSameName)
}
}
private inline fun getModulePackageMembersWithSameName(
packageMember: CallableMemberDescriptor,
overloadFilter: OverloadFilter,
getMembersByName: (MemberScope, Name) -> Collection
): Collection {
val containingPackage = packageMember.containingDeclaration
if (containingPackage !is PackageFragmentDescriptor) {
throw AssertionError("$packageMember is not a top-level package member")
}
val containingModule = DescriptorUtils.getContainingModuleOrNull(packageMember) ?: return listOf(packageMember)
val containingPackageScope = containingModule.getPackage(containingPackage.fqName).memberScope
val possibleOverloads =
getMembersByName(containingPackageScope, packageMember.name).filter {
// NB memberScope for PackageViewDescriptor includes module dependencies
DescriptorUtils.getContainingModule(it) == containingModule
}
return overloadFilter.filterPackageMemberOverloads(possibleOverloads)
}
private fun MemberDescriptor.isPrivate() = Visibilities.isPrivate(this.visibility)
public @JvmStatic fun getPossibleRedeclarationGroups(members: Collection): Collection> {
val result = arrayListOf>()
val nonPrivates = members.filter { !it.isPrivate() }
if (nonPrivates.size > 1) {
result.add(nonPrivates)
}
val bySourceFile = MultiMap.createSmart()
for (member in members) {
val sourceFile = DescriptorUtils.getContainingSourceFile(member)
if (sourceFile != SourceFile.NO_SOURCE_FILE) {
bySourceFile.putValue(sourceFile, member)
}
}
for ((sourceFile, membersInFile) in bySourceFile.entrySet()) {
// File member groups are interesting in redeclaration check if at least one file member is private.
if (membersInFile.size > 1 && membersInFile.any { it.isPrivate() }) {
result.add(membersInFile)
}
}
return result
}
}