Switch to new repository
diff --git a/node_modules/eslint/lib/rules/no-loop-func.js b/node_modules/eslint/lib/rules/no-loop-func.js
new file mode 100644
index 0000000..f4531f3
--- /dev/null
+++ b/node_modules/eslint/lib/rules/no-loop-func.js
@@ -0,0 +1,209 @@
+/**
+ * @fileoverview Rule to flag creation of function inside a loop
+ * @author Ilya Volodin
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Helpers
+//------------------------------------------------------------------------------
+
+/**
+ * Gets the containing loop node of a specified node.
+ *
+ * We don't need to check nested functions, so this ignores those.
+ * `Scope.through` contains references of nested functions.
+ *
+ * @param {ASTNode} node - An AST node to get.
+ * @returns {ASTNode|null} The containing loop node of the specified node, or
+ *      `null`.
+ */
+function getContainingLoopNode(node) {
+    for (let currentNode = node; currentNode.parent; currentNode = currentNode.parent) {
+        const parent = currentNode.parent;
+
+        switch (parent.type) {
+            case "WhileStatement":
+            case "DoWhileStatement":
+                return parent;
+
+            case "ForStatement":
+
+                // `init` is outside of the loop.
+                if (parent.init !== currentNode) {
+                    return parent;
+                }
+                break;
+
+            case "ForInStatement":
+            case "ForOfStatement":
+
+                // `right` is outside of the loop.
+                if (parent.right !== currentNode) {
+                    return parent;
+                }
+                break;
+
+            case "ArrowFunctionExpression":
+            case "FunctionExpression":
+            case "FunctionDeclaration":
+
+                // We don't need to check nested functions.
+                return null;
+
+            default:
+                break;
+        }
+    }
+
+    return null;
+}
+
+/**
+ * Gets the containing loop node of a given node.
+ * If the loop was nested, this returns the most outer loop.
+ *
+ * @param {ASTNode} node - A node to get. This is a loop node.
+ * @param {ASTNode|null} excludedNode - A node that the result node should not
+ *      include.
+ * @returns {ASTNode} The most outer loop node.
+ */
+function getTopLoopNode(node, excludedNode) {
+    const border = excludedNode ? excludedNode.range[1] : 0;
+    let retv = node;
+    let containingLoopNode = node;
+
+    while (containingLoopNode && containingLoopNode.range[0] >= border) {
+        retv = containingLoopNode;
+        containingLoopNode = getContainingLoopNode(containingLoopNode);
+    }
+
+    return retv;
+}
+
+/**
+ * Checks whether a given reference which refers to an upper scope's variable is
+ * safe or not.
+ *
+ * @param {ASTNode} loopNode - A containing loop node.
+ * @param {eslint-scope.Reference} reference - A reference to check.
+ * @returns {boolean} `true` if the reference is safe or not.
+ */
+function isSafe(loopNode, reference) {
+    const variable = reference.resolved;
+    const definition = variable && variable.defs[0];
+    const declaration = definition && definition.parent;
+    const kind = (declaration && declaration.type === "VariableDeclaration")
+        ? declaration.kind
+        : "";
+
+    // Variables which are declared by `const` is safe.
+    if (kind === "const") {
+        return true;
+    }
+
+    /*
+     * Variables which are declared by `let` in the loop is safe.
+     * It's a different instance from the next loop step's.
+     */
+    if (kind === "let" &&
+        declaration.range[0] > loopNode.range[0] &&
+        declaration.range[1] < loopNode.range[1]
+    ) {
+        return true;
+    }
+
+    /*
+     * WriteReferences which exist after this border are unsafe because those
+     * can modify the variable.
+     */
+    const border = getTopLoopNode(
+        loopNode,
+        (kind === "let") ? declaration : null
+    ).range[0];
+
+    /**
+     * Checks whether a given reference is safe or not.
+     * The reference is every reference of the upper scope's variable we are
+     * looking now.
+     *
+     * It's safeafe if the reference matches one of the following condition.
+     * - is readonly.
+     * - doesn't exist inside a local function and after the border.
+     *
+     * @param {eslint-scope.Reference} upperRef - A reference to check.
+     * @returns {boolean} `true` if the reference is safe.
+     */
+    function isSafeReference(upperRef) {
+        const id = upperRef.identifier;
+
+        return (
+            !upperRef.isWrite() ||
+            variable.scope.variableScope === upperRef.from.variableScope &&
+            id.range[0] < border
+        );
+    }
+
+    return Boolean(variable) && variable.references.every(isSafeReference);
+}
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = {
+    meta: {
+        type: "suggestion",
+
+        docs: {
+            description: "disallow function declarations that contain unsafe references inside loop statements",
+            category: "Best Practices",
+            recommended: false,
+            url: "https://eslint.org/docs/rules/no-loop-func"
+        },
+
+        schema: [],
+
+        messages: {
+            unsafeRefs: "Function declared in a loop contains unsafe references to variable(s) {{ varNames }}."
+        }
+    },
+
+    create(context) {
+
+        /**
+         * Reports functions which match the following condition:
+         *
+         * - has a loop node in ancestors.
+         * - has any references which refers to an unsafe variable.
+         *
+         * @param {ASTNode} node The AST node to check.
+         * @returns {boolean} Whether or not the node is within a loop.
+         */
+        function checkForLoops(node) {
+            const loopNode = getContainingLoopNode(node);
+
+            if (!loopNode) {
+                return;
+            }
+
+            const references = context.getScope().through;
+            const unsafeRefs = references.filter(r => !isSafe(loopNode, r)).map(r => r.identifier.name);
+
+            if (unsafeRefs.length > 0) {
+                context.report({
+                    node,
+                    messageId: "unsafeRefs",
+                    data: { varNames: `'${unsafeRefs.join("', '")}'` }
+                });
+            }
+        }
+
+        return {
+            ArrowFunctionExpression: checkForLoops,
+            FunctionExpression: checkForLoops,
+            FunctionDeclaration: checkForLoops
+        };
+    }
+};