-
-
Notifications
You must be signed in to change notification settings - Fork 938
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 false positives for objects in declaration-block-trailing-semicolon #4749
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.
Thanks!
I've requested two changes. One to the tests and another to the fix itself.
Yes; @jeddy3 suggests a solution in #4650 (comment) that did not work for me:
isStandardSyntaxRule
only accepts Rule nodes, but if used in declaration-block-trailing-semicolon, it would also be given AtRule nodes
I've been meaning to write up an issue about this. I realised shortly after writing that suggestion that the isStandardSyntax*
utils should only be used when a syntax parses a non-standard construct as a standard one, e.g. postcss-scss will parse a SCSS map as a decl
node.
I think we need a new set of utilities for when a syntax parses a standard construct correctly, but the punctuation of the construct is non-standard, e.g. postcss-css-in-js will correctly parse the object pair {{ color: "red" }}
as a decl
, but it has non-standard punctuation.
The first of theseisStandardPunctuation*
utils can be isStandardPunctuationDeclarationList
and would use the type === "object"
conditional.
I'll create a new issue about this so I can flesh out the rationale behind it. I think we can merge this pull request with a type === "object"
conditional directly in the rule.
@@ -25,6 +25,10 @@ testRule(rule, { | |||
code: 'a { color: red; &:hover { color: pink; }}', | |||
description: 'nesting with first-level decl', | |||
}, | |||
{ |
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.
Let's replace these two tests with a single one at the bottom of the file that tests the problematic syntax, e.g.:
testRule({
ruleName,
config: ['always'],
syntax: 'css-in-js',
fix: true,
accept: [
{
code: 'const C = () => { return <a style={{ color: "red" }}></a> }',
description: 'css-in-js object',
},
],
reject: [
{
code: 'const C = styled.a`color: red`;',
fixed: 'const C = styled.a`color: red;`;',
description: 'css-in-js template literal',
message: messages.expected,
line: 1,
column: 29,
},
],
});
So that we're consistent with the conventions:
You should:
- use standard CSS syntax by default, and only swap parsers when testing a specific piece of non-standard syntax
I think this will also highlight that template literals are incorrectly excluded by the proposed fix.
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've updated the snippet above to use the new testRule
signature because we now dogfood our Jest preset for testing rules (#4758).
You'll need to rebase your branch off master
when updating this pull request.
As an aside, as a member of the stylelint organisation you can, if you like, clone this repository directly rather than work on a fork. It can make collaboration easier.
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.
Ah, very nice. Thanks much!
@@ -42,6 +42,10 @@ function rule(expectation, _, context) { | |||
}); | |||
|
|||
root.walkDecls((decl) => { | |||
if (decl.parent.type !== 'rule' && decl.parent.type !== 'atrule') { |
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 think we should use:
if (decl.parent.type === 'object') return;
As not to exclude template literals, e.g.:
const C = styled.a`color: red;`;
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.
Done
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.
Thanks for making the changes, LGTM!
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.
LGTM, thank you @srawlins.
Changelog entry:
|
Fixes #4650
Yes; @jeddy3 suggests a solution in #4650 (comment) that did not work for me:
isStandardSyntaxRule
only accepts Rule nodes, but if used indeclaration-block-trailing-semicolon
, it would also be given AtRule nodes (like in the SCSS test case:a { @foo { color: pink } }
). This complicates things further becauseisStandardSyntaxRule
examines theselector
of the Rule which it receives, and AtRule has noselector
.This simple solution seems to work for now.