From a9bbbdb84e309a6a3b1f16847a7bf39137e20c53 Mon Sep 17 00:00:00 2001 From: immitsu Date: Fri, 18 Jun 2021 17:12:05 +0300 Subject: [PATCH 1/5] Fix processing of less parametric mixins --- lib/utils/__tests__/isStandardSyntaxRule.test.js | 3 +++ lib/utils/isStandardSyntaxRule.js | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/lib/utils/__tests__/isStandardSyntaxRule.test.js b/lib/utils/__tests__/isStandardSyntaxRule.test.js index 025ab14a04..d4379764ca 100644 --- a/lib/utils/__tests__/isStandardSyntaxRule.test.js +++ b/lib/utils/__tests__/isStandardSyntaxRule.test.js @@ -79,6 +79,9 @@ describe('isStandardSyntaxRule', () => { it('less guarded namespaces', () => { expect(isStandardSyntaxRule(lessNode('#namespace when (@mode=huge) {}'))).toBeFalsy(); }); + it('less parametric mixins', () => { + expect(isStandardSyntaxRule(lessNode('.mixin (@variable: 5) {}'))).toBeFalsy(); + }); it('mixin guards', () => { expect( isStandardSyntaxRule(lessNode('.mixin (@variable) when (@variable = 10px) {}')), diff --git a/lib/utils/isStandardSyntaxRule.js b/lib/utils/isStandardSyntaxRule.js index dc999c52e0..6ea9121f13 100644 --- a/lib/utils/isStandardSyntaxRule.js +++ b/lib/utils/isStandardSyntaxRule.js @@ -57,6 +57,11 @@ module.exports = function (rule) { return false; } + // Less Parametric mixins (e.g. .mixin(@variable: x) {}) + if (/\(@.*\)$/.test(selector)) { + return false; + } + // Ignore Scss nested properties if (selector.endsWith(':')) { return false; From 15cca41b5b65d065dd9acdb46a98356938b5efb1 Mon Sep 17 00:00:00 2001 From: immitsu Date: Sun, 18 Jul 2021 22:54:27 +0300 Subject: [PATCH 2/5] Remove redundant conditionals --- lib/utils/isStandardSyntaxRule.js | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/lib/utils/isStandardSyntaxRule.js b/lib/utils/isStandardSyntaxRule.js index 6ea9121f13..0fe6dc3f67 100644 --- a/lib/utils/isStandardSyntaxRule.js +++ b/lib/utils/isStandardSyntaxRule.js @@ -13,8 +13,6 @@ module.exports = function (rule) { return false; } - // Casting this to any because 'selector' does not exist on type 'NodeRaws' - /** @type {any} */ const raws = rule.raws; // Get full selector @@ -24,39 +22,11 @@ module.exports = function (rule) { return false; } - // Called Less mixin (e.g. a { .mixin() }) - // @ts-ignore TODO TYPES support LESS and SASS types somehow - if (rule.mixin) { - return false; - } - - // Less detached rulesets - if (selector.startsWith('@') && selector.endsWith(':')) { - return false; - } - - // Ignore Less &:extend rule - if ('extend' in rule && rule.extend) { - return false; - } - - // Ignore mixin or &:extend rule - // https://github.com/shellscape/postcss-less/blob/master/lib/less-parser.js#L52 - // @ts-ignore TODO TYPES support LESS and SASS types somehow - if (rule.params && rule.params[0]) { - return false; - } - // Non-outputting Less mixin definition (e.g. .mixin() {}) if (selector.endsWith(')') && !selector.includes(':')) { return false; } - // Less guards - if (/when\s+(not\s+)*\(/.test(selector)) { - return false; - } - // Less Parametric mixins (e.g. .mixin(@variable: x) {}) if (/\(@.*\)$/.test(selector)) { return false; From 72ec5111bb82709f2ff2cbdea1e31de4df42a089 Mon Sep 17 00:00:00 2001 From: immitsu Date: Sat, 24 Jul 2021 23:50:52 +0300 Subject: [PATCH 3/5] Fix not-rule test cases --- .../__tests__/isStandardSyntaxRule.test.js | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/lib/utils/__tests__/isStandardSyntaxRule.test.js b/lib/utils/__tests__/isStandardSyntaxRule.test.js index d4379764ca..dac5b56bff 100644 --- a/lib/utils/__tests__/isStandardSyntaxRule.test.js +++ b/lib/utils/__tests__/isStandardSyntaxRule.test.js @@ -38,8 +38,8 @@ describe('isStandardSyntaxRule', () => { it('Scss nested properties', () => { expect(isStandardSyntaxRule(node('foo: {};'))).toBeFalsy(); }); - it('called Less class parametric mixin', () => { - expect(isStandardSyntaxRule(lessNode('.mixin-name(@var);'))).toBeFalsy(); + it('Less class parametric mixin', () => { + expect(isStandardSyntaxRule(lessNode('.mixin-name(@var) {}'))).toBeFalsy(); }); it('non-outputting parametric Less class mixin definition', () => { expect(isStandardSyntaxRule(lessNode('.mixin-name() {}'))).toBeFalsy(); @@ -53,25 +53,13 @@ describe('isStandardSyntaxRule', () => { it('non-outputting Less ID mixin definition', () => { expect(isStandardSyntaxRule(lessNode('#mixin-name() {}'))).toBeFalsy(); }); - it('called Less ID mixin', () => { - expect(isStandardSyntaxRule(lessNode('#mixin-name;'))).toBeFalsy(); - }); - it('called namespaced Less mixin (child)', () => { - expect(isStandardSyntaxRule(lessNode('#namespace > .mixin-name;'))).toBeFalsy(); - }); - it('called namespaced Less mixin (descendant)', () => { - expect(isStandardSyntaxRule(lessNode('#namespace .mixin-name;'))).toBeFalsy(); - }); - it('called namespaced Less mixin (compound)', () => { - expect(isStandardSyntaxRule(lessNode('#namespace.mixin-name;'))).toBeFalsy(); - }); it('less mixin', () => { expect( isStandardSyntaxRule(lessNode('.box-shadow(@style, @c) when (iscolor(@c)) {}')), ).toBeFalsy(); }); it('less extend', () => { - expect(isStandardSyntaxRule(lessNode('&:extend(.inline);'))).toBeFalsy(); + expect(isStandardSyntaxRule(lessNode('&:extend(.inline) {}'))).toBeFalsy(); }); it('less detached rulesets', () => { expect(isStandardSyntaxRule(lessNode('@foo: {};'))).toBeFalsy(); From 71fa8d60888bacfe589fa72d66f297ec513605b8 Mon Sep 17 00:00:00 2001 From: immitsu Date: Sun, 25 Jul 2021 10:18:28 +0300 Subject: [PATCH 4/5] Replace checks for selector --- .../__tests__/isStandardSyntaxRule.test.js | 4 ++-- lib/utils/isStandardSyntaxRule.js | 21 +++---------------- lib/utils/isStandardSyntaxSelector.js | 15 +++++++++++++ 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/utils/__tests__/isStandardSyntaxRule.test.js b/lib/utils/__tests__/isStandardSyntaxRule.test.js index dac5b56bff..199bb5d079 100644 --- a/lib/utils/__tests__/isStandardSyntaxRule.test.js +++ b/lib/utils/__tests__/isStandardSyntaxRule.test.js @@ -35,10 +35,10 @@ describe('isStandardSyntaxRule', () => { it('custom-property-set', () => { expect(isStandardSyntaxRule(node('--custom-property-set: {}'))).toBeFalsy(); }); - it('Scss nested properties', () => { + it('scss nested properties', () => { expect(isStandardSyntaxRule(node('foo: {};'))).toBeFalsy(); }); - it('Less class parametric mixin', () => { + it('less class parametric mixin', () => { expect(isStandardSyntaxRule(lessNode('.mixin-name(@var) {}'))).toBeFalsy(); }); it('non-outputting parametric Less class mixin definition', () => { diff --git a/lib/utils/isStandardSyntaxRule.js b/lib/utils/isStandardSyntaxRule.js index 0fe6dc3f67..cc28563494 100644 --- a/lib/utils/isStandardSyntaxRule.js +++ b/lib/utils/isStandardSyntaxRule.js @@ -13,27 +13,12 @@ module.exports = function (rule) { return false; } - const raws = rule.raws; - - // Get full selector - const selector = (raws.selector && raws.selector.raw) || rule.selector; - - if (!isStandardSyntaxSelector(rule.selector)) { - return false; - } - - // Non-outputting Less mixin definition (e.g. .mixin() {}) - if (selector.endsWith(')') && !selector.includes(':')) { + // Ignore Less &:extend rule + if ('extend' in rule && rule.extend) { return false; } - // Less Parametric mixins (e.g. .mixin(@variable: x) {}) - if (/\(@.*\)$/.test(selector)) { - return false; - } - - // Ignore Scss nested properties - if (selector.endsWith(':')) { + if (!isStandardSyntaxSelector(rule.selector)) { return false; } diff --git a/lib/utils/isStandardSyntaxSelector.js b/lib/utils/isStandardSyntaxSelector.js index 7c446578b3..dd74d29e7d 100644 --- a/lib/utils/isStandardSyntaxSelector.js +++ b/lib/utils/isStandardSyntaxSelector.js @@ -19,6 +19,11 @@ module.exports = function (selector) { return false; } + // SCSS nested properties + if (selector.endsWith(':')) { + return false; + } + // Less :extend() if (/:extend(\(.*?\))?/.test(selector)) { return false; @@ -29,6 +34,16 @@ module.exports = function (selector) { return false; } + // Less non-outputting mixin definition (e.g. .mixin() {}) + if (selector.endsWith(')') && !selector.includes(':')) { + return false; + } + + // Less Parametric mixins (e.g. .mixin(@variable: x) {}) + if (/\(@.*\)$/.test(selector)) { + return false; + } + // ERB template tags if (selector.includes('<%') || selector.includes('%>')) { return false; From bff625555f4e873ecd7d072829d36781d6306ef8 Mon Sep 17 00:00:00 2001 From: immitsu Date: Sun, 25 Jul 2021 14:06:37 +0300 Subject: [PATCH 5/5] Add tests for selector --- .../__tests__/isStandardSyntaxSelector.test.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/utils/__tests__/isStandardSyntaxSelector.test.js b/lib/utils/__tests__/isStandardSyntaxSelector.test.js index d1cdc0050f..2f973e5845 100644 --- a/lib/utils/__tests__/isStandardSyntaxSelector.test.js +++ b/lib/utils/__tests__/isStandardSyntaxSelector.test.js @@ -42,6 +42,13 @@ describe('isStandardSyntaxSelector', () => { it('SCSS interpolation (pseudo)', () => { expect(isStandardSyntaxSelector(':n-#{$n}')).toBeFalsy(); }); + it('SCSS placeholder', () => { + expect(isStandardSyntaxSelector('%foo')).toBeFalsy(); + }); + it('SCSS nested properties', () => { + expect(isStandardSyntaxSelector('.a { .b }')).toBeFalsy(); + expect(isStandardSyntaxSelector('.a { &:hover }')).toBeFalsy(); + }); it('Less interpolation', () => { expect(isStandardSyntaxSelector('.n-@{n}')).toBeFalsy(); }); @@ -54,8 +61,8 @@ describe('isStandardSyntaxSelector', () => { it('Less extend inside ruleset', () => { expect(isStandardSyntaxSelector('a { &:extend(.a all) }')).toBeFalsy(); }); - it('SCSS placeholder', () => { - expect(isStandardSyntaxSelector('%foo')).toBeFalsy(); + it('Less mixin', () => { + expect(isStandardSyntaxSelector('.foo()')).toBeFalsy(); }); it('Less mixin with resolved nested selectors', () => { expect(isStandardSyntaxSelector('.foo().bar')).toBeFalsy(); @@ -69,6 +76,10 @@ describe('isStandardSyntaxSelector', () => { expect(isStandardSyntaxSelector('.foo()[bar]')).toBeFalsy(); expect(isStandardSyntaxSelector(".foo()[bar='baz']")).toBeFalsy(); }); + it('Less parametric mixin', () => { + expect(isStandardSyntaxSelector('.foo(@a)')).toBeFalsy(); + expect(isStandardSyntaxSelector('.foo(@a: 5px)')).toBeFalsy(); + }); it('ERB templates', () => { // E. g. like in https://github.com/stylelint/stylelint/issues/4489