Skip to content

Plugin to the Kotlin compiler to calculate combined field size of data classes in compile time

Notifications You must be signed in to change notification settings

muldrik/kotlinc-shallowSize-plugin

Repository files navigation

ShallowSize - Kotlin compiler plugin allowing to calculate data class total property size in compile time

Test CI

The plugin is powered by Arrow Meta and works for Kotlin version 1.5.0 and 1.5.10

Quick start

  1. Download a compiled plugin from the release tab

  2. If you use gradle, add the following code to your build.gradle

compileKotlin {
    kotlinOptions {
        freeCompilerArgs += ["-Xplugin=<path to shallowSizePlugin.jar>"]
    }
}

If you use build.gradle.kts instead add

tasks.compileKotlin {
    kotlinOptions {
        freeCompilerArgs = freeCompilerArgs + "-Xplugin=<path to shallowSizePlugin.jar>"
    }
}

kotlinc is currently not supported as the project maker was too late to realise that ArrowMeta doesn't register a compatible plugin by default

  1. Now your data classes have a member function shallowSize()

For example

data class A(val i: Int, var j: Long)
fun main() {
  val a = A(1, 100)
  println(a.shallowSize()) // 12
}

Bulding from source and testing

All files needed to build the plugin from source are located in shallowSizePlugin directory (except for some environment variables that can be found in gradle.properties

To execute tests, run

./gradlew test-plugin:test

Usage notes

Properties in Kotlin are what is declared by val and var keywords. Properties take space in bytes only if they contain a backing field. For example

data class A(val i: Int) {
  var j: Long = 20
}

data class A contains 2 properties, each with a backing field, resulting in shallowSize of 12.

Properties without a backing field

However, not all properties contain a backing field. Consider

data class Rect(val height: Int, val width: Int) {
  val area
    get() = height*width
}

Here, property area can be accessed without storing additional data. Therefore, the plugin considers its size to be zero

Inheriting from an open class

Inheritance can also introduce properties without backing fields

open class SimpleParent {
    val superClassProp = 100
}

data class SimpleInherited(val a: Long): SimpleParent()

Here, SimpleInherited class contains superClassProp property, however the decision was made to not account for it when calculating SimpleInherited shallow size. This can easily changed for future release.

Super class properties can be overriden. Then they are checked for a backing field

open class ParentWithOpenValProp {
  open val overridable: Int = 10
}

data class A(val i: Int) {
  override val overridable
        get() = 30
}

data class B(val i: Int) {
  override val overridable = 40
}

Class A has a shallow size of 4, while class B has a shallow size of 8

About

Plugin to the Kotlin compiler to calculate combined field size of data classes in compile time

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages