diff --git a/lib/no-loops.js b/lib/no-loops.js index 5f53f6a..a110347 100644 --- a/lib/no-loops.js +++ b/lib/no-loops.js @@ -5,11 +5,33 @@ module.exports = function (context) { context.report(node, 'loops are not allowed', { identifier: node.name }); } + var loopsContainAwait = [] + + function enterLoop() { + loopsContainAwait.unshift(false) + } + + function exitLoop(node) { + if (!loopsContainAwait.shift()) reportLoopPresence(node) + } + + function foundAwait() { + for (var i = 0; i < loopsContainAwait.length; i++) { + loopsContainAwait[i] = true + } + } + return { - ForStatement: reportLoopPresence, - ForInStatement: reportLoopPresence, - WhileStatement: reportLoopPresence, - DoWhileStatement: reportLoopPresence, - ForOfStatement: reportLoopPresence + ForStatement: enterLoop, + 'ForStatement:exit': exitLoop, + ForInStatement: enterLoop, + 'ForInStatement:exit': exitLoop, + WhileStatement: enterLoop, + 'WhileStatement:exit': exitLoop, + DoWhileStatement: enterLoop, + 'DoWhileStatement:exit': exitLoop, + ForOfStatement: enterLoop, + 'ForOfStatement:exit': exitLoop, + AwaitExpression: foundAwait }; }; diff --git a/package.json b/package.json index 3b84a0f..4d4dd37 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,8 @@ }, "homepage": "https://github.com/buildo/eslint-plugin-no-loops#readme", "devDependencies": { - "babel-eslint": "^6.1.0", - "eslint": "^2.0.0" + "babel-eslint": "8", + "eslint": "5" }, "peerDependencies": { "eslint": ">=2.0.0" diff --git a/tests/index.js b/tests/index.js index 78f788c..76690a1 100644 --- a/tests/index.js +++ b/tests/index.js @@ -3,11 +3,29 @@ var rule = require('../lib/no-loops.js'); var RuleTester = require('eslint').RuleTester; -var ruleTester = new RuleTester(); +var ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018 } }); ruleTester.run('no-loops', rule, { valid: [ { code: '[1, 2, 3].map(function (i) { console.log(i); });' + }, + { + code: 'async function ok() { for (var i = 0; i < n; i++) { await x[i]() } }' + }, + { + code: 'const ok = async () => { for (const x of y) { for (const z of y) { await z() } } }' + }, + { + code: 'async function ok() { for (const x of y) { await x() } }' + }, + { + code: 'async function ok() { while (true) { await x() } }' + }, + { + code: 'async function ok() { do { await x() } while (true) }' + }, + { + code: 'const ok = async () => { for (const x of y) { for (const z in y) { await z() } } }' } ], @@ -32,6 +50,16 @@ ruleTester.run('no-loops', rule, { code: 'for (i of [1, 2, 3]) { console.log(i) }', parser: 'babel-eslint', errors: [ { message: 'loops are not allowed' } ] + }, + { + code: 'async function bad() { while (true) { x() } }', + parser: 'babel-eslint', + errors: [ { message: 'loops are not allowed' } ] + }, + { + code: 'const ok = async () => { for (const x of y) { await x(); for (const z in y) { z() } } }', + parser: 'babel-eslint', + errors: [ { message: 'loops are not allowed' } ] } ] });