ShortenReferences: shouldn't analyze root prefix elements & should get rid of them at end
Relates to #KT-33937
This commit is contained in:
@@ -226,7 +226,9 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT
|
|||||||
failedToImportDescriptors.add(descriptor)
|
failedToImportDescriptors.add(descriptor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!anyChange) processors.forEach { it.removeRootPrefixes() }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!anyChange) break
|
if (!anyChange) break
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,6 +251,7 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT
|
|||||||
var options: Options = Options.DEFAULT
|
var options: Options = Options.DEFAULT
|
||||||
|
|
||||||
private val elementsToAnalyze = ArrayList<ElementToAnalyze<TElement>>()
|
private val elementsToAnalyze = ArrayList<ElementToAnalyze<TElement>>()
|
||||||
|
private val elementsWithRootPrefix = mutableListOf<SmartPsiElementPointer<TElement>>()
|
||||||
|
|
||||||
private var level = 0
|
private var level = 0
|
||||||
|
|
||||||
@@ -265,7 +268,10 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT
|
|||||||
* Should be invoked by implementors when visiting the PSI tree for those elements that can potentially be shortened
|
* Should be invoked by implementors when visiting the PSI tree for those elements that can potentially be shortened
|
||||||
*/
|
*/
|
||||||
protected fun addQualifiedElementToAnalyze(element: TElement) {
|
protected fun addQualifiedElementToAnalyze(element: TElement) {
|
||||||
elementsToAnalyze.add(ElementToAnalyze(element, level))
|
if (element.isRootPrefix())
|
||||||
|
elementsWithRootPrefix += element.createSmartPointer()
|
||||||
|
else
|
||||||
|
elementsToAnalyze += ElementToAnalyze(element, level)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitElement(element: PsiElement) {
|
override fun visitElement(element: PsiElement) {
|
||||||
@@ -275,6 +281,7 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getElementsToAnalyze(): List<ElementToAnalyze<TElement>> = elementsToAnalyze
|
fun getElementsToAnalyze(): List<ElementToAnalyze<TElement>> = elementsToAnalyze
|
||||||
|
fun getElementsWithRootPrefix(): Collection<SmartPsiElementPointer<TElement>> = elementsWithRootPrefix
|
||||||
}
|
}
|
||||||
|
|
||||||
private abstract class ShorteningProcessor<TElement : KtElement>(
|
private abstract class ShorteningProcessor<TElement : KtElement>(
|
||||||
@@ -362,6 +369,13 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun removeRootPrefixes() {
|
||||||
|
for (pointer in collectElementsVisitor.getElementsWithRootPrefix()) {
|
||||||
|
val element = pointer.element ?: continue
|
||||||
|
shortenElement(element, Options.DEFAULT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getDescriptorsToImport(): Set<DeclarationDescriptor> = descriptorsToImport
|
fun getDescriptorsToImport(): Set<DeclarationDescriptor> = descriptorsToImport
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -393,40 +407,31 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun analyzeQualifiedElement(element: KtUserType, bindingContext: BindingContext): AnalyzeQualifiedElementResult {
|
override fun analyzeQualifiedElement(element: KtUserType, bindingContext: BindingContext): AnalyzeQualifiedElementResult {
|
||||||
fun eval(element: KtUserType, bindingContext: BindingContext): AnalyzeQualifiedElementResult {
|
if (element.qualifier == null) return AnalyzeQualifiedElementResult.Skip
|
||||||
if (element.qualifier == null) return AnalyzeQualifiedElementResult.Skip
|
val referenceExpression = element.referenceExpression ?: return AnalyzeQualifiedElementResult.Skip
|
||||||
val referenceExpression = element.referenceExpression ?: return AnalyzeQualifiedElementResult.Skip
|
|
||||||
|
|
||||||
val target = referenceExpression.targets(bindingContext).singleOrNull()
|
val target = referenceExpression.targets(bindingContext).singleOrNull()
|
||||||
?: return AnalyzeQualifiedElementResult.Skip
|
?: return AnalyzeQualifiedElementResult.Skip
|
||||||
|
|
||||||
val scope = element.getResolutionScope(bindingContext, resolutionFacade)
|
val scope = element.getResolutionScope(bindingContext, resolutionFacade)
|
||||||
val name = target.name
|
val name = target.name
|
||||||
|
|
||||||
val targetByName: DeclarationDescriptor?
|
val targetByName: DeclarationDescriptor?
|
||||||
val isDeprecated: Boolean
|
val isDeprecated: Boolean
|
||||||
|
|
||||||
if (target is ClassifierDescriptor) {
|
if (target is ClassifierDescriptor) {
|
||||||
val classifierWithDeprecation = scope.findFirstClassifierWithDeprecationStatus(name, NoLookupLocation.FROM_IDE)
|
val classifierWithDeprecation = scope.findFirstClassifierWithDeprecationStatus(name, NoLookupLocation.FROM_IDE)
|
||||||
targetByName = classifierWithDeprecation?.descriptor
|
targetByName = classifierWithDeprecation?.descriptor
|
||||||
isDeprecated = classifierWithDeprecation?.isDeprecated ?: false
|
isDeprecated = classifierWithDeprecation?.isDeprecated ?: false
|
||||||
} else {
|
} else {
|
||||||
targetByName = scope.findPackage(name)
|
targetByName = scope.findPackage(name)
|
||||||
isDeprecated = false
|
isDeprecated = false
|
||||||
}
|
|
||||||
|
|
||||||
val canShortenNow = targetByName?.asString() == target.asString() && !isDeprecated
|
|
||||||
return if (canShortenNow) AnalyzeQualifiedElementResult.ShortenNow else AnalyzeQualifiedElementResult.ImportDescriptors(
|
|
||||||
listOfNotNull(target)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = eval(element, bindingContext)
|
val canShortenNow = targetByName?.asString() == target.asString() && !isDeprecated
|
||||||
if (result is AnalyzeQualifiedElementResult.Skip &&
|
return if (canShortenNow) AnalyzeQualifiedElementResult.ShortenNow else AnalyzeQualifiedElementResult.ImportDescriptors(
|
||||||
element.qualifier?.text == ROOT_PREFIX_FOR_IDE_RESOLUTION_MODE
|
listOfNotNull(target)
|
||||||
) return AnalyzeQualifiedElementResult.ShortenNow
|
)
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun shortenElement(element: KtUserType, options: Options): KtElement {
|
override fun shortenElement(element: KtUserType, options: Options): KtElement {
|
||||||
@@ -487,8 +492,6 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT
|
|||||||
element: KtDotQualifiedExpression,
|
element: KtDotQualifiedExpression,
|
||||||
bindingContext: BindingContext
|
bindingContext: BindingContext
|
||||||
): AnalyzeQualifiedElementResult {
|
): AnalyzeQualifiedElementResult {
|
||||||
if (element.receiverExpression.text == ROOT_PREFIX_FOR_IDE_RESOLUTION_MODE) return AnalyzeQualifiedElementResult.ShortenNow
|
|
||||||
|
|
||||||
if (PsiTreeUtil.getParentOfType(
|
if (PsiTreeUtil.getParentOfType(
|
||||||
element,
|
element,
|
||||||
KtImportDirective::class.java, KtPackageDirective::class.java
|
KtImportDirective::class.java, KtPackageDirective::class.java
|
||||||
@@ -746,3 +749,9 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun PsiElement.isRootPrefix(): Boolean = when (this) {
|
||||||
|
is KtDotQualifiedExpression -> receiverExpression.text == ROOT_PREFIX_FOR_IDE_RESOLUTION_MODE
|
||||||
|
is KtUserType -> qualifier?.text == ROOT_PREFIX_FOR_IDE_RESOLUTION_MODE
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user