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 6fb79be4441..0c0a824e722 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 @@ -11,7 +11,6 @@ import com.intellij.psi.PsiModifierList import com.intellij.psi.PsiReferenceList 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 @@ -27,12 +26,8 @@ import org.jetbrains.kotlin.builtins.StandardNames.HASHCODE_NAME import org.jetbrains.kotlin.descriptors.Modality 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.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.isConst -import org.jetbrains.kotlin.light.classes.symbol.isLateInit import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightSimpleMethod import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList import org.jetbrains.kotlin.load.java.JvmAbi @@ -263,45 +258,6 @@ internal open class SymbolLightClassForClassOrObject : SymbolLightClassForNamedC } } - context(KtAnalysisSession) - protected fun addPropertyBackingFields(result: MutableList, symbolWithMembers: KtSymbolWithMembers) { - val propertySymbols = symbolWithMembers.getDeclaredMemberScope().getCallableSymbols() - .filterIsInstance() - .applyIf(isCompanionObject) { - // All fields for companion object of classes are generated to the containing class - // For interfaces, only @JvmField-annotated properties are generated to the containing class - // Probably, the same should work for const vals but it doesn't at the moment (see KT-28294) - filter { containingClass?.isInterface == true && !it.hasJvmFieldAnnotation() } - } - - val propertyGroups = propertySymbols.groupBy { it.isFromPrimaryConstructor } - - val nameGenerator = SymbolLightField.FieldNameGenerator() - - fun addPropertyBackingField(propertySymbol: KtPropertySymbol) { - val isJvmField = propertySymbol.hasJvmFieldAnnotation() - val isLateInit = propertySymbol.isLateInit - val isConst = propertySymbol.isConst - - val forceStatic = isObject - val takePropertyVisibility = isLateInit || isJvmField || isConst - - createField( - declaration = propertySymbol, - nameGenerator = nameGenerator, - isTopLevel = false, - forceStatic = forceStatic, - takePropertyVisibility = takePropertyVisibility, - result = result - ) - } - - // First, properties from parameters - propertyGroups[true]?.forEach(::addPropertyBackingField) - // Then, regular member properties - propertyGroups[false]?.forEach(::addPropertyBackingField) - } - context(KtAnalysisSession) private fun addInstanceFieldIfNeeded(result: MutableList, namedClassOrObjectSymbol: KtNamedClassOrObjectSymbol) { if (!isNamedObject || isLocal) return 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 2bc353b8dd4..e33ead15cb8 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,19 +11,19 @@ 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.KtLightField +import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.light.classes.symbol.codeReferences.SymbolLightPsiJavaCodeReferenceElementWithNoReference import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForEnumEntry import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList +import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind +import org.jetbrains.kotlin.psi.KtEnumEntry internal class SymbolLightClassForEnumEntry( private val enumConstant: SymbolLightFieldForEnumEntry, private val enumClass: SymbolLightClassForClassOrObject, ktModule: KtModule, -) : SymbolLightClassForClassOrObject( - enumConstant.kotlinOrigin, - ktModule, -), PsiEnumConstantInitializer { +) : SymbolLightClassBase(ktModule, enumConstant.manager), PsiEnumConstantInitializer { override fun getBaseClassType(): PsiClassType = enumConstant.type as PsiClassType //???TODO override fun getBaseClassReference(): PsiJavaCodeReferenceElement = @@ -85,10 +85,11 @@ internal class SymbolLightClassForEnumEntry( override fun getSuperClass(): PsiClass = enumClass override fun getInterfaces(): Array = PsiClass.EMPTY_ARRAY override fun getSupers(): Array = arrayOf(enumClass) + override fun getSuperTypes(): Array = arrayOf(baseClassType) - override fun getParent(): PsiElement? = containingClass + override fun getParent(): PsiElement = containingClass - override fun getScope(): PsiElement? = parent + override fun getScope(): PsiElement = parent private val _ownFields: List by lazyPub { enumConstant.withEnumEntrySymbol { enumEntrySymbol -> @@ -110,9 +111,7 @@ internal class SymbolLightClassForEnumEntry( val declaredMemberScope = enumEntrySymbol.getDeclaredMemberScope() val visibleDeclarations = declaredMemberScope.getCallableSymbols() - val suppressStatic = isCompanionObject - createMethods(visibleDeclarations, result, suppressStatic = suppressStatic) - + createMethods(visibleDeclarations, result) createConstructors(declaredMemberScope.getConstructors(), result) result @@ -121,4 +120,25 @@ internal class SymbolLightClassForEnumEntry( override fun getOwnMethods(): List = _ownMethods override fun getOwnInnerClasses(): MutableList = mutableListOf() + override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean { + if (!checkDeep) return baseClass == enumClass + + return super.isInheritor(baseClass, checkDeep = true) + } + + private val _identifier: PsiIdentifier by lazyPub { + KtLightIdentifier(this, kotlinOrigin) + } + + // probably should be dropped after KT-54798 + override fun getNameIdentifier(): PsiIdentifier = _identifier + override fun getName(): String? = kotlinOrigin.name + + override fun isDeprecated(): Boolean = false + override fun isInterface(): Boolean = false + override fun isAnnotationType(): Boolean = false + override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean = false + override val kotlinOrigin: KtEnumEntry get() = enumConstant.kotlinOrigin + override val originKind: LightClassOriginKind = LightClassOriginKind.SOURCE + override fun isValid(): Boolean = enumConstant.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 b63316c3f54..82b91cd6cf6 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 @@ -35,6 +35,8 @@ import org.jetbrains.kotlin.light.classes.symbol.copy 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.SymbolLightFieldForProperty +import org.jetbrains.kotlin.light.classes.symbol.isConst +import org.jetbrains.kotlin.light.classes.symbol.isLateInit import org.jetbrains.kotlin.light.classes.symbol.mapType import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightAccessorMethod import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightConstructor @@ -46,6 +48,7 @@ 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 org.jetbrains.kotlin.utils.addToStdlib.applyIf import java.util.* internal fun createSymbolLightClassNoCache(classOrObject: KtClassOrObject, ktModule: KtModule): KtLightClass? = when { @@ -101,7 +104,7 @@ private fun lightClassForEnumEntry(ktEnumEntry: KtEnumEntry): KtLightClass? { } context(KtAnalysisSession) -internal fun SymbolLightClassForClassLike<*>.createConstructors( +internal fun SymbolLightClassBase.createConstructors( declarations: Sequence, result: MutableList, ) { @@ -156,10 +159,10 @@ private fun SymbolLightClassBase.shouldGenerateNoArgOverload( !primaryConstructor.hasJvmOverloadsAnnotation() } -private fun SymbolLightClassForClassLike<*>.defaultConstructor(): KtLightMethod { +private fun SymbolLightClassBase.defaultConstructor(): KtLightMethod { val classOrObject = kotlinOrigin val visibility = when { - isObject || isEnum -> PsiModifier.PRIVATE + this is SymbolLightClassForClassLike<*> && (isObject || isEnum) -> PsiModifier.PRIVATE classOrObject?.hasModifier(SEALED_KEYWORD) == true -> PsiModifier.PROTECTED this is SymbolLightClassForEnumEntry -> PsiModifier.PACKAGE_LOCAL else -> PsiModifier.PUBLIC @@ -168,7 +171,7 @@ private fun SymbolLightClassForClassLike<*>.defaultConstructor(): KtLightMethod return noArgConstructor(visibility, METHOD_INDEX_FOR_DEFAULT_CTOR) } -private fun SymbolLightClassForClassLike<*>.noArgConstructor( +private fun SymbolLightClassBase.noArgConstructor( visibility: String, methodIndex: Int, ): KtLightMethod = SymbolLightNoArgConstructor( @@ -516,3 +519,45 @@ internal fun KtClassOrObject.checkIsInheritor(superClassOrigin: KtClassOrObject, private val KtSymbolWithTypeParameters.hasReifiedParameters: Boolean get() = typeParameters.any { it.isReified } + +context(KtAnalysisSession) +internal fun SymbolLightClassBase.addPropertyBackingFields( + result: MutableList, + symbolWithMembers: KtSymbolWithMembers, +) { + val propertySymbols = symbolWithMembers.getDeclaredMemberScope().getCallableSymbols() + .filterIsInstance() + .applyIf(symbolWithMembers is KtClassOrObjectSymbol && symbolWithMembers.classKind == KtClassKind.COMPANION_OBJECT) { + // All fields for companion object of classes are generated to the containing class + // For interfaces, only @JvmField-annotated properties are generated to the containing class + // Probably, the same should work for const vals but it doesn't at the moment (see KT-28294) + filter { containingClass?.isInterface == true && !it.hasJvmFieldAnnotation() } + } + + val propertyGroups = propertySymbols.groupBy { it.isFromPrimaryConstructor } + + val nameGenerator = SymbolLightField.FieldNameGenerator() + + val forceStatic = symbolWithMembers is KtClassOrObjectSymbol && symbolWithMembers.classKind.isObject + fun addPropertyBackingField(propertySymbol: KtPropertySymbol) { + val isJvmField = propertySymbol.hasJvmFieldAnnotation() + val isLateInit = propertySymbol.isLateInit + val isConst = propertySymbol.isConst + + val takePropertyVisibility = isLateInit || isJvmField || isConst + + createField( + declaration = propertySymbol, + nameGenerator = nameGenerator, + isTopLevel = false, + forceStatic = forceStatic, + takePropertyVisibility = takePropertyVisibility, + result = result + ) + } + + // First, properties from parameters + propertyGroups[true]?.forEach(::addPropertyBackingField) + // Then, regular member properties + propertyGroups[false]?.forEach(::addPropertyBackingField) +} 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 afbc3b6570e..83d22f00d77 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 @@ -9,13 +9,13 @@ import com.intellij.psi.* import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier -import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForClassLike +import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightMemberModifierList import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightParameterList internal class SymbolLightNoArgConstructor( lightMemberOrigin: LightMemberOrigin?, - containingClass: SymbolLightClassForClassLike<*>, + containingClass: SymbolLightClassBase, private val visibility: String, methodIndex: Int, ) : SymbolLightMethodBase(lightMemberOrigin, containingClass, methodIndex) {