LC: rework modality of enum class

It is abstract if it has abstract member.
It is final if it doesn't have enum entries that need subclass.
Otherwise, it is open (i.e., no modifier)

^KT-57567 Fixed
This commit is contained in:
Jinseong Jeon
2023-06-15 19:23:22 -07:00
committed by Ilya Kirillov
parent 7930885131
commit 7f1424737e
7 changed files with 55 additions and 11 deletions
@@ -142,7 +142,10 @@ abstract class SymbolLightClassForNamedClassLike : SymbolLightClassForClassLike<
GranularModifiersBox.computeVisibilityForClass(ktModule, classOrObjectSymbolPointer, isTopLevel)
}
in GranularModifiersBox.MODALITY_MODIFIERS -> GranularModifiersBox.computeSimpleModality(ktModule, classOrObjectSymbolPointer)
in GranularModifiersBox.MODALITY_MODIFIERS -> {
GranularModifiersBox.computeSimpleModality(ktModule, classOrObjectSymbolPointer)
}
PsiModifier.STATIC -> {
val isStatic = !isTopLevel && !isInner
mapOf(modifier to isStatic)
@@ -8,10 +8,13 @@ package org.jetbrains.kotlin.light.classes.symbol.modifierLists
import com.intellij.psi.PsiModifier
import kotlinx.collections.immutable.PersistentMap
import kotlinx.collections.immutable.toPersistentHashMap
import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind
import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithModality
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.light.classes.symbol.*
import org.jetbrains.kotlin.light.classes.symbol.computeSimpleModality
import org.jetbrains.kotlin.light.classes.symbol.toPsiVisibilityForClass
import org.jetbrains.kotlin.light.classes.symbol.toPsiVisibilityForMember
@@ -89,7 +92,11 @@ internal class GranularModifiersBox(
declarationPointer: KtSymbolPointer<KtSymbolWithModality>,
): PersistentMap<String, Boolean> {
val modality = declarationPointer.withSymbol(ktModule) {
it.computeSimpleModality()
if ((it as? KtClassOrObjectSymbol)?.classKind == KtClassKind.ENUM_CLASS) {
it.enumClassModality()
} else {
it.computeSimpleModality()
}
}
return MODALITY_MODIFIERS_MAP.with(modality)
@@ -15,9 +15,7 @@ import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.annotations.*
import org.jetbrains.kotlin.analysis.api.base.KtConstantValue
import org.jetbrains.kotlin.analysis.api.components.DefaultTypeClassIds
import org.jetbrains.kotlin.analysis.api.symbols.KtKotlinPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithModality
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithTypeParameters
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility
@@ -78,6 +76,24 @@ internal fun KtSymbolWithModality.computeSimpleModality(): String? = when (modal
Modality.OPEN -> null
}
context(KtAnalysisSession)
internal fun KtClassOrObjectSymbol.enumClassModality(): String? {
if (getMemberScope().getCallableSymbols().any { (it as? KtSymbolWithModality)?.modality == Modality.ABSTRACT }) {
return PsiModifier.ABSTRACT
}
if (getDeclaredMemberScope().getCallableSymbols().none { it is KtEnumEntrySymbol && it.requiresSubClass() }) {
return PsiModifier.FINAL
}
return null
}
context(KtAnalysisSession)
private fun KtEnumEntrySymbol.requiresSubClass(): Boolean {
return getDeclaredMemberScope().getAllSymbols().any { it !is KtConstructorSymbol }
}
internal fun KtSymbolWithVisibility.toPsiVisibilityForMember(): String = visibility.toPsiVisibilityForMember()
internal fun KtSymbolWithVisibility.toPsiVisibilityForClass(isNested: Boolean): String = visibility.toPsiVisibilityForClass(isNested)