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

Fix how "except" options are checked in *-empty-line-before rules #2920

Merged
merged 1 commit into from
Sep 24, 2017

Conversation

nwoltman
Copy link
Contributor

Which issue, if any, is this issue related to?

Fixes #2919

Is there anything in the PR that needs further explanation?

The bug reported in #2919 was being caused by multiple "except" options being checked individually, which caused the expectation to flip-flop and be incorrect if an even number of exceptions were satisfied.

This PR fixes that type of code in the various *-empty-line-before rules so that as soon as one exception is satisfied, it skips the rest. The other *-empty-line-before rules that I did not touch were already doing this correctly.

@jeddy3
Copy link
Member

jeddy3 commented Sep 23, 2017

@nwoltman Oh wow, thanks for the quick fix!

The bug reported in #2919 was being caused by multiple "except" options being checked individually, which caused the expectation to flip-flop and be incorrect if an even number of exceptions were satisfied.

It's surprising that this hasn't come to light before! Good catch, though.

Is there still an issue here with shared-line comments not being ignored by rule-empty-line-before, though? e.g.

@media screen { /* comment */
    .foo {
        display: none;
    }
}

The /* comment */ should be ignored (as all shared-line comments are ignored), but it is triggering the except: ["after-single-line-comment"] option. This exception revealed the "flip-flop" bug you've fixed as .foo {} is also the "first-nested" - one option turned the exception on and the other turned it off. However, the "after-single-line-comment" option should never have been triggered to begin with.

I think we should address this within this PR. What do you think?

}

function isAfterSingleLineComment(rule) {
const prevRule = rule.prev();
Copy link
Member

@jeddy3 jeddy3 Sep 23, 2017

Choose a reason for hiding this comment

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

Should this use the isSharedLineComment util?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Turns out there's already an isAfterCommentLine util so this function doesn't even need to exist.

Copy link
Contributor Author

@nwoltman nwoltman Sep 23, 2017

Choose a reason for hiding this comment

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

Whoops, never mind about that; isAfterCommentLine also counts multi-line comments.

Also, when I fix this function (by using isSharedLineComment), a few tests start failing:

rule-empty-line-before › accept › ["always", {"except": ["after-single-line-comment"]}]

@media { /* comment */
  a {}
}

rule-empty-line-before › reject › ["always", {"except": ["after-single-line-comment"]}]

@media { /* comment */

  a {}
}

They actually need to be reversed now because the shared-line comment doesn't count as a single-line comment, so the first test should be rejected and the second one should be accepted. This might need to be highlighted in the release notes of the release that includes this fix.

Copy link
Member

@jeddy3 jeddy3 Sep 23, 2017

Choose a reason for hiding this comment

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

They actually need to be reversed now because the shared-line comment doesn't count as a single-line comment

Sounds about right. I had assumed we weren't testing for this eventuality. However, it turns out we are but the tests are wrong.

This might need to be highlighted in the release notes of the release that includes this fix.

Good point. FYI, due to our Semantic Versioning Policy, this can be included in a minor release, even though it could break some users' builds.

Copy link
Member

Choose a reason for hiding this comment

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

Whoops, never mind about that; isAfterCommentLine also counts multi-line comments.

Feel free to create a isAfterSingleLineComment util, though.

And also free feel to rename the isAfterCommentLine util to isAfterComment for consistency with the other isAfter* utils. I'm not sure the Line suffix makes sense now that shared-line comments are always ignored.

@@ -153,6 +131,20 @@ const rule = function(expectation, options, context) {
};
};

function isAfterRule(rule) {
const prevRule = rule.prev();
Copy link
Member

@jeddy3 jeddy3 Sep 23, 2017

Choose a reason for hiding this comment

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

Should this use the getPreviousNonSharedLineCommentNode util? Like custom-property-empty-line-before does? If so, can we get a test for this.

@nwoltman
Copy link
Contributor Author

@jeddy3 Ah yes, you're right that shared-line comments should be ignored and shouldn't trigger "after-single-line-comment". I'll fix up this PR to handle that.

@nwoltman
Copy link
Contributor Author

@jeddy3 I've updated the PR. Would it be alright if I renamed the isAfterCommentLine util in a separate PR? I feel like that change out be a little out of place in this PR.

Copy link
Member

@jeddy3 jeddy3 left a comment

Choose a reason for hiding this comment

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

All looks great to me. Thanks again!

{
code:
"@media screen { /* comment */\n .foo {\n display: none;\n }\n}",
description: "shared-line comment - issue #2919"
Copy link
Member

Choose a reason for hiding this comment

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

We should try to do this more often when warranted 👌

Copy link
Member

@ntwb ntwb left a comment

Choose a reason for hiding this comment

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

👍

@jeddy3 jeddy3 merged commit f055370 into stylelint:master Sep 24, 2017
@jeddy3
Copy link
Member

jeddy3 commented Sep 24, 2017

  • Fixed: *-empty-line-before false negatives and positives when two or more except: [*] options were triggered (#2920).
  • Fixed: rule-empty-line-before false positives for except: ["after-single-line-comment"] and preceding shared-line comments (#2920).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Fix false positives for shared-line comments in nested blocks in rule-empty-line-before
3 participants