Cant understand annotation propagation for lambdas in Kotlin - kotlin

According to official documentation - https://kotlinlang.org/docs/annotations.html#lambdas
there is an approach for introspect a lambda function for annotations searching. But i cant find any examples for this approach
But invoke() method does not provide any context, because it is just a directive for function evaluating
How to properly find any annotation placed right before lambda function? Should I implement any javaagent (AOP) for this solution?
Example of code was taken right from official documentation
val f = #Suspendable { Fiber.sleep(10) }

Related

Is there a way to use an annotation class as a decorator on a function in Kotlin?

I am very new to Kotlin development and I came across custom annotation classes in the documentation.
Is there a way for me to use an annotation on a function as a way to pre-populate some variables, or to run a decorator function before running the annotated function?
Something like:
class TestClass {
#Friendly("Hello World")
private fun testFun() {
greet()
//does something else
}
}
with an annotation class like
#Target(AnnotationTarget.FUNCTION)
#Retention(AnnotationRetention.BINARY)
annotation class Friendly(val message: String) {
fun greet() {
println(message)
}
}
I know this isn't valid Kotlin code, but I can't find any examples on how to actually use values from annotations without using reflection (if it's even possible)
Please let me know if I can do something like this, and more usefully, a better resource on annotation classes for Kotlin?
To make use of your custom annotations, you need to either create your own annotation processor (and use kapt Kotlin compiler plugin) to generate some new sources (but not modify existing!) at compile time, or use #Retention(AnnotationRetention.RUNTIME) meta-annotation (which is default in Kotlin), so that they could be accessed via reflection in runtime.
#Retention(AnnotationRetention.BINARY) meta-annotation you're using is equivalent of #Retention(RetentionPolicy.CLASS) in java, which is mostly useless (see https://stackoverflow.com/a/5971247/13968673).
What you're trying to do with annotations (call some additional code before/after method execution) reminds me aspect-oriented programming. Take a look at Spring AOP and AspectJ frameworks, following this paradigm, and their approach for annotations processing. TL;DR: Spring AOP is processing annotations in runtime, generating proxy-classes with respectful code, while AspectJ is using its own compiler (even not an annotation processor, cause it also introduces its own syntactic extension for java language), and can generate respectful bytecode at compile-time. They both are originally java-oriented, but with some configurational pain could be used with Kotlin too.

Kotlin Annotation Reflection to inject an argument to a function with a custom annotation

I'd love to create a new library for my purposes and am currently struggling with the technical approach needed to fulfill the requirements.
I want to have something like this:
class MyFoo {
#Populate("myText")
fun giveMeAValue(bar: Bar) {
LOG.info(bar.message) // "myText"
}
}
I'd like to hook on the function call of giveMeAValue or better said I want to hook logic on every function that is annotated with #Populate. If a call is being registered I'd like to execute some logic and pass a value for the bar parameter. Please ignore the fact that I might overwrite a value that has been passed already.
I was reading up for Reflection using Kotling (i.e. https://medium.com/tompee/kotlin-annotation-processor-and-code-generation-58bd7d0d333b) but could not find the thing I'd like to have here.
The hooking/proxy mechanism before the "real" function is being called. That's what I want to achieve.
Can anybody tell me what I am actually looking for? Is there a word for that concept or an article/guide describing this? I was not able to find anything. A code snippet/example would be awesome, too!

How to inline function map on Flux or Mono object in Kotlin and Project Reactor

I'm trying to develop a demo app using Kotlin and Project Reactor and I want to inline some functions like map on objects like Flux or Mono.
I did like this:
private inline fun Flux<Account>.map(noinline transformer: (Account) -> AccountDTO): Flux<AccountDTO> {
return this.map(transformer)
}
but it's not ok because I'm receiving the following warning from IDEA:
Expected performance impact of inlining 'private open inline fun Flux<Account>.map(noinline transformer: (Account) -> AccountDTO): Flux<AccountDTO> defined in com.freesoft.reactiveaccountservice.api.controller.AccountController' is insignificant. Inlining works best for functions with parameters of functional types.
Does anyone have any idea how I can implement this inline functions or if it matters to implement it?
Tx!
So far as you are just calling the non-inlined map defined in Java, there won't be a benefit. You could in principle look at the Java definition, and translate it to Kotlin, and make that your inlined map's defintion, but (without checking) I'd expect it just to be something like return new MapFlux(...) which probably won't benefit either because the lambda needs to be stored in a field.
So you'd need to reimplement a considerable portion of the library in Kotlin.
Usually, you want to inline lambda functions which are passed into higher-order functions because it reduces the runtime overhead. No anonymous classes and function reference objects will be created during runtime when you inline the lambdas. In your case, inlining doesn't boost performance because it's a regular function. You can read full explanation with examples here

What is the purpose of actual keyword in Kotlin

I noticed that some functions for coroutines are marked with actual keyword.
From documentation:
actual denotes a platform-specific implementation in multiplatform
projects
As I understood from documentation actual keyword is used for multiplatform projects and should work in pair with expect keyword.
Something like this:
Common module:
package org.jetbrains.foo
expect class Foo(bar: String) {
fun frob()
}
fun main(args: Array<String>) {
Foo("Hello").frob()
}
Corresponding module:
package org.jetbrains.foo
actual class Foo actual constructor(val bar: String) {
actual fun frob() {
println("Frobbing the $bar")
}
}
That case is clear.
But in package kotlinx.coroutines.experimental I noticed that some functions like launch or withContext are marked as actual but there are no expect functions in package.
So what is the purpose of actual keyword without expect?
The kotlinx.coroutines library actually makes use of multiplatform projects since it supports both the JVM and JS compilation targets.
You can find the common module here, and the specific expect declarations for the functions you've mentioned here.
While the source code in the other answer helped, I found this page (linked off of the page #jim-andreas mentioned in the comments above) was much more helpful.
Specifically, this passage:
If you're developing a multiplatform application that needs to access platform-specific APIs that implement the required functionality (for example, generating a UUID), use the Kotlin mechanism of expected and actual declarations.
With this mechanism, a common source set defines an expected
declaration, and platform source sets must provide the actual
declaration that corresponds to the expected declaration. This works
for most Kotlin declarations, such as functions, classes, interfaces,
enumerations, properties, and annotations.
The compiler ensures that every declaration marked with the expect keyword in the common module has the corresponding declarations marked with the actual keyword in all platform modules. The IDE provides tools that help you create the missing actual declarations.
Again, for more information, you can visit this page.

What is the #InlineOnly annotation?

I often see the #InlineOnly annotation when browsing Kotlin's stdlib. As far as I recall the annotation only happens to be on inline functions. What is the purpose of this annotation? Isn't it obvious that inline functions are always inlined? It's documentation isn't really helpful
Specifies that this function should not be called directly without inlining
Is it possible for inline functions to be called not inline?
To quote an answer found here:
InlineOnly means that the Java method corresponding to this Kotlin
function is marked private so that Java code can not access it (which
is the only way to call an inline function without actually inlining
it).
This annotation is internal only because
This annotation was added in the last moment before release, so we hadn't time to validate the design and decided to keep it internal for a while. There are good chances we make it public later.