diff --git a/eslint/babel-eslint-plugin/README.md b/eslint/babel-eslint-plugin/README.md index 9444f93f9c..82a80d5d42 100644 --- a/eslint/babel-eslint-plugin/README.md +++ b/eslint/babel-eslint-plugin/README.md @@ -30,8 +30,6 @@ original ones as well!). "rules": { "babel/new-cap": 1, "babel/object-curly-spacing": 1, - "babel/no-await-in-loop": 1, - "babel/flow-object-type": 1, "babel/no-invalid-this": 1, "babel/semi": 1 } @@ -41,17 +39,12 @@ original ones as well!). Each rule corresponds to a core `eslint` rule, and has the same options. -🛠 : means it's autofixable with `--fix`. +🛠: means it's autofixable with `--fix`. - `babel/new-cap`: Ignores capitalized decorators (`@Decorator`) -- `babel/object-curly-spacing`: doesn't complain about `export x from "mod";` or `export * as x from "mod";` (🛠 ) +- `babel/object-curly-spacing`: doesn't complain about `export x from "mod";` or `export * as x from "mod";` (🛠) - `babel/no-invalid-this`: doesn't fail when inside class properties (`class A { a = this.b; }`) -- `babel/semi`: Includes class properties (🛠 ) - -The following rules are not in `eslint`, but are relevant only to syntax that is not specified by -the current JavaScript standard or supported by `eslint`. - -- `babel/no-await-in-loop`: guard against awaiting async functions inside of a loop +- `babel/semi`: Includes class properties (🛠) #### Deprecated @@ -61,3 +54,4 @@ the current JavaScript standard or supported by `eslint`. - `babel/func-params-comma-dangle`: Use [`comma-dangle`](http://eslint.org/docs/rules/comma-dangle). - `babel/array-bracket-spacing`: Use [`array-bracket-spacing`](http://eslint.org/docs/rules/array-bracket-spacing). - `babel/flow-object-type`: Use [`flowtype/object-type-delimiter`](https://github.com/gajus/eslint-plugin-flowtype#eslint-plugin-flowtype-rules-object-type-delimiter). +- `babel/no-await-in-loop`: Use [`no-await-in-loop`](http://eslint.org/docs/rules/no-await-in-loop). diff --git a/eslint/babel-eslint-plugin/rules/no-await-in-loop.js b/eslint/babel-eslint-plugin/rules/no-await-in-loop.js index 037f29be74..8ef295f36f 100644 --- a/eslint/babel-eslint-plugin/rules/no-await-in-loop.js +++ b/eslint/babel-eslint-plugin/rules/no-await-in-loop.js @@ -1,68 +1,24 @@ -/** - * @fileoverview Rule to disallow uses of await inside of loops. - * @author Nat Mote - */ "use strict"; -// Node types which are considered loops. -var loopTypes = { - 'ForStatement': true, - 'ForOfStatement': true, - 'ForInStatement': true, - 'WhileStatement': true, - 'DoWhileStatement': true, -}; - -// Node types at which we should stop looking for loops. For example, it is fine to declare an async -// function within a loop, and use await inside of that. -var boundaryTypes = { - 'FunctionDeclaration': true, - 'FunctionExpression': true, - 'ArrowFunctionExpression': true, -}; - -module.exports = function(context) { - return { - AwaitExpression(node) { - var ancestors = context.getAncestors(); - // Reverse so that we can traverse from the deepest node upwards. - ancestors.reverse(); - // Create a set of all the ancestors plus this node so that we can check - // if this use of await appears in the body of the loop as opposed to - // the right-hand side of a for...of, for example. - // - // Implement the set with an Array since there are likely to be very few - // elements. An Object would not be appropriate since the elements are - // not strings. - var ancestorSet = [].concat(ancestors, [node]); - var ancestorSetHas = function(element) { - return ancestorSet.indexOf(element) !== -1; - } - for (var i = 0; i < ancestors.length; i++) { - var ancestor = ancestors[i]; - if (boundaryTypes.hasOwnProperty(ancestor.type)) { - // Short-circuit out if we encounter a boundary type. Loops above - // this do not matter. - return; - } - if (loopTypes.hasOwnProperty(ancestor.type)) { - // Only report if we are actually in the body or another part that gets executed on - // every iteration. - if ( - ancestorSetHas(ancestor.body) || - ancestorSetHas(ancestor.test) || - ancestorSetHas(ancestor.update) - ) { - context.report( - node, - 'Avoid using await inside a loop. Consider refactoring to use Promise.all. If ' + - 'you are sure you want to do this, add `// eslint-disable-line ' + - context.id + '` at the end of this line.' - ); - return; - } - } - } +var isWarnedForDeprecation = false; +module.exports = { + meta: { + deprecated: true, + schema: [] }, - }; -} + create: function() { + return { + Program: function() { + if (isWarnedForDeprecation || /\=-(f|-format)=/.test(process.argv.join('='))) { + return; + } + + /* eslint-disable no-console */ + console.log('The babel/no-await-in-loop rule is deprecated. Please ' + + 'use the built in no-await-in-loop rule instead.'); + /* eslint-enable no-console */ + isWarnedForDeprecation = true; + } + }; + } +}; diff --git a/eslint/babel-eslint-plugin/tests/rules/no-await-in-loop.js b/eslint/babel-eslint-plugin/tests/rules/no-await-in-loop.js deleted file mode 100644 index 97de50fdd9..0000000000 --- a/eslint/babel-eslint-plugin/tests/rules/no-await-in-loop.js +++ /dev/null @@ -1,106 +0,0 @@ -/** - * @fileoverview Tests for no-await-in-loop. - * @author Nat Mote - */ - -"use strict"; - -var rule = require("../../rules/no-await-in-loop"), - RuleTester = require('../RuleTester'); - -var features = { -}; - -function test(code, errors){ - var result = { - code: code, - parser: 'babel-eslint', - ecmaFeatures: features, - }; - if (errors != null) { - result.errors = errors; - } - return result; -} - -var ruleName = 'babel/no-await-in-loop'; - -var message = 'Avoid using await inside a loop. Consider refactoring to use Promise.all. If ' + - 'you are sure you want to do this, add `// eslint-disable-line ' + - ruleName + '` at the end of this line.' - -function ok(code) { - return test(code); -} - -function err(code) { - return test(code, [message]); -} - -// Construct an async function with the given body -function fun(body) { - return "async function foo() { " + body + " }"; -} - -// Construct a loop -function loop(kind, condition, body) { - return kind + " (" + condition + ") { " + body + " }"; -} - -// Construct a class with the given body -function cls(body) { - return "class Foo { " + body + " }"; -} - -var cases = [ - ok(fun("await bar;")), - - // While loops - ok(fun(loop("while", "true", fun("await bar;")))), // Blocked by a function declaration - err(fun(loop("while", "baz", "await bar;"))), - err(fun(loop("while", "await foo()", ""))), - - // For of loops - err(fun(loop("for", "var bar of baz", "await bar;"))), - - // For in loops - err(fun(loop("for", "var bar in baz", "await bar;"))), - - // For loops - ok(fun(loop("for", "var i = await bar; i < n; i++", ""))), - err(fun(loop("for", "var i; i < n; i++", "await bar;"))), - err(fun(loop("for", "var i; await foo(i); i++", ""))), - err(fun(loop("for", "var i; i < n; i = await bar", ""))), - - // Do while loops - ok(fun("do { } while (bar);")), - err(fun("do { await bar; } while (baz);")), - err(fun("do { } while (await bar);")), - - // Blocked by a function expression - ok(fun(loop("while", "true", "var y = async function() { await bar; }"))), - // Blocked by an arrow function - ok(fun(loop("while", "true", "var y = async () => await foo;"))), - ok(fun(loop("while", "true", "var y = async () => { await foo; }"))), - // Blocked by a class method, - ok(fun(loop("while", "true", cls("async foo() { await bar; }")))), - - // Deep in a loop body - err(fun(loop("while", "true", "if (bar) { foo(await bar); }"))), - // Deep in a loop condition - err(fun(loop("while", "xyz || 5 > await x", ""))), -]; - -function hasError(testCase) { - return testCase.errors != null && testCase.errors.length > 0; -} - -function hasNoError(testCase) { - return !hasError(testCase); -} - -var ruleTester = new RuleTester(); -ruleTester.run(ruleName, rule, { - valid: cases.filter(hasNoError), - invalid: cases.filter(hasError), -});