Skip to content

Commit 4ed2adf

Browse files
authored
Improve consistent-function-scoping message (#773)
1 parent 2d54895 commit 4ed2adf

File tree

3 files changed

+64
-45
lines changed

3 files changed

+64
-45
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"clean-regexp": "^1.0.0",
3838
"eslint-ast-utils": "^1.1.0",
3939
"eslint-template-visitor": "^2.0.0",
40-
"eslint-utils": "^2.0.0",
40+
"eslint-utils": "^2.1.0",
4141
"import-modules": "^2.0.0",
4242
"lodash": "^4.17.15",
4343
"pluralize": "^8.0.0",

rules/consistent-function-scoping.js

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
'use strict';
2+
const {getFunctionNameWithKind} = require('eslint-utils');
23
const getDocumentationUrl = require('./utils/get-documentation-url');
34
const getReferences = require('./utils/get-references');
45

5-
const MESSAGE_ID_NAMED = 'named';
6-
const MESSAGE_ID_ANONYMOUS = 'anonymous';
6+
const MESSAGE_ID = 'consistent-function-scoping';
77

88
const isSameScope = (scope1, scope2) =>
99
scope1 && scope2 && (scope1 === scope2 || scope1.block === scope2.block);
@@ -163,25 +163,11 @@ const create = context => {
163163
},
164164
':matches(ArrowFunctionExpression, FunctionDeclaration):exit': node => {
165165
if (!hasJsx && !checkNode(node, scopeManager)) {
166-
const functionType = node.type === 'ArrowFunctionExpression' ? 'arrow function' : 'function';
167-
let functionName = '';
168-
if (node.id) {
169-
functionName = node.id.name;
170-
} else if (
171-
node.parent &&
172-
node.parent.type === 'VariableDeclarator' &&
173-
node.parent.id &&
174-
node.parent.id.type === 'Identifier'
175-
) {
176-
functionName = node.parent.id.name;
177-
}
178-
179166
context.report({
180167
node,
181-
messageId: functionName ? MESSAGE_ID_NAMED : MESSAGE_ID_ANONYMOUS,
168+
messageId: MESSAGE_ID,
182169
data: {
183-
functionType,
184-
functionName
170+
functionNameWithKind: getFunctionNameWithKind(node)
185171
}
186172
});
187173
}
@@ -202,8 +188,7 @@ module.exports = {
202188
url: getDocumentationUrl(__filename)
203189
},
204190
messages: {
205-
[MESSAGE_ID_NAMED]: 'Move {{functionType}} `{{functionName}}` to the outer scope.',
206-
[MESSAGE_ID_ANONYMOUS]: 'Move {{functionType}} to the outer scope.'
191+
[MESSAGE_ID]: 'Move {{functionNameWithKind}} to the outer scope.'
207192
}
208193
}
209194
};

test/consistent-function-scoping.js

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,12 @@ const typescriptRuleTester = avaRuleTester(test, {
1717
parser: require.resolve('@typescript-eslint/parser')
1818
});
1919

20-
const MESSAGE_ID_NAMED = 'named';
21-
const MESSAGE_ID_ANONYMOUS = 'anonymous';
20+
const MESSAGE_ID = 'consistent-function-scoping';
2221

