Skip to content
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

Allow a single whitespace line in chained expressions #1469

Merged
merged 10 commits into from
May 25, 2022

Conversation

seadowg
Copy link
Contributor

@seadowg seadowg commented May 16, 2022

Description

Closes #1248

There's a lot of discussion in the issues as to the right approach, but here's my proposal for a fix. Given the rule is intended to detect "consecutive" blank lines, I've made sure a single blank line is allowed in a chained expression (but that multiple is still disallowed and formats correctly). This will allow for the "blank line followed by a comment" examples brought up in the issue and keeps the whitespace rules consistent between regular statements and chained expressions.

The reasoning behind arguing for blank lines to be allowed in chained expressions is that there's nothing about disallowing them in either the Kotlin coding conventions or the Android Kotlin style guide (as far as I can see) and people have brought up use cases where it's useful in the issue.

Checklist

  • PR description added
  • tests are added
  • CHANGELOG.md is updated

@seadowg seadowg changed the title Allow one whitespace line and then a comment in chained expressions Allow a single whitespace in between chained expressions May 16, 2022
@seadowg seadowg changed the title Allow a single whitespace in between chained expressions Allow a single whitespace line in chained expressions May 16, 2022
@seadowg seadowg marked this pull request as ready for review May 16, 2022 13:58
@paul-dingemans
Copy link
Collaborator

@seadowg Tnx for making the effort for this PR.

Basically you have reverted issue #1105 without offering an alternative solution for that issue. I do not think that we should do so as that functionality is expected to be in place by other users who do not want allow single blank line within dot qualified expression.

So I think that your PR has to be expanded with a new rule that just disallows (needless) blank lines in a dot qualified expression. This new rule should be a simplified version of the current rule. To allow blank lines in a dot qualified expression you will need to disable that additional rule in your projects.

@seadowg
Copy link
Contributor Author

seadowg commented May 18, 2022

So I think that your PR has to be expanded with a new rule that just disallows (needless) blank lines in a dot qualified expression. This new rule should be a simplified version of the current rule. To allow blank lines in a dot qualified expression you will need to disable that additional rule in your projects.

Sounds good! For the name of the new rule, how about no-blank-lines-in-chain? That's what pops into my head after looking at the language used in chain-wrapping and no-consecutive-blank-lines.

@paul-dingemans
Copy link
Collaborator

Sounds good! For the name of the new rule, how about no-blank-lines-in-chain? That's what pops into my head after looking at the language used in chain-wrapping and no-consecutive-blank-lines.

I prefer the longer version no-blank-lines-in-chained-method-calls.

@@ -15,7 +15,10 @@ public class NoBlankLinesInChainedMethodCallsRule : Rule("no-blank-lines-in-chai
val isBlankLine = node is PsiWhiteSpace && node.getText().contains("\n\n")
if (isBlankLine && node.treeParent.elementType == DOT_QUALIFIED_EXPRESSION) {
emit(node.startOffset + 1, "Needless blank line(s)", true)
(node as LeafPsiElement).rawReplaceWithText("\n" + node.getText().split("\n\n")[1])

if (autoCorrect) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume we need this check, but I couldn't find a good way to write a test that drives it out. Help would be appreciated!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you mean if (autoCorrect) { then you have already done so in test case single blank line in dot qualified expression returns lint error.

When calling hasLintViolations, the rule engine is executed with autocorrect set to false which results in emitting the error without fixing it. When calling 'isFormattedAs, the rule engine is invoked with autocorrectset totrue` resulting in formattting the code.

        noBlankLinesInChainedMethodCallsRuleAssertThat(code)
            .hasLintViolations(LintViolation(3, 1, "Needless blank line(s)"))
            .isFormattedAs(
                """
                fun foo(inputText: String) {
                    inputText
                        .toLowerCase()
                }
                """.trimIndent()
            )
            ```

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right. But, if I remove the if statement (and just always remove the blank line), I don't see a failure. I'm assuming we don't want to be messing around with the code when autocorrect is false. Maybe we need to add a check to hasLintViolations to check that the code is unchanged?

Copy link
Contributor Author

@seadowg seadowg May 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@paul-dingemans thanks for merging, but I'm still a little concerned there's no coverage for the if (autocorrect) check. I'd be happy to look at that in the future if you agree it's an issue?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you think that there is no coverage for the line? As I explained, the line is already covered. You can easily check it out by placing a breakpoint inside the if-statement (line 20) and then run test single blank line in dot qualified expression returns lint error in debug mode.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, being more specific, I mean that it doesn't have "branch" coverage - it does indeed have "line" coverage. If I change the if statement to just be if (true) for example (or just remove the if and keep the rawReplaceWithText), the tests will still all pass. There's no test that ensures that we only run reformat when autoCorrect is true.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't have to worry about that. There is not a single rule for which this is being tested.

@seadowg
Copy link
Contributor Author

seadowg commented May 23, 2022

@paul-dingemans this is probably ready for another look.

@paul-dingemans
Copy link
Collaborator

Tnx for your contribution @seadowg. I hope you like contributing to ktlint. Please feel free to pick up another issue from the list!

@paul-dingemans paul-dingemans merged commit d4ad6b6 into pinterest:master May 25, 2022
@paul-dingemans paul-dingemans added this to the 0.46.0 milestone May 25, 2022
@seadowg seadowg deleted the fix-comments-in-chain branch May 26, 2022 09:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Consecutive blank lines are reported in chained method calls
2 participants