Assigned
Status Update
Comments
au...@google.com <au...@google.com> #2
The Kotlin compiler also treats NestedOptIn as part of the feature.
Do you have a link that shows this is the case? I want to make sure we follow Kotlin's implementation as close as possible.
al...@google.com <al...@google.com> #3
You mean like official documentation? For Kotlin compiler behavior? No...
This snippet shows the behavior, though:
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
@Retention(AnnotationRetention.BINARY)
annotation class ExperimentalFeature
@ExperimentalFeature
class OuterOptIn {
// ...
class NestedOptIn {
//...
}
}
// This will fail to compile without `@OptIn(...)`.
fun usesNestedOptIn() = NestedOptIn()
It also follows logically that if an outer class is experimental and may be removed at any time, all inner classes may be removed at any time (by removal of the outer class) and thus must implicitly be considered experimental.
Description
Annotations meta-annotated with
@RequiresOptIn
are considered by both Metalava and the Kotlin compiler to propagate to nested classes, but Metalava writes nested classes as top-level declarations in API text files. This can be confusing for a human reader.For example, consider the following class structure:
According to Metalava,
NestedOptIn
is also part of the@ExperimentalFeature
and has the same compatibility properties asOuterOptIn
. The Kotlin compiler also treatsNestedOptIn
as part of the feature.However, Metalava writes the following to the API text file:
Which developers and API Council reviewers find ambiguous.
We should consider adding a feature whereby we can tell Metalava which annotations should be propagated to top-level declarations such that we get the following output: