Permalink
Cannot retrieve contributors at this time
| /** | |
| * @fileoverview Rule to disallow uses of await inside of loops. | |
| * @author Nat Mote (nmote) | |
| */ | |
| "use strict"; | |
| /** | |
| * Check whether it should stop traversing ancestors at the given node. | |
| * @param {ASTNode} node A node to check. | |
| * @returns {boolean} `true` if it should stop traversing. | |
| */ | |
| function isBoundary(node) { | |
| const t = node.type; | |
| return ( | |
| t === "FunctionDeclaration" || | |
| t === "FunctionExpression" || | |
| t === "ArrowFunctionExpression" || | |
| /* | |
| * Don't report the await expressions on for-await-of loop since it's | |
| * asynchronous iteration intentionally. | |
| */ | |
| (t === "ForOfStatement" && node.await === true) | |
| ); | |
| } | |
| /** | |
| * Check whether the given node is in loop. | |
| * @param {ASTNode} node A node to check. | |
| * @param {ASTNode} parent A parent node to check. | |
| * @returns {boolean} `true` if the node is in loop. | |
| */ | |
| function isLooped(node, parent) { | |
| switch (parent.type) { | |
| case "ForStatement": | |
| return ( | |
| node === parent.test || | |
| node === parent.update || | |
| node === parent.body | |
| ); | |
| case "ForOfStatement": | |
| case "ForInStatement": | |
| return node === parent.body; | |
| case "WhileStatement": | |
| case "DoWhileStatement": | |
| return node === parent.test || node === parent.body; | |
| default: | |
| return false; | |
| } | |
| } | |
| module.exports = { | |
| meta: { | |
| type: "problem", | |
| docs: { | |
| description: "disallow `await` inside of loops", | |
| category: "Possible Errors", | |
| recommended: false, | |
| url: "https://eslint.org/docs/rules/no-await-in-loop" | |
| }, | |
| schema: [], | |
| messages: { | |
| unexpectedAwait: "Unexpected `await` inside a loop." | |
| } | |
| }, | |
| create(context) { | |
| /** | |
| * Validate an await expression. | |
| * @param {ASTNode} awaitNode An AwaitExpression or ForOfStatement node to validate. | |
| * @returns {void} | |
| */ | |
| function validate(awaitNode) { | |
| if (awaitNode.type === "ForOfStatement" && !awaitNode.await) { | |
| return; | |
| } | |
| let node = awaitNode; | |
| let parent = node.parent; | |
| while (parent && !isBoundary(parent)) { | |
| if (isLooped(node, parent)) { | |
| context.report({ | |
| node: awaitNode, | |
| messageId: "unexpectedAwait" | |
| }); | |
| return; | |
| } | |
| node = parent; | |
| parent = parent.parent; | |
| } | |
| } | |
| return { | |
| AwaitExpression: validate, | |
| ForOfStatement: validate | |
| }; | |
| } | |
| }; |