[SLC] implement lazy calculation for modifiers
and fix some annotations ^KTIJ-23783 Fixed
This commit is contained in:
committed by
Space Team
parent
e2082fb0d7
commit
856d272ca4
+34
-19
@@ -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) {
|
||||
|
||||
+15
-26
@@ -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
|
||||
|
||||
+2
-1
@@ -48,7 +48,8 @@ internal class SymbolLightClassForEnumEntry(
|
||||
SymbolLightClassModifierList(
|
||||
containingDeclaration = this,
|
||||
staticModifiers = setOf(PsiModifier.STATIC, PsiModifier.FINAL),
|
||||
) { emptyList() }
|
||||
annotationsComputer = null,
|
||||
)
|
||||
}
|
||||
|
||||
override fun getModifierList(): PsiModifierList = _modifierList
|
||||
|
||||
+2
-1
@@ -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
|
||||
|
||||
+4
-15
@@ -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(
|
||||
|
||||
+25
@@ -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
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -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>()
|
||||
|
||||
+14
-10
@@ -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()
|
||||
|
||||
+41
-32
@@ -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)) {
|
||||
|
||||
+31
-22
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-14
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+52
-28
@@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
+15
-6
@@ -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)
|
||||
}
|
||||
|
||||
+15
-6
@@ -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
|
||||
|
||||
+102
-18
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -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
|
||||
}
|
||||
|
||||
+4
-1
@@ -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)
|
||||
|
||||
+4
-1
@@ -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,
|
||||
|
||||
+4
-1
@@ -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
|
||||
|
||||
+1
-30
@@ -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
|
||||
|
||||
+6
@@ -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 {
|
||||
|
||||
+6
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
+38
@@ -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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user