.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / no-duplicate-imports.js
1 /**
2  * @fileoverview Restrict usage of duplicate imports.
3  * @author Simen Bekkhus
4  */
5 "use strict";
6
7 //------------------------------------------------------------------------------
8 // Rule Definition
9 //------------------------------------------------------------------------------
10
11 /**
12  * Returns the name of the module imported or re-exported.
13  * @param {ASTNode} node A node to get.
14  * @returns {string} the name of the module, or empty string if no name.
15  */
16 function getValue(node) {
17     if (node && node.source && node.source.value) {
18         return node.source.value.trim();
19     }
20
21     return "";
22 }
23
24 /**
25  * Checks if the name of the import or export exists in the given array, and reports if so.
26  * @param {RuleContext} context The ESLint rule context object.
27  * @param {ASTNode} node A node to get.
28  * @param {string} value The name of the imported or exported module.
29  * @param {string[]} array The array containing other imports or exports in the file.
30  * @param {string} messageId A messageId to be reported after the name of the module
31  *
32  * @returns {void} No return value
33  */
34 function checkAndReport(context, node, value, array, messageId) {
35     if (array.indexOf(value) !== -1) {
36         context.report({
37             node,
38             messageId,
39             data: {
40                 module: value
41             }
42         });
43     }
44 }
45
46 /**
47  * @callback nodeCallback
48  * @param {ASTNode} node A node to handle.
49  */
50
51 /**
52  * Returns a function handling the imports of a given file
53  * @param {RuleContext} context The ESLint rule context object.
54  * @param {boolean} includeExports Whether or not to check for exports in addition to imports.
55  * @param {string[]} importsInFile The array containing other imports in the file.
56  * @param {string[]} exportsInFile The array containing other exports in the file.
57  *
58  * @returns {nodeCallback} A function passed to ESLint to handle the statement.
59  */
60 function handleImports(context, includeExports, importsInFile, exportsInFile) {
61     return function(node) {
62         const value = getValue(node);
63
64         if (value) {
65             checkAndReport(context, node, value, importsInFile, "import");
66
67             if (includeExports) {
68                 checkAndReport(context, node, value, exportsInFile, "importAs");
69             }
70
71             importsInFile.push(value);
72         }
73     };
74 }
75
76 /**
77  * Returns a function handling the exports of a given file
78  * @param {RuleContext} context The ESLint rule context object.
79  * @param {string[]} importsInFile The array containing other imports in the file.
80  * @param {string[]} exportsInFile The array containing other exports in the file.
81  *
82  * @returns {nodeCallback} A function passed to ESLint to handle the statement.
83  */
84 function handleExports(context, importsInFile, exportsInFile) {
85     return function(node) {
86         const value = getValue(node);
87
88         if (value) {
89             checkAndReport(context, node, value, exportsInFile, "export");
90             checkAndReport(context, node, value, importsInFile, "exportAs");
91
92             exportsInFile.push(value);
93         }
94     };
95 }
96
97 module.exports = {
98     meta: {
99         type: "problem",
100
101         docs: {
102             description: "disallow duplicate module imports",
103             category: "ECMAScript 6",
104             recommended: false,
105             url: "https://eslint.org/docs/rules/no-duplicate-imports"
106         },
107
108         schema: [{
109             type: "object",
110             properties: {
111                 includeExports: {
112                     type: "boolean",
113                     default: false
114                 }
115             },
116             additionalProperties: false
117         }],
118         messages: {
119             import: "'{{module}}' import is duplicated.",
120             importAs: "'{{module}}' import is duplicated as export.",
121             export: "'{{module}}' export is duplicated.",
122             exportAs: "'{{module}}' export is duplicated as import."
123         }
124     },
125
126     create(context) {
127         const includeExports = (context.options[0] || {}).includeExports,
128             importsInFile = [],
129             exportsInFile = [];
130
131         const handlers = {
132             ImportDeclaration: handleImports(context, includeExports, importsInFile, exportsInFile)
133         };
134
135         if (includeExports) {
136             handlers.ExportNamedDeclaration = handleExports(context, importsInFile, exportsInFile);
137             handlers.ExportAllDeclaration = handleExports(context, importsInFile, exportsInFile);
138         }
139
140         return handlers;
141     }
142 };