]> git.proxmox.com Git - pve-eslint.git/blob - eslint/lib/rules/no-await-in-loop.js
import 8.3.0 source
[pve-eslint.git] / eslint / lib / rules / no-await-in-loop.js
1 /**
2 * @fileoverview Rule to disallow uses of await inside of loops.
3 * @author Nat Mote (nmote)
4 */
5 "use strict";
6
7 /**
8 * Check whether it should stop traversing ancestors at the given node.
9 * @param {ASTNode} node A node to check.
10 * @returns {boolean} `true` if it should stop traversing.
11 */
12 function isBoundary(node) {
13 const t = node.type;
14
15 return (
16 t === "FunctionDeclaration" ||
17 t === "FunctionExpression" ||
18 t === "ArrowFunctionExpression" ||
19
20 /*
21 * Don't report the await expressions on for-await-of loop since it's
22 * asynchronous iteration intentionally.
23 */
24 (t === "ForOfStatement" && node.await === true)
25 );
26 }
27
28 /**
29 * Check whether the given node is in loop.
30 * @param {ASTNode} node A node to check.
31 * @param {ASTNode} parent A parent node to check.
32 * @returns {boolean} `true` if the node is in loop.
33 */
34 function isLooped(node, parent) {
35 switch (parent.type) {
36 case "ForStatement":
37 return (
38 node === parent.test ||
39 node === parent.update ||
40 node === parent.body
41 );
42
43 case "ForOfStatement":
44 case "ForInStatement":
45 return node === parent.body;
46
47 case "WhileStatement":
48 case "DoWhileStatement":
49 return node === parent.test || node === parent.body;
50
51 default:
52 return false;
53 }
54 }
55
56 module.exports = {
57 meta: {
58 type: "problem",
59
60 docs: {
61 description: "disallow `await` inside of loops",
62 recommended: false,
63 url: "https://eslint.org/docs/rules/no-await-in-loop"
64 },
65
66 schema: [],
67
68 messages: {
69 unexpectedAwait: "Unexpected `await` inside a loop."
70 }
71 },
72 create(context) {
73
74 /**
75 * Validate an await expression.
76 * @param {ASTNode} awaitNode An AwaitExpression or ForOfStatement node to validate.
77 * @returns {void}
78 */
79 function validate(awaitNode) {
80 if (awaitNode.type === "ForOfStatement" && !awaitNode.await) {
81 return;
82 }
83
84 let node = awaitNode;
85 let parent = node.parent;
86
87 while (parent && !isBoundary(parent)) {
88 if (isLooped(node, parent)) {
89 context.report({
90 node: awaitNode,
91 messageId: "unexpectedAwait"
92 });
93 return;
94 }
95 node = parent;
96 parent = parent.parent;
97 }
98 }
99
100 return {
101 AwaitExpression: validate,
102 ForOfStatement: validate
103 };
104 }
105 };