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