[ULC] Add annotation support for UL facades

This commit is contained in:
Igor Yakovlev
2020-07-14 18:36:07 +03:00
parent a5e304f520
commit 7b0eb51f8d
3 changed files with 55 additions and 27 deletions
@@ -10,11 +10,12 @@ import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
import com.intellij.psi.util.CachedValue
import org.jetbrains.kotlin.asJava.builder.LightClassData
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.asJava.elements.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.SpecialNames.NO_NAME_PROVIDED
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtProperty
@@ -38,6 +39,28 @@ class KtUltraLightClassForFacade(
override val javaFileStub: PsiJavaFileStub? = null
private val _modifierList: PsiModifierList =
KtUltraLightSimpleModifierList(owner = this, modifiers = setOf(PsiModifier.PUBLIC, PsiModifier.FINAL))
private val _givenAnnotations: List<KtLightAbstractAnnotation>? by lazyPub {
files.flatMap { file ->
file.annotationEntries.mapNotNull { entry ->
entry.analyzeAnnotation()?.fqName?.let { fqName ->
KtLightAnnotationForSourceEntry(
qualifiedName = fqName.asString(),
kotlinOrigin = entry,
parent = _modifierList,
lazyClsDelegate = null
)
}
}
}
}
override val givenAnnotations: List<KtLightAbstractAnnotation>? get() = _givenAnnotations
override fun getModifierList(): PsiModifierList = _modifierList
override fun getScope(): PsiElement? = parent
private val filesWithSupportsWithCreators by lazyPub {
@@ -13,10 +13,7 @@ import org.jetbrains.annotations.NonNls
import org.jetbrains.annotations.NotNull
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightFieldForSourceDeclarationSupport
import org.jetbrains.kotlin.asJava.elements.KtUltraLightSimpleModifierList
import org.jetbrains.kotlin.asJava.elements.*
import org.jetbrains.kotlin.codegen.PropertyCodegen
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
@@ -33,16 +30,17 @@ import org.jetbrains.kotlin.resolve.jvm.annotations.VOLATILE_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
import org.jetbrains.kotlin.types.KotlinType
private class KtUltraLightSimpleModifierListField(
private class KtUltraLightFieldModifierList(
private val support: KtUltraLightSupport,
private val declaration: KtNamedDeclaration,
owner: KtLightElement<KtModifierListOwner, PsiModifierListOwner>,
private val modifiers: Set<String>,
) : KtUltraLightSimpleModifierList(owner, modifiers, support) {
) : KtUltraLightModifierList<KtLightElement<KtModifierListOwner, PsiModifierListOwner>>(owner, support) {
override fun hasModifierProperty(name: String): Boolean = when (name) {
PsiModifier.VOLATILE -> hasFieldAnnotation(VOLATILE_ANNOTATION_FQ_NAME)
PsiModifier.TRANSIENT -> hasFieldAnnotation(TRANSIENT_ANNOTATION_FQ_NAME)
else -> super.hasModifierProperty(name)
else -> modifiers.contains(name)
}
private fun hasFieldAnnotation(fqName: FqName): Boolean {
@@ -54,7 +52,7 @@ private class KtUltraLightSimpleModifierListField(
return target == expectedTarget
}
override fun copy() = KtUltraLightSimpleModifierListField(support, declaration, owner, modifiers)
override fun copy() = KtUltraLightFieldModifierList(support, declaration, owner, modifiers)
}
internal class KtUltraLightFieldForSourceDeclaration(
@@ -76,7 +74,7 @@ internal open class KtUltraLightFieldImpl protected constructor(
KtUltraLightElementWithNullabilityAnnotation<KtDeclaration, PsiField> {
private val modifierList by lazyPub {
KtUltraLightSimpleModifierListField(support, declaration, this, modifiers)
KtUltraLightFieldModifierList(support, declaration, this, modifiers)
}
override fun isEquivalentTo(another: PsiElement?): Boolean =
@@ -92,30 +92,19 @@ abstract class KtLightModifierList<out T : KtLightElement<KtModifierListOwner, P
}
}
open class KtUltraLightSimpleModifierList(
class KtUltraLightSimpleModifierList(
owner: KtLightElement<KtModifierListOwner, PsiModifierListOwner>,
private val modifiers: Set<String>,
private val support: KtUltraLightSupport
) : KtUltraLightModifierList<KtLightElement<KtModifierListOwner, PsiModifierListOwner>>(owner, support) {
) : KtUltraLightModifierListBase<KtLightElement<KtModifierListOwner, PsiModifierListOwner>>(owner) {
override fun hasModifierProperty(name: String) = name in modifiers
override fun copy() = KtUltraLightSimpleModifierList(owner, modifiers, support)
override fun copy() = KtUltraLightSimpleModifierList(owner, modifiers)
}
abstract class KtUltraLightModifierList<out T : KtLightElement<KtModifierListOwner, PsiModifierListOwner>>(
owner: T,
private val support: KtUltraLightSupport
) : KtLightModifierList<T>(owner) {
override val clsDelegate: PsiModifierList get() = invalidAccess()
private fun throwInvalidOperation(): Nothing = throw IncorrectOperationException()
override fun setModifierProperty(name: String, value: Boolean): Unit = throwInvalidOperation()
override fun checkSetModifierProperty(name: String, value: Boolean): Unit = throwInvalidOperation()
override fun addAnnotation(qualifiedName: String): PsiAnnotation = throwInvalidOperation()
) : KtUltraLightModifierListBase<T>(owner) {
override fun nonSourceAnnotationsForAnnotationType(sourceAnnotations: List<PsiAnnotation>): List<KtLightAbstractAnnotation> {
@@ -136,7 +125,25 @@ abstract class KtUltraLightModifierList<out T : KtLightElement<KtModifierListOwn
}
}
open class KtLightSimpleModifierList(
abstract class KtUltraLightModifierListBase<out T : KtLightElement<KtModifierListOwner, PsiModifierListOwner>>(
owner: T
) : KtLightModifierList<T>(owner) {
override val clsDelegate: PsiModifierList get() = invalidAccess()
private fun throwInvalidOperation(): Nothing = throw IncorrectOperationException()
override fun setModifierProperty(name: String, value: Boolean): Unit = throwInvalidOperation()
override fun checkSetModifierProperty(name: String, value: Boolean): Unit = throwInvalidOperation()
override fun addAnnotation(qualifiedName: String): PsiAnnotation = throwInvalidOperation()
override fun nonSourceAnnotationsForAnnotationType(sourceAnnotations: List<PsiAnnotation>): List<KtLightAbstractAnnotation> =
emptyList()
}
class KtLightSimpleModifierList(
owner: KtLightElement<KtModifierListOwner, PsiModifierListOwner>, private val modifiers: Set<String>
) : KtLightModifierList<KtLightElement<KtModifierListOwner, PsiModifierListOwner>>(owner) {
override fun hasModifierProperty(name: String) = name in modifiers