diff --git a/src/rules/at-import-partial-extension-allowed-list/__tests__/index.js b/src/rules/at-import-partial-extension-allowed-list/__tests__/index.js index f534ba95..e51585c1 100644 --- a/src/rules/at-import-partial-extension-allowed-list/__tests__/index.js +++ b/src/rules/at-import-partial-extension-allowed-list/__tests__/index.js @@ -83,8 +83,7 @@ testRule({ line: 2, column: 20, message: messages.rejected("scssy"), - description: - "One file, ext not from an allowed list, space at the end." + description: "One file, ext not from an allowed list, space at the end." }, { code: ` diff --git a/src/rules/no-global-function-names/__tests__/index.js b/src/rules/no-global-function-names/__tests__/index.js index 54752038..72af14fd 100644 --- a/src/rules/no-global-function-names/__tests__/index.js +++ b/src/rules/no-global-function-names/__tests__/index.js @@ -290,6 +290,26 @@ testRule({ @debug string.unique-id() `, description: "string.unique-id" + }, + { + code: ` + @use "sass:meta" + @function is-number($value) { + @return meta.type-of($value) == 'number' + } + `, + description: "Allowed non-global function in @return" + }, + { + code: ` + @use "sass:meta" + @mixin foo($name) { + @if meta.type-of($name) != 'string' { + @error 'name must be a string, but was ' + meta.type-of($name) + } + } + `, + description: "Allowed non-global function in @if and @error" } ], @@ -491,6 +511,41 @@ testRule({ "Expected color.adjust($color, $lightness: $amount) instead of lighten($color, $amount)" ), description: "lighten" + }, + { + code: ` + @function is-number($value) { + @return type-of($value) == 'number' + } + `, + line: 3, + column: 17, + message: messages.rejected("type-of"), + description: "Global function in @return" + }, + { + code: ` + @mixin foo($name) { + @if type-of($name) != 'string' { + @error 'name must be a test(string), but was' + type-of($name) + } + } + `, + warnings: [ + { + line: 3, + column: 13, + message: messages.rejected("type-of"), + description: "Global function in @if" + }, + { + line: 4, + column: 59, + message: messages.rejected("type-of"), + description: "Global function in @error" + } + ], + description: "Global function in @if and @error" } ] }); diff --git a/src/rules/no-global-function-names/index.js b/src/rules/no-global-function-names/index.js index 0fa707e9..f6238135 100644 --- a/src/rules/no-global-function-names/index.js +++ b/src/rules/no-global-function-names/index.js @@ -2,6 +2,7 @@ const valueParser = require("postcss-value-parser"); const { utils } = require("stylelint"); +const getAtRuleParams = require("../../utils/getAtRuleParams"); const namespace = require("../../utils/namespace"); const ruleUrl = require("../../utils/ruleUrl"); @@ -173,7 +174,15 @@ function rule(value) { } root.walkDecls(decl => { - valueParser(decl.value).walk(node => { + checkValue(decl, decl.value); + }); + root.walkAtRules(atRule => { + const params = getAtRuleParams(atRule); + checkValue(atRule, params); + }); + + function checkValue(parentNode, value) { + valueParser(value).walk(node => { const cleanValue = node.value.replace(interpolationPrefix, ""); // Verify that we're only looking at functions. @@ -184,14 +193,14 @@ function rule(value) { if (rules[cleanValue]) { utils.report({ message: messages.rejected(cleanValue), - node: decl, + node: parentNode, word: cleanValue, result, ruleName }); } }); - }); + } }; } diff --git a/src/utils/getAtRuleParams.js b/src/utils/getAtRuleParams.js new file mode 100644 index 00000000..dbeaca1c --- /dev/null +++ b/src/utils/getAtRuleParams.js @@ -0,0 +1,11 @@ +"use strict"; + +/** + * @param {import('postcss').AtRule} atRule + * @returns {string} + */ +function getAtRuleParams(atRule) { + return atRule.raws.params?.raw ?? atRule.params; +} + +module.exports = getAtRuleParams;