IR: annotations are represented as IrConstructorCall elements
Also, they are rendered somewhat nicer
This commit is contained in:
+3
-3
@@ -48,8 +48,8 @@ abstract class WrappedDeclarationDescriptor<T : IrDeclaration>(annotations: Anno
|
||||
Annotations.create(ownerAnnotations.map { it.toAnnotationDescriptor() })
|
||||
}
|
||||
|
||||
private fun IrCall.toAnnotationDescriptor(): AnnotationDescriptor {
|
||||
assert(symbol.owner is IrConstructor && symbol.owner.parentAsClass.isAnnotationClass) {
|
||||
private fun IrConstructorCall.toAnnotationDescriptor(): AnnotationDescriptor {
|
||||
assert(symbol.owner.parentAsClass.isAnnotationClass) {
|
||||
"Expected call to constructor of annotation class but was: ${this.dump()}"
|
||||
}
|
||||
return AnnotationDescriptorImpl(
|
||||
@@ -88,7 +88,7 @@ abstract class WrappedDeclarationDescriptor<T : IrDeclaration>(annotations: Anno
|
||||
|
||||
this is IrClassReference -> KClassValue(classType.classifierOrFail.descriptor.classId!!, /*TODO*/0)
|
||||
|
||||
this is IrCall -> AnnotationValue(this.toAnnotationDescriptor())
|
||||
this is IrConstructorCall -> AnnotationValue(this.toAnnotationDescriptor())
|
||||
|
||||
else -> error("$this is not expected: ${this.dump()}")
|
||||
}
|
||||
|
||||
@@ -246,18 +246,11 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
|
||||
): IrExpression =
|
||||
call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
val irType = constructorDescriptor.returnType.toIrType()
|
||||
val classTypeParametersCount = constructorDescriptor.constructedClass.original.declaredTypeParameters.size
|
||||
val totalTypeParametersCount = constructorDescriptor.typeParameters.size
|
||||
|
||||
IrConstructorCallImpl(
|
||||
IrConstructorCallImpl.fromSymbolDescriptor(
|
||||
startOffset, endOffset,
|
||||
irType,
|
||||
context.symbolTable.referenceConstructor(constructorDescriptor.original),
|
||||
constructorDescriptor,
|
||||
typeArgumentsCount = totalTypeParametersCount,
|
||||
constructorTypeArgumentsCount = totalTypeParametersCount - classTypeParametersCount,
|
||||
valueArgumentsCount = constructorDescriptor.valueParameters.size,
|
||||
origin = origin
|
||||
origin
|
||||
).run {
|
||||
putTypeArguments(call.typeArguments) { it.toIrType() }
|
||||
dispatchReceiver = dispatchReceiverValue?.load()
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
|
||||
interface IrAnnotationContainer {
|
||||
val annotations: MutableList<IrCall>
|
||||
val annotations: MutableList<IrConstructorCall>
|
||||
}
|
||||
+2
-1
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
|
||||
import org.jetbrains.kotlin.ir.declarations.MetadataSource
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
|
||||
abstract class IrDeclarationBase(
|
||||
startOffset: Int,
|
||||
@@ -32,7 +33,7 @@ abstract class IrDeclarationBase(
|
||||
|
||||
override lateinit var parent: IrDeclarationParent
|
||||
|
||||
override val annotations: MutableList<IrCall> = ArrayList()
|
||||
override val annotations: MutableList<IrConstructorCall> = ArrayList()
|
||||
|
||||
override val metadata: MetadataSource?
|
||||
get() = null
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.ir.SourceManager
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.MetadataSource
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFileSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFileSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
@@ -55,7 +55,7 @@ class IrFileImpl(
|
||||
|
||||
override val declarations: MutableList<IrDeclaration> = ArrayList()
|
||||
|
||||
override val annotations: MutableList<IrCall> = ArrayList()
|
||||
override val annotations: MutableList<IrConstructorCall> = ArrayList()
|
||||
|
||||
override var metadata: MetadataSource.File? = null
|
||||
|
||||
|
||||
+2
-1
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrDeclarationBase
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.TypeTranslator
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
@@ -50,7 +51,7 @@ abstract class IrLazyDeclarationBase(
|
||||
createLazyParent()!!
|
||||
}
|
||||
|
||||
override val annotations: MutableList<IrCall> by lazy {
|
||||
override val annotations: MutableList<IrConstructorCall> by lazy {
|
||||
descriptor.annotations.map {
|
||||
typeTranslator.constantValueGenerator.generateAnnotationConstructorCall(it)
|
||||
}.toMutableList()
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.ir.expressions.impl
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
@@ -45,6 +46,12 @@ class IrCallImpl(
|
||||
),
|
||||
IrCall {
|
||||
|
||||
init {
|
||||
if (symbol is IrClassSymbol) {
|
||||
throw AssertionError("Should be IrConstructorCall: $descriptor")
|
||||
}
|
||||
}
|
||||
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
|
||||
+50
-1
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.ir.expressions.impl
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
@@ -28,4 +29,52 @@ class IrConstructorCallImpl(
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitConstructorCall(this, data)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun fromSymbolDescriptor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: IrType,
|
||||
constructorSymbol: IrConstructorSymbol,
|
||||
origin: IrStatementOrigin? = null
|
||||
): IrConstructorCallImpl {
|
||||
val constructorDescriptor = constructorSymbol.descriptor
|
||||
val classTypeParametersCount = constructorDescriptor.constructedClass.original.declaredTypeParameters.size
|
||||
val totalTypeParametersCount = constructorDescriptor.typeParameters.size
|
||||
val valueParametersCount = constructorDescriptor.valueParameters.size
|
||||
|
||||
return IrConstructorCallImpl(
|
||||
startOffset, endOffset,
|
||||
type,
|
||||
constructorSymbol,
|
||||
constructorDescriptor,
|
||||
totalTypeParametersCount,
|
||||
totalTypeParametersCount - classTypeParametersCount,
|
||||
valueParametersCount,
|
||||
origin
|
||||
)
|
||||
}
|
||||
|
||||
fun fromSymbolDescriptor(
|
||||
type: IrType,
|
||||
constructorSymbol: IrConstructorSymbol,
|
||||
origin: IrStatementOrigin? = null
|
||||
): IrConstructorCallImpl {
|
||||
val constructorDescriptor = constructorSymbol.descriptor
|
||||
val classTypeParametersCount = constructorDescriptor.constructedClass.original.declaredTypeParameters.size
|
||||
val totalTypeParametersCount = constructorDescriptor.typeParameters.size
|
||||
val valueParametersCount = constructorDescriptor.valueParameters.size
|
||||
|
||||
return IrConstructorCallImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
type,
|
||||
constructorSymbol, constructorDescriptor,
|
||||
totalTypeParametersCount,
|
||||
totalTypeParametersCount - classTypeParametersCount,
|
||||
valueParametersCount,
|
||||
origin
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.types
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
interface IrType {
|
||||
val annotations: List<IrCall>
|
||||
val annotations: List<IrConstructorCall>
|
||||
|
||||
/**
|
||||
* @return true if this type is equal to [other] symbolically. Note that this is NOT EQUIVALENT to the full type checking algorithm
|
||||
@@ -46,4 +46,4 @@ interface IrStarProjection : IrTypeArgument
|
||||
interface IrTypeProjection : IrTypeArgument {
|
||||
val variance: Variance
|
||||
val type: IrType
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.types.impl
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.symbols.FqNameEqualityChecker
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
@@ -17,14 +17,14 @@ class IrSimpleTypeImpl(
|
||||
override val classifier: IrClassifierSymbol,
|
||||
override val hasQuestionMark: Boolean,
|
||||
override val arguments: List<IrTypeArgument>,
|
||||
annotations: List<IrCall>
|
||||
annotations: List<IrConstructorCall>
|
||||
) : IrTypeBase(kotlinType, annotations, Variance.INVARIANT), IrSimpleType, IrTypeProjection {
|
||||
|
||||
constructor(
|
||||
classifier: IrClassifierSymbol,
|
||||
hasQuestionMark: Boolean,
|
||||
arguments: List<IrTypeArgument>,
|
||||
annotations: List<IrCall>
|
||||
annotations: List<IrConstructorCall>
|
||||
) : this(null, classifier, hasQuestionMark, arguments, annotations)
|
||||
|
||||
override fun equals(other: Any?): Boolean =
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.ir.types.impl
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -13,7 +14,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
abstract class IrTypeBase(
|
||||
val kotlinType: KotlinType?,
|
||||
override val annotations: List<IrCall>,
|
||||
override val annotations: List<IrConstructorCall>,
|
||||
override val variance: Variance
|
||||
) : IrType, IrTypeProjection {
|
||||
override val type: IrType get() = this
|
||||
@@ -21,7 +22,7 @@ abstract class IrTypeBase(
|
||||
|
||||
class IrErrorTypeImpl(
|
||||
kotlinType: KotlinType?,
|
||||
annotations: List<IrCall>,
|
||||
annotations: List<IrConstructorCall>,
|
||||
variance: Variance
|
||||
) : IrTypeBase(kotlinType, annotations, variance), IrErrorType {
|
||||
override fun equals(other: Any?): Boolean = other is IrErrorTypeImpl
|
||||
@@ -31,7 +32,7 @@ class IrErrorTypeImpl(
|
||||
|
||||
class IrDynamicTypeImpl(
|
||||
kotlinType: KotlinType?,
|
||||
annotations: List<IrCall>,
|
||||
annotations: List<IrConstructorCall>,
|
||||
variance: Variance
|
||||
) : IrTypeBase(kotlinType, annotations, variance), IrDynamicType, IrTypeProjection {
|
||||
override fun equals(other: Any?): Boolean = other is IrDynamicTypeImpl
|
||||
@@ -52,7 +53,7 @@ object IrStarProjectionImpl : IrStarProjection {
|
||||
|
||||
@Deprecated("Hack to temporary cover late type initialization")
|
||||
object IrUninitializedType : IrType {
|
||||
override val annotations: List<IrCall> = emptyList()
|
||||
override val annotations: List<IrConstructorCall> = emptyList()
|
||||
|
||||
override fun equals(other: Any?): Boolean = this === other
|
||||
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.util
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.ir.SourceManager
|
||||
import org.jetbrains.kotlin.ir.SourceRangeInfo
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -74,15 +75,15 @@ fun IrSimpleFunction.overrides(other: IrSimpleFunction): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
private val IrCall.annotationClass
|
||||
get() = (this.symbol.owner as IrConstructor).constructedClass
|
||||
private val IrConstructorCall.annotationClass
|
||||
get() = this.symbol.owner.constructedClass
|
||||
|
||||
fun List<IrCall>.hasAnnotation(fqName: FqName): Boolean =
|
||||
this.any { it.annotationClass.fqNameSafe == fqName }
|
||||
fun List<IrConstructorCall>.hasAnnotation(fqName: FqName): Boolean =
|
||||
any { it.annotationClass.fqNameSafe == fqName }
|
||||
|
||||
fun List<IrConstructorCall>.findAnnotation(fqName: FqName): IrConstructorCall? =
|
||||
firstOrNull { it.annotationClass.fqNameSafe == fqName }
|
||||
|
||||
fun List<IrCall>.findAnnotation(fqName: FqName): IrCall? = this.firstOrNull {
|
||||
it.annotationClass.fqNameSafe == fqName
|
||||
}
|
||||
val IrDeclaration.fileEntry: SourceManager.FileEntry
|
||||
get() = parent.let {
|
||||
when (it) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
@@ -19,7 +20,6 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.constants.*
|
||||
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
|
||||
import org.jetbrains.kotlin.resolve.source.PsiSourceFile
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
@@ -73,7 +73,7 @@ class ConstantValueGenerator(
|
||||
is EnumValue -> {
|
||||
val enumEntryDescriptor =
|
||||
constantKtType.memberScope.getContributedClassifier(constantValue.enumEntryName, NoLookupLocation.FROM_BACKEND)
|
||||
?: throw AssertionError("No such enum entry ${constantValue.enumEntryName} in $constantType")
|
||||
?: throw AssertionError("No such enum entry ${constantValue.enumEntryName} in $constantType")
|
||||
if (enumEntryDescriptor !is ClassDescriptor) {
|
||||
throw AssertionError("Enum entry $enumEntryDescriptor should be a ClassDescriptor")
|
||||
}
|
||||
@@ -89,7 +89,7 @@ class ConstantValueGenerator(
|
||||
is KClassValue -> {
|
||||
val classifierKtType = constantValue.getArgumentType(moduleDescriptor)
|
||||
val classifierDescriptor = classifierKtType.constructor.declarationDescriptor
|
||||
?: throw AssertionError("Unexpected KClassValue: $classifierKtType")
|
||||
?: throw AssertionError("Unexpected KClassValue: $classifierKtType")
|
||||
|
||||
IrClassReferenceImpl(
|
||||
startOffset, endOffset,
|
||||
@@ -103,29 +103,28 @@ class ConstantValueGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
fun generateAnnotationConstructorCall(annotationDescriptor: AnnotationDescriptor): IrCall {
|
||||
fun generateAnnotationConstructorCall(annotationDescriptor: AnnotationDescriptor): IrConstructorCall {
|
||||
val annotationType = annotationDescriptor.type
|
||||
val annotationClassDescriptor = annotationType.constructor.declarationDescriptor as? ClassDescriptor
|
||||
?: throw AssertionError("No declaration descriptor for annotation $annotationDescriptor")
|
||||
?: throw AssertionError("No declaration descriptor for annotation $annotationDescriptor")
|
||||
|
||||
assert(DescriptorUtils.isAnnotationClass(annotationClassDescriptor)) {
|
||||
"Annotation class expected: $annotationClassDescriptor"
|
||||
}
|
||||
|
||||
val primaryConstructorDescriptor = annotationClassDescriptor.unsubstitutedPrimaryConstructor
|
||||
?: annotationClassDescriptor.constructors.singleOrNull()
|
||||
?: throw AssertionError("No constructor for annotation class $annotationClassDescriptor")
|
||||
?: annotationClassDescriptor.constructors.singleOrNull()
|
||||
?: throw AssertionError("No constructor for annotation class $annotationClassDescriptor")
|
||||
val primaryConstructorSymbol = symbolTable.referenceConstructor(primaryConstructorDescriptor)
|
||||
|
||||
val psi = annotationDescriptor.source.safeAs<PsiSourceElement>()?.psi
|
||||
val startOffset = psi?.takeUnless { it.containingFile.fileType.isBinary }?.startOffset ?: UNDEFINED_OFFSET
|
||||
val endOffset = psi?.takeUnless { it.containingFile.fileType.isBinary }?.endOffset ?: UNDEFINED_OFFSET
|
||||
|
||||
val irCall = IrCallImpl(
|
||||
val irCall = IrConstructorCallImpl.fromSymbolDescriptor(
|
||||
startOffset, endOffset,
|
||||
annotationType.toIrType(),
|
||||
primaryConstructorSymbol, primaryConstructorDescriptor,
|
||||
typeArgumentsCount = 0
|
||||
primaryConstructorSymbol
|
||||
)
|
||||
|
||||
for (valueParameter in primaryConstructorDescriptor.valueParameters) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.kotlin.ir.util
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeProjection
|
||||
@@ -39,14 +39,15 @@ class DeepCopyTypeRemapper(
|
||||
}
|
||||
}
|
||||
|
||||
val annotations = type.annotations.map { it.transform(deepCopy, null) as IrCall }
|
||||
val annotations = type.annotations.map { it.transform(deepCopy, null) as IrConstructorCall }
|
||||
|
||||
return IrSimpleTypeImpl(
|
||||
null,
|
||||
symbolRemapper.getReferencedClassifier(type.classifier),
|
||||
type.hasQuestionMark,
|
||||
arguments,
|
||||
annotations)
|
||||
annotations
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -99,8 +99,8 @@ class DumpIrTreeVisitor(
|
||||
}
|
||||
|
||||
private fun dumpAnnotations(element: IrAnnotationContainer) {
|
||||
element.annotations.dumpItems("annotations") {
|
||||
element.annotations.dumpElements()
|
||||
element.annotations.dumpItems("annotations") { irAnnotation: IrConstructorCall ->
|
||||
printer.println(elementRenderer.renderAsAnnotation(irAnnotation))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ class DumpIrTreeVisitor(
|
||||
dumpTypeArguments(expression)
|
||||
expression.dispatchReceiver?.accept(this, "\$this")
|
||||
expression.extensionReceiver?.accept(this, "\$receiver")
|
||||
val valueParameterNames = expression.getValueParameterNames(expression.valueArgumentsCount)
|
||||
val valueParameterNames = expression.getValueParameterNamesForDebug()
|
||||
for (index in 0 until expression.valueArgumentsCount) {
|
||||
expression.getValueArgument(index)?.accept(this, valueParameterNames[index])
|
||||
}
|
||||
@@ -175,10 +175,14 @@ class DumpIrTreeVisitor(
|
||||
expression.dumpLabeledElementWith(data) {
|
||||
dumpTypeArguments(expression)
|
||||
expression.outerClassReceiver?.accept(this, "\$outer")
|
||||
val valueParameterNames = expression.getValueParameterNames(expression.valueArgumentsCount)
|
||||
for (index in 0 until expression.valueArgumentsCount) {
|
||||
expression.getValueArgument(index)?.accept(this, valueParameterNames[index])
|
||||
}
|
||||
dumpConstructorValueArguments(expression)
|
||||
}
|
||||
}
|
||||
|
||||
private fun dumpConstructorValueArguments(expression: IrConstructorCall) {
|
||||
val valueParameterNames = expression.getValueParameterNamesForDebug()
|
||||
for (index in 0 until expression.valueArgumentsCount) {
|
||||
expression.getValueArgument(index)?.accept(this, valueParameterNames[index])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,15 +212,6 @@ class DumpIrTreeVisitor(
|
||||
else
|
||||
getPlaceholderParameterNames(expectedCount)
|
||||
|
||||
private fun IrMemberAccessExpression.getValueParameterNames(expectedCount: Int): List<String> =
|
||||
if (this is IrDeclarationReference && symbol.isBound)
|
||||
symbol.owner.getValueParameterNames(expectedCount)
|
||||
else
|
||||
getPlaceholderParameterNames(expectedCount)
|
||||
|
||||
private fun getPlaceholderParameterNames(expectedCount: Int) =
|
||||
(1..expectedCount).map { "$it" }
|
||||
|
||||
private fun IrSymbolOwner.getTypeParameterNames(expectedCount: Int): List<String> =
|
||||
if (this is IrTypeParametersContainer) {
|
||||
val typeParameters = if (this is IrConstructor) getFullTypeParametersList() else this.typeParameters
|
||||
@@ -230,18 +225,6 @@ class DumpIrTreeVisitor(
|
||||
getPlaceholderParameterNames(expectedCount)
|
||||
}
|
||||
|
||||
private fun IrSymbolOwner.getValueParameterNames(expectedCount: Int): List<String> =
|
||||
if (this is IrFunction) {
|
||||
(0 until expectedCount).map {
|
||||
if (it < valueParameters.size)
|
||||
valueParameters[it].name.asString()
|
||||
else
|
||||
"${it + 1}"
|
||||
}
|
||||
} else {
|
||||
getPlaceholderParameterNames(expectedCount)
|
||||
}
|
||||
|
||||
private fun IrConstructor.getFullTypeParametersList(): List<IrTypeParameter> {
|
||||
val parentClass = try {
|
||||
parent as? IrClass ?: return typeParameters
|
||||
@@ -378,3 +361,24 @@ class DumpTreeFromSourceLineVisitor(
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun IrMemberAccessExpression.getValueParameterNamesForDebug(): List<String> {
|
||||
val expectedCount = valueArgumentsCount
|
||||
return if (this is IrDeclarationReference && symbol.isBound) {
|
||||
val owner = symbol.owner
|
||||
if (owner is IrFunction) {
|
||||
(0 until expectedCount).map {
|
||||
if (it < owner.valueParameters.size)
|
||||
owner.valueParameters[it].name.asString()
|
||||
else
|
||||
"${it + 1}"
|
||||
}
|
||||
} else {
|
||||
getPlaceholderParameterNames(expectedCount)
|
||||
}
|
||||
} else
|
||||
getPlaceholderParameterNames(expectedCount)
|
||||
}
|
||||
|
||||
internal fun getPlaceholderParameterNames(expectedCount: Int) =
|
||||
(1..expectedCount).map { "$it" }
|
||||
|
||||
@@ -299,7 +299,7 @@ tailrec fun IrElement.getPackageFragment(): IrPackageFragment? {
|
||||
}
|
||||
}
|
||||
|
||||
fun IrAnnotationContainer.getAnnotation(name: FqName) =
|
||||
fun IrAnnotationContainer.getAnnotation(name: FqName): IrConstructorCall? =
|
||||
annotations.find {
|
||||
it.symbol.owner.parentAsClass.descriptor.fqNameSafe == name
|
||||
}
|
||||
|
||||
@@ -39,6 +39,53 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
||||
|
||||
fun renderSymbolReference(symbol: IrSymbol) = symbol.renderReference()
|
||||
|
||||
fun renderAsAnnotation(irAnnotation: IrConstructorCall): String =
|
||||
StringBuilder().also { it.renderAsAnnotation(irAnnotation) }.toString()
|
||||
|
||||
private fun StringBuilder.renderAsAnnotation(irAnnotation: IrConstructorCall) {
|
||||
val annotationClassName = try {
|
||||
irAnnotation.symbol.owner.parentAsClass.name.asString()
|
||||
} catch (e: Exception) {
|
||||
"<unbound>"
|
||||
}
|
||||
append(annotationClassName)
|
||||
|
||||
if (irAnnotation.valueArgumentsCount == 0) return
|
||||
|
||||
val valueParameterNames = irAnnotation.getValueParameterNamesForDebug()
|
||||
var first = true
|
||||
append("(")
|
||||
for (i in 0 until irAnnotation.valueArgumentsCount) {
|
||||
if (first) {
|
||||
first = false
|
||||
} else {
|
||||
append(", ")
|
||||
}
|
||||
append(valueParameterNames[i])
|
||||
append(" = ")
|
||||
renderAsAnnotationArgument(irAnnotation.getValueArgument(i))
|
||||
}
|
||||
append(")")
|
||||
}
|
||||
|
||||
private fun StringBuilder.renderAsAnnotationArgument(irElement: IrElement?) {
|
||||
when (irElement) {
|
||||
null -> append("<null>")
|
||||
is IrConstructorCall -> renderAsAnnotation(irElement)
|
||||
is IrConst<*> -> {
|
||||
append('\'')
|
||||
append(irElement.value.toString())
|
||||
append('\'')
|
||||
}
|
||||
is IrVararg -> {
|
||||
appendListWith(irElement.elements, "[", "]", ", ") {
|
||||
renderAsAnnotationArgument(it)
|
||||
}
|
||||
}
|
||||
else -> append(irElement.accept(this@RenderIrElementVisitor, null))
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun buildTrimEnd(fn: StringBuilder.() -> Unit): String =
|
||||
buildString(fn).trimEnd()
|
||||
|
||||
@@ -82,11 +129,11 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
||||
}
|
||||
|
||||
|
||||
private fun renderTypeAnnotations(annotations: List<IrCall>) =
|
||||
private fun renderTypeAnnotations(annotations: List<IrConstructorCall>) =
|
||||
if (annotations.isEmpty())
|
||||
""
|
||||
else
|
||||
annotations.joinToString(prefix = "", postfix = " ", separator = " ") { "@[${it.render()}]" }
|
||||
annotations.joinToString(prefix = "", postfix = " ", separator = " ") { "@[${renderAsAnnotation(it)}]" }
|
||||
|
||||
private fun IrSymbol.renderReference() =
|
||||
if (isBound)
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.IrTypeProjection
|
||||
import org.jetbrains.kotlin.ir.types.impl.*
|
||||
@@ -131,7 +132,7 @@ class TypeTranslator(
|
||||
}
|
||||
|
||||
|
||||
private fun translateTypeAnnotations(annotations: Annotations): List<IrCall> =
|
||||
private fun translateTypeAnnotations(annotations: Annotations): List<IrConstructorCall> =
|
||||
annotations.map(constantValueGenerator::generateAnnotationConstructorCall)
|
||||
|
||||
private fun translateTypeArguments(arguments: List<TypeProjection>) =
|
||||
|
||||
+80
-62
@@ -83,9 +83,9 @@ abstract class IrModuleDeserializer(
|
||||
|
||||
}
|
||||
|
||||
fun deserializeAnnotations(annotations: KotlinIr.Annotations): List<IrCall> {
|
||||
fun deserializeAnnotations(annotations: KotlinIr.Annotations): List<IrConstructorCall> {
|
||||
return annotations.annotationList.map {
|
||||
deserializeCall(it, 0, 0, builtIns.unitType) // TODO: need a proper deserialization here
|
||||
deserializeConstructorCall(it, 0, 0, builtIns.unitType) // TODO: need a proper deserialization here
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,6 +243,19 @@ abstract class IrModuleDeserializer(
|
||||
return IrClassReferenceImpl(start, end, type, symbol, classType)
|
||||
}
|
||||
|
||||
private fun deserializeConstructorCall(proto: KotlinIr.IrConstructorCall, start: Int, end: Int, type: IrType): IrConstructorCall {
|
||||
val symbol = deserializeIrSymbol(proto.symbol) as IrConstructorSymbol
|
||||
return IrConstructorCallImpl(
|
||||
start, end, type,
|
||||
symbol, symbol.descriptor,
|
||||
typeArgumentsCount = proto.memberAccess.typeArguments.typeArgumentCount,
|
||||
constructorTypeArgumentsCount = proto.constructorTypeArgumentsCount,
|
||||
valueArgumentsCount = proto.memberAccess.valueArgumentCount
|
||||
).also {
|
||||
deserializeMemberAccessCommon(it, proto.memberAccess)
|
||||
}
|
||||
}
|
||||
|
||||
private fun deserializeCall(proto: KotlinIr.IrCall, start: Int, end: Int, type: IrType): IrCall {
|
||||
val symbol = deserializeIrSymbol(proto.symbol) as IrFunctionSymbol
|
||||
|
||||
@@ -415,11 +428,11 @@ abstract class IrModuleDeserializer(
|
||||
val getter = if (proto.hasGetter()) deserializeIrSymbol(proto.getter) as IrSimpleFunctionSymbol else null
|
||||
val setter = if (proto.hasSetter()) deserializeIrSymbol(proto.setter) as IrSimpleFunctionSymbol else null
|
||||
val descriptor =
|
||||
if (proto.hasDescriptorReference())
|
||||
deserializeDescriptorReference(proto.descriptorReference) as PropertyDescriptor
|
||||
else
|
||||
field?.descriptor as? WrappedPropertyDescriptor // If field's descriptor coincides with property's.
|
||||
?: getterToPropertyDescriptorMap.getOrPut(getter!!) { WrappedPropertyDescriptor() }
|
||||
if (proto.hasDescriptorReference())
|
||||
deserializeDescriptorReference(proto.descriptorReference) as PropertyDescriptor
|
||||
else
|
||||
field?.descriptor as? WrappedPropertyDescriptor // If field's descriptor coincides with property's.
|
||||
?: getterToPropertyDescriptorMap.getOrPut(getter!!) { WrappedPropertyDescriptor() }
|
||||
|
||||
val callable = IrPropertyReferenceImpl(
|
||||
start, end, type,
|
||||
@@ -573,10 +586,10 @@ abstract class IrModuleDeserializer(
|
||||
// we create the loop before deserializing the body, so that
|
||||
// IrBreak statements have something to put into 'loop' field.
|
||||
private fun deserializeDoWhile(proto: KotlinIr.IrDoWhile, start: Int, end: Int, type: IrType) =
|
||||
deserializeLoop(proto.loop, deserializeLoopHeader(proto.loop.loopId) { IrDoWhileLoopImpl(start, end, type, null) })
|
||||
deserializeLoop(proto.loop, deserializeLoopHeader(proto.loop.loopId) { IrDoWhileLoopImpl(start, end, type, null) })
|
||||
|
||||
private fun deserializeWhile(proto: KotlinIr.IrWhile, start: Int, end: Int, type: IrType) =
|
||||
deserializeLoop(proto.loop, deserializeLoopHeader(proto.loop.loopId) { IrWhileLoopImpl(start, end, type, null) })
|
||||
deserializeLoop(proto.loop, deserializeLoopHeader(proto.loop.loopId) { IrWhileLoopImpl(start, end, type, null) })
|
||||
|
||||
private fun deserializeDynamicMemberExpression(proto: KotlinIr.IrDynamicMemberExpression, start: Int, end: Int, type: IrType) =
|
||||
IrDynamicMemberExpressionImpl(start, end, type, deserializeString(proto.memberName), deserializeExpression(proto.receiver))
|
||||
@@ -741,6 +754,8 @@ abstract class IrModuleDeserializer(
|
||||
-> deserializeDynamicMemberExpression(proto.dynamicMember, start, end, type)
|
||||
DYNAMIC_OPERATOR
|
||||
-> deserializeDynamicOperatorExpression(proto.dynamicOperator, start, end, type)
|
||||
CONSTRUCTOR_CALL
|
||||
-> deserializeConstructorCall(proto.constructorCall, start, end, type)
|
||||
OPERATION_NOT_SET
|
||||
-> error("Expression deserialization not implemented: ${proto.operationCase}")
|
||||
}
|
||||
@@ -834,20 +849,22 @@ abstract class IrModuleDeserializer(
|
||||
val symbol = deserializeIrSymbol(proto.symbol) as IrClassSymbol
|
||||
|
||||
val modality = deserializeModality(proto.modality)
|
||||
val clazz = symbolTable.declareClass(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin,
|
||||
symbol.descriptor, modality) {
|
||||
val clazz = symbolTable.declareClass(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin,
|
||||
symbol.descriptor, modality
|
||||
) {
|
||||
IrClassImpl(
|
||||
start, end, origin,
|
||||
it,
|
||||
deserializeName(proto.name),
|
||||
deserializeClassKind(proto.kind),
|
||||
deserializeVisibility(proto.visibility),
|
||||
modality,
|
||||
proto.isCompanion,
|
||||
proto.isInner,
|
||||
proto.isData,
|
||||
proto.isExternal,
|
||||
proto.isInline
|
||||
start, end, origin,
|
||||
it,
|
||||
deserializeName(proto.name),
|
||||
deserializeClassKind(proto.kind),
|
||||
deserializeVisibility(proto.visibility),
|
||||
modality,
|
||||
proto.isCompanion,
|
||||
proto.isInner,
|
||||
proto.isData,
|
||||
proto.isExternal,
|
||||
proto.isInline
|
||||
)
|
||||
}
|
||||
|
||||
@@ -901,19 +918,19 @@ abstract class IrModuleDeserializer(
|
||||
val symbol = deserializeIrSymbol(proto.symbol) as IrSimpleFunctionSymbol
|
||||
|
||||
val function = symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin,
|
||||
symbol.descriptor, {
|
||||
IrFunctionImpl(
|
||||
start, end, origin, it,
|
||||
deserializeName(proto.base.name),
|
||||
deserializeVisibility(proto.base.visibility),
|
||||
deserializeModality(proto.modality),
|
||||
deserializeIrType(proto.base.returnType),
|
||||
proto.base.isInline,
|
||||
proto.base.isExternal,
|
||||
proto.isTailrec,
|
||||
proto.isSuspend
|
||||
)
|
||||
})
|
||||
symbol.descriptor, {
|
||||
IrFunctionImpl(
|
||||
start, end, origin, it,
|
||||
deserializeName(proto.base.name),
|
||||
deserializeVisibility(proto.base.visibility),
|
||||
deserializeModality(proto.modality),
|
||||
deserializeIrType(proto.base.returnType),
|
||||
proto.base.isInline,
|
||||
proto.base.isExternal,
|
||||
proto.isTailrec,
|
||||
proto.isSuspend
|
||||
)
|
||||
})
|
||||
|
||||
deserializeIrFunctionBase(proto.base, function as IrFunctionBase, start, end, origin)
|
||||
val overridden = proto.overriddenList.map { deserializeIrSymbol(it) as IrSimpleFunctionSymbol }
|
||||
@@ -1010,19 +1027,19 @@ abstract class IrModuleDeserializer(
|
||||
val symbol = deserializeIrSymbol(proto.symbol) as IrConstructorSymbol
|
||||
|
||||
val constructor = symbolTable.declareConstructor(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin,
|
||||
symbol.descriptor, {
|
||||
IrConstructorImpl(
|
||||
start, end, origin,
|
||||
it,
|
||||
deserializeName(proto.base.name),
|
||||
deserializeVisibility(proto.base.visibility),
|
||||
deserializeIrType(proto.base.returnType),
|
||||
proto.base.isInline,
|
||||
proto.base.isExternal,
|
||||
proto.isPrimary
|
||||
)
|
||||
symbol.descriptor, {
|
||||
IrConstructorImpl(
|
||||
start, end, origin,
|
||||
it,
|
||||
deserializeName(proto.base.name),
|
||||
deserializeVisibility(proto.base.visibility),
|
||||
deserializeIrType(proto.base.returnType),
|
||||
proto.base.isInline,
|
||||
proto.base.isExternal,
|
||||
proto.isPrimary
|
||||
)
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
deserializeIrFunctionBase(proto.base, constructor as IrFunctionBase, start, end, origin)
|
||||
return constructor
|
||||
@@ -1033,21 +1050,22 @@ abstract class IrModuleDeserializer(
|
||||
val symbol = deserializeIrSymbol(proto.symbol) as IrFieldSymbol
|
||||
val type = deserializeIrType(proto.type)
|
||||
val field = symbolTable.declareField(UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
irrelevantOrigin,
|
||||
symbol.descriptor,
|
||||
type,
|
||||
{ IrFieldImpl(
|
||||
start, end, origin,
|
||||
it,
|
||||
deserializeName(proto.name),
|
||||
type,
|
||||
deserializeVisibility(proto.visibility),
|
||||
proto.isFinal,
|
||||
proto.isExternal,
|
||||
proto.isStatic
|
||||
)
|
||||
}
|
||||
UNDEFINED_OFFSET,
|
||||
irrelevantOrigin,
|
||||
symbol.descriptor,
|
||||
type,
|
||||
{
|
||||
IrFieldImpl(
|
||||
start, end, origin,
|
||||
it,
|
||||
deserializeName(proto.name),
|
||||
type,
|
||||
deserializeVisibility(proto.visibility),
|
||||
proto.isFinal,
|
||||
proto.isExternal,
|
||||
proto.isStatic
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
val initializer = if (proto.hasInitializer()) deserializeExpression(proto.initializer) else null
|
||||
|
||||
+11
-4
@@ -173,10 +173,10 @@ open class IrModuleSerializer(
|
||||
Variance.INVARIANT -> KotlinIr.IrTypeVariance.INV
|
||||
}
|
||||
|
||||
fun serializeAnnotations(annotations: List<IrCall>): KotlinIr.Annotations {
|
||||
fun serializeAnnotations(annotations: List<IrConstructorCall>): KotlinIr.Annotations {
|
||||
val proto = KotlinIr.Annotations.newBuilder()
|
||||
annotations.forEach {
|
||||
proto.addAnnotation(serializeCall(it))
|
||||
proto.addAnnotation(serializeConstructorCall(it))
|
||||
}
|
||||
return proto.build()
|
||||
}
|
||||
@@ -245,12 +245,12 @@ open class IrModuleSerializer(
|
||||
}
|
||||
|
||||
// This is just IrType repacked as a data class, good to address a hash map.
|
||||
data class IrTypeKey (
|
||||
data class IrTypeKey(
|
||||
val kind: IrTypeKind,
|
||||
val classifier: IrClassifierSymbol?,
|
||||
val hasQuestionMark: Boolean?,
|
||||
val arguments: List<IrTypeArgumentKey>?,
|
||||
val annotations: List<IrCall>
|
||||
val annotations: List<IrConstructorCall>
|
||||
)
|
||||
|
||||
data class IrTypeArgumentKey (
|
||||
@@ -399,6 +399,13 @@ open class IrModuleSerializer(
|
||||
return proto.build()
|
||||
}
|
||||
|
||||
private fun serializeConstructorCall(call: IrConstructorCall): KotlinIr.IrConstructorCall =
|
||||
KotlinIr.IrConstructorCall.newBuilder().apply {
|
||||
symbol = serializeIrSymbol(call.symbol)
|
||||
constructorTypeArgumentsCount = call.constructorTypeArgumentsCount
|
||||
memberAccess = serializeMemberAccessCommon(call)
|
||||
}.build()
|
||||
|
||||
private fun serializeFunctionReference(callable: IrFunctionReference): KotlinIr.IrFunctionReference {
|
||||
val proto = KotlinIr.IrFunctionReference.newBuilder()
|
||||
.setSymbol(serializeIrSymbol(callable.symbol))
|
||||
|
||||
Reference in New Issue
Block a user