jwstegemann / fritz2

Easily build reactive web-apps in Kotlin based on flows and coroutines.
https://www.fritz2.dev
MIT License
636 stars 25 forks source link

Consider visibility modifier of `@Lenses` annotated data classes #773

Open haukesomm opened 1 year ago

haukesomm commented 1 year ago

Current state

Currently, when a data class has a visiblity modifier other than public, the generated lenses will leak their non-public receiver type. This causes the compilation to fail.

Example:

@Lenses
internal data class Test (
    val someProperty: String
) {
   companion object
}

Generated lens:

public fun Test.Companion.someProperty(): Lens<Test, String> = lensOf(
// ^^^
// + public is no valid visibility modifier since `Test` is internal
  "someProperty",
  { it.someProperty},
  { p, v -> p.copy(someProperty= v)}
)

Suggestion

The data class's visibility modifier should be used in the generated lenses.

Lysander commented 11 months ago

This sounds totally valid, but in order to understand the necessity of this issue, can you provide some (real world) example or use case, where one needs some internal or more general some none public data class for store mappings?

haukesomm commented 6 months ago

In a real world application there might be a project that is structured like this:

<root module>
|
+-> core
|   |
|   +-> commonMain (shared model classes, etc.)
|
+-> ui-lib
    |
    +-> commonMain (ui-lib-internal model classes used for state handling etc.)
    +-> jsMain (actual components)

In the example above there might be some data classes that are internally used in the ui-lib for state handling but that should not be exposed to the outside world. Those would typically be marked internal.

In order to be able to fully use them with Stores (mapping), it would be convenient to still be able to generate lenses for them.

If the entire class is marked as internal, all lenses generated for that class could be marked internal as well. If only a specific property is marked as internal, only the respective lens could be made internal, retaining the other lense`s visiblities.

Also, after some thinking about the matter, one could argue that only the internal visiblity modifier needs to be considered since in data classes protected is virtually the same as private and private doesn't make much sense in lenses.