source: imaps-frontend/node_modules/eslint-plugin-react/lib/rules/jsx-sort-default-props.js

main
Last change on this file was 0c6b92a, checked in by stefan toskovski <stefantoska84@…>, 7 months ago

Pred finalna verzija

  • Property mode set to 100644
File size: 5.5 KB
Line 
1/**
2 * @fileoverview Enforce default props alphabetical sorting
3 * @author Vladimir Kattsov
4 * @deprecated
5 */
6
7'use strict';
8
9const variableUtil = require('../util/variable');
10const docsUrl = require('../util/docsUrl');
11const report = require('../util/report');
12const log = require('../util/log');
13const eslintUtil = require('../util/eslint');
14
15const getFirstTokens = eslintUtil.getFirstTokens;
16const getText = eslintUtil.getText;
17
18let isWarnedForDeprecation = false;
19
20// ------------------------------------------------------------------------------
21// Rule Definition
22// ------------------------------------------------------------------------------
23
24const messages = {
25 propsNotSorted: 'Default prop types declarations should be sorted alphabetically',
26};
27
28/** @type {import('eslint').Rule.RuleModule} */
29module.exports = {
30 meta: {
31 deprecated: true,
32 replacedBy: ['sort-default-props'],
33 docs: {
34 description: 'Enforce defaultProps declarations alphabetical sorting',
35 category: 'Stylistic Issues',
36 recommended: false,
37 url: docsUrl('jsx-sort-default-props'),
38 },
39 // fixable: 'code',
40
41 messages,
42
43 schema: [{
44 type: 'object',
45 properties: {
46 ignoreCase: {
47 type: 'boolean',
48 },
49 },
50 additionalProperties: false,
51 }],
52 },
53
54 create(context) {
55 const configuration = context.options[0] || {};
56 const ignoreCase = configuration.ignoreCase || false;
57
58 /**
59 * Get properties name
60 * @param {Object} node - Property.
61 * @returns {string} Property name.
62 */
63 function getPropertyName(node) {
64 if (node.key || ['MethodDefinition', 'Property'].indexOf(node.type) !== -1) {
65 return node.key.name;
66 }
67 if (node.type === 'MemberExpression') {
68 return node.property.name;
69 // Special case for class properties
70 // (babel-eslint@5 does not expose property name so we have to rely on tokens)
71 }
72 if (node.type === 'ClassProperty') {
73 const tokens = getFirstTokens(context, node, 2);
74 return tokens[1] && tokens[1].type === 'Identifier' ? tokens[1].value : tokens[0].value;
75 }
76 return '';
77 }
78
79 /**
80 * Checks if the Identifier node passed in looks like a defaultProps declaration.
81 * @param {ASTNode} node The node to check. Must be an Identifier node.
82 * @returns {boolean} `true` if the node is a defaultProps declaration, `false` if not
83 */
84 function isDefaultPropsDeclaration(node) {
85 const propName = getPropertyName(node);
86 return (propName === 'defaultProps' || propName === 'getDefaultProps');
87 }
88
89 function getKey(node) {
90 return getText(context, node.key || node.argument);
91 }
92
93 /**
94 * Find a variable by name in the current scope.
95 * @param {ASTNode} node The node to look for.
96 * @param {string} name Name of the variable to look for.
97 * @returns {ASTNode|null} Return null if the variable could not be found, ASTNode otherwise.
98 */
99 function findVariableByName(node, name) {
100 const variable = variableUtil
101 .getVariableFromContext(context, node, name);
102
103 if (!variable || !variable.defs[0] || !variable.defs[0].node) {
104 return null;
105 }
106
107 if (variable.defs[0].node.type === 'TypeAlias') {
108 return variable.defs[0].node.right;
109 }
110
111 return variable.defs[0].node.init;
112 }
113
114 /**
115 * Checks if defaultProps declarations are sorted
116 * @param {Array} declarations The array of AST nodes being checked.
117 * @returns {void}
118 */
119 function checkSorted(declarations) {
120 // function fix(fixer) {
121 // return propTypesSortUtil.fixPropTypesSort(context, fixer, declarations, ignoreCase);
122 // }
123
124 declarations.reduce((prev, curr, idx, decls) => {
125 if (/Spread(?:Property|Element)$/.test(curr.type)) {
126 return decls[idx + 1];
127 }
128
129 let prevPropName = getKey(prev);
130 let currentPropName = getKey(curr);
131
132 if (ignoreCase) {
133 prevPropName = prevPropName.toLowerCase();
134 currentPropName = currentPropName.toLowerCase();
135 }
136
137 if (currentPropName < prevPropName) {
138 report(context, messages.propsNotSorted, 'propsNotSorted', {
139 node: curr,
140 // fix
141 });
142
143 return prev;
144 }
145
146 return curr;
147 }, declarations[0]);
148 }
149
150 function checkNode(node) {
151 if (!node) {
152 return;
153 }
154 if (node.type === 'ObjectExpression') {
155 checkSorted(node.properties);
156 } else if (node.type === 'Identifier') {
157 const propTypesObject = findVariableByName(node, node.name);
158 if (propTypesObject && propTypesObject.properties) {
159 checkSorted(propTypesObject.properties);
160 }
161 }
162 }
163
164 // --------------------------------------------------------------------------
165 // Public API
166 // --------------------------------------------------------------------------
167
168 return {
169 'ClassProperty, PropertyDefinition'(node) {
170 if (!isDefaultPropsDeclaration(node)) {
171 return;
172 }
173
174 checkNode(node.value);
175 },
176
177 MemberExpression(node) {
178 if (!isDefaultPropsDeclaration(node)) {
179 return;
180 }
181
182 checkNode('right' in node.parent && node.parent.right);
183 },
184
185 Program() {
186 if (isWarnedForDeprecation) {
187 return;
188 }
189
190 log('The react/jsx-sort-default-props rule is deprecated. It has been renamed to `react/sort-default-props`.');
191 isWarnedForDeprecation = true;
192 },
193 };
194 },
195};
Note: See TracBrowser for help on using the repository browser.