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

main
Last change on this file was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

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