Move KtReference interface to psi module

This commit is contained in:
Ilya Kirillov
2021-06-19 18:43:27 +02:00
parent 796baf261d
commit 28dbfeb845
18 changed files with 84 additions and 94 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.
*/
@@ -22,4 +22,4 @@ abstract class KDocReference(element: KDocName) : KtMultiReference<KDocName>(ele
override fun getCanonicalText(): String = element.getNameText()
override val resolvesByNames: Collection<Name> get() = listOf(Name.identifier(element.getNameText()))
}
}
@@ -0,0 +1,50 @@
/*
* 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.kotlin.idea.references
import com.intellij.openapi.components.ServiceManager
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiReference
import com.intellij.util.containers.MultiMap
import org.jetbrains.kotlin.psi.KtElement
interface KotlinPsiReferenceProvider {
fun getReferencesByElement(element: PsiElement): Array<PsiReference>
}
interface KotlinReferenceProviderContributor {
fun registerReferenceProviders(registrar: KotlinPsiReferenceRegistrar)
companion object {
fun getInstance(): KotlinReferenceProviderContributor =
ServiceManager.getService(KotlinReferenceProviderContributor::class.java)
}
}
class KotlinPsiReferenceRegistrar {
val providers: MultiMap<Class<out PsiElement>, KotlinPsiReferenceProvider> = MultiMap.create()
inline fun <reified E : KtElement> registerProvider(crossinline factory: (E) -> PsiReference?) {
registerMultiProvider<E> { element ->
factory(element)?.let { reference -> arrayOf(reference) } ?: PsiReference.EMPTY_ARRAY
}
}
inline fun <reified E : KtElement> registerMultiProvider(crossinline factory: (E) -> Array<PsiReference>) {
val provider: KotlinPsiReferenceProvider = object : KotlinPsiReferenceProvider {
override fun getReferencesByElement(element: PsiElement): Array<PsiReference> {
return factory(element as E)
}
}
registerMultiProvider(E::class.java, provider)
}
fun registerMultiProvider(klass: Class<out PsiElement>, provider: KotlinPsiReferenceProvider) {
providers.putValue(klass, provider)
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.
*/
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.idea.references
import com.google.common.collect.Lists
import com.intellij.psi.MultiRangeReference
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.lexer.KtToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name
@@ -48,7 +47,7 @@ abstract class KtArrayAccessReference(
appendExpressions(arrayAccessExpression.indexExpressions, ",")
appendFixedText(")")
}
val fullCallExpression = arrayAccessExpression.replaced(replacement)
val fullCallExpression = arrayAccessExpression.replace(replacement) as KtExpression
val callExpression = fullCallExpression.getPossiblyQualifiedCallExpression()
if (callExpression != null && canMoveLambdaOutsideParentheses(callExpression)) {
moveFunctionLiteralOutsideParentheses(callExpression)
@@ -66,4 +65,4 @@ abstract class KtArrayAccessReference(
companion object {
private val NAMES = Lists.newArrayList(OperatorNameConventions.GET, OperatorNameConventions.SET)
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.
*/
@@ -9,7 +9,7 @@ import com.intellij.openapi.util.TextRange
import com.intellij.psi.MultiRangeReference
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtCollectionLiteralExpression
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.ArrayFqNames
abstract class KtCollectionLiteralReference(expression: KtCollectionLiteralExpression) :
@@ -28,4 +28,4 @@ abstract class KtCollectionLiteralReference(expression: KtCollectionLiteralExpre
get() = COLLECTION_LITERAL_CALL_NAMES
private fun PsiElement.normalizeRange(): TextRange = this.textRange.shiftRight(-expression.textOffset)
}
}
@@ -1,13 +1,14 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.kotlin.idea.references
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtConstructorDelegationReferenceExpression
import org.jetbrains.kotlin.psi.*
abstract class KtConstructorDelegationReference(
expression: KtConstructorDelegationReferenceExpression
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.
*/
@@ -31,4 +31,4 @@ abstract class KtDestructuringDeclarationReference(
val componentIndex = destructuringParent.entries.indexOf(element) + 1
return listOf(Name.identifier("component$componentIndex"))
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.
*/
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.idea.references
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtForExpression
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.util.OperatorNameConventions
abstract class KtForLoopInReference(element: KtForExpression) : KtMultiReference<KtForExpression>(element) {
@@ -28,4 +28,4 @@ abstract class KtForLoopInReference(element: KtForExpression) : KtMultiReference
OperatorNameConventions.HAS_NEXT
)
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.
*/
@@ -8,31 +8,16 @@ package org.jetbrains.kotlin.idea.references
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiReference
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.plugin.references.SimpleNameReferenceExtension
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.types.expressions.OperatorConventions
abstract class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleReference<KtSimpleNameExpression>(expression) {
override fun isReferenceTo(element: PsiElement): Boolean {
if (!doCanBeReferenceTo(element)) return false
@Suppress("DEPRECATION") // compatibility with 191
for (extension in Extensions.getArea(element.project).getExtensionPoint(SimpleNameReferenceExtension.EP_NAME).extensions) {
if (extension.isReferenceTo(this, element)) return true
}
return isReferenceToWithoutExtensionChecking(element)
}
protected abstract fun doCanBeReferenceTo(candidateTarget: PsiElement): Boolean
protected abstract fun isReferenceToWithoutExtensionChecking(candidateTarget: PsiElement): Boolean
override fun getRangeInElement(): TextRange {
val element = element.getReferencedNameElement()
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.
*/
@@ -15,16 +15,9 @@ abstract class SyntheticPropertyAccessorReference(
expression: KtNameReferenceExpression,
val getter: Boolean
) : KtSimpleReference<KtNameReferenceExpression>(expression) {
override fun isReferenceTo(element: PsiElement): Boolean {
if (element !is PsiMethod || !isAccessorName(element.name)) return false
if (!getter && expression.readWriteAccess(true) == ReferenceAccess.READ) return false
return additionalIsReferenceToChecker(element)
}
protected abstract fun additionalIsReferenceToChecker(element: PsiElement): Boolean
private fun isAccessorName(name: String): Boolean {
protected fun isAccessorName(name: String): Boolean {
if (getter) {
return name.startsWith("get") || name.startsWith("is")
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.
*/
@@ -42,12 +42,10 @@ import org.jetbrains.kotlin.types.expressions.OperatorConventions
class KtSimpleNameReferenceDescriptorsImpl(
expression: KtSimpleNameExpression
) : KtSimpleNameReference(expression), KtDescriptorsBasedReference {
override fun doCanBeReferenceTo(candidateTarget: PsiElement): Boolean =
canBeReferenceTo(candidateTarget)
override fun isReferenceToWithoutExtensionChecking(candidateTarget: PsiElement): Boolean =
matchesTarget(candidateTarget)
override fun getTargetDescriptors(context: BindingContext): Collection<DeclarationDescriptor> {
return SmartList<DeclarationDescriptor>().apply {
// Replace Java property with its accessor(s)
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.idea.references
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.util.SmartList
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
@@ -29,8 +30,12 @@ class SyntheticPropertyAccessorReferenceDescriptorImpl(
expression: KtNameReferenceExpression,
getter: Boolean
) : SyntheticPropertyAccessorReference(expression, getter), KtDescriptorsBasedReference {
override fun isReferenceTo(element: PsiElement): Boolean =
super<SyntheticPropertyAccessorReference>.isReferenceTo(element)
override fun isReferenceTo(element: PsiElement): Boolean {
if (element !is PsiMethod || !isAccessorName(element.name)) return false
if (!getter && expression.readWriteAccess(true) == ReferenceAccess.READ) return false
return additionalIsReferenceToChecker(element)
}
override fun additionalIsReferenceToChecker(element: PsiElement): Boolean = matchesTarget(element)
@@ -7,9 +7,7 @@ package org.jetbrains.kotlin.idea.frontend.api.components
import org.jetbrains.kotlin.idea.frontend.api.KtSymbolBasedReference
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.idea.references.KtReference
import org.jetbrains.kotlin.idea.references.KtSimpleReference
interface KtReferenceResolveMixIn : KtAnalysisSessionMixIn {
fun KtReference.resolveToSymbols(): Collection<KtSymbol> {
@@ -47,8 +47,9 @@ internal class KtFirSimpleNameReference(
return true // TODO
}
override fun isReferenceToWithoutExtensionChecking(candidateTarget: PsiElement): Boolean {
return resolve() == candidateTarget //todo
override fun isReferenceTo(element: PsiElement): Boolean {
return resolve() == element //todo
}
override fun handleElementRename(newElementName: String): PsiElement? {
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.idea.references
import com.intellij.openapi.components.service
import com.intellij.openapi.project.IndexNotReadyException
import com.intellij.psi.ContributedReferenceHost
import com.intellij.psi.PsiElement
@@ -16,49 +15,10 @@ import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.PsiModificationTracker
import com.intellij.util.containers.ConcurrentFactoryMap
import com.intellij.util.containers.ContainerUtil
import com.intellij.util.containers.MultiMap
import org.jetbrains.kotlin.psi.KotlinReferenceProvidersService
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.utils.SmartList
interface KotlinPsiReferenceProvider {
fun getReferencesByElement(element: PsiElement): Array<PsiReference>
}
interface KotlinReferenceProviderContributor {
fun registerReferenceProviders(registrar: KotlinPsiReferenceRegistrar)
companion object {
fun getInstance(): KotlinReferenceProviderContributor = service()
}
}
class KotlinPsiReferenceRegistrar {
val providers: MultiMap<Class<out PsiElement>, KotlinPsiReferenceProvider> = MultiMap.create()
inline fun <reified E : KtElement> registerProvider(crossinline factory: (E) -> PsiReference?) {
registerMultiProvider<E> { element ->
factory(element)?.let { reference -> arrayOf(reference) } ?: PsiReference.EMPTY_ARRAY
}
}
inline fun <reified E : KtElement> registerMultiProvider(crossinline factory: (E) -> Array<PsiReference>) {
val provider: KotlinPsiReferenceProvider = object : KotlinPsiReferenceProvider {
override fun getReferencesByElement(element: PsiElement): Array<PsiReference> {
return factory(element as E)
}
}
registerMultiProvider(E::class.java, provider)
}
fun registerMultiProvider(klass: Class<out PsiElement>, provider: KotlinPsiReferenceProvider) {
providers.putValue(klass, provider)
}
}
class KtIdeReferenceProviderService : KotlinReferenceProvidersService() {
private val originalProvidersBinding: MultiMap<Class<out PsiElement>, KotlinPsiReferenceProvider>
private val providersBindingCache: Map<Class<out PsiElement>, List<KotlinPsiReferenceProvider>>