UNPKG

5.2 kBJavaScriptView Raw
1/**
2 * @fileoverview Disallow renaming import, export, and destructured assignments to the same name.
3 * @author Kai Cataldo
4 */
5
6"use strict";
7
8//------------------------------------------------------------------------------
9// Rule Definition
10//------------------------------------------------------------------------------
11
12module.exports = {
13 meta: {
14 type: "suggestion",
15
16 docs: {
17 description: "disallow renaming import, export, and destructured assignments to the same name",
18 category: "ECMAScript 6",
19 recommended: false,
20 url: "https://eslint.org/docs/rules/no-useless-rename"
21 },
22
23 fixable: "code",
24
25 schema: [
26 {
27 type: "object",
28 properties: {
29 ignoreDestructuring: { type: "boolean", default: false },
30 ignoreImport: { type: "boolean", default: false },
31 ignoreExport: { type: "boolean", default: false }
32 },
33 additionalProperties: false
34 }
35 ]
36 },
37
38 create(context) {
39 const options = context.options[0] || {},
40 ignoreDestructuring = options.ignoreDestructuring === true,
41 ignoreImport = options.ignoreImport === true,
42 ignoreExport = options.ignoreExport === true;
43
44 //--------------------------------------------------------------------------
45 // Helpers
46 //--------------------------------------------------------------------------
47
48 /**
49 * Reports error for unnecessarily renamed assignments
50 * @param {ASTNode} node - node to report
51 * @param {ASTNode} initial - node with initial name value
52 * @param {ASTNode} result - node with new name value
53 * @param {string} type - the type of the offending node
54 * @returns {void}
55 */
56 function reportError(node, initial, result, type) {
57 const name = initial.type === "Identifier" ? initial.name : initial.value;
58
59 return context.report({
60 node,
61 message: "{{type}} {{name}} unnecessarily renamed.",
62 data: {
63 name,
64 type
65 },
66 fix(fixer) {
67 return fixer.replaceTextRange([
68 initial.range[0],
69 result.range[1]
70 ], name);
71 }
72 });
73 }
74
75 /**
76 * Checks whether a destructured assignment is unnecessarily renamed
77 * @param {ASTNode} node - node to check
78 * @returns {void}
79 */
80 function checkDestructured(node) {
81 if (ignoreDestructuring) {
82 return;
83 }
84
85 const properties = node.properties;
86
87 for (let i = 0; i < properties.length; i++) {
88 if (properties[i].shorthand) {
89 continue;
90 }
91
92 /**
93 * If an ObjectPattern property is computed, we have no idea
94 * if a rename is useless or not. If an ObjectPattern property
95 * lacks a key, it is likely an ExperimentalRestProperty and
96 * so there is no "renaming" occurring here.
97 */
98 if (properties[i].computed || !properties[i].key) {
99 continue;
100 }
101
102 if (properties[i].key.type === "Identifier" && properties[i].key.name === properties[i].value.name ||
103 properties[i].key.type === "Literal" && properties[i].key.value === properties[i].value.name) {
104 reportError(properties[i], properties[i].key, properties[i].value, "Destructuring assignment");
105 }
106 }
107 }
108
109 /**
110 * Checks whether an import is unnecessarily renamed
111 * @param {ASTNode} node - node to check
112 * @returns {void}
113 */
114 function checkImport(node) {
115 if (ignoreImport) {
116 return;
117 }
118
119 if (node.imported.name === node.local.name &&
120 node.imported.range[0] !== node.local.range[0]) {
121 reportError(node, node.imported, node.local, "Import");
122 }
123 }
124
125 /**
126 * Checks whether an export is unnecessarily renamed
127 * @param {ASTNode} node - node to check
128 * @returns {void}
129 */
130 function checkExport(node) {
131 if (ignoreExport) {
132 return;
133 }
134
135 if (node.local.name === node.exported.name &&
136 node.local.range[0] !== node.exported.range[0]) {
137 reportError(node, node.local, node.exported, "Export");
138 }
139
140 }
141
142 //--------------------------------------------------------------------------
143 // Public
144 //--------------------------------------------------------------------------
145
146 return {
147 ObjectPattern: checkDestructured,
148 ImportSpecifier: checkImport,
149 ExportSpecifier: checkExport
150 };
151 }
152};