Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorAntoine du Hamel <duhamelantoine1995@gmail.com>2021-01-06 21:19:36 +0300
committerDanielle Adams <adamzdanielle@gmail.com>2021-03-16 15:55:09 +0300
commit057c6a842a55fbbf59db5c422f943c770568ce3d (patch)
treeb8cc6fa1a69586185ed18e80e33fdbe796e0d5c3 /tools
parentdaa4ac54c5a46ab17fa40178170e0e96aecba849 (diff)
tools: add ESLint rule no-array-destructuring
Iterating over arrays should be avoided because it relies on user-mutable global methods (`Array.prototype[Symbol.iterator]` and `%ArrayIteratorPrototype%.next`), we should instead use other alternatives. This commit adds a rule that disallow array destructuring syntax in favor of object destructuring syntax. Note that you can ignore this rule if you are using the array destructuring syntax over a safe iterable, or actually want to iterate over a user-provided object. PR-URL: https://github.com/nodejs/node/pull/36818 Reviewed-By: Rich Trott <rtrott@gmail.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/eslint-rules/no-array-destructuring.js83
1 files changed, 83 insertions, 0 deletions
diff --git a/tools/eslint-rules/no-array-destructuring.js b/tools/eslint-rules/no-array-destructuring.js
new file mode 100644
index 00000000000..81667e698fb
--- /dev/null
+++ b/tools/eslint-rules/no-array-destructuring.js
@@ -0,0 +1,83 @@
+/**
+ * @fileoverview Iterating over arrays should be avoided because it relies on
+ * user-mutable global methods (`Array.prototype[Symbol.iterator]`
+ * and `%ArrayIteratorPrototype%.next`), we should instead use
+ * other alternatives. This file defines a rule that disallow
+ * array destructuring syntax in favor of object destructuring
+ * syntax. Note that you can ignore this rule if you are using
+ * the array destructuring syntax over a safe iterable, or
+ * actually want to iterate over a user-provided object.
+ * @author aduh95 <duhamelantoine1995@gmail.com>
+ */
+'use strict';
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+const USE_OBJ_DESTRUCTURING =
+ 'Use object destructuring instead of array destructuring.';
+const USE_ARRAY_METHODS =
+ 'Use primordials.ArrayPrototypeSlice to avoid unsafe array iteration.';
+
+const findComma = (sourceCode, elements, i, start) => {
+ if (i === 0)
+ return sourceCode.getTokenAfter(sourceCode.getTokenByRangeStart(start));
+
+ let element;
+ const originalIndex = i;
+ while (i && !element) {
+ element = elements[--i];
+ }
+ let token = sourceCode.getTokenAfter(
+ element ?? sourceCode.getTokenByRangeStart(start)
+ );
+ for (; i < originalIndex; i++) {
+ token = sourceCode.getTokenAfter(token);
+ }
+ return token;
+};
+const createFix = (fixer, sourceCode, { range: [start, end], elements }) => [
+ fixer.replaceTextRange([start, start + 1], '{'),
+ fixer.replaceTextRange([end - 1, end], '}'),
+ ...elements.map((node, i) =>
+ (node === null ?
+ fixer.remove(findComma(sourceCode, elements, i, start)) :
+ fixer.insertTextBefore(node, i + ':'))
+ ),
+];
+const arrayPatternContainsRestOperator = ({ elements }) =>
+ elements?.find((node) => node?.type === 'RestElement');
+
+module.exports = {
+ meta: {
+ type: 'suggestion',
+ fixable: 'code',
+ schema: [],
+ },
+ create(context) {
+ const sourceCode = context.getSourceCode();
+
+ return {
+ ArrayPattern(node) {
+ const hasRest = arrayPatternContainsRestOperator(node);
+ context.report({
+ message: hasRest ? USE_ARRAY_METHODS : USE_OBJ_DESTRUCTURING,
+ node: hasRest || node,
+ fix: hasRest ?
+ undefined :
+ (fixer) => [
+ ...(node.parent.type === 'AssignmentExpression' ?
+ [
+ fixer.insertTextBefore(node.parent, '('),
+ fixer.insertTextAfter(node.parent, ')'),
+ ] :
+ []),
+ ...createFix(fixer, sourceCode, node),
+ ],
+ });
+
+ },
+ };
+ },
+};