-
-
Notifications
You must be signed in to change notification settings - Fork 760
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use reference in fallback property delegate #3982
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't download the code and test it myself but it's strange that you need to expose the deprecated properties. We should be able to avoid that, right?
detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/ConfigPropertySpec.kt
Show resolved
Hide resolved
You can checkout to code using the github tooling There are 2 reasons why the deprecated properties must be there:
I am wondering if it safe to include the |
Codecov Report
@@ Coverage Diff @@
## main #3982 +/- ##
============================================
- Coverage 83.60% 83.56% -0.04%
- Complexity 3187 3190 +3
============================================
Files 459 460 +1
Lines 9098 9108 +10
Branches 1769 1773 +4
============================================
+ Hits 7606 7611 +5
- Misses 560 563 +3
- Partials 932 934 +2
Continue to review full report at Codecov.
|
val fallback: String by config(42) { (it + fallbackOffset).toString() } | ||
val missing: String by config(42) { (it + fallbackOffset).toString() } | ||
val present: String by configWithFallback(::fallback, defaultValue) { v -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is very close to your use case @BraisGabin. Am I right?
if (fallbackProperty.isPrivate()) { | ||
invalidDocumentation { | ||
"The fallback property '$fallbackPropertyReference' of property '$name' may not be private" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I played a bit with your PR and I still don't get why the fallback can't be private. I make one of them private and I commented this code and the tests and the generateDocumentation
task worked fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can change the visibility in line detekt-api/src/test/kotlin/io/gitlab/arturbosch/detekt/api/ConfigPropertySpec.kt:300
to private and then the test will fail with:
java.lang.IllegalAccessException: class kotlin.reflect.jvm.internal.calls.CallerImpl$Method cannot access a member of class io.gitlab.arturbosch.detekt.api.ConfigPropertySpec$1$1$4$1$subject$2$1 with modifiers "private final"
The reason is that the FallbackConfigProperty
tries to access the getter of the field via reflection which is not possible when it is private. That code path is only executed if:
- the config does not contain the key of the new property (configured with
configProperty(::xxx, 42)
) - AND the config contains the key of the old (deprecated) property
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Triggered by a missing feature
What is exactly the missing feature?
I don't have a strong opinion on this PR to be frank.
Just a small note, imho we're making the API safer but also harder to use.
Maybe we can provide methods with both String
and KProperty
instead? of introducing a breaking change?
Previously it was only possible to use the exact value from the deprecated property but not apply a function to its value. |
I am a little bit weary to increase the api surface even further. Especially for such a functionality that is most likely not used very much. I am very much open to suggestions on how to implement the missing feature in a better way. As I wrote earlier, I do not really know if relying on reflection for this feature is such a great idea. |
…ence # Conflicts: # gradle/libs.versions.toml
How do we want to proceed? Ideally if we want to merge this, it should go inside |
Sorry, I didn't have the time to look at this until now. I did this: marschwar/detekt@fallback-with-reference...BraisGabin:fallback-with-reference It seems that now it allows private properties. The key is to use |
Thank you @BraisGabin. Let me look at it tonight. It seems like a good solution. |
Fallback with reference
/**
* Represents a property without any kind of receiver.
* Such property is either originally declared in a receiverless context such as a package,
* or has the receiver bound to it.
*/
public actual interface KProperty0<out V> : KProperty<V>, () -> V I don't really understand why it is working either but it seems to do the trick. Thank you for looking into it. |
8d3de2c
to
3bf2c61
Compare
return transform(getValueOrDefault(thisRef, property.name, defaultValue)) | ||
} | ||
if (thisRef.isConfigured(fallbackProperty.name)) { | ||
return fallbackProperty.get() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: If we specify fallback property and transformer at the same time, would the transformer be disregarded?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the property exists in the config, the transformer is executed. If that is not the case and the fallback property exists, then its transformer (if present) is used.
We could add |
I'd vote to move this to 1.19.0 so we can release 1.18.0. Add this code after 3 RC doesn't feel the right move. |
Agree. Given the unstable annotation we added to those APIs, we can easily change it in the next release. |
Can we merge this now? |
@marschwar Can you take a look at the merge conflicts? Then I belive we can merge this. |
The fallback property syntax has always been awkward to use. Triggered by a missing feature for #3972 I wanted to find a way to
Drawbacks of this solution:The property to fall back onto has to be publicThis solution relies onkotlin-reflect
to be available at runtime (which looks like is the case sincekotlin-compiler-embeddable
depends on it)