[Analysis API] Move default annotation argument reference to kotlin repo

This reference is frontend-independent, so its implementation is placed
inside kt-references directly.
This commit is contained in:
Tianyu Geng
2022-05-05 18:05:17 +00:00
committed by Ilya Kirillov
parent a7c37286a3
commit 19e9143bc1
3 changed files with 80 additions and 6 deletions
@@ -9,12 +9,11 @@ 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.KtDefaultAnnotationArgumentReference
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.*
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.resolve.references.ReferenceAccess
@@ -51,6 +50,14 @@ class KtFe10KotlinReferenceProviderContributor : KotlinReferenceProviderContribu
)
}
}
registerProvider<KtValueArgument> provider@{ element: KtValueArgument ->
if (element.isNamed()) return@provider null
val annotationEntry = element.getParentOfTypeAndBranch<KtAnnotationEntry> { valueArgumentList } ?: return@provider null
if (annotationEntry.valueArguments.size != 1) return@provider null
KtDefaultAnnotationArgumentReference(element)
}
}
}
}
@@ -0,0 +1,69 @@
/*
* 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.idea.references
import com.intellij.openapi.util.TextRange
import com.intellij.psi.*
import com.intellij.psi.impl.source.resolve.ResolveCache
import com.intellij.psi.util.MethodSignatureUtil
import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtPrimaryConstructor
import org.jetbrains.kotlin.psi.KtValueArgument
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.findPropertyByName
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
class KtDefaultAnnotationArgumentReference(element: KtValueArgument) : AbstractKtReference<KtValueArgument>(element) {
override val resolver: ResolveCache.PolyVariantResolver<KtReference>
get() = Resolver
override val resolvesByNames: Collection<Name>
get() = listOf(Name.identifier(PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME))
override fun getRangeInElement() = TextRange.EMPTY_RANGE
override fun getCanonicalText() = PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME
override fun isReferenceTo(candidateTarget: PsiElement): Boolean {
val unwrapped = candidateTarget.unwrapped
return (unwrapped is PsiMethod || unwrapped is KtParameter) && unwrapped == resolve()
}
override fun canRename(): Boolean = true
private object Resolver : ResolveCache.PolyVariantResolver<KtReference> {
override fun resolve(t: KtReference, incompleteCode: Boolean): Array<ResolveResult> {
require(t is KtDefaultAnnotationArgumentReference)
val annotationPsi = t.resolveAnnotationCallee() ?: return emptyArray()
val name = PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME
return when (annotationPsi) {
is PsiClass -> {
val signature = MethodSignatureUtil.createMethodSignature(
name, PsiType.EMPTY_ARRAY, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY
)
val method = MethodSignatureUtil.findMethodBySignature(annotationPsi, signature, false) ?: return emptyArray()
arrayOf(PsiElementResolveResult(method))
}
is KtPrimaryConstructor -> {
val property = annotationPsi.containingClassOrObject?.findPropertyByName(name) as? KtParameter ?: return emptyArray()
arrayOf(PsiElementResolveResult(property))
}
else -> emptyArray()
}
}
private fun KtDefaultAnnotationArgumentReference.resolveAnnotationCallee(): PsiElement? =
element.getStrictParentOfType<KtAnnotationEntry>()
?.calleeExpression
?.constructorReferenceExpression
?.mainReference
?.resolve()
}
}
@@ -5,11 +5,9 @@
package org.jetbrains.kotlin.idea.references
import com.intellij.openapi.application.Application
import com.intellij.openapi.components.ServiceManager
import com.intellij.psi.*
import com.intellij.psi.impl.source.resolve.ResolveCache
import com.intellij.util.IncorrectOperationException
import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*