UNPKG

3.08 kBJavaScriptView Raw
1/**
2 * @fileoverview Rule to disallow async functions which have no `await` expression.
3 * @author Toru Nagashima
4 */
5
6"use strict";
7
8//------------------------------------------------------------------------------
9// Requirements
10//------------------------------------------------------------------------------
11
12const astUtils = require("../ast-utils");
13
14//------------------------------------------------------------------------------
15// Helpers
16//------------------------------------------------------------------------------
17
18/**
19 * Capitalize the 1st letter of the given text.
20 *
21 * @param {string} text - The text to capitalize.
22 * @returns {string} The text that the 1st letter was capitalized.
23 */
24function capitalizeFirstLetter(text) {
25 return text[0].toUpperCase() + text.slice(1);
26}
27
28//------------------------------------------------------------------------------
29// Rule Definition
30//------------------------------------------------------------------------------
31
32module.exports = {
33 meta: {
34 docs: {
35 description: "disallow async functions which have no `await` expression",
36 category: "Best Practices",
37 recommended: false,
38 url: "https://eslint.org/docs/rules/require-await"
39 },
40 schema: []
41 },
42
43 create(context) {
44 const sourceCode = context.getSourceCode();
45 let scopeInfo = null;
46
47 /**
48 * Push the scope info object to the stack.
49 *
50 * @returns {void}
51 */
52 function enterFunction() {
53 scopeInfo = {
54 upper: scopeInfo,
55 hasAwait: false
56 };
57 }
58
59 /**
60 * Pop the top scope info object from the stack.
61 * Also, it reports the function if needed.
62 *
63 * @param {ASTNode} node - The node to report.
64 * @returns {void}
65 */
66 function exitFunction(node) {
67 if (node.async && !scopeInfo.hasAwait && !astUtils.isEmptyFunction(node)) {
68 context.report({
69 node,
70 loc: astUtils.getFunctionHeadLoc(node, sourceCode),
71 message: "{{name}} has no 'await' expression.",
72 data: {
73 name: capitalizeFirstLetter(
74 astUtils.getFunctionNameWithKind(node)
75 )
76 }
77 });
78 }
79
80 scopeInfo = scopeInfo.upper;
81 }
82
83 return {
84 FunctionDeclaration: enterFunction,
85 FunctionExpression: enterFunction,
86 ArrowFunctionExpression: enterFunction,
87 "FunctionDeclaration:exit": exitFunction,
88 "FunctionExpression:exit": exitFunction,
89 "ArrowFunctionExpression:exit": exitFunction,
90
91 AwaitExpression() {
92 scopeInfo.hasAwait = true;
93 },
94 ForOfStatement(node) {
95 if (node.await) {
96 scopeInfo.hasAwait = true;
97 }
98 }
99 };
100 }
101};