Babin Ruslan
03/16/2022, 11:26 PMirClass {...}
i'm modifying function body, but i don't know, how to return updated irClass
😞
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.
}
}
)
}
raulraja
03/17/2022, 12:00 PMclassDeclaration
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.raulraja
03/17/2022, 12:01 PMBabin Ruslan
03/17/2022, 1:27 PMTODO
in irClass
. I couldn't find examples of using arrow-meta wrappers over kotlin IR.
Here is my 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 😞raulraja
03/18/2022, 11:17 AMThat should be doable just on IR without theCopy codeOnly 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
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.