UNPKG

3.12 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("./utils/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 type: "suggestion",
35
36 docs: {
37 description: "disallow async functions which have no `await` expression",
38 category: "Best Practices",
39 recommended: false,
40 url: "https://eslint.org/docs/rules/require-await"
41 },
42
43 schema: []
44 },
45
46 create(context) {
47 const sourceCode = context.getSourceCode();
48 let scopeInfo = null;
49
50 /**
51 * Push the scope info object to the stack.
52 *
53 * @returns {void}
54 */
55 function enterFunction() {
56 scopeInfo = {
57 upper: scopeInfo,
58 hasAwait: false
59 };
60 }
61
62 /**
63 * Pop the top scope info object from the stack.
64 * Also, it reports the function if needed.
65 *
66 * @param {ASTNode} node - The node to report.
67 * @returns {void}
68 */
69 function exitFunction(node) {
70 if (node.async && !scopeInfo.hasAwait && !astUtils.isEmptyFunction(node)) {
71 context.report({
72 node,
73 loc: astUtils.getFunctionHeadLoc(node, sourceCode),
74 message: "{{name}} has no 'await' expression.",
75 data: {
76 name: capitalizeFirstLetter(
77 astUtils.getFunctionNameWithKind(node)
78 )
79 }
80 });
81 }
82
83 scopeInfo = scopeInfo.upper;
84 }
85
86 return {
87 FunctionDeclaration: enterFunction,
88 FunctionExpression: enterFunction,
89 ArrowFunctionExpression: enterFunction,
90 "FunctionDeclaration:exit": exitFunction,
91 "FunctionExpression:exit": exitFunction,
92 "ArrowFunctionExpression:exit": exitFunction,
93
94 AwaitExpression() {
95 scopeInfo.hasAwait = true;
96 },
97 ForOfStatement(node) {
98 if (node.await) {
99 scopeInfo.hasAwait = true;
100 }
101 }
102 };
103 }
104};