Обработка аннотации Kotlin: возможно ли генерировать метод расширения?

Я играю с Kotlin, и я думаю, что было бы здорово иметь « функциональные классы », см. Пример того, что я хочу:

functional class MyStrFunction(val function: MyStrFunction.(String) -> String) { val memory = HashMap<String, String>() fun output(message: String) = println(message) } 

Идея состоит в том, что я мог бы использовать ее так:

 val f = MyStrFunction { output("reversing $it"); if (it in memory) output(memory[it]) return it.reverse() } 

Если бы я должен был написать MyStrFunction который я хочу сам, результирующий класс будет:

 class MyStrFunction(val function: MyStrFunction.(String) -> String) { val memory = HashMap<String, String>() fun output(message: String) = println(message) public fun invoke(s: String) = this.function(s) } 

Но немного утомительно писать это руками в каждом « функциональном классе ».

Итак, вот мой вопрос: возможно ли сделать functional аннотацию, а затем обработать ее добавлением метода invoke с желаемым кодом?

Я знаю, что kapt можно использовать для обработки аннотации Kotlin, но AFAIK пока не может генерировать код Kotlin, и нет возможности сделать функцию расширения в Java-коде.

Есть ли способ генерировать новый метод Kotlin для класса?

Узел: Я понимаю, что идея функциональных классов имеет мало практических примеров и что не сложно добавить упомянутый метод invoke вручную, но для меня это академический интерес к концепции обработки аннотаций в Котлине.

UPD: Просто мои мысли о функциональных классах: есть функция языка делегирования интерфейсов, и здесь это будет работать хорошо, но this ссылка не отображается в этом блоке. Пример:

 class MyStrFunction(val function: MyStrFunction.(String) -> String) : (String) -> String by { this.function(it) } { // <-- won't compile :( val memory = HashMap<String, String>() fun output(message: String) = println(message) } 

Не уверен, что то, что вы хотите, можно сделать напрямую, но вот подход без «функциональных классов». Насколько я понимаю, вы хотите добавить функциональность к регулярной лямбда-функции. Во-первых, определите свою функциональность как обычный класс:

 class Memory() { val memory = hashMapOf<String, String>() fun output(message: String) = println(message) } 

Затем определите вспомогательную функцию для связывания функций расширения с приемником:

 fun <T, R, E> T.bind(function: T.(R) -> E): (R) -> E = { this.function(it) } 

И затем используйте его так

 fun main(args: Array<String>) { val mem = Memory() val memoryFunction: Memory.(String) -> String = { output("reversing $it"); if (it in memory) output(memory[it]) it.reverse() } val function: (String) -> String = mem.bind(memoryFunction) println(listOf("foo", "bar").map(function)) }