Unleash the secret power of Kotlin Metadata

Unleash the secret power of Kotlin Metadata

When compiling Kotlin code for the JVM, the resulting bytecode doesn't understand the advanced features of the language – like the difference between `List` and `MutableList`. These "metadata" are hidden, but not lost, and they're a gold mine when trying to create tools designed from the ground up with Kotlin in mind. Join us to learn where to find them, how they're structured and how we can make the most out of them.

Video: https://youtu.be/dAQaZFyZ_hQ

Slides in Keynote (animated): https://goo.gl/5Z7kBc

Links:
+ https://goo.gl/INLPDl -> The Future of Kotlin
+ https://goo.gl/UiT6yh -> descriptors.proto

Fde10bcf0813b2162545477be4e7470b?s=128

Eugenio Marletti

July 06, 2017
Tweet

Transcript

  1. None
  2. None
  3. None
  4. None
  5. List<String> List<String?> MutableList<String> MyTypeAlias -> -> -> -> List<String> List<String>

    List<String> List<String>
  6. class object data class sealed class -> -> -> ->

    class class class abstract class
  7. data class Sample(val counter: Int)

  8. None
  9. None
  10. None
  11. public final class Sample { private final int counter; public

    final int getCounter() { return this.counter; } public Sample(int counter) { this.counter = counter; } public final int component1() { return this.counter; } @NotNull public final Sample copy(int counter) { return new Sample(counter); } // $FF: synthetic method // $FF: bridge method @NotNull public static Sample copy$default(Sample var0, int var1, int var2, Object var3) { if((var2 & 1) != 0) { var1 = var0.counter; } return var0.copy(var1); } public String toString() { return "Sample(counter=" + this.counter + ")"; } public int hashCode() { return this.counter; } public boolean equals(Object var1) { if(this != var1) { if(var1 instanceof Sample) { Sample var2 = (Sample)var1; if(this.counter == var2.counter) { return true; } } return false; } else { return true; } } } @Metadata( k = 1, mv = {1, 1, 6}, bv = {1, 0, 1}, d1 = {"\u0000 \n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0010\b\n\u0002\b\u0006\n\u0002\u0010\u000b\n\u0002\b\u0003\n\u0002\u0010\u000e\n\u0000\b\u0086\b\u0018\u00002\u00020\u0001B\r\u0012\u0006\u0010\u0002\u001a\u0010\ d2 = {"LSample;", "", "counter", "", "(I)V", "getCounter", "()I", "component1", "copy", "equals", "", "other", "hashCode", "toString", "", "production sources for module app"} ))
  12. @Metadata( k = 1, mv = {1, 1, 6}, bv

    = {1, 0, 1}, d1 = {"\u0000 \n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0 d2 = {"LSample;", "", "counter", "", "(I)V", "getCounter", "()I", "compon ))
  13. @Metadata k mv bv d1 d2 xs xi

  14. @Metadata 1. kind 2. metadata version 3. bytecode version 4.

    data1 5. data2 6. extra string 7. extra int
  15. 7. extra int 0 -> multi-file class facade or part

    1 -> compiled by a pre-release version 2 -> Kotlin script source file (.kts)
  16. None
  17. “it depends” 4. data1 5. data2 6. extra string

  18. “it depends” mostly Protocol Buffers 4. data1 5. data2 6.

    extra string
  19. 1. kind 1 -> Class 2 -> File 3 ->

    Synthetic class 4 -> Multi-file class facade 5 -> Multi-file class part
  20. * nullability (also nested) * secondary constructors * companion object

    name * properties list * delegated types * internal visibility * sealed class hierarchy * type aliases (declaration and usage) * generic types (also in/out /*, reified) * classes (data/sealed/object/companion) * property (var/getter/setter/const/lateinit) * value parameter (default/crossinline/noinline) * function (operator/infix/inline/tailrec/external)
  21. warning: PLEASE TRY THIS AT HOME

  22. goo.gl/INLPDl -> The Future of Kotlin goo.gl/8oFRaU -> kotlin-metadata-samples (Coming

    Soon™) goo.gl/UiT6yh -> descriptors.proto
  23. bit.ly/unleash-kotlin-metadata Eugenio Marletti @workingkills