123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- 'use strict';
- const {
- addParenthesizesToReturnOrThrowExpression,
- removeSpacesAfter,
- } = require('./fix/index.js');
- const {isParenthesized} = require('./utils/parentheses.js');
- const needsSemicolon = require('./utils/needs-semicolon.js');
- const isOnSameLine = require('./utils/is-on-same-line.js');
- const MESSAGE_ID = 'no-unnecessary-await';
- const messages = {
- [MESSAGE_ID]: 'Do not `await` non-promise value.',
- };
- function notPromise(node) {
- switch (node.type) {
- case 'ArrayExpression':
- case 'ArrowFunctionExpression':
- case 'AwaitExpression':
- case 'BinaryExpression':
- case 'ClassExpression':
- case 'FunctionExpression':
- case 'JSXElement':
- case 'JSXFragment':
- case 'Literal':
- case 'TemplateLiteral':
- case 'UnaryExpression':
- case 'UpdateExpression': {
- return true;
- }
- case 'SequenceExpression': {
- return notPromise(node.expressions[node.expressions.length - 1]);
- }
- // No default
- }
- return false;
- }
- /** @param {import('eslint').Rule.RuleContext} context */
- const create = context => ({
- AwaitExpression(node) {
- if (!notPromise(node.argument)) {
- return;
- }
- const sourceCode = context.getSourceCode();
- const awaitToken = sourceCode.getFirstToken(node);
- const problem = {
- node,
- loc: awaitToken.loc,
- messageId: MESSAGE_ID,
- };
- const valueNode = node.argument;
- if (
- // Removing `await` may change them to a declaration, if there is no `id` will cause SyntaxError
- valueNode.type === 'FunctionExpression'
- || valueNode.type === 'ClassExpression'
- // `+await +1` -> `++1`
- || (
- node.parent.type === 'UnaryExpression'
- && valueNode.type === 'UnaryExpression'
- && node.parent.operator === valueNode.operator
- )
- ) {
- return problem;
- }
- return Object.assign(problem, {
- /** @param {import('eslint').Rule.RuleFixer} fixer */
- * fix(fixer) {
- if (
- !isOnSameLine(awaitToken, valueNode)
- && !isParenthesized(node, sourceCode)
- ) {
- yield * addParenthesizesToReturnOrThrowExpression(fixer, node.parent, sourceCode);
- }
- yield fixer.remove(awaitToken);
- yield removeSpacesAfter(awaitToken, sourceCode, fixer);
- const nextToken = sourceCode.getTokenAfter(awaitToken);
- const tokenBefore = sourceCode.getTokenBefore(awaitToken);
- if (needsSemicolon(tokenBefore, sourceCode, nextToken.value)) {
- yield fixer.insertTextBefore(nextToken, ';');
- }
- },
- });
- },
- });
- /** @type {import('eslint').Rule.RuleModule} */
- module.exports = {
- create,
- meta: {
- type: 'suggestion',
- docs: {
- description: 'Disallow awaiting non-promise values.',
- },
- fixable: 'code',
- messages,
- },
- };
|