Refactoring: extract common function (some usages were slightly changed)

This commit is contained in:
Nikolay Krasko
2017-03-20 22:21:30 +03:00
parent ccfa42289c
commit c976c3d909
7 changed files with 19 additions and 23 deletions
@@ -156,6 +156,11 @@ val KtElement.mainReference: KtReference?
} }
} }
fun KtElement.resolveMainReferenceToDescriptors(): Collection<DeclarationDescriptor> {
val bindingContext = analyze(BodyResolveMode.PARTIAL)
return mainReference?.resolveToDescriptors(bindingContext) ?: emptyList()
}
// ----------- Read/write access ----------------------------------------------------------------------------------------------------------------------- // ----------- Read/write access -----------------------------------------------------------------------------------------------------------------------
enum class ReferenceAccess(val isRead: Boolean, val isWrite: Boolean) { enum class ReferenceAccess(val isRead: Boolean, val isWrite: Boolean) {
@@ -20,16 +20,14 @@ import com.intellij.codeInsight.completion.PrefixMatcher
import com.intellij.codeInsight.lookup.LookupElementBuilder import com.intellij.codeInsight.lookup.LookupElementBuilder
import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.progress.ProgressManager
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.highlighter.KotlinPsiChecker import org.jetbrains.kotlin.idea.highlighter.KotlinPsiChecker
import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtNameReferenceExpression import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import java.util.* import java.util.*
class FromUnresolvedNamesCompletion( class FromUnresolvedNamesCompletion(
@@ -64,7 +62,7 @@ class FromUnresolvedNamesCompletion(
if (afterOffset != null && refExpr.startOffset < afterOffset) return@forEachDescendantOfType if (afterOffset != null && refExpr.startOffset < afterOffset) return@forEachDescendantOfType
if (refExpr.mainReference.resolveToDescriptors(refExpr.analyze(BodyResolveMode.PARTIAL)).isEmpty()) { if (refExpr.resolveMainReferenceToDescriptors().isEmpty()) {
names.add(name) names.add(name)
} }
} }
@@ -49,7 +49,6 @@ import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.asJava.toLightMethods import org.jetbrains.kotlin.asJava.toLightMethods
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.core.toDescriptor import org.jetbrains.kotlin.idea.core.toDescriptor
@@ -58,6 +57,7 @@ import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindClassUsagesHandle
import org.jetbrains.kotlin.idea.highlighter.markers.hasImplementationsOf import org.jetbrains.kotlin.idea.highlighter.markers.hasImplementationsOf
import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
import org.jetbrains.kotlin.idea.search.usagesSearch.dataClassComponentFunction import org.jetbrains.kotlin.idea.search.usagesSearch.dataClassComponentFunction
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
import org.jetbrains.kotlin.idea.search.usagesSearch.getAccessorNames import org.jetbrains.kotlin.idea.search.usagesSearch.getAccessorNames
@@ -67,7 +67,6 @@ import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.util.findCallableMemberBySignature import org.jetbrains.kotlin.util.findCallableMemberBySignature
import java.awt.GridBagConstraints import java.awt.GridBagConstraints
import java.awt.GridBagLayout import java.awt.GridBagLayout
@@ -351,8 +350,7 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
for (annotationEntry in declaration.annotationEntries) { for (annotationEntry in declaration.annotationEntries) {
val typeElement = annotationEntry.typeReference?.typeElement as? KtUserType ?: continue val typeElement = annotationEntry.typeReference?.typeElement as? KtUserType ?: continue
val bindingContext = annotationEntry.analyze(BodyResolveMode.PARTIAL) val target = typeElement.referenceExpression?.resolveMainReferenceToDescriptors()?.singleOrNull() ?: continue
val target = typeElement.referenceExpression?.mainReference?.resolveToDescriptors(bindingContext)?.singleOrNull() ?: continue
val fqName = target.importableFqName?.asString() ?: continue val fqName = target.importableFqName?.asString() ?: continue
// checks taken from com.intellij.codeInspection.util.SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes // checks taken from com.intellij.codeInspection.util.SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.idea.core.ShortenReferences
import org.jetbrains.kotlin.idea.imports.canBeReferencedViaImport import org.jetbrains.kotlin.idea.imports.canBeReferencedViaImport
import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
import org.jetbrains.kotlin.idea.util.ImportDescriptorResult import org.jetbrains.kotlin.idea.util.ImportDescriptorResult
import org.jetbrains.kotlin.idea.util.ImportInsertHelper import org.jetbrains.kotlin.idea.util.ImportInsertHelper
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -58,8 +59,9 @@ class ImportMemberIntention : SelfTargetingOffsetIndependentIntention<KtNameRefe
// If expression is fqn reference, take full qualified selector, otherwise (Type reference) take element // If expression is fqn reference, take full qualified selector, otherwise (Type reference) take element
val targetElement = qualifiedElement?.selectorExpression?.getQualifiedElementSelector() ?: element val targetElement = qualifiedElement?.selectorExpression?.getQualifiedElementSelector() ?: element
val bindingContext = targetElement.analyze(BodyResolveMode.PARTIAL) val targets = targetElement.resolveMainReferenceToDescriptors()
val targets = targetElement.mainReference?.resolveToDescriptors(bindingContext) ?: return if (targets.isEmpty()) return
val fqName = targets.map { it.importableFqName!! }.single() val fqName = targets.map { it.importableFqName!! }.single()
val file = targetElement.containingKtFile val file = targetElement.containingKtFile
@@ -26,8 +26,7 @@ import com.intellij.refactoring.rename.RenameProcessor
import com.intellij.usageView.UsageInfo import com.intellij.usageView.UsageInfo
import org.jetbrains.kotlin.descriptors.ParameterDescriptor import org.jetbrains.kotlin.descriptors.ParameterDescriptor
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.psi.KtFunctionLiteral import org.jetbrains.kotlin.psi.KtFunctionLiteral
import org.jetbrains.kotlin.psi.KtNameReferenceExpression import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.psi.KtSimpleNameExpression import org.jetbrains.kotlin.psi.KtSimpleNameExpression
@@ -35,7 +34,6 @@ import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class ReplaceExplicitFunctionLiteralParamWithItIntention : PsiElementBaseIntentionAction() { class ReplaceExplicitFunctionLiteralParamWithItIntention : PsiElementBaseIntentionAction() {
override fun getFamilyName() = "Replace explicit lambda parameter with 'it'" override fun getFamilyName() = "Replace explicit lambda parameter with 'it'"
@@ -72,8 +70,7 @@ class ReplaceExplicitFunctionLiteralParamWithItIntention : PsiElementBaseIntenti
private fun targetFunctionLiteral(element: PsiElement, caretOffset: Int): KtFunctionLiteral? { private fun targetFunctionLiteral(element: PsiElement, caretOffset: Int): KtFunctionLiteral? {
val expression = element.getParentOfType<KtNameReferenceExpression>(true) val expression = element.getParentOfType<KtNameReferenceExpression>(true)
if (expression != null) { if (expression != null) {
val target = expression.mainReference.resolveToDescriptors(expression.analyze(BodyResolveMode.PARTIAL)) val target = expression.resolveMainReferenceToDescriptors().singleOrNull() as? ParameterDescriptor ?: return null
.singleOrNull() as? ParameterDescriptor ?: return null
val functionDescriptor = target.containingDeclaration as? AnonymousFunctionDescriptor ?: return null val functionDescriptor = target.containingDeclaration as? AnonymousFunctionDescriptor ?: return null
return DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor) as? KtFunctionLiteral return DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor) as? KtFunctionLiteral
} }
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.core.resolveCandidates import org.jetbrains.kotlin.idea.core.resolveCandidates
import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.allChildren import org.jetbrains.kotlin.psi.psiUtil.allChildren
@@ -45,8 +45,7 @@ class KotlinClassTypeArgumentInfoHandler : KotlinTypeArgumentInfoHandlerBase<Cla
override fun findParameterOwners(argumentList: KtTypeArgumentList): Collection<ClassDescriptor>? { override fun findParameterOwners(argumentList: KtTypeArgumentList): Collection<ClassDescriptor>? {
val userType = argumentList.parent as? KtUserType ?: return null val userType = argumentList.parent as? KtUserType ?: return null
val bindingContext = argumentList.analyze(BodyResolveMode.PARTIAL) return userType.referenceExpression?.resolveMainReferenceToDescriptors()?.mapNotNull { it as? ClassDescriptor }
return userType.referenceExpression?.mainReference?.resolveToDescriptors(bindingContext)?.mapNotNull { it as? ClassDescriptor }
} }
override fun getArgumentListAllowedParentClasses() = setOf(KtUserType::class.java) override fun getArgumentListAllowedParentClasses() = setOf(KtUserType::class.java)
@@ -23,19 +23,17 @@ import com.intellij.refactoring.rename.ResolveSnapshotProvider
import com.intellij.util.containers.HashMap import com.intellij.util.containers.HashMap
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.ShortenReferences import org.jetbrains.kotlin.idea.core.ShortenReferences
import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.refactoring.explicateAsTextForReceiver import org.jetbrains.kotlin.idea.refactoring.explicateAsTextForReceiver
import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtPsiFactory import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.KtSimpleNameExpression import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.jetbrains.kotlin.psi.KtTreeVisitorVoid import org.jetbrains.kotlin.psi.KtTreeVisitorVoid
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import java.util.* import java.util.*
class KotlinResolveSnapshotProvider : ResolveSnapshotProvider() { class KotlinResolveSnapshotProvider : ResolveSnapshotProvider() {
@@ -49,8 +47,7 @@ class KotlinResolveSnapshotProvider : ResolveSnapshotProvider() {
object: KtTreeVisitorVoid() { object: KtTreeVisitorVoid() {
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) { override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
if (expression.getQualifiedExpressionForSelector() != null) return super.visitSimpleNameExpression(expression) if (expression.getQualifiedExpressionForSelector() != null) return super.visitSimpleNameExpression(expression)
val context = expression.analyze(BodyResolveMode.PARTIAL) val targetDescriptor = expression.resolveMainReferenceToDescriptors().singleOrNull() ?: return
val targetDescriptor = expression.mainReference.resolveToDescriptors(context).singleOrNull() ?: return
if (targetDescriptor !is PropertyDescriptor) return if (targetDescriptor !is PropertyDescriptor) return
refExpressionToDescriptor[expression.createSmartPointer()] = targetDescriptor refExpressionToDescriptor[expression.createSmartPointer()] = targetDescriptor
} }