source: imaps-frontend/node_modules/eslint/lib/rules/no-array-constructor.js@ d565449

main
Last change on this file since d565449 was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 4.4 KB
Line 
1/**
2 * @fileoverview Disallow construction of dense arrays using the Array constructor
3 * @author Matt DuVall <http://www.mattduvall.com/>
4 */
5
6"use strict";
7
8//------------------------------------------------------------------------------
9// Requirements
10//------------------------------------------------------------------------------
11
12const {
13 getVariableByName,
14 isClosingParenToken,
15 isOpeningParenToken,
16 isStartOfExpressionStatement,
17 needsPrecedingSemicolon
18} = require("./utils/ast-utils");
19
20//------------------------------------------------------------------------------
21// Rule Definition
22//------------------------------------------------------------------------------
23
24/** @type {import('../shared/types').Rule} */
25module.exports = {
26 meta: {
27 type: "suggestion",
28
29 docs: {
30 description: "Disallow `Array` constructors",
31 recommended: false,
32 url: "https://eslint.org/docs/latest/rules/no-array-constructor"
33 },
34
35 hasSuggestions: true,
36
37 schema: [],
38
39 messages: {
40 preferLiteral: "The array literal notation [] is preferable.",
41 useLiteral: "Replace with an array literal.",
42 useLiteralAfterSemicolon: "Replace with an array literal, add preceding semicolon."
43 }
44 },
45
46 create(context) {
47
48 const sourceCode = context.sourceCode;
49
50 /**
51 * Gets the text between the calling parentheses of a CallExpression or NewExpression.
52 * @param {ASTNode} node A CallExpression or NewExpression node.
53 * @returns {string} The text between the calling parentheses, or an empty string if there are none.
54 */
55 function getArgumentsText(node) {
56 const lastToken = sourceCode.getLastToken(node);
57
58 if (!isClosingParenToken(lastToken)) {
59 return "";
60 }
61
62 let firstToken = node.callee;
63
64 do {
65 firstToken = sourceCode.getTokenAfter(firstToken);
66 if (!firstToken || firstToken === lastToken) {
67 return "";
68 }
69 } while (!isOpeningParenToken(firstToken));
70
71 return sourceCode.text.slice(firstToken.range[1], lastToken.range[0]);
72 }
73
74 /**
75 * Disallow construction of dense arrays using the Array constructor
76 * @param {ASTNode} node node to evaluate
77 * @returns {void}
78 * @private
79 */
80 function check(node) {
81 if (
82 node.callee.type !== "Identifier" ||
83 node.callee.name !== "Array" ||
84 node.arguments.length === 1 &&
85 node.arguments[0].type !== "SpreadElement") {
86 return;
87 }
88
89 const variable = getVariableByName(sourceCode.getScope(node), "Array");
90
91 /*
92 * Check if `Array` is a predefined global variable: predefined globals have no declarations,
93 * meaning that the `identifiers` list of the variable object is empty.
94 */
95 if (variable && variable.identifiers.length === 0) {
96 const argsText = getArgumentsText(node);
97 let fixText;
98 let messageId;
99
100 /*
101 * Check if the suggested change should include a preceding semicolon or not.
102 * Due to JavaScript's ASI rules, a missing semicolon may be inserted automatically
103 * before an expression like `Array()` or `new Array()`, but not when the expression
104 * is changed into an array literal like `[]`.
105 */
106 if (isStartOfExpressionStatement(node) && needsPrecedingSemicolon(sourceCode, node)) {
107 fixText = `;[${argsText}]`;
108 messageId = "useLiteralAfterSemicolon";
109 } else {
110 fixText = `[${argsText}]`;
111 messageId = "useLiteral";
112 }
113
114 context.report({
115 node,
116 messageId: "preferLiteral",
117 suggest: [
118 {
119 messageId,
120 fix: fixer => fixer.replaceText(node, fixText)
121 }
122 ]
123 });
124 }
125 }
126
127 return {
128 CallExpression: check,
129 NewExpression: check
130 };
131
132 }
133};
Note: See TracBrowser for help on using the repository browser.