diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/references/base/KtFe10KotlinReferenceProviderContributor.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/references/base/KtFe10KotlinReferenceProviderContributor.kt index a488cb181af..d0de0c21640 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/references/base/KtFe10KotlinReferenceProviderContributor.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/references/base/KtFe10KotlinReferenceProviderContributor.kt @@ -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 provider@{ element: KtValueArgument -> + if (element.isNamed()) return@provider null + val annotationEntry = element.getParentOfTypeAndBranch { valueArgumentList } ?: return@provider null + if (annotationEntry.valueArguments.size != 1) return@provider null + + KtDefaultAnnotationArgumentReference(element) + } } } } \ No newline at end of file diff --git a/analysis/kt-references/src/org/jetbrains/kotlin/idea/references/KtDefaultAnnotationArgumentReference.kt b/analysis/kt-references/src/org/jetbrains/kotlin/idea/references/KtDefaultAnnotationArgumentReference.kt new file mode 100644 index 00000000000..cf67518ba66 --- /dev/null +++ b/analysis/kt-references/src/org/jetbrains/kotlin/idea/references/KtDefaultAnnotationArgumentReference.kt @@ -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(element) { + override val resolver: ResolveCache.PolyVariantResolver + get() = Resolver + + override val resolvesByNames: Collection + 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 { + override fun resolve(t: KtReference, incompleteCode: Boolean): Array { + 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() + ?.calleeExpression + ?.constructorReferenceExpression + ?.mainReference + ?.resolve() + + } +} diff --git a/analysis/kt-references/src/org/jetbrains/kotlin/idea/references/KtReference.kt b/analysis/kt-references/src/org/jetbrains/kotlin/idea/references/KtReference.kt index 89d54c4596b..93f774e58e2 100644 --- a/analysis/kt-references/src/org/jetbrains/kotlin/idea/references/KtReference.kt +++ b/analysis/kt-references/src/org/jetbrains/kotlin/idea/references/KtReference.kt @@ -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.*