Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: JamieMason/eslint-plugin-prefer-arrow-functions
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 3.1.4
Choose a base ref
...
head repository: JamieMason/eslint-plugin-prefer-arrow-functions
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 3.2.4
Choose a head ref
  • 3 commits
  • 7 files changed
  • 3 contributors

Commits on Oct 23, 2023

  1. Copy the full SHA
    50fb3b6 View commit details
  2. chore(github): update funding.yml

    Closes #18
    Closes #19
    JamieMason committed Oct 23, 2023
    Copy the full SHA
    f1ee400 View commit details
  3. chore(release): 3.2.4

    JamieMason committed Oct 23, 2023
    Copy the full SHA
    9b76409 View commit details
Showing with 111 additions and 6 deletions.
  1. +1 −2 .github/FUNDING.yml
  2. +9 −0 CHANGELOG.md
  3. +5 −0 README.md
  4. +1 −1 package.json
  5. +1 −0 src/config.ts
  6. +88 −0 src/prefer-arrow-functions.spec.ts
  7. +6 −3 src/prefer-arrow-functions.ts
3 changes: 1 addition & 2 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
open_collective: fold_left
custom: ['https://www.paypal.me/foldleft']
github: JamieMason
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## [3.2.4](https://github.com/JamieMason/eslint-plugin-prefer-arrow-functions/compare/3.1.4...3.2.4) (2023-10-23)


### Features

