forked from sindresorhus/eslint-plugin-unicorn
/
no-await-expression-member.js
87 lines (76 loc) · 2.35 KB
/
no-await-expression-member.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
'use strict';
const {
removeParentheses,
removeMemberExpressionProperty,
} = require('./fix/index.js');
const MESSAGE_ID = 'no-await-expression-member';
const messages = {
[MESSAGE_ID]: 'Do not access a member directly from an await expression.',
};
/** @param {import('eslint').Rule.RuleContext} context */
const create = context => {
const sourceCode = context.getSourceCode();
return {
'MemberExpression[object.type="AwaitExpression"]'(memberExpression) {
const {property} = memberExpression;
const problem = {
node: property,
messageId: MESSAGE_ID,
};
// `const foo = (await bar)[0]`
if (
memberExpression.computed
&& !memberExpression.optional
&& property.type === 'Literal'
&& (property.value === 0 || property.value === 1)
&& memberExpression.parent.type === 'VariableDeclarator'
&& memberExpression.parent.init === memberExpression
&& memberExpression.parent.id.type === 'Identifier'
) {
problem.fix = function * (fixer) {
const variable = memberExpression.parent.id;
yield fixer.insertTextBefore(variable, property.value === 0 ? '[' : '[, ');
yield fixer.insertTextAfter(variable, ']');
yield removeMemberExpressionProperty(fixer, memberExpression, sourceCode);
yield * removeParentheses(memberExpression.object, fixer, sourceCode);
};
return problem;
}
// `const foo = (await bar).foo`
if (
!memberExpression.computed
&& !memberExpression.optional
&& property.type === 'Identifier'
&& memberExpression.parent.type === 'VariableDeclarator'
&& memberExpression.parent.init === memberExpression
&& memberExpression.parent.id.type === 'Identifier'
&& memberExpression.parent.id.name === property.name
) {
problem.fix = function * (fixer) {
const variable = memberExpression.parent.id;
yield fixer.insertTextBefore(variable, '{');
yield fixer.insertTextAfter(variable, '}');
yield removeMemberExpressionProperty(fixer, memberExpression, sourceCode);
yield * removeParentheses(memberExpression.object, fixer, sourceCode);
};
return problem;
}
return problem;
},
};
};
/**
* @type {import('eslint').Rule.RuleModule}
*/
module.exports = {
create,
meta: {
type: 'suggestion',
docs: {
description: 'Forbid member access from await expression.',
},
fixable: 'code',
schema: [],
messages,
},
};