From 3a7e4acf2256f5420b6c5db6ec887f428b1b303c Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 11 Jan 2018 18:17:57 +0100 Subject: [PATCH] Reformat and cleanup --- .../kotlin/idea/core/ShortenReferences.kt | 223 +++++++++--------- 1 file changed, 114 insertions(+), 109 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 a723d44efd8..ca8f1c8558d 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 @@ -1,17 +1,6 @@ /* - * Copyright 2010-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.core @@ -25,7 +14,6 @@ import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.analysis.analyzeAsReplacement import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade -import org.jetbrains.kotlin.idea.core.ShortenReferences.Options import org.jetbrains.kotlin.idea.imports.canBeReferencedViaImport import org.jetbrains.kotlin.idea.imports.getImportableTargets import org.jetbrains.kotlin.idea.util.ImportDescriptorResult @@ -56,10 +44,10 @@ import java.util.* class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT }) { data class Options( - val removeThisLabels: Boolean = false, - val removeThis: Boolean = false, - // TODO: remove this option and all related stuff (RETAIN_COMPANION etc.) after KT-13934 fixed - val removeExplicitCompanion: Boolean = true + val removeThisLabels: Boolean = false, + val removeThis: Boolean = false, + // TODO: remove this option and all related stuff (RETAIN_COMPANION etc.) after KT-13934 fixed + val removeExplicitCompanion: Boolean = true ) { companion object { val DEFAULT = Options() @@ -73,18 +61,18 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT val RETAIN_COMPANION = ShortenReferences { Options(removeExplicitCompanion = false) } - private fun DeclarationDescriptor.asString() - = DescriptorRenderer.FQ_NAMES_IN_TYPES.render(this) + private fun DeclarationDescriptor.asString() = DescriptorRenderer.FQ_NAMES_IN_TYPES.render(this) private fun KtReferenceExpression.targets(context: BindingContext) = getImportableTargets(context) private fun mayImport(descriptor: DeclarationDescriptor, file: KtFile): Boolean { return descriptor.canBeReferencedViaImport() - && ImportInsertHelper.getInstance(file.project).mayImportOnShortenReferences(descriptor) + && ImportInsertHelper.getInstance(file.project).mayImportOnShortenReferences(descriptor) } } - @JvmOverloads fun process(element: KtElement, elementFilter: (PsiElement) -> FilterResult = { FilterResult.PROCESS }): KtElement { + @JvmOverloads + fun process(element: KtElement, elementFilter: (PsiElement) -> FilterResult = { FilterResult.PROCESS }): KtElement { return process(listOf(element), elementFilter).single() } @@ -110,26 +98,23 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT range.intersects(elementRange) -> { // for qualified call expression allow to shorten only the part without parenthesis val calleeExpression = ((element as? KtDotQualifiedExpression) - ?.selectorExpression as? KtCallExpression) - ?.calleeExpression + ?.selectorExpression as? KtCallExpression) + ?.calleeExpression if (calleeExpression != null) { val rangeWithoutParenthesis = TextRange(elementRange.startOffset, calleeExpression.textRange!!.endOffset) if (range.contains(rangeWithoutParenthesis)) FilterResult.PROCESS else FilterResult.GO_INSIDE - } - else { + } else { FilterResult.GO_INSIDE } } else -> FilterResult.SKIP } - } - else { + } else { FilterResult.SKIP } }) - } - finally { + } finally { rangeMarker.dispose() } } @@ -140,15 +125,19 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT PROCESS } - @JvmOverloads fun process(elements: Iterable, elementFilter: (PsiElement) -> FilterResult = { FilterResult.PROCESS }): Collection { + @JvmOverloads + fun process( + elements: Iterable, + elementFilter: (PsiElement) -> FilterResult = { FilterResult.PROCESS } + ): Collection { return elements.groupBy(KtElement::getContainingKtFile) - .flatMap { shortenReferencesInFile(it.key, it.value, elementFilter) } + .flatMap { shortenReferencesInFile(it.key, it.value, elementFilter) } } private fun shortenReferencesInFile( - file: KtFile, - elements: List, - elementFilter: (PsiElement) -> FilterResult + file: KtFile, + elements: List, + elementFilter: (PsiElement) -> FilterResult ): Collection { //TODO: that's not correct since we have options! val elementsToUse = dropNestedElements(elements) @@ -160,8 +149,7 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT val companionElementFilter = { element: PsiElement -> if (element is KtElement && !options(element).removeExplicitCompanion) { FilterResult.SKIP - } - else { + } else { elementFilter(element) } } @@ -170,10 +158,10 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT // Processors order is important here so that enclosing elements are not shortened before their children are, e.g. // test.foo(this@A) -> foo(this) val processors: List> = listOf( - ShortenTypesProcessor(file, elementFilter, failedToImportDescriptors), - ShortenThisExpressionsProcessor(file, elementFilter, failedToImportDescriptors), - ShortenQualifiedExpressionsProcessor(file, elementFilter, failedToImportDescriptors), - RemoveExplicitCompanionObjectReferenceProcessor(file, companionElementFilter, failedToImportDescriptors) + ShortenTypesProcessor(file, elementFilter, failedToImportDescriptors), + ShortenThisExpressionsProcessor(file, elementFilter, failedToImportDescriptors), + ShortenQualifiedExpressionsProcessor(file, elementFilter, failedToImportDescriptors), + RemoveExplicitCompanionObjectReferenceProcessor(file, companionElementFilter, failedToImportDescriptors) ) // step 1: collect qualified elements to analyze (no resolve at this step) @@ -215,7 +203,7 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT private fun dropNestedElements(elements: List): LinkedHashSet { val elementSet = elements.toSet() - return elementSet.filterTo(LinkedHashSet(elementSet.size)) { element -> + return elementSet.filterTo(LinkedHashSet(elementSet.size)) { element -> element.parents.none { it in elementSet } } } @@ -223,7 +211,7 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT private data class ElementToAnalyze(val element: TElement, val level: Int) private abstract class CollectElementsVisitor( - protected val elementFilter: (PsiElement) -> FilterResult + protected val elementFilter: (PsiElement) -> FilterResult ) : KtVisitorVoid() { var options: Options = Options.DEFAULT @@ -258,8 +246,8 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT } private abstract class ShorteningProcessor( - protected val file: KtFile, - protected val failedToImportDescriptors: Set + protected val file: KtFile, + protected val failedToImportDescriptors: Set ) { protected val resolutionFacade = file.getResolutionFacade() private val elementsToShorten = ArrayList>() @@ -278,25 +266,24 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT val toBeShortened: Boolean when (result) { - is AnalyzeQualifiedElementResult.ShortenNow -> { + AnalyzeQualifiedElementResult.ShortenNow -> { elementsToShorten.add(element.createSmartPointer()) toBeShortened = true } is AnalyzeQualifiedElementResult.ImportDescriptors -> { val tryImport = result.descriptors.isNotEmpty() - && result.descriptors.none { it in failedToImportDescriptors } - && result.descriptors.all { mayImport(it, file) } + && result.descriptors.none { it in failedToImportDescriptors } + && result.descriptors.all { mayImport(it, file) } toBeShortened = if (tryImport) { descriptorsToImport.addAll(result.descriptors) true - } - else { + } else { false } } - is AnalyzeQualifiedElementResult.Skip -> { + AnalyzeQualifiedElementResult.Skip -> { toBeShortened = false } } @@ -347,36 +334,36 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT } private class ShortenTypesProcessor( - file: KtFile, - elementFilter: (PsiElement) -> FilterResult, - failedToImportDescriptors: Set + file: KtFile, + elementFilter: (PsiElement) -> FilterResult, + failedToImportDescriptors: Set ) : ShorteningProcessor(file, failedToImportDescriptors) { override val collectElementsVisitor: CollectElementsVisitor = - object : CollectElementsVisitor(elementFilter) { - override fun visitUserType(userType: KtUserType) { - val filterResult = elementFilter(userType) - if (filterResult == FilterResult.SKIP) return + object : CollectElementsVisitor(elementFilter) { + override fun visitUserType(userType: KtUserType) { + val filterResult = elementFilter(userType) + if (filterResult == FilterResult.SKIP) return - userType.typeArgumentList?.accept(this) + userType.typeArgumentList?.accept(this) - if (filterResult == FilterResult.PROCESS) { - addQualifiedElementToAnalyze(userType) - } - - // elements in qualifier must be under - nextLevel() - userType.qualifier?.accept(this) - prevLevel() + if (filterResult == FilterResult.PROCESS) { + addQualifiedElementToAnalyze(userType) } + + // elements in qualifier must be under + nextLevel() + userType.qualifier?.accept(this) + prevLevel() } + } override fun analyzeQualifiedElement(element: KtUserType, bindingContext: BindingContext): AnalyzeQualifiedElementResult { if (element.qualifier == null) return AnalyzeQualifiedElementResult.Skip val referenceExpression = element.referenceExpression ?: return AnalyzeQualifiedElementResult.Skip val target = referenceExpression.targets(bindingContext).singleOrNull() - ?: return AnalyzeQualifiedElementResult.Skip + ?: return AnalyzeQualifiedElementResult.Skip val scope = element.getResolutionScope(bindingContext, resolutionFacade) val name = target.name @@ -386,7 +373,9 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT scope.findPackage(name) val canShortenNow = targetByName?.asString() == target.asString() - return if (canShortenNow) AnalyzeQualifiedElementResult.ShortenNow else AnalyzeQualifiedElementResult.ImportDescriptors(listOfNotNull(target)) + return if (canShortenNow) AnalyzeQualifiedElementResult.ShortenNow else AnalyzeQualifiedElementResult.ImportDescriptors( + listOfNotNull(target) + ) } override fun shortenElement(element: KtUserType): KtElement { @@ -396,12 +385,13 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT } private abstract class QualifiedExpressionShorteningProcessor( - file: KtFile, - elementFilter: (PsiElement) -> FilterResult, - failedToImportDescriptors: Set + file: KtFile, + elementFilter: (PsiElement) -> FilterResult, + failedToImportDescriptors: Set ) : ShorteningProcessor(file, failedToImportDescriptors) { - protected open class MyVisitor(elementFilter: (PsiElement) -> FilterResult) : CollectElementsVisitor(elementFilter) { + protected open class MyVisitor(elementFilter: (PsiElement) -> FilterResult) : + CollectElementsVisitor(elementFilter) { override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression) { val filterResult = elementFilter(expression) if (filterResult == FilterResult.SKIP) return @@ -423,9 +413,9 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT } private class ShortenQualifiedExpressionsProcessor( - file: KtFile, - elementFilter: (PsiElement) -> FilterResult, - failedToImportDescriptors: Set + file: KtFile, + elementFilter: (PsiElement) -> FilterResult, + failedToImportDescriptors: Set ) : QualifiedExpressionShorteningProcessor(file, elementFilter, failedToImportDescriptors) { override val collectElementsVisitor = object : MyVisitor(elementFilter) { @@ -435,13 +425,17 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT } } - override fun analyzeQualifiedElement(element: KtDotQualifiedExpression, bindingContext: BindingContext): AnalyzeQualifiedElementResult { + override fun analyzeQualifiedElement( + element: KtDotQualifiedExpression, + bindingContext: BindingContext + ): AnalyzeQualifiedElementResult { val receiver = element.receiverExpression if (receiver !is KtThisExpression && bindingContext[BindingContext.QUALIFIER, receiver] == null) return AnalyzeQualifiedElementResult.Skip if (PsiTreeUtil.getParentOfType( element, - KtImportDirective::class.java, KtPackageDirective::class.java) != null) return AnalyzeQualifiedElementResult.Skip + KtImportDirective::class.java, KtPackageDirective::class.java + ) != null) return AnalyzeQualifiedElementResult.Skip val selector = element.selectorExpression ?: return AnalyzeQualifiedElementResult.Skip val callee = selector.getCalleeExpressionIfAny() as? KtReferenceExpression ?: return AnalyzeQualifiedElementResult.Skip @@ -459,9 +453,9 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT val resolvedCallWhenShort = newCallee.getResolvedCall(newContext) val targetsMatch = targetsMatch(targets, targetsWhenShort) && - (resolvedCall !is VariableAsFunctionResolvedCall || ( - resolvedCallWhenShort is VariableAsFunctionResolvedCall? && - resolvedCallsMatch(resolvedCall, resolvedCallWhenShort))) + (resolvedCall !is VariableAsFunctionResolvedCall || ( + resolvedCallWhenShort is VariableAsFunctionResolvedCall? && + resolvedCallsMatch(resolvedCall, resolvedCallWhenShort))) // If before and after shorten call can be resolved unambiguously, then preform comparing of such calls, @@ -474,16 +468,17 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT // TODO: Add possibility to check if descriptor from completion can't be resolved after shorten and not preform shorten than val resolvedCallsMatch = if (resolvedCall != null && resolvedCallWhenShort != null) { resolvedCall.resultingDescriptor.original == resolvedCallWhenShort.resultingDescriptor.original - } - else { + } else { val resolvedCalls = selector.getCall(bindingContext)?.resolveCandidates(bindingContext, resolutionFacade) ?: emptyList() val callWhenShort = selectorAfterShortening.getCall(newContext) - val resolvedCallsWhenShort = selectorAfterShortening.getCall(newContext)?.resolveCandidates(newContext, resolutionFacade) ?: emptyList() + val resolvedCallsWhenShort = + selectorAfterShortening.getCall(newContext)?.resolveCandidates(newContext, resolutionFacade) ?: emptyList() val descriptorsOfResolvedCallsWhenShort = resolvedCallsWhenShort.map { it.resultingDescriptor.original } val descriptorsOfResolvedCalls = resolvedCalls.mapTo(mutableSetOf()) { it.resultingDescriptor.original } - val filter = ShadowedDeclarationsFilter(newContext, resolutionFacade, newCallee, callWhenShort?.explicitReceiver as? ReceiverValue) + val filter = + ShadowedDeclarationsFilter(newContext, resolutionFacade, newCallee, callWhenShort?.explicitReceiver as? ReceiverValue) val availableDescriptorsWhenShort = filter.filter(descriptorsOfResolvedCallsWhenShort) availableDescriptorsWhenShort.any { it in descriptorsOfResolvedCalls } @@ -496,10 +491,10 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT val newCall = selectorAfterShortening.getResolvedCall(newContext) ?: return AnalyzeQualifiedElementResult.Skip val receiverKind = originalCall.explicitReceiverKind val newReceiver = when (receiverKind) { - ExplicitReceiverKind.BOTH_RECEIVERS, ExplicitReceiverKind.EXTENSION_RECEIVER -> newCall.extensionReceiver - ExplicitReceiverKind.DISPATCH_RECEIVER -> newCall.dispatchReceiver - else -> return AnalyzeQualifiedElementResult.Skip - } as? ImplicitReceiver ?: return AnalyzeQualifiedElementResult.Skip + ExplicitReceiverKind.BOTH_RECEIVERS, ExplicitReceiverKind.EXTENSION_RECEIVER -> newCall.extensionReceiver + ExplicitReceiverKind.DISPATCH_RECEIVER -> newCall.dispatchReceiver + else -> return AnalyzeQualifiedElementResult.Skip + } as? ImplicitReceiver ?: return AnalyzeQualifiedElementResult.Skip val thisTarget = receiver.instanceReference.targets(bindingContext).singleOrNull() if (newReceiver.declarationDescriptor.asString() != thisTarget?.asString()) return AnalyzeQualifiedElementResult.Skip @@ -516,7 +511,10 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT } } - private fun copyShortenAndAnalyze(element: KtDotQualifiedExpression, bindingContext: BindingContext): Pair { + private fun copyShortenAndAnalyze( + element: KtDotQualifiedExpression, + bindingContext: BindingContext + ): Pair { val selector = element.selectorExpression!! // selector V V selector V V @@ -529,7 +527,8 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT if (doubleColonExpression != null && doubleColonExpression.receiverExpression == element) { val doubleColonExpressionCopy = doubleColonExpression.copied() doubleColonExpressionCopy.receiverExpression!!.replace(selector) - val newBindingContext = doubleColonExpressionCopy.analyzeAsReplacement(doubleColonExpression, bindingContext, resolutionFacade) + val newBindingContext = + doubleColonExpressionCopy.analyzeAsReplacement(doubleColonExpression, bindingContext, resolutionFacade) return newBindingContext to doubleColonExpressionCopy.receiverExpression!! } @@ -550,15 +549,14 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT if (targets1.size != targets2.size) return false return if (targets1.size == 1) { targets1.single().asString() == targets2.single().asString() - } - else { + } else { targets1.map { it.asString() }.toSet() == targets2.map { it.asString() }.toSet() } } private fun resolvedCallsMatch(rc1: VariableAsFunctionResolvedCall?, rc2: VariableAsFunctionResolvedCall?): Boolean { return rc1?.variableCall?.candidateDescriptor?.asString() == rc2?.variableCall?.candidateDescriptor?.asString() && - rc1?.functionCall?.candidateDescriptor?.asString() == rc2?.functionCall?.candidateDescriptor?.asString() + rc1?.functionCall?.candidateDescriptor?.asString() == rc2?.functionCall?.candidateDescriptor?.asString() } override fun shortenElement(element: KtDotQualifiedExpression): KtElement { @@ -571,21 +569,21 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT } private class ShortenThisExpressionsProcessor( - file: KtFile, - elementFilter: (PsiElement) -> FilterResult, - failedToImportDescriptors: Set + file: KtFile, + elementFilter: (PsiElement) -> FilterResult, + failedToImportDescriptors: Set ) : ShorteningProcessor(file, failedToImportDescriptors) { private val simpleThis = KtPsiFactory(file).createExpression("this") as KtThisExpression override val collectElementsVisitor: CollectElementsVisitor = - object : CollectElementsVisitor(elementFilter) { - override fun visitThisExpression(expression: KtThisExpression) { - if (options.removeThisLabels && elementFilter(expression) == FilterResult.PROCESS && expression.getTargetLabel() != null) { - addQualifiedElementToAnalyze(expression) - } + object : CollectElementsVisitor(elementFilter) { + override fun visitThisExpression(expression: KtThisExpression) { + if (options.removeThisLabels && elementFilter(expression) == FilterResult.PROCESS && expression.getTargetLabel() != null) { + addQualifiedElementToAnalyze(expression) } } + } override fun analyzeQualifiedElement(element: KtThisExpression, bindingContext: BindingContext): AnalyzeQualifiedElementResult { val targetBefore = element.instanceReference.targets(bindingContext).singleOrNull() ?: return AnalyzeQualifiedElementResult.Skip @@ -600,16 +598,19 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT } private class RemoveExplicitCompanionObjectReferenceProcessor( - file: KtFile, - elementFilter: (PsiElement) -> FilterResult, - failedToImportDescriptors: Set + file: KtFile, + elementFilter: (PsiElement) -> FilterResult, + failedToImportDescriptors: Set ) : QualifiedExpressionShorteningProcessor(file, elementFilter, failedToImportDescriptors) { private fun KtExpression.singleTarget(context: BindingContext): DeclarationDescriptor? { return (getCalleeExpressionIfAny() as? KtReferenceExpression)?.targets(context)?.singleOrNull() } - override fun analyzeQualifiedElement(element: KtDotQualifiedExpression, bindingContext: BindingContext): AnalyzeQualifiedElementResult { + override fun analyzeQualifiedElement( + element: KtDotQualifiedExpression, + bindingContext: BindingContext + ): AnalyzeQualifiedElementResult { val parent = element.parent // TODO: Delete this code when KT-13934 is fixed if (parent is KtCallableReferenceExpression && parent.receiverExpression == element) return AnalyzeQualifiedElementResult.Skip @@ -618,7 +619,8 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT if (PsiTreeUtil.getParentOfType( element, - KtImportDirective::class.java, KtPackageDirective::class.java) != null) return AnalyzeQualifiedElementResult.Skip + KtImportDirective::class.java, KtPackageDirective::class.java + ) != null) return AnalyzeQualifiedElementResult.Skip val receiverTarget = receiver.singleTarget(bindingContext) as? ClassDescriptor ?: return AnalyzeQualifiedElementResult.Skip @@ -628,14 +630,17 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT if (receiverTarget.companionObjectDescriptor != selectorTarget) return AnalyzeQualifiedElementResult.Skip val selectorsSelector = (parent as? KtDotQualifiedExpression)?.selectorExpression - ?: return AnalyzeQualifiedElementResult.ShortenNow + ?: return AnalyzeQualifiedElementResult.ShortenNow val selectorsSelectorTarget = selectorsSelector.singleTarget(bindingContext) ?: return AnalyzeQualifiedElementResult.Skip if (selectorsSelectorTarget is ClassDescriptor) return AnalyzeQualifiedElementResult.Skip // TODO: More generic solution may be possible if (selectorsSelectorTarget is PropertyDescriptor) { val source = selectorsSelectorTarget.source.getPsi() as? KtProperty - if (source != null && isEnumCompanionPropertyWithEntryConflict(source, source.name ?: "")) return AnalyzeQualifiedElementResult.Skip + if (source != null && isEnumCompanionPropertyWithEntryConflict( + source, + source.name ?: "" + )) return AnalyzeQualifiedElementResult.Skip } return AnalyzeQualifiedElementResult.ShortenNow