Hello. I'm trying to write a plugin, which counts ...
# arrow-meta
b
Hello. I'm trying to write a plugin, which counts size in bytes of data classes. In
irClass {...}
i'm modifying function body, but i don't know, how to return updated
irClass
😞
Copy code
val Meta.GenerateShallowSize: CliPlugin
    get() = "Generate shallowSize method" {
        meta(
            classDeclaration(this, { element.isData() }) { declaration ->
                Transform.replace(
                    replacing = declaration.element,
                    newDeclaration =
                        """|$`@annotations` $kind $name $`(typeParameters)` $`(params)` : $supertypes {
                           |   $body
                           |   fun shallowSize(): Unit
                           |}""".`class`
                )
            },
            irClass { clazz ->
                {
                    val function = clazz.functions.find { it.name.asString() == "shallowSize" }!!
                    with(DeclarationIrBuilder(pluginContext, function.symbol)) {
                            function.body = irBlockBody {
                                irInt(clazz.fields.map { it.type.byteSize() }.sum())
                            }
                    }
                    return clazz.
                }
            }
        )
    }
r
Hi @Babin Ruslan, The api for the
classDeclaration
part is no longer part of Meta and will be removed until we adapt to the new FIR frontend. As for the
irClass
you can instead of attempting to find the function
shallowSize
,add it yourself to the
irClass
. The IR DSL expect you to mutate the tree in place. In this case insert the function you want. This does not make it available for the same module frontend or IDE, so you can’t rely locally on a plugin and have
shallowSize
available in the IDE unless you fiddle with synthetic descriptors or wait for FIR to be stable in the kotlin compiler.
But it will work once compiled and packaged in a jar to be discoverable by others since in IR we are just generating compiled code and not sources.
b
My problem is implementing
TODO
in
irClass
. I couldn't find examples of using arrow-meta wrappers over kotlin IR. Here is my code:
Copy code
fun IrType.byteSize(): Int = when {
    this.isChar() -> Char.SIZE_BYTES
    this.isByte() -> Byte.SIZE_BYTES
    this.isShort() -> Short.SIZE_BYTES
    this.isInt() -> Int.SIZE_BYTES
    this.isLong() -> Long.SIZE_BYTES
    this.isUByte() -> UByte.SIZE_BYTES
    this.isUShort() -> UShort.SIZE_BYTES
    this.isULong() -> ULong.SIZE_BYTES
    this.isFloat() -> Float.SIZE_BYTES
    this.isDouble() -> Double.SIZE_BYTES
    this.isBoolean() -> 1
    this.isUnit() -> 8 // 64 bit
    else -> DEFAULT_SIZE
}

val Meta.GenerateShallowSize: CliPlugin
    get() = "Generate shallowSize method" {
        meta(
            classDeclaration(this, { element.isData() }) { declaration ->
                Transform.replace(
                    replacing = declaration.element,
                    newDeclaration =
                        """|$`@annotations` $kind $name $`(typeParameters)` $`(params)` : $supertypes {
                           |   $body
                           |   fun shallowSize(): Unit
                           |}""".`class`
                )
            },
            irClass { clazz ->
                TODO("Only for data classes calculate the sum of sized its properties and replace the shallowSize function body, please use org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder,  org.jetbrains.kotlin.ir.builders.irBlockBody, and org.jetbrains.kotlin.ir.builders.irInt to build new function body")
            }
        )
    }
I understand that with such an implementation there will be problems with the IDE and others, but that's what I need 😞
r
Copy code
Only for data classes calculate the sum of sized its properties and replace the shallowSize function body, please use org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder,  org.jetbrains.kotlin.ir.builders.irBlockBody, and org.jetbrains.kotlin.ir.builders.irInt to build new function body
That should be doable just on IR without the
classDeclaration
part you have separate. There is a
org.jetbrains.kotlin.ir.builders.declarations
where the
IrFunctionBuilder
and others can be used in IR to construct the function. There you also have access to the members. I’m confused though, are you trying to get the compilation unit byte size? if so properties is not enough as classes have headers and others artifacts added post IR when it lowers to JVM which would add to the class byte size.