Support for internal types and "explicit API" mode in library projects
Version: 1.6.15-beta
I have a library project that I want to use Destinations with, but all of my composables marked with @Destination have internal visibility and many of the arguments I'm passing to the destinations are also internal types.
Because the generated code does not explicitly specify visibility, it defaults to public leading to compilation errors that a public class is exposing an internal type.
I'm not sure if this would work in all cases, but perhaps the generated types' visibility could be made to match the type that it's sourced from. For example:
Source:
@Destination
@Composable
internal fun HomeScreen()
Generated:
internal object HomeScreenDestination
A related problem is when "explicit API" mode is enabled for Kotlin. It causes compilation errors due to the generated types not specifying their visibility explicitly. I believe adding explicit visibility modifiers to all generated types based on the source type's visibility could resolve both issues.
Hi @sarathijh
Yeah this seems like a nice improvement. Thanks for reporting 🙇
I'll try to check this soonish.
@raamcosta we need it! thanks!
Hey @sarathijh and @alexzaitsev 👋
This just got merged and released. Please let me know how it goes as my testing here was limited. I may have missed some detail where I forgot to add either explicit type, visibility or such, but I believe it should be done. Let me know either way though! Thanks!
Thank you @raamcosta! how this can be used? any documentation?
Nothing especial. Internal will be used if the annotated Composable is internal. And all generated types will be using explicit types and visibility always.
Is it possible to disable this or at least configure each destination? Because each of my composables are in a separated module and internal, I cannot create a navigation-like class in my app module. I want to expose the destinations, not the composables.
Hmm I see. We can make it configurable in some way. For now, keep with version before if this bothers you. I'll reopen this to take a look at it.
What do you guys think should be the default here? I'm kinda torn 🤔
In one hand, it was always like this (visibility of the Composable was not taken into account), on the other hand, I feel like it makes sense and is a good default behaviour here. At the same time, if by default, I copy the visibility of the Composable functions, then some users might have errors and they won't know how to fix. While if the default is making Destinations public, then the more "advanced" use case of needing to make them internal should be a rarer occurence which justifies looking up on documentation.
Btw, I'm thinking of making this a module-wide configuration, done on gradle build files, like so:
ksp {
arg("compose-destinations.useComposableVisibility", "true") // or "false"
}
Just wondering what to do if the user doesn't specify this 🤔
I think by default destinations should be public as it's the more popular version. I'm personally taking advantage of the fact that my composables can be internal, too