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 -> ) : CreateExpectedFix<KtClassOrObject>(klass, outerExpectedClass, commonModule, block@{ project, element ->
val originalElements = element.collectDeclarations(false).toList() val originalElements = element.collectDeclarations(false).toList()
val existingClasses = findClasses(originalElements + klass) val existingClasses = findClasses(originalElements + klass)
if (!element.checkTypeAccessibilityInModule(commonModule, existingClasses)) {
showUnknownTypesError(element)
return@block null
}
val (members, declarationsWithNonExistentClasses) = originalElements.filterNot(KtNamedDeclaration::isAlwaysActual).partition { val (members, declarationsWithNonExistentClasses) = originalElements.filterNot(KtNamedDeclaration::isAlwaysActual).partition {
it.checkTypeAccessibilityInModule(commonModule, existingClasses) it.checkTypeAccessibilityInModule(commonModule, existingClasses)
@@ -135,6 +139,11 @@ class CreateExpectedClassFix(
}.let { selectedElements -> }.let { selectedElements ->
val selectedClasses = findClasses(selectedElements + klass) val selectedClasses = findClasses(selectedElements + klass)
if (selectedClasses != existingClasses) { if (selectedClasses != existingClasses) {
if (!element.checkTypeAccessibilityInModule(commonModule, selectedClasses)) {
showUnknownTypesError(element)
return@block null
}
val (resultDeclarations, withErrors) = selectedElements.partition { val (resultDeclarations, withErrors) = selectedElements.partition {
it.checkTypeAccessibilityInModule(commonModule, selectedClasses) it.checkTypeAccessibilityInModule(commonModule, selectedClasses)
} }
@@ -323,8 +323,14 @@ class KotlinTypeInaccessibleException(val type: KotlinType) : Exception() {
fun DeclarationDescriptor.checkTypeAccessibilityInModule( fun DeclarationDescriptor.checkTypeAccessibilityInModule(
project: Project, project: Project,
module: Module, module: Module,
existedClasses: Set<String> = emptySet() existingClasses: Set<String> = emptySet()
): Boolean = collectAllTypes().all { it?.canFindClassInModule(project, module, existedClasses) == true } ): 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?> { private fun DeclarationDescriptor.collectAllTypes(): Sequence<FqName?> {
return when (this) { return when (this) {
@@ -346,8 +352,8 @@ private fun KotlinType.collectAllTypes(): Sequence<FqName?> = sequenceOf(fqName)
.map(TypeProjection::getType) .map(TypeProjection::getType)
.flatMap(KotlinType::collectAllTypes) .flatMap(KotlinType::collectAllTypes)
fun KtNamedDeclaration.checkTypeAccessibilityInModule(module: Module, existedClasses: Set<String> = emptySet()): Boolean { fun KtNamedDeclaration.checkTypeAccessibilityInModule(module: Module, existingClasses: Set<String> = emptySet()): Boolean {
return !hasPrivateModifier() && descriptor?.checkTypeAccessibilityInModule(project, module, existedClasses) == true return !hasPrivateModifier() && descriptor?.checkTypeAccessibilityInModule(project, module, existingClasses) == true
} }
val KotlinType.fqName: FqName? get() = constructor.declarationDescriptor?.fqNameOrNull() val KotlinType.fqName: FqName? get() = constructor.declarationDescriptor?.fqNameOrNull()