UNPKG

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