IR: annotations are represented as IrConstructorCall elements

Also, they are rendered somewhat nicer
This commit is contained in:
Dmitry Petrov
2019-03-26 13:11:04 +03:00
parent db7bcb6464
commit e3fd74a580
66 changed files with 540 additions and 643 deletions
@@ -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()
@@ -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>
}
@@ -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
@@ -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,
@@ -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>) =
@@ -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
@@ -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))