.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / 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             category: "Possible Errors",
63             recommended: false,
64             url: "https://eslint.org/docs/rules/no-await-in-loop"
65         },
66
67         schema: [],
68
69         messages: {
70             unexpectedAwait: "Unexpected `await` inside a loop."
71         }
72     },
73     create(context) {
74
75         /**
76          * Validate an await expression.
77          * @param {ASTNode} awaitNode An AwaitExpression or ForOfStatement node to validate.
78          * @returns {void}
79          */
80         function validate(awaitNode) {
81             if (awaitNode.type === "ForOfStatement" && !awaitNode.await) {
82                 return;
83             }
84
85             let node = awaitNode;
86             let parent = node.parent;
87
88             while (parent && !isBoundary(parent)) {
89                 if (isLooped(node, parent)) {
90                     context.report({
91                         node: awaitNode,
92                         messageId: "unexpectedAwait"
93                     });
94                     return;
95                 }
96                 node = parent;
97                 parent = parent.parent;
98             }
99         }
100
101         return {
102             AwaitExpression: validate,
103             ForOfStatement: validate
104         };
105     }
106 };