[SLC] implement lazy calculation for modifiers

and fix some annotations

^KTIJ-23783 Fixed
This commit is contained in:
Dmitrii Gridin
2022-12-01 19:44:09 +01:00
committed by Space Team
parent e2082fb0d7
commit 856d272ca4
31 changed files with 516 additions and 241 deletions
@@ -33,8 +33,10 @@ import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_CLASS_ID
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
import org.jetbrains.kotlin.resolve.inline.INLINE_ONLY_ANNOTATION_FQ_NAME
internal fun KtAnnotatedSymbol.hasJvmSyntheticAnnotation(annotationUseSiteTarget: AnnotationUseSiteTarget? = null): Boolean =
hasAnnotation(JVM_SYNTHETIC_ANNOTATION_CLASS_ID, annotationUseSiteTarget)
internal fun KtAnnotatedSymbol.hasJvmSyntheticAnnotation(
annotationUseSiteTarget: AnnotationUseSiteTarget? = null,
strictUseSite: Boolean = true,
): Boolean = hasAnnotation(JVM_SYNTHETIC_ANNOTATION_CLASS_ID, annotationUseSiteTarget, strictUseSite)
internal fun KtFileSymbol.hasJvmMultifileClassAnnotation(): Boolean =
hasAnnotation(JVM_MULTIFILE_CLASS_ID, AnnotationUseSiteTarget.FILE)
@@ -54,14 +56,16 @@ internal fun KtAnnotatedSymbol.getJvmNameFromAnnotation(annotationUseSiteTarget:
context(KtAnalysisSession)
internal fun isHiddenByDeprecation(
symbol: KtAnnotatedSymbol,
annotationUseSiteTarget: AnnotationUseSiteTarget? = null
annotationUseSiteTarget: AnnotationUseSiteTarget? = null,
): Boolean {
return symbol.getDeprecationStatus(annotationUseSiteTarget)?.deprecationLevel == DeprecationLevelValue.HIDDEN
}
context(KtAnalysisSession)
internal fun KtAnnotatedSymbol.isHiddenOrSynthetic(annotationUseSiteTarget: AnnotationUseSiteTarget? = null) =
isHiddenByDeprecation(this, annotationUseSiteTarget) || hasJvmSyntheticAnnotation(annotationUseSiteTarget)
internal fun KtAnnotatedSymbol.isHiddenOrSynthetic(
annotationUseSiteTarget: AnnotationUseSiteTarget? = null,
strictUseSite: Boolean = true,
) = isHiddenByDeprecation(this, annotationUseSiteTarget) || hasJvmSyntheticAnnotation(annotationUseSiteTarget, strictUseSite)
internal fun KtAnnotatedSymbol.hasJvmFieldAnnotation(): Boolean =
hasAnnotation(JVM_FIELD_ANNOTATION_CLASS_ID, null)
@@ -69,27 +73,38 @@ internal fun KtAnnotatedSymbol.hasJvmFieldAnnotation(): Boolean =
internal fun KtAnnotatedSymbol.hasPublishedApiAnnotation(annotationUseSiteTarget: AnnotationUseSiteTarget? = null): Boolean =
hasAnnotation(StandardClassIds.Annotations.PublishedApi, annotationUseSiteTarget)
internal fun KtAnnotatedSymbol.hasDeprecatedAnnotation(annotationUseSiteTarget: AnnotationUseSiteTarget? = null): Boolean =
hasAnnotation(StandardClassIds.Annotations.Deprecated, annotationUseSiteTarget)
internal fun KtAnnotatedSymbol.hasDeprecatedAnnotation(
annotationUseSiteTarget: AnnotationUseSiteTarget? = null,
strictUseSite: Boolean = true,
): Boolean = hasAnnotation(StandardClassIds.Annotations.Deprecated, annotationUseSiteTarget, strictUseSite)
internal fun KtAnnotatedSymbol.hasJvmOverloadsAnnotation(): Boolean =
hasAnnotation(JVM_OVERLOADS_CLASS_ID, null)
internal fun KtAnnotatedSymbol.hasJvmOverloadsAnnotation(): Boolean = hasAnnotation(JVM_OVERLOADS_CLASS_ID, null)
internal fun KtAnnotatedSymbol.hasJvmStaticAnnotation(annotationUseSiteTarget: AnnotationUseSiteTarget? = null): Boolean =
hasAnnotation(JVM_STATIC_ANNOTATION_CLASS_ID, annotationUseSiteTarget)
internal fun KtAnnotatedSymbol.hasJvmStaticAnnotation(
annotationUseSiteTarget: AnnotationUseSiteTarget? = null,
strictUseSite: Boolean = true,
): Boolean = hasAnnotation(JVM_STATIC_ANNOTATION_CLASS_ID, annotationUseSiteTarget, strictUseSite)
internal fun KtAnnotatedSymbol.hasInlineOnlyAnnotation(): Boolean =
hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME, null)
internal fun KtAnnotatedSymbol.hasAnnotation(classId: ClassId, annotationUseSiteTarget: AnnotationUseSiteTarget?): Boolean =
annotations.any {
it.useSiteTarget == annotationUseSiteTarget && it.classId == classId
}
internal fun KtAnnotatedSymbol.hasAnnotation(
classId: ClassId,
annotationUseSiteTarget: AnnotationUseSiteTarget?,
strictUseSite: Boolean = true,
): Boolean = annotations.any {
val useSiteTarget = it.useSiteTarget
(useSiteTarget == annotationUseSiteTarget || !strictUseSite && useSiteTarget == null) && it.classId == classId
}
internal fun KtAnnotatedSymbol.hasAnnotation(fqName: FqName, annotationUseSiteTarget: AnnotationUseSiteTarget?): Boolean =
annotations.any {
it.useSiteTarget == annotationUseSiteTarget && it.classId?.asSingleFqName() == fqName
}
internal fun KtAnnotatedSymbol.hasAnnotation(
fqName: FqName,
annotationUseSiteTarget: AnnotationUseSiteTarget?,
strictUseSite: Boolean = true,
): Boolean = annotations.any {
val useSiteTarget = it.useSiteTarget
(useSiteTarget == annotationUseSiteTarget || !strictUseSite && useSiteTarget == null) && it.classId?.asSingleFqName() == fqName
}
internal fun NullabilityType.computeNullabilityAnnotation(parent: PsiModifierList): SymbolLightSimpleAnnotation? {
return when (this) {
@@ -5,7 +5,10 @@
package org.jetbrains.kotlin.light.classes.symbol.classes
import com.intellij.psi.*
import com.intellij.psi.PsiManager
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiModifierList
import com.intellij.psi.PsiReferenceList
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
@@ -25,13 +28,11 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.light.classes.symbol.NullabilityType
import org.jetbrains.kotlin.light.classes.symbol.annotations.computeAnnotations
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmFieldAnnotation
import org.jetbrains.kotlin.light.classes.symbol.computeSimpleModality
import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightField
import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForEnumEntry
import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForObject
import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightSimpleMethod
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList
import org.jetbrains.kotlin.light.classes.symbol.toPsiVisibilityForClass
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
@@ -43,7 +44,6 @@ import org.jetbrains.kotlin.resolve.DataClassResolver
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
import org.jetbrains.kotlin.util.OperatorNameConventions.EQUALS
import org.jetbrains.kotlin.util.OperatorNameConventions.TO_STRING
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
internal open class SymbolLightClassForClassOrObject : SymbolLightClassForNamedClassLike {
@@ -86,30 +86,19 @@ internal open class SymbolLightClassForClassOrObject : SymbolLightClassForNamedC
)
private val _modifierList: PsiModifierList? by lazyPub {
val lazyModifiers = lazyPub {
withClassOrObjectSymbol { classOrObjectSymbol ->
buildSet {
add(classOrObjectSymbol.toPsiVisibilityForClass(isNested = !isTopLevel))
addIfNotNull(classOrObjectSymbol.computeSimpleModality())
if (!isTopLevel && !classOrObjectSymbol.isInner) {
add(PsiModifier.STATIC)
}
}
}
}
SymbolLightClassModifierList(
containingDeclaration = this,
lazyModifiers = lazyModifiers,
) { modifierList ->
withClassOrObjectSymbol { classOrObjectSymbol ->
classOrObjectSymbol.computeAnnotations(
modifierList = modifierList,
nullability = NullabilityType.Unknown,
annotationUseSiteTarget = null,
)
}
}
lazyModifiersComputer = ::computeModifiers,
annotationsComputer = { modifierList ->
withClassOrObjectSymbol { classOrObjectSymbol ->
classOrObjectSymbol.computeAnnotations(
modifierList = modifierList,
nullability = NullabilityType.Unknown,
annotationUseSiteTarget = null,
)
}
},
)
}
override fun getModifierList(): PsiModifierList? = _modifierList
@@ -48,7 +48,8 @@ internal class SymbolLightClassForEnumEntry(
SymbolLightClassModifierList(
containingDeclaration = this,
staticModifiers = setOf(PsiModifier.STATIC, PsiModifier.FINAL),
) { emptyList() }
annotationsComputer = null,
)
}
override fun getModifierList(): PsiModifierList = _modifierList
@@ -37,7 +37,8 @@ internal class SymbolLightClassForInterfaceDefaultImpls(private val containingCl
SymbolLightClassModifierList(
containingDeclaration = this,
staticModifiers = setOf(PsiModifier.PUBLIC, PsiModifier.STATIC, PsiModifier.FINAL),
) { emptyList() }
annotationsComputer = null,
)
}
override fun getModifierList(): PsiModifierList? = _modifierList
@@ -19,8 +19,9 @@ import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.light.classes.symbol.NullabilityType
import org.jetbrains.kotlin.light.classes.symbol.annotations.computeAnnotations
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.LazyModifiersBox
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList
import org.jetbrains.kotlin.light.classes.symbol.toPsiVisibilityForClass
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.with
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtClassOrObject
@@ -65,22 +66,10 @@ internal abstract class SymbolLightClassForInterfaceOrAnnotationClass : SymbolLi
)
private val _modifierList: PsiModifierList? by lazyPub {
val staticModifiers = setOf(PsiModifier.ABSTRACT)
val lazyModifiers = lazyPub {
withClassOrObjectSymbol { classOrObjectSymbol ->
buildSet {
add(classOrObjectSymbol.toPsiVisibilityForClass(isNested = !isTopLevel))
if (!isTopLevel && !classOrObjectSymbol.isInner) {
add(PsiModifier.STATIC)
}
}
}
}
SymbolLightClassModifierList(
containingDeclaration = this,
staticModifiers = staticModifiers,
lazyModifiers = lazyModifiers,
initialValue = LazyModifiersBox.MODALITY_MODIFIERS_MAP.with(PsiModifier.ABSTRACT),
lazyModifiersComputer = ::computeModifiers
) { modifierList ->
withClassOrObjectSymbol { classOrObjectSymbol ->
classOrObjectSymbol.computeAnnotations(
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.light.classes.symbol.classes
import com.intellij.psi.PsiManager
import com.intellij.psi.PsiModifier
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtKotlinPropertySymbol
@@ -15,11 +16,17 @@ import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.lexer.KtTokens
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.fields.SymbolLightFieldForObject
import org.jetbrains.kotlin.light.classes.symbol.fields.SymbolLightFieldForProperty
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.LazyModifiersBox
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.with
import org.jetbrains.kotlin.light.classes.symbol.toPsiVisibilityForClass
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.util.javaslang.ImmutableHashMap
import org.jetbrains.kotlin.util.javaslang.ImmutableMap
import org.jetbrains.kotlin.utils.addToStdlib.applyIf
abstract class SymbolLightClassForNamedClassLike : SymbolLightClassForClassLike<KtNamedClassOrObjectSymbol> {
@@ -78,6 +85,9 @@ abstract class SymbolLightClassForNamedClassLike : SymbolLightClassForClassLike<
private val KtPropertySymbol.isConst: Boolean get() = (this as? KtKotlinPropertySymbol)?.isConst == true
private val KtPropertySymbol.isLateInit: Boolean get() = (this as? KtKotlinPropertySymbol)?.isLateInit == true
private val isInner: Boolean
get() = classOrObjectDeclaration?.hasModifier(KtTokens.INNER_KEYWORD) ?: withClassOrObjectSymbol { it.isInner }
context(KtAnalysisSession)
protected fun addFieldsFromCompanionIfNeeded(
result: MutableList<KtLightField>,
@@ -122,4 +132,19 @@ abstract class SymbolLightClassForNamedClassLike : SymbolLightClassForClassLike<
)
}
}
internal fun computeModifiers(modifier: String): ImmutableMap<String, Boolean>? = when (modifier) {
in LazyModifiersBox.VISIBILITY_MODIFIERS -> {
val visibility = withClassOrObjectSymbol { it.toPsiVisibilityForClass(isNested = !isTopLevel) }
LazyModifiersBox.VISIBILITY_MODIFIERS_MAP.with(visibility)
}
in LazyModifiersBox.MODALITY_MODIFIERS -> LazyModifiersBox.computeSimpleModality(ktModule, classOrObjectSymbolPointer)
PsiModifier.STATIC -> {
val isStatic = !isTopLevel && !isInner
ImmutableHashMap.of(modifier, isStatic)
}
else -> null
}
}
@@ -286,11 +286,15 @@ internal fun SymbolLightClassBase.createPropertyAccessors(
if (declaration.hasJvmFieldAnnotation()) return
fun KtPropertyAccessorSymbol.needToCreateAccessor(siteTarget: AnnotationUseSiteTarget): Boolean {
if (onlyJvmStatic && !hasJvmStaticAnnotation(siteTarget) && !declaration.hasJvmStaticAnnotation()) return false
if (onlyJvmStatic &&
!hasJvmStaticAnnotation(siteTarget, strictUseSite = false) &&
!declaration.hasJvmStaticAnnotation(siteTarget, strictUseSite = false)
) return false
if (declaration.hasReifiedParameters) return false
if (!hasBody && visibility.isPrivateOrPrivateToThis()) return false
if (declaration.isHiddenOrSynthetic(siteTarget)) return false
return !isHiddenOrSynthetic()
return !isHiddenOrSynthetic(siteTarget, strictUseSite = false)
}
val originalElement = declaration.sourcePsiSafe<KtDeclaration>()
@@ -16,12 +16,18 @@ import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.api.symbols.sourcePsiSafe
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.light.classes.symbol.*
import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolLightSimpleAnnotation
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasDeprecatedAnnotation
import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForClassLike
import org.jetbrains.kotlin.light.classes.symbol.compareSymbolPointers
import org.jetbrains.kotlin.light.classes.symbol.isValid
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.LazyModifiersBox
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightMemberModifierList
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.with
import org.jetbrains.kotlin.light.classes.symbol.nonExistentType
import org.jetbrains.kotlin.light.classes.symbol.withSymbol
import org.jetbrains.kotlin.psi.KtObjectDeclaration
import org.jetbrains.kotlin.util.javaslang.ImmutableMap
internal class SymbolLightFieldForObject private constructor(
containingClass: SymbolLightClassForClassLike<*>,
@@ -50,22 +56,20 @@ internal class SymbolLightFieldForObject private constructor(
override fun getName(): String = name
private val _modifierList: PsiModifierList by lazyPub {
val staticModifiers = setOf(PsiModifier.STATIC, PsiModifier.FINAL)
val lazyModifiers = lazyPub {
withObjectDeclarationSymbol { objectSymbol ->
setOf(objectSymbol.toPsiVisibilityForMember())
}
}
SymbolLightMemberModifierList(
containingDeclaration = this,
staticModifiers = staticModifiers,
lazyModifiers = lazyModifiers,
initialValue = LazyModifiersBox.MODALITY_MODIFIERS_MAP.with(PsiModifier.FINAL).with(PsiModifier.STATIC),
lazyModifiersComputer = ::computeModifiers,
) { modifierList ->
listOf(SymbolLightSimpleAnnotation(NotNull::class.java.name, modifierList))
}
}
private fun computeModifiers(modifier: String): ImmutableMap<String, Boolean>? {
if (modifier !in LazyModifiersBox.VISIBILITY_MODIFIERS) return null
return LazyModifiersBox.computeVisibilityForMember(ktModule, objectSymbolPointer)
}
private val _isDeprecated: Boolean by lazyPub {
withObjectDeclarationSymbol { objectSymbol ->
objectSymbol.hasDeprecatedAnnotation()
@@ -25,11 +25,15 @@ 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.modifierLists.LazyModifiersBox
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightMemberModifierList
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.with
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.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.util.javaslang.ImmutableHashMap
import org.jetbrains.kotlin.util.javaslang.ImmutableMap
internal class SymbolLightFieldForProperty private constructor(
private val propertySymbolPointer: KtSymbolPointer<KtPropertySymbol>,
@@ -81,7 +85,7 @@ internal class SymbolLightFieldForProperty private constructor(
private val _isDeprecated: Boolean by lazyPub {
withPropertySymbol { propertySymbol ->
propertySymbol.hasDeprecatedAnnotation(AnnotationUseSiteTarget.FIELD)
propertySymbol.hasDeprecatedAnnotation(AnnotationUseSiteTarget.FIELD, strictUseSite = false)
}
}
@@ -91,46 +95,51 @@ internal class SymbolLightFieldForProperty private constructor(
override fun getName(): String = fieldName
private fun computeLazyModifiers(): Set<String> = withPropertySymbol { propertySymbol ->
buildSet {
val suppressFinal = !propertySymbol.isVal
propertySymbol.computeModalityForMethod(
isTopLevel = isTopLevel,
suppressFinal = suppressFinal,
result = this
)
if (takePropertyVisibility) {
add(propertySymbol.toPsiVisibilityForMember())
private fun computeModifiers(modifier: String): ImmutableMap<String, Boolean>? = when (modifier) {
in LazyModifiersBox.VISIBILITY_MODIFIERS -> LazyModifiersBox.computeVisibilityForMember(ktModule, propertySymbolPointer)
in LazyModifiersBox.MODALITY_MODIFIERS -> {
val modality = withPropertySymbol { propertySymbol ->
if (propertySymbol.isVal) {
PsiModifier.FINAL
} else {
propertySymbol.computeSimpleModality()?.takeIf {
it != PsiModifier.FINAL || isTopLevel && propertySymbol.isDelegatedProperty
}
}
}
if (!suppressFinal) {
add(PsiModifier.FINAL)
}
if (propertySymbol.hasAnnotation(TRANSIENT_ANNOTATION_CLASS_ID, null)) {
add(PsiModifier.TRANSIENT)
}
if (propertySymbol.hasAnnotation(VOLATILE_ANNOTATION_CLASS_ID, null)) {
add(PsiModifier.VOLATILE)
}
LazyModifiersBox.MODALITY_MODIFIERS_MAP.with(modality)
}
PsiModifier.STATIC -> {
val isStatic = forceStatic || isTopLevel
ImmutableHashMap.of(modifier, isStatic)
}
PsiModifier.VOLATILE -> withPropertySymbol { propertySymbol ->
val hasAnnotation = propertySymbol.hasAnnotation(VOLATILE_ANNOTATION_CLASS_ID, null)
ImmutableHashMap.of(modifier, hasAnnotation)
}
PsiModifier.TRANSIENT -> withPropertySymbol { propertySymbol ->
val hasAnnotation = propertySymbol.hasAnnotation(TRANSIENT_ANNOTATION_CLASS_ID, null)
ImmutableHashMap.of(modifier, hasAnnotation)
}
else -> null
}
private val _modifierList: PsiModifierList by lazyPub {
val staticModifiers = setOfNotNull(
PsiModifier.PRIVATE.takeUnless { takePropertyVisibility },
PsiModifier.STATIC.takeIf { forceStatic },
)
val lazyModifiers = lazyPub { computeLazyModifiers() }
val initializerValue = if (takePropertyVisibility) {
ImmutableHashMap.empty()
} else {
LazyModifiersBox.VISIBILITY_MODIFIERS_MAP.with(PsiModifier.PRIVATE)
}
SymbolLightMemberModifierList(
containingDeclaration = this,
staticModifiers = staticModifiers,
lazyModifiers = lazyModifiers,
initialValue = initializerValue,
lazyModifiersComputer = ::computeModifiers,
) { modifierList ->
withPropertySymbol { propertySymbol ->
val nullability = if (!(propertySymbol is KtKotlinPropertySymbol && propertySymbol.isLateInit)) {
@@ -27,7 +27,9 @@ import org.jetbrains.kotlin.light.classes.symbol.annotations.getJvmNameFromAnnot
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasDeprecatedAnnotation
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmStaticAnnotation
import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.LazyModifiersBox
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightMemberModifierList
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.with
import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightParameterList
import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightSetterParameter
import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightTypeParameterList
@@ -37,6 +39,8 @@ import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtPropertyAccessor
import org.jetbrains.kotlin.util.javaslang.ImmutableHashMap
import org.jetbrains.kotlin.util.javaslang.ImmutableMap
import org.jetbrains.kotlin.utils.addToStdlib.ifTrue
internal class SymbolLightAccessorMethod private constructor(
@@ -153,37 +157,41 @@ internal class SymbolLightAccessorMethod private constructor(
annotationsFromProperty + annotationsFromAccessor
}
private fun computeModifiers(): Set<String> = analyzeForLightClasses(ktModule) {
val propertySymbol = propertySymbol()
val propertyAccessorSymbol = propertyAccessorSymbol()
val modifiers = mutableSetOf<String>()
private fun computeModifiers(modifier: String): ImmutableMap<String, Boolean>? {
return when (modifier) {
in LazyModifiersBox.VISIBILITY_MODIFIERS -> LazyModifiersBox.computeVisibilityForMember(ktModule, propertyAccessorSymbolPointer)
propertySymbol.computeModalityForMethod(
isTopLevel = isTopLevel,
suppressFinal = containingClass.isInterface,
result = modifiers,
)
in LazyModifiersBox.MODALITY_MODIFIERS -> {
if (containingClass.isInterface) {
return LazyModifiersBox.MODALITY_MODIFIERS_MAP.with(PsiModifier.ABSTRACT)
}
modifiers.add(propertyAccessorSymbol.toPsiVisibilityForMember())
LazyModifiersBox.computeSimpleModality(ktModule, containingPropertySymbolPointer)
}
if (!suppressStatic &&
(propertySymbol.hasJvmStaticAnnotation() || propertyAccessorSymbol.hasJvmStaticAnnotation(accessorSite))
) {
modifiers.add(PsiModifier.STATIC)
PsiModifier.STATIC -> {
val isStatic = if (suppressStatic) {
false
} else {
isTopLevel || hasJvmStaticAnnotation()
}
ImmutableHashMap.of(modifier, isStatic)
}
else -> null
}
}
modifiers
private fun hasJvmStaticAnnotation(): Boolean = analyzeForLightClasses(ktModule) {
propertySymbol().hasJvmStaticAnnotation(accessorSite, strictUseSite = false) ||
propertyAccessorSymbol().hasJvmStaticAnnotation(accessorSite, strictUseSite = false)
}
private val _modifierList: PsiModifierList by lazyPub {
val staticModifiers = setOfNotNull(
PsiModifier.ABSTRACT.takeIf { containingClass.isInterface },
)
SymbolLightMemberModifierList(
containingDeclaration = this,
staticModifiers = staticModifiers,
lazyModifiers = lazyPub { computeModifiers() },
lazyModifiersComputer = ::computeModifiers,
annotationsComputer = ::computeAnnotations,
)
}
@@ -194,7 +202,8 @@ internal class SymbolLightAccessorMethod private constructor(
private val _isDeprecated: Boolean by lazyPub {
analyzeForLightClasses(ktModule) {
propertySymbol().hasDeprecatedAnnotation(accessorSite)
propertySymbol().hasDeprecatedAnnotation(accessorSite, strictUseSite = false) ||
propertyAccessorSymbol().hasDeprecatedAnnotation(accessorSite, strictUseSite = false)
}
}
@@ -13,8 +13,11 @@ import org.jetbrains.kotlin.light.classes.symbol.NullabilityType
import org.jetbrains.kotlin.light.classes.symbol.annotations.computeAnnotations
import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase
import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassForEnumEntry
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.LazyModifiersBox
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightMemberModifierList
import org.jetbrains.kotlin.light.classes.symbol.toPsiVisibilityForMember
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.with
import org.jetbrains.kotlin.util.javaslang.ImmutableHashMap
import org.jetbrains.kotlin.util.javaslang.ImmutableMap
import java.util.*
internal class SymbolLightConstructor(
@@ -42,24 +45,16 @@ internal class SymbolLightConstructor(
override fun getTypeParameters(): Array<PsiTypeParameter> = PsiTypeParameter.EMPTY_ARRAY
private val _modifierList: PsiModifierList by lazyPub {
val (staticModifiers, lazyModifiers) = if (containingClass is SymbolLightClassForEnumEntry) {
setOf(PsiModifier.PACKAGE_LOCAL) to null
val initialValue = if (containingClass is SymbolLightClassForEnumEntry) {
LazyModifiersBox.VISIBILITY_MODIFIERS_MAP.with(PsiModifier.PACKAGE_LOCAL)
} else {
emptySet<String>() to 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.
withFunctionSymbol { constructorSymbol ->
setOf(constructorSymbol.toPsiVisibilityForMember())
}
}
ImmutableHashMap.empty()
}
SymbolLightMemberModifierList(
containingDeclaration = this,
staticModifiers = staticModifiers,
lazyModifiers = lazyModifiers,
initialValue = initialValue,
lazyModifiersComputer = ::computeModifiers,
) { modifierList ->
withFunctionSymbol { constructorSymbol ->
constructorSymbol.computeAnnotations(
@@ -71,6 +66,11 @@ internal class SymbolLightConstructor(
}
}
private fun computeModifiers(modifier: String): ImmutableMap<String, Boolean>? {
if (modifier !in LazyModifiersBox.VISIBILITY_MODIFIERS) return null
return LazyModifiersBox.computeVisibilityForMember(ktModule, functionSymbolPointer)
}
override fun getModifierList(): PsiModifierList = _modifierList
override fun getReturnType(): PsiType? = null
@@ -36,7 +36,7 @@ internal class SymbolLightNoArgConstructor(
override fun isDeprecated(): Boolean = false
private val _modifierList: PsiModifierList by lazyPub {
SymbolLightMemberModifierList(containingDeclaration = this, staticModifiers = setOf(visibility)) { emptyList() }
SymbolLightMemberModifierList(containingDeclaration = this, staticModifiers = setOf(visibility), annotationsComputer = null)
}
override fun getModifierList(): PsiModifierList = _modifierList
@@ -12,16 +12,21 @@ import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.api.types.KtTypeMappingMode
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.light.classes.symbol.*
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.hasInlineOnlyAnnotation
import org.jetbrains.kotlin.light.classes.symbol.annotations.hasJvmStaticAnnotation
import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.LazyModifiersBox
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightMemberModifierList
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.with
import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightTypeParameterList
import org.jetbrains.kotlin.name.JvmNames.STRICTFP_ANNOTATION_CLASS_ID
import org.jetbrains.kotlin.name.JvmNames.SYNCHRONIZED_ANNOTATION_CLASS_ID
import org.jetbrains.kotlin.util.javaslang.ImmutableHashMap
import org.jetbrains.kotlin.util.javaslang.ImmutableMap
import org.jetbrains.kotlin.utils.addToStdlib.ifTrue
import java.util.*
@@ -85,48 +90,67 @@ internal class SymbolLightSimpleMethod(
)
}
context(KtAnalysisSession)
private fun computeModifiers(functionSymbol: KtFunctionSymbol): Set<String> {
if (functionSymbol.hasInlineOnlyAnnotation()) return setOf(PsiModifier.FINAL, PsiModifier.PRIVATE)
val modifiers = mutableSetOf<String>()
functionSymbol.computeModalityForMethod(
isTopLevel = isTopLevel,
suppressFinal = containingClass.isInterface,
result = modifiers
)
if (functionSymbol.isExternal) {
modifiers.add(PsiModifier.NATIVE)
private fun computeModifiers(modifier: String): ImmutableMap<String, Boolean>? = when (modifier) {
in LazyModifiersBox.MODALITY_MODIFIERS -> {
ifInlineOnly { return modifiersForInlineOnlyCase() }
val modality = if (isTopLevel) PsiModifier.FINAL else withFunctionSymbol { it.computeSimpleModality() }
LazyModifiersBox.MODALITY_MODIFIERS_MAP.with(modality)
}
modifiers.add(functionSymbol.toPsiVisibilityForMember())
if (!suppressStatic && functionSymbol.hasJvmStaticAnnotation()) {
modifiers.add(PsiModifier.STATIC)
in LazyModifiersBox.VISIBILITY_MODIFIERS -> {
ifInlineOnly { return modifiersForInlineOnlyCase() }
LazyModifiersBox.computeVisibilityForMember(ktModule, functionSymbolPointer)
}
if (functionSymbol.hasAnnotation(STRICTFP_ANNOTATION_CLASS_ID, null)) {
modifiers.add(PsiModifier.STRICTFP)
PsiModifier.STATIC -> {
ifInlineOnly { return null }
val isStatic = if (suppressStatic) {
false
} else {
isTopLevel || withFunctionSymbol { it.hasJvmStaticAnnotation() }
}
ImmutableHashMap.of(modifier, isStatic)
}
if (functionSymbol.hasAnnotation(SYNCHRONIZED_ANNOTATION_CLASS_ID, null)) {
modifiers.add(PsiModifier.SYNCHRONIZED)
PsiModifier.NATIVE -> {
ifInlineOnly { return null }
val isExternal = functionDeclaration?.hasModifier(KtTokens.EXTERNAL_KEYWORD) ?: withFunctionSymbol { it.isExternal }
ImmutableHashMap.of(modifier, isExternal)
}
return modifiers
PsiModifier.STRICTFP -> {
ifInlineOnly { return null }
val hasAnnotation = withFunctionSymbol { it.hasAnnotation(STRICTFP_ANNOTATION_CLASS_ID, null) }
ImmutableHashMap.of(modifier, hasAnnotation)
}
PsiModifier.SYNCHRONIZED -> {
ifInlineOnly { return null }
val hasAnnotation = withFunctionSymbol { it.hasAnnotation(SYNCHRONIZED_ANNOTATION_CLASS_ID, null) }
ImmutableHashMap.of(modifier, hasAnnotation)
}
else -> null
}
private val _modifierList: PsiModifierList by lazyPub {
val lazyModifiers = lazyPub {
withFunctionSymbol { functionSymbol ->
computeModifiers(functionSymbol)
}
private inline fun ifInlineOnly(action: () -> Unit) {
if (hasInlineOnlyAnnotation) {
action()
}
}
private fun modifiersForInlineOnlyCase(): ImmutableMap<String, Boolean> =
LazyModifiersBox.MODALITY_MODIFIERS_MAP.merge(LazyModifiersBox.VISIBILITY_MODIFIERS_MAP)
.with(PsiModifier.FINAL)
.with(PsiModifier.PRIVATE)
private val hasInlineOnlyAnnotation: Boolean by lazyPub { withFunctionSymbol { it.hasInlineOnlyAnnotation() } }
private val _modifierList: PsiModifierList by lazyPub {
SymbolLightMemberModifierList(
containingDeclaration = this,
lazyModifiers = lazyModifiers,
lazyModifiersComputer = ::computeModifiers,
annotationsComputer = ::computeAnnotations,
)
}
@@ -10,10 +10,19 @@ import com.intellij.psi.PsiModifierList
import com.intellij.psi.PsiModifierListOwner
import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.psi.KtModifierListOwner
import org.jetbrains.kotlin.util.javaslang.ImmutableHashMap
internal class SymbolLightClassModifierList<T : KtLightElement<KtModifierListOwner, PsiModifierListOwner>>(
containingDeclaration: T,
staticModifiers: Set<String> = emptySet(),
lazyModifiers: Lazy<Set<String>>? = null,
annotationsComputer: (PsiModifierList) -> List<PsiAnnotation>,
) : SymbolLightModifierList<T>(containingDeclaration, staticModifiers, lazyModifiers, annotationsComputer)
internal class SymbolLightClassModifierList<T : KtLightElement<KtModifierListOwner, PsiModifierListOwner>> : SymbolLightModifierList<T> {
constructor(
containingDeclaration: T,
initialValue: ImmutableHashMap<String, Boolean> = ImmutableHashMap.empty(),
lazyModifiersComputer: LazyModifiersComputer,
annotationsComputer: ((PsiModifierList) -> List<PsiAnnotation>)?,
) : super(containingDeclaration, initialValue, lazyModifiersComputer, annotationsComputer)
constructor(
containingDeclaration: T,
staticModifiers: Set<String>,
annotationsComputer: ((PsiModifierList) -> List<PsiAnnotation>)?,
) : super(containingDeclaration, staticModifiers, annotationsComputer)
}
@@ -14,13 +14,22 @@ import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightMethodBase
import org.jetbrains.kotlin.psi.KtModifierList
import org.jetbrains.kotlin.psi.KtPropertyAccessor
import org.jetbrains.kotlin.psi.psiUtil.hasBody
import org.jetbrains.kotlin.util.javaslang.ImmutableHashMap
internal class SymbolLightMemberModifierList<T : KtLightMember<*>> : SymbolLightModifierList<T> {
constructor(
containingDeclaration: T,
initialValue: ImmutableHashMap<String, Boolean> = ImmutableHashMap.empty(),
lazyModifiersComputer: LazyModifiersComputer,
annotationsComputer: ((PsiModifierList) -> List<PsiAnnotation>)?,
) : super(containingDeclaration, initialValue, lazyModifiersComputer, annotationsComputer)
constructor(
containingDeclaration: T,
staticModifiers: Set<String>,
annotationsComputer: ((PsiModifierList) -> List<PsiAnnotation>)?,
) : super(containingDeclaration, staticModifiers, annotationsComputer)
internal class SymbolLightMemberModifierList<T : KtLightMember<*>>(
containingDeclaration: T,
staticModifiers: Set<String> = emptySet(),
lazyModifiers: Lazy<Set<String>>? = null,
annotationsComputer: (PsiModifierList) -> List<PsiAnnotation>,
) : SymbolLightModifierList<T>(containingDeclaration, staticModifiers, lazyModifiers, annotationsComputer) {
override fun hasModifierProperty(name: String): Boolean = when {
name == PsiModifier.ABSTRACT && isImplementationInInterface() -> false
// Pretend this method behaves like a `default` method
@@ -5,26 +5,58 @@
package org.jetbrains.kotlin.light.classes.symbol.modifierLists
import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiModifierList
import com.intellij.psi.PsiModifierListOwner
import com.intellij.psi.*
import com.intellij.util.IncorrectOperationException
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithModality
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithVisibility
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.asJava.classes.cannotModify
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation
import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.asJava.elements.KtLightElementBase
import org.jetbrains.kotlin.light.classes.symbol.invalidAccess
import org.jetbrains.kotlin.light.classes.symbol.*
import org.jetbrains.kotlin.psi.KtModifierList
import org.jetbrains.kotlin.psi.KtModifierListOwner
import org.jetbrains.kotlin.util.javaslang.ImmutableHashMap
import org.jetbrains.kotlin.util.javaslang.ImmutableMap
import org.jetbrains.kotlin.util.javaslang.getOrNull
import org.jetbrains.kotlin.utils.keysToMap
import java.util.concurrent.atomic.AtomicReference
internal open class SymbolLightModifierList<out T : KtLightElement<KtModifierListOwner, PsiModifierListOwner>> :
KtLightElementBase, PsiModifierList, KtLightElement<KtModifierList, PsiModifierListOwner> {
protected val owner: T
private val staticModifiers: Set<String>?
private val lazyModifiersBox: LazyModifiersBox?
private val lazyAnnotations: Lazy<List<PsiAnnotation>>?
constructor(
owner: T,
initialValue: ImmutableHashMap<String, Boolean>,
lazyModifiersComputer: LazyModifiersComputer,
annotationsComputer: ((PsiModifierList) -> List<PsiAnnotation>)?,
) : super(owner) {
this.owner = owner
this.lazyAnnotations = annotationsComputer?.let { lazyPub { annotationsComputer(this) } }
this.lazyModifiersBox = LazyModifiersBox(initialValue, lazyModifiersComputer)
this.staticModifiers = null
}
constructor(
owner: T,
staticModifiers: Set<String>,
annotationsComputer: ((PsiModifierList) -> List<PsiAnnotation>)?,
) : super(owner) {
this.owner = owner
this.lazyAnnotations = annotationsComputer?.let { lazyPub { annotationsComputer(this) } }
this.lazyModifiersBox = null
this.staticModifiers = staticModifiers
}
internal abstract class SymbolLightModifierList<out T : KtLightElement<KtModifierListOwner, PsiModifierListOwner>>(
protected val owner: T,
private val staticModifiers: Set<String>,
private val lazyModifiers: Lazy<Set<String>>?,
annotationsComputer: (PsiModifierList) -> List<PsiAnnotation>,
) : KtLightElementBase(owner), PsiModifierList, KtLightElement<KtModifierList, PsiModifierListOwner> {
override val kotlinOrigin: KtModifierList? get() = owner.kotlinOrigin?.modifierList
override fun getParent() = owner
override fun setModifierProperty(name: String, value: Boolean) = cannotModify()
@@ -37,17 +69,69 @@ internal abstract class SymbolLightModifierList<out T : KtLightElement<KtModifie
override val givenAnnotations: List<KtLightAbstractAnnotation> get() = invalidAccess()
private val lazyAnnotations: Lazy<List<PsiAnnotation>> = lazyPub {
annotationsComputer(this)
}
override fun getAnnotations(): Array<out PsiAnnotation> = lazyAnnotations.value.toTypedArray()
override fun getAnnotations(): Array<out PsiAnnotation> = lazyAnnotations?.value?.toTypedArray().orEmpty()
override fun findAnnotation(qualifiedName: String): PsiAnnotation? =
lazyAnnotations.value.firstOrNull { it.qualifiedName == qualifiedName }
lazyAnnotations?.value?.firstOrNull { it.qualifiedName == qualifiedName }
override fun equals(other: Any?): Boolean = this === other
override fun hashCode(): Int = kotlinOrigin.hashCode()
override fun hasExplicitModifier(name: String) = hasModifierProperty(name)
override fun hasModifierProperty(name: String): Boolean = name in staticModifiers || lazyModifiers?.value?.contains(name) == true
override fun hasModifierProperty(name: String): Boolean =
staticModifiers?.contains(name) == true || lazyModifiersBox?.hasModifier(name) == true
}
internal typealias LazyModifiersComputer = (modifier: String) -> ImmutableMap<String, Boolean>?
@Suppress("NOTHING_TO_INLINE")
internal inline fun ImmutableHashMap<String, Boolean>.with(modifier: String?): ImmutableHashMap<String, Boolean> {
return modifier?.let { put(modifier, true) } ?: this
}
internal class LazyModifiersBox(
initialValue: ImmutableHashMap<String, Boolean>,
private val computer: LazyModifiersComputer,
) {
private val modifiersMapReference: AtomicReference<ImmutableHashMap<String, Boolean>> = AtomicReference(initialValue)
fun hasModifier(modifier: String): Boolean {
modifiersMapReference.get().getOrNull(modifier)?.let { return it }
val newValues = computer(modifier) ?: ImmutableHashMap.of(modifier, false)
do {
val currentMap = modifiersMapReference.get()
val newMap = currentMap.merge(newValues)
} while (!modifiersMapReference.compareAndSet(currentMap, newMap))
return newValues.getOrNull(modifier) ?: error("Inconsistent state: $modifier")
}
companion object {
internal val VISIBILITY_MODIFIERS = setOf(PsiModifier.PUBLIC, PsiModifier.PACKAGE_LOCAL, PsiModifier.PROTECTED, PsiModifier.PRIVATE)
internal val VISIBILITY_MODIFIERS_MAP = ImmutableHashMap.ofAll(VISIBILITY_MODIFIERS.keysToMap { false })
internal val MODALITY_MODIFIERS = setOf(PsiModifier.FINAL, PsiModifier.ABSTRACT)
internal val MODALITY_MODIFIERS_MAP = ImmutableHashMap.ofAll(MODALITY_MODIFIERS.keysToMap { false })
internal fun computeVisibilityForMember(
ktModule: KtModule,
declarationPointer: KtSymbolPointer<KtSymbolWithVisibility>,
): ImmutableMap<String, Boolean> {
val visibility = analyzeForLightClasses(ktModule) {
declarationPointer.restoreSymbolOrThrowIfDisposed().toPsiVisibilityForMember()
}
return VISIBILITY_MODIFIERS_MAP.with(visibility)
}
internal fun computeSimpleModality(
ktModule: KtModule,
declarationPointer: KtSymbolPointer<KtSymbolWithModality>,
): ImmutableMap<String, Boolean> {
val visibility = analyzeForLightClasses(ktModule) {
declarationPointer.restoreSymbolOrThrowIfDisposed().computeSimpleModality()
}
return MODALITY_MODIFIERS_MAP.with(visibility)
}
}
}
@@ -27,7 +27,10 @@ internal class SymbolLightParameter(
override fun getModifierList(): PsiModifierList = _modifierList
private val _modifierList: PsiModifierList by lazyPub {
SymbolLightClassModifierList(containingDeclaration = this) { modifierList ->
SymbolLightClassModifierList(
containingDeclaration = this,
staticModifiers = emptySet(),
) { modifierList ->
val annotationSite = isConstructorParameterSymbol.ifTrue {
AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER
}
@@ -68,7 +68,10 @@ internal class SymbolLightParameterForReceiver private constructor(
override fun getModifierList(): PsiModifierList = _modifierList
private val _modifierList: PsiModifierList by lazyPub {
SymbolLightClassModifierList(containingDeclaration = this) { modifierList ->
SymbolLightClassModifierList(
containingDeclaration = this,
staticModifiers = emptySet(),
) { modifierList ->
withReceiverSymbol { receiver ->
buildList {
receiver.type.nullabilityType.computeNullabilityAnnotation(modifierList)?.let(::add)
@@ -41,7 +41,10 @@ internal class SymbolLightSetterParameter(
override fun getModifierList(): PsiModifierList = _modifierList
private val _modifierList: PsiModifierList by lazyPub {
SymbolLightClassModifierList(containingDeclaration = this) { modifierList ->
SymbolLightClassModifierList(
containingDeclaration = this,
staticModifiers = emptySet(),
) { modifierList ->
analyzeForLightClasses(ktModule) {
val annotationsFromSetter = parameterSymbolPointer.restoreSymbolOrThrowIfDisposed().computeAnnotations(
modifierList = modifierList,
@@ -50,7 +50,10 @@ internal class SymbolLightSuspendContinuationParameter(
override fun getModifierList(): PsiModifierList = _modifierList
private val _modifierList: PsiModifierList by lazyPub {
SymbolLightClassModifierList(containingDeclaration = this) { modifierList ->
SymbolLightClassModifierList(
containingDeclaration = this,
staticModifiers = emptySet(),
) { modifierList ->
if (withFunctionSymbol { it.visibility.isPrivateOrPrivateToThis() })
emptyList()
else
@@ -12,9 +12,6 @@ import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.annotations.*
import org.jetbrains.kotlin.analysis.api.base.KtConstantValue
import org.jetbrains.kotlin.analysis.api.components.DefaultTypeClassIds
import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithModality
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithTypeParameters
@@ -76,37 +73,11 @@ internal fun KtSymbolWithModality.computeSimpleModality(): String? = when (modal
Modality.OPEN -> null
}
internal fun KtSymbolWithModality.computeModalityForMethod(
isTopLevel: Boolean,
suppressFinal: Boolean,
result: MutableSet<String>
) {
require(this !is KtClassLikeSymbol)
computeSimpleModality()?.run {
if (this != PsiModifier.FINAL || !suppressFinal) {
result.add(this)
}
}
if (isTopLevel) {
result.add(PsiModifier.STATIC)
val needFinalModifier = when (this) {
is KtPropertySymbol -> isDelegatedProperty || isVal
else -> true
}
if (needFinalModifier) {
result.add(PsiModifier.FINAL)
}
}
}
internal fun KtSymbolWithVisibility.toPsiVisibilityForMember(): String = visibility.toPsiVisibilityForMember()
internal fun KtSymbolWithVisibility.toPsiVisibilityForClass(isNested: Boolean): String = visibility.toPsiVisibilityForClass(isNested)
internal fun Visibility.toPsiVisibilityForMember(): String = when (this) {
private fun Visibility.toPsiVisibilityForMember(): String = when (this) {
Visibilities.Private, Visibilities.PrivateToThis -> PsiModifier.PRIVATE
Visibilities.Protected -> PsiModifier.PROTECTED
else -> PsiModifier.PUBLIC
@@ -168,6 +168,12 @@ public class SymbolLightClassesLoadingForLibraryTestGenerated extends AbstractSy
runTest("compiler/testData/asJava/ultraLightClasses/jvmRecord.kt");
}
@Test
@TestMetadata("jvmStaticOnPropertySetter.kt")
public void testJvmStaticOnPropertySetter() throws Exception {
runTest("compiler/testData/asJava/ultraLightClasses/jvmStaticOnPropertySetter.kt");
}
@Test
@TestMetadata("jvmSynthetic.kt")
public void testJvmSynthetic() throws Exception {
@@ -168,6 +168,12 @@ public class SymbolLightClassesLoadingForSourceTestGenerated extends AbstractSym
runTest("compiler/testData/asJava/ultraLightClasses/jvmRecord.kt");
}
@Test
@TestMetadata("jvmStaticOnPropertySetter.kt")
public void testJvmStaticOnPropertySetter() throws Exception {
runTest("compiler/testData/asJava/ultraLightClasses/jvmStaticOnPropertySetter.kt");
}
@Test
@TestMetadata("jvmSynthetic.kt")
public void testJvmSynthetic() throws Exception {
@@ -0,0 +1,38 @@
public final class MyClass /* MyClass*/ {
@org.jetbrains.annotations.NotNull()
private static java.lang.String prop2 = "" /* initializer type: java.lang.String */;
@org.jetbrains.annotations.NotNull()
public static final MyClass.Companion Companion;
private static int prop = 4 /* initializer type: int */;
@kotlin.jvm.JvmStatic()
@org.jetbrains.annotations.NotNull()
public static final java.lang.String getProp2();// getProp2()
@kotlin.jvm.JvmStatic()
public static final void setProp(int);// setProp(int)
public MyClass();// .ctor()
class Companion ...
}
public static final class Companion /* MyClass.Companion*/ {
@kotlin.jvm.JvmStatic()
@org.jetbrains.annotations.NotNull()
public final java.lang.String getProp2();// getProp2()
@kotlin.jvm.JvmStatic()
public final void setProp(int);// setProp(int)
private Companion();// .ctor()
public final int getProp();// getProp()
public final void setProp2(@org.jetbrains.annotations.NotNull() java.lang.String);// setProp2(java.lang.String)
}
@@ -0,0 +1,17 @@
class MyClass {
companion object {
var prop: Int = 4
@JvmStatic
set(value) {
field = value
}
get() = field
@get:JvmStatic
var prop2: String = ""
set(value) {
field = value
}
}
}
@@ -0,0 +1,38 @@
public final class MyClass /* MyClass*/ {
@org.jetbrains.annotations.NotNull()
private static java.lang.String prop2;
@org.jetbrains.annotations.NotNull()
public static final MyClass.Companion Companion;
private static int prop;
@kotlin.jvm.JvmStatic()
@org.jetbrains.annotations.NotNull()
public static final java.lang.String getProp2();// getProp2()
@kotlin.jvm.JvmStatic()
public static final void setProp(int);// setProp(int)
public MyClass();// .ctor()
class Companion ...
}
public static final class Companion /* MyClass.Companion*/ {
@kotlin.jvm.JvmStatic()
@org.jetbrains.annotations.NotNull()
public final java.lang.String getProp2();// getProp2()
@kotlin.jvm.JvmStatic()
public final void setProp(int);// setProp(int)
private Companion();// .ctor()
public final int getProp();// getProp()
public final void setProp2(@org.jetbrains.annotations.NotNull() java.lang.String);// setProp2(java.lang.String)
}
@@ -1,10 +1,14 @@
public final class A /* A*/ {
private int z = 1 /* initializer type: int */;
public A f;
public A();// .ctor()
public final int getX();// getX()
public final void setF(@org.jetbrains.annotations.NotNull() A);// setF(A)
public final void setX(int);// setX(int)
}
@@ -1,10 +1,14 @@
public final class A /* A*/ {
private int z;
public A f;
public A();// .ctor()
public final int getX();// getX()
public final void setF(@org.jetbrains.annotations.NotNull() A);// setF(A)
public final void setX(int);// setX(int)
}
@@ -12,5 +12,8 @@ class A {
var z = 1
@JvmSynthetic get
@JvmSynthetic set
@get:JvmSynthetic
lateinit var f: A
}
@@ -3,12 +3,6 @@ public final class X /* X*/ {
private int w = 1 /* initializer type: int */;
@kotlin.jvm.JvmSynthetic()
public final int getV();// getV()
@kotlin.jvm.JvmSynthetic()
public final void setW(int);// setW(int)
public X();// .ctor()
public final int getW();// getW()
@@ -15,9 +15,19 @@ public final class C /* C*/ {
@org.jetbrains.annotations.NotNull()
public static final C.Factory Factory;
@kotlin.jvm.JvmStatic()
@org.jetbrains.annotations.NotNull()
public static final java.lang.String getC(@org.jetbrains.annotations.NotNull() I);// getC(I)
@kotlin.jvm.JvmStatic()
public static final void foo();// foo()
@kotlin.jvm.JvmStatic()
public static final void setC(@org.jetbrains.annotations.NotNull() I, @org.jetbrains.annotations.NotNull() java.lang.String);// setC(I, java.lang.String)
@kotlin.jvm.JvmStatic()
public static final void setC1(@org.jetbrains.annotations.NotNull() java.lang.String);// setC1(java.lang.String)
@org.jetbrains.annotations.NotNull()
public static final java.lang.String getX();// getX()