diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/SymbolKotlinAsJavaSupport.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/SymbolKotlinAsJavaSupport.kt index cd59c829324..9905a8aa37f 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/SymbolKotlinAsJavaSupport.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/SymbolKotlinAsJavaSupport.kt @@ -101,7 +101,7 @@ class SymbolKotlinAsJavaSupport(project: Project) : KotlinAsJavaSupportBase): KtLightClassForFacade? { @@ -123,8 +123,11 @@ class SymbolKotlinAsJavaSupport(project: Project) : KotlinAsJavaSupportBase, - ): KtLightClassForFacade = analyzeForLightClasses(files.first()) { - SymbolLightClassForFacade(facadeFqName, files) + ): KtLightClassForFacade { + val firstFile = files.first() + return analyzeForLightClasses(firstFile) { + SymbolLightClassForFacade(facadeFqName, files, firstFile.getKtModule(project)) + } } override val KtModule.contentSearchScope: GlobalSearchScope get() = this.contentScope diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolBasedFakeLightClass.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolBasedFakeLightClass.kt index 5c99dceeb9c..2a211e6b4d9 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolBasedFakeLightClass.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolBasedFakeLightClass.kt @@ -30,7 +30,7 @@ class SymbolBasedFakeLightClass(kotlinOrigin: KtClassOrObject) : LightClassInheritanceHelper.getService(project).isInheritor(this, baseClass, checkDeep).ifSure { return it } val baseClassOrigin = (baseClass as? KtLightClass)?.kotlinOrigin ?: return false - return analyzeForLightClasses(baseClassOrigin) { + return analyzeForLightClasses(kotlinOrigin) { kotlinOrigin.checkIsInheritor(baseClassOrigin, checkDeep) } } 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 7e139d550fe..74718021406 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,52 +5,41 @@ 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.lifetime.isValid -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.project.structure.KtModule import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.psi.KtClassOrObject -context(KtAnalysisSession) internal class SymbolLightAnnotationClass( - private val classOrObjectSymbol: KtNamedClassOrObjectSymbol, - manager: PsiManager -) : SymbolLightInterfaceOrAnnotationClass(classOrObjectSymbol, manager) { - + classOrObject: KtClassOrObject, + ktModule: KtModule, +) : SymbolLightInterfaceOrAnnotationClass(classOrObject, ktModule) { init { - require(classOrObjectSymbol.classKind == KtClassKind.ANNOTATION_CLASS) + require(isAnnotation) } override fun isAnnotationType(): Boolean = true private val _ownMethods: List by lazyPub { - val result = mutableListOf() - val visibleDeclarations = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols() - .filterNot { it is KtFunctionSymbol && it.visibility.isPrivateOrPrivateToThis() } - .filterNot { it is KtConstructorSymbol } + withClassOrObjectSymbol { classOrObjectSymbol -> + val result = mutableListOf() + val visibleDeclarations = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols() + .filterNot { it is KtFunctionSymbol && it.visibility.isPrivateOrPrivateToThis() } + .filterNot { it is KtConstructorSymbol } - createMethods(visibleDeclarations, result) - result + createMethods(visibleDeclarations, result) + result + } } override fun getOwnMethods(): List = _ownMethods override fun getExtendsList(): PsiReferenceList? = null - override fun equals(other: Any?): Boolean = - other is SymbolLightAnnotationClass && classOrObjectSymbol == other.classOrObjectSymbol - - override fun hashCode(): Int = classOrObjectSymbol.hashCode() - - - override fun isValid(): Boolean = super.isValid() && classOrObjectSymbol.isValid() - - override fun copy(): SymbolLightClassForClassOrObject = SymbolLightAnnotationClass(classOrObjectSymbol, manager) + override fun copy(): SymbolLightClassForClassOrObject = SymbolLightAnnotationClass(classOrObject, ktModule) } 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 735c8a7acee..f244cd13205 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,15 +6,8 @@ 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.SearchScope -import com.intellij.psi.stubs.IStubElementType -import com.intellij.psi.stubs.StubElement -import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.lifetime.isValid -import org.jetbrains.kotlin.analysis.api.symbols.KtAnonymousObjectSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol +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 @@ -22,17 +15,10 @@ import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmFieldAnnotation import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightField -import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind import org.jetbrains.kotlin.psi.KtClassOrObject -import org.jetbrains.kotlin.psi.debugText.getDebugText -import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub -context(KtAnalysisSession) -internal class SymbolLightAnonymousClass( - private val anonymousObjectSymbol: KtAnonymousObjectSymbol, - manager: PsiManager -) : SymbolLightClassBase(manager), - StubBasedPsiElement>, PsiAnonymousClass { +internal class SymbolLightAnonymousClass(classOrObject: KtClassOrObject, ktModule: KtModule) : + SymbolLightClassForClassOrObject(classOrObject, ktModule), PsiAnonymousClass { private val _baseClassType: PsiClassType by lazyPub { extendsListTypes.firstOrNull() @@ -45,69 +31,58 @@ internal class SymbolLightAnonymousClass( override fun getBaseClassType(): PsiClassType = _baseClassType - private val _extendsList by lazyPub { createInheritanceList(forExtendsList = true, anonymousObjectSymbol.superTypes) } - private val _implementsList by lazyPub { createInheritanceList(forExtendsList = false, anonymousObjectSymbol.superTypes) } + private val _extendsList by lazyPub { + withClassOrObjectSymbol { + createInheritanceList(forExtendsList = true, it.superTypes) + } + } - override fun getExtendsList(): PsiReferenceList? = _extendsList - override fun getImplementsList(): PsiReferenceList? = _implementsList + private val _implementsList by lazyPub { + withClassOrObjectSymbol { + createInheritanceList(forExtendsList = false, it.superTypes) + } + } + + override fun getExtendsList(): PsiReferenceList = _extendsList + override fun getImplementsList(): PsiReferenceList = _implementsList override fun getOwnFields(): List = _ownFields override fun getOwnMethods(): List = _ownMethods private val _ownMethods: List by lazyPub { - val result = mutableListOf() + withClassOrObjectSymbol { + val result = mutableListOf() + val declaredMemberScope = it.getDeclaredMemberScope() - val declaredMemberScope = anonymousObjectSymbol.getDeclaredMemberScope() - - createMethods(declaredMemberScope.getCallableSymbols(), result) - createConstructors(declaredMemberScope.getConstructors(), result) - - result + createMethods(declaredMemberScope.getCallableSymbols(), result) + createConstructors(declaredMemberScope.getConstructors(), result) + result + } } private val _ownFields: List by lazyPub { val result = mutableListOf() val nameGenerator = SymbolLightField.FieldNameGenerator() - anonymousObjectSymbol.getDeclaredMemberScope().getCallableSymbols() - .filterIsInstance() - .forEach { propertySymbol -> - createField( - propertySymbol, - nameGenerator, - isTopLevel = false, - forceStatic = false, - takePropertyVisibility = propertySymbol.hasJvmFieldAnnotation(), - result - ) - } + withClassOrObjectSymbol { + it.getDeclaredMemberScope().getCallableSymbols() + .filterIsInstance() + .forEach { propertySymbol -> + createField( + propertySymbol, + nameGenerator, + isTopLevel = false, + forceStatic = false, + takePropertyVisibility = propertySymbol.hasJvmFieldAnnotation(), + result + ) + } - result + result + } } - private val _ownInnerClasses: List by lazyPub { - anonymousObjectSymbol.createInnerClasses(manager, this, kotlinOrigin) - } - - override fun getOwnInnerClasses(): List = _ownInnerClasses - - override fun getParent(): PsiElement? = - kotlinOrigin?.let(::getParentForLocalDeclaration) - - override fun getScope(): PsiElement? = parent - override fun getInterfaces(): Array = PsiClassImplUtil.getInterfaces(this) - override fun getSuperClass(): PsiClass? = PsiClassImplUtil.getSuperClass(this) - override fun getSupers(): Array = PsiClassImplUtil.getSupers(this) - override fun getSuperTypes(): Array = PsiClassImplUtil.getSuperTypes(this) - - override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean = - baseClass?.let { InheritanceImplUtil.isInheritorDeep(this, it, classToByPass) } ?: false - - override val kotlinOrigin: KtClassOrObject? = anonymousObjectSymbol.psi as? KtClassOrObject - - override val originKind: LightClassOriginKind - get() = LightClassOriginKind.SOURCE - + override fun getParent(): PsiElement? = kotlinOrigin.let(::getParentForLocalDeclaration) override fun getArgumentList(): PsiExpressionList? = null override fun isInQualifiedNew(): Boolean = false override fun getName(): String? = null @@ -115,30 +90,8 @@ internal class SymbolLightAnonymousClass( override fun getModifierList(): PsiModifierList? = null override fun hasModifierProperty(name: String): Boolean = name == PsiModifier.FINAL override fun getContainingClass(): PsiClass? = null - override fun isDeprecated(): Boolean = false //TODO override fun getTypeParameters(): Array = PsiTypeParameter.EMPTY_ARRAY - override fun isInterface() = false - override fun isAnnotationType() = false override fun getTypeParameterList(): PsiTypeParameterList? = null override fun getQualifiedName(): String? = null - override fun isEnum() = false - override fun getUseScope(): SearchScope = kotlinOrigin?.useScope ?: TODO() - override fun getElementType(): IStubElementType, *>? = kotlinOrigin?.elementType - override fun getStub(): KotlinClassOrObjectStub? = kotlinOrigin?.stub - - override fun isEquivalentTo(another: PsiElement?): Boolean = equals(another) //TODO - - override fun equals(other: Any?): Boolean = - this === other || - (other is SymbolLightAnonymousClass && anonymousObjectSymbol == other.anonymousObjectSymbol) - - override fun hashCode(): Int = anonymousObjectSymbol.hashCode() - - override fun copy() = - SymbolLightAnonymousClass(anonymousObjectSymbol, manager) - - override fun isValid(): Boolean = super.isValid() && anonymousObjectSymbol.isValid() - - override fun toString() = - "${this::class.java.simpleName}:${kotlinOrigin?.getDebugText()}" + override fun copy() = SymbolLightAnonymousClass(classOrObject, ktModule) } 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 993fad7f194..5ed63828b4f 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,11 +5,13 @@ package org.jetbrains.kotlin.light.classes.symbol.classes -import com.intellij.psi.* +import com.intellij.psi.PsiMethod +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.lifetime.isValid import org.jetbrains.kotlin.analysis.api.symbols.* -import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind +import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration import org.jetbrains.kotlin.asJava.classes.METHOD_INDEX_BASE import org.jetbrains.kotlin.asJava.classes.METHOD_INDEX_FOR_NON_ORIGIN_METHOD @@ -20,17 +22,21 @@ import org.jetbrains.kotlin.builtins.StandardNames.ENUM_VALUES import org.jetbrains.kotlin.builtins.StandardNames.ENUM_VALUE_OF import org.jetbrains.kotlin.builtins.StandardNames.HASHCODE_NAME import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.light.classes.symbol.* +import org.jetbrains.kotlin.light.classes.symbol.NullabilityType import org.jetbrains.kotlin.light.classes.symbol.annotations.computeAnnotations import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmFieldAnnotation +import org.jetbrains.kotlin.light.classes.symbol.computeSimpleModality import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightField import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForEnumEntry import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForObject import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightSimpleMethod import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList +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.KtClass +import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.resolve.DataClassResolver import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind @@ -39,36 +45,34 @@ import org.jetbrains.kotlin.util.OperatorNameConventions.TO_STRING import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addToStdlib.applyIf -context(KtAnalysisSession) -internal open class SymbolLightClass( - private val classOrObjectSymbol: KtNamedClassOrObjectSymbol, - manager: PsiManager -) : SymbolLightClassForClassOrObject(classOrObjectSymbol, manager) { - +internal open class SymbolLightClass(classOrObject: KtClassOrObject, ktModule: KtModule) : + SymbolLightClassForClassOrObject(classOrObject, ktModule) { init { - require(classOrObjectSymbol.classKind != KtClassKind.INTERFACE && classOrObjectSymbol.classKind != KtClassKind.ANNOTATION_CLASS) + require(classOrObject !is KtClass || !classOrObject.isInterface() && !classOrObject.isAnnotation()) } private val _modifierList: PsiModifierList? by lazyPub { - val lazyModifiers = lazy { - buildSet { - add(classOrObjectSymbol.toPsiVisibilityForClass(isNested = !isTopLevel)) - addIfNotNull(classOrObjectSymbol.computeSimpleModality()) - if (!isTopLevel && !classOrObjectSymbol.isInner) { - add(PsiModifier.STATIC) + withNamedClassOrObjectSymbol { classOrObjectSymbol -> + val lazyModifiers = lazy { + buildSet { + add(classOrObjectSymbol.toPsiVisibilityForClass(isNested = !isTopLevel)) + addIfNotNull(classOrObjectSymbol.computeSimpleModality()) + if (!isTopLevel && !classOrObjectSymbol.isInner) { + add(PsiModifier.STATIC) + } } } - } - val lazyAnnotations = lazyPub { - classOrObjectSymbol.computeAnnotations( - parent = this@SymbolLightClass, - nullability = NullabilityType.Unknown, - annotationUseSiteTarget = null, - ) - } + val lazyAnnotations = lazyPub { + classOrObjectSymbol.computeAnnotations( + parent = this@SymbolLightClass, + nullability = NullabilityType.Unknown, + annotationUseSiteTarget = null, + ) + } - SymbolLightClassModifierList(this@SymbolLightClass, lazyModifiers, lazyAnnotations) + SymbolLightClassModifierList(this@SymbolLightClass, lazyModifiers, lazyAnnotations) + } } override fun getModifierList(): PsiModifierList? = _modifierList @@ -77,52 +81,63 @@ internal open class SymbolLightClass( override fun getExtendsList(): PsiReferenceList? = _extendsList override fun getImplementsList(): PsiReferenceList? = _implementsList - private val _extendsList by lazyPub { createInheritanceList(forExtendsList = true, classOrObjectSymbol.superTypes) } - private val _implementsList by lazyPub { createInheritanceList(forExtendsList = false, classOrObjectSymbol.superTypes) } - - private val _ownMethods: List by lazyPub { - - val result = mutableListOf() - - val declaredMemberScope = classOrObjectSymbol.getDeclaredMemberScope() - - val visibleDeclarations = declaredMemberScope.getCallableSymbols().applyIf(isEnum) { - filterNot { function -> - function is KtFunctionSymbol && - (function.name == ENUM_VALUES || function.name == ENUM_VALUE_OF) - } - }.applyIf(classOrObjectSymbol.isObject) { - filterNot { - it is KtKotlinPropertySymbol && it.isConst - } - }.applyIf(classOrObjectSymbol.isData) { - // Technically, synthetic members of `data` class, such as `componentN` or `copy`, are visible. - // They're just needed to be added later (to be in a backward-compatible order of members). - filterNot { function -> - function is KtFunctionSymbol && function.origin == KtSymbolOrigin.SOURCE_MEMBER_GENERATED - } + private val _extendsList by lazyPub { + withClassOrObjectSymbol { classOrObjectSymbol -> + createInheritanceList(forExtendsList = true, classOrObjectSymbol.superTypes) } - - val suppressStatic = isCompanionObject - createMethods(visibleDeclarations, result, suppressStatic = suppressStatic) - - createConstructors(declaredMemberScope.getConstructors(), result) - - - addMethodsFromCompanionIfNeeded(result) - - addMethodsFromDataClass(result) - addDelegatesToInterfaceMethods(result) - - result } - private fun addMethodsFromDataClass(result: MutableList) { + private val _implementsList by lazyPub { + withClassOrObjectSymbol { classOrObjectSymbol -> + createInheritanceList(forExtendsList = false, classOrObjectSymbol.superTypes) + } + } + + private val _ownMethods: List by lazyPub { + withNamedClassOrObjectSymbol { classOrObjectSymbol -> + val result = mutableListOf() + + val declaredMemberScope = classOrObjectSymbol.getDeclaredMemberScope() + + val visibleDeclarations = declaredMemberScope.getCallableSymbols().applyIf(isEnum) { + filterNot { function -> + function is KtFunctionSymbol && + (function.name == ENUM_VALUES || function.name == ENUM_VALUE_OF) + } + }.applyIf(isObject) { + filterNot { + it is KtKotlinPropertySymbol && it.isConst + } + }.applyIf(classOrObjectSymbol.isData) { + // Technically, synthetic members of `data` class, such as `componentN` or `copy`, are visible. + // They're just needed to be added later (to be in a backward-compatible order of members). + filterNot { function -> + function is KtFunctionSymbol && function.origin == KtSymbolOrigin.SOURCE_MEMBER_GENERATED + } + } + + val suppressStatic = isCompanionObject + createMethods(visibleDeclarations, result, suppressStatic = suppressStatic) + + createConstructors(declaredMemberScope.getConstructors(), result) + + + addMethodsFromCompanionIfNeeded(result) + + addMethodsFromDataClass(result, classOrObjectSymbol) + addDelegatesToInterfaceMethods(result, classOrObjectSymbol) + + result + } + } + + context(KtAnalysisSession) + private fun addMethodsFromDataClass(result: MutableList, classOrObjectSymbol: KtNamedClassOrObjectSymbol) { if (!classOrObjectSymbol.isData) return 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(this.kotlinOrigin!!, JvmDeclarationOriginKind.OTHER) + val lightMemberOrigin = LightMemberOriginForDeclaration(classOrObject, JvmDeclarationOriginKind.OTHER) result.add( SymbolLightSimpleMethod( ktFunctionSymbol, lightMemberOrigin, this, METHOD_INDEX_BASE, false, @@ -169,9 +184,10 @@ internal open class SymbolLightClass( private val Name.isFromAny: Boolean get() = this == EQUALS || this == HASHCODE_NAME || this == TO_STRING - private fun addDelegatesToInterfaceMethods(result: MutableList) { + context(KtAnalysisSession) + private fun addDelegatesToInterfaceMethods(result: MutableList, classOrObjectSymbol: KtNamedClassOrObjectSymbol) { fun createDelegateMethod(ktFunctionSymbol: KtFunctionSymbol) { - val kotlinOrigin = ktFunctionSymbol.psi as? KtDeclaration ?: kotlinOrigin!! + val kotlinOrigin = ktFunctionSymbol.psi as? KtDeclaration ?: classOrObject val lightMemberOrigin = LightMemberOriginForDeclaration(kotlinOrigin, JvmDeclarationOriginKind.DELEGATION) result.add( SymbolLightSimpleMethod( @@ -194,26 +210,28 @@ internal open class SymbolLightClass( } private val _ownFields: List by lazyPub { + withNamedClassOrObjectSymbol { classOrObjectSymbol -> + val result = mutableListOf() - val result = mutableListOf() + // First, add static fields: companion object and fields from companion object + addCompanionObjectFieldIfNeeded(result) + addFieldsFromCompanionIfNeeded(result) - // First, add static fields: companion object and fields from companion object - addCompanionObjectFieldIfNeeded(result) - addFieldsFromCompanionIfNeeded(result) + // Then, add instance fields: properties from parameters, and then member properties + addPropertyBackingFields(result, classOrObjectSymbol) - // Then, add instance fields: properties from parameters, and then member properties - addPropertyBackingFields(result) + // Next, add INSTANCE field if non-local named object + addInstanceFieldIfNeeded(result, classOrObjectSymbol) - // Next, add INSTANCE field if non-local named object - addInstanceFieldIfNeeded(result) + // Last, add fields for enum entries + addFieldsForEnumEntries(result, classOrObjectSymbol) - // Last, add fields for enum entries - addFieldsForEnumEntries(result) - - result + result + } } - protected fun addPropertyBackingFields(result: MutableList) { + context(KtAnalysisSession) + protected fun addPropertyBackingFields(result: MutableList, classOrObjectSymbol: KtNamedClassOrObjectSymbol) { val propertySymbols = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols() .filterIsInstance() .applyIf(isCompanionObject) { @@ -231,7 +249,7 @@ internal open class SymbolLightClass( val isLateInit = (propertySymbol as? KtKotlinPropertySymbol)?.isLateInit == true val isConst = (propertySymbol as? KtKotlinPropertySymbol)?.isConst == true - val forceStatic = classOrObjectSymbol.isObject || isCompanionObject + val forceStatic = isObject val takePropertyVisibility = isLateInit || isJvmField || isConst createField( @@ -250,8 +268,9 @@ internal open class SymbolLightClass( propertyGroups[false]?.forEach(::addPropertyBackingField) } - private fun addInstanceFieldIfNeeded(result: MutableList) { - if (classOrObjectSymbol.isNamedObject && !classOrObjectSymbol.isLocal) { + context(KtAnalysisSession) + private fun addInstanceFieldIfNeeded(result: MutableList, classOrObjectSymbol: KtNamedClassOrObjectSymbol) { + if (isNamedObject && !isLocal) { result.add( SymbolLightFieldForObject( objectSymbol = classOrObjectSymbol, @@ -263,7 +282,8 @@ internal open class SymbolLightClass( } } - private fun addFieldsForEnumEntries(result: MutableList) { + context(KtAnalysisSession) + private fun addFieldsForEnumEntries(result: MutableList, classOrObjectSymbol: KtNamedClassOrObjectSymbol) { if (isEnum) { classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols() .filterIsInstance() @@ -271,29 +291,9 @@ internal open class SymbolLightClass( } } - private val KtClassOrObjectSymbol.isObject: Boolean - get() = classKind == KtClassKind.OBJECT - - private val KtClassOrObjectSymbol.isNamedObject: Boolean - get() = isObject && !isCompanionObject - - private val KtClassOrObjectSymbol.isLocal: Boolean - get() = symbolKind == KtSymbolKind.LOCAL - - override fun hashCode(): Int = classOrObjectSymbol.hashCode() - - override fun equals(other: Any?): Boolean = - this === other || (other is SymbolLightClass && classOrObjectSymbol == other.classOrObjectSymbol) - override fun isInterface(): Boolean = false override fun isAnnotationType(): Boolean = false - override fun isEnum(): Boolean = - classOrObjectSymbol.classKind == KtClassKind.ENUM_CLASS - - override fun copy(): SymbolLightClass = - SymbolLightClass(classOrObjectSymbol, manager) - - override fun isValid(): Boolean = super.isValid() && classOrObjectSymbol.isValid() + override fun copy(): SymbolLightClass = SymbolLightClass(classOrObject, ktModule) } diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassBase.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassBase.kt index 123845aa7b1..e16c521091a 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassBase.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassBase.kt @@ -18,7 +18,7 @@ import com.intellij.psi.scope.PsiScopeProcessor import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.PsiUtil import org.jetbrains.annotations.NonNls -import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker import org.jetbrains.kotlin.asJava.classes.* import org.jetbrains.kotlin.asJava.toLightClass @@ -28,19 +28,16 @@ import org.jetbrains.kotlin.light.classes.symbol.allowLightClassesOnEdt import org.jetbrains.kotlin.utils.addToStdlib.ifFalse import javax.swing.Icon -context(KtAnalysisSession) -abstract class SymbolLightClassBase protected constructor( - manager: PsiManager -) : LightElement(manager, KotlinLanguage.INSTANCE), PsiClass, KtExtensibleLightClass { + +abstract class SymbolLightClassBase protected constructor(val ktModule: KtModule, manager: PsiManager) : + LightElement(manager, KotlinLanguage.INSTANCE), PsiClass, KtExtensibleLightClass { private class SymbolLightClassesLazyCreator(private val project: Project) : KotlinClassInnerStuffCache.LazyCreator() { override fun get(initializer: () -> T, dependencies: List): Lazy = object : Lazy { private val cachedValue = PsiCachedValueImpl(PsiManager.getInstance(project)) { CachedValueProvider.Result.create(allowLightClassesOnEdt(initializer), dependencies) } - override val value: T - get() = cachedValue.value - ?: error("Unexpected null value from PsiCachedValueImpl") + override val value: T get() = cachedValue.value ?: error("Unexpected null value from PsiCachedValueImpl") override fun isInitialized(): Boolean { // Lazy is a bad interface here as it has unneeded and unused in LC `isInitialized` method @@ -50,6 +47,7 @@ abstract class SymbolLightClassBase protected constructor( } } + @Suppress("LeakingThis") private val myInnersCache = KotlinClassInnerStuffCache( myClass = this@SymbolLightClassBase, dependencies = listOf(manager.project.createProjectWideOutOfBlockModificationTracker()), @@ -102,7 +100,9 @@ abstract class SymbolLightClassBase protected constructor( val baseClassOrigin = (baseClass as? KtLightClass)?.kotlinOrigin return if (baseClassOrigin != null && thisClassOrigin != null) { - thisClassOrigin.checkIsInheritor(baseClassOrigin, checkDeep) + analyzeForLightClasses(ktModule) { + thisClassOrigin.checkIsInheritor(baseClassOrigin, checkDeep) + } } else { hasSuper(baseClass, checkDeep) || InheritanceImplUtil.isInheritor(this, baseClass, checkDeep) @@ -122,7 +122,7 @@ abstract class SymbolLightClassBase protected constructor( private fun PsiClass.hasSuper( baseClass: PsiClass, checkDeep: Boolean, - visitedSupers: MutableSet = mutableSetOf() + visitedSupers: MutableSet = mutableSetOf() ): Boolean { visitedSupers.add(this) val notVisitedSupers = supers.filterNot { visitedSupers.contains(it) } @@ -135,8 +135,7 @@ abstract class SymbolLightClassBase protected constructor( override fun getLanguage(): KotlinLanguage = KotlinLanguage.INSTANCE - override fun getPresentation(): ItemPresentation? = - ItemPresentationProviders.getItemPresentation(this) + override fun getPresentation(): ItemPresentation? = ItemPresentationProviders.getItemPresentation(this) abstract override fun equals(other: Any?): Boolean @@ -144,18 +143,15 @@ abstract class SymbolLightClassBase protected constructor( override fun getContext(): PsiElement = parent - override fun isEquivalentTo(another: PsiElement?): Boolean = - PsiClassImplUtil.isClassEquivalentTo(this, another) + override fun isEquivalentTo(another: PsiElement?): Boolean = PsiClassImplUtil.isClassEquivalentTo(this, another) override fun getDocComment(): PsiDocComment? = null override fun hasTypeParameters(): Boolean = PsiImplUtil.hasTypeParameters(this) - override fun getExtendsListTypes(): Array = - PsiClassImplUtil.getExtendsListTypes(this) + override fun getExtendsListTypes(): Array = PsiClassImplUtil.getExtendsListTypes(this) - override fun getImplementsListTypes(): Array = - PsiClassImplUtil.getImplementsListTypes(this) + override fun getImplementsListTypes(): Array = PsiClassImplUtil.getImplementsListTypes(this) override fun findMethodBySignature(patternMethod: PsiMethod?, checkBases: Boolean): PsiMethod? = patternMethod?.let { PsiClassImplUtil.findMethodBySignature(this, it, checkBases) } 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 c27f72f128e..9157c218288 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 @@ -14,15 +14,13 @@ 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.markers.KtSymbolWithKind +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.asJava.toLightClass import org.jetbrains.kotlin.light.classes.symbol.SymbolLightIdentifier -import org.jetbrains.kotlin.light.classes.symbol.allowLightClassesOnEdt 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 @@ -31,28 +29,43 @@ import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForObjec import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForProperty import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightTypeParameterList import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind +import org.jetbrains.kotlin.psi.KtClass 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.applyIf import org.jetbrains.kotlin.utils.addToStdlib.ifTrue import org.jetbrains.kotlin.utils.addToStdlib.safeAs -context(KtAnalysisSession) -abstract class SymbolLightClassForClassOrObject( - private val classOrObjectSymbol: KtNamedClassOrObjectSymbol, - manager: PsiManager -) : SymbolLightClassBase(manager), +abstract class SymbolLightClassForClassOrObject(protected val classOrObject: KtClassOrObject, ktModule: KtModule) : + SymbolLightClassBase(ktModule, classOrObject.manager), StubBasedPsiElement> { + protected fun withClassOrObjectSymbol(action: KtAnalysisSession.(KtClassOrObjectSymbol) -> T): T = + analyzeForLightClasses(ktModule) { + action(classOrObject.getClassOrObjectSymbol()!!) + } - override val isTopLevel: Boolean = classOrObjectSymbol.symbolKind == KtSymbolKind.TOP_LEVEL + protected fun withNamedClassOrObjectSymbol(action: KtAnalysisSession.(KtNamedClassOrObjectSymbol) -> T): T = + analyzeForLightClasses(ktModule) { + val namedClassOrObjectSymbol = classOrObject.getNamedClassOrObjectSymbol() + require(namedClassOrObjectSymbol != null) - internal val isCompanionObject: Boolean - get() = classOrObjectSymbol.classKind == KtClassKind.COMPANION_OBJECT + action(namedClassOrObjectSymbol) + } + + 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() private val _isDeprecated: Boolean by lazyPub { - classOrObjectSymbol.hasDeprecatedAnnotation() + withClassOrObjectSymbol { it.hasDeprecatedAnnotation() } } override fun isDeprecated(): Boolean = _isDeprecated @@ -62,7 +75,9 @@ abstract class SymbolLightClassForClassOrObject( abstract override fun getOwnMethods(): List private val _identifier: PsiIdentifier by lazyPub { - SymbolLightIdentifier(this, classOrObjectSymbol) + withClassOrObjectSymbol { + SymbolLightIdentifier(this@SymbolLightClassForClassOrObject, it) + } } override fun getNameIdentifier(): PsiIdentifier? = _identifier @@ -72,40 +87,44 @@ abstract class SymbolLightClassForClassOrObject( private val _typeParameterList: PsiTypeParameterList? by lazyPub { hasTypeParameters().ifTrue { - SymbolLightTypeParameterList( - owner = this, - symbolWithTypeParameterList = classOrObjectSymbol, - ) + withClassOrObjectSymbol { + SymbolLightTypeParameterList( + owner = this@SymbolLightClassForClassOrObject, + symbolWithTypeParameterList = it, + ) + } } } - override fun hasTypeParameters(): Boolean = - classOrObjectSymbol.typeParameters.isNotEmpty() + override fun hasTypeParameters(): Boolean = classOrObject.typeParameters.isNotEmpty() override fun getTypeParameterList(): PsiTypeParameterList? = _typeParameterList - override fun getTypeParameters(): Array = - _typeParameterList?.typeParameters ?: PsiTypeParameter.EMPTY_ARRAY + override fun getTypeParameters(): Array = _typeParameterList?.typeParameters ?: PsiTypeParameter.EMPTY_ARRAY private val _ownInnerClasses: List by lazyPub { - classOrObjectSymbol.createInnerClasses(manager, this, kotlinOrigin) + withClassOrObjectSymbol { + it.createInnerClasses(this@SymbolLightClassForClassOrObject, classOrObject) + } } override fun getOwnInnerClasses(): List = _ownInnerClasses - override fun getTextOffset(): Int = kotlinOrigin?.textOffset ?: 0 - override fun getStartOffsetInParent(): Int = kotlinOrigin?.startOffsetInParent ?: 0 + override fun getTextOffset(): Int = classOrObject.textOffset + override fun getStartOffsetInParent(): Int = classOrObject.startOffsetInParent override fun isWritable() = false - override val kotlinOrigin: KtClassOrObject? = classOrObjectSymbol.psi as? KtClassOrObject + override val kotlinOrigin: KtClassOrObject = classOrObject - protected fun addMethodsFromCompanionIfNeeded(result: MutableList) { + 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() + val properties = getDeclaredMemberScope().getCallableSymbols().filterIsInstance() properties.forEach { property -> createPropertyAccessors( result, @@ -117,7 +136,9 @@ abstract class SymbolLightClassForClassOrObject( } } - protected fun addCompanionObjectFieldIfNeeded(result: MutableList) { + protected fun addCompanionObjectFieldIfNeeded( + result: MutableList, + ): Unit = withNamedClassOrObjectSymbol { classOrObjectSymbol -> classOrObjectSymbol.companionObject?.run { result.add( SymbolLightFieldForObject( @@ -130,25 +151,28 @@ abstract class SymbolLightClassForClassOrObject( } } - protected fun addFieldsFromCompanionIfNeeded(result: MutableList) { - classOrObjectSymbol.companionObject?.run { - getDeclaredMemberScope().getCallableSymbols() - .filterIsInstance() - .applyIf(isInterface) { - filter { it.isConstOrJvmField } - } - .mapTo(result) { - SymbolLightFieldForProperty( - propertySymbol = it, - fieldName = it.name.asString(), - containingClass = this@SymbolLightClassForClassOrObject, - lightMemberOrigin = null, - isTopLevel = false, - forceStatic = true, - takePropertyVisibility = it.isConstOrJvmField - ) - } - } + protected fun addFieldsFromCompanionIfNeeded( + result: MutableList, + ): Unit = withNamedClassOrObjectSymbol { classOrObjectSymbol -> + classOrObjectSymbol.companionObject + ?.getDeclaredMemberScope() + ?.getCallableSymbols() + ?.filterIsInstance() + ?.applyIf(isInterface) { + filter { it.isConstOrJvmField } + } + ?.mapTo(result) { + SymbolLightFieldForProperty( + propertySymbol = it, + fieldName = it.name.asString(), + containingClass = this@SymbolLightClassForClassOrObject, + lightMemberOrigin = null, + isTopLevel = false, + forceStatic = true, + takePropertyVisibility = it.isConstOrJvmField, + ) + } + } private val KtPropertySymbol.isConstOrJvmField: Boolean @@ -157,39 +181,39 @@ abstract class SymbolLightClassForClassOrObject( private val KtPropertySymbol.isConst: Boolean get() = (this as? KtKotlinPropertySymbol)?.isConst == true - override fun getNavigationElement(): PsiElement = kotlinOrigin ?: this + override fun getNavigationElement(): PsiElement = classOrObject override fun isEquivalentTo(another: PsiElement?): Boolean = basicIsEquivalentTo(this, another) || another is PsiClass && qualifiedName != null && another.qualifiedName == qualifiedName - abstract override fun equals(other: Any?): Boolean + override fun equals(other: Any?): Boolean { + if (this === other) return true - abstract override fun hashCode(): Int + return other?.safeAs()?.classOrObject == classOrObject + } - override fun getName(): String? = allowLightClassesOnEdt { classOrObjectSymbol.name.asString() } + override fun hashCode(): Int = classOrObject.hashCode() + + override fun getName(): String? = classOrObject.name override fun hasModifierProperty(@NonNls name: String): Boolean = modifierList?.hasModifierProperty(name) ?: false - abstract override fun isInterface(): Boolean + override fun isInterface(): Boolean = isInterface + override fun isAnnotationType(): Boolean = isAnnotation + override fun isEnum(): Boolean = isEnum - abstract override fun isAnnotationType(): Boolean + override fun isValid(): Boolean = classOrObject.isValid - abstract override fun isEnum(): Boolean + override fun toString() = "${this::class.java.simpleName}:${classOrObject.getDebugText()}" - override fun isValid(): Boolean = kotlinOrigin?.isValid ?: true + override fun getUseScope(): SearchScope = classOrObject.useScope + override fun getElementType(): IStubElementType, *>? = classOrObject.elementType + override fun getStub(): KotlinClassOrObjectStub? = classOrObject.stub - override fun toString() = - "${this::class.java.simpleName}:${kotlinOrigin?.getDebugText()}" + override val originKind: LightClassOriginKind get() = LightClassOriginKind.SOURCE - override fun getUseScope(): SearchScope = kotlinOrigin?.useScope ?: TODO() - override fun getElementType(): IStubElementType, *>? = kotlinOrigin?.elementType - override fun getStub(): KotlinClassOrObjectStub? = kotlinOrigin?.stub - - override val originKind: LightClassOriginKind - get() = LightClassOriginKind.SOURCE - - override fun getQualifiedName() = kotlinOrigin?.fqName?.asString() + override fun getQualifiedName() = classOrObject.fqName?.asString() override fun getInterfaces(): Array = PsiClassImplUtil.getInterfaces(this) override fun getSuperClass(): PsiClass? = PsiClassImplUtil.getSuperClass(this) @@ -197,16 +221,17 @@ abstract class SymbolLightClassForClassOrObject( override fun getSuperTypes(): Array = PsiClassImplUtil.getSuperTypes(this) override fun getContainingClass(): PsiClass? { - val containingBody = kotlinOrigin?.parent as? KtClassBody + val containingBody = classOrObject.parent as? KtClassBody val containingClass = containingBody?.parent as? KtClassOrObject containingClass?.let { return it.toLightClass() } return null } override fun getParent(): PsiElement? { - if (classOrObjectSymbol.safeAs()?.symbolKind == KtSymbolKind.LOCAL) { - return kotlinOrigin?.let(::getParentForLocalDeclaration) + if (isLocal) { + return classOrObject.let(::getParentForLocalDeclaration) } + return containingClass ?: containingFile } 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 88c32d97004..f7468938d96 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 @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.lifetime.isValid import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode +import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.asJava.classes.KotlinSuperTypeListBuilder import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.elements.KtLightMethod @@ -25,10 +26,10 @@ internal class SymbolLightClassForEnumEntry( private val enumEntrySymbol: KtEnumEntrySymbol, private val enumConstant: SymbolLightFieldForEnumEntry, private val enumClass: SymbolLightClass, - manager: PsiManager -) : SymbolLightClassBase(manager), PsiEnumConstantInitializer { + ktModule: KtModule, +) : SymbolLightClassBase(ktModule, enumConstant.manager), PsiEnumConstantInitializer { - override fun getName(): String? = enumEntrySymbol.name.asString() + override fun getName(): String = enumEntrySymbol.name.asString() override fun getBaseClassType(): PsiClassType = enumConstant.type as PsiClassType //???TODO @@ -48,8 +49,7 @@ internal class SymbolLightClassForEnumEntry( override fun hashCode(): Int = enumEntrySymbol.hashCode() - override fun copy(): PsiElement = - SymbolLightClassForEnumEntry(enumEntrySymbol, enumConstant, enumClass, manager) + override fun copy(): PsiElement = SymbolLightClassForEnumEntry(enumEntrySymbol, enumConstant, enumClass, ktModule) override fun toString(): String = "SymbolLightClassForEnumEntry:$name" @@ -63,12 +63,12 @@ internal class SymbolLightClassForEnumEntry( ) } - override fun getModifierList(): PsiModifierList? = _modifierList + override fun getModifierList(): PsiModifierList = _modifierList override fun hasModifierProperty(name: String): Boolean = name == PsiModifier.PUBLIC || name == PsiModifier.STATIC || name == PsiModifier.FINAL - override fun getContainingClass(): PsiClass? = enumClass + override fun getContainingClass(): PsiClass = enumClass override fun isDeprecated(): Boolean = false @@ -76,7 +76,7 @@ internal class SymbolLightClassForEnumEntry( override fun getTypeParameterList(): PsiTypeParameterList? = null - override fun getQualifiedName(): String? = "${enumConstant.containingClass.qualifiedName}.${enumConstant.name}" + override fun getQualifiedName(): String = "${enumConstant.containingClass.qualifiedName}.${enumConstant.name}" override fun isInterface(): Boolean = false @@ -89,9 +89,8 @@ internal class SymbolLightClassForEnumEntry( enumEntrySymbol.returnType.asPsiType(this@SymbolLightClassForEnumEntry, KtTypeMappingMode.SUPER_TYPE) as? PsiClassType ?: return@lazyPub null - KotlinSuperTypeListBuilder( - kotlinOrigin = enumClass.kotlinOrigin?.getSuperTypeList(), + kotlinOrigin = enumClass.kotlinOrigin.getSuperTypeList(), manager = manager, language = language, role = PsiReferenceList.Role.EXTENDS_LIST @@ -104,7 +103,7 @@ internal class SymbolLightClassForEnumEntry( override fun getImplementsList(): PsiReferenceList? = null - override fun getSuperClass(): PsiClass? = enumClass + override fun getSuperClass(): PsiClass = enumClass override fun getInterfaces(): Array = PsiClass.EMPTY_ARRAY @@ -112,7 +111,7 @@ internal class SymbolLightClassForEnumEntry( override fun getSuperTypes(): Array = PsiClassImplUtil.getSuperTypes(this) - override fun getParent(): PsiElement? = containingClass ?: containingFile + override fun getParent(): PsiElement? = containingClass override fun getScope(): PsiElement? = parent diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForFacade.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForFacade.kt index 16b5a4e82a2..a1e6edfd57e 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForFacade.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForFacade.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtKotlinPropertySymbol import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility +import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass @@ -41,8 +42,9 @@ import org.jetbrains.kotlin.psi.KtFile context(KtAnalysisSession) class SymbolLightClassForFacade( override val facadeClassFqName: FqName, - override val files: Collection -) : SymbolLightClassBase(files.first().manager), KtLightClassForFacade { + override val files: Collection, + ktModule: KtModule, +) : SymbolLightClassBase(ktModule, files.first().manager), KtLightClassForFacade { init { require(files.isNotEmpty()) @@ -159,7 +161,7 @@ class SymbolLightClassForFacade( override fun getOwnMethods() = _ownMethods - override fun copy(): SymbolLightClassForFacade = SymbolLightClassForFacade(facadeClassFqName, files) + override fun copy(): SymbolLightClassForFacade = SymbolLightClassForFacade(facadeClassFqName, files, ktModule) private val packageFqName: FqName = facadeClassFqName.parent() 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 3381314a2e3..c39ffd38d7c 100644 --- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterfaceDefaultImpls.kt +++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/classes/SymbolLightClassForInterfaceDefaultImpls.kt @@ -7,25 +7,18 @@ package org.jetbrains.kotlin.light.classes.symbol.classes import com.intellij.psi.* import com.intellij.util.IncorrectOperationException -import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList import org.jetbrains.kotlin.load.java.JvmAbi -context(KtAnalysisSession) -internal class SymbolLightClassForInterfaceDefaultImpls( - private val classOrObjectSymbol: KtNamedClassOrObjectSymbol, - private val containingClass: SymbolLightClassBase, - manager: PsiManager -) : SymbolLightInterfaceClass(classOrObjectSymbol, manager) { +internal class SymbolLightClassForInterfaceDefaultImpls(private val containingClass: SymbolLightInterfaceClass) : + SymbolLightInterfaceClass(containingClass.kotlinOrigin, containingClass.ktModule) { override fun getQualifiedName(): String? = containingClass.qualifiedName?.let { it + ".${JvmAbi.DEFAULT_IMPLS_CLASS_NAME}" } override fun getName() = JvmAbi.DEFAULT_IMPLS_CLASS_NAME override fun getParent() = containingClass - override fun copy() = - SymbolLightClassForInterfaceDefaultImpls(classOrObjectSymbol, containingClass, manager) + override fun copy() = SymbolLightClassForInterfaceDefaultImpls(containingClass) override fun getTypeParameterList(): PsiTypeParameterList? = null override fun getTypeParameters(): Array = emptyArray() @@ -44,6 +37,7 @@ internal class SymbolLightClassForInterfaceDefaultImpls( override fun isEnum(): Boolean = false override fun hasTypeParameters(): Boolean = false override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean = false + override fun getExtendsList(): PsiReferenceList? = null @Throws(IncorrectOperationException::class) override fun setName(name: String): PsiElement { 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 dd4ae69ee0f..4de9b6ec10f 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,61 +5,64 @@ package org.jetbrains.kotlin.light.classes.symbol.classes -import com.intellij.psi.PsiManager import com.intellij.psi.PsiMethod -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.project.structure.KtModule 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 +import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue -context(KtAnalysisSession) -internal class SymbolLightInlineClass( - private val classOrObjectSymbol: KtNamedClassOrObjectSymbol, - manager: PsiManager -) : SymbolLightClass(classOrObjectSymbol, manager) { - +internal class SymbolLightInlineClass(classOrObject: KtClassOrObject, ktModule: KtModule) : SymbolLightClass(classOrObject, ktModule) { init { - require(classOrObjectSymbol.isInline) + require(classOrObject.hasModifier(KtTokens.INLINE_KEYWORD)) } private val _ownMethods: List by lazyPub { - val result = mutableListOf() + withClassOrObjectSymbol { classOrObjectSymbol -> + val result = mutableListOf() - val declaredMemberScope = classOrObjectSymbol.getDeclaredMemberScope() - val applicableDeclarations = declaredMemberScope.getCallableSymbols() - .filter { - (it as? KtPropertySymbol)?.isOverride == true || (it as? KtFunctionSymbol)?.isOverride == true - } - .filterNot { - it.deprecationStatus?.deprecationLevel == DeprecationLevelValue.HIDDEN + val declaredMemberScope = classOrObjectSymbol.getDeclaredMemberScope() + val applicableDeclarations = declaredMemberScope.getCallableSymbols() + .filter { + (it as? KtPropertySymbol)?.isOverride == true || (it as? KtFunctionSymbol)?.isOverride == true + } + .filterNot { + it.deprecationStatus?.deprecationLevel == DeprecationLevelValue.HIDDEN + } + + createMethods(applicableDeclarations, result, suppressStatic = false) + + val inlineClassParameterSymbol = declaredMemberScope.getConstructors() + .singleOrNull { it.isPrimary } + ?.valueParameters + ?.singleOrNull() + + if (inlineClassParameterSymbol != null) { + val propertySymbol = declaredMemberScope.getCallableSymbols { it == inlineClassParameterSymbol.name } + .singleOrNull { it is KtPropertySymbol && it.isFromPrimaryConstructor } as? KtPropertySymbol + + if (propertySymbol != null) { + // (inline or) value class primary constructor must have only final read-only (val) property parameter + // Even though the property parameter is mutable (for some reasons, e.g., testing or not checked yet), + // we can enforce immutability here. + createPropertyAccessors(result, propertySymbol, isTopLevel = false, isMutable = false) + } } - createMethods(applicableDeclarations, result, suppressStatic = false) - val inlineClassParameterSymbol = - declaredMemberScope.getConstructors().singleOrNull { it.isPrimary }?.valueParameters?.singleOrNull() - if (inlineClassParameterSymbol != null) { - val propertySymbol = declaredMemberScope.getCallableSymbols { it == inlineClassParameterSymbol.name } - .singleOrNull { it is KtPropertySymbol && it.isFromPrimaryConstructor } as? KtPropertySymbol - if (propertySymbol != null) { - // (inline or) value class primary constructor must have only final read-only (val) property parameter - // Even though the property parameter is mutable (for some reasons, e.g., testing or not checked yet), - // we can enforce immutability here. - createPropertyAccessors(result, propertySymbol, isTopLevel = false, isMutable = false) - } + result } - - - result } private val _ownFields: List by lazyPub { - mutableListOf().apply { - addPropertyBackingFields(this) + withNamedClassOrObjectSymbol { classOrObjectSymbol -> + mutableListOf().apply { + addPropertyBackingFields(this, classOrObjectSymbol) + } } } @@ -67,5 +70,5 @@ internal class SymbolLightInlineClass( override fun getOwnFields(): List = _ownFields - override fun copy(): SymbolLightInlineClass = SymbolLightInlineClass(classOrObjectSymbol, manager) + override fun copy(): SymbolLightInlineClass = SymbolLightInlineClass(classOrObject, ktModule) } 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 8951f49c74e..587dfa22f38 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,56 +5,46 @@ 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.lifetime.isValid -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.project.structure.KtModule import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.psi.KtClassOrObject -context(KtAnalysisSession) internal open class SymbolLightInterfaceClass( - private val classOrObjectSymbol: KtNamedClassOrObjectSymbol, - manager: PsiManager -) : SymbolLightInterfaceOrAnnotationClass(classOrObjectSymbol, manager) { - + classOrObject: KtClassOrObject, + ktModule: KtModule, +) : SymbolLightInterfaceOrAnnotationClass(classOrObject, ktModule) { init { - require(classOrObjectSymbol.classKind == KtClassKind.INTERFACE) + require(isInterface) } private val _ownMethods: List by lazyPub { - val result = mutableListOf() + withClassOrObjectSymbol { classOrObjectSymbol -> + val result = mutableListOf() - val visibleDeclarations = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols() - .filterNot { it is KtFunctionSymbol && it.visibility.isPrivateOrPrivateToThis() } + val visibleDeclarations = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols() + .filterNot { it is KtFunctionSymbol && it.visibility.isPrivateOrPrivateToThis() } - createMethods(visibleDeclarations, result) - addMethodsFromCompanionIfNeeded(result) + createMethods(visibleDeclarations, result) + addMethodsFromCompanionIfNeeded(result) - result + result + } } override fun getOwnMethods(): List = _ownMethods - override fun equals(other: Any?): Boolean = - other === this || (other is SymbolLightInterfaceClass && classOrObjectSymbol == other.classOrObjectSymbol) - - override fun hashCode(): Int = classOrObjectSymbol.hashCode() - - override fun isAnnotationType(): Boolean = false - - override fun copy(): SymbolLightClassForClassOrObject = SymbolLightInterfaceClass(classOrObjectSymbol, manager) + override fun copy(): SymbolLightClassForClassOrObject = SymbolLightInterfaceClass(classOrObject, ktModule) private val _extendsList: PsiReferenceList by lazyPub { - createInheritanceList(forExtendsList = true, classOrObjectSymbol.superTypes) + withClassOrObjectSymbol { classOrObjectSymbol -> + createInheritanceList(forExtendsList = true, classOrObjectSymbol.superTypes) + } } override fun getExtendsList(): PsiReferenceList? = _extendsList - - override fun isValid(): Boolean = super.isValid() && classOrObjectSymbol.isValid() } 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 696d404ba8b..e72d8109bd6 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,57 +5,52 @@ 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.lifetime.isValid -import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind -import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.elements.KtLightField 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.KtClassOrObject -context(KtAnalysisSession) -internal abstract class SymbolLightInterfaceOrAnnotationClass( - private val classOrObjectSymbol: KtNamedClassOrObjectSymbol, - manager: PsiManager -) : SymbolLightClassForClassOrObject(classOrObjectSymbol, manager) { +internal abstract class SymbolLightInterfaceOrAnnotationClass(classOrObject: KtClassOrObject, ktModule: KtModule) : + SymbolLightClassForClassOrObject(classOrObject, ktModule) { init { - require( - classOrObjectSymbol.classKind == KtClassKind.OBJECT || - classOrObjectSymbol.classKind == KtClassKind.INTERFACE || - classOrObjectSymbol.classKind == KtClassKind.ANNOTATION_CLASS - ) + require(isInterface || isAnnotation) } private val _modifierList: PsiModifierList? by lazyPub { - val lazyModifiers = lazy { - buildSet { - add(classOrObjectSymbol.toPsiVisibilityForClass(isNested = !isTopLevel)) - add(PsiModifier.ABSTRACT) - if (!isTopLevel && !classOrObjectSymbol.isInner) { - add(PsiModifier.STATIC) + withNamedClassOrObjectSymbol { classOrObjectSymbol -> + val lazyModifiers = lazy { + buildSet { + add(classOrObjectSymbol.toPsiVisibilityForClass(isNested = !isTopLevel)) + add(PsiModifier.ABSTRACT) + if (!isTopLevel && !classOrObjectSymbol.isInner) { + add(PsiModifier.STATIC) + } } } - } - val lazyAnnotations = lazyPub { - classOrObjectSymbol.computeAnnotations( - parent = this@SymbolLightInterfaceOrAnnotationClass, - nullability = NullabilityType.Unknown, - annotationUseSiteTarget = null, - ) - } + val lazyAnnotations = lazyPub { + classOrObjectSymbol.computeAnnotations( + parent = this@SymbolLightInterfaceOrAnnotationClass, + nullability = NullabilityType.Unknown, + annotationUseSiteTarget = null, + ) + } - SymbolLightClassModifierList(this@SymbolLightInterfaceOrAnnotationClass, lazyModifiers, lazyAnnotations) + SymbolLightClassModifierList(this@SymbolLightInterfaceOrAnnotationClass, lazyModifiers, lazyAnnotations) + } } + override fun isInterface(): Boolean = true + override fun isEnum(): Boolean = false + override fun getModifierList(): PsiModifierList? = _modifierList private val _ownFields: List by lazyPub { @@ -68,10 +63,4 @@ internal abstract class SymbolLightInterfaceOrAnnotationClass( override fun getOwnFields(): List = _ownFields override fun getImplementsList(): PsiReferenceList? = null - - override fun isInterface(): Boolean = true - - override fun isEnum(): Boolean = false - - override fun isValid(): Boolean = super.isValid() && classOrObjectSymbol.isValid() } 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 a295f22fb85..8b35853a752 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,7 +5,6 @@ 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 @@ -16,6 +15,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.markers.isPrivateOrPrivateToThi import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode +import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule import org.jetbrains.kotlin.analysis.project.structure.getKtModuleOfTypeSafe import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration @@ -29,7 +29,6 @@ import org.jetbrains.kotlin.config.JvmDefaultMode import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.lexer.KtTokens.* -import org.jetbrains.kotlin.light.classes.symbol.allowLightClassesOnEdt import org.jetbrains.kotlin.light.classes.symbol.annotations.* import org.jetbrains.kotlin.light.classes.symbol.copy import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightField @@ -44,48 +43,23 @@ import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClass +import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind import java.util.* -internal fun createSymbolLightClassNoCache(classOrObject: KtClassOrObject): KtLightClass? = allowLightClassesOnEdt { - val anonymousObject = classOrObject.parent as? KtObjectLiteralExpression - if (anonymousObject != null) { - return analyzeForLightClasses(anonymousObject) { - anonymousObject.getAnonymousObjectSymbol().createLightClassNoCache(anonymousObject.manager) - } - } - - return when { - classOrObject is KtEnumEntry -> analyzeForLightClasses(classOrObject) { - lightClassForEnumEntry(classOrObject) - } - - classOrObject.hasModifier(INLINE_KEYWORD) -> { - analyzeForLightClasses(classOrObject) { - classOrObject.getNamedClassOrObjectSymbol()?.let { SymbolLightInlineClass(it, classOrObject.manager) } - } - } - - else -> { - analyzeForLightClasses(classOrObject) { - classOrObject.getClassOrObjectSymbol()?.createLightClassNoCache(classOrObject.manager) - } - } - } +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) } - -context(KtAnalysisSession) -internal fun KtClassOrObjectSymbol.createLightClassNoCache(manager: PsiManager): SymbolLightClassBase = when (this) { - is KtAnonymousObjectSymbol -> SymbolLightAnonymousClass(this, manager) - is KtNamedClassOrObjectSymbol -> when (classKind) { - KtClassKind.INTERFACE -> SymbolLightInterfaceClass(this, manager) - KtClassKind.ANNOTATION_CLASS -> SymbolLightAnnotationClass(this, manager) - else -> SymbolLightClass(this, manager) - } +internal fun createLightClassNoCache(ktClassOrObject: KtClassOrObject, ktModule: KtModule): SymbolLightClassBase = when { + ktClassOrObject is KtClass && ktClassOrObject.isAnnotation() -> SymbolLightAnnotationClass(ktClassOrObject, ktModule) + ktClassOrObject is KtClass && ktClassOrObject.isInterface() -> SymbolLightInterfaceClass(ktClassOrObject, ktModule) + else -> SymbolLightClass(ktClassOrObject, ktModule) } -context(KtAnalysisSession) private fun lightClassForEnumEntry(ktEnumEntry: KtEnumEntry): KtLightClass? { if (ktEnumEntry.body == null) return null @@ -441,9 +415,8 @@ internal fun SymbolLightClassBase.createInheritanceList(forExtendsList: Boolean, context(KtAnalysisSession) internal fun KtSymbolWithMembers.createInnerClasses( - manager: PsiManager, containingClass: SymbolLightClassBase, - classOrObject: KtClassOrObject? + classOrObject: KtClassOrObject ): List { val result = ArrayList() @@ -452,20 +425,20 @@ 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) { - it.createLightClassNoCache(manager) + createLightClassNoCache(it.psi(), ktModule = containingClass.ktModule) } - val jvmDefaultMode = - classOrObject?.getKtModuleOfTypeSafe()?.languageVersionSettings?.getFlag(JvmAnalysisFlags.jvmDefaultMode) + classOrObject.getKtModuleOfTypeSafe()?.languageVersionSettings?.getFlag(JvmAnalysisFlags.jvmDefaultMode) ?: JvmDefaultMode.DEFAULT - if (this is KtNamedClassOrObjectSymbol && - classOrObject?.hasInterfaceDefaultImpls == true && - jvmDefaultMode != JvmDefaultMode.ALL_INCOMPATIBLE + if (classOrObject.hasInterfaceDefaultImpls && + jvmDefaultMode != JvmDefaultMode.ALL_INCOMPATIBLE && + containingClass is SymbolLightInterfaceClass ) { - result.add(SymbolLightClassForInterfaceDefaultImpls(this, containingClass, manager)) + result.add(SymbolLightClassForInterfaceDefaultImpls(containingClass)) } + return result } 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 8226dab39a8..74e757803e8 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 @@ -57,7 +57,7 @@ internal class SymbolLightFieldForEnumEntry( enumEntrySymbol = enumEntrySymbol, enumConstant = this@SymbolLightFieldForEnumEntry, enumClass = containingClass, - manager = manager + ktModule = enumEntrySymbol.getContainingModule(), ) } } diff --git a/compiler/testData/asJava/ultraLightClasses/objects.fir.java b/compiler/testData/asJava/ultraLightClasses/objects.fir.java index 9c49b56c7eb..fe4842ce0d6 100644 --- a/compiler/testData/asJava/ultraLightClasses/objects.fir.java +++ b/compiler/testData/asJava/ultraLightClasses/objects.fir.java @@ -12,6 +12,9 @@ public final class C /* C*/ { @org.jetbrains.annotations.NotNull() public static final C.Companion Companion; + @org.jetbrains.annotations.NotNull() + public static final C.Factory Factory; + @kotlin.jvm.JvmStatic() public static final void foo();// foo()