[SLC] SymbolLightClassForClassLike: avoid redundant memory allocation

^KT-56046
This commit is contained in:
Dmitrii Gridin
2023-01-25 15:54:45 +01:00
committed by Space Team
parent b2436ba176
commit 3e1c1e8b14
10 changed files with 50 additions and 60 deletions
@@ -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 { private val _containingFile: PsiFile? by lazyPub {
val kotlinOrigin = kotlinOrigin ?: return@lazyPub null val kotlinOrigin = kotlinOrigin ?: return@lazyPub null
@@ -50,7 +50,7 @@ internal open class SymbolLightClassForAnnotationClass : SymbolLightClassForInte
manager = manager, manager = manager,
) )
override fun isAnnotationType(): Boolean = true override fun classKind(): KtClassKind = KtClassKind.ANNOTATION_CLASS
protected open fun computeOwnMethods(): List<PsiMethod> = withClassOrObjectSymbol { classOrObjectSymbol -> protected open fun computeOwnMethods(): List<PsiMethod> = withClassOrObjectSymbol { classOrObjectSymbol ->
val result = mutableListOf<KtLightMethod>() val result = mutableListOf<KtLightMethod>()
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.light.classes.symbol.classes
import com.intellij.psi.* import com.intellij.psi.*
import org.jetbrains.kotlin.analysis.api.symbols.KtAnonymousObjectSymbol 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.KtPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.api.symbols.pointers.symbolPointerOfType import org.jetbrains.kotlin.analysis.api.symbols.pointers.symbolPointerOfType
@@ -108,9 +109,7 @@ internal class SymbolLightClassForAnonymousObject : SymbolLightClassForClassLike
override fun getModifierList(): PsiModifierList? = null override fun getModifierList(): PsiModifierList? = null
override fun hasModifierProperty(name: String): Boolean = name == PsiModifier.FINAL override fun hasModifierProperty(name: String): Boolean = name == PsiModifier.FINAL
override fun isInterface(): Boolean = false override fun classKind(): KtClassKind = KtClassKind.ANONYMOUS_OBJECT
override fun isAnnotationType(): Boolean = false
override fun isEnum(): Boolean = false
override fun getContainingClass(): PsiClass? = null override fun getContainingClass(): PsiClass? = null
override fun getTypeParameters(): Array<PsiTypeParameter> = PsiTypeParameter.EMPTY_ARRAY override fun getTypeParameters(): Array<PsiTypeParameter> = PsiTypeParameter.EMPTY_ARRAY
@@ -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.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.api.symbols.sourcePsiSafe import org.jetbrains.kotlin.analysis.api.symbols.sourcePsiSafe
import org.jetbrains.kotlin.analysis.project.structure.KtModule 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.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.KtLightField import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier 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.load.java.structure.LightClassOriginKind
import org.jetbrains.kotlin.psi.KtClassBody import org.jetbrains.kotlin.psi.KtClassBody
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtObjectDeclaration
import org.jetbrains.kotlin.psi.debugText.getDebugText import org.jetbrains.kotlin.psi.debugText.getDebugText
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
import org.jetbrains.kotlin.utils.addToStdlib.ifTrue import org.jetbrains.kotlin.utils.addToStdlib.ifTrue
@@ -67,26 +65,6 @@ abstract class SymbolLightClassForClassLike<SType : KtClassOrObjectSymbol> prote
classOrObjectDeclaration?.isTopLevel() ?: withClassOrObjectSymbol { it.symbolKind == KtSymbolKind.TOP_LEVEL } 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 { private val _isDeprecated: Boolean by lazyPub {
withClassOrObjectSymbol { it.hasDeprecatedAnnotation() } withClassOrObjectSymbol { it.hasDeprecatedAnnotation() }
} }
@@ -94,9 +72,9 @@ abstract class SymbolLightClassForClassLike<SType : KtClassOrObjectSymbol> prote
override fun isDeprecated(): Boolean = _isDeprecated override fun isDeprecated(): Boolean = _isDeprecated
abstract override fun getModifierList(): PsiModifierList? abstract override fun getModifierList(): PsiModifierList?
abstract override fun getOwnFields(): List<KtLightField> abstract override fun getOwnFields(): List<KtLightField>
abstract override fun getOwnMethods(): List<PsiMethod> abstract override fun getOwnMethods(): List<PsiMethod>
private val _identifier: PsiIdentifier by lazyPub { private val _identifier: PsiIdentifier by lazyPub {
KtLightIdentifier(this, classOrObjectDeclaration) KtLightIdentifier(this, classOrObjectDeclaration)
} }
@@ -104,6 +82,7 @@ abstract class SymbolLightClassForClassLike<SType : KtClassOrObjectSymbol> prote
override fun getNameIdentifier(): PsiIdentifier? = _identifier override fun getNameIdentifier(): PsiIdentifier? = _identifier
abstract override fun getExtendsList(): PsiReferenceList? abstract override fun getExtendsList(): PsiReferenceList?
abstract override fun getImplementsList(): PsiReferenceList? abstract override fun getImplementsList(): PsiReferenceList?
private val _typeParameterList: PsiTypeParameterList? by lazyPub { private val _typeParameterList: PsiTypeParameterList? by lazyPub {
@@ -120,6 +99,7 @@ abstract class SymbolLightClassForClassLike<SType : KtClassOrObjectSymbol> prote
override fun hasTypeParameters(): Boolean = hasTypeParameters(ktModule, classOrObjectDeclaration, classOrObjectSymbolPointer) override fun hasTypeParameters(): Boolean = hasTypeParameters(ktModule, classOrObjectDeclaration, classOrObjectSymbolPointer)
override fun getTypeParameterList(): PsiTypeParameterList? = _typeParameterList override fun getTypeParameterList(): PsiTypeParameterList? = _typeParameterList
override fun getTypeParameters(): Array<PsiTypeParameter> = _typeParameterList?.typeParameters ?: PsiTypeParameter.EMPTY_ARRAY override fun getTypeParameters(): Array<PsiTypeParameter> = _typeParameterList?.typeParameters ?: PsiTypeParameter.EMPTY_ARRAY
private val _ownInnerClasses: List<SymbolLightClassBase> by lazyPub { private val _ownInnerClasses: List<SymbolLightClassBase> by lazyPub {
@@ -131,9 +111,9 @@ abstract class SymbolLightClassForClassLike<SType : KtClassOrObjectSymbol> prote
override fun getOwnInnerClasses(): List<PsiClass> = _ownInnerClasses override fun getOwnInnerClasses(): List<PsiClass> = _ownInnerClasses
override fun getTextOffset(): Int = classOrObjectDeclaration?.textOffset ?: -1 override fun getTextOffset(): Int = classOrObjectDeclaration?.textOffset ?: -1
override fun getStartOffsetInParent(): Int = classOrObjectDeclaration?.startOffsetInParent ?: -1 override fun getStartOffsetInParent(): Int = classOrObjectDeclaration?.startOffsetInParent ?: -1
override fun isWritable() = false override fun isWritable() = false
override fun getNavigationElement(): PsiElement = classOrObjectDeclaration ?: this override fun getNavigationElement(): PsiElement = classOrObjectDeclaration ?: this
override fun isEquivalentTo(another: PsiElement?): Boolean = override fun isEquivalentTo(another: PsiElement?): Boolean =
@@ -161,9 +141,10 @@ abstract class SymbolLightClassForClassLike<SType : KtClassOrObjectSymbol> prote
override fun hasModifierProperty(@NonNls name: String): Boolean = modifierList?.hasModifierProperty(name) ?: false override fun hasModifierProperty(@NonNls name: String): Boolean = modifierList?.hasModifierProperty(name) ?: false
abstract override fun isInterface(): Boolean abstract fun classKind(): KtClassKind
abstract override fun isAnnotationType(): Boolean override fun isInterface(): Boolean = classKind().let { it == KtClassKind.INTERFACE || it == KtClassKind.ANNOTATION_CLASS }
abstract override fun isEnum(): Boolean 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) override fun isValid(): Boolean = classOrObjectDeclaration?.isValid ?: classOrObjectSymbolPointer.isValid(ktModule)
@@ -189,14 +170,7 @@ abstract class SymbolLightClassForClassLike<SType : KtClassOrObjectSymbol> prote
return null return null
} }
override fun getParent(): PsiElement? { abstract override fun getParent(): PsiElement?
if (isLocal) {
return classOrObjectDeclaration?.let(::getParentForLocalDeclaration)
}
return containingClass ?: containingFile
}
override fun getScope(): PsiElement? = parent override fun getScope(): PsiElement? = parent
override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean = override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean =
@@ -35,10 +35,7 @@ import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassM
import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtEnumEntry
import org.jetbrains.kotlin.resolve.DataClassResolver import org.jetbrains.kotlin.resolve.DataClassResolver
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
import org.jetbrains.kotlin.util.OperatorNameConventions.EQUALS import org.jetbrains.kotlin.util.OperatorNameConventions.EQUALS
@@ -119,7 +116,7 @@ internal open class SymbolLightClassForClassOrObject : SymbolLightClassForNamedC
val declaredMemberScope = classOrObjectSymbol.getDeclaredMemberScope() val declaredMemberScope = classOrObjectSymbol.getDeclaredMemberScope()
val visibleDeclarations = declaredMemberScope.getCallableSymbols() val visibleDeclarations = declaredMemberScope.getCallableSymbols()
.applyIf(isObject) { .applyIf(classKind().isObject) {
filterNot { filterNot {
it is KtKotlinPropertySymbol && it.isConst it is KtKotlinPropertySymbol && it.isConst
} }
@@ -138,7 +135,7 @@ internal open class SymbolLightClassForClassOrObject : SymbolLightClassForNamedC
it.hasTypeForValueClassInSignature() it.hasTypeForValueClassInSignature()
} }
val suppressStatic = isCompanionObject val suppressStatic = classKind() == KtClassKind.COMPANION_OBJECT
createMethods(visibleDeclarations, result, suppressStatic = suppressStatic) createMethods(visibleDeclarations, result, suppressStatic = suppressStatic)
createConstructors(declaredMemberScope.getConstructors(), result) createConstructors(declaredMemberScope.getConstructors(), result)
@@ -267,7 +264,7 @@ internal open class SymbolLightClassForClassOrObject : SymbolLightClassForNamedC
context(KtAnalysisSession) context(KtAnalysisSession)
private fun addInstanceFieldIfNeeded(result: MutableList<KtLightField>, namedClassOrObjectSymbol: KtNamedClassOrObjectSymbol) { private fun addInstanceFieldIfNeeded(result: MutableList<KtLightField>, namedClassOrObjectSymbol: KtNamedClassOrObjectSymbol) {
if (!isNamedObject || isLocal) return if (classKind() != KtClassKind.OBJECT || isLocal) return
result.add( result.add(
SymbolLightFieldForObject( SymbolLightFieldForObject(
@@ -299,15 +296,22 @@ internal open class SymbolLightClassForClassOrObject : SymbolLightClassForNamedC
override fun isInterface(): Boolean = false override fun isInterface(): Boolean = false
override fun isAnnotationType(): Boolean = false override fun isAnnotationType(): Boolean = false
override fun classKind(): KtClassKind = _classKind
private val _isEnum: Boolean by lazyPub { private val _classKind: KtClassKind by lazyPub {
classOrObjectDeclaration?.let { it is KtClass && it.isEnum() } ?: withClassOrObjectSymbol { when (classOrObjectDeclaration) {
it.classKind == KtClassKind.ENUM_CLASS 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 = override fun copy(): SymbolLightClassForClassOrObject =
SymbolLightClassForClassOrObject(classOrObjectDeclaration, classOrObjectSymbolPointer, ktModule, manager) SymbolLightClassForClassOrObject(classOrObjectDeclaration, classOrObjectSymbolPointer, ktModule, manager)
} }
@@ -78,5 +78,5 @@ internal open class SymbolLightClassForInterface : SymbolLightClassForInterfaceO
} }
override fun getExtendsList(): PsiReferenceList? = _extendsList override fun getExtendsList(): PsiReferenceList? = _extendsList
override fun isAnnotationType(): Boolean = false override fun classKind(): KtClassKind = KtClassKind.INTERFACE
} }
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.light.classes.symbol.classes
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.util.IncorrectOperationException 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.SimpleModifiersBox
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList
import org.jetbrains.kotlin.load.java.JvmAbi 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), modifiersBox = SimpleModifiersBox(PsiModifier.PUBLIC, PsiModifier.STATIC, PsiModifier.FINAL),
) )
override fun isInterface(): Boolean = false override fun classKind(): KtClassKind = KtClassKind.CLASS
override fun isDeprecated(): Boolean = false
override fun isAnnotationType(): Boolean = false
override fun hasTypeParameters(): Boolean = false override fun hasTypeParameters(): Boolean = false
override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean = override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean =
baseClass.qualifiedName == CommonClassNames.JAVA_LANG_OBJECT baseClass.qualifiedName == CommonClassNames.JAVA_LANG_OBJECT
@@ -82,9 +82,6 @@ internal abstract class SymbolLightClassForInterfaceOrAnnotationClass : SymbolLi
computeModifierList() computeModifierList()
} }
override fun isInterface(): Boolean = true
override fun isEnum(): Boolean = false
final override fun getModifierList(): PsiModifierList? = _modifierList final override fun getModifierList(): PsiModifierList? = _modifierList
private val _ownFields: List<KtLightField> by lazyPub { private val _ownFields: List<KtLightField> by lazyPub {
@@ -5,14 +5,18 @@
package org.jetbrains.kotlin.light.classes.symbol.classes package org.jetbrains.kotlin.light.classes.symbol.classes
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiManager import com.intellij.psi.PsiManager
import com.intellij.psi.PsiModifier import com.intellij.psi.PsiModifier
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol 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.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.project.structure.KtModule 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.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
@@ -52,6 +56,18 @@ abstract class SymbolLightClassForNamedClassLike : SymbolLightClassForClassLike<
manager = manager 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) context(KtAnalysisSession)
protected fun addMethodsFromCompanionIfNeeded( protected fun addMethodsFromCompanionIfNeeded(
result: MutableList<KtLightMethod>, result: MutableList<KtLightMethod>,
@@ -169,7 +169,7 @@ private fun SymbolLightClassBase.shouldGenerateNoArgOverload(
private fun SymbolLightClassBase.defaultConstructor(): KtLightMethod { private fun SymbolLightClassBase.defaultConstructor(): KtLightMethod {
val classOrObject = kotlinOrigin val classOrObject = kotlinOrigin
val visibility = when { 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 classOrObject?.hasModifier(SEALED_KEYWORD) == true -> PsiModifier.PROTECTED
this is SymbolLightClassForEnumEntry -> PsiModifier.PACKAGE_LOCAL this is SymbolLightClassForEnumEntry -> PsiModifier.PACKAGE_LOCAL
else -> PsiModifier.PUBLIC else -> PsiModifier.PUBLIC