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 negatives for where, is, nth-child and nth-last-child in selector-max-* (except selector-max-type) #4842
Fix false negatives for where, is, nth-child and nth-last-child in selector-max-* (except selector-max-type) #4842
Conversation
…alPseudoClass note: possible logic error in selector-max-type, will investigate further
@malsf21 Thanks for starting this. It's looking great so far.
That's correct. The rule now checks within I believe the // add to selector-max-type/index.js line 86
if (childNode.type === 'tag' && !isStandardSyntaxTypeSelector(childNode)) {
return total;
} The util has some logic within it to workaround this limitation of the selector parser. However in its current form, the util will blanket ignore all type selectors that are child nodes of if (parentValue) {
const normalisedParentName = parentValue.toLowerCase().replace(/:+/, '');
if (
parentType === 'pseudo' &&
(keywordSets.aNPlusBNotationPseudoClasses.has(normalisedParentName) ||
keywordSets.aNPlusBOfSNotationPseudoClasses.has(normalisedParentName) ||
keywordSets.linguisticPseudoClasses.has(normalisedParentName) ||
keywordSets.shadowTreePseudoElements.has(normalisedParentName))
) {
return false;
}
} For example, it will have a false negative for the The heuristics need to be more nuanced and only ignore
It should also ignore But it shouldn't ignore, for example, the We can ignore the likes of |
Gotcha, thank you for the in-depth reply! Hm, looking for those elements might be a bit tricky, I'll try to think of a workaround. Regex is one option, though I'm thinking about tokenizing (?) the thing inside the pseudo-class and splitting it up into a set of possible types:
That being said, I wonder if we can easily do this by stripping out elements one at a time (e.g. remove all operators, then numerical atoms, etc.). Not sure how that will work with an edge case like I'll toy around and see what I can conjure up. Worst-case scenario, I could revert the change for this current rule, and then create another issue to tackle this problem later on. |
That would be amazing. If you've time to delve into tokenising it may be better to fix this issue upstream in the parser itself. (I've only had time to operate one-level above the parsers, i.e. helping to build stylelint consuming the various parsers rather than working on the parsers themselves, so it's not an area I know.)
Yes, I agree we push this to another issue. I suggest we make one more change to this pull request; make use of the
The tests should pass then and all the The pull request will fix the false negatives for |
Great, that sounds good. I've implemented the addition to I've got to say, I have very little experience with tokenization or writing parsers (I'm only vaguely familiar from a PL class I took in university), and as you've noticed I've been trying to get familiar with |
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.
@malsf21 Looking good. I've a few nitpicks (as suggestions), then I think we're ready to merge.
If you've not seen it already, the The Super Tiny Compiler is an excellent learning resource.
Yes, it's great to see! Thank you for your contributions. There are plenty of interesting issues to work on directly in stylelint if that parser fix doesn't end up appealing to you. |
minor documentation fixes! Co-authored-by: Richard Hallows <jeddy3@users.noreply.github.com>
Implemented the changes! |
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.
Excellent. LGTM, thanks!
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.
Thank you @malsf21, this LGTM!
Your clear write-up was particularly helpful for review purposes 👍
Updated changelog:
|
* master: Update CHANGELOG.md Fix false negatives for where, is, nth-child and nth-last-child in selector-max-* (except selector-max-type) (#4842) Bump @types/lodash from 4.14.155 to 4.14.157 (#4869) Remove `postcss-reporter` package (#4858) Bump lodash from 4.17.15 to 4.17.19 (#4864) Replace 3rd-party type definitions (#4857)
Hey,
This is a PR to address a concern brought up in #4836. As suggested, I
is
,not
,matches
andhas
out of this set and into a newlogicalCombinationsPseudoClasses
set.where
to this set.nth-child
andnth-last-child
out of this set and into a newaNPlusBOfSNotationPseudoClasses
set (note the extraOfS
).isLogicalCombination
toisContextFunctionalPseudoClass
, and replace theswitch
with requiring the two new sets and checking for a match.In addition, I also
pseudoClasses
to contain our new keyword setsisContextFunctionalPseudoClass
from the ones inisLogicalCombination
isStandardSyntaxTypeSelector
to also check foraNPlusBOfSNotationPseudoClasses
, as it previously relied onnth-child
andnth-last-child
being inaNPlusBNotationPseudoClasses
!isStandardSyntaxTypeSelector
inselector-max-type
In general, it seems like everything works as intended; however, I noticed that we now fail the tests forselector-max-type
, and in particular those involvingnth-child
andnth-last-child
- I think it might be incorrectly recognizingn
or tokens involvingn
as a type selector, but I'm not entirely sure. It also might be that we would want to preserve the original behaviour ofisLogicalCombination
in this case. I've spent a few days wiggling things around, but I think my unfamiliarity with the implementation ofselector-max-type
is hindering me. Would love to get feedback on this!Until then, I'm marking this PR as a draft.Closes #4836.
Don't think so!