[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? = public inline fun <reified PSI : PsiElement> KtSymbol.psiSafe(): PSI? =
psi as? 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 * A place where [KtSymbol] came from
*/ */
@@ -168,6 +168,7 @@ abstract class SymbolLightClassForClassOrObject(protected val classOrObject: KtC
isTopLevel = false, isTopLevel = false,
forceStatic = true, forceStatic = true,
takePropertyVisibility = it.isConstOrJvmField, takePropertyVisibility = it.isConstOrJvmField,
ktModule = ktModule,
) )
} }
@@ -354,7 +354,8 @@ internal fun SymbolLightClassBase.createField(
lightMemberOrigin = null, lightMemberOrigin = null,
isTopLevel = isTopLevel, isTopLevel = isTopLevel,
forceStatic = forceStatic, 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 com.intellij.psi.*
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.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.KtKotlinPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol 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.api.types.KtTypeMappingMode
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.classes.lazyPub import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget 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.hasAnnotation
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.classes.SymbolLightClassBase 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.light.classes.symbol.modifierLists.SymbolLightMemberModifierList
import org.jetbrains.kotlin.name.JvmNames.TRANSIENT_ANNOTATION_CLASS_ID import org.jetbrains.kotlin.name.JvmNames.TRANSIENT_ANNOTATION_CLASS_ID
import org.jetbrains.kotlin.name.JvmNames.VOLATILE_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 import org.jetbrains.kotlin.psi.KtProperty
context(KtAnalysisSession)
internal class SymbolLightFieldForProperty( internal class SymbolLightFieldForProperty(
private val propertySymbol: KtPropertySymbol, propertySymbol: KtPropertySymbol,
private val fieldName: String, private val fieldName: String,
containingClass: SymbolLightClassBase, containingClass: SymbolLightClassBase,
lightMemberOrigin: LightMemberOrigin?, lightMemberOrigin: LightMemberOrigin?,
isTopLevel: Boolean, isTopLevel: Boolean,
forceStatic: Boolean, forceStatic: Boolean,
takePropertyVisibility: Boolean takePropertyVisibility: Boolean,
private val ktModule: KtModule,
) : SymbolLightField(containingClass, lightMemberOrigin) { ) : 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 { private val _returnedType: PsiType by lazyPub {
val isDelegated = (propertySymbol as? KtKotlinPropertySymbol)?.isDelegatedProperty == true withPropertySymbol { propertySymbol ->
when { val isDelegated = (propertySymbol as? KtKotlinPropertySymbol)?.isDelegatedProperty == true
isDelegated -> when {
(kotlinOrigin as? KtProperty)?.delegateExpression?.let { isDelegated ->
it.getKtType()?.asPsiType(this@SymbolLightFieldForProperty, KtTypeMappingMode.RETURN_TYPE) (kotlinOrigin as? KtProperty)?.delegateExpression?.let {
} it.getKtType()?.asPsiType(this@SymbolLightFieldForProperty, KtTypeMappingMode.RETURN_TYPE)
}
else -> { else -> propertySymbol.returnType.asPsiType(this@SymbolLightFieldForProperty, KtTypeMappingMode.RETURN_TYPE)
propertySymbol.returnType.asPsiType(this@SymbolLightFieldForProperty, KtTypeMappingMode.RETURN_TYPE) } ?: nonExistentType()
} }
} ?: nonExistentType()
} }
private val _isDeprecated: Boolean by lazyPub { private val _isDeprecated: Boolean by lazyPub {
propertySymbol.hasDeprecatedAnnotation(AnnotationUseSiteTarget.FIELD) withPropertySymbol { propertySymbol ->
propertySymbol.hasDeprecatedAnnotation(AnnotationUseSiteTarget.FIELD)
}
} }
override fun isDeprecated(): Boolean = _isDeprecated override fun isDeprecated(): Boolean = _isDeprecated
private val _identifier: PsiIdentifier by lazyPub { private val _identifier: PsiIdentifier by lazyPub {
SymbolLightIdentifier(this, propertySymbol) withPropertySymbol { propertySymbol ->
SymbolLightIdentifier(this@SymbolLightFieldForProperty, propertySymbol)
}
} }
override fun getNameIdentifier(): PsiIdentifier = _identifier override fun getNameIdentifier(): PsiIdentifier = _identifier
@@ -70,53 +84,57 @@ internal class SymbolLightFieldForProperty(
override fun getName(): String = fieldName override fun getName(): String = fieldName
private val _modifierList: PsiModifierList by lazyPub { 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( if (forceStatic) {
isTopLevel = isTopLevel, modifiers.add(PsiModifier.STATIC)
suppressFinal = suppressFinal, }
result = modifiers
)
if (forceStatic) { val visibility = if (takePropertyVisibility) propertySymbol.toPsiVisibilityForMember() else PsiModifier.PRIVATE
modifiers.add(PsiModifier.STATIC) 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 override fun getModifierList(): PsiModifierList = _modifierList
private val _initializerValue by lazyPub { private val _initializerValue: KtConstantValue? by lazyPub {
if (propertySymbol !is KtKotlinPropertySymbol) return@lazyPub null withPropertySymbol { propertySymbol ->
(propertySymbol.initializer as? KtConstantInitializerValue)?.constant if (propertySymbol !is KtKotlinPropertySymbol) return@withPropertySymbol null
(propertySymbol.initializer as? KtConstantInitializerValue)?.constant
}
} }
private val _initializer by lazyPub { private val _initializer by lazyPub {
@@ -127,24 +145,38 @@ internal class SymbolLightFieldForProperty(
private val _constantValue by lazyPub { private val _constantValue by lazyPub {
_initializerValue?.value?.takeIf { _initializerValue?.value?.takeIf {
// val => final withPropertySymbol { propertySymbol ->
propertySymbol.isVal && // val => final
// NB: not as?, since _initializerValue already checks that propertySymbol.isVal &&
(propertySymbol as KtKotlinPropertySymbol).isConst && // NB: not as?, since _initializerValue already checks that
// javac rejects all non-primitive and non String constants (propertySymbol as KtKotlinPropertySymbol).isConst &&
(propertySymbol.returnType.isPrimitive || propertySymbol.returnType.isString) // javac rejects all non-primitive and non String constants
(propertySymbol.returnType.isPrimitive || propertySymbol.returnType.isString)
}
} }
} }
override fun computeConstantValue(): Any? = _constantValue override fun computeConstantValue(): Any? = _constantValue
override fun equals(other: Any?): Boolean = override fun equals(other: Any?): Boolean {
this === other || if (this === other) return true
(other is SymbolLightFieldForProperty && if (other !is SymbolLightFieldForProperty) return false
kotlinOrigin == other.kotlinOrigin && if (kotlinOrigin != null) {
propertySymbol == other.propertySymbol) 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
}
} }