FIR/LC: create synthetic members of enum class

^KTIJ-17414 In Progress
^KTIJ-17444 In Progress
This commit is contained in:
Jinseong Jeon
2022-02-12 01:16:37 -08:00
committed by Ilya Kirillov
parent 790f2d13ae
commit 1b6ded6005
13 changed files with 133 additions and 10 deletions
@@ -96,8 +96,10 @@ internal open class FirLightClassForSymbol(
val declaredMemberScope = classOrObjectSymbol.getDeclaredMemberScope()
val visibleDeclarations = declaredMemberScope.getCallableSymbols().applyIf(isEnum) {
// Technically, synthetic members of `enum` class, such as `values` or `valueOf`, 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 is KtFunctionSymbol && function.origin == KtSymbolOrigin.SOURCE_MEMBER_GENERATED &&
(function.name == ENUM_VALUES || function.name == ENUM_VALUE_OF)
}
}.applyIf(classOrObjectSymbol.isObject) {
@@ -120,6 +122,7 @@ internal open class FirLightClassForSymbol(
addMethodsFromCompanionIfNeeded(result)
addMethodsFromEnumClass(result)
addMethodsFromDataClass(result)
addDelegatesToInterfaceMethods(result)
@@ -137,6 +140,19 @@ internal open class FirLightClassForSymbol(
}
}
private fun addMethodsFromEnumClass(result: MutableList<KtLightMethod>) {
if (!isEnum) return
analyzeWithSymbolAsContext(classOrObjectSymbol) {
val valuesAndValueOfFunctions = classOrObjectSymbol.getDeclaredMemberScope()
.getCallableSymbols { name -> name == ENUM_VALUES || name == ENUM_VALUE_OF }
.filter { it.origin == KtSymbolOrigin.SOURCE_MEMBER_GENERATED }
.filterIsInstance<KtFunctionSymbol>()
createMethods(valuesAndValueOfFunctions, result)
}
}
private fun addMethodsFromDataClass(result: MutableList<KtLightMethod>) {
if (!classOrObjectSymbol.isData) return
@@ -31,7 +31,7 @@ internal abstract class FirLightParameterBaseForSymbol(
protected val nullabilityType: NullabilityType
get() {
val nullabilityApplicable = !containingMethod.containingClass.let { it.isAnnotationType || it.isEnum } &&
val nullabilityApplicable = !containingMethod.containingClass.let { it.isAnnotationType } &&
!containingMethod.hasModifierProperty(PsiModifier.PRIVATE)
return if (nullabilityApplicable) {