From e0975df1c068984cf8219c19bc3bebd126bd95aa Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Fri, 14 Dec 2018 11:02:57 +0300 Subject: [PATCH] Create annotation arguments in ultra-light classes via PsiElementFactory --- .../asJava/classes/ultraLightAnnotations.kt | 67 ++++++++----------- .../elements/KtLightAnnotationsValues.kt | 4 +- .../elements/KtLightAnnotationsValues.kt.173 | 4 +- .../delegatesWithAnnotations.java | 4 +- 4 files changed, 33 insertions(+), 46 deletions(-) diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightAnnotations.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightAnnotations.kt index eb9ff23f2ef..a830a95af3f 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightAnnotations.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightAnnotations.kt @@ -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 @@ -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 -> "" - 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 diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightAnnotationsValues.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightAnnotationsValues.kt index bed0fcec011..ddaaf526b05 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightAnnotationsValues.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightAnnotationsValues.kt @@ -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() -} \ No newline at end of file +} diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightAnnotationsValues.kt.173 b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightAnnotationsValues.kt.173 index 6145a5ecee8..e92006027a3 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightAnnotationsValues.kt.173 +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/elements/KtLightAnnotationsValues.kt.173 @@ -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() -} \ No newline at end of file +} diff --git a/compiler/testData/asJava/ultraLightClasses/delegatesWithAnnotations.java b/compiler/testData/asJava/ultraLightClasses/delegatesWithAnnotations.java index 1feac1d5b9b..f0c9811f56a 100644 --- a/compiler/testData/asJava/ultraLightClasses/delegatesWithAnnotations.java +++ b/compiler/testData/asJava/ultraLightClasses/delegatesWithAnnotations.java @@ -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);