[SLC] modifiers should be calculated lazily

^KTIJ-23280 Fixed
This commit is contained in:
Dmitrii Gridin
2022-11-25 16:21:25 +01:00
committed by Space Team
parent 90bf4a3a24
commit 608d1e3431
19 changed files with 182 additions and 192 deletions
@@ -50,7 +50,7 @@ internal open class SymbolLightClass(classOrObject: KtClassOrObject, ktModule: K
require(classOrObject !is KtClass || !classOrObject.isInterface() && !classOrObject.isAnnotation()) require(classOrObject !is KtClass || !classOrObject.isInterface() && !classOrObject.isAnnotation())
} }
private val _modifierList: PsiModifierList? by lazyPub { private val _modifierList: PsiModifierList? by lazy {
val lazyModifiers = lazy { val lazyModifiers = lazy {
withNamedClassOrObjectSymbol { classOrObjectSymbol -> withNamedClassOrObjectSymbol { classOrObjectSymbol ->
buildSet { buildSet {
@@ -73,7 +73,7 @@ internal open class SymbolLightClass(classOrObject: KtClassOrObject, ktModule: K
} }
} }
SymbolLightClassModifierList(this@SymbolLightClass, lazyModifiers, lazyAnnotations) SymbolLightClassModifierList(this, lazyModifiers, lazyAnnotations)
} }
override fun getModifierList(): PsiModifierList? = _modifierList override fun getModifierList(): PsiModifierList? = _modifierList
@@ -36,11 +36,11 @@ internal class SymbolLightClassForEnumEntry(
override fun toString(): String = "SymbolLightClassForEnumEntry:$name" override fun toString(): String = "SymbolLightClassForEnumEntry:$name"
private val _modifierList: PsiModifierList by lazyPub { private val _modifierList: PsiModifierList by lazy {
SymbolLightClassModifierList( SymbolLightClassModifierList(
containingDeclaration = this, containingDeclaration = this,
lazyModifiers = lazyOf(setOf(PsiModifier.STATIC, PsiModifier.FINAL)), lazyModifiers = lazyOf(setOf(PsiModifier.STATIC, PsiModifier.FINAL)),
lazyAnnotations = lazyOf(emptyList()) lazyAnnotations = lazyOf(emptyList()),
) )
} }
@@ -62,11 +62,11 @@ class SymbolLightClassForFacade(
action(files.map { it.getFileSymbol() }) action(files.map { it.getFileSymbol() })
} }
private val firstFileInFacade by lazyPub { files.first() } private val firstFileInFacade by lazy { files.first() }
private val _modifierList: PsiModifierList by lazyPub { private val _modifierList: PsiModifierList by lazy {
if (multiFileClass) if (multiFileClass)
return@lazyPub LightModifierList(manager, KotlinLanguage.INSTANCE, PsiModifier.PUBLIC, PsiModifier.FINAL) return@lazy LightModifierList(manager, KotlinLanguage.INSTANCE, PsiModifier.PUBLIC, PsiModifier.FINAL)
val lazyModifiers = lazyOf(setOf(PsiModifier.PUBLIC, PsiModifier.FINAL)) val lazyModifiers = lazyOf(setOf(PsiModifier.PUBLIC, PsiModifier.FINAL))
@@ -83,7 +83,7 @@ class SymbolLightClassForFacade(
} }
} }
SymbolLightClassModifierList(this@SymbolLightClassForFacade, lazyModifiers, lazyAnnotations) SymbolLightClassModifierList(this, lazyModifiers, lazyAnnotations)
} }
override fun getModifierList(): PsiModifierList = _modifierList override fun getModifierList(): PsiModifierList = _modifierList
@@ -7,7 +7,6 @@ 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.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
@@ -23,10 +22,10 @@ internal class SymbolLightClassForInterfaceDefaultImpls(private val containingCl
override fun getTypeParameterList(): PsiTypeParameterList? = null override fun getTypeParameterList(): PsiTypeParameterList? = null
override fun getTypeParameters(): Array<PsiTypeParameter> = emptyArray() override fun getTypeParameters(): Array<PsiTypeParameter> = emptyArray()
private val _modifierList: PsiModifierList? by lazyPub { private val _modifierList: PsiModifierList? by lazy {
val lazyModifiers = lazyOf(setOf(PsiModifier.PUBLIC, PsiModifier.STATIC, PsiModifier.FINAL)) val lazyModifiers = lazyOf(setOf(PsiModifier.PUBLIC, PsiModifier.STATIC, PsiModifier.FINAL))
val lazyAnnotations = lazyOf(emptyList<PsiAnnotation>()) val lazyAnnotations = lazyOf(emptyList<PsiAnnotation>())
SymbolLightClassModifierList(this@SymbolLightClassForInterfaceDefaultImpls, lazyModifiers, lazyAnnotations) SymbolLightClassModifierList(this, lazyModifiers, lazyAnnotations)
} }
override fun getModifierList(): PsiModifierList? = _modifierList override fun getModifierList(): PsiModifierList? = _modifierList
@@ -24,7 +24,7 @@ internal abstract class SymbolLightInterfaceOrAnnotationClass(classOrObject: KtC
require(isInterface || isAnnotation) require(isInterface || isAnnotation)
} }
private val _modifierList: PsiModifierList? by lazyPub { private val _modifierList: PsiModifierList? by lazy {
val lazyModifiers = lazy { val lazyModifiers = lazy {
withNamedClassOrObjectSymbol { classOrObjectSymbol -> withNamedClassOrObjectSymbol { classOrObjectSymbol ->
buildSet { buildSet {
@@ -47,7 +47,7 @@ internal abstract class SymbolLightInterfaceOrAnnotationClass(classOrObject: KtC
} }
} }
SymbolLightClassModifierList(this@SymbolLightInterfaceOrAnnotationClass, lazyModifiers, lazyAnnotations) SymbolLightClassModifierList(this, lazyModifiers, lazyAnnotations)
} }
override fun isInterface(): Boolean = true override fun isInterface(): Boolean = true
@@ -32,16 +32,18 @@ internal class SymbolLightFieldForEnumEntry(
action(enumEntry.getEnumEntrySymbol()) action(enumEntry.getEnumEntrySymbol())
} }
private val _modifierList by lazyPub { private val _modifierList by lazy {
SymbolLightMemberModifierList( SymbolLightMemberModifierList(
containingDeclaration = this@SymbolLightFieldForEnumEntry, containingDeclaration = this@SymbolLightFieldForEnumEntry,
modifiers = setOf(PsiModifier.STATIC, PsiModifier.FINAL, PsiModifier.PUBLIC), lazyModifiers = lazyOf(setOf(PsiModifier.STATIC, PsiModifier.FINAL, PsiModifier.PUBLIC)),
annotations = withEnumEntrySymbol { enumEntrySymbol -> lazyAnnotations = lazyPub {
enumEntrySymbol.computeAnnotations( withEnumEntrySymbol { enumEntrySymbol ->
this@SymbolLightFieldForEnumEntry, enumEntrySymbol.computeAnnotations(
nullability = NullabilityType.Unknown, // there is no need to add nullability annotations on enum entries this@SymbolLightFieldForEnumEntry,
annotationUseSiteTarget = AnnotationUseSiteTarget.FIELD nullability = NullabilityType.Unknown, // there is no need to add nullability annotations on enum entries
) annotationUseSiteTarget = AnnotationUseSiteTarget.FIELD,
)
}
} }
) )
} }
@@ -38,13 +38,19 @@ internal class SymbolLightFieldForObject(
override fun getName(): String = name override fun getName(): String = name
private val _modifierList: PsiModifierList by lazyPub { private val _modifierList: PsiModifierList by lazy {
val modifiers = withObjectDeclarationSymbol { objectSymbol -> val lazyModifiers = lazy {
setOf(objectSymbol.toPsiVisibilityForMember(), PsiModifier.STATIC, PsiModifier.FINAL) withObjectDeclarationSymbol { objectSymbol ->
setOf(objectSymbol.toPsiVisibilityForMember(), PsiModifier.STATIC, PsiModifier.FINAL)
}
} }
val notNullAnnotation = SymbolLightSimpleAnnotation(NotNull::class.java.name, this) val lazyAnnotations = lazyPub {
SymbolLightMemberModifierList(this, modifiers, listOf(notNullAnnotation)) val notNullAnnotation = SymbolLightSimpleAnnotation(NotNull::class.java.name, this)
listOf(notNullAnnotation)
}
SymbolLightMemberModifierList(this, lazyModifiers, lazyAnnotations)
} }
private val _isDeprecated: Boolean by lazyPub { private val _isDeprecated: Boolean by lazyPub {
@@ -5,10 +5,7 @@
package org.jetbrains.kotlin.light.classes.symbol.fields package org.jetbrains.kotlin.light.classes.symbol.fields
import com.intellij.psi.PsiExpression import com.intellij.psi.*
import com.intellij.psi.PsiModifier
import com.intellij.psi.PsiModifierList
import com.intellij.psi.PsiType
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.KtConstantInitializerValue import org.jetbrains.kotlin.analysis.api.KtConstantInitializerValue
import org.jetbrains.kotlin.analysis.api.base.KtConstantValue import org.jetbrains.kotlin.analysis.api.base.KtConstantValue
@@ -36,9 +33,9 @@ internal class SymbolLightFieldForProperty private constructor(
private val fieldName: String, private val fieldName: String,
containingClass: SymbolLightClassBase, containingClass: SymbolLightClassBase,
lightMemberOrigin: LightMemberOrigin?, lightMemberOrigin: LightMemberOrigin?,
isTopLevel: Boolean, private val isTopLevel: Boolean,
forceStatic: Boolean, private val forceStatic: Boolean,
takePropertyVisibility: Boolean, private val takePropertyVisibility: Boolean,
override val kotlinOrigin: KtCallableDeclaration?, override val kotlinOrigin: KtCallableDeclaration?,
) : SymbolLightField(containingClass, lightMemberOrigin) { ) : SymbolLightField(containingClass, lightMemberOrigin) {
internal constructor( internal constructor(
@@ -91,51 +88,55 @@ internal class SymbolLightFieldForProperty private constructor(
override fun getName(): String = fieldName override fun getName(): String = fieldName
private val _modifierList: PsiModifierList by lazyPub { private fun computeModifiers(): Set<String> = withPropertySymbol { propertySymbol ->
withPropertySymbol { propertySymbol -> buildSet {
val modifiers = mutableSetOf<String>()
val suppressFinal = !propertySymbol.isVal val suppressFinal = !propertySymbol.isVal
propertySymbol.computeModalityForMethod( propertySymbol.computeModalityForMethod(
isTopLevel = isTopLevel, isTopLevel = isTopLevel,
suppressFinal = suppressFinal, suppressFinal = suppressFinal,
result = modifiers result = this
) )
if (forceStatic) { if (forceStatic) {
modifiers.add(PsiModifier.STATIC) add(PsiModifier.STATIC)
} }
val visibility = if (takePropertyVisibility) propertySymbol.toPsiVisibilityForMember() else PsiModifier.PRIVATE val visibility = if (takePropertyVisibility) propertySymbol.toPsiVisibilityForMember() else PsiModifier.PRIVATE
modifiers.add(visibility) add(visibility)
if (!suppressFinal) { if (!suppressFinal) {
modifiers.add(PsiModifier.FINAL) add(PsiModifier.FINAL)
} }
if (propertySymbol.hasAnnotation(TRANSIENT_ANNOTATION_CLASS_ID, null)) { if (propertySymbol.hasAnnotation(TRANSIENT_ANNOTATION_CLASS_ID, null)) {
modifiers.add(PsiModifier.TRANSIENT) add(PsiModifier.TRANSIENT)
} }
if (propertySymbol.hasAnnotation(VOLATILE_ANNOTATION_CLASS_ID, null)) { if (propertySymbol.hasAnnotation(VOLATILE_ANNOTATION_CLASS_ID, null)) {
modifiers.add(PsiModifier.VOLATILE) add(PsiModifier.VOLATILE)
} }
val nullability = if (!(propertySymbol is KtKotlinPropertySymbol && propertySymbol.isLateInit)) {
getTypeNullability(propertySymbol.returnType)
} else NullabilityType.Unknown
val annotations = propertySymbol.computeAnnotations(
parent = this@SymbolLightFieldForProperty,
nullability = nullability,
annotationUseSiteTarget = AnnotationUseSiteTarget.FIELD,
)
SymbolLightMemberModifierList(this@SymbolLightFieldForProperty, modifiers, annotations)
} }
} }
private fun computeAnnotations(): List<PsiAnnotation> = withPropertySymbol { propertySymbol ->
val nullability = if (!(propertySymbol is KtKotlinPropertySymbol && propertySymbol.isLateInit)) {
getTypeNullability(propertySymbol.returnType)
} else NullabilityType.Unknown
propertySymbol.computeAnnotations(
parent = this@SymbolLightFieldForProperty,
nullability = nullability,
annotationUseSiteTarget = AnnotationUseSiteTarget.FIELD,
)
}
private val _modifierList: PsiModifierList by lazy {
val lazyModifiers = lazyPub { computeModifiers() }
val lazyAnnotations = lazyPub { computeAnnotations() }
SymbolLightMemberModifierList(this, lazyModifiers, lazyAnnotations)
}
override fun getModifierList(): PsiModifierList = _modifierList override fun getModifierList(): PsiModifierList = _modifierList
private val _initializerValue: KtConstantValue? by lazyPub { private val _initializerValue: KtConstantValue? by lazyPub {
@@ -183,10 +183,10 @@ internal class SymbolLightAccessorMethod private constructor(
modifiers modifiers
} }
private val _modifierList: PsiModifierList by lazyPub { private val _modifierList: PsiModifierList by lazy {
val modifiers = computeModifiers() val lazyModifiers = lazyPub { computeModifiers() }
val annotations = computeAnnotations(modifiers.contains(PsiModifier.PRIVATE)) val lazyAnnotations = lazyPub { computeAnnotations(PsiModifier.PRIVATE in lazyModifiers.value) }
SymbolLightMemberModifierList(this, modifiers, annotations) SymbolLightMemberModifierList(this, lazyModifiers, lazyAnnotations)
} }
override fun getModifierList(): PsiModifierList = _modifierList override fun getModifierList(): PsiModifierList = _modifierList
@@ -43,31 +43,31 @@ internal class SymbolLightConstructor(
override fun getTypeParameterList(): PsiTypeParameterList? = null override fun getTypeParameterList(): PsiTypeParameterList? = null
override fun getTypeParameters(): Array<PsiTypeParameter> = PsiTypeParameter.EMPTY_ARRAY override fun getTypeParameters(): Array<PsiTypeParameter> = PsiTypeParameter.EMPTY_ARRAY
private val _annotations: List<PsiAnnotation> by lazyPub { private val _modifierList: PsiModifierList by lazy {
withFunctionSymbol { constructorSymbol -> val lazyAnnotations: Lazy<List<PsiAnnotation>> = lazyPub {
constructorSymbol.computeAnnotations(
parent = this@SymbolLightConstructor,
nullability = NullabilityType.Unknown,
annotationUseSiteTarget = null,
)
}
}
private val _modifiers: Set<String> by lazyPub {
// FIR treats an enum entry as an anonymous object w/ its own ctor (not default one).
// On the other hand, FE 1.0 doesn't add anything; then ULC adds default ctor w/ package local visibility.
// Technically, an enum entry should not be instantiated anywhere else, and thus FIR's modeling makes sense.
// But, to be backward compatible, we manually force the visibility of enum entry ctor to be package private.
if (containingClass is SymbolLightClassForEnumEntry)
setOf(PsiModifier.PACKAGE_LOCAL)
else
withFunctionSymbol { constructorSymbol -> withFunctionSymbol { constructorSymbol ->
setOf(constructorSymbol.toPsiVisibilityForMember()) constructorSymbol.computeAnnotations(
parent = this@SymbolLightConstructor,
nullability = NullabilityType.Unknown,
annotationUseSiteTarget = null,
)
} }
} }
private val _modifierList: PsiModifierList by lazyPub { val lazyModifiers: Lazy<Set<String>> = lazy {
SymbolLightMemberModifierList(this, _modifiers, _annotations) // FIR treats an enum entry as an anonymous object w/ its own ctor (not default one).
// On the other hand, FE 1.0 doesn't add anything; then ULC adds default ctor w/ package local visibility.
// Technically, an enum entry should not be instantiated anywhere else, and thus FIR's modeling makes sense.
// But, to be backward compatible, we manually force the visibility of enum entry ctor to be package private.
if (containingClass is SymbolLightClassForEnumEntry)
setOf(PsiModifier.PACKAGE_LOCAL)
else
withFunctionSymbol { constructorSymbol ->
setOf(constructorSymbol.toPsiVisibilityForMember())
}
}
SymbolLightMemberModifierList(this, lazyModifiers, lazyAnnotations)
} }
override fun getModifierList(): PsiModifierList = _modifierList override fun getModifierList(): PsiModifierList = _modifierList
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightParameter
internal class SymbolLightNoArgConstructor( internal class SymbolLightNoArgConstructor(
lightMemberOrigin: LightMemberOrigin, lightMemberOrigin: LightMemberOrigin,
containingClass: SymbolLightClassForClassOrObject, containingClass: SymbolLightClassForClassOrObject,
visibility: String, private val visibility: String,
methodIndex: Int, methodIndex: Int,
) : SymbolLightMethodBase(lightMemberOrigin, containingClass, methodIndex) { ) : SymbolLightMethodBase(lightMemberOrigin, containingClass, methodIndex) {
override fun getName(): String = containingClass.name ?: "" override fun getName(): String = containingClass.name ?: ""
@@ -35,10 +35,8 @@ internal class SymbolLightNoArgConstructor(
override fun isDeprecated(): Boolean = false override fun isDeprecated(): Boolean = false
private val _modifiers: Set<String> = setOf(visibility) private val _modifierList: PsiModifierList by lazy {
SymbolLightMemberModifierList(this, lazyOf(setOf(visibility)), lazyOf(emptyList()))
private val _modifierList: PsiModifierList by lazyPub {
SymbolLightMemberModifierList(this, _modifiers, emptyList())
} }
override fun getModifierList(): PsiModifierList = _modifierList override fun getModifierList(): PsiModifierList = _modifierList
@@ -119,12 +119,20 @@ internal class SymbolLightSimpleMethod(
return modifiers return modifiers
} }
private val _modifierList: PsiModifierList by lazyPub { private val _modifierList: PsiModifierList by lazy {
withFunctionSymbol { functionSymbol -> val lazyModifiers = lazyPub {
val modifiers = computeModifiers(functionSymbol) withFunctionSymbol { functionSymbol ->
val annotations = computeAnnotations(functionSymbol, modifiers.contains(PsiModifier.PRIVATE)) computeModifiers(functionSymbol)
SymbolLightMemberModifierList(this@SymbolLightSimpleMethod, modifiers, annotations) }
} }
val lazyAnnotations = lazyPub {
withFunctionSymbol { functionSymbol ->
computeAnnotations(functionSymbol, PsiModifier.PRIVATE in lazyModifiers.value)
}
}
SymbolLightMemberModifierList(this, lazyModifiers, lazyAnnotations)
} }
override fun getModifierList(): PsiModifierList = _modifierList override fun getModifierList(): PsiModifierList = _modifierList
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.light.classes.symbol.modifierLists
import com.intellij.psi.PsiAnnotation import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiModifierListOwner import com.intellij.psi.PsiModifierListOwner
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation
import org.jetbrains.kotlin.asJava.elements.KtLightElement import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.asJava.elements.KtLightElementBase import org.jetbrains.kotlin.asJava.elements.KtLightElementBase
@@ -17,20 +16,19 @@ import org.jetbrains.kotlin.psi.KtModifierListOwner
internal class SymbolLightClassModifierList<T : KtLightElement<KtModifierListOwner, PsiModifierListOwner>>( internal class SymbolLightClassModifierList<T : KtLightElement<KtModifierListOwner, PsiModifierListOwner>>(
containingDeclaration: T, containingDeclaration: T,
private val lazyModifiers: Lazy<Set<String>>, private val lazyModifiers: Lazy<Set<String>>,
lazyAnnotations: Lazy<List<PsiAnnotation>> lazyAnnotations: Lazy<List<PsiAnnotation>>,
) : SymbolLightModifierList<T>(containingDeclaration) { ) : SymbolLightModifierList<T>(containingDeclaration) {
private val lazyAnnotations = lazy { private val lazyAnnotations: Lazy<List<PsiAnnotation>> = lazy {
lazyAnnotations.value lazyAnnotations.value.onEach { (it as? KtLightElementBase)?.parent = this }
.onEach { (it as? KtLightElementBase)?.parent = this }
} }
override fun hasModifierProperty(name: String): Boolean = name in lazyModifiers.value override fun hasModifierProperty(name: String): Boolean = name in lazyModifiers.value
override val givenAnnotations: List<KtLightAbstractAnnotation>? override val givenAnnotations: List<KtLightAbstractAnnotation> get() = invalidAccess()
get() = invalidAccess()
override fun getAnnotations(): Array<out PsiAnnotation> = lazyAnnotations.value.toTypedArray() override fun getAnnotations(): Array<out PsiAnnotation> = lazyAnnotations.value.toTypedArray()
override fun findAnnotation(qualifiedName: String) = annotations.firstOrNull { it.qualifiedName == qualifiedName } override fun findAnnotation(qualifiedName: String): PsiAnnotation? =
lazyAnnotations.value.firstOrNull { it.qualifiedName == qualifiedName }
override fun equals(other: Any?): Boolean = this === other override fun equals(other: Any?): Boolean = this === other
@@ -19,25 +19,19 @@ import org.jetbrains.kotlin.psi.psiUtil.hasBody
internal class SymbolLightMemberModifierList<T : KtLightMember<*>>( internal class SymbolLightMemberModifierList<T : KtLightMember<*>>(
containingDeclaration: T, containingDeclaration: T,
private val modifiers: Set<String>, private val lazyModifiers: Lazy<Set<String>>,
private val annotations: List<PsiAnnotation> lazyAnnotations: Lazy<List<PsiAnnotation>>
) : SymbolLightModifierList<T>(containingDeclaration) { ) : SymbolLightModifierList<T>(containingDeclaration) {
init { private val lazyAnnotations: Lazy<List<PsiAnnotation>> = lazy {
annotations.forEach { lazyAnnotations.value.onEach { (it as? KtLightElementBase)?.parent = this }
(it as? KtLightElementBase)?.parent = this
}
} }
override fun hasModifierProperty(name: String): Boolean { override fun hasModifierProperty(name: String): Boolean = when {
return when { name == PsiModifier.ABSTRACT && isImplementationInInterface() -> false
name == PsiModifier.ABSTRACT && isImplementationInInterface() -> false // Pretend this method behaves like a `default` method
// Pretend this method behaves like a `default` method name == PsiModifier.DEFAULT && isImplementationInInterface() -> true
name == PsiModifier.DEFAULT && isImplementationInInterface() -> true // TODO: FINAL && isPossiblyAffectedByAllOpen
// TODO: FINAL && isPossiblyAffectedByAllOpen else -> name in lazyModifiers.value
else -> {
name in modifiers
}
}
} }
private fun isImplementationInInterface(): Boolean { private fun isImplementationInInterface(): Boolean {
@@ -49,12 +43,12 @@ internal class SymbolLightMemberModifierList<T : KtLightMember<*>>(
return if (name == PsiModifier.DEFAULT) false else super.hasExplicitModifier(name) return if (name == PsiModifier.DEFAULT) false else super.hasExplicitModifier(name)
} }
override val givenAnnotations: List<KtLightAbstractAnnotation>? override val givenAnnotations: List<KtLightAbstractAnnotation> get() = invalidAccess()
get() = invalidAccess()
override fun getAnnotations(): Array<out PsiAnnotation> = annotations.toTypedArray() override fun getAnnotations(): Array<out PsiAnnotation> = lazyAnnotations.value.toTypedArray()
override fun findAnnotation(qualifiedName: String) = annotations.firstOrNull { it.qualifiedName == qualifiedName } override fun findAnnotation(qualifiedName: String): PsiAnnotation? =
lazyAnnotations.value.firstOrNull { it.qualifiedName == qualifiedName }
private inline fun <R> getTextVariantFromModifierListOfPropertyAccessorIfNeeded( private inline fun <R> getTextVariantFromModifierListOfPropertyAccessorIfNeeded(
retriever: (KtModifierList) -> R retriever: (KtModifierList) -> R
@@ -19,31 +19,16 @@ import org.jetbrains.kotlin.psi.KtModifierListOwner
internal abstract class SymbolLightModifierList<out T : KtLightElement<KtModifierListOwner, PsiModifierListOwner>>( internal abstract class SymbolLightModifierList<out T : KtLightElement<KtModifierListOwner, PsiModifierListOwner>>(
protected val owner: T protected val owner: T
) : KtLightElementBase(owner), PsiModifierList, KtLightElement<KtModifierList, PsiModifierListOwner> { ) : KtLightElementBase(owner), PsiModifierList, KtLightElement<KtModifierList, PsiModifierListOwner> {
override val kotlinOrigin: KtModifierList? get() = owner.kotlinOrigin?.modifierList
override val kotlinOrigin: KtModifierList?
get() = owner.kotlinOrigin?.modifierList
override fun getParent() = owner override fun getParent() = owner
override fun hasExplicitModifier(name: String) = hasModifierProperty(name) override fun hasExplicitModifier(name: String) = hasModifierProperty(name)
override fun setModifierProperty(name: String, value: Boolean) = cannotModify() override fun setModifierProperty(name: String, value: Boolean) = cannotModify()
override fun checkSetModifierProperty(name: String, value: Boolean) = throw IncorrectOperationException() override fun checkSetModifierProperty(name: String, value: Boolean) = throw IncorrectOperationException()
override fun addAnnotation(qualifiedName: String): PsiAnnotation = cannotModify() override fun addAnnotation(qualifiedName: String): PsiAnnotation = cannotModify()
override fun getApplicableAnnotations(): Array<out PsiAnnotation> = annotations override fun getApplicableAnnotations(): Array<out PsiAnnotation> = annotations
override fun isEquivalentTo(another: PsiElement?) = another is SymbolLightModifierList<*> && owner == another.owner
override fun getAnnotations(): Array<out PsiAnnotation> = emptyArray() //TODO()
override fun findAnnotation(qualifiedName: String): PsiAnnotation? = null //TODO()
override fun isEquivalentTo(another: PsiElement?) =
another is SymbolLightModifierList<*> && owner == another.owner
override fun isWritable() = false override fun isWritable() = false
override fun toString() = "Light modifier list of $owner" override fun toString() = "Light modifier list of $owner"
abstract override fun equals(other: Any?): Boolean abstract override fun equals(other: Any?): Boolean
abstract override fun hashCode(): Int abstract override fun hashCode(): Int
} }
@@ -25,28 +25,27 @@ internal class SymbolLightParameter(
) : SymbolLightParameterCommon(ktAnalysisSession, parameterSymbol, containingMethod) { ) : SymbolLightParameterCommon(ktAnalysisSession, parameterSymbol, containingMethod) {
private val isConstructorParameterSymbol = containingMethod.isConstructor private val isConstructorParameterSymbol = containingMethod.isConstructor
private val _annotations: List<PsiAnnotation> by lazyPub {
val annotationSite = isConstructorParameterSymbol.ifTrue {
AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER
}
parameterSymbolPointer.withSymbol(ktModule) { parameterSymbol ->
val nullability = if (parameterSymbol.isVararg) NullabilityType.NotNull else super.nullabilityType
parameterSymbol.computeAnnotations(
parent = this@SymbolLightParameter,
nullability = nullability,
annotationUseSiteTarget = annotationSite,
includeAnnotationsWithoutSite = true
)
}
}
override fun getModifierList(): PsiModifierList = _modifierList override fun getModifierList(): PsiModifierList = _modifierList
private val _modifierList: PsiModifierList by lazyPub { private val _modifierList: PsiModifierList by lazy {
SymbolLightClassModifierList(this, lazyOf(emptySet()), lazyOf(_annotations)) val lazyAnnotations: Lazy<List<PsiAnnotation>> = lazyPub {
val annotationSite = isConstructorParameterSymbol.ifTrue {
AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER
}
parameterSymbolPointer.withSymbol(ktModule) { parameterSymbol ->
val nullability = if (parameterSymbol.isVararg) NullabilityType.NotNull else super.nullabilityType
parameterSymbol.computeAnnotations(
parent = this@SymbolLightParameter,
nullability = nullability,
annotationUseSiteTarget = annotationSite,
includeAnnotationsWithoutSite = true,
)
}
}
SymbolLightClassModifierList(this, lazyOf(emptySet()), lazyAnnotations)
} }
private val isVararg: Boolean by lazy { private val isVararg: Boolean by lazy {
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.light.classes.symbol.parameters package org.jetbrains.kotlin.light.classes.symbol.parameters
import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiIdentifier import com.intellij.psi.PsiIdentifier
import com.intellij.psi.PsiModifierList import com.intellij.psi.PsiModifierList
import com.intellij.psi.PsiType import com.intellij.psi.PsiType
@@ -18,6 +17,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.light.classes.symbol.* import org.jetbrains.kotlin.light.classes.symbol.*
import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolLightAbstractAnnotation
import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolLightAnnotationForAnnotationCall import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolLightAnnotationForAnnotationCall
import org.jetbrains.kotlin.light.classes.symbol.annotations.computeNullabilityAnnotation import org.jetbrains.kotlin.light.classes.symbol.annotations.computeNullabilityAnnotation
import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightMethodBase import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightMethodBase
@@ -66,21 +66,21 @@ internal class SymbolLightParameterForReceiver private constructor(
override val kotlinOrigin: KtParameter? = null override val kotlinOrigin: KtParameter? = null
private val _annotations: List<PsiAnnotation> by lazyPub {
withReceiverSymbol { receiver ->
buildList {
receiver.type.nullabilityType.computeNullabilityAnnotation(this@SymbolLightParameterForReceiver)?.let(::add)
receiver.annotations.mapTo(this) {
SymbolLightAnnotationForAnnotationCall(it, this@SymbolLightParameterForReceiver)
}
}
}
}
override fun getModifierList(): PsiModifierList = _modifierList override fun getModifierList(): PsiModifierList = _modifierList
private val _modifierList: PsiModifierList by lazy { private val _modifierList: PsiModifierList by lazy {
SymbolLightClassModifierList(this, lazyOf(emptySet()), lazyOf(_annotations)) val lazyAnnotations: Lazy<List<SymbolLightAbstractAnnotation>> = lazyPub {
withReceiverSymbol { receiver ->
buildList {
receiver.type.nullabilityType.computeNullabilityAnnotation(this@SymbolLightParameterForReceiver)?.let(::add)
receiver.annotations.mapTo(this) {
SymbolLightAnnotationForAnnotationCall(it, this@SymbolLightParameterForReceiver)
}
}
}
}
SymbolLightClassModifierList(this, lazyOf(emptySet()), lazyAnnotations)
} }
private val _type: PsiType by lazy { private val _type: PsiType by lazy {
@@ -39,29 +39,29 @@ internal class SymbolLightSetterParameter(
} }
} }
private val _annotations: List<PsiAnnotation> by lazyPub {
analyzeForLightClasses(ktModule) {
val annotationsFromSetter = parameterSymbolPointer.restoreSymbolOrThrowIfDisposed().computeAnnotations(
parent = this@SymbolLightSetterParameter,
nullability = NullabilityType.Unknown,
annotationUseSiteTarget = AnnotationUseSiteTarget.SETTER_PARAMETER,
)
val annotationsFromProperty = containingPropertySymbolPointer.restoreSymbolOrThrowIfDisposed().computeAnnotations(
parent = this@SymbolLightSetterParameter,
nullability = nullabilityType,
annotationUseSiteTarget = AnnotationUseSiteTarget.SETTER_PARAMETER,
includeAnnotationsWithoutSite = false,
)
annotationsFromSetter + annotationsFromProperty
}
}
override fun getModifierList(): PsiModifierList = _modifierList override fun getModifierList(): PsiModifierList = _modifierList
private val _modifierList: PsiModifierList by lazyPub { private val _modifierList: PsiModifierList by lazy {
SymbolLightClassModifierList(this, lazyOf(emptySet()), lazyOf(_annotations)) val lazyAnnotations: Lazy<List<PsiAnnotation>> = lazyPub {
analyzeForLightClasses(ktModule) {
val annotationsFromSetter = parameterSymbolPointer.restoreSymbolOrThrowIfDisposed().computeAnnotations(
parent = this@SymbolLightSetterParameter,
nullability = NullabilityType.Unknown,
annotationUseSiteTarget = AnnotationUseSiteTarget.SETTER_PARAMETER,
)
val annotationsFromProperty = containingPropertySymbolPointer.restoreSymbolOrThrowIfDisposed().computeAnnotations(
parent = this@SymbolLightSetterParameter,
nullability = nullabilityType,
annotationUseSiteTarget = AnnotationUseSiteTarget.SETTER_PARAMETER,
includeAnnotationsWithoutSite = false,
)
annotationsFromSetter + annotationsFromProperty
}
}
SymbolLightClassModifierList(this, lazyOf(emptySet()), lazyAnnotations)
} }
override fun isVarArgs() = false override fun isVarArgs() = false
@@ -50,11 +50,11 @@ internal class SymbolLightSuspendContinuationParameter(
override fun getModifierList(): PsiModifierList = _modifierList override fun getModifierList(): PsiModifierList = _modifierList
private val _modifierList: PsiModifierList by lazy { private val _modifierList: PsiModifierList by lazy {
val lazyAnnotations = lazy { val lazyAnnotations = lazyPub {
if (withFunctionSymbol { it.visibility.isPrivateOrPrivateToThis() }) if (withFunctionSymbol { it.visibility.isPrivateOrPrivateToThis() })
emptyList() emptyList()
else else
listOf(SymbolLightSimpleAnnotation(NotNull::class.java.name, this@SymbolLightSuspendContinuationParameter)) listOf(SymbolLightSimpleAnnotation(NotNull::class.java.name, this))
} }
SymbolLightClassModifierList(this, lazyOf(emptySet()), lazyAnnotations) SymbolLightClassModifierList(this, lazyOf(emptySet()), lazyAnnotations)