ExpectActualUtils: add type arguments accessibility check for top level classes

This commit is contained in:
Dmitry Gridin
2019-08-06 17:54:33 +03:00
parent bad9459978
commit e59571c482
2 changed files with 19 additions and 4 deletions
@@ -118,6 +118,10 @@ class CreateExpectedClassFix(
) : CreateExpectedFix<KtClassOrObject>(klass, outerExpectedClass, commonModule, block@{ project, element ->
val originalElements = element.collectDeclarations(false).toList()
val existingClasses = findClasses(originalElements + klass)
if (!element.checkTypeAccessibilityInModule(commonModule, existingClasses)) {
showUnknownTypesError(element)
return@block null
}
val (members, declarationsWithNonExistentClasses) = originalElements.filterNot(KtNamedDeclaration::isAlwaysActual).partition {
it.checkTypeAccessibilityInModule(commonModule, existingClasses)
@@ -135,6 +139,11 @@ class CreateExpectedClassFix(
}.let { selectedElements ->
val selectedClasses = findClasses(selectedElements + klass)
if (selectedClasses != existingClasses) {
if (!element.checkTypeAccessibilityInModule(commonModule, selectedClasses)) {
showUnknownTypesError(element)
return@block null
}
val (resultDeclarations, withErrors) = selectedElements.partition {
it.checkTypeAccessibilityInModule(commonModule, selectedClasses)
}
@@ -323,8 +323,14 @@ class KotlinTypeInaccessibleException(val type: KotlinType) : Exception() {
fun DeclarationDescriptor.checkTypeAccessibilityInModule(
project: Project,
module: Module,
existedClasses: Set<String> = emptySet()
): Boolean = collectAllTypes().all { it?.canFindClassInModule(project, module, existedClasses) == true }
existingClasses: Set<String> = emptySet()
): Boolean {
val existingClassesWithTypeParameters = if (this is ClassifierDescriptorWithTypeParameters)
existingClasses + declaredTypeParameters.map { it.fqNameOrNull()?.asString() ?: return false }.toSet()
else
existingClasses
return collectAllTypes().all { it?.canFindClassInModule(project, module, existingClassesWithTypeParameters) == true }
}
private fun DeclarationDescriptor.collectAllTypes(): Sequence<FqName?> {
return when (this) {
@@ -346,8 +352,8 @@ private fun KotlinType.collectAllTypes(): Sequence<FqName?> = sequenceOf(fqName)
.map(TypeProjection::getType)
.flatMap(KotlinType::collectAllTypes)
fun KtNamedDeclaration.checkTypeAccessibilityInModule(module: Module, existedClasses: Set<String> = emptySet()): Boolean {
return !hasPrivateModifier() && descriptor?.checkTypeAccessibilityInModule(project, module, existedClasses) == true
fun KtNamedDeclaration.checkTypeAccessibilityInModule(module: Module, existingClasses: Set<String> = emptySet()): Boolean {
return !hasPrivateModifier() && descriptor?.checkTypeAccessibilityInModule(project, module, existingClasses) == true
}
val KotlinType.fqName: FqName? get() = constructor.declarationDescriptor?.fqNameOrNull()