[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 {
val kotlinOrigin = kotlinOrigin ?: return@lazyPub null
@@ -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<PsiMethod> = withClassOrObjectSymbol { classOrObjectSymbol ->
val result = mutableListOf<KtLightMethod>()
@@ -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> = 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.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<SType : KtClassOrObjectSymbol> 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<SType : KtClassOrObjectSymbol> prote
override fun isDeprecated(): Boolean = _isDeprecated
abstract override fun getModifierList(): PsiModifierList?
abstract override fun getOwnFields(): List<KtLightField>
abstract override fun getOwnMethods(): List<PsiMethod>
private val _identifier: PsiIdentifier by lazyPub {
KtLightIdentifier(this, classOrObjectDeclaration)
}
@@ -104,6 +82,7 @@ abstract class SymbolLightClassForClassLike<SType : KtClassOrObjectSymbol> 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<SType : KtClassOrObjectSymbol> prote
override fun hasTypeParameters(): Boolean = hasTypeParameters(ktModule, classOrObjectDeclaration, classOrObjectSymbolPointer)
override fun getTypeParameterList(): PsiTypeParameterList? = _typeParameterList
override fun getTypeParameters(): Array<PsiTypeParameter> = _typeParameterList?.typeParameters ?: PsiTypeParameter.EMPTY_ARRAY
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 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<SType : KtClassOrObjectSymbol> 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<SType : KtClassOrObjectSymbol> 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 =
@@ -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<KtLightField>, 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)
}
@@ -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
}
@@ -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
@@ -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<KtLightField> by lazyPub {
@@ -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<KtLightMethod>,
@@ -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