Performance optimization: do not invoke DescriptorToSourceUtilsIde.getAnyDeclaration() on creating LookupElement - do it lazily
#KT-14606 In Progress
This commit is contained in:
+33
-23
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
||||
import org.jetbrains.kotlin.idea.completion.handlers.BaseDeclarationInsertHandler
|
||||
import org.jetbrains.kotlin.idea.completion.handlers.KotlinClassifierInsertHandler
|
||||
import org.jetbrains.kotlin.idea.completion.handlers.KotlinFunctionInsertHandler
|
||||
import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject
|
||||
import org.jetbrains.kotlin.idea.core.completion.PackageLookupObject
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -55,12 +56,13 @@ class BasicLookupElementFactory(
|
||||
DescriptorUtils.unwrapFakeOverride(descriptor)
|
||||
else
|
||||
descriptor
|
||||
val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, _descriptor)
|
||||
return createLookupElement(_descriptor, declaration, qualifyNestedClasses, includeClassTypeArguments, parametersAndTypeGrayed)
|
||||
return createLookupElementUnwrappedDescriptor(_descriptor, qualifyNestedClasses, includeClassTypeArguments, parametersAndTypeGrayed)
|
||||
}
|
||||
|
||||
fun createLookupElementForJavaClass(psiClass: PsiClass, qualifyNestedClasses: Boolean = false, includeClassTypeArguments: Boolean = true): LookupElement {
|
||||
val lookupObject = object : DeclarationLookupObjectImpl(null, psiClass) {
|
||||
val lookupObject = object : DeclarationLookupObjectImpl(null) {
|
||||
override val psiElement: PsiElement?
|
||||
get() = psiClass
|
||||
override fun getIcon(flags: Int) = psiClass.getIcon(flags)
|
||||
}
|
||||
var element = LookupElementBuilder.create(lookupObject, psiClass.name!!)
|
||||
@@ -109,20 +111,21 @@ class BasicLookupElementFactory(
|
||||
return element.withIconFromLookupObject()
|
||||
}
|
||||
|
||||
private fun createLookupElement(
|
||||
private fun createLookupElementUnwrappedDescriptor(
|
||||
descriptor: DeclarationDescriptor,
|
||||
declaration: PsiElement?,
|
||||
qualifyNestedClasses: Boolean,
|
||||
includeClassTypeArguments: Boolean,
|
||||
parametersAndTypeGrayed: Boolean
|
||||
): LookupElement {
|
||||
val declarationLazy by lazy { DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor) }
|
||||
|
||||
if (descriptor is ClassifierDescriptor &&
|
||||
declaration is PsiClass &&
|
||||
declaration !is KtLightClass) {
|
||||
declarationLazy is PsiClass &&
|
||||
declarationLazy !is KtLightClass) {
|
||||
// for java classes we create special lookup elements
|
||||
// because they must be equal to ones created in TypesCompletion
|
||||
// otherwise we may have duplicates
|
||||
return createLookupElementForJavaClass(declaration, qualifyNestedClasses, includeClassTypeArguments)
|
||||
return createLookupElementForJavaClass(declarationLazy, qualifyNestedClasses, includeClassTypeArguments)
|
||||
}
|
||||
|
||||
if (descriptor is PackageViewDescriptor) {
|
||||
@@ -132,26 +135,33 @@ class BasicLookupElementFactory(
|
||||
return createLookupElementForPackage(descriptor.fqName)
|
||||
}
|
||||
|
||||
// for constructor use name and icon of containing class
|
||||
val nameAndIconDescriptor: DeclarationDescriptor
|
||||
val iconDeclaration: PsiElement?
|
||||
val lookupObject: DeclarationLookupObject
|
||||
val name: String
|
||||
if (descriptor is ConstructorDescriptor) {
|
||||
nameAndIconDescriptor = descriptor.containingDeclaration
|
||||
iconDeclaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, nameAndIconDescriptor)
|
||||
// for constructor use name and icon of containing class
|
||||
val classifierDescriptor = descriptor.containingDeclaration
|
||||
lookupObject = object : DeclarationLookupObjectImpl(descriptor) {
|
||||
override val psiElement by lazy { DescriptorToSourceUtilsIde.getAnyDeclaration(project, classifierDescriptor) }
|
||||
override fun getIcon(flags: Int) = KotlinDescriptorIconProvider.getIcon(classifierDescriptor, psiElement, flags)
|
||||
}
|
||||
name = classifierDescriptor.name.asString()
|
||||
}
|
||||
else if (descriptor is SyntheticJavaPropertyDescriptor) {
|
||||
lookupObject = object : DeclarationLookupObjectImpl(descriptor) {
|
||||
override val psiElement by lazy { DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor.getMethod) }
|
||||
override fun getIcon(flags: Int) = KotlinDescriptorIconProvider.getIcon(descriptor, null, flags)
|
||||
}
|
||||
name = descriptor.name.asString()
|
||||
}
|
||||
else {
|
||||
nameAndIconDescriptor = descriptor
|
||||
iconDeclaration = declaration
|
||||
lookupObject = object : DeclarationLookupObjectImpl(descriptor) {
|
||||
override val psiElement: PsiElement?
|
||||
get() = declarationLazy
|
||||
override fun getIcon(flags: Int) = KotlinDescriptorIconProvider.getIcon(descriptor, psiElement, flags)
|
||||
}
|
||||
name = descriptor.name.asString()
|
||||
}
|
||||
val name = nameAndIconDescriptor.name.asString()
|
||||
|
||||
val psiElement = declaration
|
||||
?: (descriptor as? SyntheticJavaPropertyDescriptor)
|
||||
?.getMethod
|
||||
?.let { DescriptorToSourceUtilsIde.getAnyDeclaration(project, it) }
|
||||
val lookupObject = object : DeclarationLookupObjectImpl(descriptor, psiElement) {
|
||||
override fun getIcon(flags: Int) = KotlinDescriptorIconProvider.getIcon(nameAndIconDescriptor, iconDeclaration, flags)
|
||||
}
|
||||
var element = LookupElementBuilder.create(lookupObject, name)
|
||||
|
||||
val insertHandler = insertHandlerProvider.insertHandler(descriptor)
|
||||
|
||||
+16
-11
@@ -16,10 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.completion
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiDocCommentOwner
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
@@ -34,13 +32,8 @@ import org.jetbrains.kotlin.util.descriptorsEqualWithSubstitution
|
||||
* Position will be used for sorting
|
||||
*/
|
||||
abstract class DeclarationLookupObjectImpl(
|
||||
final override val descriptor: DeclarationDescriptor?,
|
||||
final override val psiElement: PsiElement?
|
||||
final override val descriptor: DeclarationDescriptor?
|
||||
): DeclarationLookupObject {
|
||||
init {
|
||||
assert(descriptor != null || psiElement != null)
|
||||
}
|
||||
|
||||
override val name: Name?
|
||||
get() = descriptor?.name ?: (psiElement as? PsiNamedElement)?.name?.let { Name.identifier(it) }
|
||||
|
||||
@@ -55,15 +48,27 @@ abstract class DeclarationLookupObjectImpl(
|
||||
override fun toString() = super.toString() + " " + (descriptor ?: psiElement)
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return if (descriptor != null) descriptor.original.hashCode() else psiElement!!.hashCode()
|
||||
return if (descriptor != null)
|
||||
descriptor.original.hashCode()
|
||||
else
|
||||
psiElement!!.hashCode()
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || javaClass != other.javaClass) return false
|
||||
val lookupObject = other as DeclarationLookupObjectImpl
|
||||
return descriptorsEqualWithSubstitution(descriptor, lookupObject.descriptor) && psiElement == lookupObject.psiElement
|
||||
if (descriptor != null)
|
||||
return descriptorsEqualWithSubstitution(descriptor, lookupObject.descriptor)
|
||||
else
|
||||
return lookupObject.descriptor == null && psiElement == lookupObject.psiElement
|
||||
}
|
||||
|
||||
override val isDeprecated = if (descriptor != null) KotlinBuiltIns.isDeprecated(descriptor) else (psiElement as? PsiDocCommentOwner)?.isDeprecated ?: false
|
||||
override val isDeprecated: Boolean
|
||||
get() {
|
||||
return if (descriptor != null)
|
||||
KotlinBuiltIns.isDeprecated(descriptor)
|
||||
else
|
||||
(psiElement as? PsiDocCommentOwner)?.isDeprecated == true
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -125,10 +125,10 @@ class LookupElementsCollector(
|
||||
result = postProcessor(result)
|
||||
}
|
||||
|
||||
val psiElement = (result.`object` as? DeclarationLookupObject)?.psiElement
|
||||
if (psiElement != null) {
|
||||
val declarationLookupObject = result.`object` as? DeclarationLookupObject
|
||||
if (declarationLookupObject != null) {
|
||||
result = object : LookupElementDecorator<LookupElement>(result) {
|
||||
override fun getPsiElement() = psiElement
|
||||
override fun getPsiElement() = declarationLookupObject.psiElement
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user