Skip to content

Commit

Permalink
Merge pull request #6842 from stylelint/fix-function-no-unknown-false…
Browse files Browse the repository at this point in the history
…-positives-for-unspaced-operators-against-nested-brackets--resourceful-kangaroo-ec239dde9a

Fix `function-no-unknown` false positives for unspaced operators against nested brackets
  • Loading branch information
romainmenke committed May 15, 2023
2 parents 0c328f9 + 8cd0ee9 commit 6f421a0
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 22 deletions.
5 changes: 5 additions & 0 deletions .changeset/mean-trees-serve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"stylelint": patch
---

Fixed: `function-no-unknown` false positives for unspaced operators against nested brackets
3 changes: 3 additions & 0 deletions lib/rules/function-no-unknown/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ testRule({
{
code: 'a { background: -webkit-gradient(linear, 0 50%, 0 100%, from(white), color-stop(0.5, yellow), to(red)); }',
},
{
code: 'a { height: calc(10px*(5*(10 - 5))); }',
},
],

reject: [
Expand Down
51 changes: 29 additions & 22 deletions lib/rules/function-no-unknown/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
'use strict';

const fs = require('fs');
const valueParser = require('postcss-value-parser');
const functionsListPath = require('css-functions-list');
const { tokenize } = require('@csstools/css-tokenizer');
const {
parseCommaSeparatedListOfComponentValues,
isFunctionNode,
isSimpleBlockNode,
} = require('@csstools/css-parser-algorithms');

const declarationValueIndex = require('../../utils/declarationValueIndex');
const optionsMatches = require('../../utils/optionsMatches');
const report = require('../../utils/report');
const ruleMessages = require('../../utils/ruleMessages');
const validateOptions = require('../../utils/validateOptions');
const isStandardSyntaxFunction = require('../../utils/isStandardSyntaxFunction');
const isCustomFunction = require('../../utils/isCustomFunction');
const { isRegExp, isString } = require('../../utils/validateTypes');
const isStandardSyntaxValue = require('../../utils/isStandardSyntaxValue');
Expand Down Expand Up @@ -60,39 +64,42 @@ const rule = (primary, secondaryOptions) => {

if (!isStandardSyntaxValue(value)) return;

valueParser(value).walk((node) => {
const name = node.value;
/**
* @param {import('@csstools/css-parser-algorithms').ComponentValue} componentValue
*/
const walker = (componentValue) => {
if (!isFunctionNode(componentValue)) return;

if (node.type !== 'function') {
return;
}
const name = componentValue.getName();

if (!isStandardSyntaxFunction(node)) {
return;
}
if (isCustomFunction(name)) return;

if (isCustomFunction(name)) {
return;
}
if (optionsMatches(secondaryOptions, 'ignoreFunctions', name)) return;

if (optionsMatches(secondaryOptions, 'ignoreFunctions', name)) {
return;
}

if (functionsList.includes(name.toLowerCase())) {
return;
}
if (functionsList.includes(name.toLowerCase())) return;

report({
message: messages.rejected,
messageArgs: [name],
node: decl,
index: declarationValueIndex(decl) + node.sourceIndex,
index: declarationValueIndex(decl) + componentValue.name[2],
result,
ruleName,
word: name,
});
});
};

parseCommaSeparatedListOfComponentValues(tokenize({ css: value }))
.flatMap((x) => x)
.forEach((componentValue) => {
if (isFunctionNode(componentValue) || isSimpleBlockNode(componentValue)) {
walker(componentValue);

componentValue.walk((entry) => {
walker(entry.node);
});
}
});
});
};
};
Expand Down

3 comments on commit 6f421a0

@ybiquitous
Copy link
Member

Choose a reason for hiding this comment

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

@romainmenke Sorry for my late notice. Could you please usually "squash and merge" pull requests as the maintainer guide says?

However, I appreciate your effort and contribution to this project! 😊

@romainmenke
Copy link
Member Author

@romainmenke romainmenke commented on 6f421a0 May 16, 2023

Choose a reason for hiding this comment

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

Thank you @ybiquitous for pointing this out, I will use the correct merge method from now on :)

Is this something that can be enforced in settings, so that only squash and merge is available?

@ybiquitous
Copy link
Member

Choose a reason for hiding this comment

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

Is this something that can be enforced in settings, so that only squash and merge is available?

It would be ideal, but we occasionally want to use "merge", for example, when merging a long-living branch to implement a big feature and preserve each commit. 😅

I wish we had a better way... 🤔

Please sign in to comment.