[FIR IDE] Separate searchers from descriptor usage
KotlinConstructorDelegationCallReferenceSearcher KotlinConventionMethodReferencesSearcher KotlinDefinitionsSearcher KotlinOverridingMethodReferenceSearcher KotlinPropertyAccessorsReferenceSearcher KotlinTodoSearcher
This commit is contained in:
+28
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.search
|
package org.jetbrains.kotlin.idea.search
|
||||||
|
|
||||||
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
@@ -14,6 +15,10 @@ import org.jetbrains.kotlin.psi.*
|
|||||||
import org.jetbrains.kotlin.resolve.ImportPath
|
import org.jetbrains.kotlin.resolve.ImportPath
|
||||||
|
|
||||||
class KotlinSearchUsagesSupportFirImpl : KotlinSearchUsagesSupport {
|
class KotlinSearchUsagesSupportFirImpl : KotlinSearchUsagesSupport {
|
||||||
|
override fun actualsForExpected(declaration: KtDeclaration, module: Module?): Set<KtDeclaration> {
|
||||||
|
return emptySet()
|
||||||
|
}
|
||||||
|
|
||||||
override fun dataClassComponentMethodName(element: KtParameter): String? {
|
override fun dataClassComponentMethodName(element: KtParameter): String? {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -109,4 +114,27 @@ class KotlinSearchUsagesSupportFirImpl : KotlinSearchUsagesSupport {
|
|||||||
override fun isExpectDeclaration(declaration: KtDeclaration): Boolean {
|
override fun isExpectDeclaration(declaration: KtDeclaration): Boolean {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun canBeResolvedWithFrontEnd(element: PsiElement): Boolean {
|
||||||
|
//TODO FIR: Is the same as PsiElement.hasJavaResolutionFacade() as for FIR?
|
||||||
|
return element.originalElement.containingFile != null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createConstructorHandle(ktDeclaration: KtDeclaration): KotlinSearchUsagesSupport.ConstructorCallHandle {
|
||||||
|
//TODO FIR: This is the stub. Need to implement
|
||||||
|
return object : KotlinSearchUsagesSupport.ConstructorCallHandle {
|
||||||
|
override fun referencedTo(element: KtElement): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createConstructorHandle(psiMethod: PsiMethod): KotlinSearchUsagesSupport.ConstructorCallHandle {
|
||||||
|
//TODO FIR: This is the stub. Need to implement
|
||||||
|
return object : KotlinSearchUsagesSupport.ConstructorCallHandle {
|
||||||
|
override fun referencedTo(element: KtElement): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+25
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.idea.search
|
package org.jetbrains.kotlin.idea.search
|
||||||
|
|
||||||
import com.intellij.openapi.components.ServiceManager
|
import com.intellij.openapi.components.ServiceManager
|
||||||
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
@@ -17,6 +18,10 @@ import org.jetbrains.kotlin.resolve.ImportPath
|
|||||||
|
|
||||||
interface KotlinSearchUsagesSupport {
|
interface KotlinSearchUsagesSupport {
|
||||||
|
|
||||||
|
interface ConstructorCallHandle {
|
||||||
|
fun referencedTo(element: KtElement): Boolean
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun getInstance(project: Project): KotlinSearchUsagesSupport {
|
fun getInstance(project: Project): KotlinSearchUsagesSupport {
|
||||||
return ServiceManager.getService(project, KotlinSearchUsagesSupport::class.java)
|
return ServiceManager.getService(project, KotlinSearchUsagesSupport::class.java)
|
||||||
@@ -95,8 +100,22 @@ interface KotlinSearchUsagesSupport {
|
|||||||
|
|
||||||
fun KtDeclaration.isExpectDeclaration(): Boolean =
|
fun KtDeclaration.isExpectDeclaration(): Boolean =
|
||||||
getInstance(project).isExpectDeclaration(this)
|
getInstance(project).isExpectDeclaration(this)
|
||||||
|
|
||||||
|
fun KtDeclaration.actualsForExpected(module: Module? = null): Set<KtDeclaration> =
|
||||||
|
getInstance(project).actualsForExpected(this, module)
|
||||||
|
|
||||||
|
fun PsiElement.canBeResolvedWithFrontEnd(): Boolean =
|
||||||
|
getInstance(project).canBeResolvedWithFrontEnd(this)
|
||||||
|
|
||||||
|
fun createConstructorHandle(ktDeclaration: KtDeclaration): ConstructorCallHandle =
|
||||||
|
getInstance(ktDeclaration.project).createConstructorHandle(ktDeclaration)
|
||||||
|
|
||||||
|
fun createConstructorHandle(psiMethod: PsiMethod): ConstructorCallHandle =
|
||||||
|
getInstance(psiMethod.project).createConstructorHandle(psiMethod)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun actualsForExpected(declaration: KtDeclaration, module: Module? = null): Set<KtDeclaration>
|
||||||
|
|
||||||
fun dataClassComponentMethodName(element: KtParameter): String?
|
fun dataClassComponentMethodName(element: KtParameter): String?
|
||||||
|
|
||||||
fun hasType(element: KtExpression): Boolean
|
fun hasType(element: KtExpression): Boolean
|
||||||
@@ -149,4 +168,10 @@ interface KotlinSearchUsagesSupport {
|
|||||||
fun expectedDeclarationIfAny(declaration: KtDeclaration): KtDeclaration?
|
fun expectedDeclarationIfAny(declaration: KtDeclaration): KtDeclaration?
|
||||||
|
|
||||||
fun isExpectDeclaration(declaration: KtDeclaration): Boolean
|
fun isExpectDeclaration(declaration: KtDeclaration): Boolean
|
||||||
|
|
||||||
|
fun canBeResolvedWithFrontEnd(element: PsiElement): Boolean
|
||||||
|
|
||||||
|
fun createConstructorHandle(ktDeclaration: KtDeclaration): ConstructorCallHandle
|
||||||
|
|
||||||
|
fun createConstructorHandle(psiMethod: PsiMethod): ConstructorCallHandle
|
||||||
}
|
}
|
||||||
+2
-2
@@ -20,15 +20,15 @@ import com.intellij.openapi.application.QueryExecutorBase
|
|||||||
import com.intellij.psi.PsiReference
|
import com.intellij.psi.PsiReference
|
||||||
import com.intellij.psi.search.searches.MethodReferencesSearch.SearchParameters
|
import com.intellij.psi.search.searches.MethodReferencesSearch.SearchParameters
|
||||||
import com.intellij.util.Processor
|
import com.intellij.util.Processor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.hasJavaResolutionFacade
|
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.canBeResolvedWithFrontEnd
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.processDelegationCallConstructorUsages
|
import org.jetbrains.kotlin.idea.search.usagesSearch.processDelegationCallConstructorUsages
|
||||||
|
|
||||||
class KotlinConstructorDelegationCallReferenceSearcher : QueryExecutorBase<PsiReference, SearchParameters>(true) {
|
class KotlinConstructorDelegationCallReferenceSearcher : QueryExecutorBase<PsiReference, SearchParameters>(true) {
|
||||||
override fun processQuery(queryParameters: SearchParameters, consumer: Processor<in PsiReference>) {
|
override fun processQuery(queryParameters: SearchParameters, consumer: Processor<in PsiReference>) {
|
||||||
val method = queryParameters.method
|
val method = queryParameters.method
|
||||||
if (!method.isConstructor) return
|
if (!method.isConstructor) return
|
||||||
if (!method.hasJavaResolutionFacade()) return
|
if (!method.canBeResolvedWithFrontEnd()) return
|
||||||
|
|
||||||
method.processDelegationCallConstructorUsages(method.useScope.intersectWith(queryParameters.effectiveSearchScope)) {
|
method.processDelegationCallConstructorUsages(method.useScope.intersectWith(queryParameters.effectiveSearchScope)) {
|
||||||
it.calleeExpression?.mainReference?.let { consumer.process(it) } ?: true
|
it.calleeExpression?.mainReference?.let { consumer.process(it) } ?: true
|
||||||
+2
-2
@@ -20,13 +20,13 @@ import com.intellij.openapi.application.QueryExecutorBase
|
|||||||
import com.intellij.psi.PsiReference
|
import com.intellij.psi.PsiReference
|
||||||
import com.intellij.psi.search.searches.MethodReferencesSearch
|
import com.intellij.psi.search.searches.MethodReferencesSearch
|
||||||
import com.intellij.util.Processor
|
import com.intellij.util.Processor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.hasJavaResolutionFacade
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.canBeResolvedWithFrontEnd
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.operators.OperatorReferenceSearcher
|
import org.jetbrains.kotlin.idea.search.usagesSearch.operators.OperatorReferenceSearcher
|
||||||
|
|
||||||
class KotlinConventionMethodReferencesSearcher : QueryExecutorBase<PsiReference, MethodReferencesSearch.SearchParameters>(true) {
|
class KotlinConventionMethodReferencesSearcher : QueryExecutorBase<PsiReference, MethodReferencesSearch.SearchParameters>(true) {
|
||||||
override fun processQuery(queryParameters: MethodReferencesSearch.SearchParameters, consumer: Processor<in PsiReference>) {
|
override fun processQuery(queryParameters: MethodReferencesSearch.SearchParameters, consumer: Processor<in PsiReference>) {
|
||||||
val method = queryParameters.method
|
val method = queryParameters.method
|
||||||
if (!method.hasJavaResolutionFacade()) return
|
if (!method.canBeResolvedWithFrontEnd()) return
|
||||||
|
|
||||||
val operatorSearcher = OperatorReferenceSearcher.create(
|
val operatorSearcher = OperatorReferenceSearcher.create(
|
||||||
queryParameters.method,
|
queryParameters.method,
|
||||||
+8
-6
@@ -28,15 +28,15 @@ import com.intellij.util.QueryExecutor
|
|||||||
import com.intellij.util.containers.ContainerUtil
|
import com.intellij.util.containers.ContainerUtil
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
import org.jetbrains.kotlin.asJava.toLightClass
|
|
||||||
import org.jetbrains.kotlin.asJava.unwrapped
|
import org.jetbrains.kotlin.asJava.unwrapped
|
||||||
import org.jetbrains.kotlin.idea.caches.lightClasses.KtFakeLightClass
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedCreateKtFakeLightClass
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedToLightClass
|
||||||
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.actualsForExpected
|
||||||
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.forEachOverridingMethod
|
||||||
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.isExpectDeclaration
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachImplementation
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachImplementation
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachOverridingMethod
|
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.toPossiblyFakeLightMethods
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.toPossiblyFakeLightMethods
|
||||||
import org.jetbrains.kotlin.idea.util.actualsForExpected
|
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.idea.util.isExpectDeclaration
|
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.contains
|
import org.jetbrains.kotlin.psi.psiUtil.contains
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -107,7 +107,9 @@ class KotlinDefinitionsSearcher : QueryExecutor<PsiElement, DefinitionsScopedSea
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun processClassImplementations(klass: KtClass, consumer: Processor<PsiElement>): Boolean {
|
private fun processClassImplementations(klass: KtClass, consumer: Processor<PsiElement>): Boolean {
|
||||||
val psiClass = runReadAction { klass.toLightClass() ?: KtFakeLightClass(klass) }
|
val psiClass = runReadAction { klass.providedToLightClass() ?: providedCreateKtFakeLightClass(klass) }
|
||||||
|
as? KtLightClass
|
||||||
|
?: return false //TODO Implement FIR support for not nullable providedCreateKtFakeLightClass
|
||||||
|
|
||||||
val searchScope = runReadAction { psiClass.useScope }
|
val searchScope = runReadAction { psiClass.useScope }
|
||||||
if (searchScope is LocalSearchScope) {
|
if (searchScope is LocalSearchScope) {
|
||||||
+3
-3
@@ -14,12 +14,12 @@ import com.intellij.psi.search.searches.MethodReferencesSearch
|
|||||||
import com.intellij.psi.util.MethodSignatureUtil
|
import com.intellij.psi.util.MethodSignatureUtil
|
||||||
import com.intellij.psi.util.TypeConversionUtil
|
import com.intellij.psi.util.TypeConversionUtil
|
||||||
import com.intellij.util.Processor
|
import com.intellij.util.Processor
|
||||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedToLightMethods
|
||||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||||
import org.jetbrains.kotlin.idea.references.SyntheticPropertyAccessorReference
|
import org.jetbrains.kotlin.idea.references.SyntheticPropertyAccessorReference
|
||||||
import org.jetbrains.kotlin.idea.references.readWriteAccess
|
import org.jetbrains.kotlin.idea.references.readWriteAccess
|
||||||
import org.jetbrains.kotlin.idea.search.restrictToKotlinSources
|
import org.jetbrains.kotlin.idea.search.restrictToKotlinSources
|
||||||
import org.jetbrains.kotlin.idea.util.runReadActionInSmartMode
|
import org.jetbrains.kotlin.idea.util.application.runReadActionInSmartMode
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
import org.jetbrains.kotlin.load.java.getPropertyNamesCandidatesByAccessorName
|
import org.jetbrains.kotlin.load.java.getPropertyNamesCandidatesByAccessorName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -106,7 +106,7 @@ class KotlinOverridingMethodReferenceSearcher : MethodUsagesSearcher() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun countNonFinalLightMethods() = refElement
|
fun countNonFinalLightMethods() = refElement
|
||||||
.toLightMethods()
|
.providedToLightMethods()
|
||||||
.filterNot { it.hasModifierProperty(PsiModifier.FINAL) }
|
.filterNot { it.hasModifierProperty(PsiModifier.FINAL) }
|
||||||
|
|
||||||
val lightMethods = when (refElement) {
|
val lightMethods = when (refElement) {
|
||||||
+126
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.search.usagesSearch
|
||||||
|
|
||||||
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import com.intellij.psi.search.SearchScope
|
||||||
|
import com.intellij.psi.search.searches.MethodReferencesSearch
|
||||||
|
import com.intellij.psi.search.searches.ReferencesSearch
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
|
import org.jetbrains.kotlin.asJava.unwrapped
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.LightClassProvider.Companion.providedToLightMethods
|
||||||
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport
|
||||||
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport.Companion.createConstructorHandle
|
||||||
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
|
||||||
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.contains
|
||||||
|
|
||||||
|
fun PsiElement.processDelegationCallConstructorUsages(scope: SearchScope, process: (KtCallElement) -> Boolean): Boolean {
|
||||||
|
val task = buildProcessDelegationCallConstructorUsagesTask(scope, process)
|
||||||
|
return task()
|
||||||
|
}
|
||||||
|
|
||||||
|
// should be executed under read-action, returns long-running part to be executed outside read-action
|
||||||
|
fun PsiElement.buildProcessDelegationCallConstructorUsagesTask(scope: SearchScope, process: (KtCallElement) -> Boolean): () -> Boolean {
|
||||||
|
ApplicationManager.getApplication().assertReadAccessAllowed()
|
||||||
|
val task1 = buildProcessDelegationCallKotlinConstructorUsagesTask(scope, process)
|
||||||
|
val task2 = buildProcessDelegationCallJavaConstructorUsagesTask(scope, process)
|
||||||
|
return { task1() && task2() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun PsiElement.buildProcessDelegationCallKotlinConstructorUsagesTask(
|
||||||
|
scope: SearchScope,
|
||||||
|
process: (KtCallElement) -> Boolean
|
||||||
|
): () -> Boolean {
|
||||||
|
val element = unwrapped
|
||||||
|
if (element != null && element !in scope) return { true }
|
||||||
|
|
||||||
|
val klass = when (element) {
|
||||||
|
is KtConstructor<*> -> element.getContainingClassOrObject()
|
||||||
|
is KtClass -> element
|
||||||
|
else -> return { true }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (klass !is KtClass || element !is KtDeclaration) return { true }
|
||||||
|
|
||||||
|
val constructorHandler = createConstructorHandle(element)
|
||||||
|
|
||||||
|
if (!processClassDelegationCallsToSpecifiedConstructor(klass, constructorHandler, process)) return { false }
|
||||||
|
|
||||||
|
// long-running task, return it to execute outside read-action
|
||||||
|
return { processInheritorsDelegatingCallToSpecifiedConstructor(klass, scope, constructorHandler, process) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun PsiElement.buildProcessDelegationCallJavaConstructorUsagesTask(
|
||||||
|
scope: SearchScope,
|
||||||
|
process: (KtCallElement) -> Boolean
|
||||||
|
): () -> Boolean {
|
||||||
|
if (this is KtLightElement<*, *>) return { true }
|
||||||
|
// TODO: Temporary hack to avoid NPE while KotlinNoOriginLightMethod is around
|
||||||
|
if (this is KtLightMethod && this.kotlinOrigin == null) return { true }
|
||||||
|
if (!(this is PsiMethod && isConstructor)) return { true }
|
||||||
|
val klass = containingClass ?: return { true }
|
||||||
|
|
||||||
|
val ctorHandle = createConstructorHandle(this)
|
||||||
|
return { processInheritorsDelegatingCallToSpecifiedConstructor(klass, scope, ctorHandle, process) }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun processInheritorsDelegatingCallToSpecifiedConstructor(
|
||||||
|
klass: PsiElement,
|
||||||
|
scope: SearchScope,
|
||||||
|
constructorCallComparator: KotlinSearchUsagesSupport.ConstructorCallHandle,
|
||||||
|
process: (KtCallElement) -> Boolean
|
||||||
|
): Boolean {
|
||||||
|
return HierarchySearchRequest(klass, scope, false).searchInheritors().all {
|
||||||
|
runReadAction {
|
||||||
|
val unwrapped = it.takeIf { it.isValid }?.unwrapped
|
||||||
|
if (unwrapped is KtClass)
|
||||||
|
processClassDelegationCallsToSpecifiedConstructor(unwrapped, constructorCallComparator, process)
|
||||||
|
else
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processClassDelegationCallsToSpecifiedConstructor(
|
||||||
|
klass: KtClass,
|
||||||
|
constructorCallHadle: KotlinSearchUsagesSupport.ConstructorCallHandle,
|
||||||
|
process: (KtCallElement) -> Boolean
|
||||||
|
): Boolean {
|
||||||
|
for (secondaryConstructor in klass.secondaryConstructors) {
|
||||||
|
val delegationCall = secondaryConstructor.getDelegationCall()
|
||||||
|
if (constructorCallHadle.referencedTo(delegationCall)) {
|
||||||
|
if (!process(delegationCall)) return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!klass.isEnum()) return true
|
||||||
|
for (declaration in klass.declarations) {
|
||||||
|
if (declaration is KtEnumEntry) {
|
||||||
|
val delegationCall =
|
||||||
|
declaration.superTypeListEntries.firstOrNull() as? KtSuperTypeCallEntry
|
||||||
|
?: continue
|
||||||
|
|
||||||
|
if (constructorCallHadle.referencedTo(delegationCall.calleeExpression)) {
|
||||||
|
if (!process(delegationCall)) return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun PsiElement.searchReferencesOrMethodReferences(): Collection<PsiReference> {
|
||||||
|
val lightMethods = providedToLightMethods()
|
||||||
|
return if (lightMethods.isNotEmpty()) {
|
||||||
|
lightMethods.flatMapTo(LinkedHashSet()) { MethodReferencesSearch.search(it) }
|
||||||
|
} else {
|
||||||
|
ReferencesSearch.search(this).findAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -177,6 +177,9 @@ The Kotlin FIR plugin provides language support in IntelliJ IDEA and Android Stu
|
|||||||
|
|
||||||
<extensions defaultExtensionNs="com.intellij">
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
|
|
||||||
|
<postStartupActivity implementation="org.jetbrains.kotlin.idea.PluginStartupActivity"/>
|
||||||
|
<projectService serviceImplementation="org.jetbrains.kotlin.idea.PluginStartupService"/>
|
||||||
|
|
||||||
<iconProvider implementation="org.jetbrains.kotlin.idea.KotlinIconProviderBase"/>
|
<iconProvider implementation="org.jetbrains.kotlin.idea.KotlinIconProviderBase"/>
|
||||||
|
|
||||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.caches.resolve.IdePackageOracleFactory"/>
|
<projectService serviceImplementation="org.jetbrains.kotlin.idea.caches.resolve.IdePackageOracleFactory"/>
|
||||||
@@ -217,15 +220,15 @@ The Kotlin FIR plugin provides language support in IntelliJ IDEA and Android Stu
|
|||||||
<gotoDeclarationHandler implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinImportAliasGotoDeclarationHandler"/>
|
<gotoDeclarationHandler implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinImportAliasGotoDeclarationHandler"/>
|
||||||
<referencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearcher"/>
|
<referencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearcher"/>
|
||||||
<referencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinAliasedImportedElementSearcher"/>
|
<referencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinAliasedImportedElementSearcher"/>
|
||||||
<!-- <directClassInheritorsSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinDirectInheritorsSearcher"/>-->
|
<methodReferencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinConstructorDelegationCallReferenceSearcher"/>
|
||||||
|
<methodReferencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinConventionMethodReferencesSearcher"/>
|
||||||
|
<definitionsScopedSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinDefinitionsSearcher"/>
|
||||||
|
<methodReferencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinOverridingMethodReferenceSearcher"/>
|
||||||
|
<methodReferencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinPropertyAccessorsReferenceSearcher"/>
|
||||||
|
<!-- <directClassInheritorsSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinDirectInheritorsSearcher"/>-->
|
||||||
<!-- <overridingMethodsSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinOverridingMethodsWithGenericsSearcher"/>-->
|
<!-- <overridingMethodsSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinOverridingMethodsWithGenericsSearcher"/>-->
|
||||||
<!-- <definitionsScopedSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinDefinitionsSearcher"/>-->
|
|
||||||
<!-- <annotatedElementsSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinAnnotatedElementsSearcher"/>-->
|
<!-- <annotatedElementsSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinAnnotatedElementsSearcher"/>-->
|
||||||
<!-- <classesWithAnnotatedMembersSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinClassesWithAnnotatedMembersSearcher"/>-->
|
<!-- <classesWithAnnotatedMembersSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinClassesWithAnnotatedMembersSearcher"/>-->
|
||||||
<!-- <methodReferencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinPropertyAccessorsReferenceSearcher"/>-->
|
|
||||||
<!-- <methodReferencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinConstructorDelegationCallReferenceSearcher"/>-->
|
|
||||||
<!-- <methodReferencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinOverridingMethodReferenceSearcher"/>-->
|
|
||||||
<!-- <methodReferencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinConventionMethodReferencesSearcher"/>-->
|
|
||||||
<!-- <methodReferencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.DefaultAnnotationMethodKotlinImplicitReferenceSearcher"/>-->
|
<!-- <methodReferencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.DefaultAnnotationMethodKotlinImplicitReferenceSearcher"/>-->
|
||||||
|
|
||||||
<readWriteAccessDetector implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReadWriteAccessDetector" id="kotlin"/>
|
<readWriteAccessDetector implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReadWriteAccessDetector" id="kotlin"/>
|
||||||
|
|||||||
@@ -5,10 +5,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.search
|
package org.jetbrains.kotlin.idea.search
|
||||||
|
|
||||||
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.intellij.psi.search.SearchScope
|
import com.intellij.psi.search.SearchScope
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.util.hasJavaResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.core.isInheritable
|
import org.jetbrains.kotlin.idea.core.isInheritable
|
||||||
import org.jetbrains.kotlin.idea.core.isOverridable
|
import org.jetbrains.kotlin.idea.core.isOverridable
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachOverridingMethod
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachOverridingMethod
|
||||||
@@ -16,12 +18,15 @@ import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOpt
|
|||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.*
|
import org.jetbrains.kotlin.idea.search.usagesSearch.*
|
||||||
import org.jetbrains.kotlin.idea.stubindex.KotlinTypeAliasShortNameIndex
|
import org.jetbrains.kotlin.idea.stubindex.KotlinTypeAliasShortNameIndex
|
||||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||||
|
import org.jetbrains.kotlin.idea.util.actualsForExpected
|
||||||
import org.jetbrains.kotlin.idea.util.expectedDeclarationIfAny
|
import org.jetbrains.kotlin.idea.util.expectedDeclarationIfAny
|
||||||
import org.jetbrains.kotlin.idea.util.isExpectDeclaration
|
import org.jetbrains.kotlin.idea.util.isExpectDeclaration
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.ImportPath
|
import org.jetbrains.kotlin.resolve.ImportPath
|
||||||
|
|
||||||
class KotlinSearchUsagesSupportImpl : KotlinSearchUsagesSupport {
|
class KotlinSearchUsagesSupportImpl : KotlinSearchUsagesSupport {
|
||||||
|
override fun actualsForExpected(declaration: KtDeclaration, module: Module?): Set<KtDeclaration> =
|
||||||
|
declaration.actualsForExpected(module)
|
||||||
|
|
||||||
override fun dataClassComponentMethodName(element: KtParameter): String? =
|
override fun dataClassComponentMethodName(element: KtParameter): String? =
|
||||||
element.dataClassComponentFunction()?.name?.asString()
|
element.dataClassComponentFunction()?.name?.asString()
|
||||||
@@ -101,4 +106,13 @@ class KotlinSearchUsagesSupportImpl : KotlinSearchUsagesSupport {
|
|||||||
|
|
||||||
override fun isExpectDeclaration(declaration: KtDeclaration): Boolean =
|
override fun isExpectDeclaration(declaration: KtDeclaration): Boolean =
|
||||||
declaration.isExpectDeclaration()
|
declaration.isExpectDeclaration()
|
||||||
|
|
||||||
|
override fun canBeResolvedWithFrontEnd(element: PsiElement): Boolean =
|
||||||
|
element.hasJavaResolutionFacade()
|
||||||
|
|
||||||
|
override fun createConstructorHandle(ktDeclaration: KtDeclaration): KotlinSearchUsagesSupport.ConstructorCallHandle =
|
||||||
|
KotlinConstructorCallLazyDescriptorHandle(ktDeclaration)
|
||||||
|
|
||||||
|
override fun createConstructorHandle(psiMethod: PsiMethod): KotlinSearchUsagesSupport.ConstructorCallHandle =
|
||||||
|
JavaConstructorCallLazyDescriptorHandle(psiMethod)
|
||||||
}
|
}
|
||||||
@@ -16,27 +16,18 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.search.usagesSearch
|
package org.jetbrains.kotlin.idea.search.usagesSearch
|
||||||
|
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.search.SearchScope
|
|
||||||
import com.intellij.psi.search.searches.MethodReferencesSearch
|
|
||||||
import com.intellij.psi.search.searches.ReferencesSearch
|
|
||||||
import com.intellij.psi.util.MethodSignatureUtil
|
import com.intellij.psi.util.MethodSignatureUtil
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
|
||||||
import org.jetbrains.kotlin.asJava.toLightClass
|
import org.jetbrains.kotlin.asJava.toLightClass
|
||||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||||
import org.jetbrains.kotlin.asJava.unwrapped
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.idea.caches.project.NotUnderContentRootModuleInfo.project
|
|
||||||
import org.jetbrains.kotlin.idea.caches.project.getNullableModuleInfo
|
import org.jetbrains.kotlin.idea.caches.project.getNullableModuleInfo
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToParameterDescriptorIfAny
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaMemberDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaMemberDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaMethodDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaMethodDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaOrKotlinMemberDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaOrKotlinMemberDescriptor
|
||||||
@@ -46,9 +37,8 @@ import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider
|
|||||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||||
import org.jetbrains.kotlin.idea.project.findAnalyzerServices
|
import org.jetbrains.kotlin.idea.project.findAnalyzerServices
|
||||||
import org.jetbrains.kotlin.idea.references.unwrappedTargets
|
import org.jetbrains.kotlin.idea.references.unwrappedTargets
|
||||||
|
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport
|
||||||
import org.jetbrains.kotlin.idea.search.ReceiverTypeSearcherInfo
|
import org.jetbrains.kotlin.idea.search.ReceiverTypeSearcherInfo
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
|
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors
|
|
||||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
||||||
import org.jetbrains.kotlin.idea.util.FuzzyType
|
import org.jetbrains.kotlin.idea.util.FuzzyType
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
@@ -57,7 +47,6 @@ import org.jetbrains.kotlin.idea.util.toFuzzyType
|
|||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.contains
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.resolve.*
|
import org.jetbrains.kotlin.resolve.*
|
||||||
@@ -70,6 +59,27 @@ import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.util.isValidOperator
|
import org.jetbrains.kotlin.util.isValidOperator
|
||||||
|
|
||||||
|
class KotlinConstructorCallLazyDescriptorHandle(ktElement: KtDeclaration) :
|
||||||
|
KotlinSearchUsagesSupport.ConstructorCallHandle {
|
||||||
|
private val descriptor: ConstructorDescriptor? by lazyPub { ktElement.constructor }
|
||||||
|
|
||||||
|
override fun referencedTo(element: KtElement): Boolean =
|
||||||
|
element.getConstructorCallDescriptor().let {
|
||||||
|
it != null && descriptor != null && it == descriptor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class JavaConstructorCallLazyDescriptorHandle(psiMethod: PsiMethod) :
|
||||||
|
KotlinSearchUsagesSupport.ConstructorCallHandle {
|
||||||
|
|
||||||
|
private val descriptor: ConstructorDescriptor? by lazyPub { psiMethod.getJavaMethodDescriptor() as? ConstructorDescriptor }
|
||||||
|
|
||||||
|
override fun referencedTo(element: KtElement): Boolean =
|
||||||
|
element.getConstructorCallDescriptor().let {
|
||||||
|
it != null && descriptor != null && it == descriptor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun tryRenderDeclarationCompactStyle(declaration: KtDeclaration): String? =
|
fun tryRenderDeclarationCompactStyle(declaration: KtDeclaration): String? =
|
||||||
declaration.descriptor?.let { DescriptorRenderer.COMPACT.render(it) }
|
declaration.descriptor?.let { DescriptorRenderer.COMPACT.render(it) }
|
||||||
|
|
||||||
@@ -143,104 +153,6 @@ private fun KtElement.getConstructorCallDescriptor(): DeclarationDescriptor? {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PsiElement.processDelegationCallConstructorUsages(scope: SearchScope, process: (KtCallElement) -> Boolean): Boolean {
|
|
||||||
val task = buildProcessDelegationCallConstructorUsagesTask(scope, process)
|
|
||||||
return task()
|
|
||||||
}
|
|
||||||
|
|
||||||
// should be executed under read-action, returns long-running part to be executed outside read-action
|
|
||||||
fun PsiElement.buildProcessDelegationCallConstructorUsagesTask(scope: SearchScope, process: (KtCallElement) -> Boolean): () -> Boolean {
|
|
||||||
ApplicationManager.getApplication().assertReadAccessAllowed()
|
|
||||||
val task1 = buildProcessDelegationCallKotlinConstructorUsagesTask(scope, process)
|
|
||||||
val task2 = buildProcessDelegationCallJavaConstructorUsagesTask(scope, process)
|
|
||||||
return { task1() && task2() }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun PsiElement.buildProcessDelegationCallKotlinConstructorUsagesTask(
|
|
||||||
scope: SearchScope,
|
|
||||||
process: (KtCallElement) -> Boolean
|
|
||||||
): () -> Boolean {
|
|
||||||
val element = unwrapped
|
|
||||||
if (element != null && element !in scope) return { true }
|
|
||||||
|
|
||||||
val klass = when (element) {
|
|
||||||
is KtConstructor<*> -> element.getContainingClassOrObject()
|
|
||||||
is KtClass -> element
|
|
||||||
else -> return { true }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (klass !is KtClass || element !is KtDeclaration) return { true }
|
|
||||||
val descriptor = lazyPub { element.constructor }
|
|
||||||
|
|
||||||
if (!processClassDelegationCallsToSpecifiedConstructor(klass, descriptor, process)) return { false }
|
|
||||||
|
|
||||||
// long-running task, return it to execute outside read-action
|
|
||||||
return { processInheritorsDelegatingCallToSpecifiedConstructor(klass, scope, descriptor, process) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun PsiElement.buildProcessDelegationCallJavaConstructorUsagesTask(
|
|
||||||
scope: SearchScope,
|
|
||||||
process: (KtCallElement) -> Boolean
|
|
||||||
): () -> Boolean {
|
|
||||||
if (this is KtLightElement<*, *>) return { true }
|
|
||||||
// TODO: Temporary hack to avoid NPE while KotlinNoOriginLightMethod is around
|
|
||||||
if (this is KtLightMethod && this.kotlinOrigin == null) return { true }
|
|
||||||
if (!(this is PsiMethod && isConstructor)) return { true }
|
|
||||||
val klass = containingClass ?: return { true }
|
|
||||||
val descriptor = lazyPub { getJavaMethodDescriptor() as? ConstructorDescriptor }
|
|
||||||
return { processInheritorsDelegatingCallToSpecifiedConstructor(klass, scope, descriptor, process) }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun processInheritorsDelegatingCallToSpecifiedConstructor(
|
|
||||||
klass: PsiElement,
|
|
||||||
scope: SearchScope,
|
|
||||||
lazyDescriptor: Lazy<ConstructorDescriptor?>,
|
|
||||||
process: (KtCallElement) -> Boolean
|
|
||||||
): Boolean {
|
|
||||||
return HierarchySearchRequest(klass, scope, false).searchInheritors().all {
|
|
||||||
runReadAction {
|
|
||||||
val unwrapped = it.takeIf { it.isValid }?.unwrapped
|
|
||||||
if (unwrapped is KtClass)
|
|
||||||
processClassDelegationCallsToSpecifiedConstructor(unwrapped, lazyDescriptor, process)
|
|
||||||
else
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun processClassDelegationCallsToSpecifiedConstructor(
|
|
||||||
klass: KtClass,
|
|
||||||
lazyDescriptor: Lazy<ConstructorDescriptor?>,
|
|
||||||
process: (KtCallElement) -> Boolean
|
|
||||||
): Boolean {
|
|
||||||
for (secondaryConstructor in klass.secondaryConstructors) {
|
|
||||||
val delegationCallDescriptor =
|
|
||||||
secondaryConstructor.getDelegationCall().getConstructorCallDescriptor()
|
|
||||||
?: continue
|
|
||||||
|
|
||||||
if (lazyDescriptor.value == delegationCallDescriptor) {
|
|
||||||
if (!process(secondaryConstructor.getDelegationCall())) return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!klass.isEnum()) return true
|
|
||||||
for (declaration in klass.declarations) {
|
|
||||||
if (declaration is KtEnumEntry) {
|
|
||||||
val delegationCall =
|
|
||||||
declaration.superTypeListEntries.firstOrNull() as? KtSuperTypeCallEntry
|
|
||||||
?: continue
|
|
||||||
val constructorCallDescriptor =
|
|
||||||
delegationCall.calleeExpression.getConstructorCallDescriptor()
|
|
||||||
?: continue
|
|
||||||
|
|
||||||
if (lazyDescriptor.value == constructorCallDescriptor) {
|
|
||||||
if (!process(delegationCall)) return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if reference resolves to extension function whose receiver is the same as declaration's parent (or its superclass)
|
// Check if reference resolves to extension function whose receiver is the same as declaration's parent (or its superclass)
|
||||||
// Used in extension search
|
// Used in extension search
|
||||||
fun PsiReference.isExtensionOfDeclarationClassUsage(declaration: KtNamedDeclaration): Boolean {
|
fun PsiReference.isExtensionOfDeclarationClassUsage(declaration: KtNamedDeclaration): Boolean {
|
||||||
@@ -304,15 +216,6 @@ fun PsiReference.isCallableOverrideUsage(declaration: KtNamedDeclaration): Boole
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PsiElement.searchReferencesOrMethodReferences(): Collection<PsiReference> {
|
|
||||||
val lightMethods = toLightMethods()
|
|
||||||
return if (lightMethods.isNotEmpty()) {
|
|
||||||
lightMethods.flatMapTo(LinkedHashSet()) { MethodReferencesSearch.search(it) }
|
|
||||||
} else {
|
|
||||||
ReferencesSearch.search(this).findAll()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T : PsiNamedElement> List<T>.filterDataClassComponentsIfDisabled(kotlinOptions: KotlinReferencesSearchOptions): List<T> {
|
fun <T : PsiNamedElement> List<T>.filterDataClassComponentsIfDisabled(kotlinOptions: KotlinReferencesSearchOptions): List<T> {
|
||||||
if (kotlinOptions.searchForComponentConventions) return this
|
if (kotlinOptions.searchForComponentConventions) return this
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user