Skip to content
This repository has been archived by the owner on Mar 10, 2021. It is now read-only.

Extension of the Java annotation processing API to Kotlin types

Notifications You must be signed in to change notification settings

tschuchortdev/kotlin-elements

Repository files navigation

WIP - Kotlin Elements


Kotlin Elements is an annotation processing API for Kotlin that allows you to write annotation processors that are fully aware of Kotlin syntax while being compatible with the Javax Element and TypeMirror API. Its unified language model combines Java and Kotlin syntax. This makes it possible to write code that just works™ with both Kotlin and Java out of the box without having to worry about any special cases.

Features

  • Kotlin-syntax aware: Let your annotation processor know about sealed classes, default parameters, properties and so on
  • Unified language model: Have a single code base that works with both Java and Kotlin out of the box. You no longer need special cases and duplicated code
  • Type-level: Kotlin-elements fully embraces type safety and makes heavy use of types to increase reliability of your code and discoverability of the API.
    • Instead of having to scour documentation, let yourself be guided by IntelliJ's autocomplete and discover the API interactively because invariants are encoded at the type level
    • Throw out unreliable casting and runtime checks in favor of fine-grained types
    • Let the types document your code: Fine-grained types makes intentions more clear
  • Seemless interoperability with Javax Element and TypeMirror: At any point you can go back and forth between Javax Element and Kotlin-Elements.
    • Migrate only the parts where it matters in your existing code base
    • Use all your functions that were written for Javax Element with Kotlin-Elements
  • Lazy by default: Conversion of elements is done on demand to keep performance high

How it works

Kotlin has no real support for annotation processing and only allows annotation processing through a "trick" by using Kapt. Kapt takes the Kotlin code and generates stub files from them. Stub files are identical Java files with the same classes and methods as the Kotlin code but without method bodies. Then Kapt calls the regular Java annotation processor Apt with these stub files. This allows Java annotation processors to work on Kotlin code but in the process of stub generation, all information about the additional syntactic features that make Kotlin so great is lost; Everything just looks like Java to the annotation processor. So an annotation processor can not possibly know about sealed classes, properties, extension methods and default parameters.

Actually the lost information about Kotlin-specific features is still present in serialized form in hidden @kotlin.Metadata annotations that are generated by the K2JVMCompiler. By parsing the @kotlin.Metadata annotations it is possible to recover the lost information. Unfortunately the Metadata AST is disjoint from the Javax Element AST and very hard to work with. The job of this library is to reconcile/combine both ASTs, so that you can easily integrate Kotlin Metadata in your code.