-
Notifications
You must be signed in to change notification settings - Fork 508
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
chain-method-continuation
shouldn't trigger on property access with only single method call
#2924
Comments
The name of this rule is not great. You're absolute right that it does take more elements into account than methods only. I also do acknowledge that code like:
is more readable than
Thnx for the suggestion. Most likely it is a simple change. But I do think that it, once implemented, opens up a whole can of worms, and requests for more exceptions based on other specific examples in which the formatting reduces readability. I think it will be possible to create similar examples that produce code that is less readable for chains like The real question is whether the construct If it just happens occasionally, I would say that either you rewrite the code a little, or just suppress the rule for a statement/file/directory etc. I won't close the issue for now. Now I have seen your problem, I might not be able to unseen it in my own code bases anymore ;-) |
I would only request and advocate for this particular simple case for precisely the reason you provided. Tail call in property chain is unfortunately quite common in Gradle Kotlin DSL, due to https://docs.gradle.org/current/javadoc/org/gradle/api/provider/Provider.html#get() and due to how Gradle Version Catalog DSL is generated. Also, it's a relatively common idiom by itself in OOP augmented by property pattern (e.g. in Kotlin), basically the extension of
See above.
in this case, the "simplest" solution for me would be to just use a string template - but then readability suffers, I really hate to use templates for such complex expressions, I think they work best for top-level/local vars, single phrase with no dots etc.
TBH I still hope my noun-verb point above can convince you at least a bit :D |
Well at least I am very interested in what you call the noun-verb pattern, or property pattern (e.g. in Kotlin). I couldn't find any references to this pattern though. I am aware of the Gradle Kotlin DSL with the 'get` function (https://docs.gradle.org/current/javadoc/org/gradle/api/provider/Provider.html#get()).
Okay fair, I used a dot too less. The point that I tried making whether the construct for which you want an exc exception, e.g. Suppose that this exception would be build in, I can imagine that the next request will be to also make an exception for construct below.
In this example
What do you think about this? |
Depends on the context. Some would refer to it as "noun-verb paradigm", https://www.usabilityfirst.com/glossary/noun-verb-paradigm/index.html , but actually it's called https://en.wikipedia.org/wiki/Subject%E2%80%93verb%E2%80%93object_word_order . It's used by most natural languages used by humans, and thus is assumed to be the easiest to read and understand by most people. As to why just a single one - When you combine them, you get the arguably most readable and understandable structure used by OOP language code. Not my invention, but a description of patterns already in use for decades. Dunno if there's any more "specific" name for it or more "strict" reference, I just seen it so many times I never really wondered too much about it TBH.
I completely understand your point and agree that this can be seen as a slippery slope. Yet, while a lambda expression of any kind is "complex", the function can understandably always take complex input, even a nested one. That nesting would trigger reformatting of its own under ktlint rules I think, so I'm not seeing any real risk here, it would turn multi-line etc. if the length or nesting would exceed the limits, right? Alternatively, maybe just treat a 0-arg method call like a property access? They are actually the same, there's no compiler or semantic difference between |
Thanks for the explanations. I keep it in consideration for a while. |
related to #2455 , mirroring the idea from #2455 (comment) somewhat; results from IMVHO excessive application of
chain-method-continuation
, coupled with the default value of https://pinterest.github.io/ktlint/1.0.0/rules/configuration-ktlint/#force-multiline-chained-methods-based-on-number-of-chain-operatorsA practical example, single
println
(please ignore the fact it doesn't use string template : ) :Expected Behavior
Line is left verbatim. Length is OK, the property access via Gradle version catalog accessor it perfectly OK, and the getter for the
Property<String>
is unfortunately necessary due to Gradle's internals (no goodtoString()
there) - however since we do not have a method chain (only a single explicit method is called, the rest is either accessors or fields or whatever, no()
anyway), no chain-method-continuation rule should trigger - since there is no chained method nor any continuation happening)Observed Behavior
a waterfall of tragedies follows:
wrapping
andmultiline-expression-wrapping
rules trigger, resulting inIt's now a lot harder to read and handle - and, let's be honest - in total that's a real overkill, that could be safely prevented by a tweak to the
chain-method-continuation
logic :)Steps to Reproduce
Take any expression that has >= 3 property etc. accesses (even with very short names!), and terminate with a method call.
Note that this won't happen for pure property access, nor for <= 2 property accesses like
libs.versieeeeeons.ooooooooour.getLibrary()
Proposed solution
Don't treat a stream of tokens as a "chained method call" if only a single
()
method is called at the end.Your Environment
ktlint ruleset 1.5.0
The text was updated successfully, but these errors were encountered: