[SLC] drop KtAnalysisSession from SymbolLightClassBase

^KT-54051
This commit is contained in:
Dmitrii Gridin
2022-09-30 22:48:38 +02:00
committed by Space Team
parent 187557306a
commit a539203e73
16 changed files with 400 additions and 481 deletions
@@ -101,7 +101,7 @@ class SymbolKotlinAsJavaSupport(project: Project) : KotlinAsJavaSupportBase<KtMo
}
override fun createInstanceOfLightClass(classOrObject: KtClassOrObject): KtLightClass? {
return createSymbolLightClassNoCache(classOrObject)
return createSymbolLightClassNoCache(classOrObject, classOrObject.getKtModule(project))
}
override fun createInstanceOfDecompiledLightFacade(facadeFqName: FqName, files: List<KtFile>): KtLightClassForFacade? {
@@ -123,8 +123,11 @@ class SymbolKotlinAsJavaSupport(project: Project) : KotlinAsJavaSupportBase<KtMo
override fun createInstanceOfLightFacade(
facadeFqName: FqName,
files: List<KtFile>,
): KtLightClassForFacade = analyzeForLightClasses(files.first()) {
SymbolLightClassForFacade(facadeFqName, files)
): KtLightClassForFacade {
val firstFile = files.first()
return analyzeForLightClasses(firstFile) {
SymbolLightClassForFacade(facadeFqName, files, firstFile.getKtModule(project))
}
}
override val KtModule.contentSearchScope: GlobalSearchScope get() = this.contentScope
@@ -30,7 +30,7 @@ class SymbolBasedFakeLightClass(kotlinOrigin: KtClassOrObject) :
LightClassInheritanceHelper.getService(project).isInheritor(this, baseClass, checkDeep).ifSure { return it }
val baseClassOrigin = (baseClass as? KtLightClass)?.kotlinOrigin ?: return false
return analyzeForLightClasses(baseClassOrigin) {
return analyzeForLightClasses(kotlinOrigin) {
kotlinOrigin.checkIsInheritor(baseClassOrigin, checkDeep)
}
}
@@ -5,52 +5,41 @@
package org.jetbrains.kotlin.light.classes.symbol.classes
import com.intellij.psi.PsiManager
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiReferenceList
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.lifetime.isValid
import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind
import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.isPrivateOrPrivateToThis
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.psi.KtClassOrObject
context(KtAnalysisSession)
internal class SymbolLightAnnotationClass(
private val classOrObjectSymbol: KtNamedClassOrObjectSymbol,
manager: PsiManager
) : SymbolLightInterfaceOrAnnotationClass(classOrObjectSymbol, manager) {
classOrObject: KtClassOrObject,
ktModule: KtModule,
) : SymbolLightInterfaceOrAnnotationClass(classOrObject, ktModule) {
init {
require(classOrObjectSymbol.classKind == KtClassKind.ANNOTATION_CLASS)
require(isAnnotation)
}
override fun isAnnotationType(): Boolean = true
private val _ownMethods: List<KtLightMethod> by lazyPub {
val result = mutableListOf<KtLightMethod>()
val visibleDeclarations = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols()
.filterNot { it is KtFunctionSymbol && it.visibility.isPrivateOrPrivateToThis() }
.filterNot { it is KtConstructorSymbol }
withClassOrObjectSymbol { classOrObjectSymbol ->
val result = mutableListOf<KtLightMethod>()
val visibleDeclarations = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols()
.filterNot { it is KtFunctionSymbol && it.visibility.isPrivateOrPrivateToThis() }
.filterNot { it is KtConstructorSymbol }
createMethods(visibleDeclarations, result)
result
createMethods(visibleDeclarations, result)
result
}
}
override fun getOwnMethods(): List<PsiMethod> = _ownMethods
override fun getExtendsList(): PsiReferenceList? = null
override fun equals(other: Any?): Boolean =
other is SymbolLightAnnotationClass && classOrObjectSymbol == other.classOrObjectSymbol
override fun hashCode(): Int = classOrObjectSymbol.hashCode()
override fun isValid(): Boolean = super.isValid() && classOrObjectSymbol.isValid()
override fun copy(): SymbolLightClassForClassOrObject = SymbolLightAnnotationClass(classOrObjectSymbol, manager)
override fun copy(): SymbolLightClassForClassOrObject = SymbolLightAnnotationClass(classOrObject, ktModule)
}
@@ -6,15 +6,8 @@
package org.jetbrains.kotlin.light.classes.symbol.classes
import com.intellij.psi.*
import com.intellij.psi.impl.InheritanceImplUtil
import com.intellij.psi.impl.PsiClassImplUtil
import com.intellij.psi.search.SearchScope
import com.intellij.psi.stubs.IStubElementType
import com.intellij.psi.stubs.StubElement
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.lifetime.isValid
import org.jetbrains.kotlin.analysis.api.symbols.KtAnonymousObjectSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.asJava.classes.getParentForLocalDeclaration
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.KtLightField
@@ -22,17 +15,10 @@ import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmFieldAnnotation
import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightField
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.debugText.getDebugText
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
context(KtAnalysisSession)
internal class SymbolLightAnonymousClass(
private val anonymousObjectSymbol: KtAnonymousObjectSymbol,
manager: PsiManager
) : SymbolLightClassBase(manager),
StubBasedPsiElement<KotlinClassOrObjectStub<out KtClassOrObject>>, PsiAnonymousClass {
internal class SymbolLightAnonymousClass(classOrObject: KtClassOrObject, ktModule: KtModule) :
SymbolLightClassForClassOrObject(classOrObject, ktModule), PsiAnonymousClass {
private val _baseClassType: PsiClassType by lazyPub {
extendsListTypes.firstOrNull()
@@ -45,69 +31,58 @@ internal class SymbolLightAnonymousClass(
override fun getBaseClassType(): PsiClassType = _baseClassType
private val _extendsList by lazyPub { createInheritanceList(forExtendsList = true, anonymousObjectSymbol.superTypes) }
private val _implementsList by lazyPub { createInheritanceList(forExtendsList = false, anonymousObjectSymbol.superTypes) }
private val _extendsList by lazyPub {
withClassOrObjectSymbol {
createInheritanceList(forExtendsList = true, it.superTypes)
}
}
override fun getExtendsList(): PsiReferenceList? = _extendsList
override fun getImplementsList(): PsiReferenceList? = _implementsList
private val _implementsList by lazyPub {
withClassOrObjectSymbol {
createInheritanceList(forExtendsList = false, it.superTypes)
}
}
override fun getExtendsList(): PsiReferenceList = _extendsList
override fun getImplementsList(): PsiReferenceList = _implementsList
override fun getOwnFields(): List<KtLightField> = _ownFields
override fun getOwnMethods(): List<PsiMethod> = _ownMethods
private val _ownMethods: List<KtLightMethod> by lazyPub {
val result = mutableListOf<KtLightMethod>()
withClassOrObjectSymbol {
val result = mutableListOf<KtLightMethod>()
val declaredMemberScope = it.getDeclaredMemberScope()
val declaredMemberScope = anonymousObjectSymbol.getDeclaredMemberScope()
createMethods(declaredMemberScope.getCallableSymbols(), result)
createConstructors(declaredMemberScope.getConstructors(), result)
result
createMethods(declaredMemberScope.getCallableSymbols(), result)
createConstructors(declaredMemberScope.getConstructors(), result)
result
}
}
private val _ownFields: List<KtLightField> by lazyPub {
val result = mutableListOf<KtLightField>()
val nameGenerator = SymbolLightField.FieldNameGenerator()
anonymousObjectSymbol.getDeclaredMemberScope().getCallableSymbols()
.filterIsInstance<KtPropertySymbol>()
.forEach { propertySymbol ->
createField(
propertySymbol,
nameGenerator,
isTopLevel = false,
forceStatic = false,
takePropertyVisibility = propertySymbol.hasJvmFieldAnnotation(),
result
)
}
withClassOrObjectSymbol {
it.getDeclaredMemberScope().getCallableSymbols()
.filterIsInstance<KtPropertySymbol>()
.forEach { propertySymbol ->
createField(
propertySymbol,
nameGenerator,
isTopLevel = false,
forceStatic = false,
takePropertyVisibility = propertySymbol.hasJvmFieldAnnotation(),
result
)
}
result
result
}
}
private val _ownInnerClasses: List<SymbolLightClassBase> by lazyPub {
anonymousObjectSymbol.createInnerClasses(manager, this, kotlinOrigin)
}
override fun getOwnInnerClasses(): List<PsiClass> = _ownInnerClasses
override fun getParent(): PsiElement? =
kotlinOrigin?.let(::getParentForLocalDeclaration)
override fun getScope(): PsiElement? = parent
override fun getInterfaces(): Array<PsiClass> = PsiClassImplUtil.getInterfaces(this)
override fun getSuperClass(): PsiClass? = PsiClassImplUtil.getSuperClass(this)
override fun getSupers(): Array<PsiClass> = PsiClassImplUtil.getSupers(this)
override fun getSuperTypes(): Array<PsiClassType> = PsiClassImplUtil.getSuperTypes(this)
override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean =
baseClass?.let { InheritanceImplUtil.isInheritorDeep(this, it, classToByPass) } ?: false
override val kotlinOrigin: KtClassOrObject? = anonymousObjectSymbol.psi as? KtClassOrObject
override val originKind: LightClassOriginKind
get() = LightClassOriginKind.SOURCE
override fun getParent(): PsiElement? = kotlinOrigin.let(::getParentForLocalDeclaration)
override fun getArgumentList(): PsiExpressionList? = null
override fun isInQualifiedNew(): Boolean = false
override fun getName(): String? = null
@@ -115,30 +90,8 @@ internal class SymbolLightAnonymousClass(
override fun getModifierList(): PsiModifierList? = null
override fun hasModifierProperty(name: String): Boolean = name == PsiModifier.FINAL
override fun getContainingClass(): PsiClass? = null
override fun isDeprecated(): Boolean = false //TODO
override fun getTypeParameters(): Array<PsiTypeParameter> = PsiTypeParameter.EMPTY_ARRAY
override fun isInterface() = false
override fun isAnnotationType() = false
override fun getTypeParameterList(): PsiTypeParameterList? = null
override fun getQualifiedName(): String? = null
override fun isEnum() = false
override fun getUseScope(): SearchScope = kotlinOrigin?.useScope ?: TODO()
override fun getElementType(): IStubElementType<out StubElement<*>, *>? = kotlinOrigin?.elementType
override fun getStub(): KotlinClassOrObjectStub<out KtClassOrObject>? = kotlinOrigin?.stub
override fun isEquivalentTo(another: PsiElement?): Boolean = equals(another) //TODO
override fun equals(other: Any?): Boolean =
this === other ||
(other is SymbolLightAnonymousClass && anonymousObjectSymbol == other.anonymousObjectSymbol)
override fun hashCode(): Int = anonymousObjectSymbol.hashCode()
override fun copy() =
SymbolLightAnonymousClass(anonymousObjectSymbol, manager)
override fun isValid(): Boolean = super.isValid() && anonymousObjectSymbol.isValid()
override fun toString() =
"${this::class.java.simpleName}:${kotlinOrigin?.getDebugText()}"
override fun copy() = SymbolLightAnonymousClass(classOrObject, ktModule)
}
@@ -5,11 +5,13 @@
package org.jetbrains.kotlin.light.classes.symbol.classes
import com.intellij.psi.*
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiModifier
import com.intellij.psi.PsiModifierList
import com.intellij.psi.PsiReferenceList
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.lifetime.isValid
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
import org.jetbrains.kotlin.asJava.classes.METHOD_INDEX_BASE
import org.jetbrains.kotlin.asJava.classes.METHOD_INDEX_FOR_NON_ORIGIN_METHOD
@@ -20,17 +22,21 @@ import org.jetbrains.kotlin.builtins.StandardNames.ENUM_VALUES
import org.jetbrains.kotlin.builtins.StandardNames.ENUM_VALUE_OF
import org.jetbrains.kotlin.builtins.StandardNames.HASHCODE_NAME
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.light.classes.symbol.*
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.computeSimpleModality
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.methods.SymbolLightSimpleMethod
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList
import org.jetbrains.kotlin.light.classes.symbol.toPsiVisibilityForClass
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.DataClassResolver
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
@@ -39,36 +45,34 @@ import org.jetbrains.kotlin.util.OperatorNameConventions.TO_STRING
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
context(KtAnalysisSession)
internal open class SymbolLightClass(
private val classOrObjectSymbol: KtNamedClassOrObjectSymbol,
manager: PsiManager
) : SymbolLightClassForClassOrObject(classOrObjectSymbol, manager) {
internal open class SymbolLightClass(classOrObject: KtClassOrObject, ktModule: KtModule) :
SymbolLightClassForClassOrObject(classOrObject, ktModule) {
init {
require(classOrObjectSymbol.classKind != KtClassKind.INTERFACE && classOrObjectSymbol.classKind != KtClassKind.ANNOTATION_CLASS)
require(classOrObject !is KtClass || !classOrObject.isInterface() && !classOrObject.isAnnotation())
}
private val _modifierList: PsiModifierList? by lazyPub {
val lazyModifiers = lazy {
buildSet {
add(classOrObjectSymbol.toPsiVisibilityForClass(isNested = !isTopLevel))
addIfNotNull(classOrObjectSymbol.computeSimpleModality())
if (!isTopLevel && !classOrObjectSymbol.isInner) {
add(PsiModifier.STATIC)
withNamedClassOrObjectSymbol { classOrObjectSymbol ->
val lazyModifiers = lazy {
buildSet {
add(classOrObjectSymbol.toPsiVisibilityForClass(isNested = !isTopLevel))
addIfNotNull(classOrObjectSymbol.computeSimpleModality())
if (!isTopLevel && !classOrObjectSymbol.isInner) {
add(PsiModifier.STATIC)
}
}
}
}
val lazyAnnotations = lazyPub {
classOrObjectSymbol.computeAnnotations(
parent = this@SymbolLightClass,
nullability = NullabilityType.Unknown,
annotationUseSiteTarget = null,
)
}
val lazyAnnotations = lazyPub {
classOrObjectSymbol.computeAnnotations(
parent = this@SymbolLightClass,
nullability = NullabilityType.Unknown,
annotationUseSiteTarget = null,
)
}
SymbolLightClassModifierList(this@SymbolLightClass, lazyModifiers, lazyAnnotations)
SymbolLightClassModifierList(this@SymbolLightClass, lazyModifiers, lazyAnnotations)
}
}
override fun getModifierList(): PsiModifierList? = _modifierList
@@ -77,52 +81,63 @@ internal open class SymbolLightClass(
override fun getExtendsList(): PsiReferenceList? = _extendsList
override fun getImplementsList(): PsiReferenceList? = _implementsList
private val _extendsList by lazyPub { createInheritanceList(forExtendsList = true, classOrObjectSymbol.superTypes) }
private val _implementsList by lazyPub { createInheritanceList(forExtendsList = false, classOrObjectSymbol.superTypes) }
private val _ownMethods: List<KtLightMethod> by lazyPub {
val result = mutableListOf<KtLightMethod>()
val declaredMemberScope = classOrObjectSymbol.getDeclaredMemberScope()
val visibleDeclarations = declaredMemberScope.getCallableSymbols().applyIf(isEnum) {
filterNot { function ->
function is KtFunctionSymbol &&
(function.name == ENUM_VALUES || function.name == ENUM_VALUE_OF)
}
}.applyIf(classOrObjectSymbol.isObject) {
filterNot {
it is KtKotlinPropertySymbol && it.isConst
}
}.applyIf(classOrObjectSymbol.isData) {
// Technically, synthetic members of `data` class, such as `componentN` or `copy`, 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.origin == KtSymbolOrigin.SOURCE_MEMBER_GENERATED
}
private val _extendsList by lazyPub {
withClassOrObjectSymbol { classOrObjectSymbol ->
createInheritanceList(forExtendsList = true, classOrObjectSymbol.superTypes)
}
val suppressStatic = isCompanionObject
createMethods(visibleDeclarations, result, suppressStatic = suppressStatic)
createConstructors(declaredMemberScope.getConstructors(), result)
addMethodsFromCompanionIfNeeded(result)
addMethodsFromDataClass(result)
addDelegatesToInterfaceMethods(result)
result
}
private fun addMethodsFromDataClass(result: MutableList<KtLightMethod>) {
private val _implementsList by lazyPub {
withClassOrObjectSymbol { classOrObjectSymbol ->
createInheritanceList(forExtendsList = false, classOrObjectSymbol.superTypes)
}
}
private val _ownMethods: List<KtLightMethod> by lazyPub {
withNamedClassOrObjectSymbol { classOrObjectSymbol ->
val result = mutableListOf<KtLightMethod>()
val declaredMemberScope = classOrObjectSymbol.getDeclaredMemberScope()
val visibleDeclarations = declaredMemberScope.getCallableSymbols().applyIf(isEnum) {
filterNot { function ->
function is KtFunctionSymbol &&
(function.name == ENUM_VALUES || function.name == ENUM_VALUE_OF)
}
}.applyIf(isObject) {
filterNot {
it is KtKotlinPropertySymbol && it.isConst
}
}.applyIf(classOrObjectSymbol.isData) {
// Technically, synthetic members of `data` class, such as `componentN` or `copy`, 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.origin == KtSymbolOrigin.SOURCE_MEMBER_GENERATED
}
}
val suppressStatic = isCompanionObject
createMethods(visibleDeclarations, result, suppressStatic = suppressStatic)
createConstructors(declaredMemberScope.getConstructors(), result)
addMethodsFromCompanionIfNeeded(result)
addMethodsFromDataClass(result, classOrObjectSymbol)
addDelegatesToInterfaceMethods(result, classOrObjectSymbol)
result
}
}
context(KtAnalysisSession)
private fun addMethodsFromDataClass(result: MutableList<KtLightMethod>, classOrObjectSymbol: KtNamedClassOrObjectSymbol) {
if (!classOrObjectSymbol.isData) return
fun createMethodFromAny(ktFunctionSymbol: KtFunctionSymbol) {
// Similar to `copy`, synthetic members from `Any` should refer to `data` class as origin, not the function in `Any`.
val lightMemberOrigin = LightMemberOriginForDeclaration(this.kotlinOrigin!!, JvmDeclarationOriginKind.OTHER)
val lightMemberOrigin = LightMemberOriginForDeclaration(classOrObject, JvmDeclarationOriginKind.OTHER)
result.add(
SymbolLightSimpleMethod(
ktFunctionSymbol, lightMemberOrigin, this, METHOD_INDEX_BASE, false,
@@ -169,9 +184,10 @@ internal open class SymbolLightClass(
private val Name.isFromAny: Boolean
get() = this == EQUALS || this == HASHCODE_NAME || this == TO_STRING
private fun addDelegatesToInterfaceMethods(result: MutableList<KtLightMethod>) {
context(KtAnalysisSession)
private fun addDelegatesToInterfaceMethods(result: MutableList<KtLightMethod>, classOrObjectSymbol: KtNamedClassOrObjectSymbol) {
fun createDelegateMethod(ktFunctionSymbol: KtFunctionSymbol) {
val kotlinOrigin = ktFunctionSymbol.psi as? KtDeclaration ?: kotlinOrigin!!
val kotlinOrigin = ktFunctionSymbol.psi as? KtDeclaration ?: classOrObject
val lightMemberOrigin = LightMemberOriginForDeclaration(kotlinOrigin, JvmDeclarationOriginKind.DELEGATION)
result.add(
SymbolLightSimpleMethod(
@@ -194,26 +210,28 @@ internal open class SymbolLightClass(
}
private val _ownFields: List<KtLightField> by lazyPub {
withNamedClassOrObjectSymbol { classOrObjectSymbol ->
val result = mutableListOf<KtLightField>()
val result = mutableListOf<KtLightField>()
// First, add static fields: companion object and fields from companion object
addCompanionObjectFieldIfNeeded(result)
addFieldsFromCompanionIfNeeded(result)
// First, add static fields: companion object and fields from companion object
addCompanionObjectFieldIfNeeded(result)
addFieldsFromCompanionIfNeeded(result)
// Then, add instance fields: properties from parameters, and then member properties
addPropertyBackingFields(result, classOrObjectSymbol)
// Then, add instance fields: properties from parameters, and then member properties
addPropertyBackingFields(result)
// Next, add INSTANCE field if non-local named object
addInstanceFieldIfNeeded(result, classOrObjectSymbol)
// Next, add INSTANCE field if non-local named object
addInstanceFieldIfNeeded(result)
// Last, add fields for enum entries
addFieldsForEnumEntries(result, classOrObjectSymbol)
// Last, add fields for enum entries
addFieldsForEnumEntries(result)
result
result
}
}
protected fun addPropertyBackingFields(result: MutableList<KtLightField>) {
context(KtAnalysisSession)
protected fun addPropertyBackingFields(result: MutableList<KtLightField>, classOrObjectSymbol: KtNamedClassOrObjectSymbol) {
val propertySymbols = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols()
.filterIsInstance<KtPropertySymbol>()
.applyIf(isCompanionObject) {
@@ -231,7 +249,7 @@ internal open class SymbolLightClass(
val isLateInit = (propertySymbol as? KtKotlinPropertySymbol)?.isLateInit == true
val isConst = (propertySymbol as? KtKotlinPropertySymbol)?.isConst == true
val forceStatic = classOrObjectSymbol.isObject || isCompanionObject
val forceStatic = isObject
val takePropertyVisibility = isLateInit || isJvmField || isConst
createField(
@@ -250,8 +268,9 @@ internal open class SymbolLightClass(
propertyGroups[false]?.forEach(::addPropertyBackingField)
}
private fun addInstanceFieldIfNeeded(result: MutableList<KtLightField>) {
if (classOrObjectSymbol.isNamedObject && !classOrObjectSymbol.isLocal) {
context(KtAnalysisSession)
private fun addInstanceFieldIfNeeded(result: MutableList<KtLightField>, classOrObjectSymbol: KtNamedClassOrObjectSymbol) {
if (isNamedObject && !isLocal) {
result.add(
SymbolLightFieldForObject(
objectSymbol = classOrObjectSymbol,
@@ -263,7 +282,8 @@ internal open class SymbolLightClass(
}
}
private fun addFieldsForEnumEntries(result: MutableList<KtLightField>) {
context(KtAnalysisSession)
private fun addFieldsForEnumEntries(result: MutableList<KtLightField>, classOrObjectSymbol: KtNamedClassOrObjectSymbol) {
if (isEnum) {
classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols()
.filterIsInstance<KtEnumEntrySymbol>()
@@ -271,29 +291,9 @@ internal open class SymbolLightClass(
}
}
private val KtClassOrObjectSymbol.isObject: Boolean
get() = classKind == KtClassKind.OBJECT
private val KtClassOrObjectSymbol.isNamedObject: Boolean
get() = isObject && !isCompanionObject
private val KtClassOrObjectSymbol.isLocal: Boolean
get() = symbolKind == KtSymbolKind.LOCAL
override fun hashCode(): Int = classOrObjectSymbol.hashCode()
override fun equals(other: Any?): Boolean =
this === other || (other is SymbolLightClass && classOrObjectSymbol == other.classOrObjectSymbol)
override fun isInterface(): Boolean = false
override fun isAnnotationType(): Boolean = false
override fun isEnum(): Boolean =
classOrObjectSymbol.classKind == KtClassKind.ENUM_CLASS
override fun copy(): SymbolLightClass =
SymbolLightClass(classOrObjectSymbol, manager)
override fun isValid(): Boolean = super.isValid() && classOrObjectSymbol.isValid()
override fun copy(): SymbolLightClass = SymbolLightClass(classOrObject, ktModule)
}
@@ -18,7 +18,7 @@ import com.intellij.psi.scope.PsiScopeProcessor
import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.PsiUtil
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.analysis.providers.createProjectWideOutOfBlockModificationTracker
import org.jetbrains.kotlin.asJava.classes.*
import org.jetbrains.kotlin.asJava.toLightClass
@@ -28,19 +28,16 @@ import org.jetbrains.kotlin.light.classes.symbol.allowLightClassesOnEdt
import org.jetbrains.kotlin.utils.addToStdlib.ifFalse
import javax.swing.Icon
context(KtAnalysisSession)
abstract class SymbolLightClassBase protected constructor(
manager: PsiManager
) : LightElement(manager, KotlinLanguage.INSTANCE), PsiClass, KtExtensibleLightClass {
abstract class SymbolLightClassBase protected constructor(val ktModule: KtModule, manager: PsiManager) :
LightElement(manager, KotlinLanguage.INSTANCE), PsiClass, KtExtensibleLightClass {
private class SymbolLightClassesLazyCreator(private val project: Project) : KotlinClassInnerStuffCache.LazyCreator() {
override fun <T : Any> get(initializer: () -> T, dependencies: List<Any>): Lazy<T> = object : Lazy<T> {
private val cachedValue = PsiCachedValueImpl(PsiManager.getInstance(project)) {
CachedValueProvider.Result.create(allowLightClassesOnEdt(initializer), dependencies)
}
override val value: T
get() = cachedValue.value
?: error("Unexpected null value from PsiCachedValueImpl")
override val value: T get() = cachedValue.value ?: error("Unexpected null value from PsiCachedValueImpl")
override fun isInitialized(): Boolean {
// Lazy is a bad interface here as it has unneeded and unused in LC `isInitialized` method
@@ -50,6 +47,7 @@ abstract class SymbolLightClassBase protected constructor(
}
}
@Suppress("LeakingThis")
private val myInnersCache = KotlinClassInnerStuffCache(
myClass = this@SymbolLightClassBase,
dependencies = listOf(manager.project.createProjectWideOutOfBlockModificationTracker()),
@@ -102,7 +100,9 @@ abstract class SymbolLightClassBase protected constructor(
val baseClassOrigin = (baseClass as? KtLightClass)?.kotlinOrigin
return if (baseClassOrigin != null && thisClassOrigin != null) {
thisClassOrigin.checkIsInheritor(baseClassOrigin, checkDeep)
analyzeForLightClasses(ktModule) {
thisClassOrigin.checkIsInheritor(baseClassOrigin, checkDeep)
}
} else {
hasSuper(baseClass, checkDeep) ||
InheritanceImplUtil.isInheritor(this, baseClass, checkDeep)
@@ -122,7 +122,7 @@ abstract class SymbolLightClassBase protected constructor(
private fun PsiClass.hasSuper(
baseClass: PsiClass,
checkDeep: Boolean,
visitedSupers: MutableSet<PsiClass> = mutableSetOf<PsiClass>()
visitedSupers: MutableSet<PsiClass> = mutableSetOf()
): Boolean {
visitedSupers.add(this)
val notVisitedSupers = supers.filterNot { visitedSupers.contains(it) }
@@ -135,8 +135,7 @@ abstract class SymbolLightClassBase protected constructor(
override fun getLanguage(): KotlinLanguage = KotlinLanguage.INSTANCE
override fun getPresentation(): ItemPresentation? =
ItemPresentationProviders.getItemPresentation(this)
override fun getPresentation(): ItemPresentation? = ItemPresentationProviders.getItemPresentation(this)
abstract override fun equals(other: Any?): Boolean
@@ -144,18 +143,15 @@ abstract class SymbolLightClassBase protected constructor(
override fun getContext(): PsiElement = parent
override fun isEquivalentTo(another: PsiElement?): Boolean =
PsiClassImplUtil.isClassEquivalentTo(this, another)
override fun isEquivalentTo(another: PsiElement?): Boolean = PsiClassImplUtil.isClassEquivalentTo(this, another)
override fun getDocComment(): PsiDocComment? = null
override fun hasTypeParameters(): Boolean = PsiImplUtil.hasTypeParameters(this)
override fun getExtendsListTypes(): Array<PsiClassType?> =
PsiClassImplUtil.getExtendsListTypes(this)
override fun getExtendsListTypes(): Array<PsiClassType?> = PsiClassImplUtil.getExtendsListTypes(this)
override fun getImplementsListTypes(): Array<PsiClassType?> =
PsiClassImplUtil.getImplementsListTypes(this)
override fun getImplementsListTypes(): Array<PsiClassType?> = PsiClassImplUtil.getImplementsListTypes(this)
override fun findMethodBySignature(patternMethod: PsiMethod?, checkBases: Boolean): PsiMethod? =
patternMethod?.let { PsiClassImplUtil.findMethodBySignature(this, it, checkBases) }
@@ -14,15 +14,13 @@ import com.intellij.psi.stubs.StubElement
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithKind
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.asJava.classes.getParentForLocalDeclaration
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.light.classes.symbol.SymbolLightIdentifier
import org.jetbrains.kotlin.light.classes.symbol.allowLightClassesOnEdt
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasDeprecatedAnnotation
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmFieldAnnotation
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmStaticAnnotation
@@ -31,28 +29,43 @@ import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForObjec
import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForProperty
import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightTypeParameterList
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtClassBody
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtObjectDeclaration
import org.jetbrains.kotlin.psi.debugText.getDebugText
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
import org.jetbrains.kotlin.utils.addToStdlib.ifTrue
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
context(KtAnalysisSession)
abstract class SymbolLightClassForClassOrObject(
private val classOrObjectSymbol: KtNamedClassOrObjectSymbol,
manager: PsiManager
) : SymbolLightClassBase(manager),
abstract class SymbolLightClassForClassOrObject(protected val classOrObject: KtClassOrObject, ktModule: KtModule) :
SymbolLightClassBase(ktModule, classOrObject.manager),
StubBasedPsiElement<KotlinClassOrObjectStub<out KtClassOrObject>> {
protected fun <T> withClassOrObjectSymbol(action: KtAnalysisSession.(KtClassOrObjectSymbol) -> T): T =
analyzeForLightClasses(ktModule) {
action(classOrObject.getClassOrObjectSymbol()!!)
}
override val isTopLevel: Boolean = classOrObjectSymbol.symbolKind == KtSymbolKind.TOP_LEVEL
protected fun <T> withNamedClassOrObjectSymbol(action: KtAnalysisSession.(KtNamedClassOrObjectSymbol) -> T): T =
analyzeForLightClasses(ktModule) {
val namedClassOrObjectSymbol = classOrObject.getNamedClassOrObjectSymbol()
require(namedClassOrObjectSymbol != null)
internal val isCompanionObject: Boolean
get() = classOrObjectSymbol.classKind == KtClassKind.COMPANION_OBJECT
action(namedClassOrObjectSymbol)
}
override val isTopLevel: Boolean get() = classOrObject.isTopLevel()
internal val isCompanionObject: Boolean get() = classOrObject is KtObjectDeclaration && classOrObject.isCompanion()
internal val isLocal: Boolean get() = classOrObject.isLocal
internal val isNamedObject: Boolean get() = classOrObject is KtObjectDeclaration && !classOrObject.isCompanion()
internal val isObject: Boolean get() = classOrObject is KtObjectDeclaration
internal val isInterface: Boolean get() = classOrObject is KtClass && classOrObject.isInterface()
internal val isAnnotation: Boolean get() = classOrObject is KtClass && classOrObject.isAnnotation()
internal val isEnum: Boolean get() = classOrObject is KtClass && classOrObject.isEnum()
private val _isDeprecated: Boolean by lazyPub {
classOrObjectSymbol.hasDeprecatedAnnotation()
withClassOrObjectSymbol { it.hasDeprecatedAnnotation() }
}
override fun isDeprecated(): Boolean = _isDeprecated
@@ -62,7 +75,9 @@ abstract class SymbolLightClassForClassOrObject(
abstract override fun getOwnMethods(): List<PsiMethod>
private val _identifier: PsiIdentifier by lazyPub {
SymbolLightIdentifier(this, classOrObjectSymbol)
withClassOrObjectSymbol {
SymbolLightIdentifier(this@SymbolLightClassForClassOrObject, it)
}
}
override fun getNameIdentifier(): PsiIdentifier? = _identifier
@@ -72,40 +87,44 @@ abstract class SymbolLightClassForClassOrObject(
private val _typeParameterList: PsiTypeParameterList? by lazyPub {
hasTypeParameters().ifTrue {
SymbolLightTypeParameterList(
owner = this,
symbolWithTypeParameterList = classOrObjectSymbol,
)
withClassOrObjectSymbol {
SymbolLightTypeParameterList(
owner = this@SymbolLightClassForClassOrObject,
symbolWithTypeParameterList = it,
)
}
}
}
override fun hasTypeParameters(): Boolean =
classOrObjectSymbol.typeParameters.isNotEmpty()
override fun hasTypeParameters(): Boolean = classOrObject.typeParameters.isNotEmpty()
override fun getTypeParameterList(): PsiTypeParameterList? = _typeParameterList
override fun getTypeParameters(): Array<PsiTypeParameter> =
_typeParameterList?.typeParameters ?: PsiTypeParameter.EMPTY_ARRAY
override fun getTypeParameters(): Array<PsiTypeParameter> = _typeParameterList?.typeParameters ?: PsiTypeParameter.EMPTY_ARRAY
private val _ownInnerClasses: List<SymbolLightClassBase> by lazyPub {
classOrObjectSymbol.createInnerClasses(manager, this, kotlinOrigin)
withClassOrObjectSymbol {
it.createInnerClasses(this@SymbolLightClassForClassOrObject, classOrObject)
}
}
override fun getOwnInnerClasses(): List<PsiClass> = _ownInnerClasses
override fun getTextOffset(): Int = kotlinOrigin?.textOffset ?: 0
override fun getStartOffsetInParent(): Int = kotlinOrigin?.startOffsetInParent ?: 0
override fun getTextOffset(): Int = classOrObject.textOffset
override fun getStartOffsetInParent(): Int = classOrObject.startOffsetInParent
override fun isWritable() = false
override val kotlinOrigin: KtClassOrObject? = classOrObjectSymbol.psi as? KtClassOrObject
override val kotlinOrigin: KtClassOrObject = classOrObject
protected fun addMethodsFromCompanionIfNeeded(result: MutableList<KtLightMethod>) {
protected fun addMethodsFromCompanionIfNeeded(
result: MutableList<KtLightMethod>,
): Unit = withNamedClassOrObjectSymbol { classOrObjectSymbol ->
classOrObjectSymbol.companionObject?.run {
val methods = getDeclaredMemberScope().getCallableSymbols()
.filterIsInstance<KtFunctionSymbol>()
.filter { it.hasJvmStaticAnnotation() }
createMethods(methods, result)
val properties = getDeclaredMemberScope().getCallableSymbols()
.filterIsInstance<KtPropertySymbol>()
val properties = getDeclaredMemberScope().getCallableSymbols().filterIsInstance<KtPropertySymbol>()
properties.forEach { property ->
createPropertyAccessors(
result,
@@ -117,7 +136,9 @@ abstract class SymbolLightClassForClassOrObject(
}
}
protected fun addCompanionObjectFieldIfNeeded(result: MutableList<KtLightField>) {
protected fun addCompanionObjectFieldIfNeeded(
result: MutableList<KtLightField>,
): Unit = withNamedClassOrObjectSymbol { classOrObjectSymbol ->
classOrObjectSymbol.companionObject?.run {
result.add(
SymbolLightFieldForObject(
@@ -130,25 +151,28 @@ abstract class SymbolLightClassForClassOrObject(
}
}
protected fun addFieldsFromCompanionIfNeeded(result: MutableList<KtLightField>) {
classOrObjectSymbol.companionObject?.run {
getDeclaredMemberScope().getCallableSymbols()
.filterIsInstance<KtPropertySymbol>()
.applyIf(isInterface) {
filter { it.isConstOrJvmField }
}
.mapTo(result) {
SymbolLightFieldForProperty(
propertySymbol = it,
fieldName = it.name.asString(),
containingClass = this@SymbolLightClassForClassOrObject,
lightMemberOrigin = null,
isTopLevel = false,
forceStatic = true,
takePropertyVisibility = it.isConstOrJvmField
)
}
}
protected fun addFieldsFromCompanionIfNeeded(
result: MutableList<KtLightField>,
): Unit = withNamedClassOrObjectSymbol { classOrObjectSymbol ->
classOrObjectSymbol.companionObject
?.getDeclaredMemberScope()
?.getCallableSymbols()
?.filterIsInstance<KtPropertySymbol>()
?.applyIf(isInterface) {
filter { it.isConstOrJvmField }
}
?.mapTo(result) {
SymbolLightFieldForProperty(
propertySymbol = it,
fieldName = it.name.asString(),
containingClass = this@SymbolLightClassForClassOrObject,
lightMemberOrigin = null,
isTopLevel = false,
forceStatic = true,
takePropertyVisibility = it.isConstOrJvmField,
)
}
}
private val KtPropertySymbol.isConstOrJvmField: Boolean
@@ -157,39 +181,39 @@ abstract class SymbolLightClassForClassOrObject(
private val KtPropertySymbol.isConst: Boolean
get() = (this as? KtKotlinPropertySymbol)?.isConst == true
override fun getNavigationElement(): PsiElement = kotlinOrigin ?: this
override fun getNavigationElement(): PsiElement = classOrObject
override fun isEquivalentTo(another: PsiElement?): Boolean =
basicIsEquivalentTo(this, another) ||
another is PsiClass && qualifiedName != null && another.qualifiedName == qualifiedName
abstract override fun equals(other: Any?): Boolean
override fun equals(other: Any?): Boolean {
if (this === other) return true
abstract override fun hashCode(): Int
return other?.safeAs<SymbolLightClassForClassOrObject>()?.classOrObject == classOrObject
}
override fun getName(): String? = allowLightClassesOnEdt { classOrObjectSymbol.name.asString() }
override fun hashCode(): Int = classOrObject.hashCode()
override fun getName(): String? = classOrObject.name
override fun hasModifierProperty(@NonNls name: String): Boolean = modifierList?.hasModifierProperty(name) ?: false
abstract override fun isInterface(): Boolean
override fun isInterface(): Boolean = isInterface
override fun isAnnotationType(): Boolean = isAnnotation
override fun isEnum(): Boolean = isEnum
abstract override fun isAnnotationType(): Boolean
override fun isValid(): Boolean = classOrObject.isValid
abstract override fun isEnum(): Boolean
override fun toString() = "${this::class.java.simpleName}:${classOrObject.getDebugText()}"
override fun isValid(): Boolean = kotlinOrigin?.isValid ?: true
override fun getUseScope(): SearchScope = classOrObject.useScope
override fun getElementType(): IStubElementType<out StubElement<*>, *>? = classOrObject.elementType
override fun getStub(): KotlinClassOrObjectStub<out KtClassOrObject>? = classOrObject.stub
override fun toString() =
"${this::class.java.simpleName}:${kotlinOrigin?.getDebugText()}"
override val originKind: LightClassOriginKind get() = LightClassOriginKind.SOURCE
override fun getUseScope(): SearchScope = kotlinOrigin?.useScope ?: TODO()
override fun getElementType(): IStubElementType<out StubElement<*>, *>? = kotlinOrigin?.elementType
override fun getStub(): KotlinClassOrObjectStub<out KtClassOrObject>? = kotlinOrigin?.stub
override val originKind: LightClassOriginKind
get() = LightClassOriginKind.SOURCE
override fun getQualifiedName() = kotlinOrigin?.fqName?.asString()
override fun getQualifiedName() = classOrObject.fqName?.asString()
override fun getInterfaces(): Array<PsiClass> = PsiClassImplUtil.getInterfaces(this)
override fun getSuperClass(): PsiClass? = PsiClassImplUtil.getSuperClass(this)
@@ -197,16 +221,17 @@ abstract class SymbolLightClassForClassOrObject(
override fun getSuperTypes(): Array<PsiClassType> = PsiClassImplUtil.getSuperTypes(this)
override fun getContainingClass(): PsiClass? {
val containingBody = kotlinOrigin?.parent as? KtClassBody
val containingBody = classOrObject.parent as? KtClassBody
val containingClass = containingBody?.parent as? KtClassOrObject
containingClass?.let { return it.toLightClass() }
return null
}
override fun getParent(): PsiElement? {
if (classOrObjectSymbol.safeAs<KtSymbolWithKind>()?.symbolKind == KtSymbolKind.LOCAL) {
return kotlinOrigin?.let(::getParentForLocalDeclaration)
if (isLocal) {
return classOrObject.let(::getParentForLocalDeclaration)
}
return containingClass ?: containingFile
}
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.lifetime.isValid
import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol
import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
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.KtLightMethod
@@ -25,10 +26,10 @@ internal class SymbolLightClassForEnumEntry(
private val enumEntrySymbol: KtEnumEntrySymbol,
private val enumConstant: SymbolLightFieldForEnumEntry,
private val enumClass: SymbolLightClass,
manager: PsiManager
) : SymbolLightClassBase(manager), PsiEnumConstantInitializer {
ktModule: KtModule,
) : SymbolLightClassBase(ktModule, enumConstant.manager), PsiEnumConstantInitializer {
override fun getName(): String? = enumEntrySymbol.name.asString()
override fun getName(): String = enumEntrySymbol.name.asString()
override fun getBaseClassType(): PsiClassType = enumConstant.type as PsiClassType //???TODO
@@ -48,8 +49,7 @@ internal class SymbolLightClassForEnumEntry(
override fun hashCode(): Int =
enumEntrySymbol.hashCode()
override fun copy(): PsiElement =
SymbolLightClassForEnumEntry(enumEntrySymbol, enumConstant, enumClass, manager)
override fun copy(): PsiElement = SymbolLightClassForEnumEntry(enumEntrySymbol, enumConstant, enumClass, ktModule)
override fun toString(): String = "SymbolLightClassForEnumEntry:$name"
@@ -63,12 +63,12 @@ internal class SymbolLightClassForEnumEntry(
)
}
override fun getModifierList(): PsiModifierList? = _modifierList
override fun getModifierList(): PsiModifierList = _modifierList
override fun hasModifierProperty(name: String): Boolean =
name == PsiModifier.PUBLIC || name == PsiModifier.STATIC || name == PsiModifier.FINAL
override fun getContainingClass(): PsiClass? = enumClass
override fun getContainingClass(): PsiClass = enumClass
override fun isDeprecated(): Boolean = false
@@ -76,7 +76,7 @@ internal class SymbolLightClassForEnumEntry(
override fun getTypeParameterList(): PsiTypeParameterList? = null
override fun getQualifiedName(): String? = "${enumConstant.containingClass.qualifiedName}.${enumConstant.name}"
override fun getQualifiedName(): String = "${enumConstant.containingClass.qualifiedName}.${enumConstant.name}"
override fun isInterface(): Boolean = false
@@ -89,9 +89,8 @@ internal class SymbolLightClassForEnumEntry(
enumEntrySymbol.returnType.asPsiType(this@SymbolLightClassForEnumEntry, KtTypeMappingMode.SUPER_TYPE) as? PsiClassType
?: return@lazyPub null
KotlinSuperTypeListBuilder(
kotlinOrigin = enumClass.kotlinOrigin?.getSuperTypeList(),
kotlinOrigin = enumClass.kotlinOrigin.getSuperTypeList(),
manager = manager,
language = language,
role = PsiReferenceList.Role.EXTENDS_LIST
@@ -104,7 +103,7 @@ internal class SymbolLightClassForEnumEntry(
override fun getImplementsList(): PsiReferenceList? = null
override fun getSuperClass(): PsiClass? = enumClass
override fun getSuperClass(): PsiClass = enumClass
override fun getInterfaces(): Array<PsiClass> = PsiClass.EMPTY_ARRAY
@@ -112,7 +111,7 @@ internal class SymbolLightClassForEnumEntry(
override fun getSuperTypes(): Array<PsiClassType> = PsiClassImplUtil.getSuperTypes(this)
override fun getParent(): PsiElement? = containingClass ?: containingFile
override fun getParent(): PsiElement? = containingClass
override fun getScope(): PsiElement? = parent
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtKotlinPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtAnnotatedSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
@@ -41,8 +42,9 @@ import org.jetbrains.kotlin.psi.KtFile
context(KtAnalysisSession)
class SymbolLightClassForFacade(
override val facadeClassFqName: FqName,
override val files: Collection<KtFile>
) : SymbolLightClassBase(files.first().manager), KtLightClassForFacade {
override val files: Collection<KtFile>,
ktModule: KtModule,
) : SymbolLightClassBase(ktModule, files.first().manager), KtLightClassForFacade {
init {
require(files.isNotEmpty())
@@ -159,7 +161,7 @@ class SymbolLightClassForFacade(
override fun getOwnMethods() = _ownMethods
override fun copy(): SymbolLightClassForFacade = SymbolLightClassForFacade(facadeClassFqName, files)
override fun copy(): SymbolLightClassForFacade = SymbolLightClassForFacade(facadeClassFqName, files, ktModule)
private val packageFqName: FqName = facadeClassFqName.parent()
@@ -7,25 +7,18 @@ package org.jetbrains.kotlin.light.classes.symbol.classes
import com.intellij.psi.*
import com.intellij.util.IncorrectOperationException
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList
import org.jetbrains.kotlin.load.java.JvmAbi
context(KtAnalysisSession)
internal class SymbolLightClassForInterfaceDefaultImpls(
private val classOrObjectSymbol: KtNamedClassOrObjectSymbol,
private val containingClass: SymbolLightClassBase,
manager: PsiManager
) : SymbolLightInterfaceClass(classOrObjectSymbol, manager) {
internal class SymbolLightClassForInterfaceDefaultImpls(private val containingClass: SymbolLightInterfaceClass) :
SymbolLightInterfaceClass(containingClass.kotlinOrigin, containingClass.ktModule) {
override fun getQualifiedName(): String? = containingClass.qualifiedName?.let { it + ".${JvmAbi.DEFAULT_IMPLS_CLASS_NAME}" }
override fun getName() = JvmAbi.DEFAULT_IMPLS_CLASS_NAME
override fun getParent() = containingClass
override fun copy() =
SymbolLightClassForInterfaceDefaultImpls(classOrObjectSymbol, containingClass, manager)
override fun copy() = SymbolLightClassForInterfaceDefaultImpls(containingClass)
override fun getTypeParameterList(): PsiTypeParameterList? = null
override fun getTypeParameters(): Array<PsiTypeParameter> = emptyArray()
@@ -44,6 +37,7 @@ internal class SymbolLightClassForInterfaceDefaultImpls(
override fun isEnum(): Boolean = false
override fun hasTypeParameters(): Boolean = false
override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean = false
override fun getExtendsList(): PsiReferenceList? = null
@Throws(IncorrectOperationException::class)
override fun setName(name: String): PsiElement {
@@ -5,61 +5,64 @@
package org.jetbrains.kotlin.light.classes.symbol.classes
import com.intellij.psi.PsiManager
import com.intellij.psi.PsiMethod
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
context(KtAnalysisSession)
internal class SymbolLightInlineClass(
private val classOrObjectSymbol: KtNamedClassOrObjectSymbol,
manager: PsiManager
) : SymbolLightClass(classOrObjectSymbol, manager) {
internal class SymbolLightInlineClass(classOrObject: KtClassOrObject, ktModule: KtModule) : SymbolLightClass(classOrObject, ktModule) {
init {
require(classOrObjectSymbol.isInline)
require(classOrObject.hasModifier(KtTokens.INLINE_KEYWORD))
}
private val _ownMethods: List<KtLightMethod> by lazyPub {
val result = mutableListOf<KtLightMethod>()
withClassOrObjectSymbol { classOrObjectSymbol ->
val result = mutableListOf<KtLightMethod>()
val declaredMemberScope = classOrObjectSymbol.getDeclaredMemberScope()
val applicableDeclarations = declaredMemberScope.getCallableSymbols()
.filter {
(it as? KtPropertySymbol)?.isOverride == true || (it as? KtFunctionSymbol)?.isOverride == true
}
.filterNot {
it.deprecationStatus?.deprecationLevel == DeprecationLevelValue.HIDDEN
val declaredMemberScope = classOrObjectSymbol.getDeclaredMemberScope()
val applicableDeclarations = declaredMemberScope.getCallableSymbols()
.filter {
(it as? KtPropertySymbol)?.isOverride == true || (it as? KtFunctionSymbol)?.isOverride == true
}
.filterNot {
it.deprecationStatus?.deprecationLevel == DeprecationLevelValue.HIDDEN
}
createMethods(applicableDeclarations, result, suppressStatic = false)
val inlineClassParameterSymbol = declaredMemberScope.getConstructors()
.singleOrNull { it.isPrimary }
?.valueParameters
?.singleOrNull()
if (inlineClassParameterSymbol != null) {
val propertySymbol = declaredMemberScope.getCallableSymbols { it == inlineClassParameterSymbol.name }
.singleOrNull { it is KtPropertySymbol && it.isFromPrimaryConstructor } as? KtPropertySymbol
if (propertySymbol != null) {
// (inline or) value class primary constructor must have only final read-only (val) property parameter
// Even though the property parameter is mutable (for some reasons, e.g., testing or not checked yet),
// we can enforce immutability here.
createPropertyAccessors(result, propertySymbol, isTopLevel = false, isMutable = false)
}
}
createMethods(applicableDeclarations, result, suppressStatic = false)
val inlineClassParameterSymbol =
declaredMemberScope.getConstructors().singleOrNull { it.isPrimary }?.valueParameters?.singleOrNull()
if (inlineClassParameterSymbol != null) {
val propertySymbol = declaredMemberScope.getCallableSymbols { it == inlineClassParameterSymbol.name }
.singleOrNull { it is KtPropertySymbol && it.isFromPrimaryConstructor } as? KtPropertySymbol
if (propertySymbol != null) {
// (inline or) value class primary constructor must have only final read-only (val) property parameter
// Even though the property parameter is mutable (for some reasons, e.g., testing or not checked yet),
// we can enforce immutability here.
createPropertyAccessors(result, propertySymbol, isTopLevel = false, isMutable = false)
}
result
}
result
}
private val _ownFields: List<KtLightField> by lazyPub {
mutableListOf<KtLightField>().apply {
addPropertyBackingFields(this)
withNamedClassOrObjectSymbol { classOrObjectSymbol ->
mutableListOf<KtLightField>().apply {
addPropertyBackingFields(this, classOrObjectSymbol)
}
}
}
@@ -67,5 +70,5 @@ internal class SymbolLightInlineClass(
override fun getOwnFields(): List<KtLightField> = _ownFields
override fun copy(): SymbolLightInlineClass = SymbolLightInlineClass(classOrObjectSymbol, manager)
override fun copy(): SymbolLightInlineClass = SymbolLightInlineClass(classOrObject, ktModule)
}
@@ -5,56 +5,46 @@
package org.jetbrains.kotlin.light.classes.symbol.classes
import com.intellij.psi.PsiManager
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiReferenceList
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.lifetime.isValid
import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.isPrivateOrPrivateToThis
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.psi.KtClassOrObject
context(KtAnalysisSession)
internal open class SymbolLightInterfaceClass(
private val classOrObjectSymbol: KtNamedClassOrObjectSymbol,
manager: PsiManager
) : SymbolLightInterfaceOrAnnotationClass(classOrObjectSymbol, manager) {
classOrObject: KtClassOrObject,
ktModule: KtModule,
) : SymbolLightInterfaceOrAnnotationClass(classOrObject, ktModule) {
init {
require(classOrObjectSymbol.classKind == KtClassKind.INTERFACE)
require(isInterface)
}
private val _ownMethods: List<KtLightMethod> by lazyPub {
val result = mutableListOf<KtLightMethod>()
withClassOrObjectSymbol { classOrObjectSymbol ->
val result = mutableListOf<KtLightMethod>()
val visibleDeclarations = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols()
.filterNot { it is KtFunctionSymbol && it.visibility.isPrivateOrPrivateToThis() }
val visibleDeclarations = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols()
.filterNot { it is KtFunctionSymbol && it.visibility.isPrivateOrPrivateToThis() }
createMethods(visibleDeclarations, result)
addMethodsFromCompanionIfNeeded(result)
createMethods(visibleDeclarations, result)
addMethodsFromCompanionIfNeeded(result)
result
result
}
}
override fun getOwnMethods(): List<PsiMethod> = _ownMethods
override fun equals(other: Any?): Boolean =
other === this || (other is SymbolLightInterfaceClass && classOrObjectSymbol == other.classOrObjectSymbol)
override fun hashCode(): Int = classOrObjectSymbol.hashCode()
override fun isAnnotationType(): Boolean = false
override fun copy(): SymbolLightClassForClassOrObject = SymbolLightInterfaceClass(classOrObjectSymbol, manager)
override fun copy(): SymbolLightClassForClassOrObject = SymbolLightInterfaceClass(classOrObject, ktModule)
private val _extendsList: PsiReferenceList by lazyPub {
createInheritanceList(forExtendsList = true, classOrObjectSymbol.superTypes)
withClassOrObjectSymbol { classOrObjectSymbol ->
createInheritanceList(forExtendsList = true, classOrObjectSymbol.superTypes)
}
}
override fun getExtendsList(): PsiReferenceList? = _extendsList
override fun isValid(): Boolean = super.isValid() && classOrObjectSymbol.isValid()
}
@@ -5,57 +5,52 @@
package org.jetbrains.kotlin.light.classes.symbol.classes
import com.intellij.psi.PsiManager
import com.intellij.psi.PsiModifier
import com.intellij.psi.PsiModifierList
import com.intellij.psi.PsiReferenceList
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.lifetime.isValid
import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.light.classes.symbol.NullabilityType
import org.jetbrains.kotlin.light.classes.symbol.annotations.computeAnnotations
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList
import org.jetbrains.kotlin.light.classes.symbol.toPsiVisibilityForClass
import org.jetbrains.kotlin.psi.KtClassOrObject
context(KtAnalysisSession)
internal abstract class SymbolLightInterfaceOrAnnotationClass(
private val classOrObjectSymbol: KtNamedClassOrObjectSymbol,
manager: PsiManager
) : SymbolLightClassForClassOrObject(classOrObjectSymbol, manager) {
internal abstract class SymbolLightInterfaceOrAnnotationClass(classOrObject: KtClassOrObject, ktModule: KtModule) :
SymbolLightClassForClassOrObject(classOrObject, ktModule) {
init {
require(
classOrObjectSymbol.classKind == KtClassKind.OBJECT ||
classOrObjectSymbol.classKind == KtClassKind.INTERFACE ||
classOrObjectSymbol.classKind == KtClassKind.ANNOTATION_CLASS
)
require(isInterface || isAnnotation)
}
private val _modifierList: PsiModifierList? by lazyPub {
val lazyModifiers = lazy {
buildSet {
add(classOrObjectSymbol.toPsiVisibilityForClass(isNested = !isTopLevel))
add(PsiModifier.ABSTRACT)
if (!isTopLevel && !classOrObjectSymbol.isInner) {
add(PsiModifier.STATIC)
withNamedClassOrObjectSymbol { classOrObjectSymbol ->
val lazyModifiers = lazy {
buildSet {
add(classOrObjectSymbol.toPsiVisibilityForClass(isNested = !isTopLevel))
add(PsiModifier.ABSTRACT)
if (!isTopLevel && !classOrObjectSymbol.isInner) {
add(PsiModifier.STATIC)
}
}
}
}
val lazyAnnotations = lazyPub {
classOrObjectSymbol.computeAnnotations(
parent = this@SymbolLightInterfaceOrAnnotationClass,
nullability = NullabilityType.Unknown,
annotationUseSiteTarget = null,
)
}
val lazyAnnotations = lazyPub {
classOrObjectSymbol.computeAnnotations(
parent = this@SymbolLightInterfaceOrAnnotationClass,
nullability = NullabilityType.Unknown,
annotationUseSiteTarget = null,
)
}
SymbolLightClassModifierList(this@SymbolLightInterfaceOrAnnotationClass, lazyModifiers, lazyAnnotations)
SymbolLightClassModifierList(this@SymbolLightInterfaceOrAnnotationClass, lazyModifiers, lazyAnnotations)
}
}
override fun isInterface(): Boolean = true
override fun isEnum(): Boolean = false
override fun getModifierList(): PsiModifierList? = _modifierList
private val _ownFields: List<KtLightField> by lazyPub {
@@ -68,10 +63,4 @@ internal abstract class SymbolLightInterfaceOrAnnotationClass(
override fun getOwnFields(): List<KtLightField> = _ownFields
override fun getImplementsList(): PsiReferenceList? = null
override fun isInterface(): Boolean = true
override fun isEnum(): Boolean = false
override fun isValid(): Boolean = super.isValid() && classOrObjectSymbol.isValid()
}
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.light.classes.symbol.classes
import com.intellij.psi.PsiManager
import com.intellij.psi.PsiModifier
import com.intellij.psi.PsiReferenceList
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
@@ -16,6 +15,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.markers.isPrivateOrPrivateToThi
import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
import org.jetbrains.kotlin.analysis.project.structure.getKtModuleOfTypeSafe
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.lexer.KtTokens.*
import org.jetbrains.kotlin.light.classes.symbol.allowLightClassesOnEdt
import org.jetbrains.kotlin.light.classes.symbol.annotations.*
import org.jetbrains.kotlin.light.classes.symbol.copy
import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightField
@@ -44,48 +43,23 @@ import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.StandardClassIds
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 java.util.*
internal fun createSymbolLightClassNoCache(classOrObject: KtClassOrObject): KtLightClass? = allowLightClassesOnEdt {
val anonymousObject = classOrObject.parent as? KtObjectLiteralExpression
if (anonymousObject != null) {
return analyzeForLightClasses(anonymousObject) {
anonymousObject.getAnonymousObjectSymbol().createLightClassNoCache(anonymousObject.manager)
}
}
return when {
classOrObject is KtEnumEntry -> analyzeForLightClasses(classOrObject) {
lightClassForEnumEntry(classOrObject)
}
classOrObject.hasModifier(INLINE_KEYWORD) -> {
analyzeForLightClasses(classOrObject) {
classOrObject.getNamedClassOrObjectSymbol()?.let { SymbolLightInlineClass(it, classOrObject.manager) }
}
}
else -> {
analyzeForLightClasses(classOrObject) {
classOrObject.getClassOrObjectSymbol()?.createLightClassNoCache(classOrObject.manager)
}
}
}
internal fun createSymbolLightClassNoCache(classOrObject: KtClassOrObject, ktModule: KtModule): KtLightClass? = when {
classOrObject.isObjectLiteral() -> SymbolLightAnonymousClass(classOrObject, ktModule)
classOrObject is KtEnumEntry -> lightClassForEnumEntry(classOrObject)
classOrObject.hasModifier(INLINE_KEYWORD) -> SymbolLightInlineClass(classOrObject, ktModule)
else -> createLightClassNoCache(classOrObject, ktModule)
}
context(KtAnalysisSession)
internal fun KtClassOrObjectSymbol.createLightClassNoCache(manager: PsiManager): SymbolLightClassBase = when (this) {
is KtAnonymousObjectSymbol -> SymbolLightAnonymousClass(this, manager)
is KtNamedClassOrObjectSymbol -> when (classKind) {
KtClassKind.INTERFACE -> SymbolLightInterfaceClass(this, manager)
KtClassKind.ANNOTATION_CLASS -> SymbolLightAnnotationClass(this, manager)
else -> SymbolLightClass(this, manager)
}
internal fun createLightClassNoCache(ktClassOrObject: KtClassOrObject, ktModule: KtModule): SymbolLightClassBase = when {
ktClassOrObject is KtClass && ktClassOrObject.isAnnotation() -> SymbolLightAnnotationClass(ktClassOrObject, ktModule)
ktClassOrObject is KtClass && ktClassOrObject.isInterface() -> SymbolLightInterfaceClass(ktClassOrObject, ktModule)
else -> SymbolLightClass(ktClassOrObject, ktModule)
}
context(KtAnalysisSession)
private fun lightClassForEnumEntry(ktEnumEntry: KtEnumEntry): KtLightClass? {
if (ktEnumEntry.body == null) return null
@@ -441,9 +415,8 @@ internal fun SymbolLightClassBase.createInheritanceList(forExtendsList: Boolean,
context(KtAnalysisSession)
internal fun KtSymbolWithMembers.createInnerClasses(
manager: PsiManager,
containingClass: SymbolLightClassBase,
classOrObject: KtClassOrObject?
classOrObject: KtClassOrObject
): List<SymbolLightClassBase> {
val result = ArrayList<SymbolLightClassBase>()
@@ -452,20 +425,20 @@ internal fun KtSymbolWithMembers.createInnerClasses(
// we can't prohibit creating light classes with null names either since they can contain members
getDeclaredMemberScope().getClassifierSymbols().filterIsInstance<KtNamedClassOrObjectSymbol>().mapTo(result) {
it.createLightClassNoCache(manager)
createLightClassNoCache(it.psi(), ktModule = containingClass.ktModule)
}
val jvmDefaultMode =
classOrObject?.getKtModuleOfTypeSafe<KtSourceModule>()?.languageVersionSettings?.getFlag(JvmAnalysisFlags.jvmDefaultMode)
classOrObject.getKtModuleOfTypeSafe<KtSourceModule>()?.languageVersionSettings?.getFlag(JvmAnalysisFlags.jvmDefaultMode)
?: JvmDefaultMode.DEFAULT
if (this is KtNamedClassOrObjectSymbol &&
classOrObject?.hasInterfaceDefaultImpls == true &&
jvmDefaultMode != JvmDefaultMode.ALL_INCOMPATIBLE
if (classOrObject.hasInterfaceDefaultImpls &&
jvmDefaultMode != JvmDefaultMode.ALL_INCOMPATIBLE &&
containingClass is SymbolLightInterfaceClass
) {
result.add(SymbolLightClassForInterfaceDefaultImpls(this, containingClass, manager))
result.add(SymbolLightClassForInterfaceDefaultImpls(containingClass))
}
return result
}
@@ -57,7 +57,7 @@ internal class SymbolLightFieldForEnumEntry(
enumEntrySymbol = enumEntrySymbol,
enumConstant = this@SymbolLightFieldForEnumEntry,
enumClass = containingClass,
manager = manager
ktModule = enumEntrySymbol.getContainingModule(),
)
}
}
@@ -12,6 +12,9 @@ public final class C /* C*/ {
@org.jetbrains.annotations.NotNull()
public static final C.Companion Companion;
@org.jetbrains.annotations.NotNull()
public static final C.Factory Factory;
@kotlin.jvm.JvmStatic()
public static final void foo();// foo()