From 207212e5b82f9e6854dce3cc4f48a1c85ac05a82 Mon Sep 17 00:00:00 2001 From: Dmitrii Gridin Date: Sat, 26 Nov 2022 16:20:02 +0100 Subject: [PATCH] [SLC] support non-psi classes ^KT-54051 --- .../pointers/KtPsiBasedSymbolPointer.kt | 45 +--- .../classes/SymbolLightAnnotationClass.kt | 44 +++- .../classes/SymbolLightAnonymousClass.kt | 32 ++- .../symbol/classes/SymbolLightClass.kt | 132 +++++++---- .../SymbolLightClassForClassOrObject.kt | 205 ++++++++---------- .../classes/SymbolLightClassForEnumEntry.kt | 11 +- ...ymbolLightClassForInterfaceDefaultImpls.kt | 12 +- .../SymbolLightClassForNamedClassOrObject.kt | 122 +++++++++++ .../symbol/classes/SymbolLightInlineClass.kt | 33 ++- .../classes/SymbolLightInterfaceClass.kt | 44 +++- .../SymbolLightInterfaceOrAnnotationClass.kt | 62 +++++- .../symbol/classes/symbolLightClassUtils.kt | 86 ++++++-- .../fields/SymbolLightFieldForEnumEntry.kt | 4 +- .../fields/SymbolLightFieldForObject.kt | 50 +++-- .../methods/SymbolLightNoArgConstructor.kt | 4 +- 15 files changed, 614 insertions(+), 272 deletions(-) create mode 100644 analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForNamedClassOrObject.kt diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/pointers/KtPsiBasedSymbolPointer.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/pointers/KtPsiBasedSymbolPointer.kt index d09efa7b1b2..3777ddf1278 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/pointers/KtPsiBasedSymbolPointer.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/symbols/pointers/KtPsiBasedSymbolPointer.kt @@ -97,36 +97,15 @@ public class KtPsiBasedSymbolPointer private constructor( public fun KtElement.symbolPointer(): KtSymbolPointer = KtPsiBasedSymbolPointer(this, KtSymbol::class) public inline fun KtElement.symbolPointerOfType(): KtSymbolPointer = KtPsiBasedSymbolPointer(this, S::class) -public fun KtFile.symbolPointer(): KtSymbolPointer = KtPsiBasedSymbolPointer(this, KtFileSymbol::class) -public fun KtParameter.symbolPointer(): KtSymbolPointer = KtPsiBasedSymbolPointer(this, KtVariableLikeSymbol::class) -public fun KtTypeAlias.symbolPointer(): KtSymbolPointer = KtPsiBasedSymbolPointer(this, KtTypeAliasSymbol::class) -public fun KtEnumEntry.symbolPointer(): KtSymbolPointer = KtPsiBasedSymbolPointer(this, KtEnumEntrySymbol::class) -public fun KtProperty.symbolPointer(): KtSymbolPointer = KtPsiBasedSymbolPointer(this, KtVariableSymbol::class) - -public fun KtNamedFunction.symbolPointer(): KtSymbolPointer { - return KtPsiBasedSymbolPointer(this, KtFunctionLikeSymbol::class) -} - -public fun KtConstructor<*>.symbolPointer(): KtSymbolPointer { - return KtPsiBasedSymbolPointer(this, KtConstructorSymbol::class) -} - -public fun KtTypeParameter.symbolPointer(): KtSymbolPointer { - return KtPsiBasedSymbolPointer(this, KtTypeParameterSymbol::class) -} - -public fun KtFunctionLiteral.symbolPointer(): KtSymbolPointer { - return KtPsiBasedSymbolPointer(this, KtAnonymousFunctionSymbol::class) -} - -public fun KtObjectLiteralExpression.symbolPointer(): KtSymbolPointer { - return KtPsiBasedSymbolPointer(this, KtAnonymousObjectSymbol::class) -} - -public fun KtClassOrObject.symbolPointer(): KtSymbolPointer { - return KtPsiBasedSymbolPointer(this, KtClassOrObjectSymbol::class) -} - -public fun KtPropertyAccessor.symbolPointer(): KtSymbolPointer { - return KtPsiBasedSymbolPointer(this, KtPropertyAccessorSymbol::class) -} +public fun KtFile.symbolPointer(): KtSymbolPointer = symbolPointerOfType() +public fun KtParameter.symbolPointer(): KtSymbolPointer = symbolPointerOfType() +public fun KtTypeAlias.symbolPointer(): KtSymbolPointer = symbolPointerOfType() +public fun KtEnumEntry.symbolPointer(): KtSymbolPointer = symbolPointerOfType() +public fun KtProperty.symbolPointer(): KtSymbolPointer = symbolPointerOfType() +public fun KtNamedFunction.symbolPointer(): KtSymbolPointer = symbolPointerOfType() +public fun KtConstructor<*>.symbolPointer(): KtSymbolPointer = symbolPointerOfType() +public fun KtTypeParameter.symbolPointer(): KtSymbolPointer = symbolPointerOfType() +public fun KtFunctionLiteral.symbolPointer(): KtSymbolPointer = symbolPointerOfType() +public fun KtObjectLiteralExpression.symbolPointer(): KtSymbolPointer = symbolPointerOfType() +public fun KtPropertyAccessor.symbolPointer(): KtSymbolPointer = symbolPointerOfType() +public fun KtClassOrObject.symbolPointer(): KtSymbolPointer = symbolPointerOfType() diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightAnnotationClass.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightAnnotationClass.kt index 74718021406..0c9b2ea1b4a 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightAnnotationClass.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightAnnotationClass.kt @@ -5,24 +5,53 @@ package org.jetbrains.kotlin.light.classes.symbol.classes +import com.intellij.psi.PsiManager import com.intellij.psi.PsiMethod import com.intellij.psi.PsiReferenceList +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol import org.jetbrains.kotlin.analysis.api.symbols.markers.isPrivateOrPrivateToThis +import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClassOrObject -internal class SymbolLightAnnotationClass( - classOrObject: KtClassOrObject, - ktModule: KtModule, -) : SymbolLightInterfaceOrAnnotationClass(classOrObject, ktModule) { - init { - require(isAnnotation) +internal class SymbolLightAnnotationClass : SymbolLightInterfaceOrAnnotationClass { + constructor( + ktAnalysisSession: KtAnalysisSession, + ktModule: KtModule, + classOrObjectSymbol: KtNamedClassOrObjectSymbol, + manager: PsiManager + ) : super( + ktAnalysisSession = ktAnalysisSession, + ktModule = ktModule, + classOrObjectSymbol = classOrObjectSymbol, + manager = manager, + ) { + require(classOrObjectSymbol.classKind == KtClassKind.ANNOTATION_CLASS) } + constructor(classOrObject: KtClassOrObject, ktModule: KtModule) : super(classOrObject, ktModule) { + require(classOrObject is KtClass && classOrObject.isAnnotation()) + } + + private constructor( + classOrObjectDeclaration: KtClassOrObject?, + classOrObjectSymbolPointer: KtSymbolPointer, + ktModule: KtModule, + manager: PsiManager, + ) : super( + classOrObjectDeclaration = classOrObjectDeclaration, + classOrObjectSymbolPointer = classOrObjectSymbolPointer, + ktModule = ktModule, + manager = manager, + ) + override fun isAnnotationType(): Boolean = true private val _ownMethods: List by lazyPub { @@ -41,5 +70,6 @@ internal class SymbolLightAnnotationClass( override fun getExtendsList(): PsiReferenceList? = null - override fun copy(): SymbolLightClassForClassOrObject = SymbolLightAnnotationClass(classOrObject, ktModule) + override fun copy(): SymbolLightAnnotationClass = + SymbolLightAnnotationClass(classOrObjectDeclaration, classOrObjectSymbolPointer, ktModule, manager) } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightAnonymousClass.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightAnonymousClass.kt index f244cd13205..6b496fd254a 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightAnonymousClass.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightAnonymousClass.kt @@ -6,7 +6,10 @@ 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.KtPropertySymbol +import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer +import org.jetbrains.kotlin.analysis.api.symbols.pointers.symbolPointerOfType import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.asJava.classes.getParentForLocalDeclaration import org.jetbrains.kotlin.asJava.classes.lazyPub @@ -17,8 +20,23 @@ import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmFieldAnnotati import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightField import org.jetbrains.kotlin.psi.KtClassOrObject -internal class SymbolLightAnonymousClass(classOrObject: KtClassOrObject, ktModule: KtModule) : - SymbolLightClassForClassOrObject(classOrObject, ktModule), PsiAnonymousClass { +internal class SymbolLightAnonymousClass : SymbolLightClassForClassOrObject, PsiAnonymousClass { + constructor( + anonymousObjectDeclaration: KtClassOrObject, + ktModule: KtModule, + ) : this( + classOrObjectDeclaration = anonymousObjectDeclaration, + classOrObjectSymbolPointer = anonymousObjectDeclaration.symbolPointerOfType(), + ktModule = ktModule, + manager = anonymousObjectDeclaration.manager, + ) + + private constructor( + classOrObjectDeclaration: KtClassOrObject?, + classOrObjectSymbolPointer: KtSymbolPointer, + ktModule: KtModule, + manager: PsiManager, + ) : super(classOrObjectDeclaration, classOrObjectSymbolPointer, ktModule, manager) private val _baseClassType: PsiClassType by lazyPub { extendsListTypes.firstOrNull() @@ -43,8 +61,8 @@ internal class SymbolLightAnonymousClass(classOrObject: KtClassOrObject, ktModul } } - override fun getExtendsList(): PsiReferenceList = _extendsList - override fun getImplementsList(): PsiReferenceList = _implementsList + override fun getExtendsList(): PsiReferenceList? = _extendsList + override fun getImplementsList(): PsiReferenceList? = _implementsList override fun getOwnFields(): List = _ownFields override fun getOwnMethods(): List = _ownMethods @@ -74,7 +92,7 @@ internal class SymbolLightAnonymousClass(classOrObject: KtClassOrObject, ktModul isTopLevel = false, forceStatic = false, takePropertyVisibility = propertySymbol.hasJvmFieldAnnotation(), - result + result, ) } @@ -82,7 +100,7 @@ internal class SymbolLightAnonymousClass(classOrObject: KtClassOrObject, ktModul } } - override fun getParent(): PsiElement? = kotlinOrigin.let(::getParentForLocalDeclaration) + override fun getParent(): PsiElement? = kotlinOrigin?.let(::getParentForLocalDeclaration) override fun getArgumentList(): PsiExpressionList? = null override fun isInQualifiedNew(): Boolean = false override fun getName(): String? = null @@ -93,5 +111,5 @@ internal class SymbolLightAnonymousClass(classOrObject: KtClassOrObject, ktModul override fun getTypeParameters(): Array = PsiTypeParameter.EMPTY_ARRAY override fun getTypeParameterList(): PsiTypeParameterList? = null override fun getQualifiedName(): String? = null - override fun copy() = SymbolLightAnonymousClass(classOrObject, ktModule) + override fun copy() = SymbolLightAnonymousClass(classOrObjectDeclaration, classOrObjectSymbolPointer, ktModule, manager) } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClass.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClass.kt index 52cd3326ed5..dc026f3004c 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClass.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClass.kt @@ -5,13 +5,12 @@ package org.jetbrains.kotlin.light.classes.symbol.classes -import com.intellij.psi.PsiMethod -import com.intellij.psi.PsiModifier -import com.intellij.psi.PsiModifierList -import com.intellij.psi.PsiReferenceList +import com.intellij.psi.* import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers +import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer +import org.jetbrains.kotlin.analysis.api.symbols.pointers.symbolPointerOfType import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration import org.jetbrains.kotlin.asJava.classes.METHOD_INDEX_BASE @@ -36,7 +35,10 @@ import org.jetbrains.kotlin.light.classes.symbol.toPsiVisibilityForClass import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.StandardClassIds -import org.jetbrains.kotlin.psi.* +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.resolve.DataClassResolver import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind import org.jetbrains.kotlin.util.OperatorNameConventions.EQUALS @@ -44,15 +46,48 @@ import org.jetbrains.kotlin.util.OperatorNameConventions.TO_STRING import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addToStdlib.applyIf -internal open class SymbolLightClass(classOrObject: KtClassOrObject, ktModule: KtModule) : - SymbolLightClassForClassOrObject(classOrObject, ktModule) { - init { +internal open class SymbolLightClass : SymbolLightClassForNamedClassOrObject { + constructor( + ktAnalysisSession: KtAnalysisSession, + ktModule: KtModule, + classOrObjectSymbol: KtNamedClassOrObjectSymbol, + manager: PsiManager + ) : super( + ktAnalysisSession = ktAnalysisSession, + ktModule = ktModule, + classOrObjectSymbol = classOrObjectSymbol, + manager = manager, + ) { + require(classOrObjectSymbol.classKind != KtClassKind.INTERFACE && classOrObjectSymbol.classKind != KtClassKind.ANNOTATION_CLASS) + } + + constructor( + classOrObject: KtClassOrObject, + ktModule: KtModule, + ) : this( + classOrObjectDeclaration = classOrObject, + classOrObjectSymbolPointer = classOrObject.symbolPointerOfType(), + ktModule = ktModule, + manager = classOrObject.manager, + ) { require(classOrObject !is KtClass || !classOrObject.isInterface() && !classOrObject.isAnnotation()) } + protected constructor( + classOrObjectDeclaration: KtClassOrObject?, + classOrObjectSymbolPointer: KtSymbolPointer, + ktModule: KtModule, + manager: PsiManager, + ) : super( + classOrObjectDeclaration = classOrObjectDeclaration, + classOrObjectSymbolPointer = classOrObjectSymbolPointer, + ktModule = ktModule, + manager = manager, + ) + private val _modifierList: PsiModifierList? by lazy { val lazyModifiers = lazy { - withNamedClassOrObjectSymbol { classOrObjectSymbol -> + withClassOrObjectSymbol { classOrObjectSymbol -> buildSet { add(classOrObjectSymbol.toPsiVisibilityForClass(isNested = !isTopLevel)) addIfNotNull(classOrObjectSymbol.computeSimpleModality()) @@ -64,7 +99,7 @@ internal open class SymbolLightClass(classOrObject: KtClassOrObject, ktModule: K } val lazyAnnotations = lazyPub { - withNamedClassOrObjectSymbol { classOrObjectSymbol -> + withClassOrObjectSymbol { classOrObjectSymbol -> classOrObjectSymbol.computeAnnotations( parent = this@SymbolLightClass, nullability = NullabilityType.Unknown, @@ -95,7 +130,7 @@ internal open class SymbolLightClass(classOrObject: KtClassOrObject, ktModule: K } private val _ownMethods: List by lazyPub { - withNamedClassOrObjectSymbol { classOrObjectSymbol -> + withClassOrObjectSymbol { classOrObjectSymbol -> val result = mutableListOf() val declaredMemberScope = classOrObjectSymbol.getDeclaredMemberScope() @@ -138,12 +173,16 @@ internal open class SymbolLightClass(classOrObject: KtClassOrObject, ktModule: K fun createMethodFromAny(ktFunctionSymbol: KtFunctionSymbol) { // Similar to `copy`, synthetic members from `Any` should refer to `data` class as origin, not the function in `Any`. - val lightMemberOrigin = LightMemberOriginForDeclaration(classOrObject, JvmDeclarationOriginKind.OTHER) + val lightMemberOrigin = classOrObjectDeclaration?.let { LightMemberOriginForDeclaration(it, JvmDeclarationOriginKind.OTHER) } result.add( SymbolLightSimpleMethod( ktAnalysisSession = this@ktAnalysisSession, - ktFunctionSymbol, lightMemberOrigin, this, METHOD_INDEX_BASE, false, - suppressStatic = false + ktFunctionSymbol, + lightMemberOrigin, + this, + METHOD_INDEX_BASE, + false, + suppressStatic = false, ) ) } @@ -189,8 +228,8 @@ internal open class SymbolLightClass(classOrObject: KtClassOrObject, ktModule: K context(ktAnalysisSession@KtAnalysisSession) private fun addDelegatesToInterfaceMethods(result: MutableList, classOrObjectSymbol: KtNamedClassOrObjectSymbol) { fun createDelegateMethod(ktFunctionSymbol: KtFunctionSymbol) { - val kotlinOrigin = ktFunctionSymbol.psiSafe() ?: classOrObject - val lightMemberOrigin = LightMemberOriginForDeclaration(kotlinOrigin, JvmDeclarationOriginKind.DELEGATION) + val kotlinOrigin = ktFunctionSymbol.psiSafe() ?: classOrObjectDeclaration + val lightMemberOrigin = kotlinOrigin?.let { LightMemberOriginForDeclaration(it, JvmDeclarationOriginKind.DELEGATION) } result.add( SymbolLightSimpleMethod( ktAnalysisSession = this@ktAnalysisSession, @@ -213,18 +252,18 @@ internal open class SymbolLightClass(classOrObject: KtClassOrObject, ktModule: K } private val _ownFields: List by lazyPub { - withNamedClassOrObjectSymbol { classOrObjectSymbol -> + withClassOrObjectSymbol { classOrObjectSymbol -> val result = mutableListOf() // First, add static fields: companion object and fields from companion object - addCompanionObjectFieldIfNeeded(result) - addFieldsFromCompanionIfNeeded(result) + addCompanionObjectFieldIfNeeded(result, classOrObjectSymbol) + addFieldsFromCompanionIfNeeded(result, classOrObjectSymbol) // Then, add instance fields: properties from parameters, and then member properties addPropertyBackingFields(result, classOrObjectSymbol) // Next, add INSTANCE field if non-local named object - addInstanceFieldIfNeeded(result) + addInstanceFieldIfNeeded(result, classOrObjectSymbol) // Last, add fields for enum entries addFieldsForEnumEntries(result, classOrObjectSymbol) @@ -271,40 +310,41 @@ internal open class SymbolLightClass(classOrObject: KtClassOrObject, ktModule: K propertyGroups[false]?.forEach(::addPropertyBackingField) } - private fun addInstanceFieldIfNeeded(result: MutableList) { - if (isNamedObject && !isLocal) { - result.add( - SymbolLightFieldForObject( - objectDeclaration = classOrObject as KtObjectDeclaration, - containingClass = this@SymbolLightClass, - name = JvmAbi.INSTANCE_FIELD, - lightMemberOrigin = null - ) + context(ktAnalysisSession@KtAnalysisSession) + private fun addInstanceFieldIfNeeded(result: MutableList, namedClassOrObjectSymbol: KtNamedClassOrObjectSymbol) { + if (!isNamedObject || isLocal) return + + result.add( + SymbolLightFieldForObject( + ktAnalysisSession = this@ktAnalysisSession, + objectSymbol = namedClassOrObjectSymbol, + containingClass = this, + name = JvmAbi.INSTANCE_FIELD, + lightMemberOrigin = null, ) - } + ) } - context(KtAnalysisSession) + context(ktAnalysisSession@KtAnalysisSession) private fun addFieldsForEnumEntries(result: MutableList, classOrObjectSymbol: KtNamedClassOrObjectSymbol) { - if (isEnum) { - classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols() - .filterIsInstance() - .mapNotNullTo(result) { - val enumEntry = it.psiSafe() - val name = enumEntry?.name ?: return@mapNotNullTo null - SymbolLightFieldForEnumEntry( - enumEntry = enumEntry, - enumEntryName = name, - containingClass = this@SymbolLightClass, - lightMemberOrigin = null, - ) - } - } + if (!isEnum) return + + classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols() + .filterIsInstance() + .mapNotNullTo(result) { + val enumEntry = it.psiSafe() + val name = enumEntry?.name ?: return@mapNotNullTo null + SymbolLightFieldForEnumEntry( + enumEntry = enumEntry, + enumEntryName = name, + containingClass = this@SymbolLightClass, + ) + } } override fun isInterface(): Boolean = false override fun isAnnotationType(): Boolean = false - override fun copy(): SymbolLightClass = SymbolLightClass(classOrObject, ktModule) + override fun copy(): SymbolLightClass = SymbolLightClass(classOrObjectDeclaration, classOrObjectSymbolPointer, ktModule, manager) } 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 e05c6020942..14c85c960b2 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 @@ -8,30 +8,24 @@ package org.jetbrains.kotlin.light.classes.symbol.classes import com.intellij.psi.* import com.intellij.psi.impl.InheritanceImplUtil import com.intellij.psi.impl.PsiClassImplUtil +import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.SearchScope import com.intellij.psi.stubs.IStubElementType import com.intellij.psi.stubs.StubElement import org.jetbrains.annotations.NonNls import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.symbols.* +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.symbolPointer 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 -import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.asJava.toLightClass -import org.jetbrains.kotlin.light.classes.symbol.analyzeForLightClasses +import org.jetbrains.kotlin.light.classes.symbol.* import org.jetbrains.kotlin.light.classes.symbol.annotations.hasDeprecatedAnnotation -import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmFieldAnnotation -import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmStaticAnnotation -import org.jetbrains.kotlin.light.classes.symbol.basicIsEquivalentTo -import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForObject -import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForProperty import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightTypeParameterList -import org.jetbrains.kotlin.light.classes.symbol.withSymbol import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClassBody @@ -39,32 +33,76 @@ 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.applyIf import org.jetbrains.kotlin.utils.addToStdlib.ifTrue -import org.jetbrains.kotlin.utils.addToStdlib.safeAs -abstract class SymbolLightClassForClassOrObject(protected val classOrObject: KtClassOrObject, ktModule: KtModule) : - SymbolLightClassBase(ktModule, classOrObject.manager), +abstract class SymbolLightClassForClassOrObject protected constructor( + internal val classOrObjectDeclaration: KtClassOrObject?, + internal val classOrObjectSymbolPointer: KtSymbolPointer, + ktModule: KtModule, + manager: PsiManager, +) : SymbolLightClassBase(ktModule, manager), StubBasedPsiElement> { - private val classOrObjectSymbolPointer: KtSymbolPointer = classOrObject.symbolPointer() + constructor( + ktAnalysisSession: KtAnalysisSession, + ktModule: KtModule, + classOrObjectSymbol: SType, + manager: PsiManager, + ) : this( + classOrObjectDeclaration = classOrObjectSymbol.sourcePsiSafe(), + classOrObjectSymbolPointer = with(ktAnalysisSession) { + @Suppress("UNCHECKED_CAST") + classOrObjectSymbol.createPointer() as KtSymbolPointer + }, + ktModule = ktModule, + manager = manager, + ) - protected fun withClassOrObjectSymbol(action: KtAnalysisSession.(KtClassOrObjectSymbol) -> T): T { - return classOrObjectSymbolPointer.withSymbol(ktModule, action) + override val kotlinOrigin: KtClassOrObject? get() = classOrObjectDeclaration + + protected fun withClassOrObjectSymbol(action: KtAnalysisSession.(SType) -> T): T = + classOrObjectSymbolPointer.withSymbol(ktModule, action) + + override val isTopLevel: Boolean by lazy { + classOrObjectDeclaration?.isTopLevel() ?: withClassOrObjectSymbol { it.symbolKind == KtSymbolKind.TOP_LEVEL } } - protected fun withNamedClassOrObjectSymbol(action: KtAnalysisSession.(KtNamedClassOrObjectSymbol) -> T): T = - analyzeForLightClasses(ktModule) { - action(requireNotNull(classOrObject.getNamedClassOrObjectSymbol())) + internal val isCompanionObject: Boolean by lazy { + classOrObjectDeclaration?.let { it is KtObjectDeclaration && it.isCompanion() } ?: withClassOrObjectSymbol { + it.classKind == KtClassKind.COMPANION_OBJECT } + } - override val isTopLevel: Boolean get() = classOrObject.isTopLevel() - internal val isCompanionObject: Boolean get() = classOrObject is KtObjectDeclaration && classOrObject.isCompanion() - internal val isLocal: Boolean get() = classOrObject.isLocal - internal val isNamedObject: Boolean get() = classOrObject is KtObjectDeclaration && !classOrObject.isCompanion() - internal val isObject: Boolean get() = classOrObject is KtObjectDeclaration - internal val isInterface: Boolean get() = classOrObject is KtClass && classOrObject.isInterface() - internal val isAnnotation: Boolean get() = classOrObject is KtClass && classOrObject.isAnnotation() - internal val isEnum: Boolean get() = classOrObject is KtClass && classOrObject.isEnum() + internal val isLocal: Boolean by lazy { + classOrObjectDeclaration?.isLocal ?: withClassOrObjectSymbol { it.symbolKind == KtSymbolKind.LOCAL } + } + + internal val isNamedObject: Boolean by lazy { + classOrObjectDeclaration?.let { it is KtObjectDeclaration && !it.isCompanion() } ?: withClassOrObjectSymbol { + it.classKind == KtClassKind.OBJECT + } + } + + internal val isObject: Boolean by lazy { + classOrObjectDeclaration?.let { it is KtObjectDeclaration } ?: withClassOrObjectSymbol { it.classKind.isObject } + } + + internal val isInterface: Boolean by lazy { + classOrObjectDeclaration?.let { it is KtClass && it.isInterface() } ?: withClassOrObjectSymbol { + it.classKind == KtClassKind.INTERFACE + } + } + + internal val isAnnotation: Boolean by lazy { + classOrObjectDeclaration?.let { it is KtClass && it.isAnnotation() } ?: withClassOrObjectSymbol { + it.classKind == KtClassKind.ANNOTATION_CLASS + } + } + + internal val isEnum: Boolean by lazy { + classOrObjectDeclaration?.let { it is KtClass && it.isEnum() } ?: withClassOrObjectSymbol { + it.classKind == KtClassKind.ENUM_CLASS + } + } private val _isDeprecated: Boolean by lazy { withClassOrObjectSymbol { it.hasDeprecatedAnnotation() } @@ -77,7 +115,7 @@ abstract class SymbolLightClassForClassOrObject(protected val classOrObject: KtC abstract override fun getOwnMethods(): List private val _identifier: PsiIdentifier by lazy { - KtLightIdentifier(this, classOrObject) + KtLightIdentifier(this, classOrObjectDeclaration) } override fun getNameIdentifier(): PsiIdentifier? = _identifier @@ -91,96 +129,29 @@ abstract class SymbolLightClassForClassOrObject(protected val classOrObject: KtC owner = this, symbolWithTypeParameterPointer = classOrObjectSymbolPointer, ktModule = ktModule, - ktDeclaration = classOrObject, + ktDeclaration = classOrObjectDeclaration, ) } } - override fun hasTypeParameters(): Boolean = classOrObject.typeParameters.isNotEmpty() + 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 { withClassOrObjectSymbol { - it.createInnerClasses(this@SymbolLightClassForClassOrObject, classOrObject) + it.createInnerClasses(manager, this@SymbolLightClassForClassOrObject, classOrObjectDeclaration) } } override fun getOwnInnerClasses(): List = _ownInnerClasses - override fun getTextOffset(): Int = classOrObject.textOffset - override fun getStartOffsetInParent(): Int = classOrObject.startOffsetInParent + override fun getTextOffset(): Int = classOrObjectDeclaration?.textOffset ?: -1 + override fun getStartOffsetInParent(): Int = classOrObjectDeclaration?.startOffsetInParent ?: -1 override fun isWritable() = false - override val kotlinOrigin: KtClassOrObject = classOrObject - protected fun addMethodsFromCompanionIfNeeded( - result: MutableList, - ): Unit = withNamedClassOrObjectSymbol { classOrObjectSymbol -> - classOrObjectSymbol.companionObject?.run { - val methods = getDeclaredMemberScope().getCallableSymbols() - .filterIsInstance() - .filter { it.hasJvmStaticAnnotation() } - - createMethods(methods, result) - - val properties = getDeclaredMemberScope().getCallableSymbols().filterIsInstance() - properties.forEach { property -> - createPropertyAccessors( - result, - property, - isTopLevel = false, - onlyJvmStatic = true - ) - } - } - } - - protected fun addCompanionObjectFieldIfNeeded(result: MutableList) { - classOrObject.companionObjects.forEach { - result.add( - SymbolLightFieldForObject( - objectDeclaration = it, - containingClass = this@SymbolLightClassForClassOrObject, - name = it.name ?: return@forEach, - lightMemberOrigin = null, - ) - ) - } - } - - protected fun addFieldsFromCompanionIfNeeded( - result: MutableList, - ): Unit = withNamedClassOrObjectSymbol { classOrObjectSymbol -> - classOrObjectSymbol.companionObject - ?.getDeclaredMemberScope() - ?.getCallableSymbols() - ?.filterIsInstance() - ?.applyIf(isInterface) { - filter { it.isConstOrJvmField } - } - ?.mapTo(result) { - SymbolLightFieldForProperty( - ktAnalysisSession = this, - propertySymbol = it, - fieldName = it.name.asString(), - containingClass = this@SymbolLightClassForClassOrObject, - lightMemberOrigin = null, - isTopLevel = false, - forceStatic = true, - takePropertyVisibility = it.isConstOrJvmField, - ) - } - - } - - private val KtPropertySymbol.isConstOrJvmField: Boolean - get() = isConst || hasJvmFieldAnnotation() - - private val KtPropertySymbol.isConst: Boolean - get() = (this as? KtKotlinPropertySymbol)?.isConst == true - - override fun getNavigationElement(): PsiElement = classOrObject + override fun getNavigationElement(): PsiElement = classOrObjectDeclaration ?: this override fun isEquivalentTo(another: PsiElement?): Boolean = basicIsEquivalentTo(this, another) || @@ -188,13 +159,21 @@ abstract class SymbolLightClassForClassOrObject(protected val classOrObject: KtC override fun equals(other: Any?): Boolean { if (this === other) return true + if (other !is SymbolLightClassForClassOrObject<*> || other.ktModule != ktModule || other.manager != manager) return false + if (classOrObjectDeclaration != null) { + return other.classOrObjectDeclaration == classOrObjectDeclaration + } - return other?.safeAs()?.classOrObject == classOrObject + return other.classOrObjectDeclaration == null && compareSymbolPointers( + ktModule, + classOrObjectSymbolPointer, + other.classOrObjectSymbolPointer, + ) } - override fun hashCode(): Int = classOrObject.hashCode() + override fun hashCode(): Int = classOrObjectDeclaration.hashCode() - override fun getName(): String? = classOrObject.name + override fun getName(): String? = classOrObjectDeclaration?.name override fun hasModifierProperty(@NonNls name: String): Boolean = modifierList?.hasModifierProperty(name) ?: false @@ -202,17 +181,17 @@ abstract class SymbolLightClassForClassOrObject(protected val classOrObject: KtC override fun isAnnotationType(): Boolean = isAnnotation override fun isEnum(): Boolean = isEnum - override fun isValid(): Boolean = classOrObject.isValid + override fun isValid(): Boolean = classOrObjectDeclaration?.isValid ?: classOrObjectSymbolPointer.isValid(ktModule) - override fun toString() = "${this::class.java.simpleName}:${classOrObject.getDebugText()}" + override fun toString() = "${this::class.java.simpleName}:${classOrObjectDeclaration?.getDebugText()}" - override fun getUseScope(): SearchScope = classOrObject.useScope - override fun getElementType(): IStubElementType, *>? = classOrObject.elementType - override fun getStub(): KotlinClassOrObjectStub? = classOrObject.stub + override fun getUseScope(): SearchScope = classOrObjectDeclaration?.useScope ?: GlobalSearchScope.projectScope(project) + override fun getElementType(): IStubElementType, *>? = classOrObjectDeclaration?.elementType + override fun getStub(): KotlinClassOrObjectStub? = classOrObjectDeclaration?.stub override val originKind: LightClassOriginKind get() = LightClassOriginKind.SOURCE - override fun getQualifiedName() = classOrObject.fqName?.asString() + override fun getQualifiedName(): String? = classOrObjectDeclaration?.fqName?.asString() override fun getInterfaces(): Array = PsiClassImplUtil.getInterfaces(this) override fun getSuperClass(): PsiClass? = PsiClassImplUtil.getSuperClass(this) @@ -220,7 +199,7 @@ abstract class SymbolLightClassForClassOrObject(protected val classOrObject: KtC override fun getSuperTypes(): Array = PsiClassImplUtil.getSuperTypes(this) override fun getContainingClass(): PsiClass? { - val containingBody = classOrObject.parent as? KtClassBody + val containingBody = classOrObjectDeclaration?.parent as? KtClassBody val containingClass = containingBody?.parent as? KtClassOrObject containingClass?.let { return it.toLightClass() } return null @@ -228,7 +207,7 @@ abstract class SymbolLightClassForClassOrObject(protected val classOrObject: KtC override fun getParent(): PsiElement? { if (isLocal) { - return classOrObject.let(::getParentForLocalDeclaration) + return classOrObjectDeclaration?.let(::getParentForLocalDeclaration) } return containingClass ?: containingFile @@ -239,5 +218,5 @@ abstract class SymbolLightClassForClassOrObject(protected val classOrObject: KtC override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean = baseClass?.let { InheritanceImplUtil.isInheritorDeep(this, it, classToByPass) } ?: false - abstract override fun copy(): SymbolLightClassForClassOrObject + abstract override fun copy(): SymbolLightClassForClassOrObject<*> } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForEnumEntry.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForEnumEntry.kt index d2417c6cd17..8f593fa4969 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForEnumEntry.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForEnumEntry.kt @@ -6,6 +6,8 @@ package org.jetbrains.kotlin.light.classes.symbol.classes import com.intellij.psi.* +import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.api.symbols.pointers.symbolPointer import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.asJava.classes.KotlinSuperTypeListBuilder @@ -20,7 +22,12 @@ internal class SymbolLightClassForEnumEntry( private val enumConstant: SymbolLightFieldForEnumEntry, private val enumClass: SymbolLightClass, ktModule: KtModule, -) : SymbolLightClass(enumConstant.kotlinOrigin, ktModule), PsiEnumConstantInitializer { +) : SymbolLightClass( + enumConstant.kotlinOrigin, + symbolPointer { null }, + ktModule, + enumClass.manager, +), PsiEnumConstantInitializer { override fun getBaseClassType(): PsiClassType = enumConstant.type as PsiClassType //???TODO override fun getBaseClassReference(): PsiJavaCodeReferenceElement = @@ -63,7 +70,7 @@ internal class SymbolLightClassForEnumEntry( } ?: return@lazyPub null KotlinSuperTypeListBuilder( - kotlinOrigin = enumClass.kotlinOrigin.getSuperTypeList(), + kotlinOrigin = enumClass.kotlinOrigin?.getSuperTypeList(), manager = manager, language = language, role = PsiReferenceList.Role.EXTENDS_LIST 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 1194a0112e4..07f6b218407 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 @@ -11,7 +11,12 @@ import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassM import org.jetbrains.kotlin.load.java.JvmAbi internal class SymbolLightClassForInterfaceDefaultImpls(private val containingClass: SymbolLightInterfaceClass) : - SymbolLightInterfaceClass(containingClass.kotlinOrigin, containingClass.ktModule) { + SymbolLightInterfaceClass( + containingClass.classOrObjectDeclaration, + containingClass.classOrObjectSymbolPointer, + containingClass.ktModule, + containingClass.manager, + ) { override fun getQualifiedName(): String? = containingClass.qualifiedName?.let { it + ".${JvmAbi.DEFAULT_IMPLS_CLASS_NAME}" } override fun getName() = JvmAbi.DEFAULT_IMPLS_CLASS_NAME @@ -19,6 +24,11 @@ internal class SymbolLightClassForInterfaceDefaultImpls(private val containingCl override fun copy() = SymbolLightClassForInterfaceDefaultImpls(containingClass) + override fun equals(other: Any?): Boolean = this === other || + other is SymbolLightClassForInterfaceDefaultImpls && other.containingClass == containingClass + + override fun hashCode(): Int = containingClass.hashCode() + override fun getTypeParameterList(): PsiTypeParameterList? = null override fun getTypeParameters(): Array = emptyArray() diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForNamedClassOrObject.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForNamedClassOrObject.kt new file mode 100644 index 00000000000..28435353ca5 --- /dev/null +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForNamedClassOrObject.kt @@ -0,0 +1,122 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.light.classes.symbol.classes + +import com.intellij.psi.PsiManager +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtKotlinPropertySymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol +import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer +import org.jetbrains.kotlin.analysis.project.structure.KtModule +import org.jetbrains.kotlin.asJava.elements.KtLightField +import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmFieldAnnotation +import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmStaticAnnotation +import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForObject +import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForProperty +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.utils.addToStdlib.applyIf + +abstract class SymbolLightClassForNamedClassOrObject : SymbolLightClassForClassOrObject { + constructor( + ktAnalysisSession: KtAnalysisSession, + ktModule: KtModule, + classOrObjectSymbol: KtNamedClassOrObjectSymbol, + manager: PsiManager + ) : super( + ktAnalysisSession = ktAnalysisSession, + ktModule = ktModule, + classOrObjectSymbol = classOrObjectSymbol, + manager = manager, + ) + + protected constructor( + classOrObjectDeclaration: KtClassOrObject?, + classOrObjectSymbolPointer: KtSymbolPointer, + ktModule: KtModule, + manager: PsiManager, + ) : super( + classOrObjectDeclaration = classOrObjectDeclaration, + classOrObjectSymbolPointer = classOrObjectSymbolPointer, + ktModule = ktModule, + manager = manager + ) + + protected fun addMethodsFromCompanionIfNeeded( + result: MutableList, + ): Unit = withClassOrObjectSymbol { classOrObjectSymbol -> + classOrObjectSymbol.companionObject?.run { + val methods = getDeclaredMemberScope().getCallableSymbols() + .filterIsInstance() + .filter { it.hasJvmStaticAnnotation() } + + createMethods(methods, result) + + val properties = getDeclaredMemberScope().getCallableSymbols().filterIsInstance() + properties.forEach { property -> + createPropertyAccessors( + result, + property, + isTopLevel = false, + onlyJvmStatic = true + ) + } + } + } + + private val KtPropertySymbol.isConstOrJvmField: Boolean + get() = isConst || hasJvmFieldAnnotation() + + private val KtPropertySymbol.isConst: Boolean + get() = (this as? KtKotlinPropertySymbol)?.isConst == true + + context(ktAnalysisSession@KtAnalysisSession) + protected fun addFieldsFromCompanionIfNeeded( + result: MutableList, + classOrObjectSymbol: KtNamedClassOrObjectSymbol, + ) { + classOrObjectSymbol.companionObject + ?.getDeclaredMemberScope() + ?.getCallableSymbols() + ?.filterIsInstance() + ?.applyIf(isInterface) { + filter { it.isConstOrJvmField } + } + ?.mapTo(result) { + SymbolLightFieldForProperty( + ktAnalysisSession = this@ktAnalysisSession, + propertySymbol = it, + fieldName = it.name.asString(), + containingClass = this, + lightMemberOrigin = null, + isTopLevel = false, + forceStatic = true, + takePropertyVisibility = it.isConstOrJvmField, + ) + } + } + + context(ktAnalysisSession@KtAnalysisSession) + protected fun addCompanionObjectFieldIfNeeded(result: MutableList, classOrObjectSymbol: KtNamedClassOrObjectSymbol) { + val companionObjectSymbols: List? = classOrObjectDeclaration?.companionObjects?.mapNotNull { + it.getNamedClassOrObjectSymbol() + } ?: classOrObjectSymbol.companionObject?.let(::listOf) + + companionObjectSymbols?.forEach { + result.add( + SymbolLightFieldForObject( + ktAnalysisSession = this@ktAnalysisSession, + objectSymbol = it, + containingClass = this, + name = it.name.asString(), + lightMemberOrigin = null, + ) + ) + } + } +} \ No newline at end of file diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightInlineClass.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightInlineClass.kt index 4de9b6ec10f..86d5342d885 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightInlineClass.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightInlineClass.kt @@ -5,9 +5,13 @@ package org.jetbrains.kotlin.light.classes.symbol.classes +import com.intellij.psi.PsiManager import com.intellij.psi.PsiMethod 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.pointers.KtSymbolPointer +import org.jetbrains.kotlin.analysis.api.symbols.pointers.symbolPointerOfType import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.elements.KtLightField @@ -16,11 +20,31 @@ import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue -internal class SymbolLightInlineClass(classOrObject: KtClassOrObject, ktModule: KtModule) : SymbolLightClass(classOrObject, ktModule) { - init { +internal class SymbolLightInlineClass : SymbolLightClass { + constructor( + classOrObject: KtClassOrObject, + ktModule: KtModule, + ) : this( + classOrObjectDeclaration = classOrObject, + classOrObjectSymbolPointer = classOrObject.symbolPointerOfType(), + ktModule = ktModule, + manager = classOrObject.manager, + ) { require(classOrObject.hasModifier(KtTokens.INLINE_KEYWORD)) } + private constructor( + classOrObjectDeclaration: KtClassOrObject?, + classOrObjectSymbolPointer: KtSymbolPointer, + ktModule: KtModule, + manager: PsiManager, + ) : super( + classOrObjectDeclaration = classOrObjectDeclaration, + classOrObjectSymbolPointer = classOrObjectSymbolPointer, + ktModule = ktModule, + manager = manager, + ) + private val _ownMethods: List by lazyPub { withClassOrObjectSymbol { classOrObjectSymbol -> val result = mutableListOf() @@ -59,7 +83,7 @@ internal class SymbolLightInlineClass(classOrObject: KtClassOrObject, ktModule: } private val _ownFields: List by lazyPub { - withNamedClassOrObjectSymbol { classOrObjectSymbol -> + withClassOrObjectSymbol { classOrObjectSymbol -> mutableListOf().apply { addPropertyBackingFields(this, classOrObjectSymbol) } @@ -70,5 +94,6 @@ internal class SymbolLightInlineClass(classOrObject: KtClassOrObject, ktModule: override fun getOwnFields(): List = _ownFields - override fun copy(): SymbolLightInlineClass = SymbolLightInlineClass(classOrObject, ktModule) + override fun copy(): SymbolLightInlineClass = + SymbolLightInlineClass(classOrObjectDeclaration, classOrObjectSymbolPointer, ktModule, manager) } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightInterfaceClass.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightInterfaceClass.kt index 587dfa22f38..a66b7ab32ab 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightInterfaceClass.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightInterfaceClass.kt @@ -5,23 +5,52 @@ package org.jetbrains.kotlin.light.classes.symbol.classes +import com.intellij.psi.PsiManager import com.intellij.psi.PsiMethod import com.intellij.psi.PsiReferenceList +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol import org.jetbrains.kotlin.analysis.api.symbols.markers.isPrivateOrPrivateToThis +import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClassOrObject -internal open class SymbolLightInterfaceClass( - classOrObject: KtClassOrObject, - ktModule: KtModule, -) : SymbolLightInterfaceOrAnnotationClass(classOrObject, ktModule) { - init { - require(isInterface) +internal open class SymbolLightInterfaceClass : SymbolLightInterfaceOrAnnotationClass { + constructor( + ktAnalysisSession: KtAnalysisSession, + ktModule: KtModule, + classOrObjectSymbol: KtNamedClassOrObjectSymbol, + manager: PsiManager + ) : super( + ktAnalysisSession = ktAnalysisSession, + ktModule = ktModule, + classOrObjectSymbol = classOrObjectSymbol, + manager = manager, + ) { + require(classOrObjectSymbol.classKind == KtClassKind.INTERFACE) } + constructor(classOrObject: KtClassOrObject, ktModule: KtModule) : super(classOrObject, ktModule) { + require(classOrObject is KtClass && classOrObject.isInterface()) + } + + protected constructor( + classOrObjectDeclaration: KtClassOrObject?, + classOrObjectSymbolPointer: KtSymbolPointer, + ktModule: KtModule, + manager: PsiManager, + ) : super( + classOrObjectDeclaration = classOrObjectDeclaration, + classOrObjectSymbolPointer = classOrObjectSymbolPointer, + ktModule = ktModule, + manager = manager, + ) + private val _ownMethods: List by lazyPub { withClassOrObjectSymbol { classOrObjectSymbol -> val result = mutableListOf() @@ -38,7 +67,8 @@ internal open class SymbolLightInterfaceClass( override fun getOwnMethods(): List = _ownMethods - override fun copy(): SymbolLightClassForClassOrObject = SymbolLightInterfaceClass(classOrObject, ktModule) + override fun copy(): SymbolLightInterfaceClass = + SymbolLightInterfaceClass(classOrObjectDeclaration, classOrObjectSymbolPointer, ktModule, manager) private val _extendsList: PsiReferenceList by lazyPub { withClassOrObjectSymbol { classOrObjectSymbol -> diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightInterfaceOrAnnotationClass.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightInterfaceOrAnnotationClass.kt index 504e273f621..aaf0b99690d 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightInterfaceOrAnnotationClass.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightInterfaceOrAnnotationClass.kt @@ -5,9 +5,15 @@ package org.jetbrains.kotlin.light.classes.symbol.classes +import com.intellij.psi.PsiManager import com.intellij.psi.PsiModifier import com.intellij.psi.PsiModifierList import com.intellij.psi.PsiReferenceList +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind +import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer +import org.jetbrains.kotlin.analysis.api.symbols.pointers.symbolPointerOfType import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.elements.KtLightField @@ -15,18 +21,52 @@ import org.jetbrains.kotlin.light.classes.symbol.NullabilityType import org.jetbrains.kotlin.light.classes.symbol.annotations.computeAnnotations import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList import org.jetbrains.kotlin.light.classes.symbol.toPsiVisibilityForClass +import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClassOrObject -internal abstract class SymbolLightInterfaceOrAnnotationClass(classOrObject: KtClassOrObject, ktModule: KtModule) : - SymbolLightClassForClassOrObject(classOrObject, ktModule) { - - init { - require(isInterface || isAnnotation) +internal abstract class SymbolLightInterfaceOrAnnotationClass : SymbolLightClassForNamedClassOrObject { + constructor( + ktAnalysisSession: KtAnalysisSession, + ktModule: KtModule, + classOrObjectSymbol: KtNamedClassOrObjectSymbol, + manager: PsiManager + ) : super( + ktAnalysisSession = ktAnalysisSession, + ktModule = ktModule, + classOrObjectSymbol = classOrObjectSymbol, + manager = manager, + ) { + val classKind = classOrObjectSymbol.classKind + require(classKind == KtClassKind.INTERFACE || classKind == KtClassKind.ANNOTATION_CLASS) } + constructor( + classOrObject: KtClassOrObject, + ktModule: KtModule, + ) : this( + classOrObjectDeclaration = classOrObject, + classOrObjectSymbolPointer = classOrObject.symbolPointerOfType(), + ktModule = ktModule, + manager = classOrObject.manager, + ) { + require(classOrObject is KtClass && (classOrObject.isInterface() || classOrObject.isAnnotation())) + } + + protected constructor( + classOrObjectDeclaration: KtClassOrObject?, + classOrObjectSymbolPointer: KtSymbolPointer, + ktModule: KtModule, + manager: PsiManager, + ) : super( + classOrObjectDeclaration = classOrObjectDeclaration, + classOrObjectSymbolPointer = classOrObjectSymbolPointer, + ktModule = ktModule, + manager = manager, + ) + private val _modifierList: PsiModifierList? by lazy { val lazyModifiers = lazy { - withNamedClassOrObjectSymbol { classOrObjectSymbol -> + withClassOrObjectSymbol { classOrObjectSymbol -> buildSet { add(classOrObjectSymbol.toPsiVisibilityForClass(isNested = !isTopLevel)) add(PsiModifier.ABSTRACT) @@ -38,7 +78,7 @@ internal abstract class SymbolLightInterfaceOrAnnotationClass(classOrObject: KtC } val lazyAnnotations = lazyPub { - withNamedClassOrObjectSymbol { classOrObjectSymbol -> + withClassOrObjectSymbol { classOrObjectSymbol -> classOrObjectSymbol.computeAnnotations( parent = this@SymbolLightInterfaceOrAnnotationClass, nullability = NullabilityType.Unknown, @@ -56,9 +96,11 @@ internal abstract class SymbolLightInterfaceOrAnnotationClass(classOrObject: KtC override fun getModifierList(): PsiModifierList? = _modifierList private val _ownFields: List by lazyPub { - mutableListOf().also { - addCompanionObjectFieldIfNeeded(it) - addFieldsFromCompanionIfNeeded(it) + withClassOrObjectSymbol { classOrObjectSymbol -> + buildList { + addCompanionObjectFieldIfNeeded(this, classOrObjectSymbol) + addFieldsFromCompanionIfNeeded(this, classOrObjectSymbol) + } } } 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 bc793083eb3..684516796a6 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 @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.light.classes.symbol.classes +import com.intellij.psi.PsiManager import com.intellij.psi.PsiModifier import com.intellij.psi.PsiReferenceList import org.jetbrains.kotlin.analysis.api.KtAnalysisSession @@ -50,16 +51,44 @@ import java.util.* internal fun createSymbolLightClassNoCache(classOrObject: KtClassOrObject, ktModule: KtModule): KtLightClass? = when { classOrObject.isObjectLiteral() -> SymbolLightAnonymousClass(classOrObject, ktModule) classOrObject is KtEnumEntry -> lightClassForEnumEntry(classOrObject) - classOrObject.hasModifier(INLINE_KEYWORD) -> SymbolLightInlineClass(classOrObject, ktModule) else -> createLightClassNoCache(classOrObject, ktModule) } internal fun createLightClassNoCache(ktClassOrObject: KtClassOrObject, ktModule: KtModule): SymbolLightClassBase = when { + ktClassOrObject.hasModifier(INLINE_KEYWORD) -> SymbolLightInlineClass(ktClassOrObject, ktModule) ktClassOrObject is KtClass && ktClassOrObject.isAnnotation() -> SymbolLightAnnotationClass(ktClassOrObject, ktModule) ktClassOrObject is KtClass && ktClassOrObject.isInterface() -> SymbolLightInterfaceClass(ktClassOrObject, ktModule) else -> SymbolLightClass(ktClassOrObject, ktModule) } +context(ktAnalysisSession@KtAnalysisSession) +internal fun createLightClassNoCache( + ktClassOrObjectSymbol: KtNamedClassOrObjectSymbol, + ktModule: KtModule, + manager: PsiManager, +): SymbolLightClassBase = when (ktClassOrObjectSymbol.classKind) { + KtClassKind.INTERFACE -> SymbolLightInterfaceClass( + ktAnalysisSession = this@ktAnalysisSession, + ktModule = ktModule, + classOrObjectSymbol = ktClassOrObjectSymbol, + manager = manager, + ) + + KtClassKind.ANNOTATION_CLASS -> SymbolLightAnnotationClass( + ktAnalysisSession = this@ktAnalysisSession, + ktModule = ktModule, + classOrObjectSymbol = ktClassOrObjectSymbol, + manager = manager, + ) + + else -> SymbolLightClass( + ktAnalysisSession = this@ktAnalysisSession, + ktModule = ktModule, + classOrObjectSymbol = ktClassOrObjectSymbol, + manager = manager, + ) +} + private fun lightClassForEnumEntry(ktEnumEntry: KtEnumEntry): KtLightClass? { if (ktEnumEntry.body == null) return null @@ -72,7 +101,7 @@ private fun lightClassForEnumEntry(ktEnumEntry: KtEnumEntry): KtLightClass? { } context(ktAnalysisSession@KtAnalysisSession) -internal fun SymbolLightClassForClassOrObject.createConstructors( +internal fun SymbolLightClassForClassOrObject<*>.createConstructors( declarations: Sequence, result: MutableList, ) { @@ -129,26 +158,28 @@ private fun SymbolLightClassBase.shouldGenerateNoArgOverload( !primaryConstructor.hasJvmOverloadsAnnotation() } -private fun SymbolLightClassForClassOrObject.defaultConstructor(): KtLightMethod { +private fun SymbolLightClassForClassOrObject<*>.defaultConstructor(): KtLightMethod { val classOrObject = kotlinOrigin val visibility = when { - classOrObject is KtObjectDeclaration || isEnum -> PsiModifier.PRIVATE - classOrObject.hasModifier(SEALED_KEYWORD) -> PsiModifier.PROTECTED - classOrObject is KtEnumEntry -> PsiModifier.PACKAGE_LOCAL + isObject || isEnum -> PsiModifier.PRIVATE + classOrObject?.hasModifier(SEALED_KEYWORD) == true -> PsiModifier.PROTECTED + this is SymbolLightClassForEnumEntry -> PsiModifier.PACKAGE_LOCAL else -> PsiModifier.PUBLIC } return noArgConstructor(visibility, METHOD_INDEX_FOR_DEFAULT_CTOR) } -private fun SymbolLightClassForClassOrObject.noArgConstructor( +private fun SymbolLightClassForClassOrObject<*>.noArgConstructor( visibility: String, methodIndex: Int, ): KtLightMethod = SymbolLightNoArgConstructor( - LightMemberOriginForDeclaration( - originalElement = kotlinOrigin, - originKind = JvmDeclarationOriginKind.OTHER, - ), + kotlinOrigin?.let { + LightMemberOriginForDeclaration( + originalElement = it, + originKind = JvmDeclarationOriginKind.OTHER, + ) + }, this, visibility, methodIndex, @@ -350,14 +381,17 @@ internal fun SymbolLightClassBase.createField( } context(KtAnalysisSession) -internal fun SymbolLightClassForClassOrObject.createInheritanceList(forExtendsList: Boolean, superTypes: List): PsiReferenceList { +internal fun SymbolLightClassForClassOrObject<*>.createInheritanceList( + forExtendsList: Boolean, + superTypes: List, +): PsiReferenceList { val role = if (forExtendsList) PsiReferenceList.Role.EXTENDS_LIST else PsiReferenceList.Role.IMPLEMENTS_LIST val listBuilder = KotlinSuperTypeListBuilder( - kotlinOrigin = kotlinOrigin.getSuperTypeList(), + kotlinOrigin = kotlinOrigin?.getSuperTypeList(), manager = manager, language = language, - role = role + role = role, ) fun KtType.needToAddTypeIntoList(): Boolean { @@ -404,8 +438,9 @@ internal fun SymbolLightClassForClassOrObject.createInheritanceList(forExtendsLi context(KtAnalysisSession) internal fun KtSymbolWithMembers.createInnerClasses( + manager: PsiManager, containingClass: SymbolLightClassBase, - classOrObject: KtClassOrObject + classOrObject: KtClassOrObject? ): List { val result = ArrayList() @@ -414,16 +449,23 @@ internal fun KtSymbolWithMembers.createInnerClasses( // we can't prohibit creating light classes with null names either since they can contain members getDeclaredMemberScope().getClassifierSymbols().filterIsInstance().mapTo(result) { - createLightClassNoCache(it.psi(), ktModule = containingClass.ktModule) + val classOrObjectDeclaration = it.psiSafe() + if (classOrObjectDeclaration != null) { + createLightClassNoCache(classOrObjectDeclaration, containingClass.ktModule) + } else { + createLightClassNoCache(it, ktModule = containingClass.ktModule, manager) + } } - val jvmDefaultMode = - classOrObject.getKtModuleOfTypeSafe()?.languageVersionSettings?.getFlag(JvmAnalysisFlags.jvmDefaultMode) - ?: JvmDefaultMode.DEFAULT + val jvmDefaultMode = classOrObject + ?.getKtModuleOfTypeSafe() + ?.languageVersionSettings + ?.getFlag(JvmAnalysisFlags.jvmDefaultMode) + ?: JvmDefaultMode.DEFAULT - if (classOrObject.hasInterfaceDefaultImpls && - jvmDefaultMode != JvmDefaultMode.ALL_INCOMPATIBLE && - containingClass is SymbolLightInterfaceClass + if (containingClass is SymbolLightInterfaceClass && + classOrObject?.hasInterfaceDefaultImpls == true && + jvmDefaultMode != JvmDefaultMode.ALL_INCOMPATIBLE ) { result.add(SymbolLightClassForInterfaceDefaultImpls(containingClass)) } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForEnumEntry.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForEnumEntry.kt index 94b7440579b..56f061285a0 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForEnumEntry.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForEnumEntry.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.light.classes.symbol.fields import com.intellij.psi.* import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol -import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin import org.jetbrains.kotlin.asJava.classes.cannotModify import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget @@ -26,8 +25,7 @@ internal class SymbolLightFieldForEnumEntry( private val enumEntry: KtEnumEntry, private val enumEntryName: String, containingClass: SymbolLightClass, - override val lightMemberOrigin: LightMemberOrigin?, -) : SymbolLightField(containingClass, lightMemberOrigin), PsiEnumConstant { +) : SymbolLightField(containingClass = containingClass, lightMemberOrigin = null), PsiEnumConstant { internal fun withEnumEntrySymbol(action: KtAnalysisSession.(KtEnumEntrySymbol) -> T): T = analyzeForLightClasses(ktModule) { action(enumEntry.getEnumEntrySymbol()) } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForObject.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForObject.kt index f75c5dc5917..9abe7fa6537 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForObject.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/fields/SymbolLightFieldForObject.kt @@ -12,29 +12,40 @@ import com.intellij.psi.PsiType import org.jetbrains.annotations.NotNull import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer +import org.jetbrains.kotlin.analysis.api.symbols.sourcePsiSafe import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin import org.jetbrains.kotlin.asJava.classes.lazyPub -import org.jetbrains.kotlin.light.classes.symbol.analyzeForLightClasses +import org.jetbrains.kotlin.light.classes.symbol.* import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolLightSimpleAnnotation import org.jetbrains.kotlin.light.classes.symbol.annotations.hasDeprecatedAnnotation import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForClassOrObject import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightMemberModifierList -import org.jetbrains.kotlin.light.classes.symbol.nonExistentType -import org.jetbrains.kotlin.light.classes.symbol.toPsiVisibilityForMember import org.jetbrains.kotlin.psi.KtObjectDeclaration -internal class SymbolLightFieldForObject( - private val objectDeclaration: KtObjectDeclaration, - containingClass: SymbolLightClassForClassOrObject, +internal class SymbolLightFieldForObject private constructor( + containingClass: SymbolLightClassForClassOrObject<*>, private val name: String, lightMemberOrigin: LightMemberOrigin?, + private val objectSymbolPointer: KtSymbolPointer, + override val kotlinOrigin: KtObjectDeclaration?, ) : SymbolLightField(containingClass, lightMemberOrigin) { - private fun withObjectDeclarationSymbol(action: KtAnalysisSession.(KtNamedClassOrObjectSymbol) -> T): T = - analyzeForLightClasses(ktModule) { - action(requireNotNull(objectDeclaration.getNamedClassOrObjectSymbol())) - } + internal constructor( + ktAnalysisSession: KtAnalysisSession, + objectSymbol: KtNamedClassOrObjectSymbol, + name: String, + lightMemberOrigin: LightMemberOrigin?, + containingClass: SymbolLightClassForClassOrObject<*>, + ) : this( + containingClass = containingClass, + name = name, + lightMemberOrigin = lightMemberOrigin, + kotlinOrigin = objectSymbol.sourcePsiSafe(), + objectSymbolPointer = with(ktAnalysisSession) { objectSymbol.createPointer() }, + ) - override val kotlinOrigin: KtObjectDeclaration = objectDeclaration + private fun withObjectDeclarationSymbol(action: KtAnalysisSession.(KtNamedClassOrObjectSymbol) -> T): T = + objectSymbolPointer.withSymbol(ktModule, action) override fun getName(): String = name @@ -73,10 +84,19 @@ internal class SymbolLightFieldForObject( override fun getInitializer(): PsiExpression? = null //TODO - override fun equals(other: Any?): Boolean = - this === other || other is SymbolLightFieldForObject && objectDeclaration == other.objectDeclaration + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is SymbolLightFieldForObject || other.ktModule != ktModule) return false + if (kotlinOrigin != null) { + return other.kotlinOrigin == kotlinOrigin + } - override fun hashCode(): Int = objectDeclaration.hashCode() + return other.kotlinOrigin == null && + other.containingClass == containingClass && + compareSymbolPointers(ktModule, other.objectSymbolPointer, objectSymbolPointer) + } - override fun isValid(): Boolean = objectDeclaration.isValid + override fun hashCode(): Int = kotlinOrigin.hashCode() + + override fun isValid(): Boolean = kotlinOrigin?.isValid ?: objectSymbolPointer.isValid(ktModule) } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightNoArgConstructor.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightNoArgConstructor.kt index 495ca92076b..8eeee8c0d0d 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightNoArgConstructor.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/methods/SymbolLightNoArgConstructor.kt @@ -13,8 +13,8 @@ import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightMember import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightParameterList internal class SymbolLightNoArgConstructor( - lightMemberOrigin: LightMemberOrigin, - containingClass: SymbolLightClassForClassOrObject, + lightMemberOrigin: LightMemberOrigin?, + containingClass: SymbolLightClassForClassOrObject<*>, private val visibility: String, methodIndex: Int, ) : SymbolLightMethodBase(lightMemberOrigin, containingClass, methodIndex) {