Create annotation arguments in ultra-light classes via PsiElementFactory
This commit is contained in:
+27
-40
@@ -4,17 +4,16 @@ import com.intellij.lang.jvm.JvmModifier
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.PsiImplUtil
|
||||
import com.intellij.psi.impl.light.LightIdentifier
|
||||
import com.intellij.psi.impl.light.LightTypeElement
|
||||
import com.intellij.psi.impl.source.PsiClassReferenceType
|
||||
import com.intellij.psi.meta.PsiMetaData
|
||||
import com.intellij.psi.util.TypeConversionUtil
|
||||
import org.jetbrains.annotations.NotNull
|
||||
import org.jetbrains.annotations.Nullable
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightElementBase
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightNullabilityAnnotation
|
||||
import org.jetbrains.kotlin.asJava.elements.psiType
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||
import org.jetbrains.kotlin.psi.KtCallElement
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.resolve.constants.*
|
||||
@@ -127,13 +126,34 @@ private fun ConstantValue<*>.toAnnotationMemberValue(
|
||||
this.value.mapNotNull { element -> element.toAnnotationMemberValue(arrayLiteralParent, ultraLightSupport) }
|
||||
}
|
||||
|
||||
is KClassValue -> KtUltraLightPsiClassObjectAccessExpression(this, ultraLightSupport, parent)
|
||||
|
||||
is ErrorValue -> null
|
||||
|
||||
else -> KtUltraLightPsiLiteralForConstantValue(this, ultraLightSupport, parent)
|
||||
else -> createPsiLiteral(parent)
|
||||
}
|
||||
|
||||
private fun ConstantValue<*>.createPsiLiteral(parent: PsiElement): PsiExpression? {
|
||||
val asString = asStringForPsiLiteral(parent)
|
||||
val instance = PsiElementFactory.SERVICE.getInstance(parent.project)
|
||||
return instance.createExpressionFromText(asString, parent)
|
||||
}
|
||||
|
||||
private fun ConstantValue<*>.asStringForPsiLiteral(parent: PsiElement): String =
|
||||
when (this) {
|
||||
is NullValue -> "null"
|
||||
is StringValue -> "\"$value\""
|
||||
is KClassValue -> {
|
||||
val arrayPart = "[]".repeat(value.arrayNestedness)
|
||||
val fqName = value.classId.asSingleFqName()
|
||||
val canonicalText = psiType(
|
||||
fqName.asString(), parent, boxPrimitiveType = value.arrayNestedness > 0
|
||||
).let(TypeConversionUtil::erasure).getCanonicalText(false)
|
||||
|
||||
"$canonicalText$arrayPart.class"
|
||||
}
|
||||
is EnumValue -> "${enumClassId.asSingleFqName().asString()}.$enumEntryName"
|
||||
else -> value.toString()
|
||||
}
|
||||
|
||||
|
||||
private class KtUltraLightPsiArrayInitializerMemberValue(
|
||||
val lightParent: PsiElement,
|
||||
private val arguments: (KtUltraLightPsiArrayInitializerMemberValue) -> List<PsiAnnotationMemberValue>
|
||||
@@ -149,39 +169,6 @@ private class KtUltraLightPsiArrayInitializerMemberValue(
|
||||
override fun getText(): String = "{" + initializers.joinToString { it.text } + "}"
|
||||
}
|
||||
|
||||
private open class KtUltraLightPsiLiteralForConstantValue(
|
||||
private val constantValue: ConstantValue<*>,
|
||||
private val ultraLightSupport: UltraLightSupport,
|
||||
lightParent: PsiElement
|
||||
) : KtLightElementBase(lightParent), PsiLiteralExpression {
|
||||
override val kotlinOrigin: KtElement? get() = null
|
||||
|
||||
override fun getValue(): Any? = constantValue.value
|
||||
|
||||
override fun getType() =
|
||||
constantValue.getType(ultraLightSupport.moduleDescriptor).asPsiType(ultraLightSupport, TypeMappingMode.DEFAULT, this)
|
||||
|
||||
override fun getText() = when (constantValue) {
|
||||
is NullValue -> "<undefined value>"
|
||||
is StringValue -> "\"${value.toString()}\""
|
||||
is EnumValue -> constantValue.enumClassId.shortClassName.asString() + "." + constantValue.enumEntryName.asString()
|
||||
else -> value.toString()
|
||||
}
|
||||
}
|
||||
|
||||
private class KtUltraLightPsiClassObjectAccessExpression(
|
||||
kClassValue: KClassValue,
|
||||
ultraLightSupport: UltraLightSupport,
|
||||
parent: PsiElement
|
||||
) : KtUltraLightPsiLiteralForConstantValue(kClassValue, ultraLightSupport, parent), PsiClassObjectAccessExpression {
|
||||
override fun getOperand(): PsiTypeElement {
|
||||
val argument = (type as? PsiClassReferenceType)?.parameters?.getOrNull(0)
|
||||
return LightTypeElement(parent.manager, argument ?: type)
|
||||
}
|
||||
|
||||
override fun getText() = operand.text + ".class"
|
||||
}
|
||||
|
||||
fun PsiModifierListOwner.isPrivateOrParameterInPrivateMethod(): Boolean {
|
||||
if (hasModifier(JvmModifier.PRIVATE)) return true
|
||||
if (this !is PsiParameter) return false
|
||||
|
||||
+2
-2
@@ -78,7 +78,7 @@ class KtLightPsiClassObjectAccessExpression(override val kotlinOrigin: KtClassLi
|
||||
override fun getOperand(): PsiTypeElement = LightTypeElement(kotlinOrigin.manager, type)
|
||||
}
|
||||
|
||||
private fun psiType(kotlinFqName: String, context: PsiElement, boxPrimitiveType: Boolean = false): PsiType? {
|
||||
internal fun psiType(kotlinFqName: String, context: PsiElement, boxPrimitiveType: Boolean = false): PsiType {
|
||||
if (!boxPrimitiveType) {
|
||||
when (kotlinFqName) {
|
||||
"kotlin.Int" -> return PsiType.INT
|
||||
@@ -132,4 +132,4 @@ class KtLightPsiNameValuePair private constructor(
|
||||
|
||||
override fun getLiteralValue(): String? = (getValue() as? PsiLiteralExpression)?.value?.toString()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -78,7 +78,7 @@ class KtLightPsiClassObjectAccessExpression(override val kotlinOrigin: KtClassLi
|
||||
override fun getOperand(): PsiTypeElement = LightTypeElement(kotlinOrigin.manager, type)
|
||||
}
|
||||
|
||||
private fun psiType(kotlinFqName: String, context: PsiElement, boxPrimitiveType: Boolean = false): PsiType? {
|
||||
internal fun psiType(kotlinFqName: String, context: PsiElement, boxPrimitiveType: Boolean = false): PsiType {
|
||||
if (!boxPrimitiveType) {
|
||||
when (kotlinFqName) {
|
||||
"kotlin.Int" -> return PsiType.INT
|
||||
@@ -132,4 +132,4 @@ class KtLightPsiNameValuePair private constructor(
|
||||
|
||||
override fun getLiteralValue(): String? = (getValue() as? PsiLiteralExpression)?.value?.toString()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ public abstract interface Base /* Base*/ {
|
||||
}
|
||||
|
||||
public final class Derived /* Derived*/ implements Base {
|
||||
@Ann(x=1, y="134", z=String.class, e={Integer.class, Double.class}, depr=DeprecationLevel.WARNING, t={@SimpleAnn(value="243"), @SimpleAnn(value="4324")})
|
||||
public void foo(@Ann(x=2, y="324", z=Ann.class, e={Byte.class, Base.class}, depr=DeprecationLevel.WARNING, t={@SimpleAnn(value="687"), @SimpleAnn(value="78")}) @org.jetbrains.annotations.NotNull() java.lang.String);
|
||||
@Ann(x=1, y="134", z=java.lang.String.class, e={int.class, double.class}, depr=kotlin.DeprecationLevel.WARNING, t={@SimpleAnn(value="243"), @SimpleAnn(value="4324")})
|
||||
public void foo(@Ann(x=2, y="324", z=Ann.class, e={byte.class, Base.class}, depr=kotlin.DeprecationLevel.WARNING, t={@SimpleAnn(value="687"), @SimpleAnn(value="78")}) @org.jetbrains.annotations.NotNull() java.lang.String);
|
||||
|
||||
@null()
|
||||
public Derived(@org.jetbrains.annotations.NotNull() Base);
|
||||
|
||||
Reference in New Issue
Block a user