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