From bb56398e2a0c30e01f65fcab50846138f4d8f635 Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Tue, 6 Feb 2024 22:34:49 +0800 Subject: [PATCH 01/25] Add tests --- configs/recommended.js | 1 + docs/rules/no-anonymous-default-export.md | 22 ++++++++ readme.md | 1 + rules/no-anonymous-default-export.js | 63 +++++++++++++++++++++++ test/no-anonymous-default-export.mjs | 24 +++++++++ 5 files changed, 111 insertions(+) create mode 100644 docs/rules/no-anonymous-default-export.md create mode 100644 rules/no-anonymous-default-export.js create mode 100644 test/no-anonymous-default-export.mjs diff --git a/configs/recommended.js b/configs/recommended.js index a807c50b02..67f99a8472 100644 --- a/configs/recommended.js +++ b/configs/recommended.js @@ -14,6 +14,7 @@ module.exports = { 'unicorn/import-style': 'error', 'unicorn/new-for-builtins': 'error', 'unicorn/no-abusive-eslint-disable': 'error', + 'unicorn/no-anonymous-default-export': 'error', 'unicorn/no-array-callback-reference': 'error', 'unicorn/no-array-for-each': 'error', 'unicorn/no-array-method-this-argument': 'error', diff --git a/docs/rules/no-anonymous-default-export.md b/docs/rules/no-anonymous-default-export.md new file mode 100644 index 0000000000..e6318f8896 --- /dev/null +++ b/docs/rules/no-anonymous-default-export.md @@ -0,0 +1,22 @@ +# Disallow anonymous functions and classes as the default export + +πΌ This rule is enabled in the β `recommended` [config](https://github.com/sindresorhus/eslint-plugin-unicorn#preset-configs). + +π‘ This rule is manually fixable by [editor suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions). + +<!-- end auto-generated rule header --> +<!-- Do not manually modify this header. Run: `npm run fix:eslint-docs` --> + +<!-- Remove this comment, add more detailed description. --> + +## Fail + +```js +const foo = 'unicorn'; +``` + +## Pass + +```js +const foo = 'π¦'; +``` diff --git a/readme.md b/readme.md index 506f43f92f..47c31feef5 100644 --- a/readme.md +++ b/readme.md @@ -124,6 +124,7 @@ If you don't use the preset, ensure you use the same `env` and `parserOptions` c | [import-style](docs/rules/import-style.md) | Enforce specific import styles per module. | β | | | | [new-for-builtins](docs/rules/new-for-builtins.md) | Enforce the use of `new` for all builtins, except `String`, `Number`, `Boolean`, `Symbol` and `BigInt`. | β | π§ | | | [no-abusive-eslint-disable](docs/rules/no-abusive-eslint-disable.md) | Enforce specifying rules to disable in `eslint-disable` comments. | β | | | +| [no-anonymous-default-export](docs/rules/no-anonymous-default-export.md) | Disallow anonymous functions and classes as the default export. | β | | π‘ | | [no-array-callback-reference](docs/rules/no-array-callback-reference.md) | Prevent passing a function reference directly to iterator methods. | β | | π‘ | | [no-array-for-each](docs/rules/no-array-for-each.md) | Prefer `forβ¦of` over the `forEach` method. | β | π§ | π‘ | | [no-array-method-this-argument](docs/rules/no-array-method-this-argument.md) | Disallow using the `this` argument in array methods. | β | π§ | π‘ | diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js new file mode 100644 index 0000000000..655cd9967e --- /dev/null +++ b/rules/no-anonymous-default-export.js @@ -0,0 +1,63 @@ +'use strict'; +const {} = require('./ast/index.js'); +const {} = require('./fix/index.js'); +const {} = require('./utils/index.js'); + + +const MESSAGE_ID_ERROR = 'no-anonymous-default-export/error'; +const MESSAGE_ID_SUGGESTION = 'no-anonymous-default-export/suggestion'; +const messages = { + [MESSAGE_ID_ERROR]: 'Prefer `{{replacement}}` over `{{value}}`.', + [MESSAGE_ID_SUGGESTION]: 'Replace `{{value}}` with `{{replacement}}`.', +}; + + +const selector = [ + 'Literal', + '[value="unicorn"]', +].join(''); + +/** @param {import('eslint').Rule.RuleContext} context */ +const create = context => { + return { + [selector](node) { + return { + node, + messageId: MESSAGE_ID_ERROR, + data: { + value: 'unicorn', + replacement: 'π¦', + }, + + + /** @param {import('eslint').Rule.RuleFixer} fixer */ + suggest: [ + { + messageId: MESSAGE_ID_SUGGESTION, + data: { + value: 'unicorn', + replacement: 'π¦', + }, + /** @param {import('eslint').Rule.RuleFixer} fixer */ + fix: fixer => fixer.replaceText(node, '\'π¦\''), + } + ], + + }; + }, + }; +}; + +/** @type {import('eslint').Rule.RuleModule} */ +module.exports = { + create, + meta: { + type: 'suggestion', + docs: { + description: 'Disallow anonymous functions and classes as the default export.', + }, + + hasSuggestions: true, + messages, + }, +}; diff --git a/test/no-anonymous-default-export.mjs b/test/no-anonymous-default-export.mjs new file mode 100644 index 0000000000..081bc287db --- /dev/null +++ b/test/no-anonymous-default-export.mjs @@ -0,0 +1,24 @@ +import outdent from 'outdent'; +import {getTester} from './utils/test.mjs'; + +const {test} = getTester(import.meta); + +test.snapshot({ + valid: [ + 'export default function named() {}', + 'export default class named {}', + 'export default []', + 'export default {}', + 'export default 1', + 'export default false', + 'export default 0n', + // `ClassExpression`s and `FunctionExpression`s are ignored + 'export default (class {})', + 'export default (function {})', + ], + invalid: [ + 'export default function () {}', + 'export default class () {}', + 'export default () => {}', + ], +}); From 7162ebfd9bffc2dbfd7b808b1ea1ba00a0873434 Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Tue, 6 Feb 2024 22:51:15 +0800 Subject: [PATCH 02/25] Implement --- rules/no-anonymous-default-export.js | 57 +++++++-- test/no-anonymous-default-export.mjs | 8 +- .../no-anonymous-default-export.mjs.md | 110 ++++++++++++++++++ .../no-anonymous-default-export.mjs.snap | Bin 0 -> 455 bytes 4 files changed, 162 insertions(+), 13 deletions(-) create mode 100644 test/snapshots/no-anonymous-default-export.mjs.md create mode 100644 test/snapshots/no-anonymous-default-export.mjs.snap diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js index 655cd9967e..2585a861f5 100644 --- a/rules/no-anonymous-default-export.js +++ b/rules/no-anonymous-default-export.js @@ -1,4 +1,6 @@ 'use strict'; + +const {getFunctionHeadLocation, getFunctionNameWithKind} = require('@eslint-community/eslint-utils'); const {} = require('./ast/index.js'); const {} = require('./fix/index.js'); const {} = require('./utils/index.js'); @@ -7,20 +9,53 @@ const {} = require('./utils/index.js'); const MESSAGE_ID_ERROR = 'no-anonymous-default-export/error'; const MESSAGE_ID_SUGGESTION = 'no-anonymous-default-export/suggestion'; const messages = { - [MESSAGE_ID_ERROR]: 'Prefer `{{replacement}}` over `{{value}}`.', - [MESSAGE_ID_SUGGESTION]: 'Replace `{{value}}` with `{{replacement}}`.', + [MESSAGE_ID_ERROR]: 'The {{description}} should be named.', + [MESSAGE_ID_SUGGESTION]: 'Name it as {{name}}.', }; +function getNodeDescription(node) { + if (node.type === 'ClassDeclaration') { + return 'class' + } + + const nameWithKind = getFunctionNameWithKind(node) + if (nameWithKind.endsWith(' \'default\'')) { + return nameWithKind.slice(0, -' \'default\''.length) + } -const selector = [ - 'Literal', - '[value="unicorn"]', -].join(''); + return nameWithKind +} /** @param {import('eslint').Rule.RuleContext} context */ const create = context => { return { - [selector](node) { + ExportDefaultDeclaration(exportDefaultDeclaration) { + const {declaration} = exportDefaultDeclaration; + + if (!( + ( + ( + declaration.type === 'FunctionDeclaration' || + declaration.type === 'ClassDeclaration' + ) + && !declaration.id + ) + || + declaration.type === 'ArrowFunctionExpression' + )) { + return; + } + + const problem = { + node: declaration, + messageId: MESSAGE_ID_ERROR, + data: { + description: getNodeDescription(declaration), + }, + }; + + return problem; + return { node, messageId: MESSAGE_ID_ERROR, @@ -28,8 +63,8 @@ const create = context => { value: 'unicorn', replacement: 'π¦', }, - - + + /** @param {import('eslint').Rule.RuleFixer} fixer */ suggest: [ { @@ -42,7 +77,7 @@ const create = context => { fix: fixer => fixer.replaceText(node, '\'π¦\''), } ], - + }; }, }; @@ -56,7 +91,7 @@ module.exports = { docs: { description: 'Disallow anonymous functions and classes as the default export.', }, - + hasSuggestions: true, messages, }, diff --git a/test/no-anonymous-default-export.mjs b/test/no-anonymous-default-export.mjs index 081bc287db..fb0f61af27 100644 --- a/test/no-anonymous-default-export.mjs +++ b/test/no-anonymous-default-export.mjs @@ -14,11 +14,15 @@ test.snapshot({ 'export default 0n', // `ClassExpression`s and `FunctionExpression`s are ignored 'export default (class {})', - 'export default (function {})', + 'export default (function () {})', ], invalid: [ 'export default function () {}', - 'export default class () {}', + 'export default class {}', 'export default () => {}', + 'export default function * () {}', + 'export default async function () {}', + 'export default async function * () {}', + 'export default async () => {}', ], }); diff --git a/test/snapshots/no-anonymous-default-export.mjs.md b/test/snapshots/no-anonymous-default-export.mjs.md new file mode 100644 index 0000000000..6d61bbe85e --- /dev/null +++ b/test/snapshots/no-anonymous-default-export.mjs.md @@ -0,0 +1,110 @@ +# Snapshot report for `test/no-anonymous-default-export.mjs` + +The actual snapshot is saved in `no-anonymous-default-export.mjs.snap`. + +Generated by [AVA](https://avajs.dev). + +## invalid(1): export default function () {} + +> Input + + `β + 1 | export default function () {}β + ` + +> Error 1/1 + + `β + > 1 | export default function () {}β + | ^^^^^^^^^^^^^^ The function should be named.β + ` + +## invalid(2): export default class {} + +> Input + + `β + 1 | export default class {}β + ` + +> Error 1/1 + + `β + > 1 | export default class {}β + | ^^^^^^^^ The class should be named.β + ` + +## invalid(3): export default () => {} + +> Input + + `β + 1 | export default () => {}β + ` + +> Error 1/1 + + `β + > 1 | export default () => {}β + | ^^^^^^^^ The arrow function should be named.β + ` + +## invalid(4): export default function * () {} + +> Input + + `β + 1 | export default function * () {}β + ` + +> Error 1/1 + + `β + > 1 | export default function * () {}β + | ^^^^^^^^^^^^^^^^ The generator function should be named.β + ` + +## invalid(5): export default async function () {} + +> Input + + `β + 1 | export default async function () {}β + ` + +> Error 1/1 + + `β + > 1 | export default async function () {}β + | ^^^^^^^^^^^^^^^^^^^^ The async function should be named.β + ` + +## invalid(6): export default async function * () {} + +> Input + + `β + 1 | export default async function * () {}β + ` + +> Error 1/1 + + `β + > 1 | export default async function * () {}β + | ^^^^^^^^^^^^^^^^^^^^^^ The async generator function should be named.β + ` + +## invalid(7): export default async () => {} + +> Input + + `β + 1 | export default async () => {}β + ` + +> Error 1/1 + + `β + > 1 | export default async () => {}β + | ^^^^^^^^^^^^^^ The async arrow function should be named.β + ` diff --git a/test/snapshots/no-anonymous-default-export.mjs.snap b/test/snapshots/no-anonymous-default-export.mjs.snap new file mode 100644 index 0000000000000000000000000000000000000000..142b0c5c349b399bdcd045d0417b14710fb053ba GIT binary patch literal 455 zcmV;&0XY6aRzV<BZeeh9Xm4~Nb~6eC09j5uuICV1X<P+rcYf1#RkK6E2ua#d9&`^I zm9r;UOCO5}00000000A}l|fI!Fcim!#+Y#P6ZjHiWDq11(WsG|2k#y@nRHtRi?t<f zrx5X=9{2{{<&zq99oBVQ!FOJN+5gw~UOytAu;5P27g)xU;E5a42Snnq;koC4Cu7DX zgg8P8kq{*`kTIjsaN+4W78H%eh)MCf2ty>%pu6d8J6~1Xa&~I_bpQ`$<&Zii$j1a< z({UnGOrl|i^}YoL0AL1x>Q*bb8R6wIF=7b`!N)++Jq{1kABnFxXB@nar-bY&AxC*3 z0YO3-RkXDXyJi*YxJg2!0S0CX8K5-&ckrK2S5Mu|r*61#*<U}kI&MnMGypQE&H&Y^ z5$Ei2jZ1H-_{Swv&@7sRo|fXEVh)<clkld2l8Q-a+Rs9&XNW20NHV^LqK;D3%PT@+ zN`uOEai*nfnKhYECRK9{HZ`j<!mM;HJ4#1b>++PYlS*BMeRZK_Y+DH{>8|(RxQ)4E x<!q%U%X#}x!(}hiX_3L=#bos|=@65#7Y!rIgxM{roS;<~)+dj4&bPn^00718&ba^p literal 0 HcmV?d00001 From 569b5367e2493168ca47b6e9a9bcf06c0777b3a9 Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Tue, 6 Feb 2024 23:00:45 +0800 Subject: [PATCH 03/25] Better location --- rules/no-anonymous-default-export.js | 51 ++++++++++-------- .../no-anonymous-default-export.mjs.md | 14 ++--- .../no-anonymous-default-export.mjs.snap | Bin 455 -> 457 bytes 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js index 2585a861f5..f93efc0f03 100644 --- a/rules/no-anonymous-default-export.js +++ b/rules/no-anonymous-default-export.js @@ -1,6 +1,7 @@ 'use strict'; const {getFunctionHeadLocation, getFunctionNameWithKind} = require('@eslint-community/eslint-utils'); +const getClassHeadLocation = require('./utils/get-class-head-location.js'); const {} = require('./ast/index.js'); const {} = require('./fix/index.js'); const {} = require('./utils/index.js'); @@ -13,49 +14,53 @@ const messages = { [MESSAGE_ID_SUGGESTION]: 'Name it as {{name}}.', }; -function getNodeDescription(node) { - if (node.type === 'ClassDeclaration') { - return 'class' - } - - const nameWithKind = getFunctionNameWithKind(node) - if (nameWithKind.endsWith(' \'default\'')) { - return nameWithKind.slice(0, -' \'default\''.length) - } - - return nameWithKind +const EXPECTED_FUNCTION_DESCRIPTION = ' \'default\'' +function getNodeDescription(node, sourceCode) { } /** @param {import('eslint').Rule.RuleContext} context */ const create = context => { - return { - ExportDefaultDeclaration(exportDefaultDeclaration) { - const {declaration} = exportDefaultDeclaration; + const {sourceCode} = context; + return { + ExportDefaultDeclaration({declaration: node}) { if (!( ( ( - declaration.type === 'FunctionDeclaration' || - declaration.type === 'ClassDeclaration' + node.type === 'FunctionDeclaration' || + node.type === 'ClassDeclaration' ) - && !declaration.id + && !node.id ) || - declaration.type === 'ArrowFunctionExpression' + node.type === 'ArrowFunctionExpression' )) { return; } const problem = { - node: declaration, + node, messageId: MESSAGE_ID_ERROR, - data: { - description: getNodeDescription(declaration), - }, - }; + data: {} + } + + if (node.type === 'ClassDeclaration') { + problem.loc = getClassHeadLocation(node, sourceCode); + problem.data.description = 'class'; + return problem; + } + + problem.loc = getFunctionHeadLocation(node, sourceCode); + // [TODO: @fisker]: Ask `@eslint-community/eslint-utils` to expose `getFunctionKind` + const nameWithKind = getFunctionNameWithKind(node) + problem.data.description = + nameWithKind.endsWith(EXPECTED_FUNCTION_DESCRIPTION) + ? nameWithKind.slice(0, -EXPECTED_FUNCTION_DESCRIPTION.length) + : nameWithKind return problem; + return { node, messageId: MESSAGE_ID_ERROR, diff --git a/test/snapshots/no-anonymous-default-export.mjs.md b/test/snapshots/no-anonymous-default-export.mjs.md index 6d61bbe85e..8e36dd0b23 100644 --- a/test/snapshots/no-anonymous-default-export.mjs.md +++ b/test/snapshots/no-anonymous-default-export.mjs.md @@ -16,7 +16,7 @@ Generated by [AVA](https://avajs.dev). `β > 1 | export default function () {}β - | ^^^^^^^^^^^^^^ The function should be named.β + | ^^^^^^^^^ The function should be named.β ` ## invalid(2): export default class {} @@ -31,7 +31,7 @@ Generated by [AVA](https://avajs.dev). `β > 1 | export default class {}β - | ^^^^^^^^ The class should be named.β + | ^^^^^ The class should be named.β ` ## invalid(3): export default () => {} @@ -46,7 +46,7 @@ Generated by [AVA](https://avajs.dev). `β > 1 | export default () => {}β - | ^^^^^^^^ The arrow function should be named.β + | ^^ The arrow function should be named.β ` ## invalid(4): export default function * () {} @@ -61,7 +61,7 @@ Generated by [AVA](https://avajs.dev). `β > 1 | export default function * () {}β - | ^^^^^^^^^^^^^^^^ The generator function should be named.β + | ^^^^^^^^^^^ The generator function should be named.β ` ## invalid(5): export default async function () {} @@ -76,7 +76,7 @@ Generated by [AVA](https://avajs.dev). `β > 1 | export default async function () {}β - | ^^^^^^^^^^^^^^^^^^^^ The async function should be named.β + | ^^^^^^^^^^^^^^^ The async function should be named.β ` ## invalid(6): export default async function * () {} @@ -91,7 +91,7 @@ Generated by [AVA](https://avajs.dev). `β > 1 | export default async function * () {}β - | ^^^^^^^^^^^^^^^^^^^^^^ The async generator function should be named.β + | ^^^^^^^^^^^^^^^^^ The async generator function should be named.β ` ## invalid(7): export default async () => {} @@ -106,5 +106,5 @@ Generated by [AVA](https://avajs.dev). `β > 1 | export default async () => {}β - | ^^^^^^^^^^^^^^ The async arrow function should be named.β + | ^^ The async arrow function should be named.β ` diff --git a/test/snapshots/no-anonymous-default-export.mjs.snap b/test/snapshots/no-anonymous-default-export.mjs.snap index 142b0c5c349b399bdcd045d0417b14710fb053ba..37377a5c8f3b367593e18fa9795a78760e46622a 100644 GIT binary patch literal 457 zcmV;)0XF_YRzV<BZeeh9Xm4~Nb~6eC0Qu4b{q~Vq0nqcz{O727uQ<?N<dhvY+RiMf z#xg;;N*{{|00000000A}l|fI!Fc^l1#+Y#P7x*Q{$RJ22qERC^58gHLMAB_V7Hhk- zonizJTs->|<d+&JotAa1%%1nX+4Jn}x6h$ZSnwd;=U7IP;ISLgCq$yK;koC4$1&p) zLOetXkuXeXAR|Vh;lk@Q5){Q^#H5(b!w^Yy*WGlso$piIa&~I_bpQ`0t3&FTARiNa zP2)r^Vqz`EulFrt001VibO!3c%?STah!IOj2tEdi9&vcMc!%hUbH>5zc*@0|a&eS* z5fCJV(L!5${av#KHE!Y$w18VPe-=<oo>Kojw?1+=kKAzKvR@rpjhm2(7BDa)X8}g! zlsZL5oU`W&pSz{lk5^Q`SycX>hHy|){$_Fg-?X5(r2b8-3$QSAk16IzGG4(>N7?D+ z?I7_&gVObIrh&E0hD=c=OEWD@nk^Z_%1mXpmZq&udCJsDsj0#?U1)f1D_1Kz_3<}u zW9C@tvaME5*?(%5{eMo2<Q1<WtN)K4QuzWd#T2b1eKDmo>#nCS`AL*bqXz&00dm?{ literal 455 zcmV;&0XY6aRzV<BZeeh9Xm4~Nb~6eC09j5uuICV1X<P+rcYf1#RkK6E2ua#d9&`^I zm9r;UOCO5}00000000A}l|fI!Fcim!#+Y#P6ZjHiWDq11(WsG|2k#y@nRHtRi?t<f zrx5X=9{2{{<&zq99oBVQ!FOJN+5gw~UOytAu;5P27g)xU;E5a42Snnq;koC4Cu7DX zgg8P8kq{*`kTIjsaN+4W78H%eh)MCf2ty>%pu6d8J6~1Xa&~I_bpQ`$<&Zii$j1a< z({UnGOrl|i^}YoL0AL1x>Q*bb8R6wIF=7b`!N)++Jq{1kABnFxXB@nar-bY&AxC*3 z0YO3-RkXDXyJi*YxJg2!0S0CX8K5-&ckrK2S5Mu|r*61#*<U}kI&MnMGypQE&H&Y^ z5$Ei2jZ1H-_{Swv&@7sRo|fXEVh)<clkld2l8Q-a+Rs9&XNW20NHV^LqK;D3%PT@+ zN`uOEai*nfnKhYECRK9{HZ`j<!mM;HJ4#1b>++PYlS*BMeRZK_Y+DH{>8|(RxQ)4E x<!q%U%X#}x!(}hiX_3L=#bos|=@65#7Y!rIgxM{roS;<~)+dj4&bPn^00718&ba^p From 414d85806869b4a8ebbf224f35f944797044cf3e Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Tue, 6 Feb 2024 23:44:15 +0800 Subject: [PATCH 04/25] Suggestion --- rules/no-anonymous-default-export.js | 115 ++++-- test/no-anonymous-default-export.mjs | 69 ++++ .../no-anonymous-default-export.mjs.md | 379 ++++++++++++++++++ .../no-anonymous-default-export.mjs.snap | Bin 457 -> 920 bytes 4 files changed, 522 insertions(+), 41 deletions(-) diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js index f93efc0f03..b7e5f14d00 100644 --- a/rules/no-anonymous-default-export.js +++ b/rules/no-anonymous-default-export.js @@ -1,26 +1,64 @@ 'use strict'; +const path = require('node:path') const {getFunctionHeadLocation, getFunctionNameWithKind} = require('@eslint-community/eslint-utils'); +const { + isIdentifierName, +} = require('@babel/helper-validator-identifier'); const getClassHeadLocation = require('./utils/get-class-head-location.js'); +const {upperFirst, camelCase} = require('./utils/lodash.js'); +const assertToken = require('./utils/assert-token.js'); const {} = require('./ast/index.js'); const {} = require('./fix/index.js'); -const {} = require('./utils/index.js'); +const { + getScopes, + avoidCapture, +} = require('./utils/index.js'); const MESSAGE_ID_ERROR = 'no-anonymous-default-export/error'; const MESSAGE_ID_SUGGESTION = 'no-anonymous-default-export/suggestion'; const messages = { [MESSAGE_ID_ERROR]: 'The {{description}} should be named.', - [MESSAGE_ID_SUGGESTION]: 'Name it as {{name}}.', + [MESSAGE_ID_SUGGESTION]: 'Name it as `{{name}}`.', }; -const EXPECTED_FUNCTION_DESCRIPTION = ' \'default\'' -function getNodeDescription(node, sourceCode) { +const EXPECTED_FUNCTION_DESCRIPTION_SUFFIX = ' \'default\'' + +function getSuggestionName(node, filename, sourceCode) { + if (filename === '<input>' || filename === '<text>') { + return; + } + + let [name] = path.basename(filename).split('.') + name = camelCase(name) + + if (!isIdentifierName(name)) { + return + } + + name = node.type === 'ClassDeclaration' ? upperFirst(name) : name + name = avoidCapture(name, getScopes(sourceCode.getScope(node))); + + return name; +} + +function addName(fixer, node, name, sourceCode) { + switch (node.type) { + case 'ClassDeclaration': { + const classToken = sourceCode.getFirstToken(node); + assertToken(classToken, { + expected: {type: 'Keyword', value: 'class'}, + ruleId: 'no-anonymous-default-export', + }) + return fixer.insertTextAfter(classToken, ` ${name}`); + } + } } /** @param {import('eslint').Rule.RuleContext} context */ const create = context => { - const {sourceCode} = context; + const {sourceCode, physicalFilename} = context; return { ExportDefaultDeclaration({declaration: node}) { @@ -38,52 +76,47 @@ const create = context => { return; } - const problem = { - node, - messageId: MESSAGE_ID_ERROR, - data: {} - } + const suggestionName = getSuggestionName(node, physicalFilename, sourceCode) + let loc + let description if (node.type === 'ClassDeclaration') { - problem.loc = getClassHeadLocation(node, sourceCode); - problem.data.description = 'class'; - return problem; + loc = getClassHeadLocation(node, sourceCode); + description = 'class'; + } else { + loc = getFunctionHeadLocation(node, sourceCode); + // [TODO: @fisker]: Ask `@eslint-community/eslint-utils` to expose `getFunctionKind` + const nameWithKind = getFunctionNameWithKind(node) + description = + nameWithKind.endsWith(EXPECTED_FUNCTION_DESCRIPTION_SUFFIX) + ? nameWithKind.slice(0, -EXPECTED_FUNCTION_DESCRIPTION_SUFFIX.length) + : nameWithKind } - problem.loc = getFunctionHeadLocation(node, sourceCode); - // [TODO: @fisker]: Ask `@eslint-community/eslint-utils` to expose `getFunctionKind` - const nameWithKind = getFunctionNameWithKind(node) - problem.data.description = - nameWithKind.endsWith(EXPECTED_FUNCTION_DESCRIPTION) - ? nameWithKind.slice(0, -EXPECTED_FUNCTION_DESCRIPTION.length) - : nameWithKind - - return problem; - - - return { + const problem = { node, + loc, messageId: MESSAGE_ID_ERROR, data: { - value: 'unicorn', - replacement: 'π¦', + description, }, + } + if (!suggestionName) { + return problem; + } - /** @param {import('eslint').Rule.RuleFixer} fixer */ - suggest: [ - { - messageId: MESSAGE_ID_SUGGESTION, - data: { - value: 'unicorn', - replacement: 'π¦', - }, - /** @param {import('eslint').Rule.RuleFixer} fixer */ - fix: fixer => fixer.replaceText(node, '\'π¦\''), - } - ], - - }; + problem.suggest = [ + { + messageId: MESSAGE_ID_SUGGESTION, + data: { + name: suggestionName, + }, + fix: fixer => addName(fixer, node, suggestionName, sourceCode) + }, + ]; + + return problem; }, }; }; diff --git a/test/no-anonymous-default-export.mjs b/test/no-anonymous-default-export.mjs index fb0f61af27..a856972e00 100644 --- a/test/no-anonymous-default-export.mjs +++ b/test/no-anonymous-default-export.mjs @@ -24,5 +24,74 @@ test.snapshot({ 'export default async function () {}', 'export default async function * () {}', 'export default async () => {}', + { + code: 'export default class {}', + filename: '/path/to/foo.js', + }, + { + code: 'export default class{}', + filename: '/path/to/foo.js', + }, + { + code: 'export default class {}', + filename: '/path/to/foo-bar.js', + }, + { + code: 'export default class {}', + filename: '/path/to/foo_bar.js', + }, + { + code: 'export default class {}', + filename: '/path/to/foo+bar.js', + }, + { + code: 'export default class {}', + filename: '/path/to/foo+bar123.js', + }, + { + code: 'export default class {}', + filename: '/path/to/foo*.js', + }, + { + code: 'export default class {}', + filename: '/path/to/[foo].js', + }, + { + code: outdent` + let Foo, Foo_, foo, foo_ + export default class {} + `, + filename: '/path/to/foo.js', + }, + + + { + code: 'export default function () {}', + filename: '/path/to/foo.js', + }, + { + code: 'export default () => {}', + filename: '/path/to/foo.js', + }, + { + code: 'export default function () {}', + filename: '123.js', + }, + { + code: 'export default function () {}', + filename: '$foo.js', + }, + { + code: 'export default function () {}', + filename: '_foo.js', + }, + { + code: 'export default class {}', + filename: '/path/to/foo.js', + }, + { + code: 'export default function () {}', + filename: '/path/to/foo.test.js', + }, ], }); diff --git a/test/snapshots/no-anonymous-default-export.mjs.md b/test/snapshots/no-anonymous-default-export.mjs.md index 8e36dd0b23..a056fc9d5d 100644 --- a/test/snapshots/no-anonymous-default-export.mjs.md +++ b/test/snapshots/no-anonymous-default-export.mjs.md @@ -108,3 +108,382 @@ Generated by [AVA](https://avajs.dev). > 1 | export default async () => {}β | ^^ The async arrow function should be named.β ` + +## invalid(8): export default class {} + +> Input + + `β + 1 | export default class {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default class {}β + | ^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`Foo\`.β + 1 | export default class Foo {}β + ` + +## invalid(9): export default class{} + +> Input + + `β + 1 | export default class{}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default class{}β + | ^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`Foo\`.β + 1 | export default class Foo{}β + ` + +## invalid(10): export default class {} + +> Input + + `β + 1 | export default class {}β + ` + +> Filename + + `β + /path/to/foo-bar.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default class {}β + | ^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`FooBar\`.β + 1 | export default class FooBar {}β + ` + +## invalid(11): export default class {} + +> Input + + `β + 1 | export default class {}β + ` + +> Filename + + `β + /path/to/foo_bar.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default class {}β + | ^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`FooBar\`.β + 1 | export default class FooBar {}β + ` + +## invalid(12): export default class {} + +> Input + + `β + 1 | export default class {}β + ` + +> Filename + + `β + /path/to/foo+bar.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default class {}β + | ^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`FooBar\`.β + 1 | export default class FooBar {}β + ` + +## invalid(13): export default class {} + +> Input + + `β + 1 | export default class {}β + ` + +> Filename + + `β + /path/to/foo+bar123.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default class {}β + | ^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`FooBar123\`.β + 1 | export default class FooBar123 {}β + ` + +## invalid(14): export default class {} + +> Input + + `β + 1 | export default class {}β + ` + +> Filename + + `β + /path/to/foo*.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default class {}β + | ^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`Foo\`.β + 1 | export default class Foo {}β + ` + +## invalid(15): export default class {} + +> Input + + `β + 1 | export default class {}β + ` + +> Filename + + `β + /path/to/[foo].jsβ + ` + +> Error 1/1 + + `β + > 1 | export default class {}β + | ^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`Foo\`.β + 1 | export default class Foo {}β + ` + +## invalid(16): let Foo, Foo_, foo, foo_ export default class {} + +> Input + + `β + 1 | let Foo, Foo_, foo, foo_β + 2 | export default class {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + 1 | let Foo, Foo_, foo, foo_β + > 2 | export default class {}β + | ^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`Foo__\`.β + 1 | let Foo, Foo_, foo, foo_β + 2 | export default class Foo__ {}β + ` + +## invalid(17): export default function () {} + +> Input + + `β + 1 | export default function () {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default function () {}β + | ^^^^^^^^^ The function should be named.β + ` + +## invalid(18): export default () => {} + +> Input + + `β + 1 | export default () => {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default () => {}β + | ^^ The arrow function should be named.β + ` + +## invalid(19): export default function () {} + +> Input + + `β + 1 | export default function () {}β + ` + +> Filename + + `β + 123.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default function () {}β + | ^^^^^^^^^ The function should be named.β + ` + +## invalid(20): export default function () {} + +> Input + + `β + 1 | export default function () {}β + ` + +> Filename + + `β + $foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default function () {}β + | ^^^^^^^^^ The function should be named.β + ` + +## invalid(21): export default function () {} + +> Input + + `β + 1 | export default function () {}β + ` + +> Filename + + `β + _foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default function () {}β + | ^^^^^^^^^ The function should be named.β + ` + +## invalid(22): export default class {} + +> Input + + `β + 1 | export default class {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default class {}β + | ^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`Foo\`.β + 1 | export default class Foo {}β + ` + +## invalid(23): export default function () {} + +> Input + + `β + 1 | export default function () {}β + ` + +> Filename + + `β + /path/to/foo.test.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default function () {}β + | ^^^^^^^^^ The function should be named.β + ` diff --git a/test/snapshots/no-anonymous-default-export.mjs.snap b/test/snapshots/no-anonymous-default-export.mjs.snap index 37377a5c8f3b367593e18fa9795a78760e46622a..e8970667c332c635e4837acc67c9a1fe9560d973 100644 GIT binary patch literal 920 zcmV;J184j}RzV<BZeeh9Xm4~Nb~6eC0DO@K(7ph>g&EQflUqvAqBMY4JxA4*vZv~) zPZzkt${&je00000000B+nM-feKoo@&5HIfv0<oeOTA)dr20IjJp;=U-5)xv=vqChT zB$LMAdLnxQMHCk8FJQ%*{yW5q6^Ipbh;42?9y?BA(kfn5S#(Z(&v)i^^R-bmSnZAd zWuJ1L8+1FTn{SDs*Jsq+6431yvpCdggR~6}jka0iIx}G=2OmD_wn<uclW}`@zg{Pt zyeJ*doXR*)_C#hPdsP8YVMi{aP=i#dK_8f{Ht))`kW5u6$B+R4*ntDjy8FPBCiO?y zP1ZK*P^Dm!En1)NzJq?>vX}*GQFXnTa=p-kUepX?+d>x#==CSXF1W)*_1BQVQ*r&C zKzQYys{j69?<JRlCC}twxtzRYcetoz0|~5)OZEhWC3mXsluRs(y-R?5)~)@fB>MTV z@Gqbeu1ADFA0GctNT?MN|9q?o&~;{$n$#kkSqa=Jy6!9l-68gSvlh8LETY0@#SV$2 zL@w<jF)nsVC>G_E=hlJIv7J&~r*1_$6`H2IsJucfuOylJ{IA@x-ApXI;zlcASwAuJ z_Mh8f=7ldqvGyM<l6V3hkO^Co@WRv?lXQ9VmgYNgcB8#P?M9PGU_vRj2yYfSD>fLL ze{FY%G*@+lIt6q`{YHWN9ul}dH!-C!;757f-rS^ihl^TNm*5fEqM$ppVPloCjd_`W ztBm;`2Kila`7MU<6XBaf?q8C8{UGW6LiE1L=p7+=5_Z$xsrW{!lWz(MoJaTyRbquA zT+3z<!yiXv2Cfh*lH&@oWb@ExDY)YNCzh2l%RX7gx}v4Ra(2wJPnLqa=MY(5Ljo5A zELE)}!Fdwl{CRY6s#+-yQB^C&gDSXG4-qOLfwKr|etc~0;n?aE6kPm=NboWeIOh|5 z*<kF|7-0_xmpz0|N5Y`o88GMksmwvc`RE)$;<J5-(3HDx7N)BJXenGd*RuBz`9e18 zy~@(}IwZlURJ>>;0nky9Whd`tN6?T7>-g>U(vXSn^(DK+j?B*p{t7DS+yuK>J*}X! zK2|c@Mxqt(r%uo;NhfvBkjiOAb_^Vyta-+1f<{F;#yv+WXO!u~F-v{tdidpYxXx7$ uhjZTgrlorcA9tn)bUyT>FSvQ9w8u{)nF|;ur#2tqiSP#|`N=dzApih`bGXa^ literal 457 zcmV;)0XF_YRzV<BZeeh9Xm4~Nb~6eC0Qu4b{q~Vq0nqcz{O727uQ<?N<dhvY+RiMf z#xg;;N*{{|00000000A}l|fI!Fc^l1#+Y#P7x*Q{$RJ22qERC^58gHLMAB_V7Hhk- zonizJTs->|<d+&JotAa1%%1nX+4Jn}x6h$ZSnwd;=U7IP;ISLgCq$yK;koC4$1&p) zLOetXkuXeXAR|Vh;lk@Q5){Q^#H5(b!w^Yy*WGlso$piIa&~I_bpQ`0t3&FTARiNa zP2)r^Vqz`EulFrt001VibO!3c%?STah!IOj2tEdi9&vcMc!%hUbH>5zc*@0|a&eS* z5fCJV(L!5${av#KHE!Y$w18VPe-=<oo>Kojw?1+=kKAzKvR@rpjhm2(7BDa)X8}g! zlsZL5oU`W&pSz{lk5^Q`SycX>hHy|){$_Fg-?X5(r2b8-3$QSAk16IzGG4(>N7?D+ z?I7_&gVObIrh&E0hD=c=OEWD@nk^Z_%1mXpmZq&udCJsDsj0#?U1)f1D_1Kz_3<}u zW9C@tvaME5*?(%5{eMo2<Q1<WtN)K4QuzWd#T2b1eKDmo>#nCS`AL*bqXz&00dm?{ From 13c4d11740057053a31f69ab6937fedcd641a975 Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Tue, 6 Feb 2024 23:56:31 +0800 Subject: [PATCH 05/25] Suggestion for function --- rules/no-anonymous-default-export.js | 22 +++- test/no-anonymous-default-export.mjs | 55 +++++++-- .../no-anonymous-default-export.mjs.md | 113 +++++++++++++----- .../no-anonymous-default-export.mjs.snap | Bin 920 -> 1128 bytes 4 files changed, 145 insertions(+), 45 deletions(-) diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js index b7e5f14d00..adf75b1cf3 100644 --- a/rules/no-anonymous-default-export.js +++ b/rules/no-anonymous-default-export.js @@ -1,7 +1,11 @@ 'use strict'; const path = require('node:path') -const {getFunctionHeadLocation, getFunctionNameWithKind} = require('@eslint-community/eslint-utils'); +const { + getFunctionHeadLocation, + getFunctionNameWithKind, + isOpeningParenToken, +} = require('@eslint-community/eslint-utils'); const { isIdentifierName, } = require('@babel/helper-validator-identifier'); @@ -43,7 +47,7 @@ function getSuggestionName(node, filename, sourceCode) { return name; } -function addName(fixer, node, name, sourceCode) { +function * addName(fixer, node, name, sourceCode) { switch (node.type) { case 'ClassDeclaration': { const classToken = sourceCode.getFirstToken(node); @@ -51,7 +55,19 @@ function addName(fixer, node, name, sourceCode) { expected: {type: 'Keyword', value: 'class'}, ruleId: 'no-anonymous-default-export', }) - return fixer.insertTextAfter(classToken, ` ${name}`); + yield fixer.insertTextAfter(classToken, ` ${name}`); + return; + } + case 'FunctionDeclaration': { + const openingParenthesisToken = sourceCode.getFirstToken( + node, + isOpeningParenToken, + ); + yield fixer.insertTextBefore( + openingParenthesisToken, + `${sourceCode.text.charAt(openingParenthesisToken.range[0] - 1) === ' ' ? '' : ' '}${name} ` + ); + return; } } } diff --git a/test/no-anonymous-default-export.mjs b/test/no-anonymous-default-export.mjs index a856972e00..474d282fa9 100644 --- a/test/no-anonymous-default-export.mjs +++ b/test/no-anonymous-default-export.mjs @@ -63,35 +63,66 @@ test.snapshot({ `, filename: '/path/to/foo.js', }, - - { code: 'export default function () {}', filename: '/path/to/foo.js', }, { - code: 'export default () => {}', + code: 'export default function* () {}', filename: '/path/to/foo.js', }, { - code: 'export default function () {}', - filename: '123.js', + code: 'export default async function* () {}', + filename: '/path/to/foo.js', }, { - code: 'export default function () {}', - filename: '$foo.js', + code: 'export default async function*() {}', + filename: '/path/to/foo.js', }, { - code: 'export default function () {}', - filename: '_foo.js', + code: 'export default async function *() {}', + filename: '/path/to/foo.js', }, { - code: 'export default class {}', + code: 'export default async function * () {}', filename: '/path/to/foo.js', }, { - code: 'export default function () {}', - filename: '/path/to/foo.test.js', + code: 'export default async function * /* comment */ () {}', + filename: '/path/to/foo.js', }, + { + code: outdent` + export default async function * // comment + () {} + `, + filename: '/path/to/foo.js', + }, + + + // { + // code: 'export default () => {}', + // filename: '/path/to/foo.js', + // }, + // { + // code: 'export default function () {}', + // filename: '123.js', + // }, + // { + // code: 'export default function () {}', + // filename: '$foo.js', + // }, + // { + // code: 'export default function () {}', + // filename: '_foo.js', + // }, + // { + // code: 'export default class {}', + // filename: '/path/to/foo.js', + // }, + // { + // code: 'export default function () {}', + // filename: '/path/to/foo.test.js', + // }, ], }); diff --git a/test/snapshots/no-anonymous-default-export.mjs.md b/test/snapshots/no-anonymous-default-export.mjs.md index a056fc9d5d..187f9dd0a4 100644 --- a/test/snapshots/no-anonymous-default-export.mjs.md +++ b/test/snapshots/no-anonymous-default-export.mjs.md @@ -356,14 +356,18 @@ Generated by [AVA](https://avajs.dev). `β > 1 | export default function () {}β | ^^^^^^^^^ The function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | export default function foo () {}β ` -## invalid(18): export default () => {} +## invalid(18): export default function* () {} > Input `β - 1 | export default () => {}β + 1 | export default function* () {}β ` > Filename @@ -375,79 +379,95 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `β - > 1 | export default () => {}β - | ^^ The arrow function should be named.β + > 1 | export default function* () {}β + | ^^^^^^^^^^ The generator function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | export default function* foo () {}β ` -## invalid(19): export default function () {} +## invalid(19): export default async function* () {} > Input `β - 1 | export default function () {}β + 1 | export default async function* () {}β ` > Filename `β - 123.jsβ + /path/to/foo.jsβ ` > Error 1/1 `β - > 1 | export default function () {}β - | ^^^^^^^^^ The function should be named.β + > 1 | export default async function* () {}β + | ^^^^^^^^^^^^^^^^ The async generator function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | export default async function* foo () {}β ` -## invalid(20): export default function () {} +## invalid(20): export default async function*() {} > Input `β - 1 | export default function () {}β + 1 | export default async function*() {}β ` > Filename `β - $foo.jsβ + /path/to/foo.jsβ ` > Error 1/1 `β - > 1 | export default function () {}β - | ^^^^^^^^^ The function should be named.β + > 1 | export default async function*() {}β + | ^^^^^^^^^^^^^^^ The async generator function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | export default async function* foo () {}β ` -## invalid(21): export default function () {} +## invalid(21): export default async function *() {} > Input `β - 1 | export default function () {}β + 1 | export default async function *() {}β ` > Filename `β - _foo.jsβ + /path/to/foo.jsβ ` > Error 1/1 `β - > 1 | export default function () {}β - | ^^^^^^^^^ The function should be named.β + > 1 | export default async function *() {}β + | ^^^^^^^^^^^^^^^^ The async generator function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | export default async function * foo () {}β ` -## invalid(22): export default class {} +## invalid(22): export default async function * () {} > Input `β - 1 | export default class {}β + 1 | export default async function * () {}β ` > Filename @@ -459,31 +479,64 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `β - > 1 | export default class {}β - | ^^^^^ The class should be named.β + > 1 | export default async function * () {}β + | ^^^^^^^^^^^^^^^^^^^^^ The async generator function should be named.β β --------------------------------------------------------------------------------β - Suggestion 1/1: Name it as \`Foo\`.β - 1 | export default class Foo {}β + Suggestion 1/1: Name it as \`foo\`.β + 1 | export default async function * foo () {}β ` -## invalid(23): export default function () {} +## invalid(23): export default async function * /* comment */ () {} > Input `β - 1 | export default function () {}β + 1 | export default async function * /* comment */ () {}β ` > Filename `β - /path/to/foo.test.jsβ + /path/to/foo.jsβ ` > Error 1/1 `β - > 1 | export default function () {}β - | ^^^^^^^^^ The function should be named.β + > 1 | export default async function * /* comment */ () {}β + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The async generator function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | export default async function * /* comment */ foo () {}β + ` + +## invalid(24): export default async function * // comment () {} + +> Input + + `β + 1 | export default async function * // commentβ + 2 | () {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default async function * // commentβ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^β + > 2 | () {}β + | ^ The async generator function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | export default async function * // commentβ + 2 | foo () {}β ` diff --git a/test/snapshots/no-anonymous-default-export.mjs.snap b/test/snapshots/no-anonymous-default-export.mjs.snap index e8970667c332c635e4837acc67c9a1fe9560d973..b890ebbd2b623b40111a4cc4795862f09cdd6282 100644 GIT binary patch literal 1128 zcmV-u1eg0kRzV<BZeeh9Xm4~Nb~6eC0GZw{OU$owgsT1<xvVf;=NH=EFC)%=`T4p5 z)@MZqs~?L900000000B+nNd&EP!z{EjGD~&fX0OQAO}H&!YJ)P1q78u5)xxf)I>sL zblV*pcD+m6DMs`GK7nt(%C|E<`K0l|n2q(0v)<d@l`?Um4}=H$=brQX^|n3zTFjX= z|Hk<;a6sI$Ym%Muvh~(5%Y`v*d>+V7mD(;8NYSX7E);84-YruL#>U~p$FgG?Ri{K< zXYZg;FkItR=3L@pqJAXLC;F4OQUDt428X1GY2=7WR;_ByZN^klOfIz~5d#3Q3vI`S zcfgAhX`SJeXw57@j(}xUNMWkEhVo<ErZ#A*=JjIO>xJ&`Mcy<VhueiTTK*uv3*PCx z`tvB@CBJ?aAg;Vo_2J)jUUJ4?^4K^mE=4cdJDpdui2^qGC9?o-$&IQTB^$O)-$lSZ z;nhA9puQrKe-@Q+J4Aj(tp6tzR1MKzk-7kyo!KH5u??5n5xS##-I?`w$8g?T`OxiQ z4iz@R?+`DF*QGra=JLD54GZfO>sH&@(w)-0PTdLZl+dOHR9;%DR{>6aJ{s4zmyl|g ztXjU79Y-^E|G6t_o_HIQy8qyi$QNK+jA%>38&l()sM{0Un(xWnjrQZZ8x5j>{*+oZ z+>+{2wMgmIw$nVNv{E)ny@2Lfzmag?1;QQkCYDOae59V&wzi1V;G(J8JUlfj1j=>V zu(?9%=2TGsRw!-t(9iFt$8S!+kB4s(b^k`dzmJpNFGTNK5WOCP7r<_WJrz%P_2L^w z0oM?|bk4Aa2-lJc#PCOtT!G7m9m;Xpu!F9{7E8`6&Oc(AJ!5%HmQt^1U12$K#`2gf zIq#k)$Z`|~4ER`TdL{tp1%&fw@8Hz*j0{mt&&WaLyi}hcR6qe&5LD&tv9*K8))qm| zi~k7{96|wCTLjmOl)gSg*a5;thOj=7Fo|0~VY2=sI|;@5uk}X|dA3gwnx*E-M7b#d zy$i3LYsveFd^#DnuBE_r{U>5%vrLUB02&EF?kLP1&Ok;q@!RiYAQL|8i|E5;<ij7q zP7vpZgznNWinj%}#3H4ruK`nUjWbvBa(r`2kMImaGa9^_fB|Jh#McqxOUYowk^@cY zQTeIEtw``@(`k(}hr$zJA@zAgYf@%99Y1>=u^$$&=dU8ffJhVVQ)5GW$>B~+vk#q| z@m5=$K#2$+ca*q|m_|kn$r%ypqfn3g!1f58Ga_sMN)+E70kIo_9zgm=q>O+Ll;{yB zKt>9kNx_-5g?-obtayMpYEp{>Pyk}TeLO;H=yGZtU5b<+y(GzD@!_I8WTJ2ec|K88 z1@g2~A(jh@D$-^ZF<y{#niCzPKv^WvGs(S$yC`{;dQPhLhJ@?IrWrbCr07pqS-QY2 u{xm~AxA}S<w_e*wuXSm?j;^aStC|Cmqe}LWW$nBIO#2HI>whs8DF6V$&?&e8 literal 920 zcmV;J184j}RzV<BZeeh9Xm4~Nb~6eC0DO@K(7ph>g&EQflUqvAqBMY4JxA4*vZv~) zPZzkt${&je00000000B+nM-feKoo@&5HIfv0<oeOTA)dr20IjJp;=U-5)xv=vqChT zB$LMAdLnxQMHCk8FJQ%*{yW5q6^Ipbh;42?9y?BA(kfn5S#(Z(&v)i^^R-bmSnZAd zWuJ1L8+1FTn{SDs*Jsq+6431yvpCdggR~6}jka0iIx}G=2OmD_wn<uclW}`@zg{Pt zyeJ*doXR*)_C#hPdsP8YVMi{aP=i#dK_8f{Ht))`kW5u6$B+R4*ntDjy8FPBCiO?y zP1ZK*P^Dm!En1)NzJq?>vX}*GQFXnTa=p-kUepX?+d>x#==CSXF1W)*_1BQVQ*r&C zKzQYys{j69?<JRlCC}twxtzRYcetoz0|~5)OZEhWC3mXsluRs(y-R?5)~)@fB>MTV z@Gqbeu1ADFA0GctNT?MN|9q?o&~;{$n$#kkSqa=Jy6!9l-68gSvlh8LETY0@#SV$2 zL@w<jF)nsVC>G_E=hlJIv7J&~r*1_$6`H2IsJucfuOylJ{IA@x-ApXI;zlcASwAuJ z_Mh8f=7ldqvGyM<l6V3hkO^Co@WRv?lXQ9VmgYNgcB8#P?M9PGU_vRj2yYfSD>fLL ze{FY%G*@+lIt6q`{YHWN9ul}dH!-C!;757f-rS^ihl^TNm*5fEqM$ppVPloCjd_`W ztBm;`2Kila`7MU<6XBaf?q8C8{UGW6LiE1L=p7+=5_Z$xsrW{!lWz(MoJaTyRbquA zT+3z<!yiXv2Cfh*lH&@oWb@ExDY)YNCzh2l%RX7gx}v4Ra(2wJPnLqa=MY(5Ljo5A zELE)}!Fdwl{CRY6s#+-yQB^C&gDSXG4-qOLfwKr|etc~0;n?aE6kPm=NboWeIOh|5 z*<kF|7-0_xmpz0|N5Y`o88GMksmwvc`RE)$;<J5-(3HDx7N)BJXenGd*RuBz`9e18 zy~@(}IwZlURJ>>;0nky9Whd`tN6?T7>-g>U(vXSn^(DK+j?B*p{t7DS+yuK>J*}X! zK2|c@Mxqt(r%uo;NhfvBkjiOAb_^Vyta-+1f<{F;#yv+WXO!u~F-v{tdidpYxXx7$ uhjZTgrlorcA9tn)bUyT>FSvQ9w8u{)nF|;ur#2tqiSP#|`N=dzApih`bGXa^ From 8e48b4cbc0e0c1d5ffc2867960fe9a2a743344ea Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Wed, 7 Feb 2024 00:12:07 +0800 Subject: [PATCH 06/25] Arrow function --- rules/no-anonymous-default-export.js | 32 +- test/no-anonymous-default-export.mjs | 87 +++-- .../no-anonymous-default-export.mjs.md | 323 +++++++++++++++++- .../no-anonymous-default-export.mjs.snap | Bin 1128 -> 1648 bytes 4 files changed, 401 insertions(+), 41 deletions(-) diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js index adf75b1cf3..dc12de479f 100644 --- a/rules/no-anonymous-default-export.js +++ b/rules/no-anonymous-default-export.js @@ -12,8 +12,7 @@ const { const getClassHeadLocation = require('./utils/get-class-head-location.js'); const {upperFirst, camelCase} = require('./utils/lodash.js'); const assertToken = require('./utils/assert-token.js'); -const {} = require('./ast/index.js'); -const {} = require('./fix/index.js'); +const {getParenthesizedRange} = require('./utils/parentheses.js'); const { getScopes, avoidCapture, @@ -47,7 +46,7 @@ function getSuggestionName(node, filename, sourceCode) { return name; } -function * addName(fixer, node, name, sourceCode) { +function addName(fixer, node, name, sourceCode) { switch (node.type) { case 'ClassDeclaration': { const classToken = sourceCode.getFirstToken(node); @@ -55,19 +54,38 @@ function * addName(fixer, node, name, sourceCode) { expected: {type: 'Keyword', value: 'class'}, ruleId: 'no-anonymous-default-export', }) - yield fixer.insertTextAfter(classToken, ` ${name}`); - return; + return fixer.insertTextAfter(classToken, ` ${name}`); } case 'FunctionDeclaration': { const openingParenthesisToken = sourceCode.getFirstToken( node, isOpeningParenToken, ); - yield fixer.insertTextBefore( + return fixer.insertTextBefore( openingParenthesisToken, `${sourceCode.text.charAt(openingParenthesisToken.range[0] - 1) === ' ' ? '' : ' '}${name} ` ); - return; + } + case 'ArrowFunctionExpression': { + const [exportDeclarationStart] = node.parent.range; + const [arrowFunctionStart] = getParenthesizedRange(node, sourceCode); + + const originalExportDefaultText = sourceCode.text.slice(exportDeclarationStart, arrowFunctionStart) + const shouldInsertSpaceAfterDefault = + !originalExportDefaultText.endsWith(' ') + && !originalExportDefaultText.endsWith('\n') + && !originalExportDefaultText.endsWith('\t') + + return [ + fixer.replaceTextRange( + [exportDeclarationStart, arrowFunctionStart], + `const ${name} = `, + ), + fixer.insertTextAfter( + node.parent, + `\n${originalExportDefaultText}${shouldInsertSpaceAfterDefault ? ' ' : ''}${name};` + ), + ] } } } diff --git a/test/no-anonymous-default-export.mjs b/test/no-anonymous-default-export.mjs index 474d282fa9..f2051fb405 100644 --- a/test/no-anonymous-default-export.mjs +++ b/test/no-anonymous-default-export.mjs @@ -24,6 +24,8 @@ test.snapshot({ 'export default async function () {}', 'export default async function * () {}', 'export default async () => {}', + + // `ClassDeclaration` { code: 'export default class {}', filename: '/path/to/foo.js', @@ -56,6 +58,10 @@ test.snapshot({ code: 'export default class {}', filename: '/path/to/[foo].js', }, + { + code: 'export default class {}', + filename: '/path/to/class.js', + }, { code: outdent` let Foo, Foo_, foo, foo_ @@ -63,6 +69,9 @@ test.snapshot({ `, filename: '/path/to/foo.js', }, + + + // `FunctionDeclaration` { code: 'export default function () {}', filename: '/path/to/foo.js', @@ -98,31 +107,59 @@ test.snapshot({ `, filename: '/path/to/foo.js', }, + { + code: outdent` + let Foo, Foo_, foo, foo_ + export default async function * () {} + `, + filename: '/path/to/foo.js', + }, - - // { - // code: 'export default () => {}', - // filename: '/path/to/foo.js', - // }, - // { - // code: 'export default function () {}', - // filename: '123.js', - // }, - // { - // code: 'export default function () {}', - // filename: '$foo.js', - // }, - // { - // code: 'export default function () {}', - // filename: '_foo.js', - // }, - // { - // code: 'export default class {}', - // filename: '/path/to/foo.js', - // }, - // { - // code: 'export default function () {}', - // filename: '/path/to/foo.test.js', - // }, + // `ArrowFunctionExpression` + { + code: 'export default () => {}', + filename: '/path/to/foo.js', + }, + { + code: 'export default async () => {}', + filename: '/path/to/foo.js', + }, + { + code: 'export default () => {};', + filename: '/path/to/foo.js', + }, + { + code: 'export default() => {}', + filename: '/path/to/foo.js', + }, + { + code: 'export default foo => {}', + filename: '/path/to/foo.js', + }, + { + code: 'export default (( () => {} ))', + filename: '/path/to/foo.js', + }, + { + code: '/* comment 1 */ export /* comment 2 */ default /* comment 3 */ () => {}', + filename: '/path/to/foo.js', + }, + { + code: outdent` + // comment 1 + export + // comment 2 + default + // comment 3 + () => {}`, + filename: '/path/to/foo.js', + }, + { + code: outdent` + let Foo, Foo_, foo, foo_ + export default async () => {} + `, + filename: '/path/to/foo.js', + }, ], }); diff --git a/test/snapshots/no-anonymous-default-export.mjs.md b/test/snapshots/no-anonymous-default-export.mjs.md index 187f9dd0a4..7839c07bac 100644 --- a/test/snapshots/no-anonymous-default-export.mjs.md +++ b/test/snapshots/no-anonymous-default-export.mjs.md @@ -309,7 +309,32 @@ Generated by [AVA](https://avajs.dev). 1 | export default class Foo {}β ` -## invalid(16): let Foo, Foo_, foo, foo_ export default class {} +## invalid(16): export default class {} + +> Input + + `β + 1 | export default class {}β + ` + +> Filename + + `β + /path/to/class.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default class {}β + | ^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`Class\`.β + 1 | export default class Class {}β + ` + +## invalid(17): let Foo, Foo_, foo, foo_ export default class {} > Input @@ -337,7 +362,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default class Foo__ {}β ` -## invalid(17): export default function () {} +## invalid(18): export default function () {} > Input @@ -362,7 +387,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default function foo () {}β ` -## invalid(18): export default function* () {} +## invalid(19): export default function* () {} > Input @@ -387,7 +412,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default function* foo () {}β ` -## invalid(19): export default async function* () {} +## invalid(20): export default async function* () {} > Input @@ -412,7 +437,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function* foo () {}β ` -## invalid(20): export default async function*() {} +## invalid(21): export default async function*() {} > Input @@ -437,7 +462,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function* foo () {}β ` -## invalid(21): export default async function *() {} +## invalid(22): export default async function *() {} > Input @@ -462,7 +487,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function * foo () {}β ` -## invalid(22): export default async function * () {} +## invalid(23): export default async function * () {} > Input @@ -487,7 +512,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function * foo () {}β ` -## invalid(23): export default async function * /* comment */ () {} +## invalid(24): export default async function * /* comment */ () {} > Input @@ -512,7 +537,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function * /* comment */ foo () {}β ` -## invalid(24): export default async function * // comment () {} +## invalid(25): export default async function * // comment () {} > Input @@ -540,3 +565,283 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function * // commentβ 2 | foo () {}β ` + +## invalid(26): let Foo, Foo_, foo, foo_ export default async function * () {} + +> Input + + `β + 1 | let Foo, Foo_, foo, foo_β + 2 | export default async function * () {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + 1 | let Foo, Foo_, foo, foo_β + > 2 | export default async function * () {}β + | ^^^^^^^^^^^^^^^^^ The async generator function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo__\`.β + 1 | let Foo, Foo_, foo, foo_β + 2 | export default async function * foo__ () {}β + ` + +## invalid(27): export default () => {} + +> Input + + `β + 1 | export default () => {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default () => {}β + | ^^ The arrow function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | const foo = () => {}β + 2 | export default foo;β + ` + +## invalid(28): export default async () => {} + +> Input + + `β + 1 | export default async () => {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default async () => {}β + | ^^ The async arrow function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | const foo = async () => {}β + 2 | export default foo;β + ` + +## invalid(29): export default () => {}; + +> Input + + `β + 1 | export default () => {};β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default () => {};β + | ^^ The arrow function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | const foo = () => {};β + 2 | export default foo;β + ` + +## invalid(30): export default() => {} + +> Input + + `β + 1 | export default() => {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default() => {}β + | ^^ The arrow function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | const foo = () => {}β + 2 | export default foo;β + ` + +## invalid(31): export default foo => {} + +> Input + + `β + 1 | export default foo => {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default foo => {}β + | ^^ The arrow function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo_\`.β + 1 | const foo_ = foo => {}β + 2 | export default foo_;β + ` + +## invalid(32): export default (( () => {} )) + +> Input + + `β + 1 | export default (( () => {} ))β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default (( () => {} ))β + | ^^ The arrow function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | const foo = (( () => {} ))β + 2 | export default foo;β + ` + +## invalid(33): /* comment 1 */ export /* comment 2 */ default /* comment 3 */ () => {} + +> Input + + `β + 1 | /* comment 1 */ export /* comment 2 */ default /* comment 3 */ () => {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | /* comment 1 */ export /* comment 2 */ default /* comment 3 */ () => {}β + | ^^ The arrow function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | /* comment 1 */ const foo = () => {}β + 2 | export /* comment 2 */ default /* comment 3 */ foo;β + ` + +## invalid(34): // comment 1 export // comment 2 default // comment 3 () => {} + +> Input + + `β + 1 | // comment 1β + 2 | exportβ + 3 | // comment 2β + 4 | defaultβ + 5 | // comment 3β + 6 | () => {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + 1 | // comment 1β + 2 | exportβ + 3 | // comment 2β + 4 | defaultβ + 5 | // comment 3β + > 6 | () => {}β + | ^^ The arrow function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | // comment 1β + 2 | const foo = () => {}β + 3 | exportβ + 4 | // comment 2β + 5 | defaultβ + 6 | // comment 3β + 7 | foo;β + ` + +## invalid(35): let Foo, Foo_, foo, foo_ export default async () => {} + +> Input + + `β + 1 | let Foo, Foo_, foo, foo_β + 2 | export default async () => {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + 1 | let Foo, Foo_, foo, foo_β + > 2 | export default async () => {}β + | ^^ The async arrow function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo__\`.β + 1 | let Foo, Foo_, foo, foo_β + 2 | const foo__ = async () => {}β + 3 | export default foo__;β + ` diff --git a/test/snapshots/no-anonymous-default-export.mjs.snap b/test/snapshots/no-anonymous-default-export.mjs.snap index b890ebbd2b623b40111a4cc4795862f09cdd6282..a9720d4be7b20c933893983ab3615352a0187a58 100644 GIT binary patch literal 1648 zcmV-$29NncRzV<BZeeh9Xm4~Nb~6eC02@I$md=RNi8?s<s!b{`mjSuN$pcb?T_A=G zK5WuEI3J4$00000000B+n_X|)R2avbqA_8#i}5l|2+?PB9gX|q+HO16&;lz|nwX{u zhQyd?<|a;);pRk+%Z4aibf17b#2vfiqaiL3S0FAX<TO6<W1n+;>^Ny=)fZKj){oEg z{Ql>~|8w$NW6vSAZ@a(DKC``+=h#omt@d}8)2h$w<qfc(bcpLg-ELTijt7mycFk*% zHq4jdhaX$rw$<r2iPt@TR<B#0^_BV3)cGm@DxI6USejD+bT|?RQEbQBvmN_ZyL0IE z!*o!XJ!MNG3;@6pM6TW7f_qJSa7VXE4xKve+0eEQ?D}%Q4XsaIm$;y7dQgkmpcY2F z7B$D}c9~UJLd~CHS0T8am46Kd_>!GJ4ZzR5m-Wg2rBB(6r#xSV&8_Sy2e-3Qc2Iy_ zcFHsWGv!{^y_7B2C66=UUI=nu6-Zy@iGK~H@Lq!WRlfXxLV-F7@>iugK)*8kcH4F> zkGL7CqXpGji&w|$e&4Po4i7g_VhijFu|lz`bc}*|>?$#XB~^-6D{{AVrSzau>xq@( zs;Pp~Tav1kKvO@5!%ZJgNtH`hTCtK1BQrYxT;~;!KMYCDKR8I{4j2i;8<OzA)Vn9^ z@I;5^_hn|Ir+LjrGbq4CMeA5zQ}c+{AY}Pbw|`4>r{&mw0{y%GLxTI0Be)?aF=Z*| zOZnn(f8Xx*xagX`0e7qe8(KbXc(_Bz!(~zZb_f~NFwXDYfZq)cKNh}4RQ-1ZkI$3d zzlh!+B6<aaCt!D#u8LR2+WBTtfHx7or9I2#BD`OkLJa>dNDsVexrrQaTCS)c4p=f? zaZZV4^^E0^ETvx2#=>&pjOCCl8SkDWWO)q*xEy1t8>Rr~%LwN`#lfi?rVLTtFy){! zUaCh36;OcJ5LESS*_vY6Iv~h+@gE_<D=5J01A-44gnV;`FcU(CBXJrCdpGeBK1T@u zDgwf7zY$`H+qjZ(jGGjr?~ORN=W}25e^eKt;s5HdB<1<uMtHXRZR5pN0E{s>2lq=K zAo@$Cq;_oy+w~%d!_TNn#gPR-FM>!rD%B3dJ>nU+Pt*8n$(C(KJzPL~c+MFO^4t#^ zFZ~98bf-;h5Q6F|*u2mg_EHchW;X|fR}q?P;?@X!=8TBnLWo~2i4jZs($YH~6Ng)s z;7vCf42C0xjeIWk4Mb~EW|JX*_6A}<%VE!MMS=n{ZA?sz8lovDYhs0Jg5hjM!f_;# zVUJGDTM;Wr5m)3Ck!f$Q;CdL05e#=My4jcC7y-E}0xdwMuSzKbQb?j8ngAJ57*rGt zn=NU3I#9)jh@&pmH~<wO_vzzfBn?AO8sVl$>7z&@IY~ZQC?8RwFs!?nP&5^4<lw+= zd!TAO+1x^mE0UUKgw9bwRV1Lhl4A?AQSwqMoT#D&NtPFNGmPW|MJi|-jn2^)+s%-V z+kd^zTV9WlydFr)E8MPhs_GjeVM!K9Wl>%dO8bl|Z9Ro=COZ{=jdXE4lZhjLkSn7K zA0rhuvw3RcJRUZ71!gwjSWB>KH9?ZpkvAB}+~Nn^QaSRXqiq@Ga|y}kJZBKg>wNC% zjXpKf?s~luWiy-&gL;FIO0wB%Fw9ooA;wf@Yw{t+jHH(l=^5d4HHyQJlfgcgUs?ss zQ3WvE*dT5t4j+}j1mX@}$&veI#Ql|o9$qO{7q4U>JoutS+<)bFZkgkpBk0v{AiC$+ zbd$RC3yF4^zH73+0_8_%vz6+*^!^;_zK!T!;O(B!Cv%7ENhMs3Bd)?G%7_iQDltc! z3~zLPo(c%c<&1MQ4w579ImG)CZ>+|T7tGO<ik;oDqiLn>-uEbY-~SA`7P{|S^dp5n zHvEr+$f3{8zVE{s4R#URyZuateB3Bje7_?#{Tiq#x0Z?*hbgX!mua+Q$@7tPHHC_% z{)XurwIQcWr_a$s&!G>|LJ#2!*+sId2f2oxf^t#-O#F940a%5j;JFIG8vX}U0a!nA ztnwCj<a=+Wk+gmbx1I`q@&y|&14pxFxI(M(3az0Et;hLZha<6wx2cHNQk!&q@qUhE u^T`kf&j`ecde(Gp7*nnguj29+++Z14WxcJN?8P8sHTXa9RF2C4K>z@B8W*ns literal 1128 zcmV-u1eg0kRzV<BZeeh9Xm4~Nb~6eC0GZw{OU$owgsT1<xvVf;=NH=EFC)%=`T4p5 z)@MZqs~?L900000000B+nNd&EP!z{EjGD~&fX0OQAO}H&!YJ)P1q78u5)xxf)I>sL zblV*pcD+m6DMs`GK7nt(%C|E<`K0l|n2q(0v)<d@l`?Um4}=H$=brQX^|n3zTFjX= z|Hk<;a6sI$Ym%Muvh~(5%Y`v*d>+V7mD(;8NYSX7E);84-YruL#>U~p$FgG?Ri{K< zXYZg;FkItR=3L@pqJAXLC;F4OQUDt428X1GY2=7WR;_ByZN^klOfIz~5d#3Q3vI`S zcfgAhX`SJeXw57@j(}xUNMWkEhVo<ErZ#A*=JjIO>xJ&`Mcy<VhueiTTK*uv3*PCx z`tvB@CBJ?aAg;Vo_2J)jUUJ4?^4K^mE=4cdJDpdui2^qGC9?o-$&IQTB^$O)-$lSZ z;nhA9puQrKe-@Q+J4Aj(tp6tzR1MKzk-7kyo!KH5u??5n5xS##-I?`w$8g?T`OxiQ z4iz@R?+`DF*QGra=JLD54GZfO>sH&@(w)-0PTdLZl+dOHR9;%DR{>6aJ{s4zmyl|g ztXjU79Y-^E|G6t_o_HIQy8qyi$QNK+jA%>38&l()sM{0Un(xWnjrQZZ8x5j>{*+oZ z+>+{2wMgmIw$nVNv{E)ny@2Lfzmag?1;QQkCYDOae59V&wzi1V;G(J8JUlfj1j=>V zu(?9%=2TGsRw!-t(9iFt$8S!+kB4s(b^k`dzmJpNFGTNK5WOCP7r<_WJrz%P_2L^w z0oM?|bk4Aa2-lJc#PCOtT!G7m9m;Xpu!F9{7E8`6&Oc(AJ!5%HmQt^1U12$K#`2gf zIq#k)$Z`|~4ER`TdL{tp1%&fw@8Hz*j0{mt&&WaLyi}hcR6qe&5LD&tv9*K8))qm| zi~k7{96|wCTLjmOl)gSg*a5;thOj=7Fo|0~VY2=sI|;@5uk}X|dA3gwnx*E-M7b#d zy$i3LYsveFd^#DnuBE_r{U>5%vrLUB02&EF?kLP1&Ok;q@!RiYAQL|8i|E5;<ij7q zP7vpZgznNWinj%}#3H4ruK`nUjWbvBa(r`2kMImaGa9^_fB|Jh#McqxOUYowk^@cY zQTeIEtw``@(`k(}hr$zJA@zAgYf@%99Y1>=u^$$&=dU8ffJhVVQ)5GW$>B~+vk#q| z@m5=$K#2$+ca*q|m_|kn$r%ypqfn3g!1f58Ga_sMN)+E70kIo_9zgm=q>O+Ll;{yB zKt>9kNx_-5g?-obtayMpYEp{>Pyk}TeLO;H=yGZtU5b<+y(GzD@!_I8WTJ2ec|K88 z1@g2~A(jh@D$-^ZF<y{#niCzPKv^WvGs(S$yC`{;dQPhLhJ@?IrWrbCr07pqS-QY2 u{xm~AxA}S<w_e*wuXSm?j;^aStC|Cmqe}LWW$nBIO#2HI>whs8DF6V$&?&e8 From 1d36811db83e4cfc1515832132ee5a190a73be37 Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Wed, 7 Feb 2024 00:24:56 +0800 Subject: [PATCH 07/25] decorator --- rules/no-anonymous-default-export.js | 11 ++- test/no-anonymous-default-export.mjs | 52 +++++++++++- .../no-anonymous-default-export.mjs.md | 75 ++++++++++++++++++ .../no-anonymous-default-export.mjs.snap | Bin 1648 -> 1783 bytes 4 files changed, 131 insertions(+), 7 deletions(-) diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js index dc12de479f..a8edd36202 100644 --- a/rules/no-anonymous-default-export.js +++ b/rules/no-anonymous-default-export.js @@ -11,7 +11,6 @@ const { } = require('@babel/helper-validator-identifier'); const getClassHeadLocation = require('./utils/get-class-head-location.js'); const {upperFirst, camelCase} = require('./utils/lodash.js'); -const assertToken = require('./utils/assert-token.js'); const {getParenthesizedRange} = require('./utils/parentheses.js'); const { getScopes, @@ -27,6 +26,7 @@ const messages = { }; const EXPECTED_FUNCTION_DESCRIPTION_SUFFIX = ' \'default\'' +const isClassKeywordToken = token => token.type === 'Keyword' && token.value === 'class'; function getSuggestionName(node, filename, sourceCode) { if (filename === '<input>' || filename === '<text>') { @@ -49,11 +49,10 @@ function getSuggestionName(node, filename, sourceCode) { function addName(fixer, node, name, sourceCode) { switch (node.type) { case 'ClassDeclaration': { - const classToken = sourceCode.getFirstToken(node); - assertToken(classToken, { - expected: {type: 'Keyword', value: 'class'}, - ruleId: 'no-anonymous-default-export', - }) + const lastDecorator = node.decorators?.at(-1) + const classToken = lastDecorator + ? sourceCode.getTokenAfter(lastDecorator, isClassKeywordToken) + : sourceCode.getFirstToken(node, isClassKeywordToken); return fixer.insertTextAfter(classToken, ` ${name}`); } case 'FunctionDeclaration': { diff --git a/test/no-anonymous-default-export.mjs b/test/no-anonymous-default-export.mjs index f2051fb405..f948603b66 100644 --- a/test/no-anonymous-default-export.mjs +++ b/test/no-anonymous-default-export.mjs @@ -1,5 +1,5 @@ import outdent from 'outdent'; -import {getTester} from './utils/test.mjs'; +import {getTester, parsers} from './utils/test.mjs'; const {test} = getTester(import.meta); @@ -163,3 +163,53 @@ test.snapshot({ }, ], }); + +// Decorators +test.snapshot({ + testerOptions: { + parser: parsers.babel, + parserOptions: { + babelOptions: { + parserOpts: { + plugins: [ + ['decorators', {decoratorsBeforeExport: true}], + ], + }, + }, + }, + }, + valid: [], + invalid: [ + { + code: '@decorator export default class {}', + filename: '/path/to/foo.js', + }, + { + code: '@decorator @decorator(class {}) export default class {}', + filename: '/path/to/foo.js', + }, + ], +}) + +// Decorators +test.snapshot({ + testerOptions: { + parser: parsers.babel, + parserOptions: { + babelOptions: { + parserOpts: { + plugins: [ + ['decorators', {decoratorsBeforeExport: false}], + ], + }, + }, + }, + }, + valid: [], + invalid: [ + { + code: 'export default @decorator(class {}) class {}', + filename: '/path/to/foo.js', + }, + ] +}); diff --git a/test/snapshots/no-anonymous-default-export.mjs.md b/test/snapshots/no-anonymous-default-export.mjs.md index 7839c07bac..9bacd2cfd3 100644 --- a/test/snapshots/no-anonymous-default-export.mjs.md +++ b/test/snapshots/no-anonymous-default-export.mjs.md @@ -845,3 +845,78 @@ Generated by [AVA](https://avajs.dev). 2 | const foo__ = async () => {}β 3 | export default foo__;β ` + +## invalid(1): @decorator export default class {} + +> Input + + `β + 1 | @decorator export default class {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | @decorator export default class {}β + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`Foo\`.β + 1 | @decorator export default class Foo {}β + ` + +## invalid(2): @decorator @decorator(class {}) export default class {} + +> Input + + `β + 1 | @decorator @decorator(class {}) export default class {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | @decorator @decorator(class {}) export default class {}β + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`Foo\`.β + 1 | @decorator @decorator(class {}) export default class Foo {}β + ` + +## invalid(1): export default @decorator(class {}) class {} + +> Input + + `β + 1 | export default @decorator(class {}) class {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default @decorator(class {}) class {}β + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`Foo\`.β + 1 | export default @decorator(class {}) class Foo {}β + ` diff --git a/test/snapshots/no-anonymous-default-export.mjs.snap b/test/snapshots/no-anonymous-default-export.mjs.snap index a9720d4be7b20c933893983ab3615352a0187a58..d3c4070cbe3fe7c4eaa69284759423ead3423f43 100644 GIT binary patch literal 1783 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 Zid(~+t4<p<>KSuL`5&=H&U=GL002p^a83XK literal 1648 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 From 139634ae4adf2e9f115e3e6766dc8c9bb95657e5 Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Wed, 7 Feb 2024 00:35:06 +0800 Subject: [PATCH 08/25] Docs / lints --- docs/rules/no-anonymous-default-export.md | 23 ++++++- test/no-anonymous-default-export.mjs | 61 +++++++++--------- .../no-anonymous-default-export.mjs.md | 20 +++--- .../no-anonymous-default-export.mjs.snap | Bin 1783 -> 1784 bytes 4 files changed, 59 insertions(+), 45 deletions(-) diff --git a/docs/rules/no-anonymous-default-export.md b/docs/rules/no-anonymous-default-export.md index e6318f8896..8235a11f95 100644 --- a/docs/rules/no-anonymous-default-export.md +++ b/docs/rules/no-anonymous-default-export.md @@ -7,16 +7,33 @@ <!-- end auto-generated rule header --> <!-- Do not manually modify this header. Run: `npm run fix:eslint-docs` --> -<!-- Remove this comment, add more detailed description. --> +Ensuring that default exports are named helps improve the grepability of the codebase by encouraging the re-use of the same identifier for the module's default export at its declaration site and at its import sites. ## Fail ```js -const foo = 'unicorn'; +export default class {} +``` + +```js +export default function () {} +``` + +```js +export default () => {} ``` ## Pass ```js -const foo = 'π¦'; +export default class Foo {} +``` + +```js +export default function foo () {} +``` + +```js +const foo = () => {}; +export default foo; ``` diff --git a/test/no-anonymous-default-export.mjs b/test/no-anonymous-default-export.mjs index f948603b66..463adbd717 100644 --- a/test/no-anonymous-default-export.mjs +++ b/test/no-anonymous-default-export.mjs @@ -165,51 +165,48 @@ test.snapshot({ }); // Decorators -test.snapshot({ - testerOptions: { - parser: parsers.babel, - parserOptions: { - babelOptions: { - parserOpts: { - plugins: [ - ['decorators', {decoratorsBeforeExport: true}], - ], - }, +const decoratorsBeforeExportOptions = { + parser: parsers.babel, + parserOptions: { + babelOptions: { + parserOpts: { + plugins: [ + ['decorators', {decoratorsBeforeExport: true}], + ], + }, + }, + }, +} +const decoratorsAfterExportOptions = { + parser: parsers.babel, + parserOptions: { + babelOptions: { + parserOpts: { + plugins: [ + ['decorators', {decoratorsBeforeExport: false}], + ], }, }, }, +} +test.snapshot({ valid: [], invalid: [ { code: '@decorator export default class {}', filename: '/path/to/foo.js', + ...decoratorsBeforeExportOptions, + }, + { + code: 'export default @decorator(class {}) class {}', + filename: '/path/to/foo.js', + ...decoratorsAfterExportOptions, }, { code: '@decorator @decorator(class {}) export default class {}', filename: '/path/to/foo.js', + ...decoratorsBeforeExportOptions, }, ], }) -// Decorators -test.snapshot({ - testerOptions: { - parser: parsers.babel, - parserOptions: { - babelOptions: { - parserOpts: { - plugins: [ - ['decorators', {decoratorsBeforeExport: false}], - ], - }, - }, - }, - }, - valid: [], - invalid: [ - { - code: 'export default @decorator(class {}) class {}', - filename: '/path/to/foo.js', - }, - ] -}); diff --git a/test/snapshots/no-anonymous-default-export.mjs.md b/test/snapshots/no-anonymous-default-export.mjs.md index 9bacd2cfd3..02794acc2f 100644 --- a/test/snapshots/no-anonymous-default-export.mjs.md +++ b/test/snapshots/no-anonymous-default-export.mjs.md @@ -871,12 +871,12 @@ Generated by [AVA](https://avajs.dev). 1 | @decorator export default class Foo {}β ` -## invalid(2): @decorator @decorator(class {}) export default class {} +## invalid(2): export default @decorator(class {}) class {} > Input `β - 1 | @decorator @decorator(class {}) export default class {}β + 1 | export default @decorator(class {}) class {}β ` > Filename @@ -888,20 +888,20 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `β - > 1 | @decorator @decorator(class {}) export default class {}β - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The class should be named.β + > 1 | export default @decorator(class {}) class {}β + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ The class should be named.β β --------------------------------------------------------------------------------β Suggestion 1/1: Name it as \`Foo\`.β - 1 | @decorator @decorator(class {}) export default class Foo {}β + 1 | export default @decorator(class {}) class Foo {}β ` -## invalid(1): export default @decorator(class {}) class {} +## invalid(3): @decorator @decorator(class {}) export default class {} > Input `β - 1 | export default @decorator(class {}) class {}β + 1 | @decorator @decorator(class {}) export default class {}β ` > Filename @@ -913,10 +913,10 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `β - > 1 | export default @decorator(class {}) class {}β - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ The class should be named.β + > 1 | @decorator @decorator(class {}) export default class {}β + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The class should be named.β β --------------------------------------------------------------------------------β Suggestion 1/1: Name it as \`Foo\`.β - 1 | export default @decorator(class {}) class Foo {}β + 1 | @decorator @decorator(class {}) export default class Foo {}β ` diff --git a/test/snapshots/no-anonymous-default-export.mjs.snap b/test/snapshots/no-anonymous-default-export.mjs.snap index d3c4070cbe3fe7c4eaa69284759423ead3423f43..8d77ae7865bfe7bc040ebc906d3ac669b2cd239b 100644 GIT binary patch delta 900 zcmV-~1AF}U4fqW*K~_N^Q*L2!b7*gLAa*kf0{}^+ymH9F#1-?1>|t@F`xMOIX?jYy z=uEZvj?R`f*MgBUTmm$uv5=SofBx&OB-Qo3i{#nx+s2EV1u%!;96ZQ;h}56Y$lA3b zY}aXk!^@~h;YcDtCxVC_jk3dVk9fxIvpBw*+_Fu`!v(~{3(jbe=6=v{)vxeJciO}X zA*il`%?pEJF9mTTc5|Tc5|ZYcxHSTwIibXFBZ*(lh$U9^rImL)Mow-`e?f1$$zU=Z zDQx6(RbNAD&8ciMq_4e+w4df^&u)c;fJ7S;BSS-P%5o+aDH9B5t0x=>i3EFeTG~V` zA|kG+5s_$bZ_Ih<ju8xZtar07y)gn(Cju=%Ca)?H0Wpvm6DB|f3X?*?u-RnW(*YGX zk&cE^;{Y^()TfV+5E`Z$e;VPYDDg2)kQ^s32jvz8g<;)AK+!cQk^OzA;ew{~u(^#i zE+{h12%RE8MFh}2#j%CiD0P&^4yxXQ$nm0XhABT#q=Bx}=p44#ZiaeX|Mfa;ydERG z9xCG%ZdW|2d_yFR<QP%btCs?4cPMEqF?=)CsqkyW#oa_Ej`~5ae}oi1K@?V#d1}Kv z9yW9W6B}@>C0Ma2L6SQ1CgYe}^nhC|M_zQaEg?Ra5I*NQgIHSUb5CycDUn9o?Tjev z;cOVHR|qM{%~q3Pw(<@!#xh&whZqwoy?~US5>8ixIQ%#o+DGz>OTY{zfZ@glaSKuL zQTa0<?%;(Kb-#>se}6^N!wcip#R~}(?tW1s>c8?kx5{zO0rcuOk-F#D>dLzFsg$;# zzH70*0_8<#Ypc|E>HR6H`z})V0&n+(KAAgQkE+7OsKiBBM;Wn2E-K8?7Q-9O<tRXq z&nKLtagY@Co<VwF;*Hh#@q#&eRApy(?B2BEcJKRCc+dX~U%3{B=Ue!ZLLZyn$3f)K z=a%pLa7Ke2r0qRFlRh6eh!x-Oh^Aiyno?`2cySox8hK26OD3O>l&dKun)(}-XViwA zGJ`%x4?TxIL=QcL4{{4(RSt3uJq6{I1+ehXlL7{qUat!N!b3N7E~r#qK)@zaZHfI( zAdHzJ3+Ncnq{ewg5VwXol$<s`)H9Zl(w(312*He~JZyZ5<h>b%I!^c$`9YgnlXn<n aNvwt`4KSyOszi0*0QNt2UKiklM*sj+%d4gU delta 899 zcmV-}1AP4W4fhQ)K~_N^Q*L2!b7*gLAa*kf0{|hUza-8B6yDQ}e5mj78hxT6>WnL7 z4`?dW?&kdBO*@e?Tmn>Ov5=Soe}42<lIr^2Me=O;ZR5qw0+>T^4jyDaMC#9HWbN7z zw(B&&;bl~$a3m3+6G6m|M%iJwM?B;9SsY(YZrLW};R52}1!pu!b3bUf>R0%qJ8fcx z5L8#e=7qtqmx4GEyE#yJ2}yHJ+!}$;oKWJok;JcN#1bp|(#ks?BPX|}f1o$rWH1?y z6gKj?s;?on=2SKr(%0TZ+D~(|XSYH^K%$L_k)feCWjPazlnI8j)f0|`M1nm!Eo~we z5fN9^h)A@zH|9Ka#|VZy*1Or4-WUO?6M+^WlUJ39fEY-O2@{|Kg-M}c*le=x>41ux zNJm4daR3@X>eI(Z2n|yWe~oZcl=v7YNRE@2gK~?4!m#clpy(Qu$o{_5a6!{~*xW`M z7ZjOhgiaBlA_C~1;@HA$lsZad2UTxD<akjx!;~K=(m>Z~bPii=H$y$H|9YJ^UXKx8 z50&u>w<{i1z9AAua*QbJ)k}f2JCwAQ7`~b6RQNUG;%*`nNBtmIe?khMAPTF=JhfpS z4;wmxi48c`60BI1AW0p0lX1)~dcZA~BQHAImJpvy2%qzuK`gEFxhFUJlt`oPc1D!- za5fCpD})r}W~<3CTX}~VW0|e;LyQTPUO-Au38$+;9DW=P?IZccC18dUz;I)OxP_?r zsQeiackn`rx?e`Rf4?H>;f3+);)MhXcfTkR^<Vj&Tje<C0DASCNZoU6b!FZ8R7%@V z-?dm@f%2lWwN>i7^!^mpeHW>Ffwy}?pUfSuM^)isRN^A6qm0-h7Zv7ci{XvtauguQ z=M&D+I7o_m&mg@o@y2TWc)=V!s<N{?c5hm7yZ3!6yyt(0Ut9~r^DX>Hp^r`P;~;YA zbIbRAIHSQ1()OO8NuQ4!#ES2CMANSUO{uk1yf}<;jXb8kC6mub%GDGSP5lkaGipOl znL(eUhn_<pqK6*B2f2l?DhIiSo`Q190$BL}lL7{qUDHv=#JYEX%mr1-tHbaq67XiU zsd2)mNC?`hn7qRvBv!+eusNM9sn<aQ*s9>qsW2bHr)m?4zQlg%6vj*uC3H?~QscaX Zid(~+t4<p<>KSuL`5&=H&U=GL001Oev26eV From bbf771ab4376da4adcb2b9e7df282bf1186a9705 Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Wed, 7 Feb 2024 00:39:49 +0800 Subject: [PATCH 09/25] More tests --- test/no-anonymous-default-export.mjs | 16 +++ .../no-anonymous-default-export.mjs.md | 134 +++++++++++++++--- .../no-anonymous-default-export.mjs.snap | Bin 1784 -> 1844 bytes 3 files changed, 131 insertions(+), 19 deletions(-) diff --git a/test/no-anonymous-default-export.mjs b/test/no-anonymous-default-export.mjs index 463adbd717..87fec72714 100644 --- a/test/no-anonymous-default-export.mjs +++ b/test/no-anonymous-default-export.mjs @@ -62,6 +62,22 @@ test.snapshot({ code: 'export default class {}', filename: '/path/to/class.js', }, + { + code: 'export default class {}', + filename: '/path/to/foo.helper.js', + }, + { + code: 'export default class {}', + filename: '/path/to/foo.bar.js', + }, + { + code: 'export default class {}', + filename: '/path/to/foo.test.js', + }, + { + code: 'export default class {}', + filename: '/path/to/.foo.js', + }, { code: outdent` let Foo, Foo_, foo, foo_ diff --git a/test/snapshots/no-anonymous-default-export.mjs.md b/test/snapshots/no-anonymous-default-export.mjs.md index 02794acc2f..a975b40096 100644 --- a/test/snapshots/no-anonymous-default-export.mjs.md +++ b/test/snapshots/no-anonymous-default-export.mjs.md @@ -334,7 +334,103 @@ Generated by [AVA](https://avajs.dev). 1 | export default class Class {}β ` -## invalid(17): let Foo, Foo_, foo, foo_ export default class {} +## invalid(17): export default class {} + +> Input + + `β + 1 | export default class {}β + ` + +> Filename + + `β + /path/to/foo.helper.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default class {}β + | ^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`Foo\`.β + 1 | export default class Foo {}β + ` + +## invalid(18): export default class {} + +> Input + + `β + 1 | export default class {}β + ` + +> Filename + + `β + /path/to/foo.bar.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default class {}β + | ^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`Foo\`.β + 1 | export default class Foo {}β + ` + +## invalid(19): export default class {} + +> Input + + `β + 1 | export default class {}β + ` + +> Filename + + `β + /path/to/foo.test.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default class {}β + | ^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`Foo\`.β + 1 | export default class Foo {}β + ` + +## invalid(20): export default class {} + +> Input + + `β + 1 | export default class {}β + ` + +> Filename + + `β + /path/to/.foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default class {}β + | ^^^^^ The class should be named.β + ` + +## invalid(21): let Foo, Foo_, foo, foo_ export default class {} > Input @@ -362,7 +458,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default class Foo__ {}β ` -## invalid(18): export default function () {} +## invalid(22): export default function () {} > Input @@ -387,7 +483,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default function foo () {}β ` -## invalid(19): export default function* () {} +## invalid(23): export default function* () {} > Input @@ -412,7 +508,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default function* foo () {}β ` -## invalid(20): export default async function* () {} +## invalid(24): export default async function* () {} > Input @@ -437,7 +533,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function* foo () {}β ` -## invalid(21): export default async function*() {} +## invalid(25): export default async function*() {} > Input @@ -462,7 +558,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function* foo () {}β ` -## invalid(22): export default async function *() {} +## invalid(26): export default async function *() {} > Input @@ -487,7 +583,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function * foo () {}β ` -## invalid(23): export default async function * () {} +## invalid(27): export default async function * () {} > Input @@ -512,7 +608,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function * foo () {}β ` -## invalid(24): export default async function * /* comment */ () {} +## invalid(28): export default async function * /* comment */ () {} > Input @@ -537,7 +633,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function * /* comment */ foo () {}β ` -## invalid(25): export default async function * // comment () {} +## invalid(29): export default async function * // comment () {} > Input @@ -566,7 +662,7 @@ Generated by [AVA](https://avajs.dev). 2 | foo () {}β ` -## invalid(26): let Foo, Foo_, foo, foo_ export default async function * () {} +## invalid(30): let Foo, Foo_, foo, foo_ export default async function * () {} > Input @@ -594,7 +690,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default async function * foo__ () {}β ` -## invalid(27): export default () => {} +## invalid(31): export default () => {} > Input @@ -620,7 +716,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(28): export default async () => {} +## invalid(32): export default async () => {} > Input @@ -646,7 +742,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(29): export default () => {}; +## invalid(33): export default () => {}; > Input @@ -672,7 +768,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(30): export default() => {} +## invalid(34): export default() => {} > Input @@ -698,7 +794,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(31): export default foo => {} +## invalid(35): export default foo => {} > Input @@ -724,7 +820,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo_;β ` -## invalid(32): export default (( () => {} )) +## invalid(36): export default (( () => {} )) > Input @@ -750,7 +846,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(33): /* comment 1 */ export /* comment 2 */ default /* comment 3 */ () => {} +## invalid(37): /* comment 1 */ export /* comment 2 */ default /* comment 3 */ () => {} > Input @@ -776,7 +872,7 @@ Generated by [AVA](https://avajs.dev). 2 | export /* comment 2 */ default /* comment 3 */ foo;β ` -## invalid(34): // comment 1 export // comment 2 default // comment 3 () => {} +## invalid(38): // comment 1 export // comment 2 default // comment 3 () => {} > Input @@ -817,7 +913,7 @@ Generated by [AVA](https://avajs.dev). 7 | foo;β ` -## invalid(35): let Foo, Foo_, foo, foo_ export default async () => {} +## invalid(39): let Foo, Foo_, foo, foo_ export default async () => {} > Input diff --git a/test/snapshots/no-anonymous-default-export.mjs.snap b/test/snapshots/no-anonymous-default-export.mjs.snap index 8d77ae7865bfe7bc040ebc906d3ac669b2cd239b..d765a62052bb8f563eeb26f4c6e9755c6ee49f2f 100644 GIT binary patch literal 1844 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 literal 1784 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 aNvwt`4KSyOszi0*0QNt2UKiklM*sl4Eoz1U From 3471bd4a9b72fe3b0ace745c571ca38159cde0a7 Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Wed, 7 Feb 2024 00:46:33 +0800 Subject: [PATCH 10/25] Linting --- rules/no-anonymous-default-export.js | 60 +++++++++++---------- scripts/internal-rules/fix-snapshot-test.js | 2 +- test/no-anonymous-default-export.mjs | 10 ++-- 3 files changed, 37 insertions(+), 35 deletions(-) diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js index a8edd36202..796a0e6788 100644 --- a/rules/no-anonymous-default-export.js +++ b/rules/no-anonymous-default-export.js @@ -1,6 +1,6 @@ 'use strict'; -const path = require('node:path') +const path = require('node:path'); const { getFunctionHeadLocation, getFunctionNameWithKind, @@ -17,7 +17,6 @@ const { avoidCapture, } = require('./utils/index.js'); - const MESSAGE_ID_ERROR = 'no-anonymous-default-export/error'; const MESSAGE_ID_SUGGESTION = 'no-anonymous-default-export/suggestion'; const messages = { @@ -25,7 +24,7 @@ const messages = { [MESSAGE_ID_SUGGESTION]: 'Name it as `{{name}}`.', }; -const EXPECTED_FUNCTION_DESCRIPTION_SUFFIX = ' \'default\'' +const EXPECTED_FUNCTION_DESCRIPTION_SUFFIX = ' \'default\''; const isClassKeywordToken = token => token.type === 'Keyword' && token.value === 'class'; function getSuggestionName(node, filename, sourceCode) { @@ -33,14 +32,14 @@ function getSuggestionName(node, filename, sourceCode) { return; } - let [name] = path.basename(filename).split('.') - name = camelCase(name) + let [name] = path.basename(filename).split('.'); + name = camelCase(name); if (!isIdentifierName(name)) { - return + return; } - name = node.type === 'ClassDeclaration' ? upperFirst(name) : name + name = node.type === 'ClassDeclaration' ? upperFirst(name) : name; name = avoidCapture(name, getScopes(sourceCode.getScope(node))); return name; @@ -49,12 +48,13 @@ function getSuggestionName(node, filename, sourceCode) { function addName(fixer, node, name, sourceCode) { switch (node.type) { case 'ClassDeclaration': { - const lastDecorator = node.decorators?.at(-1) + const lastDecorator = node.decorators?.at(-1); const classToken = lastDecorator ? sourceCode.getTokenAfter(lastDecorator, isClassKeywordToken) : sourceCode.getFirstToken(node, isClassKeywordToken); return fixer.insertTextAfter(classToken, ` ${name}`); } + case 'FunctionDeclaration': { const openingParenthesisToken = sourceCode.getFirstToken( node, @@ -62,18 +62,19 @@ function addName(fixer, node, name, sourceCode) { ); return fixer.insertTextBefore( openingParenthesisToken, - `${sourceCode.text.charAt(openingParenthesisToken.range[0] - 1) === ' ' ? '' : ' '}${name} ` + `${sourceCode.text.charAt(openingParenthesisToken.range[0] - 1) === ' ' ? '' : ' '}${name} `, ); } + case 'ArrowFunctionExpression': { const [exportDeclarationStart] = node.parent.range; const [arrowFunctionStart] = getParenthesizedRange(node, sourceCode); - const originalExportDefaultText = sourceCode.text.slice(exportDeclarationStart, arrowFunctionStart) - const shouldInsertSpaceAfterDefault = - !originalExportDefaultText.endsWith(' ') + const originalExportDefaultText = sourceCode.text.slice(exportDeclarationStart, arrowFunctionStart); + const shouldInsertSpaceAfterDefault + = !originalExportDefaultText.endsWith(' ') && !originalExportDefaultText.endsWith('\n') - && !originalExportDefaultText.endsWith('\t') + && !originalExportDefaultText.endsWith('\t'); return [ fixer.replaceTextRange( @@ -82,10 +83,12 @@ function addName(fixer, node, name, sourceCode) { ), fixer.insertTextAfter( node.parent, - `\n${originalExportDefaultText}${shouldInsertSpaceAfterDefault ? ' ' : ''}${name};` + `\n${originalExportDefaultText}${shouldInsertSpaceAfterDefault ? ' ' : ''}${name};`, ), - ] + ]; } + + // No default } } @@ -98,32 +101,31 @@ const create = context => { if (!( ( ( - node.type === 'FunctionDeclaration' || - node.type === 'ClassDeclaration' + node.type === 'FunctionDeclaration' + || node.type === 'ClassDeclaration' ) && !node.id ) - || - node.type === 'ArrowFunctionExpression' + || node.type === 'ArrowFunctionExpression' )) { return; } - const suggestionName = getSuggestionName(node, physicalFilename, sourceCode) + const suggestionName = getSuggestionName(node, physicalFilename, sourceCode); - let loc - let description + let loc; + let description; if (node.type === 'ClassDeclaration') { loc = getClassHeadLocation(node, sourceCode); description = 'class'; } else { loc = getFunctionHeadLocation(node, sourceCode); // [TODO: @fisker]: Ask `@eslint-community/eslint-utils` to expose `getFunctionKind` - const nameWithKind = getFunctionNameWithKind(node) - description = - nameWithKind.endsWith(EXPECTED_FUNCTION_DESCRIPTION_SUFFIX) - ? nameWithKind.slice(0, -EXPECTED_FUNCTION_DESCRIPTION_SUFFIX.length) - : nameWithKind + const nameWithKind = getFunctionNameWithKind(node); + description + = nameWithKind.endsWith(EXPECTED_FUNCTION_DESCRIPTION_SUFFIX) + ? nameWithKind.slice(0, -EXPECTED_FUNCTION_DESCRIPTION_SUFFIX.length) + : nameWithKind; } const problem = { @@ -133,7 +135,7 @@ const create = context => { data: { description, }, - } + }; if (!suggestionName) { return problem; @@ -145,7 +147,7 @@ const create = context => { data: { name: suggestionName, }, - fix: fixer => addName(fixer, node, suggestionName, sourceCode) + fix: fixer => addName(fixer, node, suggestionName, sourceCode), }, ]; diff --git a/scripts/internal-rules/fix-snapshot-test.js b/scripts/internal-rules/fix-snapshot-test.js index 1699b0719a..9e206494f0 100644 --- a/scripts/internal-rules/fix-snapshot-test.js +++ b/scripts/internal-rules/fix-snapshot-test.js @@ -101,7 +101,7 @@ function checkInvalidCases(node, context) { } for (const propertyNode of testCaseNode.properties) { - if (propertyNode.computed || propertyNode.key.type !== 'Identifier') { + if (propertyNode.type !== 'Property' || propertyNode.computed || propertyNode.key.type !== 'Identifier') { continue; } diff --git a/test/no-anonymous-default-export.mjs b/test/no-anonymous-default-export.mjs index 87fec72714..eb396b50e3 100644 --- a/test/no-anonymous-default-export.mjs +++ b/test/no-anonymous-default-export.mjs @@ -86,7 +86,6 @@ test.snapshot({ filename: '/path/to/foo.js', }, - // `FunctionDeclaration` { code: 'export default function () {}', @@ -167,7 +166,8 @@ test.snapshot({ // comment 2 default // comment 3 - () => {}`, + () => {} + `, filename: '/path/to/foo.js', }, { @@ -192,7 +192,7 @@ const decoratorsBeforeExportOptions = { }, }, }, -} +}; const decoratorsAfterExportOptions = { parser: parsers.babel, parserOptions: { @@ -204,7 +204,7 @@ const decoratorsAfterExportOptions = { }, }, }, -} +}; test.snapshot({ valid: [], invalid: [ @@ -224,5 +224,5 @@ test.snapshot({ ...decoratorsBeforeExportOptions, }, ], -}) +}); From c886c202612e24db3f72f46fd30363231004e701 Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Wed, 7 Feb 2024 00:54:12 +0800 Subject: [PATCH 11/25] Test super class --- test/no-anonymous-default-export.mjs | 6 +- .../no-anonymous-default-export.mjs.md | 97 +++++++++++------- .../no-anonymous-default-export.mjs.snap | Bin 1844 -> 1901 bytes 3 files changed, 66 insertions(+), 37 deletions(-) diff --git a/test/no-anonymous-default-export.mjs b/test/no-anonymous-default-export.mjs index eb396b50e3..bfb1f02d4a 100644 --- a/test/no-anonymous-default-export.mjs +++ b/test/no-anonymous-default-export.mjs @@ -30,6 +30,10 @@ test.snapshot({ code: 'export default class {}', filename: '/path/to/foo.js', }, + { + code: 'export default class extends class {} {}', + filename: '/path/to/foo.js', + }, { code: 'export default class{}', filename: '/path/to/foo.js', @@ -214,7 +218,7 @@ test.snapshot({ ...decoratorsBeforeExportOptions, }, { - code: 'export default @decorator(class {}) class {}', + code: 'export default @decorator(class {}) class extends class {} {}', filename: '/path/to/foo.js', ...decoratorsAfterExportOptions, }, diff --git a/test/snapshots/no-anonymous-default-export.mjs.md b/test/snapshots/no-anonymous-default-export.mjs.md index a975b40096..f9ff65b586 100644 --- a/test/snapshots/no-anonymous-default-export.mjs.md +++ b/test/snapshots/no-anonymous-default-export.mjs.md @@ -134,7 +134,32 @@ Generated by [AVA](https://avajs.dev). 1 | export default class Foo {}β ` -## invalid(9): export default class{} +## invalid(9): export default class extends class {} {} + +> Input + + `β + 1 | export default class extends class {} {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default class extends class {} {}β + | ^^^^^^^^^^^^^^^^^^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`Foo\`.β + 1 | export default class Foo extends class {} {}β + ` + +## invalid(10): export default class{} > Input @@ -159,7 +184,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default class Foo{}β ` -## invalid(10): export default class {} +## invalid(11): export default class {} > Input @@ -184,7 +209,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default class FooBar {}β ` -## invalid(11): export default class {} +## invalid(12): export default class {} > Input @@ -209,7 +234,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default class FooBar {}β ` -## invalid(12): export default class {} +## invalid(13): export default class {} > Input @@ -234,7 +259,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default class FooBar {}β ` -## invalid(13): export default class {} +## invalid(14): export default class {} > Input @@ -259,7 +284,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default class FooBar123 {}β ` -## invalid(14): export default class {} +## invalid(15): export default class {} > Input @@ -284,7 +309,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default class Foo {}β ` -## invalid(15): export default class {} +## invalid(16): export default class {} > Input @@ -309,7 +334,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default class Foo {}β ` -## invalid(16): export default class {} +## invalid(17): export default class {} > Input @@ -334,7 +359,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default class Class {}β ` -## invalid(17): export default class {} +## invalid(18): export default class {} > Input @@ -359,7 +384,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default class Foo {}β ` -## invalid(18): export default class {} +## invalid(19): export default class {} > Input @@ -384,7 +409,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default class Foo {}β ` -## invalid(19): export default class {} +## invalid(20): export default class {} > Input @@ -409,7 +434,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default class Foo {}β ` -## invalid(20): export default class {} +## invalid(21): export default class {} > Input @@ -430,7 +455,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^ The class should be named.β ` -## invalid(21): let Foo, Foo_, foo, foo_ export default class {} +## invalid(22): let Foo, Foo_, foo, foo_ export default class {} > Input @@ -458,7 +483,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default class Foo__ {}β ` -## invalid(22): export default function () {} +## invalid(23): export default function () {} > Input @@ -483,7 +508,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default function foo () {}β ` -## invalid(23): export default function* () {} +## invalid(24): export default function* () {} > Input @@ -508,7 +533,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default function* foo () {}β ` -## invalid(24): export default async function* () {} +## invalid(25): export default async function* () {} > Input @@ -533,7 +558,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function* foo () {}β ` -## invalid(25): export default async function*() {} +## invalid(26): export default async function*() {} > Input @@ -558,7 +583,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function* foo () {}β ` -## invalid(26): export default async function *() {} +## invalid(27): export default async function *() {} > Input @@ -583,7 +608,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function * foo () {}β ` -## invalid(27): export default async function * () {} +## invalid(28): export default async function * () {} > Input @@ -608,7 +633,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function * foo () {}β ` -## invalid(28): export default async function * /* comment */ () {} +## invalid(29): export default async function * /* comment */ () {} > Input @@ -633,7 +658,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function * /* comment */ foo () {}β ` -## invalid(29): export default async function * // comment () {} +## invalid(30): export default async function * // comment () {} > Input @@ -662,7 +687,7 @@ Generated by [AVA](https://avajs.dev). 2 | foo () {}β ` -## invalid(30): let Foo, Foo_, foo, foo_ export default async function * () {} +## invalid(31): let Foo, Foo_, foo, foo_ export default async function * () {} > Input @@ -690,7 +715,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default async function * foo__ () {}β ` -## invalid(31): export default () => {} +## invalid(32): export default () => {} > Input @@ -716,7 +741,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(32): export default async () => {} +## invalid(33): export default async () => {} > Input @@ -742,7 +767,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(33): export default () => {}; +## invalid(34): export default () => {}; > Input @@ -768,7 +793,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(34): export default() => {} +## invalid(35): export default() => {} > Input @@ -794,7 +819,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(35): export default foo => {} +## invalid(36): export default foo => {} > Input @@ -820,7 +845,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo_;β ` -## invalid(36): export default (( () => {} )) +## invalid(37): export default (( () => {} )) > Input @@ -846,7 +871,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(37): /* comment 1 */ export /* comment 2 */ default /* comment 3 */ () => {} +## invalid(38): /* comment 1 */ export /* comment 2 */ default /* comment 3 */ () => {} > Input @@ -872,7 +897,7 @@ Generated by [AVA](https://avajs.dev). 2 | export /* comment 2 */ default /* comment 3 */ foo;β ` -## invalid(38): // comment 1 export // comment 2 default // comment 3 () => {} +## invalid(39): // comment 1 export // comment 2 default // comment 3 () => {} > Input @@ -913,7 +938,7 @@ Generated by [AVA](https://avajs.dev). 7 | foo;β ` -## invalid(39): let Foo, Foo_, foo, foo_ export default async () => {} +## invalid(40): let Foo, Foo_, foo, foo_ export default async () => {} > Input @@ -967,12 +992,12 @@ Generated by [AVA](https://avajs.dev). 1 | @decorator export default class Foo {}β ` -## invalid(2): export default @decorator(class {}) class {} +## invalid(2): export default @decorator(class {}) class extends class {} {} > Input `β - 1 | export default @decorator(class {}) class {}β + 1 | export default @decorator(class {}) class extends class {} {}β ` > Filename @@ -984,12 +1009,12 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `β - > 1 | export default @decorator(class {}) class {}β - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ The class should be named.β + > 1 | export default @decorator(class {}) class extends class {} {}β + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The class should be named.β β --------------------------------------------------------------------------------β Suggestion 1/1: Name it as \`Foo\`.β - 1 | export default @decorator(class {}) class Foo {}β + 1 | export default @decorator(class {}) class Foo extends class {} {}β ` ## invalid(3): @decorator @decorator(class {}) export default class {} diff --git a/test/snapshots/no-anonymous-default-export.mjs.snap b/test/snapshots/no-anonymous-default-export.mjs.snap index d765a62052bb8f563eeb26f4c6e9755c6ee49f2f..8908d119b5be2c40688473625937ea222ea03b61 100644 GIT binary patch literal 1901 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 literal 1844 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 From a2a3ff7ad6ead6324d9d042be68cfa248d33d77a Mon Sep 17 00:00:00 2001 From: fisker Cheung <lionkay@gmail.com> Date: Wed, 7 Feb 2024 00:56:55 +0800 Subject: [PATCH 12/25] Update no-anonymous-default-export.md --- docs/rules/no-anonymous-default-export.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/no-anonymous-default-export.md b/docs/rules/no-anonymous-default-export.md index 8235a11f95..e2e4566a01 100644 --- a/docs/rules/no-anonymous-default-export.md +++ b/docs/rules/no-anonymous-default-export.md @@ -20,7 +20,7 @@ export default function () {} ``` ```js -export default () => {} +export default () => {}; ``` ## Pass From 266ce9f3bb81270404ababc0878903a11abed938 Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Wed, 7 Feb 2024 01:09:46 +0800 Subject: [PATCH 13/25] Prepare for `cjs` --- rules/no-anonymous-default-export.js | 139 ++++++++++++++++----------- 1 file changed, 82 insertions(+), 57 deletions(-) diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js index 796a0e6788..8832021c66 100644 --- a/rules/no-anonymous-default-export.js +++ b/rules/no-anonymous-default-export.js @@ -16,6 +16,7 @@ const { getScopes, avoidCapture, } = require('./utils/index.js'); +const {isMemberExpression} = require('./ast/index.js'); const MESSAGE_ID_ERROR = 'no-anonymous-default-export/error'; const MESSAGE_ID_SUGGESTION = 'no-anonymous-default-export/suggestion'; @@ -26,6 +27,15 @@ const messages = { const EXPECTED_FUNCTION_DESCRIPTION_SUFFIX = ' \'default\''; const isClassKeywordToken = token => token.type === 'Keyword' && token.value === 'class'; +const isAnonymousClassOrFunction = node => + ( + ( + node.type === 'FunctionDeclaration' + || node.type === 'ClassDeclaration' + ) + && !node.id + ) + || node.type === 'ArrowFunctionExpression'; function getSuggestionName(node, filename, sourceCode) { if (filename === '<input>' || filename === '<text>') { @@ -92,68 +102,83 @@ function addName(fixer, node, name, sourceCode) { } } -/** @param {import('eslint').Rule.RuleContext} context */ -const create = context => { +function getProblem(node, context) { const {sourceCode, physicalFilename} = context; - return { - ExportDefaultDeclaration({declaration: node}) { - if (!( - ( - ( - node.type === 'FunctionDeclaration' - || node.type === 'ClassDeclaration' - ) - && !node.id - ) - || node.type === 'ArrowFunctionExpression' - )) { - return; - } - - const suggestionName = getSuggestionName(node, physicalFilename, sourceCode); - - let loc; - let description; - if (node.type === 'ClassDeclaration') { - loc = getClassHeadLocation(node, sourceCode); - description = 'class'; - } else { - loc = getFunctionHeadLocation(node, sourceCode); - // [TODO: @fisker]: Ask `@eslint-community/eslint-utils` to expose `getFunctionKind` - const nameWithKind = getFunctionNameWithKind(node); - description - = nameWithKind.endsWith(EXPECTED_FUNCTION_DESCRIPTION_SUFFIX) - ? nameWithKind.slice(0, -EXPECTED_FUNCTION_DESCRIPTION_SUFFIX.length) - : nameWithKind; - } - - const problem = { - node, - loc, - messageId: MESSAGE_ID_ERROR, - data: { - description, - }, - }; - - if (!suggestionName) { - return problem; - } - - problem.suggest = [ - { - messageId: MESSAGE_ID_SUGGESTION, - data: { - name: suggestionName, - }, - fix: fixer => addName(fixer, node, suggestionName, sourceCode), - }, - ]; + const suggestionName = getSuggestionName(node, physicalFilename, sourceCode); + + let loc; + let description; + if (node.type === 'ClassDeclaration') { + loc = getClassHeadLocation(node, sourceCode); + description = 'class'; + } else { + loc = getFunctionHeadLocation(node, sourceCode); + // [TODO: @fisker]: Ask `@eslint-community/eslint-utils` to expose `getFunctionKind` + const nameWithKind = getFunctionNameWithKind(node); + description + = nameWithKind.endsWith(EXPECTED_FUNCTION_DESCRIPTION_SUFFIX) + ? nameWithKind.slice(0, -EXPECTED_FUNCTION_DESCRIPTION_SUFFIX.length) + : nameWithKind; + } - return problem; + const problem = { + node, + loc, + messageId: MESSAGE_ID_ERROR, + data: { + description, }, }; + + if (!suggestionName) { + return problem; + } + + problem.suggest = [ + { + messageId: MESSAGE_ID_SUGGESTION, + data: { + name: suggestionName, + }, + fix: fixer => addName(fixer, node, suggestionName, sourceCode), + }, + ]; + + return problem; +} + +/** @param {import('eslint').Rule.RuleContext} context */ +const create = context => { + context.on('ExportDefaultDeclaration', (node) => { + if (!isAnonymousClassOrFunction(node.declaration)) { + return; + } + + return getProblem(node.declaration, context) + }); + + context.on('AssignmentExpression', (assignment) => { + if ( + !isAnonymousClassOrFunction(node.right) + || !( + isMemberExpression(node.left, { + object: 'module', + property: 'exports', + computed: false, + optional: false + }) + || ( + node.left.type === 'Identifier', + node.left.name === 'exports' + ) + ) + ) { + return + } + + return getProblem(node.right, context); + }) }; /** @type {import('eslint').Rule.RuleModule} */ From c70f9b08e8b4b178dbae31172c86bd406c97b321 Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Wed, 7 Feb 2024 01:19:11 +0800 Subject: [PATCH 14/25] Support `ClassExpression` & `FunctionExpression` --- rules/no-anonymous-default-export.js | 10 +- test/no-anonymous-default-export.mjs | 25 +++- .../no-anonymous-default-export.mjs.md | 117 +++++++++++++++--- .../no-anonymous-default-export.mjs.snap | Bin 1901 -> 2036 bytes 4 files changed, 128 insertions(+), 24 deletions(-) diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js index 8832021c66..9eb6b37c8e 100644 --- a/rules/no-anonymous-default-export.js +++ b/rules/no-anonymous-default-export.js @@ -31,7 +31,9 @@ const isAnonymousClassOrFunction = node => ( ( node.type === 'FunctionDeclaration' + || node.type === 'FunctionExpression' || node.type === 'ClassDeclaration' + || node.type === 'ClassExpression' ) && !node.id ) @@ -57,7 +59,8 @@ function getSuggestionName(node, filename, sourceCode) { function addName(fixer, node, name, sourceCode) { switch (node.type) { - case 'ClassDeclaration': { + case 'ClassDeclaration': + case 'ClassExpression': { const lastDecorator = node.decorators?.at(-1); const classToken = lastDecorator ? sourceCode.getTokenAfter(lastDecorator, isClassKeywordToken) @@ -65,7 +68,8 @@ function addName(fixer, node, name, sourceCode) { return fixer.insertTextAfter(classToken, ` ${name}`); } - case 'FunctionDeclaration': { + case 'FunctionDeclaration': + case 'FunctionExpression': { const openingParenthesisToken = sourceCode.getFirstToken( node, isOpeningParenToken, @@ -109,7 +113,7 @@ function getProblem(node, context) { let loc; let description; - if (node.type === 'ClassDeclaration') { + if (node.type === 'ClassDeclaration' || node.type === 'ClassExpression') { loc = getClassHeadLocation(node, sourceCode); description = 'class'; } else { diff --git a/test/no-anonymous-default-export.mjs b/test/no-anonymous-default-export.mjs index bfb1f02d4a..6d0ad89b48 100644 --- a/test/no-anonymous-default-export.mjs +++ b/test/no-anonymous-default-export.mjs @@ -12,9 +12,6 @@ test.snapshot({ 'export default 1', 'export default false', 'export default 0n', - // `ClassExpression`s and `FunctionExpression`s are ignored - 'export default (class {})', - 'export default (function () {})', ], invalid: [ 'export default function () {}', @@ -90,6 +87,19 @@ test.snapshot({ filename: '/path/to/foo.js', }, + // `ClassExpression` + { + code: outdent` + let Foo, Foo_, foo, foo_ + export default (class{}) + `, + filename: '/path/to/foo.js', + }, + { + code: 'export default (class extends class {} {})', + filename: '/path/to/foo.js', + }, + // `FunctionDeclaration` { code: 'export default function () {}', @@ -134,6 +144,15 @@ test.snapshot({ filename: '/path/to/foo.js', }, + // `FunctionExpression` + { + code: outdent` + let Foo, Foo_, foo, foo_ + export default (async function * () {}) + `, + filename: '/path/to/foo.js', + }, + // `ArrowFunctionExpression` { code: 'export default () => {}', diff --git a/test/snapshots/no-anonymous-default-export.mjs.md b/test/snapshots/no-anonymous-default-export.mjs.md index f9ff65b586..5b6d87ec15 100644 --- a/test/snapshots/no-anonymous-default-export.mjs.md +++ b/test/snapshots/no-anonymous-default-export.mjs.md @@ -483,7 +483,60 @@ Generated by [AVA](https://avajs.dev). 2 | export default class Foo__ {}β ` -## invalid(23): export default function () {} +## invalid(23): let Foo, Foo_, foo, foo_ export default (class{}) + +> Input + + `β + 1 | let Foo, Foo_, foo, foo_β + 2 | export default (class{})β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + 1 | let Foo, Foo_, foo, foo_β + > 2 | export default (class{})β + | ^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo__\`.β + 1 | let Foo, Foo_, foo, foo_β + 2 | export default (class foo__{})β + ` + +## invalid(24): export default (class extends class {} {}) + +> Input + + `β + 1 | export default (class extends class {} {})β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | export default (class extends class {} {})β + | ^^^^^^^^^^^^^^^^^^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | export default (class foo extends class {} {})β + ` + +## invalid(25): export default function () {} > Input @@ -508,7 +561,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default function foo () {}β ` -## invalid(24): export default function* () {} +## invalid(26): export default function* () {} > Input @@ -533,7 +586,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default function* foo () {}β ` -## invalid(25): export default async function* () {} +## invalid(27): export default async function* () {} > Input @@ -558,7 +611,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function* foo () {}β ` -## invalid(26): export default async function*() {} +## invalid(28): export default async function*() {} > Input @@ -583,7 +636,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function* foo () {}β ` -## invalid(27): export default async function *() {} +## invalid(29): export default async function *() {} > Input @@ -608,7 +661,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function * foo () {}β ` -## invalid(28): export default async function * () {} +## invalid(30): export default async function * () {} > Input @@ -633,7 +686,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function * foo () {}β ` -## invalid(29): export default async function * /* comment */ () {} +## invalid(31): export default async function * /* comment */ () {} > Input @@ -658,7 +711,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function * /* comment */ foo () {}β ` -## invalid(30): export default async function * // comment () {} +## invalid(32): export default async function * // comment () {} > Input @@ -687,7 +740,7 @@ Generated by [AVA](https://avajs.dev). 2 | foo () {}β ` -## invalid(31): let Foo, Foo_, foo, foo_ export default async function * () {} +## invalid(33): let Foo, Foo_, foo, foo_ export default async function * () {} > Input @@ -715,7 +768,35 @@ Generated by [AVA](https://avajs.dev). 2 | export default async function * foo__ () {}β ` -## invalid(32): export default () => {} +## invalid(34): let Foo, Foo_, foo, foo_ export default (async function * () {}) + +> Input + + `β + 1 | let Foo, Foo_, foo, foo_β + 2 | export default (async function * () {})β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + 1 | let Foo, Foo_, foo, foo_β + > 2 | export default (async function * () {})β + | ^^^^^^^^^^^^^^^^^ The async generator function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo__\`.β + 1 | let Foo, Foo_, foo, foo_β + 2 | export default (async function * foo__ () {})β + ` + +## invalid(35): export default () => {} > Input @@ -741,7 +822,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(33): export default async () => {} +## invalid(36): export default async () => {} > Input @@ -767,7 +848,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(34): export default () => {}; +## invalid(37): export default () => {}; > Input @@ -793,7 +874,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(35): export default() => {} +## invalid(38): export default() => {} > Input @@ -819,7 +900,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(36): export default foo => {} +## invalid(39): export default foo => {} > Input @@ -845,7 +926,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo_;β ` -## invalid(37): export default (( () => {} )) +## invalid(40): export default (( () => {} )) > Input @@ -871,7 +952,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(38): /* comment 1 */ export /* comment 2 */ default /* comment 3 */ () => {} +## invalid(41): /* comment 1 */ export /* comment 2 */ default /* comment 3 */ () => {} > Input @@ -897,7 +978,7 @@ Generated by [AVA](https://avajs.dev). 2 | export /* comment 2 */ default /* comment 3 */ foo;β ` -## invalid(39): // comment 1 export // comment 2 default // comment 3 () => {} +## invalid(42): // comment 1 export // comment 2 default // comment 3 () => {} > Input @@ -938,7 +1019,7 @@ Generated by [AVA](https://avajs.dev). 7 | foo;β ` -## invalid(40): let Foo, Foo_, foo, foo_ export default async () => {} +## invalid(43): let Foo, Foo_, foo, foo_ export default async () => {} > Input diff --git a/test/snapshots/no-anonymous-default-export.mjs.snap b/test/snapshots/no-anonymous-default-export.mjs.snap index 8908d119b5be2c40688473625937ea222ea03b61..f94bb290be8ca4de2a0152e78264eca0fbc2bab4 100644 GIT binary patch literal 2036 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 SQh8vEZ~p-uQeC)eR{#K9*48Wl literal 1901 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 From 9a5f2763580067de972b4c2daac4f920e85a8237 Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Wed, 7 Feb 2024 01:29:11 +0800 Subject: [PATCH 15/25] Support `module.exports =` and `exports =` --- docs/rules/no-anonymous-default-export.md | 25 ++ rules/no-anonymous-default-export.js | 2 +- test/no-anonymous-default-export.mjs | 51 ++++ .../no-anonymous-default-export.mjs.md | 247 ++++++++++++++++-- .../no-anonymous-default-export.mjs.snap | Bin 2036 -> 2476 bytes 5 files changed, 304 insertions(+), 21 deletions(-) diff --git a/docs/rules/no-anonymous-default-export.md b/docs/rules/no-anonymous-default-export.md index e2e4566a01..40511fbbed 100644 --- a/docs/rules/no-anonymous-default-export.md +++ b/docs/rules/no-anonymous-default-export.md @@ -23,6 +23,18 @@ export default function () {} export default () => {}; ``` +```js +module.exports = class {}; +``` + +```js +module.exports = function () {}; +``` + +```js +module.exports = () => {}; +``` + ## Pass ```js @@ -37,3 +49,16 @@ export default function foo () {} const foo = () => {}; export default foo; ``` + +```js +module.exports = class Foo {}; +``` + +```js +module.exports = function foo () {}; +``` + +```js +const foo = () => {}; +module.exports = foo; +``` diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js index 9eb6b37c8e..a442e3104d 100644 --- a/rules/no-anonymous-default-export.js +++ b/rules/no-anonymous-default-export.js @@ -162,7 +162,7 @@ const create = context => { return getProblem(node.declaration, context) }); - context.on('AssignmentExpression', (assignment) => { + context.on('AssignmentExpression', (node) => { if ( !isAnonymousClassOrFunction(node.right) || !( diff --git a/test/no-anonymous-default-export.mjs b/test/no-anonymous-default-export.mjs index 6d0ad89b48..595578673a 100644 --- a/test/no-anonymous-default-export.mjs +++ b/test/no-anonymous-default-export.mjs @@ -12,6 +12,10 @@ test.snapshot({ 'export default 1', 'export default false', 'export default 0n', + 'notExports = class {}', + 'notModule.exports = class {}', + 'module.notExports = class {}', + 'module.exports.foo = class {}', ], invalid: [ 'export default function () {}', @@ -99,6 +103,17 @@ test.snapshot({ code: 'export default (class extends class {} {})', filename: '/path/to/foo.js', }, + { + code: outdent` + let Exports, Exports_, exports, exports_ + exports = class {} + `, + filename: '/path/to/exports.js', + }, + { + code: 'module.exports = class {}', + filename: '/path/to/module.js', + }, // `FunctionDeclaration` { @@ -152,6 +167,17 @@ test.snapshot({ `, filename: '/path/to/foo.js', }, + { + code: outdent` + let Exports, Exports_, exports, exports_ + exports = function() {} + `, + filename: '/path/to/exports.js', + }, + { + code: 'module.exports = function() {}', + filename: '/path/to/module.js', + }, // `ArrowFunctionExpression` { @@ -200,6 +226,26 @@ test.snapshot({ `, filename: '/path/to/foo.js', }, + { + code: outdent` + let Exports, Exports_, exports, exports_ + exports = (( () => {} )) + `, + filename: '/path/to/exports.js', + }, + { + code: outdent` + // comment 1 + module + // comment 2 + .exports + // comment 3 + = + // comment 4 + () => {} + `, + filename: '/path/to/module.js', + }, ], }); @@ -241,6 +287,11 @@ test.snapshot({ filename: '/path/to/foo.js', ...decoratorsAfterExportOptions, }, + { + code: 'module.exports = @decorator(class {}) class extends class {} {}', + filename: '/path/to/foo.js', + ...decoratorsAfterExportOptions, + }, { code: '@decorator @decorator(class {}) export default class {}', filename: '/path/to/foo.js', diff --git a/test/snapshots/no-anonymous-default-export.mjs.md b/test/snapshots/no-anonymous-default-export.mjs.md index 5b6d87ec15..2677d0938a 100644 --- a/test/snapshots/no-anonymous-default-export.mjs.md +++ b/test/snapshots/no-anonymous-default-export.mjs.md @@ -536,7 +536,60 @@ Generated by [AVA](https://avajs.dev). 1 | export default (class foo extends class {} {})β ` -## invalid(25): export default function () {} +## invalid(25): let Exports, Exports_, exports, exports_ exports = class {} + +> Input + + `β + 1 | let Exports, Exports_, exports, exports_β + 2 | exports = class {}β + ` + +> Filename + + `β + /path/to/exports.jsβ + ` + +> Error 1/1 + + `β + 1 | let Exports, Exports_, exports, exports_β + > 2 | exports = class {}β + | ^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`exports__\`.β + 1 | let Exports, Exports_, exports, exports_β + 2 | exports = class exports__ {}β + ` + +## invalid(26): module.exports = class {} + +> Input + + `β + 1 | module.exports = class {}β + ` + +> Filename + + `β + /path/to/module.jsβ + ` + +> Error 1/1 + + `β + > 1 | module.exports = class {}β + | ^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`module_\`.β + 1 | module.exports = class module_ {}β + ` + +## invalid(27): export default function () {} > Input @@ -561,7 +614,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default function foo () {}β ` -## invalid(26): export default function* () {} +## invalid(28): export default function* () {} > Input @@ -586,7 +639,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default function* foo () {}β ` -## invalid(27): export default async function* () {} +## invalid(29): export default async function* () {} > Input @@ -611,7 +664,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function* foo () {}β ` -## invalid(28): export default async function*() {} +## invalid(30): export default async function*() {} > Input @@ -636,7 +689,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function* foo () {}β ` -## invalid(29): export default async function *() {} +## invalid(31): export default async function *() {} > Input @@ -661,7 +714,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function * foo () {}β ` -## invalid(30): export default async function * () {} +## invalid(32): export default async function * () {} > Input @@ -686,7 +739,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function * foo () {}β ` -## invalid(31): export default async function * /* comment */ () {} +## invalid(33): export default async function * /* comment */ () {} > Input @@ -711,7 +764,7 @@ Generated by [AVA](https://avajs.dev). 1 | export default async function * /* comment */ foo () {}β ` -## invalid(32): export default async function * // comment () {} +## invalid(34): export default async function * // comment () {} > Input @@ -740,7 +793,7 @@ Generated by [AVA](https://avajs.dev). 2 | foo () {}β ` -## invalid(33): let Foo, Foo_, foo, foo_ export default async function * () {} +## invalid(35): let Foo, Foo_, foo, foo_ export default async function * () {} > Input @@ -768,7 +821,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default async function * foo__ () {}β ` -## invalid(34): let Foo, Foo_, foo, foo_ export default (async function * () {}) +## invalid(36): let Foo, Foo_, foo, foo_ export default (async function * () {}) > Input @@ -796,7 +849,60 @@ Generated by [AVA](https://avajs.dev). 2 | export default (async function * foo__ () {})β ` -## invalid(35): export default () => {} +## invalid(37): let Exports, Exports_, exports, exports_ exports = function() {} + +> Input + + `β + 1 | let Exports, Exports_, exports, exports_β + 2 | exports = function() {}β + ` + +> Filename + + `β + /path/to/exports.jsβ + ` + +> Error 1/1 + + `β + 1 | let Exports, Exports_, exports, exports_β + > 2 | exports = function() {}β + | ^^^^^^^^ The function 'exports' should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`exports__\`.β + 1 | let Exports, Exports_, exports, exports_β + 2 | exports = function exports__ () {}β + ` + +## invalid(38): module.exports = function() {} + +> Input + + `β + 1 | module.exports = function() {}β + ` + +> Filename + + `β + /path/to/module.jsβ + ` + +> Error 1/1 + + `β + > 1 | module.exports = function() {}β + | ^^^^^^^^ The function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`module_\`.β + 1 | module.exports = function module_ () {}β + ` + +## invalid(39): export default () => {} > Input @@ -822,7 +928,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(36): export default async () => {} +## invalid(40): export default async () => {} > Input @@ -848,7 +954,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(37): export default () => {}; +## invalid(41): export default () => {}; > Input @@ -874,7 +980,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(38): export default() => {} +## invalid(42): export default() => {} > Input @@ -900,7 +1006,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(39): export default foo => {} +## invalid(43): export default foo => {} > Input @@ -926,7 +1032,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo_;β ` -## invalid(40): export default (( () => {} )) +## invalid(44): export default (( () => {} )) > Input @@ -952,7 +1058,7 @@ Generated by [AVA](https://avajs.dev). 2 | export default foo;β ` -## invalid(41): /* comment 1 */ export /* comment 2 */ default /* comment 3 */ () => {} +## invalid(45): /* comment 1 */ export /* comment 2 */ default /* comment 3 */ () => {} > Input @@ -978,7 +1084,7 @@ Generated by [AVA](https://avajs.dev). 2 | export /* comment 2 */ default /* comment 3 */ foo;β ` -## invalid(42): // comment 1 export // comment 2 default // comment 3 () => {} +## invalid(46): // comment 1 export // comment 2 default // comment 3 () => {} > Input @@ -1019,7 +1125,7 @@ Generated by [AVA](https://avajs.dev). 7 | foo;β ` -## invalid(43): let Foo, Foo_, foo, foo_ export default async () => {} +## invalid(47): let Foo, Foo_, foo, foo_ export default async () => {} > Input @@ -1048,6 +1154,82 @@ Generated by [AVA](https://avajs.dev). 3 | export default foo__;β ` +## invalid(48): let Exports, Exports_, exports, exports_ exports = (( () => {} )) + +> Input + + `β + 1 | let Exports, Exports_, exports, exports_β + 2 | exports = (( () => {} ))β + ` + +> Filename + + `β + /path/to/exports.jsβ + ` + +> Error 1/1 + + `β + 1 | let Exports, Exports_, exports, exports_β + > 2 | exports = (( () => {} ))β + | ^^ The arrow function 'exports' should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`exports__\`.β + 1 | let Exports, Exports_, exports, exports_β + 2 | const exports__ = (( () => {} ))β + 3 | exports = exports__;β + ` + +## invalid(49): // comment 1 module // comment 2 .exports // comment 3 = // comment 4 () => {} + +> Input + + `β + 1 | // comment 1β + 2 | moduleβ + 3 | // comment 2β + 4 | .exportsβ + 5 | // comment 3β + 6 | =β + 7 | // comment 4β + 8 | () => {}β + ` + +> Filename + + `β + /path/to/module.jsβ + ` + +> Error 1/1 + + `β + 1 | // comment 1β + 2 | moduleβ + 3 | // comment 2β + 4 | .exportsβ + 5 | // comment 3β + 6 | =β + 7 | // comment 4β + > 8 | () => {}β + | ^^ The arrow function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`module_\`.β + 1 | // comment 1β + 2 | const module_ = () => {}β + 3 | moduleβ + 4 | // comment 2β + 5 | .exportsβ + 6 | // comment 3β + 7 | =β + 8 | // comment 4β + 9 | module_;β + ` + ## invalid(1): @decorator export default class {} > Input @@ -1098,7 +1280,32 @@ Generated by [AVA](https://avajs.dev). 1 | export default @decorator(class {}) class Foo extends class {} {}β ` -## invalid(3): @decorator @decorator(class {}) export default class {} +## invalid(3): module.exports = @decorator(class {}) class extends class {} {} + +> Input + + `β + 1 | module.exports = @decorator(class {}) class extends class {} {}β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | module.exports = @decorator(class {}) class extends class {} {}β + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The class should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | module.exports = @decorator(class {}) class foo extends class {} {}β + ` + +## invalid(4): @decorator @decorator(class {}) export default class {} > Input diff --git a/test/snapshots/no-anonymous-default-export.mjs.snap b/test/snapshots/no-anonymous-default-export.mjs.snap index f94bb290be8ca4de2a0152e78264eca0fbc2bab4..2f3bcfcefb4ca365da5b0beeaab214559028b3bc 100644 GIT binary patch literal 2476 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 literal 2036 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 SQh8vEZ~p-uQeC)eR{#K9*48Wl From cd95e26bbff915bcda0939e1be043f1a4a592bd4 Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Wed, 7 Feb 2024 01:30:25 +0800 Subject: [PATCH 16/25] Remove name in error message --- rules/no-anonymous-default-export.js | 6 +----- .../no-anonymous-default-export.mjs.md | 4 ++-- .../no-anonymous-default-export.mjs.snap | Bin 2476 -> 2470 bytes 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js index a442e3104d..dd59e9b622 100644 --- a/rules/no-anonymous-default-export.js +++ b/rules/no-anonymous-default-export.js @@ -25,7 +25,6 @@ const messages = { [MESSAGE_ID_SUGGESTION]: 'Name it as `{{name}}`.', }; -const EXPECTED_FUNCTION_DESCRIPTION_SUFFIX = ' \'default\''; const isClassKeywordToken = token => token.type === 'Keyword' && token.value === 'class'; const isAnonymousClassOrFunction = node => ( @@ -120,10 +119,7 @@ function getProblem(node, context) { loc = getFunctionHeadLocation(node, sourceCode); // [TODO: @fisker]: Ask `@eslint-community/eslint-utils` to expose `getFunctionKind` const nameWithKind = getFunctionNameWithKind(node); - description - = nameWithKind.endsWith(EXPECTED_FUNCTION_DESCRIPTION_SUFFIX) - ? nameWithKind.slice(0, -EXPECTED_FUNCTION_DESCRIPTION_SUFFIX.length) - : nameWithKind; + description = nameWithKind.replace(/ '.*?'$/, ''); } const problem = { diff --git a/test/snapshots/no-anonymous-default-export.mjs.md b/test/snapshots/no-anonymous-default-export.mjs.md index 2677d0938a..7bdff4d390 100644 --- a/test/snapshots/no-anonymous-default-export.mjs.md +++ b/test/snapshots/no-anonymous-default-export.mjs.md @@ -869,7 +869,7 @@ Generated by [AVA](https://avajs.dev). `β 1 | let Exports, Exports_, exports, exports_β > 2 | exports = function() {}β - | ^^^^^^^^ The function 'exports' should be named.β + | ^^^^^^^^ The function should be named.β β --------------------------------------------------------------------------------β Suggestion 1/1: Name it as \`exports__\`.β @@ -1174,7 +1174,7 @@ Generated by [AVA](https://avajs.dev). `β 1 | let Exports, Exports_, exports, exports_β > 2 | exports = (( () => {} ))β - | ^^ The arrow function 'exports' should be named.β + | ^^ The arrow function should be named.β β --------------------------------------------------------------------------------β Suggestion 1/1: Name it as \`exports__\`.β diff --git a/test/snapshots/no-anonymous-default-export.mjs.snap b/test/snapshots/no-anonymous-default-export.mjs.snap index 2f3bcfcefb4ca365da5b0beeaab214559028b3bc..f2197aa38bc976fc7ccc87455dac127973ca0d58 100644 GIT binary patch literal 2470 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 literal 2476 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 From 5922bd2dbb601daf7280f2549068f8a0fbcc5a0e Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Wed, 7 Feb 2024 01:41:37 +0800 Subject: [PATCH 17/25] Fix Parenthesized assignment --- rules/no-anonymous-default-export.js | 32 +++++--- test/no-anonymous-default-export.mjs | 8 ++ .../no-anonymous-default-export.mjs.md | 72 +++++++++++++++--- .../no-anonymous-default-export.mjs.snap | Bin 2470 -> 2547 bytes 4 files changed, 93 insertions(+), 19 deletions(-) diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js index dd59e9b622..e1feacae12 100644 --- a/rules/no-anonymous-default-export.js +++ b/rules/no-anonymous-default-export.js @@ -80,23 +80,37 @@ function addName(fixer, node, name, sourceCode) { } case 'ArrowFunctionExpression': { - const [exportDeclarationStart] = node.parent.range; - const [arrowFunctionStart] = getParenthesizedRange(node, sourceCode); + const [exportDeclarationStart, exportDeclarationEnd] = getParenthesizedRange(node.parent, sourceCode); + const [arrowFunctionStart, arrowFunctionEnd] = getParenthesizedRange(node, sourceCode); + + let textBefore = sourceCode.text.slice(exportDeclarationStart, arrowFunctionStart); + let textAfter = sourceCode.text.slice(arrowFunctionEnd, exportDeclarationEnd); + + textBefore = `\n${textBefore}`; + if (!/\s$/.test(textBefore)) { + textBefore = `${textBefore} `; + } + if (!textAfter.endsWith(';')) { + textAfter = `${textAfter};` + } - const originalExportDefaultText = sourceCode.text.slice(exportDeclarationStart, arrowFunctionStart); const shouldInsertSpaceAfterDefault - = !originalExportDefaultText.endsWith(' ') - && !originalExportDefaultText.endsWith('\n') - && !originalExportDefaultText.endsWith('\t'); + = !textBefore.endsWith(' ') + && !textBefore.endsWith('\n') + && !textBefore.endsWith('\t'); return [ fixer.replaceTextRange( [exportDeclarationStart, arrowFunctionStart], `const ${name} = `, ), - fixer.insertTextAfter( - node.parent, - `\n${originalExportDefaultText}${shouldInsertSpaceAfterDefault ? ' ' : ''}${name};`, + fixer.replaceTextRange( + [arrowFunctionEnd, exportDeclarationEnd], + `;`, + ), + fixer.insertTextAfterRange( + [exportDeclarationEnd, exportDeclarationEnd], + `${textBefore}${name}${textAfter}`, ), ]; } diff --git a/test/no-anonymous-default-export.mjs b/test/no-anonymous-default-export.mjs index 595578673a..845aab04e1 100644 --- a/test/no-anonymous-default-export.mjs +++ b/test/no-anonymous-default-export.mjs @@ -246,6 +246,14 @@ test.snapshot({ `, filename: '/path/to/module.js', }, + { + code: '(( exports = (( () => {} )) ))', + filename: '/path/to/foo.js', + }, + { + code: '(( module.exports = (( () => {} )) ))', + filename: '/path/to/foo.js', + }, ], }); diff --git a/test/snapshots/no-anonymous-default-export.mjs.md b/test/snapshots/no-anonymous-default-export.mjs.md index 7bdff4d390..b0d1d92665 100644 --- a/test/snapshots/no-anonymous-default-export.mjs.md +++ b/test/snapshots/no-anonymous-default-export.mjs.md @@ -924,7 +924,7 @@ Generated by [AVA](https://avajs.dev). β --------------------------------------------------------------------------------β Suggestion 1/1: Name it as \`foo\`.β - 1 | const foo = () => {}β + 1 | const foo = () => {};β 2 | export default foo;β ` @@ -950,7 +950,7 @@ Generated by [AVA](https://avajs.dev). β --------------------------------------------------------------------------------β Suggestion 1/1: Name it as \`foo\`.β - 1 | const foo = async () => {}β + 1 | const foo = async () => {};β 2 | export default foo;β ` @@ -1002,7 +1002,7 @@ Generated by [AVA](https://avajs.dev). β --------------------------------------------------------------------------------β Suggestion 1/1: Name it as \`foo\`.β - 1 | const foo = () => {}β + 1 | const foo = () => {};β 2 | export default foo;β ` @@ -1028,7 +1028,7 @@ Generated by [AVA](https://avajs.dev). β --------------------------------------------------------------------------------β Suggestion 1/1: Name it as \`foo_\`.β - 1 | const foo_ = foo => {}β + 1 | const foo_ = foo => {};β 2 | export default foo_;β ` @@ -1054,7 +1054,7 @@ Generated by [AVA](https://avajs.dev). β --------------------------------------------------------------------------------β Suggestion 1/1: Name it as \`foo\`.β - 1 | const foo = (( () => {} ))β + 1 | const foo = (( () => {} ));β 2 | export default foo;β ` @@ -1080,7 +1080,7 @@ Generated by [AVA](https://avajs.dev). β --------------------------------------------------------------------------------β Suggestion 1/1: Name it as \`foo\`.β - 1 | /* comment 1 */ const foo = () => {}β + 1 | /* comment 1 */ const foo = () => {};β 2 | export /* comment 2 */ default /* comment 3 */ foo;β ` @@ -1117,7 +1117,7 @@ Generated by [AVA](https://avajs.dev). --------------------------------------------------------------------------------β Suggestion 1/1: Name it as \`foo\`.β 1 | // comment 1β - 2 | const foo = () => {}β + 2 | const foo = () => {};β 3 | exportβ 4 | // comment 2β 5 | defaultβ @@ -1150,7 +1150,7 @@ Generated by [AVA](https://avajs.dev). --------------------------------------------------------------------------------β Suggestion 1/1: Name it as \`foo__\`.β 1 | let Foo, Foo_, foo, foo_β - 2 | const foo__ = async () => {}β + 2 | const foo__ = async () => {};β 3 | export default foo__;β ` @@ -1179,7 +1179,7 @@ Generated by [AVA](https://avajs.dev). --------------------------------------------------------------------------------β Suggestion 1/1: Name it as \`exports__\`.β 1 | let Exports, Exports_, exports, exports_β - 2 | const exports__ = (( () => {} ))β + 2 | const exports__ = (( () => {} ));β 3 | exports = exports__;β ` @@ -1220,7 +1220,7 @@ Generated by [AVA](https://avajs.dev). --------------------------------------------------------------------------------β Suggestion 1/1: Name it as \`module_\`.β 1 | // comment 1β - 2 | const module_ = () => {}β + 2 | const module_ = () => {};β 3 | moduleβ 4 | // comment 2β 5 | .exportsβ @@ -1230,6 +1230,58 @@ Generated by [AVA](https://avajs.dev). 9 | module_;β ` +## invalid(50): (( exports = (( () => {} )) )) + +> Input + + `β + 1 | (( exports = (( () => {} )) ))β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | (( exports = (( () => {} )) ))β + | ^^ The arrow function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | const foo = (( () => {} ));β + 2 | (( exports = foo ));β + ` + +## invalid(51): (( module.exports = (( () => {} )) )) + +> Input + + `β + 1 | (( module.exports = (( () => {} )) ))β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | (( module.exports = (( () => {} )) ))β + | ^^ The arrow function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | const foo = (( () => {} ));β + 2 | (( module.exports = foo ));β + ` + ## invalid(1): @decorator export default class {} > Input diff --git a/test/snapshots/no-anonymous-default-export.mjs.snap b/test/snapshots/no-anonymous-default-export.mjs.snap index f2197aa38bc976fc7ccc87455dac127973ca0d58..578667e4432694bf167ba0f0634696dc956f203e 100644 GIT binary patch literal 2547 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 JXp6sW000-|%CG<c literal 2470 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 From 03c9c967986c0e2e4ca85fe3c71a1b43b25ef3b2 Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Wed, 7 Feb 2024 01:44:30 +0800 Subject: [PATCH 18/25] Only check expressions --- rules/no-anonymous-default-export.js | 4 ++++ test/no-anonymous-default-export.mjs | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js index e1feacae12..837f0fab4e 100644 --- a/rules/no-anonymous-default-export.js +++ b/rules/no-anonymous-default-export.js @@ -175,6 +175,10 @@ const create = context => { context.on('AssignmentExpression', (node) => { if ( !isAnonymousClassOrFunction(node.right) + || !( + node.parent.type === 'ExpressionStatement' + && node.parent.expression === node + ) || !( isMemberExpression(node.left, { object: 'module', diff --git a/test/no-anonymous-default-export.mjs b/test/no-anonymous-default-export.mjs index 845aab04e1..d42154e3b9 100644 --- a/test/no-anonymous-default-export.mjs +++ b/test/no-anonymous-default-export.mjs @@ -16,6 +16,8 @@ test.snapshot({ 'notModule.exports = class {}', 'module.notExports = class {}', 'module.exports.foo = class {}', + 'alert(exports = class {})', + 'foo = module.exports = class {}', ], invalid: [ 'export default function () {}', @@ -254,7 +256,6 @@ test.snapshot({ code: '(( module.exports = (( () => {} )) ))', filename: '/path/to/foo.js', }, - ], }); // Decorators From df2b8608b03653b2175a513e8a3b5615d9aaf37b Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Wed, 7 Feb 2024 01:45:54 +0800 Subject: [PATCH 19/25] Linting --- rules/no-anonymous-default-export.js | 22 +++++++++------------- test/no-anonymous-default-export.mjs | 1 + 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js index 837f0fab4e..18a5d6317f 100644 --- a/rules/no-anonymous-default-export.js +++ b/rules/no-anonymous-default-export.js @@ -90,15 +90,11 @@ function addName(fixer, node, name, sourceCode) { if (!/\s$/.test(textBefore)) { textBefore = `${textBefore} `; } + if (!textAfter.endsWith(';')) { - textAfter = `${textAfter};` + textAfter = `${textAfter};`; } - const shouldInsertSpaceAfterDefault - = !textBefore.endsWith(' ') - && !textBefore.endsWith('\n') - && !textBefore.endsWith('\t'); - return [ fixer.replaceTextRange( [exportDeclarationStart, arrowFunctionStart], @@ -106,7 +102,7 @@ function addName(fixer, node, name, sourceCode) { ), fixer.replaceTextRange( [arrowFunctionEnd, exportDeclarationEnd], - `;`, + ';', ), fixer.insertTextAfterRange( [exportDeclarationEnd, exportDeclarationEnd], @@ -164,15 +160,15 @@ function getProblem(node, context) { /** @param {import('eslint').Rule.RuleContext} context */ const create = context => { - context.on('ExportDefaultDeclaration', (node) => { + context.on('ExportDefaultDeclaration', node => { if (!isAnonymousClassOrFunction(node.declaration)) { return; } - return getProblem(node.declaration, context) + return getProblem(node.declaration, context); }); - context.on('AssignmentExpression', (node) => { + context.on('AssignmentExpression', node => { if ( !isAnonymousClassOrFunction(node.right) || !( @@ -184,7 +180,7 @@ const create = context => { object: 'module', property: 'exports', computed: false, - optional: false + optional: false, }) || ( node.left.type === 'Identifier', @@ -192,11 +188,11 @@ const create = context => { ) ) ) { - return + return; } return getProblem(node.right, context); - }) + }); }; /** @type {import('eslint').Rule.RuleModule} */ diff --git a/test/no-anonymous-default-export.mjs b/test/no-anonymous-default-export.mjs index d42154e3b9..02b57e7e71 100644 --- a/test/no-anonymous-default-export.mjs +++ b/test/no-anonymous-default-export.mjs @@ -256,6 +256,7 @@ test.snapshot({ code: '(( module.exports = (( () => {} )) ))', filename: '/path/to/foo.js', }, + ], }); // Decorators From eb78a88eaa3e365c5b17d89905d6b3a09c6fcb7d Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Wed, 7 Feb 2024 02:02:52 +0800 Subject: [PATCH 20/25] Fix codebase --- package.json | 3 ++- rules/no-anonymous-default-export.js | 1 - rules/utils/avoid-capture.js | 3 ++- rules/utils/cartesian-product-samples.js | 2 +- rules/utils/escape-string.js | 2 +- rules/utils/escape-template-element-raw.js | 3 ++- rules/utils/get-documentation-url.js | 2 +- rules/utils/get-variable-identifiers.js | 3 ++- rules/utils/has-same-range.js | 3 ++- rules/utils/is-object-method.js | 2 +- rules/utils/is-value-not-usable.js | 3 ++- rules/utils/resolve-variable-name.js | 2 +- 12 files changed, 17 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index c2ebe2dec4..df437f7798 100644 --- a/package.json +++ b/package.json @@ -134,7 +134,8 @@ ] } ], - "import/order": "off" + "import/order": "off", + "func-names": "off" }, "overrides": [ { diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js index 18a5d6317f..9ee199cd70 100644 --- a/rules/no-anonymous-default-export.js +++ b/rules/no-anonymous-default-export.js @@ -203,7 +203,6 @@ module.exports = { docs: { description: 'Disallow anonymous functions and classes as the default export.', }, - hasSuggestions: true, messages, }, diff --git a/rules/utils/avoid-capture.js b/rules/utils/avoid-capture.js index 9a1f9faa42..1de17b16c1 100644 --- a/rules/utils/avoid-capture.js +++ b/rules/utils/avoid-capture.js @@ -129,7 +129,7 @@ Useful when you want to rename a variable (or create a new variable) while being @param {isSafe} [isSafe] - Rule-specific name check function. @returns {string} - Either `name` as is, or a string like `${name}_` suffixed with underscores to make the name unique. */ -module.exports = (name, scopes, isSafe = alwaysTrue) => { +module.exports = function avoidCapture(name, scopes, isSafe = alwaysTrue) { if (!isValidIdentifier(name)) { name += '_'; @@ -144,3 +144,4 @@ module.exports = (name, scopes, isSafe = alwaysTrue) => { return name; }; + diff --git a/rules/utils/cartesian-product-samples.js b/rules/utils/cartesian-product-samples.js index 726b37ec87..e20926b265 100644 --- a/rules/utils/cartesian-product-samples.js +++ b/rules/utils/cartesian-product-samples.js @@ -1,6 +1,6 @@ 'use strict'; -module.exports = (combinations, length = Number.POSITIVE_INFINITY) => { +module.exports = function cartesianProductSamples(combinations, length = Number.POSITIVE_INFINITY) { const total = combinations.reduce((total, {length}) => total * length, 1); const samples = Array.from({length: Math.min(total, length)}, (_, sampleIndex) => { diff --git a/rules/utils/escape-string.js b/rules/utils/escape-string.js index be0ffc85ec..06c4ff04bb 100644 --- a/rules/utils/escape-string.js +++ b/rules/utils/escape-string.js @@ -9,7 +9,7 @@ Escape string and wrap the result in quotes. @param {string} [quote] - The quote character. @returns {string} - The quoted and escaped string. */ -module.exports = (string, quote = '\'') => { +module.exports = function escapeString(string, quote = '\'') { /* c8 ignore start */ if (typeof string !== 'string') { throw new TypeError('Unexpected string.'); diff --git a/rules/utils/escape-template-element-raw.js b/rules/utils/escape-template-element-raw.js index 1fdcbf7e27..14bc08c40a 100644 --- a/rules/utils/escape-template-element-raw.js +++ b/rules/utils/escape-template-element-raw.js @@ -1,6 +1,7 @@ 'use strict'; -module.exports = string => string.replaceAll( +const escapeTemplateElementRaw = string => string.replaceAll( /(?<=(?:^|[^\\])(?:\\\\)*)(?<symbol>(?:`|\$(?={)))/g, '\\$<symbol>', ); +module.exports = escapeTemplateElementRaw; diff --git a/rules/utils/get-documentation-url.js b/rules/utils/get-documentation-url.js index 3128369df3..0b1c9738f7 100644 --- a/rules/utils/get-documentation-url.js +++ b/rules/utils/get-documentation-url.js @@ -4,7 +4,7 @@ const packageJson = require('../../package.json'); const repoUrl = 'https://github.com/sindresorhus/eslint-plugin-unicorn'; -module.exports = filename => { +module.exports = function getDocumentationUrl(filename) { const ruleName = path.basename(filename, '.js'); return `${repoUrl}/blob/v${packageJson.version}/docs/rules/${ruleName}.md`; }; diff --git a/rules/utils/get-variable-identifiers.js b/rules/utils/get-variable-identifiers.js index 5a2617655d..816d5e6b40 100644 --- a/rules/utils/get-variable-identifiers.js +++ b/rules/utils/get-variable-identifiers.js @@ -1,7 +1,8 @@ 'use strict'; // Get identifiers of given variable -module.exports = ({identifiers, references}) => [...new Set([ +const getVariableIdentifiers = ({identifiers, references}) => [...new Set([ ...identifiers, ...references.map(({identifier}) => identifier), ])]; +module.exports = getVariableIdentifiers; diff --git a/rules/utils/has-same-range.js b/rules/utils/has-same-range.js index 07227b18e2..7018ffc159 100644 --- a/rules/utils/has-same-range.js +++ b/rules/utils/has-same-range.js @@ -1,7 +1,8 @@ 'use strict'; -module.exports = (node1, node2) => +const hasSameRange = (node1, node2) => node1 && node2 && node1.range[0] === node2.range[0] && node1.range[1] === node2.range[1]; +module.exports = hasSameRange; diff --git a/rules/utils/is-object-method.js b/rules/utils/is-object-method.js index c82184f277..f4df81a2dc 100644 --- a/rules/utils/is-object-method.js +++ b/rules/utils/is-object-method.js @@ -1,5 +1,5 @@ 'use strict'; -module.exports = (node, object, method) => { +module.exports = function isObjectMethod(node, object, method) { const {callee} = node; return ( callee.type === 'MemberExpression' diff --git a/rules/utils/is-value-not-usable.js b/rules/utils/is-value-not-usable.js index a838ffd926..88c5df827f 100644 --- a/rules/utils/is-value-not-usable.js +++ b/rules/utils/is-value-not-usable.js @@ -2,4 +2,5 @@ const {isExpressionStatement} = require('../ast/index.js'); -module.exports = node => isExpressionStatement(node.parent); +const isValueNotUsable = node => isExpressionStatement(node.parent); +module.exports = isValueNotUsable; diff --git a/rules/utils/resolve-variable-name.js b/rules/utils/resolve-variable-name.js index 09784128ff..f5b50d126a 100644 --- a/rules/utils/resolve-variable-name.js +++ b/rules/utils/resolve-variable-name.js @@ -7,7 +7,7 @@ Finds a variable named `name` in the scope `scope` (or it's parents). @param {Scope} scope - The scope to look for the variable in. @returns {Variable?} - The found variable, if any. */ -module.exports = (name, scope) => { +module.exports = function resolveVariableName(name, scope) { while (scope) { const variable = scope.set.get(name); From 0e2927a8bd2b8bc2a5bd1d88add03a62809ffcbe Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Wed, 7 Feb 2024 02:05:27 +0800 Subject: [PATCH 21/25] More tests --- test/no-anonymous-default-export.mjs | 10 ++- .../no-anonymous-default-export.mjs.md | 60 ++++++++++++++++-- .../no-anonymous-default-export.mjs.snap | Bin 2547 -> 2618 bytes 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/test/no-anonymous-default-export.mjs b/test/no-anonymous-default-export.mjs index 02b57e7e71..c9be26d50d 100644 --- a/test/no-anonymous-default-export.mjs +++ b/test/no-anonymous-default-export.mjs @@ -244,7 +244,7 @@ test.snapshot({ // comment 3 = // comment 4 - () => {} + () => {}; `, filename: '/path/to/module.js', }, @@ -256,6 +256,14 @@ test.snapshot({ code: '(( module.exports = (( () => {} )) ))', filename: '/path/to/foo.js', }, + { + code: '(( exports = (( () => {} )) ));', + filename: '/path/to/foo.js', + }, + { + code: '(( module.exports = (( () => {} )) ));', + filename: '/path/to/foo.js', + }, ], }); diff --git a/test/snapshots/no-anonymous-default-export.mjs.md b/test/snapshots/no-anonymous-default-export.mjs.md index b0d1d92665..3ded5c1065 100644 --- a/test/snapshots/no-anonymous-default-export.mjs.md +++ b/test/snapshots/no-anonymous-default-export.mjs.md @@ -1183,7 +1183,7 @@ Generated by [AVA](https://avajs.dev). 3 | exports = exports__;β ` -## invalid(49): // comment 1 module // comment 2 .exports // comment 3 = // comment 4 () => {} +## invalid(49): // comment 1 module // comment 2 .exports // comment 3 = // comment 4 () => {}; > Input @@ -1195,7 +1195,7 @@ Generated by [AVA](https://avajs.dev). 5 | // comment 3β 6 | =β 7 | // comment 4β - 8 | () => {}β + 8 | () => {};β ` > Filename @@ -1214,7 +1214,7 @@ Generated by [AVA](https://avajs.dev). 5 | // comment 3β 6 | =β 7 | // comment 4β - > 8 | () => {}β + > 8 | () => {};β | ^^ The arrow function should be named.β β --------------------------------------------------------------------------------β @@ -1227,7 +1227,7 @@ Generated by [AVA](https://avajs.dev). 6 | // comment 3β 7 | =β 8 | // comment 4β - 9 | module_;β + 9 | module_;;β ` ## invalid(50): (( exports = (( () => {} )) )) @@ -1282,6 +1282,58 @@ Generated by [AVA](https://avajs.dev). 2 | (( module.exports = foo ));β ` +## invalid(52): (( exports = (( () => {} )) )); + +> Input + + `β + 1 | (( exports = (( () => {} )) ));β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | (( exports = (( () => {} )) ));β + | ^^ The arrow function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | const foo = (( () => {} ));β + 2 | (( exports = foo ));;β + ` + +## invalid(53): (( module.exports = (( () => {} )) )); + +> Input + + `β + 1 | (( module.exports = (( () => {} )) ));β + ` + +> Filename + + `β + /path/to/foo.jsβ + ` + +> Error 1/1 + + `β + > 1 | (( module.exports = (( () => {} )) ));β + | ^^ The arrow function should be named.β + β + --------------------------------------------------------------------------------β + Suggestion 1/1: Name it as \`foo\`.β + 1 | const foo = (( () => {} ));β + 2 | (( module.exports = foo ));;β + ` + ## invalid(1): @decorator export default class {} > Input diff --git a/test/snapshots/no-anonymous-default-export.mjs.snap b/test/snapshots/no-anonymous-default-export.mjs.snap index 578667e4432694bf167ba0f0634696dc956f203e..2a6cca8849280a20e1087ccc2644c0685556f280 100644 GIT binary patch literal 2618 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 literal 2547 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 JXp6sW000-|%CG<c From 3b52c8a54a2e355d859501a538a552900d50284b Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Wed, 7 Feb 2024 02:11:27 +0800 Subject: [PATCH 22/25] Improve fix --- rules/no-anonymous-default-export.js | 5 ++++- .../no-anonymous-default-export.mjs.md | 6 +++--- .../no-anonymous-default-export.mjs.snap | Bin 2618 -> 2613 bytes 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js index 9ee199cd70..0b1b65c54b 100644 --- a/rules/no-anonymous-default-export.js +++ b/rules/no-anonymous-default-export.js @@ -80,7 +80,10 @@ function addName(fixer, node, name, sourceCode) { } case 'ArrowFunctionExpression': { - const [exportDeclarationStart, exportDeclarationEnd] = getParenthesizedRange(node.parent, sourceCode); + const [exportDeclarationStart, exportDeclarationEnd] = + node.parent.parent.type === 'ExpressionStatement' + ? node.parent.parent.range + : node.parent.range; const [arrowFunctionStart, arrowFunctionEnd] = getParenthesizedRange(node, sourceCode); let textBefore = sourceCode.text.slice(exportDeclarationStart, arrowFunctionStart); diff --git a/test/snapshots/no-anonymous-default-export.mjs.md b/test/snapshots/no-anonymous-default-export.mjs.md index 3ded5c1065..d016aec97d 100644 --- a/test/snapshots/no-anonymous-default-export.mjs.md +++ b/test/snapshots/no-anonymous-default-export.mjs.md @@ -1227,7 +1227,7 @@ Generated by [AVA](https://avajs.dev). 6 | // comment 3β 7 | =β 8 | // comment 4β - 9 | module_;;β + 9 | module_;β ` ## invalid(50): (( exports = (( () => {} )) )) @@ -1305,7 +1305,7 @@ Generated by [AVA](https://avajs.dev). --------------------------------------------------------------------------------β Suggestion 1/1: Name it as \`foo\`.β 1 | const foo = (( () => {} ));β - 2 | (( exports = foo ));;β + 2 | (( exports = foo ));β ` ## invalid(53): (( module.exports = (( () => {} )) )); @@ -1331,7 +1331,7 @@ Generated by [AVA](https://avajs.dev). --------------------------------------------------------------------------------β Suggestion 1/1: Name it as \`foo\`.β 1 | const foo = (( () => {} ));β - 2 | (( module.exports = foo ));;β + 2 | (( module.exports = foo ));β ` ## invalid(1): @decorator export default class {} diff --git a/test/snapshots/no-anonymous-default-export.mjs.snap b/test/snapshots/no-anonymous-default-export.mjs.snap index 2a6cca8849280a20e1087ccc2644c0685556f280..5d4237c13aabef49691413cb90cf9830c43f5350 100644 GIT binary patch delta 2306 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 delta 2312 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 From a8a968ea4ccd7f4c4576c1a10e5f8bb15822a7a6 Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Wed, 7 Feb 2024 02:12:55 +0800 Subject: [PATCH 23/25] linting --- rules/no-anonymous-default-export.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js index 0b1b65c54b..e7ecc251cb 100644 --- a/rules/no-anonymous-default-export.js +++ b/rules/no-anonymous-default-export.js @@ -80,10 +80,10 @@ function addName(fixer, node, name, sourceCode) { } case 'ArrowFunctionExpression': { - const [exportDeclarationStart, exportDeclarationEnd] = - node.parent.parent.type === 'ExpressionStatement' - ? node.parent.parent.range - : node.parent.range; + const [exportDeclarationStart, exportDeclarationEnd] + = node.parent.parent.type === 'ExpressionStatement' + ? node.parent.parent.range + : node.parent.range; const [arrowFunctionStart, arrowFunctionEnd] = getParenthesizedRange(node, sourceCode); let textBefore = sourceCode.text.slice(exportDeclarationStart, arrowFunctionStart); From 3d73e06d9c598c20ba9d55b2bc1e5e6d7f4a2024 Mon Sep 17 00:00:00 2001 From: fisker <lionkay@gmail.com> Date: Wed, 7 Feb 2024 02:13:45 +0800 Subject: [PATCH 24/25] Check parent type instead --- rules/no-anonymous-default-export.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rules/no-anonymous-default-export.js b/rules/no-anonymous-default-export.js index e7ecc251cb..f520801af5 100644 --- a/rules/no-anonymous-default-export.js +++ b/rules/no-anonymous-default-export.js @@ -81,9 +81,9 @@ function addName(fixer, node, name, sourceCode) { case 'ArrowFunctionExpression': { const [exportDeclarationStart, exportDeclarationEnd] - = node.parent.parent.type === 'ExpressionStatement' - ? node.parent.parent.range - : node.parent.range; + = node.parent.type === 'ExportDefaultDeclaration' + ? node.parent.range + : node.parent.parent.range; const [arrowFunctionStart, arrowFunctionEnd] = getParenthesizedRange(node, sourceCode); let textBefore = sourceCode.text.slice(exportDeclarationStart, arrowFunctionStart); From 6ff9e91b5e858093427638c695527f7c1d279bc5 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus <sindresorhus@gmail.com> Date: Fri, 9 Feb 2024 17:55:38 +0700 Subject: [PATCH 25/25] Update no-anonymous-default-export.md --- docs/rules/no-anonymous-default-export.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/no-anonymous-default-export.md b/docs/rules/no-anonymous-default-export.md index 40511fbbed..8ac3c117fe 100644 --- a/docs/rules/no-anonymous-default-export.md +++ b/docs/rules/no-anonymous-default-export.md @@ -7,7 +7,7 @@ <!-- end auto-generated rule header --> <!-- Do not manually modify this header. Run: `npm run fix:eslint-docs` --> -Ensuring that default exports are named helps improve the grepability of the codebase by encouraging the re-use of the same identifier for the module's default export at its declaration site and at its import sites. +Naming default exports improves codebase searchability by ensuring consistent identifier use for a module's default export, both where it's declared and where it's imported. ## Fail