Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Improve consistent-function-scoping message (#773)
  • Loading branch information
fisker committed Jun 20, 2020
1 parent 2d54895 commit 4ed2adf
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 45 deletions.
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -37,7 +37,7 @@
"clean-regexp": "^1.0.0",
"eslint-ast-utils": "^1.1.0",
"eslint-template-visitor": "^2.0.0",
"eslint-utils": "^2.0.0",
"eslint-utils": "^2.1.0",
"import-modules": "^2.0.0",
"lodash": "^4.17.15",
"pluralize": "^8.0.0",
Expand Down
25 changes: 5 additions & 20 deletions rules/consistent-function-scoping.js
@@ -1,9 +1,9 @@
'use strict';
const {getFunctionNameWithKind} = require('eslint-utils');
const getDocumentationUrl = require('./utils/get-documentation-url');
const getReferences = require('./utils/get-references');

const MESSAGE_ID_NAMED = 'named';
const MESSAGE_ID_ANONYMOUS = 'anonymous';
const MESSAGE_ID = 'consistent-function-scoping';

const isSameScope = (scope1, scope2) =>
scope1 && scope2 && (scope1 === scope2 || scope1.block === scope2.block);
Expand Down Expand Up @@ -163,25 +163,11 @@ const create = context => {
},
':matches(ArrowFunctionExpression, FunctionDeclaration):exit': node => {
if (!hasJsx && !checkNode(node, scopeManager)) {
const functionType = node.type === 'ArrowFunctionExpression' ? 'arrow function' : 'function';
let functionName = '';
if (node.id) {
functionName = node.id.name;
} else if (
node.parent &&
node.parent.type === 'VariableDeclarator' &&
node.parent.id &&
node.parent.id.type === 'Identifier'
) {
functionName = node.parent.id.name;
}

context.report({
node,
messageId: functionName ? MESSAGE_ID_NAMED : MESSAGE_ID_ANONYMOUS,
messageId: MESSAGE_ID,
data: {
functionType,
functionName
functionNameWithKind: getFunctionNameWithKind(node)
}
});
}
Expand All @@ -202,8 +188,7 @@ module.exports = {
url: getDocumentationUrl(__filename)
},
messages: {
[MESSAGE_ID_NAMED]: 'Move {{functionType}} `{{functionName}}` to the outer scope.',
[MESSAGE_ID_ANONYMOUS]: 'Move {{functionType}} to the outer scope.'
[MESSAGE_ID]: 'Move {{functionNameWithKind}} to the outer scope.'
}
}
};
82 changes: 58 additions & 24 deletions test/consistent-function-scoping.js
Expand Up @@ -17,14 +17,12 @@ const typescriptRuleTester = avaRuleTester(test, {
parser: require.resolve('@typescript-eslint/parser')
});

const MESSAGE_ID_NAMED = 'named';
const MESSAGE_ID_ANONYMOUS = 'anonymous';
const MESSAGE_ID = 'consistent-function-scoping';

const createError = ({name, arrow}) => ({
messageId: name ? MESSAGE_ID_NAMED : MESSAGE_ID_ANONYMOUS,
const createError = functionNameWithKind => ({
messageId: MESSAGE_ID,
data: {
functionType: arrow ? 'arrow function' : 'function',
functionName: name
functionNameWithKind
}
});

Expand Down Expand Up @@ -332,7 +330,7 @@ ruleTester.run('consistent-function-scoping', rule, {
return foo;
}
`,
errors: [createError({name: 'doBar'})]
errors: [createError('function \'doBar\'')]
},
{
code: outdent`
Expand All @@ -344,7 +342,7 @@ ruleTester.run('consistent-function-scoping', rule, {
return foo;
}
`,
errors: [createError({name: 'doBar'})]
errors: [createError('function \'doBar\'')]
},
{
code: outdent`
Expand All @@ -354,7 +352,7 @@ ruleTester.run('consistent-function-scoping', rule, {
}
}
`,
errors: [createError({name: 'doBar'})]
errors: [createError('function \'doBar\'')]
},
{
code: outdent`
Expand All @@ -364,13 +362,13 @@ ruleTester.run('consistent-function-scoping', rule, {
}
}
`,
errors: [createError({name: 'doBar', arrow: true})]
errors: [createError('arrow function \'doBar\'')]
},
{
code: outdent`
const doFoo = () => bar => bar;
`,
errors: [createError({arrow: true})]
errors: [createError('arrow function')]
},
// `this`
{
Expand All @@ -382,7 +380,7 @@ ruleTester.run('consistent-function-scoping', rule, {
return doBar();
};
`,
errors: [createError({name: 'doBar'})]
errors: [createError('function \'doBar\'')]
},
{
code: outdent`
Expand All @@ -391,7 +389,7 @@ ruleTester.run('consistent-function-scoping', rule, {
return doBar();
};
`,
errors: [createError({name: 'doBar', arrow: true})]
errors: [createError('arrow function \'doBar\'')]
},
{
code: outdent`
Expand All @@ -400,7 +398,7 @@ ruleTester.run('consistent-function-scoping', rule, {
return doBar();
};
`,
errors: [createError({name: 'doBar', arrow: true})]
errors: [createError('arrow function \'doBar\'')]
},
// `arguments`
{
Expand All @@ -412,7 +410,7 @@ ruleTester.run('consistent-function-scoping', rule, {
return doBar();
};
`,
errors: [createError({name: 'doBar'})]
errors: [createError('function \'doBar\'')]
},
{
code: outdent`
Expand All @@ -421,7 +419,7 @@ ruleTester.run('consistent-function-scoping', rule, {
return doBar();
};
`,
errors: [createError({name: 'doBar', arrow: true})]
errors: [createError('arrow function \'doBar\'')]
},
{
code: outdent`
Expand All @@ -432,7 +430,7 @@ ruleTester.run('consistent-function-scoping', rule, {
return foo;
}
`,
errors: [createError({name: 'doBar'})]
errors: [createError('function \'doBar\'')]
},
{
code: outdent`
Expand All @@ -443,15 +441,15 @@ ruleTester.run('consistent-function-scoping', rule, {
return doBar;
}
`,
errors: [createError({name: 'doBar'})]
errors: [createError('function \'doBar\'')]
},
{
code: outdent`
function doFoo() {
function doBar() {}
}
`,
errors: [createError({name: 'doBar'})]
errors: [createError('function \'doBar\'')]
},
{
code: outdent`
Expand All @@ -466,7 +464,7 @@ ruleTester.run('consistent-function-scoping', rule, {
return foo;
}
`,
errors: [createError({name: 'doBar'})]
errors: [createError('function \'doBar\'')]
},
{
code: outdent`
Expand All @@ -478,7 +476,7 @@ ruleTester.run('consistent-function-scoping', rule, {
}
}
`,
errors: [createError({name: 'doBar'})]
errors: [createError('function \'doBar\'')]
},
{
code: outdent`
Expand All @@ -488,7 +486,43 @@ ruleTester.run('consistent-function-scoping', rule, {
}
}
`,
errors: [createError({name: 'doBar'})]
errors: [createError('function \'doBar\'')]
},
// Function kinds and names
{
code: 'function foo() { function bar() {} }',
errors: [createError('function \'bar\'')]
},
{
code: 'function foo() { async function bar() {} }',
errors: [createError('async function \'bar\'')]
},
{
code: 'function foo() { function* bar() {} }',
errors: [createError('generator function \'bar\'')]
},
{
code: 'function foo() { async function* bar() {} }',
errors: [createError('async generator function \'bar\'')]
},
{
code: 'function foo() { const bar = () => {} }',
errors: [createError('arrow function \'bar\'')]
},
{
code: 'const doFoo = () => bar => bar;',
errors: [createError('arrow function')]
},
{
code: 'function foo() { const bar = async () => {} }',
errors: [createError('async arrow function \'bar\'')]
},
// Actual message
{
code: 'function foo() { async function* bar() {} }',
errors: [{
message: 'Move async generator function \'bar\' to the outer scope.'
}]
},
// React Hooks
{
Expand All @@ -500,7 +534,7 @@ ruleTester.run('consistent-function-scoping', rule, {
}
}, [])
`,
errors: [createError({name: 'bar'})]
errors: [createError('function \'bar\'')]
},
// IIFE
{
Expand All @@ -512,7 +546,7 @@ ruleTester.run('consistent-function-scoping', rule, {
}
})();
`,
errors: [createError({name: 'bar'})]
errors: [createError('function \'bar\'')]
}
]
});
Expand Down

0 comments on commit 4ed2adf

Please sign in to comment.