Analysis API: add KDoc, small cosmetic improvements
This commit is contained in:
+3
-3
@@ -299,9 +299,9 @@ internal fun ConstantValue<*>.toKtAnnotationValue(): KtAnnotationValue {
|
|||||||
is KClassValue -> when (val value = value) {
|
is KClassValue -> when (val value = value) {
|
||||||
is KClassValue.Value.LocalClass -> {
|
is KClassValue.Value.LocalClass -> {
|
||||||
val descriptor = value.type.constructor.declarationDescriptor as ClassDescriptor
|
val descriptor = value.type.constructor.declarationDescriptor as ClassDescriptor
|
||||||
KtLocalKClassAnnotationValue(descriptor.source.getPsi() as KtClassOrObject, sourcePsi = null)
|
KtKClassAnnotationValue.KtLocalKClassAnnotationValue(descriptor.source.getPsi() as KtClassOrObject, sourcePsi = null)
|
||||||
}
|
}
|
||||||
is KClassValue.Value.NormalClass -> KtNonLocalKClassAnnotationValue(value.classId, sourcePsi = null)
|
is KClassValue.Value.NormalClass -> KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue(value.classId, sourcePsi = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
is AnnotationValue -> {
|
is AnnotationValue -> {
|
||||||
@@ -461,5 +461,5 @@ internal fun AnnotationDescriptor.toKtAnnotationApplication(): KtAnnotationAppli
|
|||||||
|
|
||||||
internal fun AnnotationDescriptor.getKtNamedAnnotationArguments() =
|
internal fun AnnotationDescriptor.getKtNamedAnnotationArguments() =
|
||||||
allValueArguments.map { (name, value) ->
|
allValueArguments.map { (name, value) ->
|
||||||
KtNamedAnnotationValue(name.asString(), value.toKtAnnotationValue())
|
KtNamedAnnotationValue(name, value.toKtAnnotationValue())
|
||||||
}
|
}
|
||||||
+3
-2
@@ -109,7 +109,8 @@ internal class KtFe10TypeRenderer(private val options: KtTypeRendererOptions, pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
printCollection(namedValues, separator = ", ", prefix = "(", postfix = ")") { (name, value) ->
|
printCollection(namedValues, separator = ", ", prefix = "(", postfix = ")") { (name, value) ->
|
||||||
append(name).append(" = ")
|
append(name.render())
|
||||||
|
append(" = ")
|
||||||
renderConstantValueDebug(value)
|
renderConstantValueDebug(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,7 +123,7 @@ internal class KtFe10TypeRenderer(private val options: KtTypeRendererOptions, pr
|
|||||||
is KtEnumEntryAnnotationValue -> append(value.callableId?.asSingleFqName()?.render())
|
is KtEnumEntryAnnotationValue -> append(value.callableId?.asSingleFqName()?.render())
|
||||||
is KtConstantAnnotationValue -> append(value.constantValue.constantValueKind.asString).append("(").append(value.constantValue.value.toString()).append(")")
|
is KtConstantAnnotationValue -> append(value.constantValue.constantValueKind.asString).append("(").append(value.constantValue.value.toString()).append(")")
|
||||||
KtUnsupportedAnnotationValue -> append(KtUnsupportedAnnotationValue::class.java.simpleName)
|
KtUnsupportedAnnotationValue -> append(KtUnsupportedAnnotationValue::class.java.simpleName)
|
||||||
is KtKClassAnnotationValue -> append(value.render())
|
is KtKClassAnnotationValue -> append(value.renderAsSourceCode())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.api.descriptors.utils
|
package org.jetbrains.kotlin.analysis.api.descriptors.utils
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.analysis.api.annotations.renderAsSourceCode
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.classId
|
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.classId
|
||||||
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationValueRenderer
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtAnnotationValue
|
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtAnnotationValue
|
||||||
import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter
|
import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
@@ -39,7 +39,7 @@ internal fun PrettyPrinter.renderFe10Annotations(
|
|||||||
printCollectionIfNotEmpty(valueArguments, separator = ", ", prefix = "(", postfix = ")") { (name, value) ->
|
printCollectionIfNotEmpty(valueArguments, separator = ", ", prefix = "(", postfix = ")") { (name, value) ->
|
||||||
append(name.render())
|
append(name.render())
|
||||||
append(" = ")
|
append(" = ")
|
||||||
append(KtAnnotationValueRenderer.render(value.toKtAnnotationValue()))
|
append(value.toKtAnnotationValue().renderAsSourceCode())
|
||||||
}
|
}
|
||||||
|
|
||||||
append(separator)
|
append(separator)
|
||||||
|
|||||||
+6
-5
@@ -16,21 +16,22 @@ import org.jetbrains.kotlin.fir.types.ConeClassLikeType
|
|||||||
import org.jetbrains.kotlin.fir.types.classId
|
import org.jetbrains.kotlin.fir.types.classId
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
internal fun mapAnnotationParameters(annotation: FirAnnotation, session: FirSession): Map<String, FirExpression> {
|
internal fun mapAnnotationParameters(annotation: FirAnnotation, session: FirSession): Map<Name, FirExpression> {
|
||||||
if (annotation.resolved) return annotation.argumentMapping.mapping.mapKeys { (name, _) -> name.identifier }
|
if (annotation.resolved) return annotation.argumentMapping.mapping.mapKeys { (name, _) -> name }
|
||||||
if (annotation !is FirAnnotationCall) return emptyMap()
|
if (annotation !is FirAnnotationCall) return emptyMap()
|
||||||
val annotationCone = annotation.annotationTypeRef.coneType as? ConeClassLikeType ?: return emptyMap()
|
val annotationCone = annotation.annotationTypeRef.coneType as? ConeClassLikeType ?: return emptyMap()
|
||||||
|
|
||||||
val annotationPrimaryCtor = (annotationCone.lookupTag.toSymbol(session)?.fir as? FirRegularClass)?.primaryConstructorIfAny(session)?.fir
|
val annotationPrimaryCtor = (annotationCone.lookupTag.toSymbol(session)?.fir as? FirRegularClass)?.primaryConstructorIfAny(session)?.fir
|
||||||
val annotationCtorParameterNames = annotationPrimaryCtor?.valueParameters?.map { it.name }
|
val annotationCtorParameterNames = annotationPrimaryCtor?.valueParameters?.map { it.name }
|
||||||
|
|
||||||
val resultMap = mutableMapOf<String, FirExpression>()
|
val resultMap = mutableMapOf<Name, FirExpression>()
|
||||||
|
|
||||||
val namesSequence = annotationCtorParameterNames?.asSequence()?.iterator()
|
val namesSequence = annotationCtorParameterNames?.asSequence()?.iterator()
|
||||||
|
|
||||||
for (argument in annotation.argumentList.arguments.filterIsInstance<FirNamedArgumentExpression>()) {
|
for (argument in annotation.argumentList.arguments.filterIsInstance<FirNamedArgumentExpression>()) {
|
||||||
resultMap[argument.name.asString()] = argument.expression
|
resultMap[argument.name] = argument.expression
|
||||||
}
|
}
|
||||||
|
|
||||||
if (namesSequence != null) {
|
if (namesSequence != null) {
|
||||||
@@ -38,7 +39,7 @@ internal fun mapAnnotationParameters(annotation: FirAnnotation, session: FirSess
|
|||||||
if (argument is FirNamedArgumentExpression) continue
|
if (argument is FirNamedArgumentExpression) continue
|
||||||
|
|
||||||
while (namesSequence.hasNext()) {
|
while (namesSequence.hasNext()) {
|
||||||
val name = namesSequence.next().asString()
|
val name = namesSequence.next()
|
||||||
if (!resultMap.contains(name)) {
|
if (!resultMap.contains(name)) {
|
||||||
resultMap[name] = argument
|
resultMap[name] = argument
|
||||||
break
|
break
|
||||||
|
|||||||
+10
-6
@@ -17,13 +17,14 @@ import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||||
import org.jetbrains.kotlin.resolve.ArrayFqNames
|
import org.jetbrains.kotlin.resolve.ArrayFqNames
|
||||||
|
|
||||||
internal object FirAnnotationValueConverter {
|
internal object FirAnnotationValueConverter {
|
||||||
fun toNamedConstantValue(
|
fun toNamedConstantValue(
|
||||||
argumentMapping: Map<String, FirExpression>,
|
argumentMapping: Map<Name, FirExpression>,
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
): List<KtNamedAnnotationValue> =
|
): List<KtNamedAnnotationValue> =
|
||||||
argumentMapping.map { (name, expression) ->
|
argumentMapping.map { (name, expression) ->
|
||||||
@@ -100,9 +101,9 @@ internal object FirAnnotationValueConverter {
|
|||||||
is FirConstructorSymbol -> {
|
is FirConstructorSymbol -> {
|
||||||
val classSymbol = resolvedSymbol.getContainingClassSymbol(session) ?: return null
|
val classSymbol = resolvedSymbol.getContainingClassSymbol(session) ?: return null
|
||||||
if ((classSymbol.fir as? FirClass)?.classKind == ClassKind.ANNOTATION_CLASS) {
|
if ((classSymbol.fir as? FirClass)?.classKind == ClassKind.ANNOTATION_CLASS) {
|
||||||
val resultMap = mutableMapOf<String, FirExpression>()
|
val resultMap = mutableMapOf<Name, FirExpression>()
|
||||||
argumentMapping?.entries?.forEach { (arg, param) ->
|
argumentMapping?.entries?.forEach { (arg, param) ->
|
||||||
resultMap[param.name.asString()] = arg
|
resultMap[param.name] = arg
|
||||||
}
|
}
|
||||||
KtAnnotationApplicationValue(
|
KtAnnotationApplicationValue(
|
||||||
KtAnnotationApplication(
|
KtAnnotationApplication(
|
||||||
@@ -135,9 +136,12 @@ internal object FirAnnotationValueConverter {
|
|||||||
is FirGetClassCall -> {
|
is FirGetClassCall -> {
|
||||||
val symbol = (argument as FirResolvedQualifier).symbol
|
val symbol = (argument as FirResolvedQualifier).symbol
|
||||||
when {
|
when {
|
||||||
symbol == null -> KtErrorClassAnnotationValue(sourcePsi)
|
symbol == null -> KtKClassAnnotationValue.KtErrorClassAnnotationValue(sourcePsi)
|
||||||
symbol.classId.isLocal -> KtLocalKClassAnnotationValue(symbol.fir.psi as KtClassOrObject, sourcePsi)
|
symbol.classId.isLocal -> KtKClassAnnotationValue.KtLocalKClassAnnotationValue(
|
||||||
else -> KtNonLocalKClassAnnotationValue(symbol.classId, sourcePsi)
|
symbol.fir.psi as KtClassOrObject,
|
||||||
|
sourcePsi
|
||||||
|
)
|
||||||
|
else -> KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue(symbol.classId, sourcePsi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
|
|||||||
+2
-3
@@ -8,9 +8,8 @@ package org.jetbrains.kotlin.analysis.api.fir.renderer
|
|||||||
import org.jetbrains.kotlin.analysis.api.fir.annotations.mapAnnotationParameters
|
import org.jetbrains.kotlin.analysis.api.fir.annotations.mapAnnotationParameters
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.evaluate.FirCompileTimeConstantEvaluator
|
import org.jetbrains.kotlin.analysis.api.fir.evaluate.FirCompileTimeConstantEvaluator
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.evaluate.FirAnnotationValueConverter
|
import org.jetbrains.kotlin.analysis.api.fir.evaluate.FirAnnotationValueConverter
|
||||||
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationValueRenderer
|
|
||||||
import org.jetbrains.kotlin.analysis.api.annotations.KtUnsupportedAnnotationValue
|
import org.jetbrains.kotlin.analysis.api.annotations.KtUnsupportedAnnotationValue
|
||||||
import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter
|
import org.jetbrains.kotlin.analysis.api.annotations.renderAsSourceCode
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId
|
import org.jetbrains.kotlin.fir.declarations.toAnnotationClassId
|
||||||
@@ -65,5 +64,5 @@ private fun renderConstant(value: FirExpression, useSiteSession: FirSession): St
|
|||||||
val constantValue = FirAnnotationValueConverter.toConstantValue(evaluated ?: value, useSiteSession)
|
val constantValue = FirAnnotationValueConverter.toConstantValue(evaluated ?: value, useSiteSession)
|
||||||
?: KtUnsupportedAnnotationValue
|
?: KtUnsupportedAnnotationValue
|
||||||
|
|
||||||
return KtAnnotationValueRenderer.render(constantValue)
|
return constantValue.renderAsSourceCode()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,19 +5,34 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.api
|
package org.jetbrains.kotlin.analysis.api
|
||||||
|
|
||||||
import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationValue
|
|
||||||
import org.jetbrains.kotlin.analysis.api.base.KtConstantValue
|
import org.jetbrains.kotlin.analysis.api.base.KtConstantValue
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value representing some property or variable initializer
|
||||||
|
*/
|
||||||
public sealed class KtInitializerValue {
|
public sealed class KtInitializerValue {
|
||||||
|
/**
|
||||||
|
* [com.intellij.psi.PsiElement] of initializer. May be null if property/variable came from non-source file.
|
||||||
|
*/
|
||||||
public abstract val initializerPsi: KtExpression?
|
public abstract val initializerPsi: KtExpression?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializer value which can be evaluated to constant. E.g, string value, number, null literal.
|
||||||
|
*
|
||||||
|
* For more info about constant values please see [official Kotlin documentation](https://kotlinlang.org/docs/properties.html#compile-time-constants]).
|
||||||
|
*/
|
||||||
public class KtConstantInitializerValue(
|
public class KtConstantInitializerValue(
|
||||||
public val constant: KtConstantValue,
|
public val constant: KtConstantValue,
|
||||||
override val initializerPsi: KtExpression?
|
override val initializerPsi: KtExpression?
|
||||||
) : KtInitializerValue()
|
) : KtInitializerValue()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property intialzer which cannot be represented as Kotlin const value.
|
||||||
|
*
|
||||||
|
* See [KtConstantInitializerValue] for more info.
|
||||||
|
*/
|
||||||
public class KtNonConstantInitializerValue(
|
public class KtNonConstantInitializerValue(
|
||||||
override val initializerPsi: KtExpression?
|
override val initializerPsi: KtExpression?
|
||||||
) : KtInitializerValue()
|
) : KtInitializerValue()
|
||||||
+28
-1
@@ -10,9 +10,36 @@ import org.jetbrains.kotlin.name.ClassId
|
|||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||||
import org.jetbrains.kotlin.psi.KtCallElement
|
import org.jetbrains.kotlin.psi.KtCallElement
|
||||||
|
|
||||||
public class KtAnnotationApplication(
|
/**
|
||||||
|
* Application of annotation to some declaration, type, or as argument inside other annotation.
|
||||||
|
*
|
||||||
|
* Some examples:
|
||||||
|
* - For declarations: `@Deprecated("Should not be used") fun foo(){}`
|
||||||
|
* - For types: `fun foo(x: List<@A Int>){}`
|
||||||
|
* - Inside other annotation (`B` is annotation here): `@A(B()) fun foo(){}
|
||||||
|
*/
|
||||||
|
public data class KtAnnotationApplication(
|
||||||
|
/**
|
||||||
|
* The [ClassId] of applied annotation. [ClassId] is a fully qualified name on annotation class.
|
||||||
|
*/
|
||||||
public val classId: ClassId?,
|
public val classId: ClassId?,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PsiElement which was used to apply annotation to declaration/type.
|
||||||
|
*
|
||||||
|
* Present only for declarations from sources. For declarations from other places (libraries, stdlib) it's `null`
|
||||||
|
*/
|
||||||
public val psi: KtAnnotationEntry?,
|
public val psi: KtAnnotationEntry?,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [AnnotationUseSiteTarget] to which annotation was applied. May be not-null only for annotation applications for declarations.
|
||||||
|
*
|
||||||
|
* See in more details in [Kotlin Documentation](https://kotlinlang.org/docs/annotations.html#annotation-use-site-targets) for more information about annotation targets.
|
||||||
|
*/
|
||||||
public val useSiteTarget: AnnotationUseSiteTarget?,
|
public val useSiteTarget: AnnotationUseSiteTarget?,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of annotation arguments which were applied when constructing annotation. Every argument is [KtAnnotationValue]
|
||||||
|
*/
|
||||||
public val arguments: List<KtNamedAnnotationValue>,
|
public val arguments: List<KtNamedAnnotationValue>,
|
||||||
)
|
)
|
||||||
+63
-14
@@ -36,11 +36,17 @@ public sealed class KtAnnotationValue(
|
|||||||
*/
|
*/
|
||||||
public object KtUnsupportedAnnotationValue : KtAnnotationValue()
|
public object KtUnsupportedAnnotationValue : KtAnnotationValue()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of annotation values. E.g: `@A([1, 2])`
|
||||||
|
*/
|
||||||
public class KtArrayAnnotationValue(
|
public class KtArrayAnnotationValue(
|
||||||
public val values: Collection<KtAnnotationValue>,
|
public val values: Collection<KtAnnotationValue>,
|
||||||
override val sourcePsi: KtElement?,
|
override val sourcePsi: KtElement?,
|
||||||
) : KtAnnotationValue()
|
) : KtAnnotationValue()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Other annotation used as argument. E.g: `@A(B)` where `B` is annotation too
|
||||||
|
*/
|
||||||
public class KtAnnotationApplicationValue(
|
public class KtAnnotationApplicationValue(
|
||||||
public val annotationValue: KtAnnotationApplication,
|
public val annotationValue: KtAnnotationApplication,
|
||||||
) : KtAnnotationValue() {
|
) : KtAnnotationValue() {
|
||||||
@@ -48,30 +54,73 @@ public class KtAnnotationApplicationValue(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public sealed class KtKClassAnnotationValue : KtAnnotationValue()
|
/**
|
||||||
|
* Class reference used as annotation argument. E.g: `@A(String::class)`
|
||||||
|
*/
|
||||||
|
public sealed class KtKClassAnnotationValue : KtAnnotationValue() {
|
||||||
|
/**
|
||||||
|
* Non-local Class reference used as annotation value. E.g: `@A(String::class)`
|
||||||
|
*/
|
||||||
|
public class KtNonLocalKClassAnnotationValue(
|
||||||
|
/**
|
||||||
|
* Fully qualified name of the class used
|
||||||
|
*/
|
||||||
|
public val classId: ClassId,
|
||||||
|
override val sourcePsi: KtElement?,
|
||||||
|
) : KtKClassAnnotationValue()
|
||||||
|
|
||||||
public class KtNonLocalKClassAnnotationValue(
|
/**
|
||||||
public val classId: ClassId,
|
* Non-local class reference used as annotation argument.
|
||||||
override val sourcePsi: KtElement?,
|
*
|
||||||
) : KtKClassAnnotationValue()
|
* E.g:
|
||||||
|
* ```
|
||||||
|
* fun x() {
|
||||||
|
* class Y
|
||||||
|
*
|
||||||
|
* @A(B::class)
|
||||||
|
* fun foo() {}
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
public class KtLocalKClassAnnotationValue(
|
||||||
|
/**
|
||||||
|
* [PsiElement] of the class used. As we can get non-local class only for sources, it is always present.
|
||||||
|
*/
|
||||||
|
public val ktClass: KtClassOrObject,
|
||||||
|
override val sourcePsi: KtElement?,
|
||||||
|
) : KtKClassAnnotationValue()
|
||||||
|
|
||||||
public class KtLocalKClassAnnotationValue(
|
/**
|
||||||
public val ktClass: KtClassOrObject,
|
* Non-existing class reference used as annotation argument. E.g: `@A(NON_EXISTING_CLASS::class)`
|
||||||
override val sourcePsi: KtElement?,
|
*/
|
||||||
) : KtKClassAnnotationValue()
|
public class KtErrorClassAnnotationValue(
|
||||||
|
override val sourcePsi: KtElement?,
|
||||||
public class KtErrorClassAnnotationValue(
|
) : KtKClassAnnotationValue()
|
||||||
override val sourcePsi: KtElement?,
|
}
|
||||||
) : KtKClassAnnotationValue()
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some enum entry (enum constant) used as annotation argument. E.g: `@A(Color.RED)`
|
||||||
|
*/
|
||||||
public class KtEnumEntryAnnotationValue(
|
public class KtEnumEntryAnnotationValue(
|
||||||
|
/**
|
||||||
|
* Fully qualified name of used enum entry.
|
||||||
|
*/
|
||||||
public val callableId: CallableId?,
|
public val callableId: CallableId?,
|
||||||
override val sourcePsi: KtElement?,
|
override val sourcePsi: KtElement?,
|
||||||
) : KtAnnotationValue()
|
) : KtAnnotationValue()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Some constant value (which may be used as initializer of `const val`) used as annotation argument. It may be String literal, number literal or some simple expression.
|
||||||
|
* E.g: `@A(1 +2, "a" + "b")` -- both arguments here are [KtConstantAnnotationValue]
|
||||||
|
* @see [KtConstantValue]
|
||||||
|
*/
|
||||||
public class KtConstantAnnotationValue(
|
public class KtConstantAnnotationValue(
|
||||||
public val constantValue: KtConstantValue,
|
public val constantValue: KtConstantValue,
|
||||||
) : KtAnnotationValue()
|
) : KtAnnotationValue()
|
||||||
|
|
||||||
public fun KtAnnotationValue.render(): String =
|
|
||||||
|
/**
|
||||||
|
* Render annotation value, resulted string is a valid Kotlin source code.
|
||||||
|
*/
|
||||||
|
public fun KtAnnotationValue.renderAsSourceCode(): String =
|
||||||
KtAnnotationValueRenderer.render(this)
|
KtAnnotationValueRenderer.render(this)
|
||||||
+5
-5
@@ -7,8 +7,8 @@ package org.jetbrains.kotlin.analysis.api.annotations
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.renderer.render
|
import org.jetbrains.kotlin.renderer.render
|
||||||
|
|
||||||
public object KtAnnotationValueRenderer {
|
internal object KtAnnotationValueRenderer {
|
||||||
public fun render(value: KtAnnotationValue): String = buildString {
|
fun render(value: KtAnnotationValue): String = buildString {
|
||||||
renderConstantValue(value)
|
renderConstantValue(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,9 +37,9 @@ public object KtAnnotationValueRenderer {
|
|||||||
|
|
||||||
private fun StringBuilder.renderKClassAnnotationValue(value: KtKClassAnnotationValue) {
|
private fun StringBuilder.renderKClassAnnotationValue(value: KtKClassAnnotationValue) {
|
||||||
when (value) {
|
when (value) {
|
||||||
is KtErrorClassAnnotationValue -> append("UNRESOLVED_CLASS")
|
is KtKClassAnnotationValue.KtErrorClassAnnotationValue -> append("UNRESOLVED_CLASS")
|
||||||
is KtLocalKClassAnnotationValue -> append(value.ktClass.nameAsName?.render())
|
is KtKClassAnnotationValue.KtLocalKClassAnnotationValue -> append(value.ktClass.nameAsName?.render())
|
||||||
is KtNonLocalKClassAnnotationValue -> append(value.classId.asSingleFqName().render())
|
is KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue -> append(value.classId.asSingleFqName().render())
|
||||||
}
|
}
|
||||||
append("::class")
|
append("::class")
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -5,4 +5,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.api.annotations
|
package org.jetbrains.kotlin.analysis.api.annotations
|
||||||
|
|
||||||
public data class KtNamedAnnotationValue(val name: String, val expression: KtAnnotationValue)
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name-Value pair which is used as annotation argument.
|
||||||
|
*/
|
||||||
|
public data class KtNamedAnnotationValue(val name: Name, val expression: KtAnnotationValue)
|
||||||
@@ -9,10 +9,28 @@ import org.jetbrains.kotlin.psi.KtElement
|
|||||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Kotlin constant value. This value amy be used as `const val` initializer or annotation argument.
|
||||||
|
* Also, may represent evaluated constant value. So, `1 + 2` will be represented as `KtIntConstantValue(3)`
|
||||||
|
*
|
||||||
|
* For more info about constant values please see [official Kotlin documentation](https://kotlinlang.org/docs/properties.html#compile-time-constants])
|
||||||
|
*/
|
||||||
public sealed class KtConstantValue(public val constantValueKind: ConstantValueKind<*>) {
|
public sealed class KtConstantValue(public val constantValueKind: ConstantValueKind<*>) {
|
||||||
|
/**
|
||||||
|
* The constant value. The type of this value is always the type specified in its name, i.e, it is `Boolean` for [KtBooleanConstantValue]
|
||||||
|
*
|
||||||
|
* It is null only for [KtNullConstantValue]
|
||||||
|
*/
|
||||||
public abstract val value: Any?
|
public abstract val value: Any?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Source element from which the value was created. May be null for constants from non-source files.
|
||||||
|
*/
|
||||||
public abstract val sourcePsi: KtElement?
|
public abstract val sourcePsi: KtElement?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constant value represented as Kotlin code. E.g: `1`, `2f, `3u` `null`, `"str"`
|
||||||
|
*/
|
||||||
public abstract fun renderAsKotlinConstant(): String
|
public abstract fun renderAsKotlinConstant(): String
|
||||||
|
|
||||||
public class KtNullConstantValue(override val sourcePsi: KtElement?) : KtConstantValue(ConstantValueKind.Null) {
|
public class KtNullConstantValue(override val sourcePsi: KtElement?) : KtConstantValue(ConstantValueKind.Null) {
|
||||||
@@ -111,6 +129,9 @@ public sealed class KtConstantValue(public val constantValueKind: ConstantValueK
|
|||||||
override fun renderAsKotlinConstant(): String = value.toString()
|
override fun renderAsKotlinConstant(): String = value.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Value which is not cosntant or there was an error (e.g, division by 0) bug during value evaluation
|
||||||
|
*/
|
||||||
public class KtErrorConstantValue(
|
public class KtErrorConstantValue(
|
||||||
public val errorMessage: String,
|
public val errorMessage: String,
|
||||||
override val sourcePsi: KtElement?,
|
override val sourcePsi: KtElement?,
|
||||||
|
|||||||
+2
-1
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter
|
|||||||
import org.jetbrains.kotlin.analysis.utils.printer.prettyPrint
|
import org.jetbrains.kotlin.analysis.utils.printer.prettyPrint
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.name.*
|
import org.jetbrains.kotlin.name.*
|
||||||
|
import org.jetbrains.kotlin.renderer.render
|
||||||
import java.lang.reflect.InvocationTargetException
|
import java.lang.reflect.InvocationTargetException
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
@@ -138,7 +139,7 @@ public object DebugSymbolRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun PrettyPrinter.renderNamedConstantValue(value: KtNamedAnnotationValue) {
|
private fun PrettyPrinter.renderNamedConstantValue(value: KtNamedAnnotationValue) {
|
||||||
append(value.name).append(" = ")
|
append(value.name.render()).append(" = ")
|
||||||
renderValue(value.expression)
|
renderValue(value.expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -45,7 +45,7 @@ private class FirNameValuePairForAnnotationArgument(
|
|||||||
override fun setValue(p0: PsiAnnotationMemberValue) = cannotModify()
|
override fun setValue(p0: PsiAnnotationMemberValue) = cannotModify()
|
||||||
|
|
||||||
private val _nameIdentifier: PsiIdentifier by lazyPub {
|
private val _nameIdentifier: PsiIdentifier by lazyPub {
|
||||||
LightIdentifier(parent.manager, constantValue.name)
|
LightIdentifier(parent.manager, constantValue.name.asString())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getNameIdentifier(): PsiIdentifier = _nameIdentifier
|
override fun getNameIdentifier(): PsiIdentifier = _nameIdentifier
|
||||||
@@ -54,5 +54,5 @@ private class FirNameValuePairForAnnotationArgument(
|
|||||||
|
|
||||||
override fun getLiteralValue(): String? = (value as? PsiLiteralExpression)?.value?.toString()
|
override fun getLiteralValue(): String? = (value as? PsiLiteralExpression)?.value?.toString()
|
||||||
|
|
||||||
override fun getName(): String = constantValue.name
|
override fun getName(): String = constantValue.name.asString()
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -202,13 +202,13 @@ internal fun KtAnnotationValue.toAnnotationMemberValue(parent: PsiElement): PsiA
|
|||||||
FirPsiExpression(sourcePsi, parent, psiExpression)
|
FirPsiExpression(sourcePsi, parent, psiExpression)
|
||||||
}
|
}
|
||||||
KtUnsupportedAnnotationValue -> null
|
KtUnsupportedAnnotationValue -> null
|
||||||
is KtErrorClassAnnotationValue -> null
|
is KtKClassAnnotationValue.KtErrorClassAnnotationValue -> null
|
||||||
is KtLocalKClassAnnotationValue -> null
|
is KtKClassAnnotationValue.KtLocalKClassAnnotationValue -> null
|
||||||
is KtNonLocalKClassAnnotationValue -> toAnnotationMemberValue(parent)
|
is KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue -> toAnnotationMemberValue(parent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtNonLocalKClassAnnotationValue.toAnnotationMemberValue(parent: PsiElement): PsiExpression? {
|
private fun KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue.toAnnotationMemberValue(parent: PsiElement): PsiExpression? {
|
||||||
val fqName = classId.asSingleFqName()
|
val fqName = classId.asSingleFqName()
|
||||||
val canonicalText = psiType(
|
val canonicalText = psiType(
|
||||||
fqName.asString(), parent, boxPrimitiveType = false /* TODO value.arrayNestedness > 0*/,
|
fqName.asString(), parent, boxPrimitiveType = false /* TODO value.arrayNestedness > 0*/,
|
||||||
|
|||||||
Reference in New Issue
Block a user