[Analysis API] Move SyntheticPropertyAccessorReferenceDescriptorImpl

Also move some utilities from IDE to kotlin repo
This commit is contained in:
Tianyu Geng
2022-05-05 16:59:19 +00:00
committed by Ilya Kirillov
parent 71a30b0c5e
commit a7c37286a3
5 changed files with 144 additions and 2 deletions
@@ -15,6 +15,7 @@ dependencies {
implementation(project(":compiler:backend.jvm"))
implementation(project(":compiler:backend-common"))
implementation(project(":compiler:backend.common.jvm"))
implementation(project(":compiler:light-classes"))
testApiJUnit5()
testImplementation(project(":analysis:analysis-api-providers"))
@@ -0,0 +1,62 @@
/*
* Copyright 2010-2022 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.kotlin.analysis.api.descriptors.references
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.util.SmartList
import org.jetbrains.kotlin.analysis.api.descriptors.references.base.KtFe10Reference
import org.jetbrains.kotlin.asJava.canHaveSyntheticGetter
import org.jetbrains.kotlin.asJava.canHaveSyntheticSetter
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.references.SyntheticPropertyAccessorReference
import org.jetbrains.kotlin.idea.references.readWriteAccess
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtImportAlias
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.bindingContextUtil.getReferenceTargets
import org.jetbrains.kotlin.resolve.references.ReferenceAccess
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
import org.jetbrains.kotlin.utils.addIfNotNull
class Fe10SyntheticPropertyAccessorReference(
expression: KtNameReferenceExpression,
getter: Boolean
) : SyntheticPropertyAccessorReference(expression, getter), KtFe10Reference {
override fun canBeReferenceTo(candidateTarget: PsiElement): Boolean {
if (candidateTarget !is PsiMethod || !isAccessorName(candidateTarget.name)) return false
if (getter && !candidateTarget.canHaveSyntheticGetter || !getter && !candidateTarget.canHaveSyntheticSetter) return false
if (!getter && expression.readWriteAccess(true) == ReferenceAccess.READ) return false
return true
}
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
val descriptors = expression.getReferenceTargets(context)
if (descriptors.none { it is SyntheticJavaPropertyDescriptor }) return emptyList()
val result = SmartList<FunctionDescriptor>()
for (descriptor in descriptors) {
if (descriptor is SyntheticJavaPropertyDescriptor) {
if (getter) {
result.add(descriptor.getMethod)
} else {
result.addIfNotNull(descriptor.setMethod)
}
}
}
return result
}
override fun isReferenceToImportAlias(alias: KtImportAlias): Boolean {
return super<KtFe10Reference>.isReferenceToImportAlias(alias)
}
override val resolvesByNames: Collection<Name>
get() = listOf(element.getReferencedNameAsName())
}
@@ -5,9 +5,18 @@
package org.jetbrains.kotlin.analysis.api.descriptors.references.base
import com.intellij.psi.PsiReference
import org.jetbrains.kotlin.analysis.api.descriptors.references.*
import org.jetbrains.kotlin.idea.references.KotlinPsiReferenceRegistrar
import org.jetbrains.kotlin.idea.references.KotlinReferenceProviderContributor
import org.jetbrains.kotlin.idea.references.readWriteAccess
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtImportDirective
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.psi.KtPackageDirective
import org.jetbrains.kotlin.psi.KtUserType
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.resolve.references.ReferenceAccess
class KtFe10KotlinReferenceProviderContributor : KotlinReferenceProviderContributor {
override fun registerReferenceProviders(registrar: KotlinPsiReferenceRegistrar) {
@@ -21,6 +30,27 @@ class KtFe10KotlinReferenceProviderContributor : KotlinReferenceProviderContribu
registerProvider(factory = ::KtFe10ConstructorDelegationReference)
registerProvider(factory = ::KtFe10CollectionLiteralReference)
registerProvider(factory = ::Fe10KDocReference)
registerMultiProvider<KtNameReferenceExpression> { nameReferenceExpression ->
if (nameReferenceExpression.getReferencedNameElementType() != KtTokens.IDENTIFIER) {
return@registerMultiProvider PsiReference.EMPTY_ARRAY
}
if (nameReferenceExpression.parents.any { it is KtImportDirective || it is KtPackageDirective || it is KtUserType }) {
return@registerMultiProvider PsiReference.EMPTY_ARRAY
}
when (nameReferenceExpression.readWriteAccess(useResolveForReadWrite = false)) {
ReferenceAccess.READ ->
arrayOf(Fe10SyntheticPropertyAccessorReference(nameReferenceExpression, getter = true))
ReferenceAccess.WRITE ->
arrayOf(Fe10SyntheticPropertyAccessorReference(nameReferenceExpression, getter = false))
ReferenceAccess.READ_WRITE ->
arrayOf(
Fe10SyntheticPropertyAccessorReference(nameReferenceExpression, getter = true),
Fe10SyntheticPropertyAccessorReference(nameReferenceExpression, getter = false)
)
}
}
}
}
}