[AA] Add KtEnumEntryInitializerSymbol
- An enum entry's body is an initializer with members only accessible
within that body. Because users of the Analysis API might want to
analyze the members of the enum entry initializer, we expose this
initializer via `KtEnumEntrySymbol`. The initializer only exists if
the enum entry has a body.
- We already have some usages of the initializer inside symbol light
classes, which generate a light class for each enum entry, which
includes the enum entry's hidden members.
- To hide the implementation detail that initializers are anonymous
objects, `KtEnumEntryInitializerSymbol` is simply a
`KtSymbolWithMembers`.
- The advantage of making it a `KtSymbolWithMembers`, instead of
providing a custom way to get a member scope, is that we can pass
around the initializer easily, e.g. in `KtEnumEntrySymbolRenderer`.
- We implement `KtEnumEntryInitializerSymbol` directly as a
`KtFirAnonymousObjectSymbol` without a wrapper. This has a few
advantages:
1. We can directly benefit from the anonymous object symbol being a
`KtSymbolWithMembers`, so we don't have to handle enum entry
initializers specially in e.g. `KtFirScopeProvider`.
2. We don't have to implement a new symbol restoration mechanism for
the initializer.
3. This implementation matches the actual FIR tree structure (with a
simplification that the connecting anonymous object expression
between the enum entry and the initializing anonymous object is
omitted).
^KT-61425 fixed
This commit is contained in:
committed by
Space Team
parent
e72a38dc82
commit
80efa34926
+7
-1
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.analysis.api.descriptors.symbols.isEqualTo
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.pointers.KtFe10DescEnumEntrySymbolPointer
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.pointers.KtFe10NeverRestoringSymbolPointer
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntryInitializerSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtPsiBasedSymbolPointer
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
|
||||
@@ -27,7 +28,7 @@ import org.jetbrains.kotlin.name.Name
|
||||
internal class KtFe10DescEnumEntrySymbol(
|
||||
override val descriptor: ClassDescriptor,
|
||||
override val analysisContext: Fe10AnalysisContext
|
||||
) : KtEnumEntrySymbol(), KtFe10DescMemberSymbol<ClassDescriptor> {
|
||||
) : KtEnumEntrySymbol(), KtEnumEntryInitializerSymbol, KtFe10DescMemberSymbol<ClassDescriptor> {
|
||||
private val enumDescriptor: ClassDescriptor
|
||||
get() = descriptor.containingDeclaration as ClassDescriptor
|
||||
|
||||
@@ -50,6 +51,11 @@ internal class KtFe10DescEnumEntrySymbol(
|
||||
override val name: Name
|
||||
get() = withValidityAssertion { descriptor.name }
|
||||
|
||||
// There doesn't seem to be a way to determine if `descriptor` has a body or not, so we return an initializer even for enum entries
|
||||
// without a body.
|
||||
override val enumEntryInitializer: KtEnumEntryInitializerSymbol?
|
||||
get() = this
|
||||
|
||||
context(KtAnalysisSession)
|
||||
override fun createPointer(): KtSymbolPointer<KtEnumEntrySymbol> = withValidityAssertion {
|
||||
KtPsiBasedSymbolPointer.createForSymbolFromSource<KtEnumEntrySymbol>(this)?.let {
|
||||
|
||||
+5
-1
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.base.calla
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.base.createErrorType
|
||||
import org.jetbrains.kotlin.analysis.api.descriptors.utils.cached
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntryInitializerSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtPsiBasedSymbolPointer
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
|
||||
@@ -33,7 +34,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
internal class KtFe10PsiEnumEntrySymbol(
|
||||
override val psi: KtEnumEntry,
|
||||
override val analysisContext: Fe10AnalysisContext
|
||||
) : KtEnumEntrySymbol(), KtFe10PsiSymbol<KtEnumEntry, ClassDescriptor> {
|
||||
) : KtEnumEntrySymbol(), KtEnumEntryInitializerSymbol, KtFe10PsiSymbol<KtEnumEntry, ClassDescriptor> {
|
||||
override val descriptor: ClassDescriptor? by cached {
|
||||
val bindingContext = analysisContext.analyze(psi, AnalysisMode.PARTIAL)
|
||||
bindingContext[BindingContext.CLASS, psi]
|
||||
@@ -61,6 +62,9 @@ internal class KtFe10PsiEnumEntrySymbol(
|
||||
override val name: Name
|
||||
get() = withValidityAssertion { psi.nameAsSafeName }
|
||||
|
||||
override val enumEntryInitializer: KtEnumEntryInitializerSymbol?
|
||||
get() = this.takeIf { psi.body != null }
|
||||
|
||||
context(KtAnalysisSession)
|
||||
override fun createPointer(): KtSymbolPointer<KtEnumEntrySymbol> = withValidityAssertion {
|
||||
KtPsiBasedSymbolPointer.createForSymbolFromSource(this) ?: KtFe10NeverRestoringSymbolPointer()
|
||||
|
||||
+2
-1
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.requireOwnerPointe
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtAnonymousObjectSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntryInitializerSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.CanNotCreateSymbolPointerForLocalLibraryDeclarationException
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtPsiBasedSymbolPointer
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
|
||||
@@ -25,7 +26,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousObjectSymbol
|
||||
internal class KtFirAnonymousObjectSymbol(
|
||||
override val firSymbol: FirAnonymousObjectSymbol,
|
||||
override val analysisSession: KtFirAnalysisSession,
|
||||
) : KtAnonymousObjectSymbol(), KtFirSymbol<FirAnonymousObjectSymbol> {
|
||||
) : KtAnonymousObjectSymbol(), KtEnumEntryInitializerSymbol, KtFirSymbol<FirAnonymousObjectSymbol> {
|
||||
override val psi: PsiElement? = withValidityAssertion { firSymbol.fir.getAllowedPsi() }
|
||||
|
||||
override val annotationsList by cached {
|
||||
|
||||
+18
@@ -15,11 +15,15 @@ import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.KtFirEnumEntrySymb
|
||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.requireOwnerPointer
|
||||
import org.jetbrains.kotlin.analysis.api.fir.utils.cached
|
||||
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntryInitializerSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtPsiBasedSymbolPointer
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnonymousObjectExpression
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -41,6 +45,20 @@ internal class KtFirEnumEntrySymbol(
|
||||
|
||||
override val callableIdIfNonLocal: CallableId? get() = withValidityAssertion { firSymbol.getCallableIdIfNonLocal() }
|
||||
|
||||
override val enumEntryInitializer: KtEnumEntryInitializerSymbol? by cached {
|
||||
if (firSymbol.fir.initializer == null) {
|
||||
return@cached null
|
||||
}
|
||||
|
||||
firSymbol.fir.lazyResolveToPhase(FirResolvePhase.BODY_RESOLVE)
|
||||
|
||||
val initializerExpression = firSymbol.fir.initializer
|
||||
check(initializerExpression is FirAnonymousObjectExpression) {
|
||||
"Unexpected enum entry initializer: ${initializerExpression?.javaClass}"
|
||||
}
|
||||
KtFirAnonymousObjectSymbol(initializerExpression.anonymousObject.symbol, analysisSession)
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
override fun createPointer(): KtSymbolPointer<KtEnumEntrySymbol> = withValidityAssertion {
|
||||
KtPsiBasedSymbolPointer.createForSymbolFromSource(this) ?: KtFirEnumEntrySymbolPointer(requireOwnerPointer(), firSymbol.name)
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ public interface KtEnumEntrySymbolRenderer {
|
||||
" ".separated(
|
||||
{ renderAnnotationsModifiersAndContextReceivers(symbol, printer) },
|
||||
{ nameRenderer.renderName(symbol, printer) },
|
||||
{ classifierBodyRenderer.renderBody(symbol, printer) },
|
||||
{ symbol.enumEntryInitializer?.let { classifierBodyRenderer.renderBody(it, printer) } },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+27
@@ -91,10 +91,37 @@ public abstract class KtEnumEntrySymbol : KtVariableLikeSymbol(), KtSymbolWithKi
|
||||
//todo reduntant, remove
|
||||
public abstract val containingEnumClassIdIfNonLocal: ClassId?
|
||||
|
||||
/**
|
||||
* Returns the enum entry's initializer, or `null` if the enum entry doesn't have a body.
|
||||
*/
|
||||
public abstract val enumEntryInitializer: KtEnumEntryInitializerSymbol?
|
||||
|
||||
context(KtAnalysisSession)
|
||||
abstract override fun createPointer(): KtSymbolPointer<KtEnumEntrySymbol>
|
||||
}
|
||||
|
||||
/**
|
||||
* An initializer for enum entries with a body. The initializer may contain its own declarations (especially overrides of members declared
|
||||
* by the enum class), and is [similar to an object declaration](https://kotlinlang.org/spec/declarations.html#enum-class-declaration).
|
||||
*
|
||||
* #### Example
|
||||
*
|
||||
* ```kotlin
|
||||
* enum class E {
|
||||
* // `A` is declared with an initializer.
|
||||
* A {
|
||||
* val x: Int = 5
|
||||
* },
|
||||
*
|
||||
* // `B` has no initializer.
|
||||
* B
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* The initializer of `A` declares a member `x: Int`, which is inaccessible outside the initializer. Still, the corresponding
|
||||
* [KtEnumEntryInitializerSymbol] can be used to get a declared member scope that contains `x`.
|
||||
*/
|
||||
public interface KtEnumEntryInitializerSymbol : KtSymbolWithMembers
|
||||
|
||||
public sealed class KtVariableSymbol : KtVariableLikeSymbol() {
|
||||
public abstract val isVal: Boolean
|
||||
|
||||
Vendored
+1
@@ -519,6 +519,7 @@ scopes:
|
||||
callableIdIfNonLocal: /E.A
|
||||
containingEnumClassIdIfNonLocal: E
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: KtAnonymousObjectSymbol(<local>/<no name provided>)
|
||||
isExtension: false
|
||||
name: A
|
||||
origin: SOURCE
|
||||
|
||||
+1
@@ -3,6 +3,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: kotlin/LazyThreadSafetyMode.SYNCHRONIZED
|
||||
containingEnumClassIdIfNonLocal: kotlin/LazyThreadSafetyMode
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: KtEnumEntrySymbol(kotlin/LazyThreadSafetyMode.SYNCHRONIZED)
|
||||
isExtension: false
|
||||
name: SYNCHRONIZED
|
||||
origin: LIBRARY
|
||||
|
||||
@@ -3,6 +3,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: kotlin/LazyThreadSafetyMode.SYNCHRONIZED
|
||||
containingEnumClassIdIfNonLocal: kotlin/LazyThreadSafetyMode
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: null
|
||||
isExtension: false
|
||||
name: SYNCHRONIZED
|
||||
origin: LIBRARY
|
||||
|
||||
@@ -3,6 +3,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /X.Y
|
||||
containingEnumClassIdIfNonLocal: X
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: null
|
||||
isExtension: false
|
||||
name: Y
|
||||
origin: SOURCE
|
||||
@@ -21,6 +22,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /X.Z
|
||||
containingEnumClassIdIfNonLocal: X
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: null
|
||||
isExtension: false
|
||||
name: Z
|
||||
origin: SOURCE
|
||||
|
||||
+3
@@ -39,6 +39,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /MyEnumClass.FirstEntry
|
||||
containingEnumClassIdIfNonLocal: MyEnumClass
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: KtEnumEntrySymbol(/MyEnumClass.FirstEntry)
|
||||
isExtension: false
|
||||
name: FirstEntry
|
||||
origin: SOURCE
|
||||
@@ -57,6 +58,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /MyEnumClass.SecondEntry
|
||||
containingEnumClassIdIfNonLocal: MyEnumClass
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: null
|
||||
isExtension: false
|
||||
name: SecondEntry
|
||||
origin: SOURCE
|
||||
@@ -170,6 +172,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /MyEnumClass.ThirdEntry
|
||||
containingEnumClassIdIfNonLocal: MyEnumClass
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: KtEnumEntrySymbol(/MyEnumClass.ThirdEntry)
|
||||
isExtension: false
|
||||
name: ThirdEntry
|
||||
origin: SOURCE
|
||||
|
||||
@@ -39,6 +39,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /MyEnumClass.FirstEntry
|
||||
containingEnumClassIdIfNonLocal: MyEnumClass
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: KtAnonymousObjectSymbol(<local>/<no name provided>)
|
||||
isExtension: false
|
||||
name: FirstEntry
|
||||
origin: SOURCE
|
||||
@@ -57,6 +58,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /MyEnumClass.SecondEntry
|
||||
containingEnumClassIdIfNonLocal: MyEnumClass
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: null
|
||||
isExtension: false
|
||||
name: SecondEntry
|
||||
origin: SOURCE
|
||||
@@ -170,6 +172,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /MyEnumClass.ThirdEntry
|
||||
containingEnumClassIdIfNonLocal: MyEnumClass
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: KtAnonymousObjectSymbol(<local>/<no name provided>)
|
||||
isExtension: false
|
||||
name: ThirdEntry
|
||||
origin: SOURCE
|
||||
|
||||
+3
@@ -75,6 +75,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /MyEnumClass.FirstEntry
|
||||
containingEnumClassIdIfNonLocal: MyEnumClass
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: KtEnumEntrySymbol(/MyEnumClass.FirstEntry)
|
||||
isExtension: false
|
||||
name: FirstEntry
|
||||
origin: SOURCE
|
||||
@@ -214,6 +215,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /MyEnumClass.SecondEntry
|
||||
containingEnumClassIdIfNonLocal: MyEnumClass
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: KtEnumEntrySymbol(/MyEnumClass.SecondEntry)
|
||||
isExtension: false
|
||||
name: SecondEntry
|
||||
origin: SOURCE
|
||||
@@ -327,6 +329,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /MyEnumClass.ThirdEntry
|
||||
containingEnumClassIdIfNonLocal: MyEnumClass
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: KtEnumEntrySymbol(/MyEnumClass.ThirdEntry)
|
||||
isExtension: false
|
||||
name: ThirdEntry
|
||||
origin: SOURCE
|
||||
|
||||
@@ -75,6 +75,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /MyEnumClass.FirstEntry
|
||||
containingEnumClassIdIfNonLocal: MyEnumClass
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: KtAnonymousObjectSymbol(<local>/<no name provided>)
|
||||
isExtension: false
|
||||
name: FirstEntry
|
||||
origin: SOURCE
|
||||
@@ -210,6 +211,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /MyEnumClass.SecondEntry
|
||||
containingEnumClassIdIfNonLocal: MyEnumClass
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: KtAnonymousObjectSymbol(<local>/<no name provided>)
|
||||
isExtension: false
|
||||
name: SecondEntry
|
||||
origin: SOURCE
|
||||
@@ -323,6 +325,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /MyEnumClass.ThirdEntry
|
||||
containingEnumClassIdIfNonLocal: MyEnumClass
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: KtAnonymousObjectSymbol(<local>/<no name provided>)
|
||||
isExtension: false
|
||||
name: ThirdEntry
|
||||
origin: SOURCE
|
||||
|
||||
+3
@@ -88,6 +88,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /MyEnumClass.FirstEntry
|
||||
containingEnumClassIdIfNonLocal: MyEnumClass
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: KtEnumEntrySymbol(/MyEnumClass.FirstEntry)
|
||||
isExtension: false
|
||||
name: FirstEntry
|
||||
origin: SOURCE
|
||||
@@ -106,6 +107,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /MyEnumClass.SecondEntry
|
||||
containingEnumClassIdIfNonLocal: MyEnumClass
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: null
|
||||
isExtension: false
|
||||
name: SecondEntry
|
||||
origin: SOURCE
|
||||
@@ -312,6 +314,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /MyEnumClass.ThirdEntry
|
||||
containingEnumClassIdIfNonLocal: MyEnumClass
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: KtEnumEntrySymbol(/MyEnumClass.ThirdEntry)
|
||||
isExtension: false
|
||||
name: ThirdEntry
|
||||
origin: SOURCE
|
||||
|
||||
@@ -88,6 +88,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /MyEnumClass.FirstEntry
|
||||
containingEnumClassIdIfNonLocal: MyEnumClass
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: KtAnonymousObjectSymbol(<local>/<no name provided>)
|
||||
isExtension: false
|
||||
name: FirstEntry
|
||||
origin: SOURCE
|
||||
@@ -106,6 +107,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /MyEnumClass.SecondEntry
|
||||
containingEnumClassIdIfNonLocal: MyEnumClass
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: null
|
||||
isExtension: false
|
||||
name: SecondEntry
|
||||
origin: SOURCE
|
||||
@@ -308,6 +310,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /MyEnumClass.ThirdEntry
|
||||
containingEnumClassIdIfNonLocal: MyEnumClass
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: KtAnonymousObjectSymbol(<local>/<no name provided>)
|
||||
isExtension: false
|
||||
name: ThirdEntry
|
||||
origin: SOURCE
|
||||
|
||||
+1
@@ -217,6 +217,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /Style.SHEET
|
||||
containingEnumClassIdIfNonLocal: Style
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: KtEnumEntrySymbol(/Style.SHEET)
|
||||
isExtension: false
|
||||
name: SHEET
|
||||
origin: SOURCE
|
||||
|
||||
@@ -213,6 +213,7 @@ KtEnumEntrySymbol:
|
||||
callableIdIfNonLocal: /Style.SHEET
|
||||
containingEnumClassIdIfNonLocal: Style
|
||||
contextReceivers: []
|
||||
enumEntryInitializer: KtAnonymousObjectSymbol(<local>/<no name provided>)
|
||||
isExtension: false
|
||||
name: SHEET
|
||||
origin: SOURCE
|
||||
|
||||
+17
-5
@@ -107,7 +107,17 @@ internal class SymbolLightClassForEnumEntry(
|
||||
val result = mutableListOf<KtLightField>()
|
||||
|
||||
// Then, add instance fields: properties from parameters, and then member properties
|
||||
addPropertyBackingFields(result, enumEntrySymbol)
|
||||
enumEntrySymbol.enumEntryInitializer?.let { initializer ->
|
||||
addPropertyBackingFields(
|
||||
result,
|
||||
initializer,
|
||||
|
||||
// `addPropertyBackingFields` detects that property fields should be static when the given symbol with members is an
|
||||
// object. Unfortunately, the enum entry's initializer is an anonymous object, yet we want the enum entry's light class
|
||||
// to have non-static properties.
|
||||
forceIsStaticTo = false,
|
||||
)
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
@@ -117,11 +127,13 @@ internal class SymbolLightClassForEnumEntry(
|
||||
enumConstant.withEnumEntrySymbol { enumEntrySymbol ->
|
||||
val result = mutableListOf<KtLightMethod>()
|
||||
|
||||
val declaredMemberScope = enumEntrySymbol.getDeclaredMemberScope()
|
||||
val visibleDeclarations = declaredMemberScope.getCallableSymbols()
|
||||
enumEntrySymbol.enumEntryInitializer?.let { initializer ->
|
||||
val declaredMemberScope = initializer.getDeclaredMemberScope()
|
||||
val visibleDeclarations = declaredMemberScope.getCallableSymbols()
|
||||
|
||||
createMethods(visibleDeclarations, result)
|
||||
createConstructors(declaredMemberScope.getConstructors(), result)
|
||||
createMethods(visibleDeclarations, result)
|
||||
createConstructors(declaredMemberScope.getConstructors(), result)
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
+2
-1
@@ -619,6 +619,7 @@ context(KtAnalysisSession)
|
||||
internal fun SymbolLightClassBase.addPropertyBackingFields(
|
||||
result: MutableList<KtLightField>,
|
||||
symbolWithMembers: KtSymbolWithMembers,
|
||||
forceIsStaticTo: Boolean? = null,
|
||||
) {
|
||||
val propertySymbols = symbolWithMembers.getDeclaredMemberScope().getCallableSymbols()
|
||||
.filterIsInstance<KtPropertySymbol>()
|
||||
@@ -633,7 +634,7 @@ internal fun SymbolLightClassBase.addPropertyBackingFields(
|
||||
|
||||
val nameGenerator = SymbolLightField.FieldNameGenerator()
|
||||
|
||||
val isStatic = symbolWithMembers is KtClassOrObjectSymbol && symbolWithMembers.classKind.isObject
|
||||
val isStatic = forceIsStaticTo ?: (symbolWithMembers is KtClassOrObjectSymbol && symbolWithMembers.classKind.isObject)
|
||||
fun addPropertyBackingField(propertySymbol: KtPropertySymbol) {
|
||||
createField(
|
||||
declaration = propertySymbol,
|
||||
|
||||
+2
-1
@@ -96,7 +96,8 @@ internal fun KtClassOrObjectSymbol.enumClassModality(): String? {
|
||||
|
||||
context(KtAnalysisSession)
|
||||
private fun KtEnumEntrySymbol.requiresSubClass(): Boolean {
|
||||
return getDeclaredMemberScope().getAllSymbols().any { it !is KtConstructorSymbol }
|
||||
val initializer = enumEntryInitializer ?: return false
|
||||
return initializer.getDeclaredMemberScope().getAllSymbols().any { it !is KtConstructorSymbol }
|
||||
}
|
||||
|
||||
internal fun KtSymbolWithVisibility.toPsiVisibilityForMember(): String = visibility.toPsiVisibilityForMember()
|
||||
|
||||
Reference in New Issue
Block a user