From 7bf071b69fa4a1cf01bb02fb8a3697ee064f8666 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Thu, 14 Dec 2017 12:35:37 +0300 Subject: [PATCH] Precount 'isPublic' property if descriptor available --- .../KotlinStructureViewElement.kt | 79 +++++++++++-------- 1 file changed, 47 insertions(+), 32 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/structureView/KotlinStructureViewElement.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/structureView/KotlinStructureViewElement.kt index 0498e77d88c..2f3dcebb4a2 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/structureView/KotlinStructureViewElement.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/structureView/KotlinStructureViewElement.kt @@ -31,52 +31,35 @@ import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.psi.* import javax.swing.Icon +import kotlin.properties.ReadWriteProperty +import kotlin.reflect.KProperty class KotlinStructureViewElement(val element: NavigatablePsiElement, private val isInherited: Boolean = false) : PsiTreeElementBase(element), Queryable { - private var _presentation: KotlinStructureElementPresentation? = null - get() { - if (field == null) { - field = KotlinStructureElementPresentation(isInherited, element, _descriptor) - } - return field + private var kotlinPresentation + by AssignableLazyProperty { + KotlinStructureElementPresentation(isInherited, element, countDescriptor()) } - private val _descriptor: DeclarationDescriptor? - get() { - if (!(element.isValid && element is KtDeclaration)) { - return null - } - - if (element is KtAnonymousInitializer) { - return null - } - - return runReadAction { - if (!DumbService.isDumb(element.getProject())) { - return@runReadAction element.resolveToDescriptorIfAny() - } - null - } - } - - val isPublic: Boolean - get() { - return (_descriptor as? DeclarationDescriptorWithVisibility)?.visibility == Visibilities.PUBLIC + var isPublic + by AssignableLazyProperty { + isPublic(countDescriptor()) } + private set constructor(element: NavigatablePsiElement, descriptor: DeclarationDescriptor, isInherited: Boolean) : this(element, isInherited){ if (element !is KtElement) { // Avoid storing descriptor in fields - _presentation = KotlinStructureElementPresentation(isInherited, element, descriptor) + kotlinPresentation = KotlinStructureElementPresentation(isInherited, element, descriptor) + isPublic = isPublic(descriptor) } } - override fun getPresentation(): ItemPresentation = _presentation!! - override fun getLocationString(): String? = _presentation!!.locationString - override fun getIcon(open: Boolean): Icon? = _presentation!!.getIcon(open) - override fun getPresentableText(): String? = _presentation!!.presentableText + override fun getPresentation(): ItemPresentation = kotlinPresentation + override fun getLocationString(): String? = kotlinPresentation.locationString + override fun getIcon(open: Boolean): Icon? = kotlinPresentation.getIcon(open) + override fun getPresentableText(): String? = kotlinPresentation.presentableText @TestOnly override fun putInfo(info: MutableMap) { @@ -116,6 +99,38 @@ class KotlinStructureViewElement(val element: NavigatablePsiElement, return result } + + private fun isPublic(descriptor: DeclarationDescriptor?) = + (descriptor as? DeclarationDescriptorWithVisibility)?.visibility == Visibilities.PUBLIC + + private fun countDescriptor(): DeclarationDescriptor? { + if (!(element.isValid && element is KtDeclaration)) { + return null + } + + if (element is KtAnonymousInitializer) { + return null + } + + return runReadAction { + if (!DumbService.isDumb(element.getProject())) { + return@runReadAction element.resolveToDescriptorIfAny() + } + null + } + } +} + +private class AssignableLazyProperty(val init: () -> T) : ReadWriteProperty { + private var _value: T? = null + + override fun getValue(thisRef: R, property: KProperty<*>): T { + return _value ?: init().also { _value = it } + } + + override fun setValue(thisRef: R, property: KProperty<*>, value: T) { + _value = value + } } fun KtClassOrObject.getStructureDeclarations() = primaryConstructorParameters.filter { it.hasValOrVar() } + declarations