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