[SLC] drop KtAnalysisSession from SymbolLightFieldForProperty

^KT-54051
This commit is contained in:
Dmitrii Gridin
2022-11-15 17:33:01 +01:00
committed by Space Team
parent 3764fa5454
commit 40bd222b78
4 changed files with 128 additions and 70 deletions
@@ -40,6 +40,30 @@ public inline fun <reified PSI : PsiElement> KtSymbol.psi(): PSI =
public inline fun <reified PSI : PsiElement> KtSymbol.psiSafe(): PSI? =
psi as? PSI
/**
* Get symbol [PsiElement]. **null** if its [KtSymbol.origin] !is [KtSymbolOrigin.SOURCE]. throws **ClassCastException** if its type !is [PSI]
*
* @see KtSymbol.psi
*/
public inline fun <reified PSI : PsiElement> KtSymbol.sourcePsi(): PSI? {
// TODO: support Java sources after KT-53669
if (origin != KtSymbolOrigin.SOURCE) return null
return psi as PSI
}
/**
* Get symbol [PsiElement] if its type is [PSI] and [KtSymbol.origin] is [KtSymbolOrigin.SOURCE], otherwise null
*
* @see KtSymbol.psiSafe
*/
public inline fun <reified PSI : PsiElement> KtSymbol.sourcePsiSafe(): PSI? {
// TODO: support Java sources after KT-53669
if (origin != KtSymbolOrigin.SOURCE) return null
return psi as? PSI
}
/**
* A place where [KtSymbol] came from
*/
@@ -168,6 +168,7 @@ abstract class SymbolLightClassForClassOrObject(protected val classOrObject: KtC
isTopLevel = false,
forceStatic = true,
takePropertyVisibility = it.isConstOrJvmField,
ktModule = ktModule,
)
}
@@ -354,7 +354,8 @@ internal fun SymbolLightClassBase.createField(
lightMemberOrigin = null,
isTopLevel = isTopLevel,
forceStatic = forceStatic,
takePropertyVisibility = takePropertyVisibility
takePropertyVisibility = takePropertyVisibility,
ktModule = ktModule,
)
)
}
@@ -8,10 +8,13 @@ package org.jetbrains.kotlin.light.classes.symbol.fields
import com.intellij.psi.*
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.KtConstantInitializerValue
import org.jetbrains.kotlin.analysis.api.lifetime.isValid
import org.jetbrains.kotlin.analysis.api.base.KtConstantValue
import org.jetbrains.kotlin.analysis.api.symbols.KtKotlinPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.api.symbols.sourcePsiSafe
import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
@@ -20,47 +23,58 @@ import org.jetbrains.kotlin.light.classes.symbol.annotations.computeAnnotations
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasAnnotation
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasDeprecatedAnnotation
import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase
import org.jetbrains.kotlin.light.classes.symbol.classes.analyzeForLightClasses
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightMemberModifierList
import org.jetbrains.kotlin.name.JvmNames.TRANSIENT_ANNOTATION_CLASS_ID
import org.jetbrains.kotlin.name.JvmNames.VOLATILE_ANNOTATION_CLASS_ID
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtProperty
context(KtAnalysisSession)
internal class SymbolLightFieldForProperty(
private val propertySymbol: KtPropertySymbol,
propertySymbol: KtPropertySymbol,
private val fieldName: String,
containingClass: SymbolLightClassBase,
lightMemberOrigin: LightMemberOrigin?,
isTopLevel: Boolean,
forceStatic: Boolean,
takePropertyVisibility: Boolean
takePropertyVisibility: Boolean,
private val ktModule: KtModule,
) : SymbolLightField(containingClass, lightMemberOrigin) {
override val kotlinOrigin: KtCallableDeclaration? = propertySymbol.sourcePsiSafe<KtCallableDeclaration>()
private val propertySymbolPointer: KtSymbolPointer<KtPropertySymbol> = propertySymbol.createPointer()
override val kotlinOrigin: KtDeclaration? = propertySymbol.psi as? KtDeclaration
private fun <T> withPropertySymbol(action: KtAnalysisSession.(KtPropertySymbol) -> T): T = analyzeForLightClasses(ktModule) {
val restoreSymbol = propertySymbolPointer.restoreSymbol()
requireNotNull(restoreSymbol) { "pointer already disposed" }
action(restoreSymbol)
}
private val _returnedType: PsiType by lazyPub {
val isDelegated = (propertySymbol as? KtKotlinPropertySymbol)?.isDelegatedProperty == true
when {
isDelegated ->
(kotlinOrigin as? KtProperty)?.delegateExpression?.let {
it.getKtType()?.asPsiType(this@SymbolLightFieldForProperty, KtTypeMappingMode.RETURN_TYPE)
}
withPropertySymbol { propertySymbol ->
val isDelegated = (propertySymbol as? KtKotlinPropertySymbol)?.isDelegatedProperty == true
when {
isDelegated ->
(kotlinOrigin as? KtProperty)?.delegateExpression?.let {
it.getKtType()?.asPsiType(this@SymbolLightFieldForProperty, KtTypeMappingMode.RETURN_TYPE)
}
else -> {
propertySymbol.returnType.asPsiType(this@SymbolLightFieldForProperty, KtTypeMappingMode.RETURN_TYPE)
}
} ?: nonExistentType()
else -> propertySymbol.returnType.asPsiType(this@SymbolLightFieldForProperty, KtTypeMappingMode.RETURN_TYPE)
} ?: nonExistentType()
}
}
private val _isDeprecated: Boolean by lazyPub {
propertySymbol.hasDeprecatedAnnotation(AnnotationUseSiteTarget.FIELD)
withPropertySymbol { propertySymbol ->
propertySymbol.hasDeprecatedAnnotation(AnnotationUseSiteTarget.FIELD)
}
}
override fun isDeprecated(): Boolean = _isDeprecated
private val _identifier: PsiIdentifier by lazyPub {
SymbolLightIdentifier(this, propertySymbol)
withPropertySymbol { propertySymbol ->
SymbolLightIdentifier(this@SymbolLightFieldForProperty, propertySymbol)
}
}
override fun getNameIdentifier(): PsiIdentifier = _identifier
@@ -70,53 +84,57 @@ internal class SymbolLightFieldForProperty(
override fun getName(): String = fieldName
private val _modifierList: PsiModifierList by lazyPub {
withPropertySymbol { propertySymbol ->
val modifiers = mutableSetOf<String>()
val modifiers = mutableSetOf<String>()
val suppressFinal = !propertySymbol.isVal
val suppressFinal = !propertySymbol.isVal
propertySymbol.computeModalityForMethod(
isTopLevel = isTopLevel,
suppressFinal = suppressFinal,
result = modifiers
)
propertySymbol.computeModalityForMethod(
isTopLevel = isTopLevel,
suppressFinal = suppressFinal,
result = modifiers
)
if (forceStatic) {
modifiers.add(PsiModifier.STATIC)
}
if (forceStatic) {
modifiers.add(PsiModifier.STATIC)
val visibility = if (takePropertyVisibility) propertySymbol.toPsiVisibilityForMember() else PsiModifier.PRIVATE
modifiers.add(visibility)
if (!suppressFinal) {
modifiers.add(PsiModifier.FINAL)
}
if (propertySymbol.hasAnnotation(TRANSIENT_ANNOTATION_CLASS_ID, null)) {
modifiers.add(PsiModifier.TRANSIENT)
}
if (propertySymbol.hasAnnotation(VOLATILE_ANNOTATION_CLASS_ID, null)) {
modifiers.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)
}
val visibility =
if (takePropertyVisibility) propertySymbol.toPsiVisibilityForMember() else PsiModifier.PRIVATE
modifiers.add(visibility)
if (!suppressFinal) {
modifiers.add(PsiModifier.FINAL)
}
if (propertySymbol.hasAnnotation(TRANSIENT_ANNOTATION_CLASS_ID, null)) {
modifiers.add(PsiModifier.TRANSIENT)
}
if (propertySymbol.hasAnnotation(VOLATILE_ANNOTATION_CLASS_ID, null)) {
modifiers.add(PsiModifier.VOLATILE)
}
val nullability = if (!(propertySymbol is KtKotlinPropertySymbol && propertySymbol.isLateInit)) {
getTypeNullability(propertySymbol.returnType)
} else NullabilityType.Unknown
val annotations = propertySymbol.computeAnnotations(
parent = this,
nullability = nullability,
annotationUseSiteTarget = AnnotationUseSiteTarget.FIELD,
)
SymbolLightMemberModifierList(this, modifiers, annotations)
}
override fun getModifierList(): PsiModifierList = _modifierList
private val _initializerValue by lazyPub {
if (propertySymbol !is KtKotlinPropertySymbol) return@lazyPub null
(propertySymbol.initializer as? KtConstantInitializerValue)?.constant
private val _initializerValue: KtConstantValue? by lazyPub {
withPropertySymbol { propertySymbol ->
if (propertySymbol !is KtKotlinPropertySymbol) return@withPropertySymbol null
(propertySymbol.initializer as? KtConstantInitializerValue)?.constant
}
}
private val _initializer by lazyPub {
@@ -127,24 +145,38 @@ internal class SymbolLightFieldForProperty(
private val _constantValue by lazyPub {
_initializerValue?.value?.takeIf {
// val => final
propertySymbol.isVal &&
// NB: not as?, since _initializerValue already checks that
(propertySymbol as KtKotlinPropertySymbol).isConst &&
// javac rejects all non-primitive and non String constants
(propertySymbol.returnType.isPrimitive || propertySymbol.returnType.isString)
withPropertySymbol { propertySymbol ->
// val => final
propertySymbol.isVal &&
// NB: not as?, since _initializerValue already checks that
(propertySymbol as KtKotlinPropertySymbol).isConst &&
// javac rejects all non-primitive and non String constants
(propertySymbol.returnType.isPrimitive || propertySymbol.returnType.isString)
}
}
}
override fun computeConstantValue(): Any? = _constantValue
override fun equals(other: Any?): Boolean =
this === other ||
(other is SymbolLightFieldForProperty &&
kotlinOrigin == other.kotlinOrigin &&
propertySymbol == other.propertySymbol)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is SymbolLightFieldForProperty) return false
if (kotlinOrigin != null) {
return kotlinOrigin == other.kotlinOrigin && ktModule == other.ktModule
}
override fun hashCode(): Int = kotlinOrigin.hashCode()
return other.kotlinOrigin == null &&
fieldName == other.fieldName &&
containingClass == other.containingClass &&
ktModule == other.ktModule &&
analyzeForLightClasses(ktModule) {
propertySymbolPointer.restoreSymbol() == other.propertySymbolPointer.restoreSymbol()
}
}
override fun isValid(): Boolean = super.isValid() && propertySymbol.isValid()
override fun hashCode(): Int = kotlinOrigin?.hashCode() ?: fieldName.hashCode()
override fun isValid(): Boolean = super.isValid() && kotlinOrigin?.isValid ?: analyzeForLightClasses(ktModule) {
propertySymbolPointer.restoreSymbol() != null
}
}