diff --git a/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/BaseKotlinUastResolveProviderService.kt b/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/BaseKotlinUastResolveProviderService.kt index 7503743aa24..fa60f07fea8 100644 --- a/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/BaseKotlinUastResolveProviderService.kt +++ b/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/BaseKotlinUastResolveProviderService.kt @@ -19,6 +19,8 @@ interface BaseKotlinUastResolveProviderService { fun convertParent(uElement: UElement): UElement? + fun getReferenceVariants(ktExpression: KtExpression, nameHint: String): Sequence + fun resolveToDeclaration(ktExpression: KtExpression): PsiElement? fun resolveToType(ktTypeReference: KtTypeReference, source: UElement): PsiType? diff --git a/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/internal/multiResolveUtils.kt b/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/internal/multiResolveUtils.kt new file mode 100644 index 00000000000..45a4bbc5514 --- /dev/null +++ b/plugins/uast-kotlin-base/src/org/jetbrains/uast/kotlin/internal/multiResolveUtils.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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.uast.kotlin.internal + +import com.intellij.psi.PsiSubstitutor +import com.intellij.psi.ResolveResult +import com.intellij.psi.infos.CandidateInfo +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.uast.kotlin.BaseKotlinUastResolveProviderService + +fun getResolveResultVariants( + baseKotlinUastResolveProviderService: BaseKotlinUastResolveProviderService, + ktExpression: KtExpression? +): Iterable { + ktExpression ?: return emptyList() + + val referenceVariants = baseKotlinUastResolveProviderService.getReferenceVariants(ktExpression, ktExpression.name ?: ktExpression.text) + + return referenceVariants.mapNotNull { CandidateInfo(it, PsiSubstitutor.EMPTY) }.asIterable() +} + diff --git a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/internal/FirCliKotlinUastResolveProviderService.kt b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/internal/FirCliKotlinUastResolveProviderService.kt index 36cb0b1b891..593618fe6c3 100644 --- a/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/internal/FirCliKotlinUastResolveProviderService.kt +++ b/plugins/uast-kotlin-fir/src/org/jetbrains/uast/kotlin/internal/FirCliKotlinUastResolveProviderService.kt @@ -6,9 +6,14 @@ package org.jetbrains.uast.kotlin.internal import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.uast.kotlin.FirKotlinUastResolveProviderService class FirCliKotlinUastResolveProviderService : FirKotlinUastResolveProviderService { // Currently, UAST CLI is used by Android Lint, i.e., everything is a JVM element. override fun isJvmElement(psiElement: PsiElement): Boolean = true + + override fun getReferenceVariants(ktExpression: KtExpression, nameHint: String): Sequence { + return emptySequence() // Not supported (as per the counterpart [CliKotlinUastResolveProviderService]) + } } diff --git a/plugins/uast-kotlin-idea-fir/src/org/jetbrains/uast/kotlin/internal/FirIdeaKotlinUastResolveProviderService.kt b/plugins/uast-kotlin-idea-fir/src/org/jetbrains/uast/kotlin/internal/FirIdeaKotlinUastResolveProviderService.kt index 8e688d0b913..c3fc5a8057f 100644 --- a/plugins/uast-kotlin-idea-fir/src/org/jetbrains/uast/kotlin/internal/FirIdeaKotlinUastResolveProviderService.kt +++ b/plugins/uast-kotlin-idea-fir/src/org/jetbrains/uast/kotlin/internal/FirIdeaKotlinUastResolveProviderService.kt @@ -6,8 +6,13 @@ package org.jetbrains.uast.kotlin.internal import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.uast.kotlin.FirKotlinUastResolveProviderService class FirIdeaKotlinUastResolveProviderService : FirKotlinUastResolveProviderService { override fun isJvmElement(psiElement: PsiElement): Boolean = psiElement.isJvmElement + + override fun getReferenceVariants(ktExpression: KtExpression, nameHint: String): Sequence { + TODO("Not yet implemented") + } } diff --git a/plugins/uast-kotlin-idea/src/org/jetbrains/uast/kotlin/internal/IdeaKotlinUastResolveProviderService.kt b/plugins/uast-kotlin-idea/src/org/jetbrains/uast/kotlin/internal/IdeaKotlinUastResolveProviderService.kt index 84e9c09ca45..d79cc53acac 100644 --- a/plugins/uast-kotlin-idea/src/org/jetbrains/uast/kotlin/internal/IdeaKotlinUastResolveProviderService.kt +++ b/plugins/uast-kotlin-idea/src/org/jetbrains/uast/kotlin/internal/IdeaKotlinUastResolveProviderService.kt @@ -9,16 +9,17 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.codegen.ClassBuilderMode import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.config.LanguageVersionSettings -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.core.resolveCandidates import org.jetbrains.kotlin.idea.project.languageVersionSettings import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.resolve.calls.callUtil.getCall import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.uast.kotlin.KotlinUastResolveProviderService +import org.jetbrains.uast.kotlin.resolveToDeclarationImpl class IdeaKotlinUastResolveProviderService : KotlinUastResolveProviderService { override fun getBindingContext(element: KtElement) = element.analyze(BodyResolveMode.PARTIAL_WITH_CFA) @@ -37,10 +38,12 @@ class IdeaKotlinUastResolveProviderService : KotlinUastResolveProviderService { return element.languageVersionSettings } - override fun getReferenceVariants(ktElement: KtElement, nameHint: String): Sequence { - val resolutionFacade = ktElement.getResolutionFacade() - val bindingContext = ktElement.analyze() - val call = ktElement.getCall(bindingContext) ?: return emptySequence() - return call.resolveCandidates(bindingContext, resolutionFacade).map { it.candidateDescriptor }.asSequence() + override fun getReferenceVariants(ktExpression: KtExpression, nameHint: String): Sequence { + val resolutionFacade = ktExpression.getResolutionFacade() + val bindingContext = ktExpression.analyze() + val call = ktExpression.getCall(bindingContext) ?: return emptySequence() + return call.resolveCandidates(bindingContext, resolutionFacade) + .mapNotNull { resolveToDeclarationImpl(ktExpression, it.candidateDescriptor) } + .asSequence() } } diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastResolveProviderService.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastResolveProviderService.kt index cc93c6046af..7cb2907bdf8 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastResolveProviderService.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/KotlinUastResolveProviderService.kt @@ -9,7 +9,6 @@ import com.intellij.psi.PsiElement import com.intellij.psi.PsiType import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.config.LanguageVersionSettings -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtTypeReference @@ -23,7 +22,6 @@ interface KotlinUastResolveProviderService : BaseKotlinUastResolveProviderServic fun getBindingContext(element: KtElement): BindingContext fun getTypeMapper(element: KtElement): KotlinTypeMapper? fun getLanguageVersionSettings(element: KtElement): LanguageVersionSettings - fun getReferenceVariants(ktElement: KtElement, nameHint: String): Sequence override val baseKotlinConverter: BaseKotlinConverter get() = KotlinConverter diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUCallableReferenceExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUCallableReferenceExpression.kt index 9fe7deb097c..177f3f3d823 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUCallableReferenceExpression.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUCallableReferenceExpression.kt @@ -25,8 +25,8 @@ import org.jetbrains.uast.* import org.jetbrains.uast.kotlin.internal.getResolveResultVariants class KotlinUCallableReferenceExpression( - override val sourcePsi: KtCallableReferenceExpression, - givenParent: UElement? + override val sourcePsi: KtCallableReferenceExpression, + givenParent: UElement? ) : KotlinAbstractUExpression(givenParent), UCallableReferenceExpression, UMultiResolvable, KotlinUElementWithType { override val qualifierExpression: UExpression? get() { @@ -48,6 +48,7 @@ class KotlinUCallableReferenceExpression( override fun resolve(): PsiElement? = baseResolveProviderService.resolveToDeclaration(sourcePsi.callableReference) - override fun multiResolve(): Iterable = getResolveResultVariants(sourcePsi.callableReference) + override fun multiResolve(): Iterable = + getResolveResultVariants(baseResolveProviderService, sourcePsi.callableReference) } diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUFunctionCallExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUFunctionCallExpression.kt index c055f7fa308..e3782e7bfc8 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUFunctionCallExpression.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUFunctionCallExpression.kt @@ -29,7 +29,6 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.uast.* import org.jetbrains.uast.internal.acceptList import org.jetbrains.uast.kotlin.internal.TypedResolveResult -import org.jetbrains.uast.kotlin.internal.getReferenceVariants import org.jetbrains.uast.visitor.UastVisitor class KotlinUFunctionCallExpression( @@ -164,7 +163,7 @@ class KotlinUFunctionCallExpression( val contextElement = sourcePsi val calleeExpression = contextElement.calleeExpression as? KtReferenceExpression ?: return emptyList() val methodName = methodName ?: calleeExpression.text ?: return emptyList() - val variants = getReferenceVariants(calleeExpression, methodName) + val variants = baseResolveProviderService.getReferenceVariants(calleeExpression, methodName) return variants.flatMap { when (it) { is PsiClass -> it.constructors.asSequence() diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSafeQualifiedExpression.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSafeQualifiedExpression.kt index 0361e799ed6..dbf6d187634 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSafeQualifiedExpression.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/expressions/KotlinUSafeQualifiedExpression.kt @@ -26,10 +26,10 @@ import org.jetbrains.uast.UQualifiedReferenceExpression import org.jetbrains.uast.kotlin.internal.getResolveResultVariants class KotlinUSafeQualifiedExpression( - override val sourcePsi: KtSafeQualifiedExpression, - givenParent: UElement? + override val sourcePsi: KtSafeQualifiedExpression, + givenParent: UElement? ) : KotlinAbstractUExpression(givenParent), UQualifiedReferenceExpression, UMultiResolvable, - KotlinUElementWithType, KotlinEvaluatableUElement { + KotlinUElementWithType, KotlinEvaluatableUElement { override val receiver by lz { KotlinConverter.convertOrEmpty(sourcePsi.receiverExpression, this) } override val selector by lz { KotlinConverter.convertOrEmpty(sourcePsi.selectorExpression, this) } override val accessType = KotlinQualifiedExpressionAccessTypes.SAFE @@ -38,5 +38,7 @@ class KotlinUSafeQualifiedExpression( get() = (resolve() as? PsiNamedElement)?.name override fun resolve(): PsiElement? = sourcePsi.selectorExpression?.let { baseResolveProviderService.resolveToDeclaration(it) } - override fun multiResolve(): Iterable = getResolveResultVariants(sourcePsi.selectorExpression) + + override fun multiResolve(): Iterable = + getResolveResultVariants(baseResolveProviderService, sourcePsi.selectorExpression) } diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/CliKotlinUastResolveProviderService.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/CliKotlinUastResolveProviderService.kt index c05512eb069..3a359812b99 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/CliKotlinUastResolveProviderService.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/CliKotlinUastResolveProviderService.kt @@ -10,10 +10,10 @@ import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl import org.jetbrains.kotlin.container.ComponentProvider import org.jetbrains.kotlin.container.get import org.jetbrains.kotlin.context.ProjectContext -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingTrace @@ -40,7 +40,7 @@ class CliKotlinUastResolveProviderService : KotlinUastResolveProviderService { return element.project.analysisCompletedHandler?.getLanguageVersionSettings() ?: LanguageVersionSettingsImpl.DEFAULT } - override fun getReferenceVariants(ktElement: KtElement, nameHint: String): Sequence = + override fun getReferenceVariants(ktExpression: KtExpression, nameHint: String): Sequence = emptySequence() // Not supported } diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/kotlinInternalUastUtils.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/kotlinInternalUastUtils.kt index 356854e980a..a639eaeaefb 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/kotlinInternalUastUtils.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/kotlinInternalUastUtils.kt @@ -308,7 +308,7 @@ internal fun resolveToDeclarationImpl(sourcePsi: KtExpression): PsiElement? = ?.let { descriptor -> resolveToDeclarationImpl(sourcePsi, descriptor) } } -internal fun resolveToDeclarationImpl(sourcePsi: KtExpression, declarationDescriptor: DeclarationDescriptor): PsiElement? { +fun resolveToDeclarationImpl(sourcePsi: KtExpression, declarationDescriptor: DeclarationDescriptor): PsiElement? { declarationDescriptor.toSource()?.getMaybeLightElement(sourcePsi)?.let { return it } var declarationDescriptor = declarationDescriptor diff --git a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/kotlinUastMultiresolve.kt b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/kotlinUastMultiresolve.kt index c1aa747378c..0eebacae823 100644 --- a/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/kotlinUastMultiresolve.kt +++ b/plugins/uast-kotlin/src/org/jetbrains/uast/kotlin/internal/kotlinUastMultiresolve.kt @@ -5,31 +5,12 @@ package org.jetbrains.uast.kotlin.internal -import com.intellij.openapi.components.ServiceManager import com.intellij.psi.PsiElement import com.intellij.psi.PsiPolyVariantReference import com.intellij.psi.PsiSubstitutor import com.intellij.psi.ResolveResult import com.intellij.psi.infos.CandidateInfo import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.psi.KtExpression -import org.jetbrains.uast.kotlin.KotlinUastResolveProviderService -import org.jetbrains.uast.kotlin.resolveToDeclarationImpl - - -internal fun getReferenceVariants(ktElement: KtExpression, nameHint: String): Sequence = - ServiceManager.getService(ktElement.project, KotlinUastResolveProviderService::class.java) - .getReferenceVariants(ktElement, nameHint) - .mapNotNull { resolveToDeclarationImpl(ktElement, it) } - -internal fun getResolveResultVariants(ktExpression: KtExpression?): Iterable { - ktExpression ?: return emptyList() - - val referenceVariants = getReferenceVariants(ktExpression, ktExpression.name ?: ktExpression.text) - - return referenceVariants.mapNotNull {CandidateInfo(it, PsiSubstitutor.EMPTY) }.asIterable() -} - internal fun KtElement.multiResolveResults(): Sequence = references.asSequence().flatMap { ref -> @@ -43,4 +24,3 @@ class TypedResolveResult(element: T) : CandidateInfo(element, Ps @Suppress("UNCHECKED_CAST") override fun getElement(): T = super.getElement() as T } -