1 | 'use strict';
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | const last = require('ramda/src/last');
|
9 | const astUtils = require('../util/ast');
|
10 |
|
11 | module.exports = function (context) {
|
12 | const sourceCode = context.getSourceCode();
|
13 |
|
14 | function formatFunctionHead(fn) {
|
15 | const paramsLeftParen = sourceCode.getFirstToken(fn);
|
16 | const paramsRightParen = sourceCode.getTokenBefore(sourceCode.getTokenBefore(fn.body));
|
17 | let paramsFullText = sourceCode.text.slice(paramsLeftParen.range[0], paramsRightParen.range[1]);
|
18 | let functionKeyword = 'function';
|
19 |
|
20 | if (fn.async) {
|
21 |
|
22 | functionKeyword = 'async function';
|
23 |
|
24 | paramsFullText = paramsFullText.slice(5);
|
25 | }
|
26 |
|
27 | if (fn.params.length > 0) {
|
28 | paramsFullText = `(${ sourceCode.text.slice(fn.params[0].start, last(fn.params).end) })`;
|
29 | }
|
30 |
|
31 | return `${functionKeyword}${paramsFullText} `;
|
32 | }
|
33 |
|
34 | function fixArrowFunction(fixer, fn) {
|
35 | if (fn.body.type === 'BlockStatement') {
|
36 |
|
37 |
|
38 | return fixer.replaceTextRange(
|
39 | [ fn.start, fn.body.start ],
|
40 | formatFunctionHead(fn)
|
41 | );
|
42 | }
|
43 |
|
44 | const bodyText = sourceCode.text.slice(fn.body.range[0], fn.body.range[1]);
|
45 | return fixer.replaceTextRange(
|
46 | [ fn.start, fn.end ],
|
47 | `${formatFunctionHead(fn)}{ return ${ bodyText }; }`
|
48 | );
|
49 | }
|
50 |
|
51 | return {
|
52 | CallExpression(node) {
|
53 | const name = astUtils.getNodeName(node.callee);
|
54 |
|
55 | if (astUtils.isMochaFunctionCall(node, context.getScope())) {
|
56 | const fnArg = node.arguments.slice(-1)[0];
|
57 | if (fnArg && fnArg.type === 'ArrowFunctionExpression') {
|
58 | context.report({
|
59 | node,
|
60 | message: `Do not pass arrow functions to ${ name }()`,
|
61 | fix(fixer) {
|
62 | return fixArrowFunction(fixer, fnArg);
|
63 | }
|
64 | });
|
65 | }
|
66 | }
|
67 | }
|
68 | };
|
69 | };
|