KTIJ-27841 [AA] Refactor ElementsToShortenCollector.findClassifierQualifierToShorten
Extract the cycle body into a separate function for clarity
This commit is contained in:
+65
-66
@@ -523,7 +523,7 @@ private class ElementsToShortenCollector(
|
|||||||
|
|
||||||
val classifierId = resolvedTypeRef.type.lowerBoundIfFlexible().candidateClassId ?: return
|
val classifierId = resolvedTypeRef.type.lowerBoundIfFlexible().candidateClassId ?: return
|
||||||
|
|
||||||
findTypeQualifierToShorten(classifierId, typeElement)?.let(::addElementToShorten)
|
findClassifierQualifierToShorten(classifierId, typeElement)?.let(::addElementToShorten)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -592,25 +592,7 @@ private class ElementsToShortenCollector(
|
|||||||
else -> return
|
else -> return
|
||||||
}
|
}
|
||||||
|
|
||||||
findTypeQualifierToShorten(wholeClassQualifier, wholeQualifierElement)?.let(::addElementToShorten)
|
findClassifierQualifierToShorten(wholeClassQualifier, wholeQualifierElement)?.let(::addElementToShorten)
|
||||||
}
|
|
||||||
|
|
||||||
private fun findTypeQualifierToShorten(
|
|
||||||
wholeClassQualifier: ClassId,
|
|
||||||
wholeQualifierElement: KtElement,
|
|
||||||
): ElementToShorten? {
|
|
||||||
val positionScopes = shorteningContext.findScopesAtPosition(
|
|
||||||
wholeQualifierElement,
|
|
||||||
getNamesToImport(),
|
|
||||||
towerContextProvider,
|
|
||||||
withImplicitReceivers = false,
|
|
||||||
) ?: return null
|
|
||||||
|
|
||||||
return findClassifierQualifierToShorten(
|
|
||||||
positionScopes,
|
|
||||||
wholeClassQualifier,
|
|
||||||
wholeQualifierElement,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val FirClassifierSymbol<*>.classIdIfExists: ClassId? get() = (this as? FirClassLikeSymbol<*>)?.classId
|
private val FirClassifierSymbol<*>.classIdIfExists: ClassId? get() = (this as? FirClassLikeSymbol<*>)?.classId
|
||||||
@@ -819,6 +801,61 @@ private class ElementsToShortenCollector(
|
|||||||
return createElementToShorten(referenceExpression, shortenedRef = aliasedName)
|
return createElementToShorten(referenceExpression, shortenedRef = aliasedName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun shortenClassifierQualifier(
|
||||||
|
positionScopes: List<FirScope>,
|
||||||
|
qualifierClassId: ClassId,
|
||||||
|
qualifierElement: KtElement,
|
||||||
|
): ElementToShorten? {
|
||||||
|
val classSymbol = shorteningContext.toClassSymbol(qualifierClassId) ?: return null
|
||||||
|
|
||||||
|
val option = classShortenStrategy(classSymbol)
|
||||||
|
if (option == ShortenStrategy.DO_NOT_SHORTEN) return null
|
||||||
|
|
||||||
|
// If its parent has a type parameter, we do not shorten it ATM because it will lose its type parameter. See KTIJ-26072
|
||||||
|
if (classSymbol.hasTypeParameterFromParent()) return null
|
||||||
|
|
||||||
|
shortenIfAlreadyImportedAsAlias(qualifierElement, qualifierClassId.asSingleFqName())?.let { return it }
|
||||||
|
|
||||||
|
if (shortenClassifierIfAlreadyImported(qualifierClassId, qualifierElement, classSymbol, positionScopes)) {
|
||||||
|
return createElementToShorten(qualifierElement)
|
||||||
|
}
|
||||||
|
if (option == ShortenStrategy.SHORTEN_IF_ALREADY_IMPORTED) return null
|
||||||
|
|
||||||
|
val importAllInParent = option == ShortenStrategy.SHORTEN_AND_STAR_IMPORT
|
||||||
|
if (importAffectsUsagesOfClassesWithSameName(qualifierClassId, qualifierElement.containingKtFile, importAllInParent)) return null
|
||||||
|
|
||||||
|
// Find class with the same name that's already available in this file.
|
||||||
|
val availableClassifier = shorteningContext.findFirstClassifierInScopesByName(positionScopes, qualifierClassId.shortClassName)
|
||||||
|
|
||||||
|
when {
|
||||||
|
// No class with name `classId.shortClassName` is present in the scope. Hence, we can safely import the name and shorten
|
||||||
|
// the reference.
|
||||||
|
availableClassifier == null -> {
|
||||||
|
return createElementToShorten(
|
||||||
|
qualifierElement,
|
||||||
|
qualifierClassId.asSingleFqName(),
|
||||||
|
importAllInParent
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// The class with name `classId.shortClassName` happens to be the same class referenced by this qualified access.
|
||||||
|
availableClassifier.symbol.classIdIfExists == qualifierClassId -> {
|
||||||
|
// Respect caller's request to use star import, if it's not already star-imported.
|
||||||
|
return when {
|
||||||
|
availableClassifier.importKind == ImportKind.EXPLICIT && importAllInParent -> {
|
||||||
|
createElementToShorten(qualifierElement, qualifierClassId.asSingleFqName(), importAllInParent)
|
||||||
|
}
|
||||||
|
// Otherwise, just shorten it and don't alter import statements
|
||||||
|
else -> createElementToShorten(qualifierElement)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
importedClassifierOverwritesAvailableClassifier(availableClassifier, importAllInParent) -> {
|
||||||
|
return createElementToShorten(qualifierElement, qualifierClassId.asSingleFqName(), importAllInParent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the longest qualifier in [wholeQualifierElement] which can be safely shortened in the [positionScopes].
|
* Finds the longest qualifier in [wholeQualifierElement] which can be safely shortened in the [positionScopes].
|
||||||
* [wholeQualifierClassId] is supposed to reflect the class which is referenced by the [wholeQualifierElement].
|
* [wholeQualifierClassId] is supposed to reflect the class which is referenced by the [wholeQualifierElement].
|
||||||
@@ -828,61 +865,23 @@ private class ElementsToShortenCollector(
|
|||||||
* So we have to check all the outer qualifiers.
|
* So we have to check all the outer qualifiers.
|
||||||
*/
|
*/
|
||||||
private fun findClassifierQualifierToShorten(
|
private fun findClassifierQualifierToShorten(
|
||||||
positionScopes: List<FirScope>,
|
|
||||||
wholeQualifierClassId: ClassId,
|
wholeQualifierClassId: ClassId,
|
||||||
wholeQualifierElement: KtElement,
|
wholeQualifierElement: KtElement,
|
||||||
): ElementToShorten? {
|
): ElementToShorten? {
|
||||||
|
val positionScopes = shorteningContext.findScopesAtPosition(
|
||||||
|
wholeQualifierElement,
|
||||||
|
getNamesToImport(),
|
||||||
|
towerContextProvider,
|
||||||
|
withImplicitReceivers = false,
|
||||||
|
) ?: return null
|
||||||
|
|
||||||
val allClassIds = wholeQualifierClassId.outerClassesWithSelf
|
val allClassIds = wholeQualifierClassId.outerClassesWithSelf
|
||||||
val allQualifiedElements = wholeQualifierElement.qualifiedElementsWithSelf
|
val allQualifiedElements = wholeQualifierElement.qualifiedElementsWithSelf
|
||||||
|
|
||||||
for ((classId, element) in allClassIds.zip(allQualifiedElements)) {
|
for ((classId, element) in allClassIds.zip(allQualifiedElements)) {
|
||||||
if (!element.inSelection) continue
|
if (!element.inSelection) continue
|
||||||
|
|
||||||
val classSymbol = shorteningContext.toClassSymbol(classId) ?: return null
|
shortenClassifierQualifier(positionScopes, classId, element)?.let { return it }
|
||||||
val option = classShortenStrategy(classSymbol)
|
|
||||||
if (option == ShortenStrategy.DO_NOT_SHORTEN) continue
|
|
||||||
|
|
||||||
// If its parent has a type parameter, we do not shorten it ATM because it will lose its type parameter. See KTIJ-26072
|
|
||||||
if (classSymbol.hasTypeParameterFromParent()) continue
|
|
||||||
|
|
||||||
shortenIfAlreadyImportedAsAlias(element, classId.asSingleFqName())?.let { return it }
|
|
||||||
|
|
||||||
if (shortenClassifierIfAlreadyImported(classId, element, classSymbol, positionScopes)) {
|
|
||||||
return createElementToShorten(element)
|
|
||||||
}
|
|
||||||
if (option == ShortenStrategy.SHORTEN_IF_ALREADY_IMPORTED) continue
|
|
||||||
|
|
||||||
val importAllInParent = option == ShortenStrategy.SHORTEN_AND_STAR_IMPORT
|
|
||||||
if (importAffectsUsagesOfClassesWithSameName(classId, element.containingKtFile, importAllInParent)) continue
|
|
||||||
|
|
||||||
// Find class with the same name that's already available in this file.
|
|
||||||
val availableClassifier = shorteningContext.findFirstClassifierInScopesByName(positionScopes, classId.shortClassName)
|
|
||||||
|
|
||||||
when {
|
|
||||||
// No class with name `classId.shortClassName` is present in the scope. Hence, we can safely import the name and shorten
|
|
||||||
// the reference.
|
|
||||||
availableClassifier == null -> {
|
|
||||||
return createElementToShorten(
|
|
||||||
element,
|
|
||||||
classId.asSingleFqName(),
|
|
||||||
importAllInParent
|
|
||||||
)
|
|
||||||
}
|
|
||||||
// The class with name `classId.shortClassName` happens to be the same class referenced by this qualified access.
|
|
||||||
availableClassifier.symbol.classIdIfExists == classId -> {
|
|
||||||
// Respect caller's request to use star import, if it's not already star-imported.
|
|
||||||
return when {
|
|
||||||
availableClassifier.importKind == ImportKind.EXPLICIT && importAllInParent -> {
|
|
||||||
createElementToShorten(element, classId.asSingleFqName(), importAllInParent)
|
|
||||||
}
|
|
||||||
// Otherwise, just shorten it and don't alter import statements
|
|
||||||
else -> createElementToShorten(element)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
importedClassifierOverwritesAvailableClassifier(availableClassifier, importAllInParent) -> {
|
|
||||||
return createElementToShorten(element, classId.asSingleFqName(), importAllInParent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val lastQualifier = allQualifiedElements.last()
|
val lastQualifier = allQualifiedElements.last()
|
||||||
|
|||||||
Reference in New Issue
Block a user