123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- /**
- * @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;
- }
- }
- /** @type {import('../shared/types').Rule} */
- module.exports = {
- meta: {
- type: "problem",
- docs: {
- description: "Disallow `await` inside of loops",
- 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
- };
- }
- };
|