Optimize searching constructor delegation calls
^KT-28755 Fixed
This commit is contained in:
@@ -25,6 +25,7 @@ import com.intellij.psi.search.SearchScope
|
|||||||
import com.intellij.psi.search.searches.MethodReferencesSearch
|
import com.intellij.psi.search.searches.MethodReferencesSearch
|
||||||
import com.intellij.psi.search.searches.ReferencesSearch
|
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.lazyPub
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||||
@@ -146,7 +147,7 @@ private fun PsiElement.buildProcessDelegationCallKotlinConstructorUsagesTask(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (klass !is KtClass || element !is KtDeclaration) return { true }
|
if (klass !is KtClass || element !is KtDeclaration) return { true }
|
||||||
val descriptor = element.constructor ?: return { true }
|
val descriptor = lazyPub { element.constructor }
|
||||||
|
|
||||||
if (!processClassDelegationCallsToSpecifiedConstructor(klass, descriptor, process)) return { false }
|
if (!processClassDelegationCallsToSpecifiedConstructor(klass, descriptor, process)) return { false }
|
||||||
|
|
||||||
@@ -163,7 +164,7 @@ private fun PsiElement.buildProcessDelegationCallJavaConstructorUsagesTask(
|
|||||||
if (this is KtLightMethod && this.kotlinOrigin == null) return { true }
|
if (this is KtLightMethod && this.kotlinOrigin == null) return { true }
|
||||||
if (!(this is PsiMethod && isConstructor)) return { true }
|
if (!(this is PsiMethod && isConstructor)) return { true }
|
||||||
val klass = containingClass ?: return { true }
|
val klass = containingClass ?: return { true }
|
||||||
val descriptor = getJavaMethodDescriptor() as? ConstructorDescriptor ?: return { true }
|
val descriptor = lazyPub { getJavaMethodDescriptor() as? ConstructorDescriptor }
|
||||||
return { processInheritorsDelegatingCallToSpecifiedConstructor(klass, scope, descriptor, process) }
|
return { processInheritorsDelegatingCallToSpecifiedConstructor(klass, scope, descriptor, process) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,14 +172,14 @@ private fun PsiElement.buildProcessDelegationCallJavaConstructorUsagesTask(
|
|||||||
private fun processInheritorsDelegatingCallToSpecifiedConstructor(
|
private fun processInheritorsDelegatingCallToSpecifiedConstructor(
|
||||||
klass: PsiElement,
|
klass: PsiElement,
|
||||||
scope: SearchScope,
|
scope: SearchScope,
|
||||||
descriptor: ConstructorDescriptor,
|
lazyDescriptor: Lazy<ConstructorDescriptor?>,
|
||||||
process: (KtCallElement) -> Boolean
|
process: (KtCallElement) -> Boolean
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return HierarchySearchRequest(klass, scope, false).searchInheritors().all {
|
return HierarchySearchRequest(klass, scope, false).searchInheritors().all {
|
||||||
runReadAction {
|
runReadAction {
|
||||||
val unwrapped = it.takeIf { it.isValid }?.unwrapped
|
val unwrapped = it.takeIf { it.isValid }?.unwrapped
|
||||||
if (unwrapped is KtClass)
|
if (unwrapped is KtClass)
|
||||||
processClassDelegationCallsToSpecifiedConstructor(unwrapped, descriptor, process)
|
processClassDelegationCallsToSpecifiedConstructor(unwrapped, lazyDescriptor, process)
|
||||||
else
|
else
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@@ -186,19 +187,30 @@ private fun processInheritorsDelegatingCallToSpecifiedConstructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun processClassDelegationCallsToSpecifiedConstructor(
|
private fun processClassDelegationCallsToSpecifiedConstructor(
|
||||||
klass: KtClass, constructor: DeclarationDescriptor, process: (KtCallElement) -> Boolean
|
klass: KtClass,
|
||||||
|
lazyDescriptor: Lazy<ConstructorDescriptor?>,
|
||||||
|
process: (KtCallElement) -> Boolean
|
||||||
): Boolean {
|
): Boolean {
|
||||||
for (secondaryConstructor in klass.secondaryConstructors) {
|
for (secondaryConstructor in klass.secondaryConstructors) {
|
||||||
val delegationCallDescriptor = secondaryConstructor.getDelegationCall().getConstructorCallDescriptor()
|
val delegationCallDescriptor =
|
||||||
if (constructor == delegationCallDescriptor) {
|
secondaryConstructor.getDelegationCall().getConstructorCallDescriptor()
|
||||||
|
?: continue
|
||||||
|
|
||||||
|
if (lazyDescriptor.value == delegationCallDescriptor) {
|
||||||
if (!process(secondaryConstructor.getDelegationCall())) return false
|
if (!process(secondaryConstructor.getDelegationCall())) return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!klass.isEnum()) return true
|
if (!klass.isEnum()) return true
|
||||||
for (declaration in klass.declarations) {
|
for (declaration in klass.declarations) {
|
||||||
if (declaration is KtEnumEntry) {
|
if (declaration is KtEnumEntry) {
|
||||||
val delegationCall = declaration.superTypeListEntries.firstOrNull()
|
val delegationCall =
|
||||||
if (delegationCall is KtSuperTypeCallEntry && constructor == delegationCall.calleeExpression.getConstructorCallDescriptor()) {
|
declaration.superTypeListEntries.firstOrNull() as? KtSuperTypeCallEntry
|
||||||
|
?: continue
|
||||||
|
val constructorCallDescriptor =
|
||||||
|
delegationCall.calleeExpression.getConstructorCallDescriptor()
|
||||||
|
?: continue
|
||||||
|
|
||||||
|
if (lazyDescriptor.value == constructorCallDescriptor) {
|
||||||
if (!process(delegationCall)) return false
|
if (!process(delegationCall)) return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user