[SLC] SymbolLightClassForEnumEntry: shouldn't be regular class
^KTIJ-23842 Fixed
This commit is contained in:
committed by
Space Team
parent
2405dd2c5c
commit
cc9beb466e
-44
@@ -11,7 +11,6 @@ import com.intellij.psi.PsiModifierList
|
|||||||
import com.intellij.psi.PsiReferenceList
|
import com.intellij.psi.PsiReferenceList
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.*
|
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.KtSymbolPointer
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.pointers.symbolPointerOfType
|
import org.jetbrains.kotlin.analysis.api.symbols.pointers.symbolPointerOfType
|
||||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
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.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.NullabilityType
|
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.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.SymbolLightFieldForEnumEntry
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForObject
|
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.methods.SymbolLightSimpleMethod
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList
|
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
@@ -263,45 +258,6 @@ internal open class SymbolLightClassForClassOrObject : SymbolLightClassForNamedC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context(KtAnalysisSession)
|
|
||||||
protected fun addPropertyBackingFields(result: MutableList<KtLightField>, symbolWithMembers: KtSymbolWithMembers) {
|
|
||||||
val propertySymbols = symbolWithMembers.getDeclaredMemberScope().getCallableSymbols()
|
|
||||||
.filterIsInstance<KtPropertySymbol>()
|
|
||||||
.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)
|
context(KtAnalysisSession)
|
||||||
private fun addInstanceFieldIfNeeded(result: MutableList<KtLightField>, namedClassOrObjectSymbol: KtNamedClassOrObjectSymbol) {
|
private fun addInstanceFieldIfNeeded(result: MutableList<KtLightField>, namedClassOrObjectSymbol: KtNamedClassOrObjectSymbol) {
|
||||||
if (!isNamedObject || isLocal) return
|
if (!isNamedObject || isLocal) return
|
||||||
|
|||||||
+29
-9
@@ -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.KotlinSuperTypeListBuilder
|
||||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
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.asJava.elements.KtLightMethod
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.codeReferences.SymbolLightPsiJavaCodeReferenceElementWithNoReference
|
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.fields.SymbolLightFieldForEnumEntry
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList
|
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(
|
internal class SymbolLightClassForEnumEntry(
|
||||||
private val enumConstant: SymbolLightFieldForEnumEntry,
|
private val enumConstant: SymbolLightFieldForEnumEntry,
|
||||||
private val enumClass: SymbolLightClassForClassOrObject,
|
private val enumClass: SymbolLightClassForClassOrObject,
|
||||||
ktModule: KtModule,
|
ktModule: KtModule,
|
||||||
) : SymbolLightClassForClassOrObject(
|
) : SymbolLightClassBase(ktModule, enumConstant.manager), PsiEnumConstantInitializer {
|
||||||
enumConstant.kotlinOrigin,
|
|
||||||
ktModule,
|
|
||||||
), PsiEnumConstantInitializer {
|
|
||||||
override fun getBaseClassType(): PsiClassType = enumConstant.type as PsiClassType //???TODO
|
override fun getBaseClassType(): PsiClassType = enumConstant.type as PsiClassType //???TODO
|
||||||
|
|
||||||
override fun getBaseClassReference(): PsiJavaCodeReferenceElement =
|
override fun getBaseClassReference(): PsiJavaCodeReferenceElement =
|
||||||
@@ -85,10 +85,11 @@ internal class SymbolLightClassForEnumEntry(
|
|||||||
override fun getSuperClass(): PsiClass = enumClass
|
override fun getSuperClass(): PsiClass = enumClass
|
||||||
override fun getInterfaces(): Array<PsiClass> = PsiClass.EMPTY_ARRAY
|
override fun getInterfaces(): Array<PsiClass> = PsiClass.EMPTY_ARRAY
|
||||||
override fun getSupers(): Array<PsiClass> = arrayOf(enumClass)
|
override fun getSupers(): Array<PsiClass> = arrayOf(enumClass)
|
||||||
|
override fun getSuperTypes(): Array<PsiClassType> = 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<KtLightField> by lazyPub {
|
private val _ownFields: List<KtLightField> by lazyPub {
|
||||||
enumConstant.withEnumEntrySymbol { enumEntrySymbol ->
|
enumConstant.withEnumEntrySymbol { enumEntrySymbol ->
|
||||||
@@ -110,9 +111,7 @@ internal class SymbolLightClassForEnumEntry(
|
|||||||
val declaredMemberScope = enumEntrySymbol.getDeclaredMemberScope()
|
val declaredMemberScope = enumEntrySymbol.getDeclaredMemberScope()
|
||||||
val visibleDeclarations = declaredMemberScope.getCallableSymbols()
|
val visibleDeclarations = declaredMemberScope.getCallableSymbols()
|
||||||
|
|
||||||
val suppressStatic = isCompanionObject
|
createMethods(visibleDeclarations, result)
|
||||||
createMethods(visibleDeclarations, result, suppressStatic = suppressStatic)
|
|
||||||
|
|
||||||
createConstructors(declaredMemberScope.getConstructors(), result)
|
createConstructors(declaredMemberScope.getConstructors(), result)
|
||||||
|
|
||||||
result
|
result
|
||||||
@@ -121,4 +120,25 @@ internal class SymbolLightClassForEnumEntry(
|
|||||||
|
|
||||||
override fun getOwnMethods(): List<KtLightMethod> = _ownMethods
|
override fun getOwnMethods(): List<KtLightMethod> = _ownMethods
|
||||||
override fun getOwnInnerClasses(): MutableList<PsiClass> = mutableListOf()
|
override fun getOwnInnerClasses(): MutableList<PsiClass> = 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
|
||||||
}
|
}
|
||||||
|
|||||||
+49
-4
@@ -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.SymbolLightField
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForEnumEntry
|
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.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.mapType
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightAccessorMethod
|
import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightAccessorMethod
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightConstructor
|
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.containingClass
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral
|
import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
internal fun createSymbolLightClassNoCache(classOrObject: KtClassOrObject, ktModule: KtModule): KtLightClass? = when {
|
internal fun createSymbolLightClassNoCache(classOrObject: KtClassOrObject, ktModule: KtModule): KtLightClass? = when {
|
||||||
@@ -101,7 +104,7 @@ private fun lightClassForEnumEntry(ktEnumEntry: KtEnumEntry): KtLightClass? {
|
|||||||
}
|
}
|
||||||
|
|
||||||
context(KtAnalysisSession)
|
context(KtAnalysisSession)
|
||||||
internal fun SymbolLightClassForClassLike<*>.createConstructors(
|
internal fun SymbolLightClassBase.createConstructors(
|
||||||
declarations: Sequence<KtConstructorSymbol>,
|
declarations: Sequence<KtConstructorSymbol>,
|
||||||
result: MutableList<KtLightMethod>,
|
result: MutableList<KtLightMethod>,
|
||||||
) {
|
) {
|
||||||
@@ -156,10 +159,10 @@ private fun SymbolLightClassBase.shouldGenerateNoArgOverload(
|
|||||||
!primaryConstructor.hasJvmOverloadsAnnotation()
|
!primaryConstructor.hasJvmOverloadsAnnotation()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SymbolLightClassForClassLike<*>.defaultConstructor(): KtLightMethod {
|
private fun SymbolLightClassBase.defaultConstructor(): KtLightMethod {
|
||||||
val classOrObject = kotlinOrigin
|
val classOrObject = kotlinOrigin
|
||||||
val visibility = when {
|
val visibility = when {
|
||||||
isObject || isEnum -> PsiModifier.PRIVATE
|
this is SymbolLightClassForClassLike<*> && (isObject || isEnum) -> PsiModifier.PRIVATE
|
||||||
classOrObject?.hasModifier(SEALED_KEYWORD) == true -> PsiModifier.PROTECTED
|
classOrObject?.hasModifier(SEALED_KEYWORD) == true -> PsiModifier.PROTECTED
|
||||||
this is SymbolLightClassForEnumEntry -> PsiModifier.PACKAGE_LOCAL
|
this is SymbolLightClassForEnumEntry -> PsiModifier.PACKAGE_LOCAL
|
||||||
else -> PsiModifier.PUBLIC
|
else -> PsiModifier.PUBLIC
|
||||||
@@ -168,7 +171,7 @@ private fun SymbolLightClassForClassLike<*>.defaultConstructor(): KtLightMethod
|
|||||||
return noArgConstructor(visibility, METHOD_INDEX_FOR_DEFAULT_CTOR)
|
return noArgConstructor(visibility, METHOD_INDEX_FOR_DEFAULT_CTOR)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SymbolLightClassForClassLike<*>.noArgConstructor(
|
private fun SymbolLightClassBase.noArgConstructor(
|
||||||
visibility: String,
|
visibility: String,
|
||||||
methodIndex: Int,
|
methodIndex: Int,
|
||||||
): KtLightMethod = SymbolLightNoArgConstructor(
|
): KtLightMethod = SymbolLightNoArgConstructor(
|
||||||
@@ -516,3 +519,45 @@ internal fun KtClassOrObject.checkIsInheritor(superClassOrigin: KtClassOrObject,
|
|||||||
|
|
||||||
private val KtSymbolWithTypeParameters.hasReifiedParameters: Boolean
|
private val KtSymbolWithTypeParameters.hasReifiedParameters: Boolean
|
||||||
get() = typeParameters.any { it.isReified }
|
get() = typeParameters.any { it.isReified }
|
||||||
|
|
||||||
|
context(KtAnalysisSession)
|
||||||
|
internal fun SymbolLightClassBase.addPropertyBackingFields(
|
||||||
|
result: MutableList<KtLightField>,
|
||||||
|
symbolWithMembers: KtSymbolWithMembers,
|
||||||
|
) {
|
||||||
|
val propertySymbols = symbolWithMembers.getDeclaredMemberScope().getCallableSymbols()
|
||||||
|
.filterIsInstance<KtPropertySymbol>()
|
||||||
|
.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)
|
||||||
|
}
|
||||||
|
|||||||
+2
-2
@@ -9,13 +9,13 @@ import com.intellij.psi.*
|
|||||||
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
||||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
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.modifierLists.SymbolLightMemberModifierList
|
||||||
import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightParameterList
|
import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightParameterList
|
||||||
|
|
||||||
internal class SymbolLightNoArgConstructor(
|
internal class SymbolLightNoArgConstructor(
|
||||||
lightMemberOrigin: LightMemberOrigin?,
|
lightMemberOrigin: LightMemberOrigin?,
|
||||||
containingClass: SymbolLightClassForClassLike<*>,
|
containingClass: SymbolLightClassBase,
|
||||||
private val visibility: String,
|
private val visibility: String,
|
||||||
methodIndex: Int,
|
methodIndex: Int,
|
||||||
) : SymbolLightMethodBase(lightMemberOrigin, containingClass, methodIndex) {
|
) : SymbolLightMethodBase(lightMemberOrigin, containingClass, methodIndex) {
|
||||||
|
|||||||
Reference in New Issue
Block a user