FIR/UAST: move multi resolve utils/APIs to the base module/service

This commit is contained in:
Jinseong Jeon
2021-06-08 18:17:37 -07:00
committed by TeamCityServer
parent e870bf7399
commit 77e8aed995
12 changed files with 59 additions and 40 deletions
@@ -19,6 +19,8 @@ interface BaseKotlinUastResolveProviderService {
fun convertParent(uElement: UElement): UElement?
fun getReferenceVariants(ktExpression: KtExpression, nameHint: String): Sequence<PsiElement>
fun resolveToDeclaration(ktExpression: KtExpression): PsiElement?
fun resolveToType(ktTypeReference: KtTypeReference, source: UElement): PsiType?
@@ -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<ResolveResult> {
ktExpression ?: return emptyList()
val referenceVariants = baseKotlinUastResolveProviderService.getReferenceVariants(ktExpression, ktExpression.name ?: ktExpression.text)
return referenceVariants.mapNotNull { CandidateInfo(it, PsiSubstitutor.EMPTY) }.asIterable()
}
@@ -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<PsiElement> {
return emptySequence() // Not supported (as per the counterpart [CliKotlinUastResolveProviderService])
}
}
@@ -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<PsiElement> {
TODO("Not yet implemented")
}
}
@@ -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<DeclarationDescriptor> {
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<PsiElement> {
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()
}
}
@@ -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<DeclarationDescriptor>
override val baseKotlinConverter: BaseKotlinConverter
get() = KotlinConverter
@@ -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<ResolveResult> = getResolveResultVariants(sourcePsi.callableReference)
override fun multiResolve(): Iterable<ResolveResult> =
getResolveResultVariants(baseResolveProviderService, sourcePsi.callableReference)
}
@@ -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()
@@ -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<ResolveResult> = getResolveResultVariants(sourcePsi.selectorExpression)
override fun multiResolve(): Iterable<ResolveResult> =
getResolveResultVariants(baseResolveProviderService, sourcePsi.selectorExpression)
}
@@ -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<DeclarationDescriptor> =
override fun getReferenceVariants(ktExpression: KtExpression, nameHint: String): Sequence<PsiElement> =
emptySequence() // Not supported
}
@@ -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
@@ -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<PsiElement> =
ServiceManager.getService(ktElement.project, KotlinUastResolveProviderService::class.java)
.getReferenceVariants(ktElement, nameHint)
.mapNotNull { resolveToDeclarationImpl(ktElement, it) }
internal fun getResolveResultVariants(ktExpression: KtExpression?): Iterable<ResolveResult> {
ktExpression ?: return emptyList()
val referenceVariants = getReferenceVariants(ktExpression, ktExpression.name ?: ktExpression.text)
return referenceVariants.mapNotNull {CandidateInfo(it, PsiSubstitutor.EMPTY) }.asIterable()
}
internal fun KtElement.multiResolveResults(): Sequence<ResolveResult> =
references.asSequence().flatMap { ref ->
@@ -43,4 +24,3 @@ class TypedResolveResult<T : PsiElement>(element: T) : CandidateInfo(element, Ps
@Suppress("UNCHECKED_CAST")
override fun getElement(): T = super.getElement() as T
}