[SLC] implement light class for RepeatableContainer
^KT-55470 Fixed
This commit is contained in:
committed by
Space Team
parent
cd0ae20c38
commit
1e1525bae5
+19
-15
@@ -5,9 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.light.classes.symbol.classes
|
||||
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiReferenceList
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol
|
||||
@@ -21,7 +19,7 @@ import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
|
||||
internal class SymbolLightClassForAnnotationClass : SymbolLightClassForInterfaceOrAnnotationClass {
|
||||
internal open class SymbolLightClassForAnnotationClass : SymbolLightClassForInterfaceOrAnnotationClass {
|
||||
constructor(
|
||||
ktAnalysisSession: KtAnalysisSession,
|
||||
ktModule: KtModule,
|
||||
@@ -40,7 +38,7 @@ internal class SymbolLightClassForAnnotationClass : SymbolLightClassForInterface
|
||||
require(classOrObject is KtClass && classOrObject.isAnnotation())
|
||||
}
|
||||
|
||||
private constructor(
|
||||
constructor(
|
||||
classOrObjectDeclaration: KtClassOrObject?,
|
||||
classOrObjectSymbolPointer: KtSymbolPointer<KtNamedClassOrObjectSymbol>,
|
||||
ktModule: KtModule,
|
||||
@@ -54,22 +52,28 @@ internal class SymbolLightClassForAnnotationClass : SymbolLightClassForInterface
|
||||
|
||||
override fun isAnnotationType(): Boolean = true
|
||||
|
||||
private val _ownMethods: List<KtLightMethod> by lazyPub {
|
||||
withClassOrObjectSymbol { classOrObjectSymbol ->
|
||||
val result = mutableListOf<KtLightMethod>()
|
||||
val visibleDeclarations = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols()
|
||||
.filterNot { it is KtFunctionSymbol && it.visibility.isPrivateOrPrivateToThis() }
|
||||
.filterNot { it is KtConstructorSymbol }
|
||||
protected open fun computeOwnMethods(): List<PsiMethod> = withClassOrObjectSymbol { classOrObjectSymbol ->
|
||||
val result = mutableListOf<KtLightMethod>()
|
||||
val visibleDeclarations = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols()
|
||||
.filterNot { it is KtFunctionSymbol && it.visibility.isPrivateOrPrivateToThis() }
|
||||
.filterNot { it is KtConstructorSymbol }
|
||||
|
||||
createMethods(visibleDeclarations, result)
|
||||
result
|
||||
}
|
||||
createMethods(visibleDeclarations, result)
|
||||
result
|
||||
}
|
||||
|
||||
override fun getOwnMethods(): List<PsiMethod> = _ownMethods
|
||||
private val _ownMethods: List<PsiMethod> by lazyPub {
|
||||
computeOwnMethods()
|
||||
}
|
||||
|
||||
final override fun getOwnMethods(): List<PsiMethod> = _ownMethods
|
||||
override fun getExtendsList(): PsiReferenceList? = null
|
||||
|
||||
final override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean {
|
||||
val qualifiedName = baseClass.qualifiedName
|
||||
return qualifiedName == CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION || qualifiedName == CommonClassNames.JAVA_LANG_OBJECT
|
||||
}
|
||||
|
||||
override fun copy(): SymbolLightClassForAnnotationClass = SymbolLightClassForAnnotationClass(
|
||||
classOrObjectDeclaration = classOrObjectDeclaration,
|
||||
classOrObjectSymbolPointer = classOrObjectSymbolPointer,
|
||||
|
||||
+5
-10
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.light.classes.symbol.classes
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
|
||||
@@ -33,15 +32,11 @@ internal class SymbolLightClassForInterfaceDefaultImpls(private val containingCl
|
||||
override fun getTypeParameterList(): PsiTypeParameterList? = null
|
||||
override fun getTypeParameters(): Array<PsiTypeParameter> = emptyArray()
|
||||
|
||||
private val _modifierList: PsiModifierList? by lazyPub {
|
||||
SymbolLightClassModifierList(
|
||||
containingDeclaration = this,
|
||||
staticModifiers = setOf(PsiModifier.PUBLIC, PsiModifier.STATIC, PsiModifier.FINAL),
|
||||
annotationsComputer = null,
|
||||
)
|
||||
}
|
||||
|
||||
override fun getModifierList(): PsiModifierList? = _modifierList
|
||||
override fun computeModifierList(): PsiModifierList = SymbolLightClassModifierList(
|
||||
containingDeclaration = this,
|
||||
staticModifiers = setOf(PsiModifier.PUBLIC, PsiModifier.STATIC, PsiModifier.FINAL),
|
||||
annotationsComputer = null,
|
||||
)
|
||||
|
||||
override fun isInterface(): Boolean = false
|
||||
override fun isDeprecated(): Boolean = false
|
||||
|
||||
+16
-14
@@ -65,26 +65,28 @@ internal abstract class SymbolLightClassForInterfaceOrAnnotationClass : SymbolLi
|
||||
manager = manager,
|
||||
)
|
||||
|
||||
private val _modifierList: PsiModifierList? by lazyPub {
|
||||
SymbolLightClassModifierList(
|
||||
containingDeclaration = this,
|
||||
initialValue = LazyModifiersBox.MODALITY_MODIFIERS_MAP.with(PsiModifier.ABSTRACT),
|
||||
lazyModifiersComputer = ::computeModifiers
|
||||
) { modifierList ->
|
||||
withClassOrObjectSymbol { classOrObjectSymbol ->
|
||||
classOrObjectSymbol.computeAnnotations(
|
||||
modifierList = modifierList,
|
||||
nullability = NullabilityType.Unknown,
|
||||
annotationUseSiteTarget = null,
|
||||
)
|
||||
}
|
||||
protected open fun computeModifierList(): PsiModifierList? = SymbolLightClassModifierList(
|
||||
containingDeclaration = this,
|
||||
initialValue = LazyModifiersBox.MODALITY_MODIFIERS_MAP.with(PsiModifier.ABSTRACT),
|
||||
lazyModifiersComputer = ::computeModifiers
|
||||
) { modifierList ->
|
||||
withClassOrObjectSymbol { classOrObjectSymbol ->
|
||||
classOrObjectSymbol.computeAnnotations(
|
||||
modifierList = modifierList,
|
||||
nullability = NullabilityType.Unknown,
|
||||
annotationUseSiteTarget = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private val _modifierList: PsiModifierList? by lazyPub {
|
||||
computeModifierList()
|
||||
}
|
||||
|
||||
override fun isInterface(): Boolean = true
|
||||
override fun isEnum(): Boolean = false
|
||||
|
||||
override fun getModifierList(): PsiModifierList? = _modifierList
|
||||
final override fun getModifierList(): PsiModifierList? = _modifierList
|
||||
|
||||
private val _ownFields: List<KtLightField> by lazyPub {
|
||||
withClassOrObjectSymbol { classOrObjectSymbol ->
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.light.classes.symbol.classes
|
||||
|
||||
import com.intellij.psi.*
|
||||
import kotlinx.collections.immutable.persistentHashSetOf
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.light.classes.symbol.NullabilityType
|
||||
import org.jetbrains.kotlin.light.classes.symbol.annotations.SymbolLightSimpleAnnotation
|
||||
import org.jetbrains.kotlin.light.classes.symbol.annotations.computeAnnotations
|
||||
import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightRepeatableAnnotationContainerMethod
|
||||
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightClassModifierList
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
|
||||
internal class SymbolLightClassForRepeatableAnnotationContainer(private val containerOwner: SymbolLightClassForAnnotationClass) :
|
||||
SymbolLightClassForAnnotationClass(
|
||||
containerOwner.classOrObjectDeclaration,
|
||||
containerOwner.classOrObjectSymbolPointer,
|
||||
containerOwner.ktModule,
|
||||
containerOwner.manager,
|
||||
) {
|
||||
override fun getQualifiedName(): String? = containerOwner.qualifiedName?.let { "$it.${JvmAbi.REPEATABLE_ANNOTATION_CONTAINER_NAME}" }
|
||||
override fun getName(): String = JvmAbi.REPEATABLE_ANNOTATION_CONTAINER_NAME
|
||||
override fun getParent(): SymbolLightClassForAnnotationClass = containerOwner
|
||||
override fun getTypeParameterList(): PsiTypeParameterList? = null
|
||||
override fun getTypeParameters(): Array<PsiTypeParameter> = PsiTypeParameter.EMPTY_ARRAY
|
||||
override fun getContainingClass(): KtLightClass = containerOwner
|
||||
override fun getScope(): PsiElement = containerOwner
|
||||
override fun getOwnInnerClasses(): List<PsiClass> = emptyList()
|
||||
override fun getOwnFields(): List<KtLightField> = emptyList()
|
||||
override fun isDeprecated(): Boolean = false
|
||||
override fun hasTypeParameters(): Boolean = false
|
||||
|
||||
override fun computeModifierList(): PsiModifierList = SymbolLightClassModifierList(
|
||||
containingDeclaration = this,
|
||||
// It is marked as Abstract because all the annotation classes are marked as Abstract
|
||||
// It is marked as Static because all nested interfaces marked as Static
|
||||
staticModifiers = setOf(PsiModifier.PUBLIC, PsiModifier.STATIC, PsiModifier.ABSTRACT),
|
||||
annotationsComputer = { psiModifierList ->
|
||||
val annotations = withClassOrObjectSymbol { classOrObjectSymbol ->
|
||||
classOrObjectSymbol.computeAnnotations(
|
||||
modifierList = psiModifierList,
|
||||
nullability = NullabilityType.Unknown,
|
||||
annotationUseSiteTarget = null,
|
||||
)
|
||||
}.filter {
|
||||
it.qualifiedName in allowedAnnotations
|
||||
}
|
||||
|
||||
annotations + SymbolLightSimpleAnnotation(fqName = KOTLIN_JVM_INTERNAL_REPEATABLE_CONTAINER, parent = psiModifierList)
|
||||
},
|
||||
)
|
||||
|
||||
override fun computeOwnMethods(): List<PsiMethod> = listOf(
|
||||
SymbolLightRepeatableAnnotationContainerMethod(containerOwner.qualifiedName, this)
|
||||
)
|
||||
|
||||
override fun copy(): SymbolLightClassForRepeatableAnnotationContainer = SymbolLightClassForRepeatableAnnotationContainer(containerOwner)
|
||||
|
||||
override fun equals(other: Any?): Boolean = this === other ||
|
||||
other is SymbolLightClassForRepeatableAnnotationContainer && other.containerOwner == containerOwner
|
||||
|
||||
override fun hashCode(): Int = containerOwner.hashCode()
|
||||
|
||||
companion object {
|
||||
private val allowedAnnotations = persistentHashSetOf(
|
||||
CommonClassNames.JAVA_LANG_ANNOTATION_RETENTION,
|
||||
StandardNames.FqNames.retention.asString(),
|
||||
CommonClassNames.JAVA_LANG_ANNOTATION_TARGET,
|
||||
StandardNames.FqNames.target.asString(),
|
||||
)
|
||||
|
||||
private const val KOTLIN_JVM_INTERNAL_REPEATABLE_CONTAINER = "kotlin.jvm.internal.RepeatableContainer"
|
||||
}
|
||||
}
|
||||
+11
-1
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.asJava.elements.KtLightField
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.asJava.hasInterfaceDefaultImpls
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.config.JvmAnalysisFlags
|
||||
import org.jetbrains.kotlin.config.JvmDefaultMode
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
@@ -43,6 +44,7 @@ import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightConstructor
|
||||
import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightNoArgConstructor
|
||||
import org.jetbrains.kotlin.light.classes.symbol.methods.SymbolLightSimpleMethod
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClass
|
||||
@@ -251,7 +253,7 @@ internal fun SymbolLightClassBase.createMethods(
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
private inline fun <T : KtFunctionLikeSymbol> SymbolLightClassBase.createJvmOverloadsIfNeeded(
|
||||
private inline fun <T : KtFunctionLikeSymbol> createJvmOverloadsIfNeeded(
|
||||
declaration: T,
|
||||
result: MutableList<KtLightMethod>,
|
||||
lightMethodCreator: (Int, BitSet) -> KtLightMethod
|
||||
@@ -475,6 +477,14 @@ internal fun KtSymbolWithMembers.createInnerClasses(
|
||||
result.add(SymbolLightClassForInterfaceDefaultImpls(containingClass))
|
||||
}
|
||||
|
||||
if (containingClass is SymbolLightClassForAnnotationClass &&
|
||||
this is KtNamedClassOrObjectSymbol &&
|
||||
hasAnnotation(StandardNames.FqNames.repeatable, annotationUseSiteTarget = null) &&
|
||||
!hasAnnotation(JvmAnnotationNames.REPEATABLE_ANNOTATION, annotationUseSiteTarget = null)
|
||||
) {
|
||||
result.add(SymbolLightClassForRepeatableAnnotationContainer(containingClass))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.light.classes.symbol.methods
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.asJava.classes.METHOD_INDEX_BASE
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
import org.jetbrains.kotlin.light.classes.symbol.classes.SymbolLightClassBase
|
||||
import org.jetbrains.kotlin.light.classes.symbol.modifierLists.SymbolLightMemberModifierList
|
||||
import org.jetbrains.kotlin.light.classes.symbol.parameters.SymbolLightParameterList
|
||||
|
||||
internal class SymbolLightRepeatableAnnotationContainerMethod(
|
||||
private val annotationClassQualifier: String?,
|
||||
containingClass: SymbolLightClassBase,
|
||||
) : SymbolLightMethodBase(
|
||||
lightMemberOrigin = null,
|
||||
containingClass = containingClass,
|
||||
methodIndex = METHOD_INDEX_BASE,
|
||||
) {
|
||||
override fun getNameIdentifier(): PsiIdentifier? = null
|
||||
override fun isDeprecated(): Boolean = false
|
||||
override fun getName(): String = "value"
|
||||
override fun getTypeParameters(): Array<PsiTypeParameter> = PsiTypeParameter.EMPTY_ARRAY
|
||||
override fun hasTypeParameters(): Boolean = false
|
||||
override fun getTypeParameterList(): PsiTypeParameterList? = null
|
||||
override fun isOverride(): Boolean = false
|
||||
|
||||
private val _modifierList by lazyPub {
|
||||
SymbolLightMemberModifierList(
|
||||
containingDeclaration = this,
|
||||
staticModifiers = setOf(PsiModifier.PUBLIC, PsiModifier.ABSTRACT),
|
||||
annotationsComputer = null,
|
||||
)
|
||||
}
|
||||
|
||||
override fun getModifierList(): PsiModifierList = _modifierList
|
||||
|
||||
private val _parameterList by lazyPub {
|
||||
SymbolLightParameterList(this)
|
||||
}
|
||||
|
||||
override fun getParameterList(): PsiParameterList = _parameterList
|
||||
|
||||
override fun isConstructor(): Boolean = false
|
||||
|
||||
private val _returnType by lazyPub {
|
||||
val qualifier = annotationClassQualifier ?: return@lazyPub null
|
||||
JavaPsiFacade.getElementFactory(project).createTypeByFQClassName(qualifier, resolveScope).createArrayType()
|
||||
}
|
||||
|
||||
override fun getReturnType(): PsiType? = _returnType
|
||||
|
||||
override fun equals(other: Any?): Boolean =
|
||||
this === other || other is SymbolLightRepeatableAnnotationContainerMethod && other.containingClass == containingClass
|
||||
|
||||
override fun hashCode(): Int = containingClass.hashCode()
|
||||
override fun copy(): PsiElement = SymbolLightRepeatableAnnotationContainerMethod(annotationClassQualifier, containingClass)
|
||||
}
|
||||
@@ -3,4 +3,10 @@
|
||||
public abstract @interface One /* simple.One*/ {
|
||||
public abstract java.lang.String value();// value()
|
||||
|
||||
}
|
||||
|
||||
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
|
||||
@kotlin.jvm.internal.RepeatableContainer()
|
||||
public static abstract @interface Container /* simple.One.Container*/ {
|
||||
public abstract simple.One[] value();// value()
|
||||
|
||||
}}
|
||||
|
||||
+9
-1
@@ -6,4 +6,12 @@
|
||||
public abstract @interface Anno /* Anno*/ {
|
||||
public abstract int i();// i()
|
||||
|
||||
}
|
||||
|
||||
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.SOURCE)
|
||||
@kotlin.annotation.Retention(value = kotlin.annotation.AnnotationRetention.SOURCE)
|
||||
@kotlin.annotation.Target(allowedTargets = {kotlin.annotation.AnnotationTarget.TYPE_PARAMETER, kotlin.annotation.AnnotationTarget.TYPE})
|
||||
@kotlin.jvm.internal.RepeatableContainer()
|
||||
public static abstract @interface Container /* Anno.Container*/ {
|
||||
public abstract Anno[] value();// value()
|
||||
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user