From 8161403e69478d052cfa0dfcde61e4b3699bafa9 Mon Sep 17 00:00:00 2001 From: Dmitry Gridin Date: Tue, 1 Oct 2019 15:54:55 +0700 Subject: [PATCH] ShortenReferences: shouldn't analyze root prefix elements & should get rid of them at end Relates to #KT-33937 --- .../kotlin/idea/core/ShortenReferences.kt | 71 +++++++++++-------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt index 07c78711161..77375d2b190 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt @@ -226,7 +226,9 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT failedToImportDescriptors.add(descriptor) } } + if (!anyChange) processors.forEach { it.removeRootPrefixes() } } + if (!anyChange) break } @@ -249,6 +251,7 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT var options: Options = Options.DEFAULT private val elementsToAnalyze = ArrayList>() + private val elementsWithRootPrefix = mutableListOf>() 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 */ 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) { @@ -275,6 +281,7 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT } fun getElementsToAnalyze(): List> = elementsToAnalyze + fun getElementsWithRootPrefix(): Collection> = elementsWithRootPrefix } private abstract class ShorteningProcessor( @@ -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 = descriptorsToImport } @@ -393,40 +407,31 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT } override fun analyzeQualifiedElement(element: KtUserType, bindingContext: BindingContext): AnalyzeQualifiedElementResult { - fun eval(element: KtUserType, bindingContext: BindingContext): AnalyzeQualifiedElementResult { - if (element.qualifier == null) return AnalyzeQualifiedElementResult.Skip - val referenceExpression = element.referenceExpression ?: return AnalyzeQualifiedElementResult.Skip + if (element.qualifier == null) return AnalyzeQualifiedElementResult.Skip + val referenceExpression = element.referenceExpression ?: return AnalyzeQualifiedElementResult.Skip - val target = referenceExpression.targets(bindingContext).singleOrNull() - ?: return AnalyzeQualifiedElementResult.Skip + val target = referenceExpression.targets(bindingContext).singleOrNull() + ?: return AnalyzeQualifiedElementResult.Skip - val scope = element.getResolutionScope(bindingContext, resolutionFacade) - val name = target.name + val scope = element.getResolutionScope(bindingContext, resolutionFacade) + val name = target.name - val targetByName: DeclarationDescriptor? - val isDeprecated: Boolean + val targetByName: DeclarationDescriptor? + val isDeprecated: Boolean - if (target is ClassifierDescriptor) { - val classifierWithDeprecation = scope.findFirstClassifierWithDeprecationStatus(name, NoLookupLocation.FROM_IDE) - targetByName = classifierWithDeprecation?.descriptor - isDeprecated = classifierWithDeprecation?.isDeprecated ?: false - } else { - targetByName = scope.findPackage(name) - isDeprecated = false - } - - val canShortenNow = targetByName?.asString() == target.asString() && !isDeprecated - return if (canShortenNow) AnalyzeQualifiedElementResult.ShortenNow else AnalyzeQualifiedElementResult.ImportDescriptors( - listOfNotNull(target) - ) + if (target is ClassifierDescriptor) { + val classifierWithDeprecation = scope.findFirstClassifierWithDeprecationStatus(name, NoLookupLocation.FROM_IDE) + targetByName = classifierWithDeprecation?.descriptor + isDeprecated = classifierWithDeprecation?.isDeprecated ?: false + } else { + targetByName = scope.findPackage(name) + isDeprecated = false } - val result = eval(element, bindingContext) - if (result is AnalyzeQualifiedElementResult.Skip && - element.qualifier?.text == ROOT_PREFIX_FOR_IDE_RESOLUTION_MODE - ) return AnalyzeQualifiedElementResult.ShortenNow - - return result + val canShortenNow = targetByName?.asString() == target.asString() && !isDeprecated + return if (canShortenNow) AnalyzeQualifiedElementResult.ShortenNow else AnalyzeQualifiedElementResult.ImportDescriptors( + listOfNotNull(target) + ) } override fun shortenElement(element: KtUserType, options: Options): KtElement { @@ -487,8 +492,6 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT element: KtDotQualifiedExpression, bindingContext: BindingContext ): AnalyzeQualifiedElementResult { - if (element.receiverExpression.text == ROOT_PREFIX_FOR_IDE_RESOLUTION_MODE) return AnalyzeQualifiedElementResult.ShortenNow - if (PsiTreeUtil.getParentOfType( element, 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 +}