* **config:** add support for allowNamedFunctions ([50fb3b6](https://github.com/JamieMason/eslint-plugin-prefer-arrow-functions/commit/50fb3b68d9b2eaf48617404bec8f9ed1b4e6a511))



## [3.1.4](https://github.com/JamieMason/eslint-plugin-prefer-arrow-functions/compare/3.1.3...3.1.4) (2021-11-13)


5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -34,6 +34,7 @@ Add the plugin to the `plugins` section and the rule to the `rules` section in y
"prefer-arrow-functions/prefer-arrow-functions": [
"warn",
{
"allowNamedFunctions": false,
"classPropertiesAllowed": false,
"disallowPrototype": false,
"returnStyle": "unchanged",
@@ -46,6 +47,10 @@ Add the plugin to the `plugins` section and the rule to the `rules` section in y

## 🤔 Options

### `allowNamedFunctions`

If set to true, the rule won't report named functions such as `function foo() {}`. Anonymous function such as `const foo = function() {}` will still be reported.

### `classPropertiesAllowed`

When `true`, functions defined as [class instance fields](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes#Field_declarations) will be converted to arrow functions when doing so would not alter or break their behaviour.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "eslint-plugin-prefer-arrow-functions",
"description": "Convert functions to arrow functions",
"version": "3.1.4",
"version": "3.2.4",
"author": "Jamie Mason (https://github.com/JamieMason)",
"bugs": "https://github.com/JamieMason/eslint-plugin-prefer-arrow-functions/issues",
"contributors": [
1 change: 1 addition & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const DEFAULT_OPTIONS = {
allowNamedFunctions: false,
classPropertiesAllowed: false,
disallowPrototype: false,
returnStyle: 'unchanged',
88 changes: 88 additions & 0 deletions src/prefer-arrow-functions.spec.ts
Original file line number Diff line number Diff line change
@@ -691,6 +691,81 @@ const invalidWhenReturnStyleIsExplicit = [
},
];

const validWhenAllowNamedFunctions = [
{ code: '() => { function foo() { return "bar"; } }' },
{ code: '() => { function * fooGen() { return yield "bar"; } }' },
{ code: '() => { async function foo() { return await "bar"; } }' },
{ code: '() => { function foo() { return () => "bar"; } }' },
{ code: 'class FooClass { foo() { return "bar" }}' },
{
code: 'export default () => { function foo() { return "bar"; } }',
},
{
// Make sure "allowNamedFunctions" works with typescript
code: '() => { function foo(a: string): string { return `bar ${a}`;} }',
parser: require.resolve('@typescript-eslint/parser'),
},
];

const invalidWhenAllowNamedFunctions = [
// Invalid tests for "allowNamedFunctions" option
{
code: '() => { var foo = function() { return "bar"; }; }',
output: '() => { var foo = () => "bar"; }',
},
{
code: '() => { var foo = async function() { return await "bar"; }; }',
output: '() => { var foo = async () => await "bar"; }',
},
{
code: '() => { var foo = function() { return () => "bar"; }; }',
output: '() => { var foo = () => () => "bar"; }',
},
{
code: '() => { var foo = function() { return "bar"; }; }',
output: '() => { var foo = () => "bar"; }',
},
{
code: 'module.exports = () => { var foo = function() { return "bar"; }; }',
output: 'module.exports = () => { var foo = () => "bar"; }',
},
{
code: 'module.exports.foo = () => { var bar = function() { return "baz"; }; }',
output: 'module.exports.foo = () => { var bar = () => "baz"; }',
},
{
code: '() => { exports.foo = function() { return "bar"; }; }',
output: '() => { exports.foo = () => "bar"; }',
},
{
code: 'exports = function() { return "bar"; };',
output: 'exports = () => "bar";',
},
{
code: 'export default () => { var foo = function() { return "bar"; }; }',
output: 'export default () => { var foo = () => "bar"; }',
},
{
// Using multiple lines to check that it only errors on the inner function
code: `function top() {
return function() { return "bar"; };
}`,
output: `function top() {
return () => "bar";
}`,
},
{
// Make sure "allowNamedFunctions" works with typescript
code: `function foo(a: string): () => string {
return function() { return \`bar \${a}\`; };
}`,
output: `function foo(a: string): () => string {
return () => \`bar \${a}\`;
}`,
parser: require.resolve('@typescript-eslint/parser'),
},
];

const ruleTester = new RuleTester({
parser: require.resolve('@typescript-eslint/parser'),
parserOptions: {
@@ -862,3 +937,16 @@ describe('when returnStyle is "explicit"', () => {
});
});
});

describe('when allowNamedFunctions is true', () => {
describe("it doesn't report named functions", () => {
ruleTester.run('lib/rules/prefer-arrow-functions', rule, {
valid: validWhenAllowNamedFunctions.map(
withOptions({ allowNamedFunctions: true }),
),
invalid: invalidWhenAllowNamedFunctions
.map(withOptions({ allowNamedFunctions: true }))
.map(withErrors([USE_ARROW_WHEN_FUNCTION])),
});
});
});
9 changes: 6 additions & 3 deletions src/prefer-arrow-functions.ts
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ export default {
{
additionalProperties: false,
properties: {
allowNamedFunctions: { type: 'boolean' },
classPropertiesAllowed: { type: 'boolean' },
disallowPrototype: { type: 'boolean' },
returnStyle: {
@@ -37,6 +38,7 @@ export default {
typeof options[name] !== 'undefined'
? options[name]
: DEFAULT_OPTIONS[name];
const allowNamedFunctions = getOption('allowNamedFunctions');
const singleReturnOnly = getOption('singleReturnOnly');
const classPropertiesAllowed = getOption('classPropertiesAllowed');
const disallowPrototype = getOption('disallowPrototype');
@@ -195,10 +197,10 @@ export default {
});
};

const isNamed = (node) => node.id && node.id.name;

const isNamedDefaultExport = (node) =>
node.id &&
node.id.name &&
node.parent.type === 'ExportDefaultDeclaration';
isNamed(node) && node.parent.type === 'ExportDefaultDeclaration';

const isSafeTransformation = (node) => {
return (
@@ -207,6 +209,7 @@ export default {
!containsSuper(node) &&
!containsArguments(node) &&
!containsNewDotTarget(node) &&
(!isNamed(node) || !allowNamedFunctions) &&
(!isPrototypeAssignment(node) || disallowPrototype) &&
(!singleReturnOnly ||
(returnsImmediately(node) && !isNamedDefaultExport(node)))