```maybeAnnotatedClass .getAnnotationByClassId...
# compiler
m
Copy code
maybeAnnotatedClass
    .getAnnotationByClassId(
        classId = ANNOTATION_CLASS,
        session = session,
    )
    .coalesce { return Either.Bar(FactoryError.ClassNotAnnotated) }
    .getKClassArgument(ANNOTATION_ARG)
    .coalesce { return Either.Bar(FactoryError.ArgumentMissing) }
    .classId
    .coalesce { return Either.Bar(FactoryError.ArgumentInvalid) }
Is it ever possible for
classId
to be
null
when the call to
getKClassArgument
has succeeded?
Copy code
public annotation class MyAnnotation(val kClass: KClass<*>)
This is the annotation type definition the plugin tries to read.
Copy code
inline fun <T: Any> T?.coalesce(fallback: () -> T): T {
    return this ?: fallback()
}
Also, this is the definition of the
coalesce
utility in use.
d
It could be null in the red code, e.g. if the user will try to use definitely not-null type in LHS:
Copy code
fun <T> foo(@Ann((T & Any)::class) x: Int) {}
m
Copy code
(T & Any)::class
What am I looking at here?
&
isn’t listed on kotlinlang.org/docs/keyword-reference.html#…
d
This is called "definitely non-nullable types" or DNN in short. https://kotlinlang.org/docs/whatsnew17.html#stable-definitely-non-nullable-types
Even simpler example of get class call without classId (also in red code):
Copy code
fun <T> foo(@Anno(T::class) x: Int) {}
m
I made my reproducible example too minimal. My
annotation class
is actually
@Target(AnnotationTarget.CLASS)
.
Copy code
@Target(AnnotationTarget.CLASS)
public annotation class MyAnnotation(val kClass: KClass<*>)
Can
classId
still be
null
after a successful call to
getKClassArgument
?
Copy code
maybeAnnotatedClass
    .getAnnotationByClassId(
        classId = ANNOTATION_CLASS,
        session = session,
    )
    .coalesce { return Either.Bar(FactoryError.ClassNotAnnotated) }
    .getKClassArgument(ANNOTATION_ARG)
    .coalesce { return Either.Bar(FactoryError.ArgumentMissing) }
    .classId
    .coalesce { return Either.Bar(FactoryError.ArgumentInvalid) }
d
Still could happen.
Copy code
class Outer<T> {
    @Ann(T::class)
    inner class Inner
}
Also note, that annotation target doesn't prevent user to write the annotation anywhere. It prevents this code to be compiled (passed to backend). The frontend would still resolve it.