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.*
|
||||||
import com.intellij.psi.impl.PsiImplUtil
|
import com.intellij.psi.impl.PsiImplUtil
|
||||||
import com.intellij.psi.impl.light.LightIdentifier
|
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.meta.PsiMetaData
|
||||||
|
import com.intellij.psi.util.TypeConversionUtil
|
||||||
import org.jetbrains.annotations.NotNull
|
import org.jetbrains.annotations.NotNull
|
||||||
import org.jetbrains.annotations.Nullable
|
import org.jetbrains.annotations.Nullable
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation
|
import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightElementBase
|
import org.jetbrains.kotlin.asJava.elements.KtLightElementBase
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightNullabilityAnnotation
|
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.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
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.KtCallElement
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.resolve.constants.*
|
import org.jetbrains.kotlin.resolve.constants.*
|
||||||
@@ -127,13 +126,34 @@ private fun ConstantValue<*>.toAnnotationMemberValue(
|
|||||||
this.value.mapNotNull { element -> element.toAnnotationMemberValue(arrayLiteralParent, ultraLightSupport) }
|
this.value.mapNotNull { element -> element.toAnnotationMemberValue(arrayLiteralParent, ultraLightSupport) }
|
||||||
}
|
}
|
||||||
|
|
||||||
is KClassValue -> KtUltraLightPsiClassObjectAccessExpression(this, ultraLightSupport, parent)
|
|
||||||
|
|
||||||
is ErrorValue -> null
|
is ErrorValue -> null
|
||||||
|
else -> createPsiLiteral(parent)
|
||||||
else -> KtUltraLightPsiLiteralForConstantValue(this, ultraLightSupport, 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(
|
private class KtUltraLightPsiArrayInitializerMemberValue(
|
||||||
val lightParent: PsiElement,
|
val lightParent: PsiElement,
|
||||||
private val arguments: (KtUltraLightPsiArrayInitializerMemberValue) -> List<PsiAnnotationMemberValue>
|
private val arguments: (KtUltraLightPsiArrayInitializerMemberValue) -> List<PsiAnnotationMemberValue>
|
||||||
@@ -149,39 +169,6 @@ private class KtUltraLightPsiArrayInitializerMemberValue(
|
|||||||
override fun getText(): String = "{" + initializers.joinToString { it.text } + "}"
|
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 {
|
fun PsiModifierListOwner.isPrivateOrParameterInPrivateMethod(): Boolean {
|
||||||
if (hasModifier(JvmModifier.PRIVATE)) return true
|
if (hasModifier(JvmModifier.PRIVATE)) return true
|
||||||
if (this !is PsiParameter) return false
|
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)
|
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) {
|
if (!boxPrimitiveType) {
|
||||||
when (kotlinFqName) {
|
when (kotlinFqName) {
|
||||||
"kotlin.Int" -> return PsiType.INT
|
"kotlin.Int" -> return PsiType.INT
|
||||||
@@ -132,4 +132,4 @@ class KtLightPsiNameValuePair private constructor(
|
|||||||
|
|
||||||
override fun getLiteralValue(): String? = (getValue() as? PsiLiteralExpression)?.value?.toString()
|
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)
|
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) {
|
if (!boxPrimitiveType) {
|
||||||
when (kotlinFqName) {
|
when (kotlinFqName) {
|
||||||
"kotlin.Int" -> return PsiType.INT
|
"kotlin.Int" -> return PsiType.INT
|
||||||
@@ -132,4 +132,4 @@ class KtLightPsiNameValuePair private constructor(
|
|||||||
|
|
||||||
override fun getLiteralValue(): String? = (getValue() as? PsiLiteralExpression)?.value?.toString()
|
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 {
|
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")})
|
@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=DeprecationLevel.WARNING, t={@SimpleAnn(value="687"), @SimpleAnn(value="78")}) @org.jetbrains.annotations.NotNull() java.lang.String);
|
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()
|
@null()
|
||||||
public Derived(@org.jetbrains.annotations.NotNull() Base);
|
public Derived(@org.jetbrains.annotations.NotNull() Base);
|
||||||
|
|||||||
Reference in New Issue
Block a user