Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

chain-method-continution should take priority over argument-list-wrapping #2451

Open
mklnwt opened this issue Dec 20, 2023 · 3 comments
Open
Labels
breaking-change Change will break the API and has to wait for Ktlint 2.0 chain-method-continuation rule

Comments

@mklnwt
Copy link

mklnwt commented Dec 20, 2023

chain-method-continution should take priority over argument-list-wrapping.

// Assume that the last
// allowed character is
// at the X character
// on the right             X
val foo = Bar.builder().baz(1).build()

Expected Rule behavior

val foo = Bar.builder()
    .baz(1)
    .build()

Current Behavior

val foo = Bar
    .builder()
    .baz(
        1,
    ).build()

Additional information

  • Current version of ktlint: 1.1.0
@mklnwt mklnwt changed the title chained-function-calls chain-method-continution should take priority over argument-list-wrapping Dec 20, 2023
@paul-dingemans
Copy link
Collaborator

I am not sure what the best order of those 2 rules is. Given code below:

                val foo1 = requireNotNull(bar.filter { it == "bar" }) { "some message" }
                val foo2 = requireNotNull(bar?.filter { it == "bar" }) { "some message" }

the expected outcome is:

                val foo1 = requireNotNull(
                    bar.filter { it == "bar" }
                ) { "some message" }
                val foo2 = requireNotNull(
                    bar?.filter { it == "bar" }
                ) { "some message" }

We need some smarter algorith do decide which rule takes precedence. But most like it will be hard to implement that without having breaking changes in the KtlintRuleEngine.

@mklnwt
Copy link
Author

mklnwt commented Dec 23, 2023

Best way would probably to check whether the chained call is within an argument or not.

Otherwise I agree, this could get very complex.

Would it be possible for an initial precedence to check if the parent of the chain is an assignment or a block.
Yes -> precedence
Not -> argument comes first

@paul-dingemans
Copy link
Collaborator

Would it be possible for an initial precedence to check if the parent of the chain is an assignment or a block.
Yes -> precedence
Not -> argument comes first

The order of the rules is defined before scanning starts. When you run ktlint CLI with --log-level=debug the order of the rules is printed.

Another complication is that a rule is not aware whether other rules are loaded or not (except when a rule has a declared dependency on another rule). If this information was available, the argument-list-wrapping rule could check if chain-method-continuation is enabled and take that into account when deciding to wrap the arguments in a method chain. This however is a breaking API change, and has to wait until Ktlint 2.0 is released (which might take a long time).

@paul-dingemans paul-dingemans added the breaking-change Change will break the API and has to wait for Ktlint 2.0 label Apr 23, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
breaking-change Change will break the API and has to wait for Ktlint 2.0 chain-method-continuation rule
Projects
None yet
Development

No branches or pull requests

2 participants