Merge pull request babel/eslint-plugin-babel#123 from daltones/master
Deprecate rule `no-await-in-loop`
This commit is contained in:
parent
c548da9d36
commit
399c182ab5
@ -30,8 +30,6 @@ original ones as well!).
|
|||||||
"rules": {
|
"rules": {
|
||||||
"babel/new-cap": 1,
|
"babel/new-cap": 1,
|
||||||
"babel/object-curly-spacing": 1,
|
"babel/object-curly-spacing": 1,
|
||||||
"babel/no-await-in-loop": 1,
|
|
||||||
"babel/flow-object-type": 1,
|
|
||||||
"babel/no-invalid-this": 1,
|
"babel/no-invalid-this": 1,
|
||||||
"babel/semi": 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.
|
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/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/no-invalid-this`: doesn't fail when inside class properties (`class A { a = this.b; }`)
|
||||||
- `babel/semi`: Includes class properties (🛠 )
|
- `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
|
|
||||||
|
|
||||||
#### Deprecated
|
#### 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/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/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/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).
|
||||||
|
|||||||
@ -1,68 +1,24 @@
|
|||||||
/**
|
|
||||||
* @fileoverview Rule to disallow uses of await inside of loops.
|
|
||||||
* @author Nat Mote
|
|
||||||
*/
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// Node types which are considered loops.
|
var isWarnedForDeprecation = false;
|
||||||
var loopTypes = {
|
module.exports = {
|
||||||
'ForStatement': true,
|
meta: {
|
||||||
'ForOfStatement': true,
|
deprecated: true,
|
||||||
'ForInStatement': true,
|
schema: []
|
||||||
'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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@ -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),
|
|
||||||
});
|
|
||||||
Loading…
x
Reference in New Issue
Block a user