23-
const createError = ({name, arrow}) => ({
24-
messageId: name ? MESSAGE_ID_NAMED : MESSAGE_ID_ANONYMOUS,
22+
const createError = functionNameWithKind => ({
23+
messageId: MESSAGE_ID,
2524
data: {
26-
functionType: arrow ? 'arrow function' : 'function',
27-
functionName: name
25+
functionNameWithKind
2826
}
2927
});
3028

@@ -332,7 +330,7 @@ ruleTester.run('consistent-function-scoping', rule, {
332330
return foo;
333331
}
334332
`,
335-
errors: [createError({name: 'doBar'})]
333+
errors: [createError('function \'doBar\'')]
336334
},
337335
{
338336
code: outdent`
@@ -344,7 +342,7 @@ ruleTester.run('consistent-function-scoping', rule, {
344342
return foo;
345343
}
346344
`,
347-
errors: [createError({name: 'doBar'})]
345+
errors: [createError('function \'doBar\'')]
348346
},
349347
{
350348
code: outdent`
@@ -354,7 +352,7 @@ ruleTester.run('consistent-function-scoping', rule, {
354352
}
355353
}
356354
`,
357-
errors: [createError({name: 'doBar'})]
355+
errors: [createError('function \'doBar\'')]
358356
},
359357
{
360358
code: outdent`
@@ -364,13 +362,13 @@ ruleTester.run('consistent-function-scoping', rule, {
364362
}
365363
}
366364
`,
367-
errors: [createError({name: 'doBar', arrow: true})]
365+
errors: [createError('arrow function \'doBar\'')]
368366
},
369367
{
370368
code: outdent`
371369
const doFoo = () => bar => bar;
372370
`,
373-
errors: [createError({arrow: true})]
371+
errors: [createError('arrow function')]
374372
},
375373
// `this`
376374
{
@@ -382,7 +380,7 @@ ruleTester.run('consistent-function-scoping', rule, {
382380
return doBar();
383381
};
384382
`,
385-
errors: [createError({name: 'doBar'})]
383+
errors: [createError('function \'doBar\'')]
386384
},
387385
{
388386
code: outdent`
@@ -391,7 +389,7 @@ ruleTester.run('consistent-function-scoping', rule, {
391389
return doBar();
392390
};
393391
`,
394-
errors: [createError({name: 'doBar', arrow: true})]
392+
errors: [createError('arrow function \'doBar\'')]
395393
},
396394
{
397395
code: outdent`
@@ -400,7 +398,7 @@ ruleTester.run('consistent-function-scoping', rule, {
400398
return doBar();
401399
};
402400
`,
403-
errors: [createError({name: 'doBar', arrow: true})]
401+
errors: [createError('arrow function \'doBar\'')]
404402
},
405403
// `arguments`
406404
{
@@ -412,7 +410,7 @@ ruleTester.run('consistent-function-scoping', rule, {
412410
return doBar();
413411
};
414412
`,
415-
errors: [createError({name: 'doBar'})]
413+
errors: [createError('function \'doBar\'')]
416414
},
417415
{
418416
code: outdent`
@@ -421,7 +419,7 @@ ruleTester.run('consistent-function-scoping', rule, {
421419
return doBar();
422420
};
423421
`,
424-
errors: [createError({name: 'doBar', arrow: true})]
422+
errors: [createError('arrow function \'doBar\'')]
425423
},
426424
{
427425
code: outdent`
@@ -432,7 +430,7 @@ ruleTester.run('consistent-function-scoping', rule, {
432430
return foo;
433431
}
434432
`,
435-
errors: [createError({name: 'doBar'})]
433+
errors: [createError('function \'doBar\'')]
436434
},
437435
{
438436
code: outdent`
@@ -443,15 +441,15 @@ ruleTester.run('consistent-function-scoping', rule, {
443441
return doBar;
444442
}
445443
`,
446-
errors: [createError({name: 'doBar'})]
444+
errors: [createError('function \'doBar\'')]
447445
},
448446
{
449447
code: outdent`
450448
function doFoo() {
451449
function doBar() {}
452450
}
453451
`,
454-
errors: [createError({name: 'doBar'})]
452+
errors: [createError('function \'doBar\'')]
455453
},
456454
{
457455
code: outdent`
@@ -466,7 +464,7 @@ ruleTester.run('consistent-function-scoping', rule, {
466464
return foo;
467465
}
468466
`,
469-
errors: [createError({name: 'doBar'})]
467+
errors: [createError('function \'doBar\'')]
470468
},
471469
{
472470
code: outdent`
@@ -478,7 +476,7 @@ ruleTester.run('consistent-function-scoping', rule, {
478476
}
479477
}
480478
`,
481-
errors: [createError({name: 'doBar'})]
479+
errors: [createError('function \'doBar\'')]
482480
},
483481
{
484482
code: outdent`
@@ -488,7 +486,43 @@ ruleTester.run('consistent-function-scoping', rule, {
488486
}
489487
}
490488
`,
491-
errors: [createError({name: 'doBar'})]
489+
errors: [createError('function \'doBar\'')]
490+
},
491+
// Function kinds and names
492+
{
493+
code: 'function foo() { function bar() {} }',
494+
errors: [createError('function \'bar\'')]
495+
},
496+
{
497+
code: 'function foo() { async function bar() {} }',
498+
errors: [createError('async function \'bar\'')]
499+
},
500+
{
501+
code: 'function foo() { function* bar() {} }',
502+
errors: [createError('generator function \'bar\'')]
503+
},
504+
{
505+
code: 'function foo() { async function* bar() {} }',
506+
errors: [createError('async generator function \'bar\'')]
507+
},
508+
{
509+
code: 'function foo() { const bar = () => {} }',
510+
errors: [createError('arrow function \'bar\'')]
511+
},
512+
{
513+
code: 'const doFoo = () => bar => bar;',
514+
errors: [createError('arrow function')]
515+
},
516+
{
517+
code: 'function foo() { const bar = async () => {} }',
518+
errors: [createError('async arrow function \'bar\'')]
519+
},
520+
// Actual message
521+
{
522+
code: 'function foo() { async function* bar() {} }',
523+
errors: [{
524+
message: 'Move async generator function \'bar\' to the outer scope.'
525+
}]
492526
},
493527
// React Hooks
494528
{
@@ -500,7 +534,7 @@ ruleTester.run('consistent-function-scoping', rule, {
500534
}
501535
}, [])
502536
`,
503-
errors: [createError({name: 'bar'})]
537+
errors: [createError('function \'bar\'')]
504538
},
505539
// IIFE
506540
{
@@ -512,7 +546,7 @@ ruleTester.run('consistent-function-scoping', rule, {
512546
}
513547
})();
514548
`,
515-
errors: [createError({name: 'bar'})]
549+
errors: [createError('function \'bar\'')]
516550
}
517551
]
518552
});

0 commit comments

Comments
 (0)