From 3e1c1e8b142c1280aa6960adfebffc5b440ebbc0 Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Wed, 25 Jan 2023 15:54:45 +0100 Subject: [PATCH] [SLC] SymbolLightClassForClassLike: avoid redundant memory allocation ^KT-56046 --- .../symbol/classes/SymbolLightClassBase.kt | 2 +- .../SymbolLightClassForAnnotationClass.kt | 2 +- .../SymbolLightClassForAnonymousObject.kt | 5 +-- .../classes/SymbolLightClassForClassLike.kt | 44 ++++--------------- .../SymbolLightClassForClassOrObject.kt | 28 +++++++----- .../classes/SymbolLightClassForInterface.kt | 2 +- ...ymbolLightClassForInterfaceDefaultImpls.kt | 6 +-- ...LightClassForInterfaceOrAnnotationClass.kt | 3 -- .../SymbolLightClassForNamedClassLike.kt | 16 +++++++ .../symbol/classes/symbolLightClassUtils.kt | 2 +- 10 files changed, 50 insertions(+), 60 deletions(-) diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassBase.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassBase.kt index 585c55af487..17e352d7e75 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassBase.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassBase.kt @@ -111,7 +111,7 @@ abstract class SymbolLightClassBase protected constructor(val ktModule: KtModule } } - protected open val isTopLevel: Boolean = false + protected open val isTopLevel: Boolean get() = false private val _containingFile: PsiFile? by lazyPub { val kotlinOrigin = kotlinOrigin ?: return@lazyPub null diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForAnnotationClass.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForAnnotationClass.kt index c320c05cc61..828551407ca 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForAnnotationClass.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForAnnotationClass.kt @@ -50,7 +50,7 @@ internal open class SymbolLightClassForAnnotationClass : SymbolLightClassForInte manager = manager, ) - override fun isAnnotationType(): Boolean = true + override fun classKind(): KtClassKind = KtClassKind.ANNOTATION_CLASS protected open fun computeOwnMethods(): List = withClassOrObjectSymbol { classOrObjectSymbol -> val result = mutableListOf() diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForAnonymousObject.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForAnonymousObject.kt index eefb31ee547..97ee65f60ae 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForAnonymousObject.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForAnonymousObject.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.light.classes.symbol.classes import com.intellij.psi.* import org.jetbrains.kotlin.analysis.api.symbols.KtAnonymousObjectSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.api.symbols.pointers.symbolPointerOfType @@ -108,9 +109,7 @@ internal class SymbolLightClassForAnonymousObject : SymbolLightClassForClassLike override fun getModifierList(): PsiModifierList? = null override fun hasModifierProperty(name: String): Boolean = name == PsiModifier.FINAL - override fun isInterface(): Boolean = false - override fun isAnnotationType(): Boolean = false - override fun isEnum(): Boolean = false + override fun classKind(): KtClassKind = KtClassKind.ANONYMOUS_OBJECT override fun getContainingClass(): PsiClass? = null override fun getTypeParameters(): Array = PsiTypeParameter.EMPTY_ARRAY diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassLike.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassLike.kt index 5a43a9ee243..0da7f0c3f73 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassLike.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassLike.kt @@ -20,7 +20,6 @@ import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.api.symbols.sourcePsiSafe import org.jetbrains.kotlin.analysis.project.structure.KtModule -import org.jetbrains.kotlin.asJava.classes.getParentForLocalDeclaration import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.elements.KtLightField import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier @@ -31,7 +30,6 @@ import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightTypeParam import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind import org.jetbrains.kotlin.psi.KtClassBody import org.jetbrains.kotlin.psi.KtClassOrObject -import org.jetbrains.kotlin.psi.KtObjectDeclaration import org.jetbrains.kotlin.psi.debugText.getDebugText import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub import org.jetbrains.kotlin.utils.addToStdlib.ifTrue @@ -67,26 +65,6 @@ abstract class SymbolLightClassForClassLike prote classOrObjectDeclaration?.isTopLevel() ?: withClassOrObjectSymbol { it.symbolKind == KtSymbolKind.TOP_LEVEL } } - internal val isCompanionObject: Boolean by lazyPub { - classOrObjectDeclaration?.let { it is KtObjectDeclaration && it.isCompanion() } ?: withClassOrObjectSymbol { - it.classKind == KtClassKind.COMPANION_OBJECT - } - } - - internal val isLocal: Boolean by lazyPub { - classOrObjectDeclaration?.isLocal ?: withClassOrObjectSymbol { it.symbolKind == KtSymbolKind.LOCAL } - } - - internal val isNamedObject: Boolean by lazyPub { - classOrObjectDeclaration?.let { it is KtObjectDeclaration && !it.isCompanion() } ?: withClassOrObjectSymbol { - it.classKind == KtClassKind.OBJECT - } - } - - internal val isObject: Boolean by lazyPub { - classOrObjectDeclaration?.let { it is KtObjectDeclaration } ?: withClassOrObjectSymbol { it.classKind.isObject } - } - private val _isDeprecated: Boolean by lazyPub { withClassOrObjectSymbol { it.hasDeprecatedAnnotation() } } @@ -94,9 +72,9 @@ abstract class SymbolLightClassForClassLike prote override fun isDeprecated(): Boolean = _isDeprecated abstract override fun getModifierList(): PsiModifierList? + abstract override fun getOwnFields(): List abstract override fun getOwnMethods(): List - private val _identifier: PsiIdentifier by lazyPub { KtLightIdentifier(this, classOrObjectDeclaration) } @@ -104,6 +82,7 @@ abstract class SymbolLightClassForClassLike prote override fun getNameIdentifier(): PsiIdentifier? = _identifier abstract override fun getExtendsList(): PsiReferenceList? + abstract override fun getImplementsList(): PsiReferenceList? private val _typeParameterList: PsiTypeParameterList? by lazyPub { @@ -120,6 +99,7 @@ abstract class SymbolLightClassForClassLike prote override fun hasTypeParameters(): Boolean = hasTypeParameters(ktModule, classOrObjectDeclaration, classOrObjectSymbolPointer) override fun getTypeParameterList(): PsiTypeParameterList? = _typeParameterList + override fun getTypeParameters(): Array = _typeParameterList?.typeParameters ?: PsiTypeParameter.EMPTY_ARRAY private val _ownInnerClasses: List by lazyPub { @@ -131,9 +111,9 @@ abstract class SymbolLightClassForClassLike prote override fun getOwnInnerClasses(): List = _ownInnerClasses override fun getTextOffset(): Int = classOrObjectDeclaration?.textOffset ?: -1 + override fun getStartOffsetInParent(): Int = classOrObjectDeclaration?.startOffsetInParent ?: -1 override fun isWritable() = false - override fun getNavigationElement(): PsiElement = classOrObjectDeclaration ?: this override fun isEquivalentTo(another: PsiElement?): Boolean = @@ -161,9 +141,10 @@ abstract class SymbolLightClassForClassLike prote override fun hasModifierProperty(@NonNls name: String): Boolean = modifierList?.hasModifierProperty(name) ?: false - abstract override fun isInterface(): Boolean - abstract override fun isAnnotationType(): Boolean - abstract override fun isEnum(): Boolean + abstract fun classKind(): KtClassKind + override fun isInterface(): Boolean = classKind().let { it == KtClassKind.INTERFACE || it == KtClassKind.ANNOTATION_CLASS } + override fun isAnnotationType(): Boolean = classKind() == KtClassKind.ANNOTATION_CLASS + override fun isEnum(): Boolean = classKind() == KtClassKind.ENUM_CLASS override fun isValid(): Boolean = classOrObjectDeclaration?.isValid ?: classOrObjectSymbolPointer.isValid(ktModule) @@ -189,14 +170,7 @@ abstract class SymbolLightClassForClassLike prote return null } - override fun getParent(): PsiElement? { - if (isLocal) { - return classOrObjectDeclaration?.let(::getParentForLocalDeclaration) - } - - return containingClass ?: containingFile - } - + abstract override fun getParent(): PsiElement? override fun getScope(): PsiElement? = parent override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean = diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassOrObject.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassOrObject.kt index 62bdb63eea8..b9265ceb3ac 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassOrObject.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForClassOrObject.kt @@ -35,10 +35,7 @@ import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassM import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.StandardClassIds -import org.jetbrains.kotlin.psi.KtClass -import org.jetbrains.kotlin.psi.KtClassOrObject -import org.jetbrains.kotlin.psi.KtDeclaration -import org.jetbrains.kotlin.psi.KtEnumEntry +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.DataClassResolver import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind import org.jetbrains.kotlin.util.OperatorNameConventions.EQUALS @@ -119,7 +116,7 @@ internal open class SymbolLightClassForClassOrObject : SymbolLightClassForNamedC val declaredMemberScope = classOrObjectSymbol.getDeclaredMemberScope() val visibleDeclarations = declaredMemberScope.getCallableSymbols() - .applyIf(isObject) { + .applyIf(classKind().isObject) { filterNot { it is KtKotlinPropertySymbol && it.isConst } @@ -138,7 +135,7 @@ internal open class SymbolLightClassForClassOrObject : SymbolLightClassForNamedC it.hasTypeForValueClassInSignature() } - val suppressStatic = isCompanionObject + val suppressStatic = classKind() == KtClassKind.COMPANION_OBJECT createMethods(visibleDeclarations, result, suppressStatic = suppressStatic) createConstructors(declaredMemberScope.getConstructors(), result) @@ -267,7 +264,7 @@ internal open class SymbolLightClassForClassOrObject : SymbolLightClassForNamedC context(KtAnalysisSession) private fun addInstanceFieldIfNeeded(result: MutableList, namedClassOrObjectSymbol: KtNamedClassOrObjectSymbol) { - if (!isNamedObject || isLocal) return + if (classKind() != KtClassKind.OBJECT || isLocal) return result.add( SymbolLightFieldForObject( @@ -299,15 +296,22 @@ internal open class SymbolLightClassForClassOrObject : SymbolLightClassForNamedC override fun isInterface(): Boolean = false override fun isAnnotationType(): Boolean = false + override fun classKind(): KtClassKind = _classKind - private val _isEnum: Boolean by lazyPub { - classOrObjectDeclaration?.let { it is KtClass && it.isEnum() } ?: withClassOrObjectSymbol { - it.classKind == KtClassKind.ENUM_CLASS + private val _classKind: KtClassKind by lazyPub { + when (classOrObjectDeclaration) { + is KtObjectDeclaration -> { + if (classOrObjectDeclaration.isCompanion()) KtClassKind.COMPANION_OBJECT else KtClassKind.OBJECT + } + + is KtClass -> { + if (classOrObjectDeclaration.isEnum()) KtClassKind.ENUM_CLASS else KtClassKind.CLASS + } + + else -> withClassOrObjectSymbol { it.classKind } } } - override fun isEnum(): Boolean = _isEnum - override fun copy(): SymbolLightClassForClassOrObject = SymbolLightClassForClassOrObject(classOrObjectDeclaration, classOrObjectSymbolPointer, ktModule, manager) } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterface.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterface.kt index 1b486832685..ac2ee21281f 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterface.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterface.kt @@ -78,5 +78,5 @@ internal open class SymbolLightClassForInterface : SymbolLightClassForInterfaceO } override fun getExtendsList(): PsiReferenceList? = _extendsList - override fun isAnnotationType(): Boolean = false + override fun classKind(): KtClassKind = KtClassKind.INTERFACE } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterfaceDefaultImpls.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterfaceDefaultImpls.kt index bc0a9caa54a..97b21458825 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterfaceDefaultImpls.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterfaceDefaultImpls.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.light.classes.symbol.classes import com.intellij.psi.* import com.intellij.util.IncorrectOperationException +import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SimpleModifiersBox import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList import org.jetbrains.kotlin.load.java.JvmAbi @@ -42,9 +43,8 @@ internal class SymbolLightClassForInterfaceDefaultImpls(private val containingCl modifiersBox = SimpleModifiersBox(PsiModifier.PUBLIC, PsiModifier.STATIC, PsiModifier.FINAL), ) - override fun isInterface(): Boolean = false - override fun isDeprecated(): Boolean = false - override fun isAnnotationType(): Boolean = false + override fun classKind(): KtClassKind = KtClassKind.CLASS + override fun hasTypeParameters(): Boolean = false override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean = baseClass.qualifiedName == CommonClassNames.JAVA_LANG_OBJECT diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterfaceOrAnnotationClass.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterfaceOrAnnotationClass.kt index 21c4baa0f8d..2545c43d323 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterfaceOrAnnotationClass.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterfaceOrAnnotationClass.kt @@ -82,9 +82,6 @@ internal abstract class SymbolLightClassForInterfaceOrAnnotationClass : SymbolLi computeModifierList() } - override fun isInterface(): Boolean = true - override fun isEnum(): Boolean = false - final override fun getModifierList(): PsiModifierList? = _modifierList private val _ownFields: List by lazyPub { diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForNamedClassLike.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForNamedClassLike.kt index 4ce555f5fb9..51a54e4e414 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForNamedClassLike.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForNamedClassLike.kt @@ -5,14 +5,18 @@ package org.jetbrains.kotlin.light.classes.symbol.classes +import com.intellij.psi.PsiElement import com.intellij.psi.PsiManager import com.intellij.psi.PsiModifier import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.asJava.classes.getParentForLocalDeclaration +import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.elements.KtLightField import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.lexer.KtTokens @@ -52,6 +56,18 @@ abstract class SymbolLightClassForNamedClassLike : SymbolLightClassForClassLike< manager = manager ) + protected val isLocal: Boolean by lazyPub { + classOrObjectDeclaration?.isLocal ?: withClassOrObjectSymbol { it.symbolKind == KtSymbolKind.LOCAL } + } + + override fun getParent(): PsiElement? { + if (isLocal) { + return classOrObjectDeclaration?.let(::getParentForLocalDeclaration) + } + + return containingClass ?: containingFile + } + context(KtAnalysisSession) protected fun addMethodsFromCompanionIfNeeded( result: MutableList, diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt index c077f2dd5f4..2e281776de6 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/symbolLightClassUtils.kt @@ -169,7 +169,7 @@ private fun SymbolLightClassBase.shouldGenerateNoArgOverload( private fun SymbolLightClassBase.defaultConstructor(): KtLightMethod { val classOrObject = kotlinOrigin val visibility = when { - this is SymbolLightClassForClassLike<*> && (isObject || isEnum) -> PsiModifier.PRIVATE + this is SymbolLightClassForClassLike<*> && (classKind().let { it.isObject || it == KtClassKind.ENUM_CLASS }) -> PsiModifier.PRIVATE classOrObject?.hasModifier(SEALED_KEYWORD) == true -> PsiModifier.PROTECTED this is SymbolLightClassForEnumEntry -> PsiModifier.PACKAGE_LOCAL else -> PsiModifier.PUBLIC