UNPKG

2.92 kBJavaScriptView Raw
1// @ts-nocheck
2
3'use strict';
4
5const _ = require('lodash');
6const declarationValueIndex = require('../../utils/declarationValueIndex');
7const isStandardSyntaxFunction = require('../../utils/isStandardSyntaxFunction');
8const keywordSets = require('../../reference/keywordSets');
9const matchesStringOrRegExp = require('../../utils/matchesStringOrRegExp');
10const report = require('../../utils/report');
11const ruleMessages = require('../../utils/ruleMessages');
12const validateOptions = require('../../utils/validateOptions');
13const valueParser = require('postcss-value-parser');
14
15const ruleName = 'function-name-case';
16
17const messages = ruleMessages(ruleName, {
18 expected: (actual, expected) => `Expected "${actual}" to be "${expected}"`,
19});
20
21const mapLowercaseFunctionNamesToCamelCase = new Map();
22
23keywordSets.camelCaseFunctionNames.forEach((func) => {
24 mapLowercaseFunctionNamesToCamelCase.set(func.toLowerCase(), func);
25});
26
27function rule(expectation, options, context) {
28 return (root, result) => {
29 const validOptions = validateOptions(
30 result,
31 ruleName,
32 {
33 actual: expectation,
34 possible: ['lower', 'upper'],
35 },
36 {
37 actual: options,
38 possible: {
39 ignoreFunctions: [_.isString, _.isRegExp],
40 },
41 optional: true,
42 },
43 );
44
45 if (!validOptions) {
46 return;
47 }
48
49 root.walkDecls((decl) => {
50 let needFix = false;
51 const parsed = valueParser(decl.raws.value ? decl.raws.value.raw : decl.value);
52
53 parsed.walk((node) => {
54 if (node.type !== 'function' || !isStandardSyntaxFunction(node)) {
55 return;
56 }
57
58 const functionName = node.value;
59 const functionNameLowerCase = functionName.toLowerCase();
60
61 const ignoreFunctions = (options && options.ignoreFunctions) || [];
62
63 if (ignoreFunctions.length > 0 && matchesStringOrRegExp(functionName, ignoreFunctions)) {
64 return;
65 }
66
67 let expectedFunctionName = null;
68
69 if (
70 expectation === 'lower' &&
71 mapLowercaseFunctionNamesToCamelCase.has(functionNameLowerCase)
72 ) {
73 expectedFunctionName = mapLowercaseFunctionNamesToCamelCase.get(functionNameLowerCase);
74 } else if (expectation === 'lower') {
75 expectedFunctionName = functionNameLowerCase;
76 } else {
77 expectedFunctionName = functionName.toUpperCase();
78 }
79
80 if (functionName === expectedFunctionName) {
81 return;
82 }
83
84 if (context.fix) {
85 needFix = true;
86 node.value = expectedFunctionName;
87
88 return;
89 }
90
91 report({
92 message: messages.expected(functionName, expectedFunctionName),
93 node: decl,
94 index: declarationValueIndex(decl) + node.sourceIndex,
95 result,
96 ruleName,
97 });
98 });
99
100 if (context.fix && needFix) {
101 const statement = parsed.toString();
102
103 if (decl.raws.value) {
104 decl.raws.value.raw = statement;
105 } else {
106 decl.value = statement;
107 }
108 }
109 });
110 };
111}
112
113rule.ruleName = ruleName;
114rule.messages = messages;
115module.exports = rule;