From 3a31ae49644876ef5aea128a8545ac32ddce36f6 Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Mon, 1 Jul 2024 16:21:26 +0900 Subject: [PATCH] feat!: separate the rules of ES2022 - ES2024 by features (#150) --- docs/configs/index.md | 162 ++++++++++++ docs/rules/index.md | 25 +- docs/rules/no-array-prototype-at.md | 58 +++++ docs/rules/no-array-prototype-toreversed.md | 3 +- docs/rules/no-array-prototype-tosorted.md | 3 +- docs/rules/no-array-prototype-tospliced.md | 3 +- docs/rules/no-array-prototype-with.md | 3 +- docs/rules/no-array-string-prototype-at.md | 13 +- docs/rules/no-class-fields.md | 13 +- docs/rules/no-class-instance-fields.md | 45 ++++ docs/rules/no-class-private-fields.md | 50 ++++ docs/rules/no-class-private-methods.md | 50 ++++ docs/rules/no-class-static-fields.md | 45 ++++ ...intl-numberformat-prototype-formatrange.md | 3 +- ...mberformat-prototype-formatrangetoparts.md | 3 +- ...-intl-pluralrules-prototype-selectrange.md | 3 +- docs/rules/no-map-groupby.md | 46 ++++ docs/rules/no-object-groupby.md | 46 ++++ docs/rules/no-object-map-groupby.md | 15 +- docs/rules/no-string-prototype-at.md | 58 +++++ ...ing-prototype-iswellformed-towellformed.md | 15 +- .../rules/no-string-prototype-iswellformed.md | 58 +++++ .../rules/no-string-prototype-towellformed.md | 58 +++++ lib/configs/flat/no-array-grouping.js | 17 ++ lib/configs/flat/no-change-array-by-copy.js | 19 ++ lib/configs/flat/no-class-fields.js | 19 ++ lib/configs/flat/no-intl-numberformat-v3.js | 18 ++ lib/configs/flat/no-is-usv-string.js | 17 ++ lib/configs/flat/no-new-in-es2022.js | 8 +- lib/configs/flat/no-new-in-es2024.js | 6 +- .../flat/no-relative-indexing-method.js | 17 ++ lib/configs/no-array-grouping.js | 13 + lib/configs/no-change-array-by-copy.js | 15 ++ lib/configs/no-class-fields.js | 15 ++ lib/configs/no-intl-numberformat-v3.js | 14 ++ lib/configs/no-is-usv-string.js | 13 + lib/configs/no-new-in-es2022.js | 8 +- lib/configs/no-new-in-es2024.js | 6 +- lib/configs/no-relative-indexing-method.js | 13 + lib/index.js | 22 ++ lib/rules/no-array-prototype-at.js | 51 ++++ lib/rules/no-array-prototype-toreversed.js | 1 + lib/rules/no-array-prototype-tosorted.js | 1 + lib/rules/no-array-prototype-tospliced.js | 1 + lib/rules/no-array-prototype-with.js | 1 + lib/rules/no-array-string-prototype-at.js | 41 ++-- lib/rules/no-class-fields.js | 116 +++------ lib/rules/no-class-instance-fields.js | 50 ++++ lib/rules/no-class-private-fields.js | 69 ++++++ lib/rules/no-class-private-methods.js | 47 ++++ lib/rules/no-class-static-fields.js | 50 ++++ ...intl-numberformat-prototype-formatrange.js | 1 + ...mberformat-prototype-formatrangetoparts.js | 1 + ...-intl-pluralrules-prototype-selectrange.js | 1 + lib/rules/no-map-groupby.js | 43 ++++ lib/rules/no-object-groupby.js | 43 ++++ lib/rules/no-object-map-groupby.js | 42 ++-- lib/rules/no-string-prototype-at.js | 40 +++ ...ing-prototype-iswellformed-towellformed.js | 31 ++- lib/rules/no-string-prototype-iswellformed.js | 37 +++ lib/rules/no-string-prototype-towellformed.js | 37 +++ lib/utils.js | 28 +++ scripts/proposals.js | 24 ++ scripts/update-docs-rules.js | 3 + tests/lib/rules/no-array-prototype-at.js | 231 ++++++++++++++++++ .../lib/rules/no-array-string-prototype-at.js | 15 +- tests/lib/rules/no-class-fields.js | 75 ++++-- tests/lib/rules/no-class-instance-fields.js | 153 ++++++++++++ tests/lib/rules/no-class-private-fields.js | 196 +++++++++++++++ tests/lib/rules/no-class-private-methods.js | 161 ++++++++++++ tests/lib/rules/no-class-static-fields.js | 153 ++++++++++++ tests/lib/rules/no-map-groupby.js | 20 ++ tests/lib/rules/no-object-groupby.js | 20 ++ tests/lib/rules/no-string-prototype-at.js | 109 +++++++++ .../rules/no-string-prototype-iswellformed.js | 140 +++++++++++ .../rules/no-string-prototype-towelformed.js | 140 +++++++++++ 76 files changed, 2954 insertions(+), 236 deletions(-) create mode 100644 docs/rules/no-array-prototype-at.md create mode 100644 docs/rules/no-class-instance-fields.md create mode 100644 docs/rules/no-class-private-fields.md create mode 100644 docs/rules/no-class-private-methods.md create mode 100644 docs/rules/no-class-static-fields.md create mode 100644 docs/rules/no-map-groupby.md create mode 100644 docs/rules/no-object-groupby.md create mode 100644 docs/rules/no-string-prototype-at.md create mode 100644 docs/rules/no-string-prototype-iswellformed.md create mode 100644 docs/rules/no-string-prototype-towellformed.md create mode 100644 lib/configs/flat/no-array-grouping.js create mode 100644 lib/configs/flat/no-change-array-by-copy.js create mode 100644 lib/configs/flat/no-class-fields.js create mode 100644 lib/configs/flat/no-intl-numberformat-v3.js create mode 100644 lib/configs/flat/no-is-usv-string.js create mode 100644 lib/configs/flat/no-relative-indexing-method.js create mode 100644 lib/configs/no-array-grouping.js create mode 100644 lib/configs/no-change-array-by-copy.js create mode 100644 lib/configs/no-class-fields.js create mode 100644 lib/configs/no-intl-numberformat-v3.js create mode 100644 lib/configs/no-is-usv-string.js create mode 100644 lib/configs/no-relative-indexing-method.js create mode 100644 lib/rules/no-array-prototype-at.js create mode 100644 lib/rules/no-class-instance-fields.js create mode 100644 lib/rules/no-class-private-fields.js create mode 100644 lib/rules/no-class-private-methods.js create mode 100644 lib/rules/no-class-static-fields.js create mode 100644 lib/rules/no-map-groupby.js create mode 100644 lib/rules/no-object-groupby.js create mode 100644 lib/rules/no-string-prototype-at.js create mode 100644 lib/rules/no-string-prototype-iswellformed.js create mode 100644 lib/rules/no-string-prototype-towellformed.js create mode 100644 tests/lib/rules/no-array-prototype-at.js create mode 100644 tests/lib/rules/no-class-instance-fields.js create mode 100644 tests/lib/rules/no-class-private-fields.js create mode 100644 tests/lib/rules/no-class-private-methods.js create mode 100644 tests/lib/rules/no-class-static-fields.js create mode 100644 tests/lib/rules/no-map-groupby.js create mode 100644 tests/lib/rules/no-object-groupby.js create mode 100644 tests/lib/rules/no-string-prototype-at.js create mode 100644 tests/lib/rules/no-string-prototype-iswellformed.js create mode 100644 tests/lib/rules/no-string-prototype-towelformed.js diff --git a/docs/configs/index.md b/docs/configs/index.md index bca093d2..110fdf1d 100644 --- a/docs/configs/index.md +++ b/docs/configs/index.md @@ -1031,5 +1031,167 @@ export default [ } ``` +## no-array-grouping + +disallow proposal ES2024 [Array Grouping](https://github.com/tc39/proposal-array-grouping) + +This configs includes rules for [es-x/no-map-groupby](../rules/no-map-groupby.md) and [es-x/no-object-groupby](../rules/no-object-groupby.md). + +### [Config (Flat Config)] + +eslint.config.js: + +```js +import pluginESx from "eslint-plugin-es-x" +export default [ + pluginESx.configs['flat/no-array-grouping'] +] +``` + +### [Legacy Config] + +.eslintrc.*: + +```json +{ + "extends": ["plugin:es-x/no-array-grouping"], +} +``` + +## no-is-usv-string + +disallow proposal ES2024 [Well-Formed Unicode Strings](https://github.com/tc39/proposal-is-usv-string) + +This configs includes rules for [es-x/no-string-prototype-iswellformed](../rules/no-string-prototype-iswellformed.md) and [es-x/no-string-prototype-towellformed](../rules/no-string-prototype-towellformed.md). + +### [Config (Flat Config)] + +eslint.config.js: + +```js +import pluginESx from "eslint-plugin-es-x" +export default [ + pluginESx.configs['flat/no-is-usv-string'] +] +``` + +### [Legacy Config] + +.eslintrc.*: + +```json +{ + "extends": ["plugin:es-x/no-is-usv-string"], +} +``` + +## no-change-array-by-copy + +disallow proposal ES2023 [Change Array by Copy](https://github.com/tc39/proposal-change-array-by-copy) + +This configs includes rules for [es-x/no-array-prototype-toreversed](../rules/no-array-prototype-toreversed.md), [es-x/no-array-prototype-tosorted](../rules/no-array-prototype-tosorted.md), [es-x/no-array-prototype-tospliced](../rules/no-array-prototype-tospliced.md), and [es-x/no-array-prototype-with](../rules/no-array-prototype-with.md). + +### [Config (Flat Config)] + +eslint.config.js: + +```js +import pluginESx from "eslint-plugin-es-x" +export default [ + pluginESx.configs['flat/no-change-array-by-copy'] +] +``` + +### [Legacy Config] + +.eslintrc.*: + +```json +{ + "extends": ["plugin:es-x/no-change-array-by-copy"], +} +``` + +## no-intl-numberformat-v3 + +disallow proposal ES2023 Intl API [Intl.NumberFormat V3](https://github.com/tc39/proposal-intl-numberformat-v3) + +This configs includes rules for [es-x/no-intl-numberformat-prototype-formatrange](../rules/no-intl-numberformat-prototype-formatrange.md), [es-x/no-intl-numberformat-prototype-formatrangetoparts](../rules/no-intl-numberformat-prototype-formatrangetoparts.md), and [es-x/no-intl-pluralrules-prototype-selectrange](../rules/no-intl-pluralrules-prototype-selectrange.md). + +### [Config (Flat Config)] + +eslint.config.js: + +```js +import pluginESx from "eslint-plugin-es-x" +export default [ + pluginESx.configs['flat/no-intl-numberformat-v3'] +] +``` + +### [Legacy Config] + +.eslintrc.*: + +```json +{ + "extends": ["plugin:es-x/no-intl-numberformat-v3"], +} +``` + +## no-class-fields + +disallow proposal ES2022 [Class Fields](https://github.com/tc39/proposal-class-fields) + +This configs includes rules for [es-x/no-class-instance-fields](../rules/no-class-instance-fields.md), [es-x/no-class-private-fields](../rules/no-class-private-fields.md), [es-x/no-class-private-methods](../rules/no-class-private-methods.md), and [es-x/no-class-static-fields](../rules/no-class-static-fields.md). + +### [Config (Flat Config)] + +eslint.config.js: + +```js +import pluginESx from "eslint-plugin-es-x" +export default [ + pluginESx.configs['flat/no-class-fields'] +] +``` + +### [Legacy Config] + +.eslintrc.*: + +```json +{ + "extends": ["plugin:es-x/no-class-fields"], +} +``` + +## no-relative-indexing-method + +disallow proposal ES2022 [An .at() method on all the built-in indexables](https://github.com/tc39/proposal-relative-indexing-method) + +This configs includes rules for [es-x/no-array-prototype-at](../rules/no-array-prototype-at.md) and [es-x/no-string-prototype-at](../rules/no-string-prototype-at.md). + +### [Config (Flat Config)] + +eslint.config.js: + +```js +import pluginESx from "eslint-plugin-es-x" +export default [ + pluginESx.configs['flat/no-relative-indexing-method'] +] +``` + +### [Legacy Config] + +.eslintrc.*: + +```json +{ + "extends": ["plugin:es-x/no-relative-indexing-method"], +} +``` + [Config (Flat Config)]: https://eslint.org/docs/latest/use/configure/configuration-files-new [Legacy Config]: https://eslint.org/docs/latest/use/configure/configuration-files diff --git a/docs/rules/index.md b/docs/rules/index.md index 7ddf0855..ab3f0bcc 100644 --- a/docs/rules/index.md +++ b/docs/rules/index.md @@ -27,11 +27,13 @@ There are multiple configs that enable all rules in this category: [`no-new-in-e |:--------|:------------|:--:| | [es-x/no-arraybuffer-prototype-transfer](./no-arraybuffer-prototype-transfer.md) | disallow the `ArrayBuffer.prototype.transfer` method. | | | [es-x/no-atomics-waitasync](./no-atomics-waitasync.md) | disallow the `Atomics.waitAsync` method. | | -| [es-x/no-object-map-groupby](./no-object-map-groupby.md) | disallow the `{Object,Map}.groupBy()` function (array grouping). | | +| [es-x/no-map-groupby](./no-map-groupby.md) | disallow the `Map.groupBy()` method. | | +| [es-x/no-object-groupby](./no-object-groupby.md) | disallow the `Object.groupBy()` method. | | | [es-x/no-promise-withresolvers](./no-promise-withresolvers.md) | disallow the `Promise.withResolvers()` method. | | | [es-x/no-regexp-v-flag](./no-regexp-v-flag.md) | disallow RegExp `v` flag. | | | [es-x/no-resizable-and-growable-arraybuffers](./no-resizable-and-growable-arraybuffers.md) | disallow resizable and growable ArrayBuffers. | | -| [es-x/no-string-prototype-iswellformed-towellformed](./no-string-prototype-iswellformed-towellformed.md) | disallow the `String.prototype.{isWellFormed,toWellFormed}` methods. | | +| [es-x/no-string-prototype-iswellformed](./no-string-prototype-iswellformed.md) | disallow the `String.prototype.isWellFormed` methods. | | +| [es-x/no-string-prototype-towellformed](./no-string-prototype-towellformed.md) | disallow the `String.prototype.toWellFormed` methods. | | ## ES2023 @@ -64,14 +66,18 @@ There are multiple configs that enable all rules in this category: [`no-new-in-e | Rule ID | Description | | |:--------|:------------|:--:| | [es-x/no-arbitrary-module-namespace-names](./no-arbitrary-module-namespace-names.md) | disallow arbitrary module namespace names. | | -| [es-x/no-array-string-prototype-at](./no-array-string-prototype-at.md) | disallow the `{Array,String}.prototype.at()` methods. | | -| [es-x/no-class-fields](./no-class-fields.md) | disallow class fields. | | +| [es-x/no-array-prototype-at](./no-array-prototype-at.md) | disallow the `Array.prototype.at()` methods. | | +| [es-x/no-class-instance-fields](./no-class-instance-fields.md) | disallow instance class fields. | | +| [es-x/no-class-private-fields](./no-class-private-fields.md) | disallow private class fields. | | +| [es-x/no-class-private-methods](./no-class-private-methods.md) | disallow private class methods. | | | [es-x/no-class-static-block](./no-class-static-block.md) | disallow class static block. | | +| [es-x/no-class-static-fields](./no-class-static-fields.md) | disallow static class fields. | | | [es-x/no-error-cause](./no-error-cause.md) | disallow Error Cause. | | | [es-x/no-object-hasown](./no-object-hasown.md) | disallow the `Object.hasOwn` method. | | | [es-x/no-private-in](./no-private-in.md) | disallow `#x in obj`. | | | [es-x/no-regexp-d-flag](./no-regexp-d-flag.md) | disallow RegExp `d` flag. | | | [es-x/no-regexp-unicode-property-escapes-2022](./no-regexp-unicode-property-escapes-2022.md) | disallow the new values of RegExp Unicode property escape sequences in ES2022. | | +| [es-x/no-string-prototype-at](./no-string-prototype-at.md) | disallow the `String.prototype.at()` methods. | | | [es-x/no-top-level-await](./no-top-level-await.md) | disallow top-level `await`. | | ## ES2022 Intl API @@ -353,6 +359,17 @@ Rules in this category are not included in any preset. | [es-x/no-string-prototype-substr](./no-string-prototype-substr.md) | disallow the `String.prototype.substr` method. | | | [es-x/no-string-prototype-trimleft-trimright](./no-string-prototype-trimleft-trimright.md) | disallow the `String.prototype.{trimLeft,trimRight}` methods. | 🔧 | +## Deprecated + +😇 We don't fix bugs which are in deprecated rules since we don't have enough resources. + +| Rule ID | Replaced By | +|:--------|:------------:| +| [es-x/no-array-string-prototype-at](./no-array-string-prototype-at.md) | [es-x/no-array-prototype-at](./no-array-prototype-at.md), [es-x/no-string-prototype-at](./no-string-prototype-at.md) | +| [es-x/no-class-fields](./no-class-fields.md) | [es-x/no-class-instance-fields](./no-class-instance-fields.md), [es-x/no-class-private-fields](./no-class-private-fields.md), [es-x/no-class-private-methods](./no-class-private-methods.md), [es-x/no-class-static-fields](./no-class-static-fields.md) | +| [es-x/no-object-map-groupby](./no-object-map-groupby.md) | [es-x/no-object-groupby](./no-object-groupby.md), [es-x/no-map-groupby](./no-map-groupby.md) | +| [es-x/no-string-prototype-iswellformed-towellformed](./no-string-prototype-iswellformed-towellformed.md) | [es-x/no-string-prototype-iswellformed](./no-string-prototype-iswellformed.md), [es-x/no-string-prototype-towellformed](./no-string-prototype-towellformed.md) | + [`no-new-in-esnext`]: ../configs/index.md#no-new-in-esnext [`no-new-in-es2024`]: ../configs/index.md#no-new-in-es2024 [`restrict-to-es2023`]: ../configs/index.md#restrict-to-es2023 diff --git a/docs/rules/no-array-prototype-at.md b/docs/rules/no-array-prototype-at.md new file mode 100644 index 00000000..8f1750b9 --- /dev/null +++ b/docs/rules/no-array-prototype-at.md @@ -0,0 +1,58 @@ +--- +title: "es-x/no-array-prototype-at" +description: "disallow the `Array.prototype.at()` methods" +--- + +# es-x/no-array-prototype-at +> disallow the `Array.prototype.at()` methods + +- ❗ ***This rule has not been released yet.*** +- ✅ The following configurations enable this rule: [no-new-in-es2022], [no-relative-indexing-method], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], and [restrict-to-es2021] + +This rule reports ES2022 [`{Array,TypedArray}.prototype.at` methods](https://github.com/tc39/proposal-relative-indexing-method) as errors. + +This rule is silent by default because it's hard to know types. You need to configure [the aggressive mode](../#the-aggressive-mode) or TypeScript in order to enable this rule. + +## 💡 Examples + +⛔ Examples of **incorrect** code for this rule: + + + +```js +/*eslint es-x/no-array-prototype-at: [error, { aggressive: true }] */ +[foo].at(-1) +``` + + + +## 🔧 Options + +This rule has an option. + +```yaml +rules: + es-x/no-array-prototype-at: [error, { aggressive: false }] +``` + +### aggressive: boolean + +Configure the aggressive mode for only this rule. +This is prior to the `settings['es-x'].aggressive` setting. + +## 📚 References + +- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-array-prototype-at.js) +- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-array-prototype-at.js) + +[no-new-in-es2022]: ../configs/index.md#no-new-in-es2022 +[no-relative-indexing-method]: ../configs/index.md#no-relative-indexing-method +[restrict-to-es3]: ../configs/index.md#restrict-to-es3 +[restrict-to-es5]: ../configs/index.md#restrict-to-es5 +[restrict-to-es2015]: ../configs/index.md#restrict-to-es2015 +[restrict-to-es2016]: ../configs/index.md#restrict-to-es2016 +[restrict-to-es2017]: ../configs/index.md#restrict-to-es2017 +[restrict-to-es2018]: ../configs/index.md#restrict-to-es2018 +[restrict-to-es2019]: ../configs/index.md#restrict-to-es2019 +[restrict-to-es2020]: ../configs/index.md#restrict-to-es2020 +[restrict-to-es2021]: ../configs/index.md#restrict-to-es2021 diff --git a/docs/rules/no-array-prototype-toreversed.md b/docs/rules/no-array-prototype-toreversed.md index 049b6358..63df6d2d 100644 --- a/docs/rules/no-array-prototype-toreversed.md +++ b/docs/rules/no-array-prototype-toreversed.md @@ -7,7 +7,7 @@ since: "v6.0.0" # es-x/no-array-prototype-toreversed > disallow the `Array.prototype.toReversed` method -- ✅ The following configurations enable this rule: [no-new-in-es2023], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], [restrict-to-es2021], and [restrict-to-es2022] +- ✅ The following configurations enable this rule: [no-change-array-by-copy], [no-new-in-es2023], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], [restrict-to-es2021], and [restrict-to-es2022] This rule reports ES2023 [`Array.prototype.toReversed` methods](https://github.com/tc39/proposal-change-array-by-copy) as errors. @@ -49,6 +49,7 @@ This rule was introduced in v6.0.0. - [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-array-prototype-toreversed.js) - [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-array-prototype-toreversed.js) +[no-change-array-by-copy]: ../configs/index.md#no-change-array-by-copy [no-new-in-es2023]: ../configs/index.md#no-new-in-es2023 [restrict-to-es3]: ../configs/index.md#restrict-to-es3 [restrict-to-es5]: ../configs/index.md#restrict-to-es5 diff --git a/docs/rules/no-array-prototype-tosorted.md b/docs/rules/no-array-prototype-tosorted.md index 3d221ee9..00034134 100644 --- a/docs/rules/no-array-prototype-tosorted.md +++ b/docs/rules/no-array-prototype-tosorted.md @@ -7,7 +7,7 @@ since: "v6.0.0" # es-x/no-array-prototype-tosorted > disallow the `Array.prototype.toSorted` method -- ✅ The following configurations enable this rule: [no-new-in-es2023], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], [restrict-to-es2021], and [restrict-to-es2022] +- ✅ The following configurations enable this rule: [no-change-array-by-copy], [no-new-in-es2023], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], [restrict-to-es2021], and [restrict-to-es2022] This rule reports ES2023 [`Array.prototype.toSorted` methods](https://github.com/tc39/proposal-change-array-by-copy) as errors. @@ -49,6 +49,7 @@ This rule was introduced in v6.0.0. - [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-array-prototype-tosorted.js) - [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-array-prototype-tosorted.js) +[no-change-array-by-copy]: ../configs/index.md#no-change-array-by-copy [no-new-in-es2023]: ../configs/index.md#no-new-in-es2023 [restrict-to-es3]: ../configs/index.md#restrict-to-es3 [restrict-to-es5]: ../configs/index.md#restrict-to-es5 diff --git a/docs/rules/no-array-prototype-tospliced.md b/docs/rules/no-array-prototype-tospliced.md index b42d0c97..efb1585f 100644 --- a/docs/rules/no-array-prototype-tospliced.md +++ b/docs/rules/no-array-prototype-tospliced.md @@ -7,7 +7,7 @@ since: "v6.0.0" # es-x/no-array-prototype-tospliced > disallow the `Array.prototype.toSpliced` method -- ✅ The following configurations enable this rule: [no-new-in-es2023], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], [restrict-to-es2021], and [restrict-to-es2022] +- ✅ The following configurations enable this rule: [no-change-array-by-copy], [no-new-in-es2023], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], [restrict-to-es2021], and [restrict-to-es2022] This rule reports ES2023 [`Array.prototype.toSpliced` methods](https://github.com/tc39/proposal-change-array-by-copy) as errors. @@ -49,6 +49,7 @@ This rule was introduced in v6.0.0. - [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-array-prototype-tospliced.js) - [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-array-prototype-tospliced.js) +[no-change-array-by-copy]: ../configs/index.md#no-change-array-by-copy [no-new-in-es2023]: ../configs/index.md#no-new-in-es2023 [restrict-to-es3]: ../configs/index.md#restrict-to-es3 [restrict-to-es5]: ../configs/index.md#restrict-to-es5 diff --git a/docs/rules/no-array-prototype-with.md b/docs/rules/no-array-prototype-with.md index ffa49143..f04eec98 100644 --- a/docs/rules/no-array-prototype-with.md +++ b/docs/rules/no-array-prototype-with.md @@ -7,7 +7,7 @@ since: "v6.0.0" # es-x/no-array-prototype-with > disallow the `Array.prototype.with` method -- ✅ The following configurations enable this rule: [no-new-in-es2023], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], [restrict-to-es2021], and [restrict-to-es2022] +- ✅ The following configurations enable this rule: [no-change-array-by-copy], [no-new-in-es2023], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], [restrict-to-es2021], and [restrict-to-es2022] This rule reports ES2023 [`Array.prototype.with` methods](https://github.com/tc39/proposal-change-array-by-copy) as errors. @@ -49,6 +49,7 @@ This rule was introduced in v6.0.0. - [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-array-prototype-with.js) - [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-array-prototype-with.js) +[no-change-array-by-copy]: ../configs/index.md#no-change-array-by-copy [no-new-in-es2023]: ../configs/index.md#no-new-in-es2023 [restrict-to-es3]: ../configs/index.md#restrict-to-es3 [restrict-to-es5]: ../configs/index.md#restrict-to-es5 diff --git a/docs/rules/no-array-string-prototype-at.md b/docs/rules/no-array-string-prototype-at.md index d79fd8da..b3697726 100644 --- a/docs/rules/no-array-string-prototype-at.md +++ b/docs/rules/no-array-string-prototype-at.md @@ -7,7 +7,7 @@ since: "v5.0.0" # es-x/no-array-string-prototype-at > disallow the `{Array,String}.prototype.at()` methods -- ✅ The following configurations enable this rule: [no-new-in-es2022], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], and [restrict-to-es2021] +- 🚫 This rule was deprecated and replaced by [es-x/no-array-prototype-at](./no-array-prototype-at.md),[es-x/no-string-prototype-at](./no-string-prototype-at.md) rules. This rule reports ES2022 [`{Array,String,TypedArray}.prototype.at` methods](https://github.com/tc39/proposal-relative-indexing-method) as errors. @@ -49,14 +49,3 @@ This rule was introduced in v5.0.0. - [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-array-string-prototype-at.js) - [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-array-string-prototype-at.js) - -[no-new-in-es2022]: ../configs/index.md#no-new-in-es2022 -[restrict-to-es3]: ../configs/index.md#restrict-to-es3 -[restrict-to-es5]: ../configs/index.md#restrict-to-es5 -[restrict-to-es2015]: ../configs/index.md#restrict-to-es2015 -[restrict-to-es2016]: ../configs/index.md#restrict-to-es2016 -[restrict-to-es2017]: ../configs/index.md#restrict-to-es2017 -[restrict-to-es2018]: ../configs/index.md#restrict-to-es2018 -[restrict-to-es2019]: ../configs/index.md#restrict-to-es2019 -[restrict-to-es2020]: ../configs/index.md#restrict-to-es2020 -[restrict-to-es2021]: ../configs/index.md#restrict-to-es2021 diff --git a/docs/rules/no-class-fields.md b/docs/rules/no-class-fields.md index dda7bad5..5adab6a3 100644 --- a/docs/rules/no-class-fields.md +++ b/docs/rules/no-class-fields.md @@ -7,7 +7,7 @@ since: "v5.0.0" # es-x/no-class-fields > disallow class fields -- ✅ The following configurations enable this rule: [no-new-in-es2022], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], and [restrict-to-es2021] +- 🚫 This rule was deprecated and replaced by [es-x/no-class-instance-fields](./no-class-instance-fields.md),[es-x/no-class-private-fields](./no-class-private-fields.md),[es-x/no-class-private-methods](./no-class-private-methods.md),[es-x/no-class-static-fields](./no-class-static-fields.md) rules. This rule reports class fields as errors. @@ -52,14 +52,3 @@ This rule was introduced in v5.0.0. - [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-class-fields.js) - [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-class-fields.js) - -[no-new-in-es2022]: ../configs/index.md#no-new-in-es2022 -[restrict-to-es3]: ../configs/index.md#restrict-to-es3 -[restrict-to-es5]: ../configs/index.md#restrict-to-es5 -[restrict-to-es2015]: ../configs/index.md#restrict-to-es2015 -[restrict-to-es2016]: ../configs/index.md#restrict-to-es2016 -[restrict-to-es2017]: ../configs/index.md#restrict-to-es2017 -[restrict-to-es2018]: ../configs/index.md#restrict-to-es2018 -[restrict-to-es2019]: ../configs/index.md#restrict-to-es2019 -[restrict-to-es2020]: ../configs/index.md#restrict-to-es2020 -[restrict-to-es2021]: ../configs/index.md#restrict-to-es2021 diff --git a/docs/rules/no-class-instance-fields.md b/docs/rules/no-class-instance-fields.md new file mode 100644 index 00000000..d99fee8e --- /dev/null +++ b/docs/rules/no-class-instance-fields.md @@ -0,0 +1,45 @@ +--- +title: "es-x/no-class-instance-fields" +description: "disallow instance class fields" +--- + +# es-x/no-class-instance-fields +> disallow instance class fields + +- ❗ ***This rule has not been released yet.*** +- ✅ The following configurations enable this rule: [no-class-fields], [no-new-in-es2022], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], and [restrict-to-es2021] + +This rule reports class fields as errors. + +## 💡 Examples + +⛔ Examples of **incorrect** code for this rule: + + + +```js +/*eslint es-x/no-class-instance-fields: error */ +class A { + a = 0 + #b = 0 +} +``` + + + +## 📚 References + +- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-class-instance-fields.js) +- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-class-instance-fields.js) + +[no-class-fields]: ../configs/index.md#no-class-fields +[no-new-in-es2022]: ../configs/index.md#no-new-in-es2022 +[restrict-to-es3]: ../configs/index.md#restrict-to-es3 +[restrict-to-es5]: ../configs/index.md#restrict-to-es5 +[restrict-to-es2015]: ../configs/index.md#restrict-to-es2015 +[restrict-to-es2016]: ../configs/index.md#restrict-to-es2016 +[restrict-to-es2017]: ../configs/index.md#restrict-to-es2017 +[restrict-to-es2018]: ../configs/index.md#restrict-to-es2018 +[restrict-to-es2019]: ../configs/index.md#restrict-to-es2019 +[restrict-to-es2020]: ../configs/index.md#restrict-to-es2020 +[restrict-to-es2021]: ../configs/index.md#restrict-to-es2021 diff --git a/docs/rules/no-class-private-fields.md b/docs/rules/no-class-private-fields.md new file mode 100644 index 00000000..40f2ee35 --- /dev/null +++ b/docs/rules/no-class-private-fields.md @@ -0,0 +1,50 @@ +--- +title: "es-x/no-class-private-fields" +description: "disallow private class fields" +--- + +# es-x/no-class-private-fields +> disallow private class fields + +- ❗ ***This rule has not been released yet.*** +- ✅ The following configurations enable this rule: [no-class-fields], [no-new-in-es2022], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], and [restrict-to-es2021] + +This rule reports class fields as errors. + +## 💡 Examples + +⛔ Examples of **incorrect** code for this rule: + + + +```js +/*eslint es-x/no-class-private-fields: error */ +class A { + #b = 0 + static #f = 0 + + fn () { + this.#b++ + A.#f++ + } +} +``` + + + +## 📚 References + +- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-class-private-fields.js) +- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-class-private-fields.js) + +[no-class-fields]: ../configs/index.md#no-class-fields +[no-new-in-es2022]: ../configs/index.md#no-new-in-es2022 +[restrict-to-es3]: ../configs/index.md#restrict-to-es3 +[restrict-to-es5]: ../configs/index.md#restrict-to-es5 +[restrict-to-es2015]: ../configs/index.md#restrict-to-es2015 +[restrict-to-es2016]: ../configs/index.md#restrict-to-es2016 +[restrict-to-es2017]: ../configs/index.md#restrict-to-es2017 +[restrict-to-es2018]: ../configs/index.md#restrict-to-es2018 +[restrict-to-es2019]: ../configs/index.md#restrict-to-es2019 +[restrict-to-es2020]: ../configs/index.md#restrict-to-es2020 +[restrict-to-es2021]: ../configs/index.md#restrict-to-es2021 diff --git a/docs/rules/no-class-private-methods.md b/docs/rules/no-class-private-methods.md new file mode 100644 index 00000000..d186c89a --- /dev/null +++ b/docs/rules/no-class-private-methods.md @@ -0,0 +1,50 @@ +--- +title: "es-x/no-class-private-methods" +description: "disallow private class methods" +--- + +# es-x/no-class-private-methods +> disallow private class methods + +- ❗ ***This rule has not been released yet.*** +- ✅ The following configurations enable this rule: [no-class-fields], [no-new-in-es2022], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], and [restrict-to-es2021] + +This rule reports class fields as errors. + +## 💡 Examples + +⛔ Examples of **incorrect** code for this rule: + + + +```js +/*eslint es-x/no-class-private-methods: error */ +class A { + #c() {} + get #d() {} + set #d(v) {} + + static #g() {} + static get #h() {} + static set #h(v) {} +} +``` + + + +## 📚 References + +- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-class-private-methods.js) +- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-class-private-methods.js) + +[no-class-fields]: ../configs/index.md#no-class-fields +[no-new-in-es2022]: ../configs/index.md#no-new-in-es2022 +[restrict-to-es3]: ../configs/index.md#restrict-to-es3 +[restrict-to-es5]: ../configs/index.md#restrict-to-es5 +[restrict-to-es2015]: ../configs/index.md#restrict-to-es2015 +[restrict-to-es2016]: ../configs/index.md#restrict-to-es2016 +[restrict-to-es2017]: ../configs/index.md#restrict-to-es2017 +[restrict-to-es2018]: ../configs/index.md#restrict-to-es2018 +[restrict-to-es2019]: ../configs/index.md#restrict-to-es2019 +[restrict-to-es2020]: ../configs/index.md#restrict-to-es2020 +[restrict-to-es2021]: ../configs/index.md#restrict-to-es2021 diff --git a/docs/rules/no-class-static-fields.md b/docs/rules/no-class-static-fields.md new file mode 100644 index 00000000..190f5603 --- /dev/null +++ b/docs/rules/no-class-static-fields.md @@ -0,0 +1,45 @@ +--- +title: "es-x/no-class-static-fields" +description: "disallow static class fields" +--- + +# es-x/no-class-static-fields +> disallow static class fields + +- ❗ ***This rule has not been released yet.*** +- ✅ The following configurations enable this rule: [no-class-fields], [no-new-in-es2022], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], and [restrict-to-es2021] + +This rule reports class fields as errors. + +## 💡 Examples + +⛔ Examples of **incorrect** code for this rule: + + + +```js +/*eslint es-x/no-class-static-fields: error */ +class A { + static e = 0 + static #f = 0 +} +``` + + + +## 📚 References + +- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-class-static-fields.js) +- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-class-static-fields.js) + +[no-class-fields]: ../configs/index.md#no-class-fields +[no-new-in-es2022]: ../configs/index.md#no-new-in-es2022 +[restrict-to-es3]: ../configs/index.md#restrict-to-es3 +[restrict-to-es5]: ../configs/index.md#restrict-to-es5 +[restrict-to-es2015]: ../configs/index.md#restrict-to-es2015 +[restrict-to-es2016]: ../configs/index.md#restrict-to-es2016 +[restrict-to-es2017]: ../configs/index.md#restrict-to-es2017 +[restrict-to-es2018]: ../configs/index.md#restrict-to-es2018 +[restrict-to-es2019]: ../configs/index.md#restrict-to-es2019 +[restrict-to-es2020]: ../configs/index.md#restrict-to-es2020 +[restrict-to-es2021]: ../configs/index.md#restrict-to-es2021 diff --git a/docs/rules/no-intl-numberformat-prototype-formatrange.md b/docs/rules/no-intl-numberformat-prototype-formatrange.md index b3123f59..ab74495b 100644 --- a/docs/rules/no-intl-numberformat-prototype-formatrange.md +++ b/docs/rules/no-intl-numberformat-prototype-formatrange.md @@ -7,7 +7,7 @@ since: "v6.0.0" # es-x/no-intl-numberformat-prototype-formatrange > disallow the `NumberFormat.prototype.formatRange` method -- ✅ The following configurations enable this rule: [no-new-in-es2023-intl-api], [restrict-to-es-intl-api-1st-edition], [restrict-to-es2015-intl-api], [restrict-to-es2016-intl-api], [restrict-to-es2017-intl-api], [restrict-to-es2018-intl-api], [restrict-to-es2019-intl-api], [restrict-to-es2020-intl-api], [restrict-to-es2021-intl-api], and [restrict-to-es2022-intl-api] +- ✅ The following configurations enable this rule: [no-intl-numberformat-v3], [no-new-in-es2023-intl-api], [restrict-to-es-intl-api-1st-edition], [restrict-to-es2015-intl-api], [restrict-to-es2016-intl-api], [restrict-to-es2017-intl-api], [restrict-to-es2018-intl-api], [restrict-to-es2019-intl-api], [restrict-to-es2020-intl-api], [restrict-to-es2021-intl-api], and [restrict-to-es2022-intl-api] This rule reports ES2023 Intl API `NumberFormat.prototype.formatRange` as errors. @@ -54,6 +54,7 @@ This rule was introduced in v6.0.0. - [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-intl-numberformat-prototype-formatrange.js) - [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-intl-numberformat-prototype-formatrange.js) +[no-intl-numberformat-v3]: ../configs/index.md#no-intl-numberformat-v3 [no-new-in-es2023-intl-api]: ../configs/index.md#no-new-in-es2023-intl-api [restrict-to-es-intl-api-1st-edition]: ../configs/index.md#restrict-to-es-intl-api-1st-edition [restrict-to-es2015-intl-api]: ../configs/index.md#restrict-to-es2015-intl-api diff --git a/docs/rules/no-intl-numberformat-prototype-formatrangetoparts.md b/docs/rules/no-intl-numberformat-prototype-formatrangetoparts.md index 6f581f10..e00af27d 100644 --- a/docs/rules/no-intl-numberformat-prototype-formatrangetoparts.md +++ b/docs/rules/no-intl-numberformat-prototype-formatrangetoparts.md @@ -7,7 +7,7 @@ since: "v6.0.0" # es-x/no-intl-numberformat-prototype-formatrangetoparts > disallow the `NumberFormat.prototype.formatRangeToParts` method -- ✅ The following configurations enable this rule: [no-new-in-es2023-intl-api], [restrict-to-es-intl-api-1st-edition], [restrict-to-es2015-intl-api], [restrict-to-es2016-intl-api], [restrict-to-es2017-intl-api], [restrict-to-es2018-intl-api], [restrict-to-es2019-intl-api], [restrict-to-es2020-intl-api], [restrict-to-es2021-intl-api], and [restrict-to-es2022-intl-api] +- ✅ The following configurations enable this rule: [no-intl-numberformat-v3], [no-new-in-es2023-intl-api], [restrict-to-es-intl-api-1st-edition], [restrict-to-es2015-intl-api], [restrict-to-es2016-intl-api], [restrict-to-es2017-intl-api], [restrict-to-es2018-intl-api], [restrict-to-es2019-intl-api], [restrict-to-es2020-intl-api], [restrict-to-es2021-intl-api], and [restrict-to-es2022-intl-api] This rule reports ES2023 Intl API `NumberFormat.prototype.formatRangeToParts` as errors. @@ -55,6 +55,7 @@ This rule was introduced in v6.0.0. - [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-intl-numberformat-prototype-formatrangetoparts.js) - [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-intl-numberformat-prototype-formatrangetoparts.js) +[no-intl-numberformat-v3]: ../configs/index.md#no-intl-numberformat-v3 [no-new-in-es2023-intl-api]: ../configs/index.md#no-new-in-es2023-intl-api [restrict-to-es-intl-api-1st-edition]: ../configs/index.md#restrict-to-es-intl-api-1st-edition [restrict-to-es2015-intl-api]: ../configs/index.md#restrict-to-es2015-intl-api diff --git a/docs/rules/no-intl-pluralrules-prototype-selectrange.md b/docs/rules/no-intl-pluralrules-prototype-selectrange.md index 5fcbe3b9..a345b2c9 100644 --- a/docs/rules/no-intl-pluralrules-prototype-selectrange.md +++ b/docs/rules/no-intl-pluralrules-prototype-selectrange.md @@ -7,7 +7,7 @@ since: "v6.0.0" # es-x/no-intl-pluralrules-prototype-selectrange > disallow the `PluralRules.prototype.selectRange` method -- ✅ The following configurations enable this rule: [no-new-in-es2023-intl-api], [restrict-to-es-intl-api-1st-edition], [restrict-to-es2015-intl-api], [restrict-to-es2016-intl-api], [restrict-to-es2017-intl-api], [restrict-to-es2018-intl-api], [restrict-to-es2019-intl-api], [restrict-to-es2020-intl-api], [restrict-to-es2021-intl-api], and [restrict-to-es2022-intl-api] +- ✅ The following configurations enable this rule: [no-intl-numberformat-v3], [no-new-in-es2023-intl-api], [restrict-to-es-intl-api-1st-edition], [restrict-to-es2015-intl-api], [restrict-to-es2016-intl-api], [restrict-to-es2017-intl-api], [restrict-to-es2018-intl-api], [restrict-to-es2019-intl-api], [restrict-to-es2020-intl-api], [restrict-to-es2021-intl-api], and [restrict-to-es2022-intl-api] This rule reports ES2023 Intl API `PluralRules.prototype.selectRange` as errors. @@ -54,6 +54,7 @@ This rule was introduced in v6.0.0. - [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-intl-pluralrules-prototype-selectrange.js) - [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-intl-pluralrules-prototype-selectrange.js) +[no-intl-numberformat-v3]: ../configs/index.md#no-intl-numberformat-v3 [no-new-in-es2023-intl-api]: ../configs/index.md#no-new-in-es2023-intl-api [restrict-to-es-intl-api-1st-edition]: ../configs/index.md#restrict-to-es-intl-api-1st-edition [restrict-to-es2015-intl-api]: ../configs/index.md#restrict-to-es2015-intl-api diff --git a/docs/rules/no-map-groupby.md b/docs/rules/no-map-groupby.md new file mode 100644 index 00000000..e0e5f945 --- /dev/null +++ b/docs/rules/no-map-groupby.md @@ -0,0 +1,46 @@ +--- +title: "es-x/no-map-groupby" +description: "disallow the `Map.groupBy()` method" +--- + +# es-x/no-map-groupby +> disallow the `Map.groupBy()` method + +- ❗ ***This rule has not been released yet.*** +- ✅ The following configurations enable this rule: [no-array-grouping], [no-new-in-es2024], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], [restrict-to-es2021], [restrict-to-es2022], and [restrict-to-es2023] + +This rule reports ES2024 [`Map.groupBy()`](https://github.com/tc39/proposal-array-grouping) method as errors. + +## 💡 Examples + +⛔ Examples of **incorrect** code for this rule: + + + +```js +/*eslint es-x/no-map-groupby: error */ +Map.groupBy(array, (num, index) => { + return num % 2 === 0 ? even: odd; +}); +``` + + + +## 📚 References + +- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-map-groupby.js) +- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-map-groupby.js) + +[no-array-grouping]: ../configs/index.md#no-array-grouping +[no-new-in-es2024]: ../configs/index.md#no-new-in-es2024 +[restrict-to-es3]: ../configs/index.md#restrict-to-es3 +[restrict-to-es5]: ../configs/index.md#restrict-to-es5 +[restrict-to-es2015]: ../configs/index.md#restrict-to-es2015 +[restrict-to-es2016]: ../configs/index.md#restrict-to-es2016 +[restrict-to-es2017]: ../configs/index.md#restrict-to-es2017 +[restrict-to-es2018]: ../configs/index.md#restrict-to-es2018 +[restrict-to-es2019]: ../configs/index.md#restrict-to-es2019 +[restrict-to-es2020]: ../configs/index.md#restrict-to-es2020 +[restrict-to-es2021]: ../configs/index.md#restrict-to-es2021 +[restrict-to-es2022]: ../configs/index.md#restrict-to-es2022 +[restrict-to-es2023]: ../configs/index.md#restrict-to-es2023 diff --git a/docs/rules/no-object-groupby.md b/docs/rules/no-object-groupby.md new file mode 100644 index 00000000..abf625f1 --- /dev/null +++ b/docs/rules/no-object-groupby.md @@ -0,0 +1,46 @@ +--- +title: "es-x/no-object-groupby" +description: "disallow the `Object.groupBy()` method" +--- + +# es-x/no-object-groupby +> disallow the `Object.groupBy()` method + +- ❗ ***This rule has not been released yet.*** +- ✅ The following configurations enable this rule: [no-array-grouping], [no-new-in-es2024], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], [restrict-to-es2021], [restrict-to-es2022], and [restrict-to-es2023] + +This rule reports ES2024 [`Object.groupBy()`](https://github.com/tc39/proposal-array-grouping) method as errors. + +## 💡 Examples + +⛔ Examples of **incorrect** code for this rule: + + + +```js +/*eslint es-x/no-object-groupby: error */ +Object.groupBy(array, (num, index) => { + return num % 2 === 0 ? 'even': 'odd'; +}); +``` + + + +## 📚 References + +- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-object-groupby.js) +- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-object-groupby.js) + +[no-array-grouping]: ../configs/index.md#no-array-grouping +[no-new-in-es2024]: ../configs/index.md#no-new-in-es2024 +[restrict-to-es3]: ../configs/index.md#restrict-to-es3 +[restrict-to-es5]: ../configs/index.md#restrict-to-es5 +[restrict-to-es2015]: ../configs/index.md#restrict-to-es2015 +[restrict-to-es2016]: ../configs/index.md#restrict-to-es2016 +[restrict-to-es2017]: ../configs/index.md#restrict-to-es2017 +[restrict-to-es2018]: ../configs/index.md#restrict-to-es2018 +[restrict-to-es2019]: ../configs/index.md#restrict-to-es2019 +[restrict-to-es2020]: ../configs/index.md#restrict-to-es2020 +[restrict-to-es2021]: ../configs/index.md#restrict-to-es2021 +[restrict-to-es2022]: ../configs/index.md#restrict-to-es2022 +[restrict-to-es2023]: ../configs/index.md#restrict-to-es2023 diff --git a/docs/rules/no-object-map-groupby.md b/docs/rules/no-object-map-groupby.md index 9c299e2c..49845075 100644 --- a/docs/rules/no-object-map-groupby.md +++ b/docs/rules/no-object-map-groupby.md @@ -7,7 +7,7 @@ since: "v7.5.0" # es-x/no-object-map-groupby > disallow the `{Object,Map}.groupBy()` function (array grouping) -- ✅ The following configurations enable this rule: [no-new-in-es2024], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], [restrict-to-es2021], [restrict-to-es2022], and [restrict-to-es2023] +- 🚫 This rule was deprecated and replaced by [es-x/no-object-groupby](./no-object-groupby.md),[es-x/no-map-groupby](./no-map-groupby.md) rules. This rule reports ES2024 `Object.groupBy()` and `Map.groupBy()` (Array grouping) as errors. @@ -38,16 +38,3 @@ This rule was introduced in v7.5.0. - [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-object-map-groupby.js) - [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-object-map-groupby.js) - -[no-new-in-es2024]: ../configs/index.md#no-new-in-es2024 -[restrict-to-es3]: ../configs/index.md#restrict-to-es3 -[restrict-to-es5]: ../configs/index.md#restrict-to-es5 -[restrict-to-es2015]: ../configs/index.md#restrict-to-es2015 -[restrict-to-es2016]: ../configs/index.md#restrict-to-es2016 -[restrict-to-es2017]: ../configs/index.md#restrict-to-es2017 -[restrict-to-es2018]: ../configs/index.md#restrict-to-es2018 -[restrict-to-es2019]: ../configs/index.md#restrict-to-es2019 -[restrict-to-es2020]: ../configs/index.md#restrict-to-es2020 -[restrict-to-es2021]: ../configs/index.md#restrict-to-es2021 -[restrict-to-es2022]: ../configs/index.md#restrict-to-es2022 -[restrict-to-es2023]: ../configs/index.md#restrict-to-es2023 diff --git a/docs/rules/no-string-prototype-at.md b/docs/rules/no-string-prototype-at.md new file mode 100644 index 00000000..1bee007b --- /dev/null +++ b/docs/rules/no-string-prototype-at.md @@ -0,0 +1,58 @@ +--- +title: "es-x/no-string-prototype-at" +description: "disallow the `String.prototype.at()` methods" +--- + +# es-x/no-string-prototype-at +> disallow the `String.prototype.at()` methods + +- ❗ ***This rule has not been released yet.*** +- ✅ The following configurations enable this rule: [no-new-in-es2022], [no-relative-indexing-method], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], and [restrict-to-es2021] + +This rule reports ES2022 [`String.prototype.at` methods](https://github.com/tc39/proposal-relative-indexing-method) as errors. + +This rule is silent by default because it's hard to know types. You need to configure [the aggressive mode](../#the-aggressive-mode) or TypeScript in order to enable this rule. + +## 💡 Examples + +⛔ Examples of **incorrect** code for this rule: + + + +```js +/*eslint es-x/no-string-prototype-at: [error, { aggressive: true }] */ +'str'.at(-1) +``` + + + +## 🔧 Options + +This rule has an option. + +```yaml +rules: + es-x/no-string-prototype-at: [error, { aggressive: false }] +``` + +### aggressive: boolean + +Configure the aggressive mode for only this rule. +This is prior to the `settings['es-x'].aggressive` setting. + +## 📚 References + +- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-string-prototype-at.js) +- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-string-prototype-at.js) + +[no-new-in-es2022]: ../configs/index.md#no-new-in-es2022 +[no-relative-indexing-method]: ../configs/index.md#no-relative-indexing-method +[restrict-to-es3]: ../configs/index.md#restrict-to-es3 +[restrict-to-es5]: ../configs/index.md#restrict-to-es5 +[restrict-to-es2015]: ../configs/index.md#restrict-to-es2015 +[restrict-to-es2016]: ../configs/index.md#restrict-to-es2016 +[restrict-to-es2017]: ../configs/index.md#restrict-to-es2017 +[restrict-to-es2018]: ../configs/index.md#restrict-to-es2018 +[restrict-to-es2019]: ../configs/index.md#restrict-to-es2019 +[restrict-to-es2020]: ../configs/index.md#restrict-to-es2020 +[restrict-to-es2021]: ../configs/index.md#restrict-to-es2021 diff --git a/docs/rules/no-string-prototype-iswellformed-towellformed.md b/docs/rules/no-string-prototype-iswellformed-towellformed.md index 5cb8b399..a51942e4 100644 --- a/docs/rules/no-string-prototype-iswellformed-towellformed.md +++ b/docs/rules/no-string-prototype-iswellformed-towellformed.md @@ -7,7 +7,7 @@ since: "v7.1.0" # es-x/no-string-prototype-iswellformed-towellformed > disallow the `String.prototype.{isWellFormed,toWellFormed}` methods -- ✅ The following configurations enable this rule: [no-new-in-es2024], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], [restrict-to-es2021], [restrict-to-es2022], and [restrict-to-es2023] +- 🚫 This rule was deprecated and replaced by [es-x/no-string-prototype-iswellformed](./no-string-prototype-iswellformed.md),[es-x/no-string-prototype-towellformed](./no-string-prototype-towellformed.md) rules. This rule reports ES2024 [`String.prototype.{isWellFormed,toWellFormed}` methods](https://github.com/tc39/proposal-is-usv-string) as errors. @@ -47,16 +47,3 @@ This rule was introduced in v7.1.0. - [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-string-prototype-iswellformed-towellformed.js) - [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-string-prototype-iswellformed-towellformed.js) - -[no-new-in-es2024]: ../configs/index.md#no-new-in-es2024 -[restrict-to-es3]: ../configs/index.md#restrict-to-es3 -[restrict-to-es5]: ../configs/index.md#restrict-to-es5 -[restrict-to-es2015]: ../configs/index.md#restrict-to-es2015 -[restrict-to-es2016]: ../configs/index.md#restrict-to-es2016 -[restrict-to-es2017]: ../configs/index.md#restrict-to-es2017 -[restrict-to-es2018]: ../configs/index.md#restrict-to-es2018 -[restrict-to-es2019]: ../configs/index.md#restrict-to-es2019 -[restrict-to-es2020]: ../configs/index.md#restrict-to-es2020 -[restrict-to-es2021]: ../configs/index.md#restrict-to-es2021 -[restrict-to-es2022]: ../configs/index.md#restrict-to-es2022 -[restrict-to-es2023]: ../configs/index.md#restrict-to-es2023 diff --git a/docs/rules/no-string-prototype-iswellformed.md b/docs/rules/no-string-prototype-iswellformed.md new file mode 100644 index 00000000..b02f4724 --- /dev/null +++ b/docs/rules/no-string-prototype-iswellformed.md @@ -0,0 +1,58 @@ +--- +title: "es-x/no-string-prototype-iswellformed" +description: "disallow the `String.prototype.isWellFormed` methods" +--- + +# es-x/no-string-prototype-iswellformed +> disallow the `String.prototype.isWellFormed` methods + +- ❗ ***This rule has not been released yet.*** +- ✅ The following configurations enable this rule: [no-is-usv-string], [no-new-in-es2024], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], [restrict-to-es2021], [restrict-to-es2022], and [restrict-to-es2023] + +This rule reports ES2024 [`String.prototype.isWellFormed` methods](https://github.com/tc39/proposal-is-usv-string) as errors. + +## 💡 Examples + +⛔ Examples of **incorrect** code for this rule: + + + +```js +/*eslint es-x/no-string-prototype-iswellformed: [error, { aggressive: true }] */ +"str".isWellFormed() +``` + +a + +## 🔧 Options + +This rule has an option. + +```yaml +rules: + es-x/no-string-prototype-iswellformed: [error, { aggressive: false }] +``` + +### aggressive: boolean + +Configure the aggressive mode for only this rule. +This is prior to the `settings['es-x'].aggressive` setting. + +## 📚 References + +- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-string-prototype-iswellformed.js) +- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-string-prototype-iswellformed.js) + +[no-is-usv-string]: ../configs/index.md#no-is-usv-string +[no-new-in-es2024]: ../configs/index.md#no-new-in-es2024 +[restrict-to-es3]: ../configs/index.md#restrict-to-es3 +[restrict-to-es5]: ../configs/index.md#restrict-to-es5 +[restrict-to-es2015]: ../configs/index.md#restrict-to-es2015 +[restrict-to-es2016]: ../configs/index.md#restrict-to-es2016 +[restrict-to-es2017]: ../configs/index.md#restrict-to-es2017 +[restrict-to-es2018]: ../configs/index.md#restrict-to-es2018 +[restrict-to-es2019]: ../configs/index.md#restrict-to-es2019 +[restrict-to-es2020]: ../configs/index.md#restrict-to-es2020 +[restrict-to-es2021]: ../configs/index.md#restrict-to-es2021 +[restrict-to-es2022]: ../configs/index.md#restrict-to-es2022 +[restrict-to-es2023]: ../configs/index.md#restrict-to-es2023 diff --git a/docs/rules/no-string-prototype-towellformed.md b/docs/rules/no-string-prototype-towellformed.md new file mode 100644 index 00000000..25bb0013 --- /dev/null +++ b/docs/rules/no-string-prototype-towellformed.md @@ -0,0 +1,58 @@ +--- +title: "es-x/no-string-prototype-towellformed" +description: "disallow the `String.prototype.toWellFormed` methods" +--- + +# es-x/no-string-prototype-towellformed +> disallow the `String.prototype.toWellFormed` methods + +- ❗ ***This rule has not been released yet.*** +- ✅ The following configurations enable this rule: [no-is-usv-string], [no-new-in-es2024], [restrict-to-es3], [restrict-to-es5], [restrict-to-es2015], [restrict-to-es2016], [restrict-to-es2017], [restrict-to-es2018], [restrict-to-es2019], [restrict-to-es2020], [restrict-to-es2021], [restrict-to-es2022], and [restrict-to-es2023] + +This rule reports ES2024 [`String.prototype.toWellFormed` methods](https://github.com/tc39/proposal-is-usv-string) as errors. + +## 💡 Examples + +⛔ Examples of **incorrect** code for this rule: + + + +```js +/*eslint es-x/no-string-prototype-towellformed: [error, { aggressive: true }] */ +"str".toWellFormed() +``` + +a + +## 🔧 Options + +This rule has an option. + +```yaml +rules: + es-x/no-string-prototype-towellformed: [error, { aggressive: false }] +``` + +### aggressive: boolean + +Configure the aggressive mode for only this rule. +This is prior to the `settings['es-x'].aggressive` setting. + +## 📚 References + +- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-string-prototype-towellformed.js) +- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-string-prototype-towellformed.js) + +[no-is-usv-string]: ../configs/index.md#no-is-usv-string +[no-new-in-es2024]: ../configs/index.md#no-new-in-es2024 +[restrict-to-es3]: ../configs/index.md#restrict-to-es3 +[restrict-to-es5]: ../configs/index.md#restrict-to-es5 +[restrict-to-es2015]: ../configs/index.md#restrict-to-es2015 +[restrict-to-es2016]: ../configs/index.md#restrict-to-es2016 +[restrict-to-es2017]: ../configs/index.md#restrict-to-es2017 +[restrict-to-es2018]: ../configs/index.md#restrict-to-es2018 +[restrict-to-es2019]: ../configs/index.md#restrict-to-es2019 +[restrict-to-es2020]: ../configs/index.md#restrict-to-es2020 +[restrict-to-es2021]: ../configs/index.md#restrict-to-es2021 +[restrict-to-es2022]: ../configs/index.md#restrict-to-es2022 +[restrict-to-es2023]: ../configs/index.md#restrict-to-es2023 diff --git a/lib/configs/flat/no-array-grouping.js b/lib/configs/flat/no-array-grouping.js new file mode 100644 index 00000000..fb62fd39 --- /dev/null +++ b/lib/configs/flat/no-array-grouping.js @@ -0,0 +1,17 @@ +/** + * DON'T EDIT THIS FILE. + * This file was generated by "scripts/update-lib-flat-configs.js" script. + */ +"use strict" + +module.exports = { + plugins: { + get "es-x"() { + return require("../../index.js") + }, + }, + rules: { + "es-x/no-map-groupby": "error", + "es-x/no-object-groupby": "error", + }, +} diff --git a/lib/configs/flat/no-change-array-by-copy.js b/lib/configs/flat/no-change-array-by-copy.js new file mode 100644 index 00000000..a3f83641 --- /dev/null +++ b/lib/configs/flat/no-change-array-by-copy.js @@ -0,0 +1,19 @@ +/** + * DON'T EDIT THIS FILE. + * This file was generated by "scripts/update-lib-flat-configs.js" script. + */ +"use strict" + +module.exports = { + plugins: { + get "es-x"() { + return require("../../index.js") + }, + }, + rules: { + "es-x/no-array-prototype-toreversed": "error", + "es-x/no-array-prototype-tosorted": "error", + "es-x/no-array-prototype-tospliced": "error", + "es-x/no-array-prototype-with": "error", + }, +} diff --git a/lib/configs/flat/no-class-fields.js b/lib/configs/flat/no-class-fields.js new file mode 100644 index 00000000..c445f17d --- /dev/null +++ b/lib/configs/flat/no-class-fields.js @@ -0,0 +1,19 @@ +/** + * DON'T EDIT THIS FILE. + * This file was generated by "scripts/update-lib-flat-configs.js" script. + */ +"use strict" + +module.exports = { + plugins: { + get "es-x"() { + return require("../../index.js") + }, + }, + rules: { + "es-x/no-class-instance-fields": "error", + "es-x/no-class-private-fields": "error", + "es-x/no-class-private-methods": "error", + "es-x/no-class-static-fields": "error", + }, +} diff --git a/lib/configs/flat/no-intl-numberformat-v3.js b/lib/configs/flat/no-intl-numberformat-v3.js new file mode 100644 index 00000000..4106b612 --- /dev/null +++ b/lib/configs/flat/no-intl-numberformat-v3.js @@ -0,0 +1,18 @@ +/** + * DON'T EDIT THIS FILE. + * This file was generated by "scripts/update-lib-flat-configs.js" script. + */ +"use strict" + +module.exports = { + plugins: { + get "es-x"() { + return require("../../index.js") + }, + }, + rules: { + "es-x/no-intl-numberformat-prototype-formatrange": "error", + "es-x/no-intl-numberformat-prototype-formatrangetoparts": "error", + "es-x/no-intl-pluralrules-prototype-selectrange": "error", + }, +} diff --git a/lib/configs/flat/no-is-usv-string.js b/lib/configs/flat/no-is-usv-string.js new file mode 100644 index 00000000..826ca8cc --- /dev/null +++ b/lib/configs/flat/no-is-usv-string.js @@ -0,0 +1,17 @@ +/** + * DON'T EDIT THIS FILE. + * This file was generated by "scripts/update-lib-flat-configs.js" script. + */ +"use strict" + +module.exports = { + plugins: { + get "es-x"() { + return require("../../index.js") + }, + }, + rules: { + "es-x/no-string-prototype-iswellformed": "error", + "es-x/no-string-prototype-towellformed": "error", + }, +} diff --git a/lib/configs/flat/no-new-in-es2022.js b/lib/configs/flat/no-new-in-es2022.js index c3210cf6..dbec51a9 100644 --- a/lib/configs/flat/no-new-in-es2022.js +++ b/lib/configs/flat/no-new-in-es2022.js @@ -12,14 +12,18 @@ module.exports = { }, rules: { "es-x/no-arbitrary-module-namespace-names": "error", - "es-x/no-array-string-prototype-at": "error", - "es-x/no-class-fields": "error", + "es-x/no-array-prototype-at": "error", + "es-x/no-class-instance-fields": "error", + "es-x/no-class-private-fields": "error", + "es-x/no-class-private-methods": "error", "es-x/no-class-static-block": "error", + "es-x/no-class-static-fields": "error", "es-x/no-error-cause": "error", "es-x/no-object-hasown": "error", "es-x/no-private-in": "error", "es-x/no-regexp-d-flag": "error", "es-x/no-regexp-unicode-property-escapes-2022": "error", + "es-x/no-string-prototype-at": "error", "es-x/no-top-level-await": "error", }, } diff --git a/lib/configs/flat/no-new-in-es2024.js b/lib/configs/flat/no-new-in-es2024.js index 1e23dc0d..7cb021f4 100644 --- a/lib/configs/flat/no-new-in-es2024.js +++ b/lib/configs/flat/no-new-in-es2024.js @@ -13,10 +13,12 @@ module.exports = { rules: { "es-x/no-arraybuffer-prototype-transfer": "error", "es-x/no-atomics-waitasync": "error", - "es-x/no-object-map-groupby": "error", + "es-x/no-map-groupby": "error", + "es-x/no-object-groupby": "error", "es-x/no-promise-withresolvers": "error", "es-x/no-regexp-v-flag": "error", "es-x/no-resizable-and-growable-arraybuffers": "error", - "es-x/no-string-prototype-iswellformed-towellformed": "error", + "es-x/no-string-prototype-iswellformed": "error", + "es-x/no-string-prototype-towellformed": "error", }, } diff --git a/lib/configs/flat/no-relative-indexing-method.js b/lib/configs/flat/no-relative-indexing-method.js new file mode 100644 index 00000000..32490949 --- /dev/null +++ b/lib/configs/flat/no-relative-indexing-method.js @@ -0,0 +1,17 @@ +/** + * DON'T EDIT THIS FILE. + * This file was generated by "scripts/update-lib-flat-configs.js" script. + */ +"use strict" + +module.exports = { + plugins: { + get "es-x"() { + return require("../../index.js") + }, + }, + rules: { + "es-x/no-array-prototype-at": "error", + "es-x/no-string-prototype-at": "error", + }, +} diff --git a/lib/configs/no-array-grouping.js b/lib/configs/no-array-grouping.js new file mode 100644 index 00000000..c7b71a16 --- /dev/null +++ b/lib/configs/no-array-grouping.js @@ -0,0 +1,13 @@ +/** + * DON'T EDIT THIS FILE. + * This file was generated by "scripts/update-lib-configs.js" script. + */ +"use strict" + +module.exports = { + plugins: ["es-x"], + rules: { + "es-x/no-map-groupby": "error", + "es-x/no-object-groupby": "error", + }, +} diff --git a/lib/configs/no-change-array-by-copy.js b/lib/configs/no-change-array-by-copy.js new file mode 100644 index 00000000..f78b6cf2 --- /dev/null +++ b/lib/configs/no-change-array-by-copy.js @@ -0,0 +1,15 @@ +/** + * DON'T EDIT THIS FILE. + * This file was generated by "scripts/update-lib-configs.js" script. + */ +"use strict" + +module.exports = { + plugins: ["es-x"], + rules: { + "es-x/no-array-prototype-toreversed": "error", + "es-x/no-array-prototype-tosorted": "error", + "es-x/no-array-prototype-tospliced": "error", + "es-x/no-array-prototype-with": "error", + }, +} diff --git a/lib/configs/no-class-fields.js b/lib/configs/no-class-fields.js new file mode 100644 index 00000000..6d8c33b2 --- /dev/null +++ b/lib/configs/no-class-fields.js @@ -0,0 +1,15 @@ +/** + * DON'T EDIT THIS FILE. + * This file was generated by "scripts/update-lib-configs.js" script. + */ +"use strict" + +module.exports = { + plugins: ["es-x"], + rules: { + "es-x/no-class-instance-fields": "error", + "es-x/no-class-private-fields": "error", + "es-x/no-class-private-methods": "error", + "es-x/no-class-static-fields": "error", + }, +} diff --git a/lib/configs/no-intl-numberformat-v3.js b/lib/configs/no-intl-numberformat-v3.js new file mode 100644 index 00000000..3ffd376c --- /dev/null +++ b/lib/configs/no-intl-numberformat-v3.js @@ -0,0 +1,14 @@ +/** + * DON'T EDIT THIS FILE. + * This file was generated by "scripts/update-lib-configs.js" script. + */ +"use strict" + +module.exports = { + plugins: ["es-x"], + rules: { + "es-x/no-intl-numberformat-prototype-formatrange": "error", + "es-x/no-intl-numberformat-prototype-formatrangetoparts": "error", + "es-x/no-intl-pluralrules-prototype-selectrange": "error", + }, +} diff --git a/lib/configs/no-is-usv-string.js b/lib/configs/no-is-usv-string.js new file mode 100644 index 00000000..ae373a9a --- /dev/null +++ b/lib/configs/no-is-usv-string.js @@ -0,0 +1,13 @@ +/** + * DON'T EDIT THIS FILE. + * This file was generated by "scripts/update-lib-configs.js" script. + */ +"use strict" + +module.exports = { + plugins: ["es-x"], + rules: { + "es-x/no-string-prototype-iswellformed": "error", + "es-x/no-string-prototype-towellformed": "error", + }, +} diff --git a/lib/configs/no-new-in-es2022.js b/lib/configs/no-new-in-es2022.js index 791ef634..4dfecac1 100644 --- a/lib/configs/no-new-in-es2022.js +++ b/lib/configs/no-new-in-es2022.js @@ -8,14 +8,18 @@ module.exports = { plugins: ["es-x"], rules: { "es-x/no-arbitrary-module-namespace-names": "error", - "es-x/no-array-string-prototype-at": "error", - "es-x/no-class-fields": "error", + "es-x/no-array-prototype-at": "error", + "es-x/no-class-instance-fields": "error", + "es-x/no-class-private-fields": "error", + "es-x/no-class-private-methods": "error", "es-x/no-class-static-block": "error", + "es-x/no-class-static-fields": "error", "es-x/no-error-cause": "error", "es-x/no-object-hasown": "error", "es-x/no-private-in": "error", "es-x/no-regexp-d-flag": "error", "es-x/no-regexp-unicode-property-escapes-2022": "error", + "es-x/no-string-prototype-at": "error", "es-x/no-top-level-await": "error", }, } diff --git a/lib/configs/no-new-in-es2024.js b/lib/configs/no-new-in-es2024.js index ff1314e8..15570958 100644 --- a/lib/configs/no-new-in-es2024.js +++ b/lib/configs/no-new-in-es2024.js @@ -9,10 +9,12 @@ module.exports = { rules: { "es-x/no-arraybuffer-prototype-transfer": "error", "es-x/no-atomics-waitasync": "error", - "es-x/no-object-map-groupby": "error", + "es-x/no-map-groupby": "error", + "es-x/no-object-groupby": "error", "es-x/no-promise-withresolvers": "error", "es-x/no-regexp-v-flag": "error", "es-x/no-resizable-and-growable-arraybuffers": "error", - "es-x/no-string-prototype-iswellformed-towellformed": "error", + "es-x/no-string-prototype-iswellformed": "error", + "es-x/no-string-prototype-towellformed": "error", }, } diff --git a/lib/configs/no-relative-indexing-method.js b/lib/configs/no-relative-indexing-method.js new file mode 100644 index 00000000..009b6235 --- /dev/null +++ b/lib/configs/no-relative-indexing-method.js @@ -0,0 +1,13 @@ +/** + * DON'T EDIT THIS FILE. + * This file was generated by "scripts/update-lib-configs.js" script. + */ +"use strict" + +module.exports = { + plugins: ["es-x"], + rules: { + "es-x/no-array-prototype-at": "error", + "es-x/no-string-prototype-at": "error", + }, +} diff --git a/lib/index.js b/lib/index.js index 1805408f..2ddadcdf 100644 --- a/lib/index.js +++ b/lib/index.js @@ -10,6 +10,11 @@ const { version, name } = require("../package.json") module.exports = { meta: { version, name }, configs: { + "flat/no-array-grouping": require("./configs/flat/no-array-grouping"), + "flat/no-change-array-by-copy": require("./configs/flat/no-change-array-by-copy"), + "flat/no-class-fields": require("./configs/flat/no-class-fields"), + "flat/no-intl-numberformat-v3": require("./configs/flat/no-intl-numberformat-v3"), + "flat/no-is-usv-string": require("./configs/flat/no-is-usv-string"), "flat/no-new-in-es5": require("./configs/flat/no-new-in-es5"), "flat/no-new-in-es2015": require("./configs/flat/no-new-in-es2015"), "flat/no-new-in-es2015-intl-api": require("./configs/flat/no-new-in-es2015-intl-api"), @@ -33,6 +38,7 @@ module.exports = { "flat/no-new-in-es2024-intl-api": require("./configs/flat/no-new-in-es2024-intl-api"), "flat/no-new-in-esnext": require("./configs/flat/no-new-in-esnext"), "flat/no-new-in-esnext-intl-api": require("./configs/flat/no-new-in-esnext-intl-api"), + "flat/no-relative-indexing-method": require("./configs/flat/no-relative-indexing-method"), "flat/no-set-methods": require("./configs/flat/no-set-methods"), "flat/restrict-to-es-intl-api-1st-edition": require("./configs/flat/restrict-to-es-intl-api-1st-edition"), "flat/restrict-to-es3": require("./configs/flat/restrict-to-es3"), @@ -55,6 +61,11 @@ module.exports = { "flat/restrict-to-es2022-intl-api": require("./configs/flat/restrict-to-es2022-intl-api"), "flat/restrict-to-es2023": require("./configs/flat/restrict-to-es2023"), "flat/restrict-to-es2023-intl-api": require("./configs/flat/restrict-to-es2023-intl-api"), + "no-array-grouping": require("./configs/no-array-grouping"), + "no-change-array-by-copy": require("./configs/no-change-array-by-copy"), + "no-class-fields": require("./configs/no-class-fields"), + "no-intl-numberformat-v3": require("./configs/no-intl-numberformat-v3"), + "no-is-usv-string": require("./configs/no-is-usv-string"), "no-new-in-es5": require("./configs/no-new-in-es5"), "no-new-in-es2015": require("./configs/no-new-in-es2015"), "no-new-in-es2015-intl-api": require("./configs/no-new-in-es2015-intl-api"), @@ -78,6 +89,7 @@ module.exports = { "no-new-in-es2024-intl-api": require("./configs/no-new-in-es2024-intl-api"), "no-new-in-esnext": require("./configs/no-new-in-esnext"), "no-new-in-esnext-intl-api": require("./configs/no-new-in-esnext-intl-api"), + "no-relative-indexing-method": require("./configs/no-relative-indexing-method"), "no-set-methods": require("./configs/no-set-methods"), "restrict-to-es-intl-api-1st-edition": require("./configs/restrict-to-es-intl-api-1st-edition"), "restrict-to-es3": require("./configs/restrict-to-es3"), @@ -131,6 +143,7 @@ module.exports = { "no-array-from": require("./rules/no-array-from"), "no-array-isarray": require("./rules/no-array-isarray"), "no-array-of": require("./rules/no-array-of"), + "no-array-prototype-at": require("./rules/no-array-prototype-at"), "no-array-prototype-copywithin": require("./rules/no-array-prototype-copywithin"), "no-array-prototype-entries": require("./rules/no-array-prototype-entries"), "no-array-prototype-every": require("./rules/no-array-prototype-every"), @@ -166,7 +179,11 @@ module.exports = { "no-block-scoped-functions": require("./rules/no-block-scoped-functions"), "no-block-scoped-variables": require("./rules/no-block-scoped-variables"), "no-class-fields": require("./rules/no-class-fields"), + "no-class-instance-fields": require("./rules/no-class-instance-fields"), + "no-class-private-fields": require("./rules/no-class-private-fields"), + "no-class-private-methods": require("./rules/no-class-private-methods"), "no-class-static-block": require("./rules/no-class-static-block"), + "no-class-static-fields": require("./rules/no-class-static-fields"), "no-classes": require("./rules/no-classes"), "no-computed-properties": require("./rules/no-computed-properties"), "no-date-now": require("./rules/no-date-now"), @@ -209,6 +226,7 @@ module.exports = { "no-logical-assignment-operators": require("./rules/no-logical-assignment-operators"), "no-malformed-template-literals": require("./rules/no-malformed-template-literals"), "no-map": require("./rules/no-map"), + "no-map-groupby": require("./rules/no-map-groupby"), "no-math-acosh": require("./rules/no-math-acosh"), "no-math-asinh": require("./rules/no-math-asinh"), "no-math-atanh": require("./rules/no-math-atanh"), @@ -251,6 +269,7 @@ module.exports = { "no-object-getownpropertynames": require("./rules/no-object-getownpropertynames"), "no-object-getownpropertysymbols": require("./rules/no-object-getownpropertysymbols"), "no-object-getprototypeof": require("./rules/no-object-getprototypeof"), + "no-object-groupby": require("./rules/no-object-groupby"), "no-object-hasown": require("./rules/no-object-hasown"), "no-object-is": require("./rules/no-object-is"), "no-object-isextensible": require("./rules/no-object-isextensible"), @@ -307,9 +326,11 @@ module.exports = { "no-spread-elements": require("./rules/no-spread-elements"), "no-string-create-html-methods": require("./rules/no-string-create-html-methods"), "no-string-fromcodepoint": require("./rules/no-string-fromcodepoint"), + "no-string-prototype-at": require("./rules/no-string-prototype-at"), "no-string-prototype-codepointat": require("./rules/no-string-prototype-codepointat"), "no-string-prototype-endswith": require("./rules/no-string-prototype-endswith"), "no-string-prototype-includes": require("./rules/no-string-prototype-includes"), + "no-string-prototype-iswellformed": require("./rules/no-string-prototype-iswellformed"), "no-string-prototype-iswellformed-towellformed": require("./rules/no-string-prototype-iswellformed-towellformed"), "no-string-prototype-matchall": require("./rules/no-string-prototype-matchall"), "no-string-prototype-normalize": require("./rules/no-string-prototype-normalize"), @@ -318,6 +339,7 @@ module.exports = { "no-string-prototype-replaceall": require("./rules/no-string-prototype-replaceall"), "no-string-prototype-startswith": require("./rules/no-string-prototype-startswith"), "no-string-prototype-substr": require("./rules/no-string-prototype-substr"), + "no-string-prototype-towellformed": require("./rules/no-string-prototype-towellformed"), "no-string-prototype-trim": require("./rules/no-string-prototype-trim"), "no-string-prototype-trimleft-trimright": require("./rules/no-string-prototype-trimleft-trimright"), "no-string-prototype-trimstart-trimend": require("./rules/no-string-prototype-trimstart-trimend"), diff --git a/lib/rules/no-array-prototype-at.js b/lib/rules/no-array-prototype-at.js new file mode 100644 index 00000000..57f3b67a --- /dev/null +++ b/lib/rules/no-array-prototype-at.js @@ -0,0 +1,51 @@ +/** + * @author Yosuke Ota + * See LICENSE file in root directory for full license. + */ +"use strict" + +const { + definePrototypeMethodHandler, +} = require("../util/define-prototype-method-handler") + +module.exports = { + meta: { + docs: { + description: "disallow the `Array.prototype.at()` methods.", + category: "ES2022", + proposal: "relative-indexing-method", + recommended: false, + url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-array-prototype-at.html", + }, + fixable: null, + messages: { + forbidden: "ES2022 '{{name}}' method is forbidden.", + }, + schema: [ + { + type: "object", + properties: { + aggressive: { type: "boolean" }, + }, + additionalProperties: false, + }, + ], + type: "problem", + }, + create(context) { + return definePrototypeMethodHandler(context, { + Array: ["at"], + Int8Array: ["at"], + Uint8Array: ["at"], + Uint8ClampedArray: ["at"], + Int16Array: ["at"], + Uint16Array: ["at"], + Int32Array: ["at"], + Uint32Array: ["at"], + Float32Array: ["at"], + Float64Array: ["at"], + BigInt64Array: ["at"], + BigUint64Array: ["at"], + }) + }, +} diff --git a/lib/rules/no-array-prototype-toreversed.js b/lib/rules/no-array-prototype-toreversed.js index 74b02f2d..72e90a11 100644 --- a/lib/rules/no-array-prototype-toreversed.js +++ b/lib/rules/no-array-prototype-toreversed.js @@ -9,6 +9,7 @@ module.exports = { docs: { description: "disallow the `Array.prototype.toReversed` method.", category: "ES2023", + proposal: "change-array-by-copy", recommended: false, url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-array-prototype-toreversed.html", }, diff --git a/lib/rules/no-array-prototype-tosorted.js b/lib/rules/no-array-prototype-tosorted.js index af65c180..6304f16f 100644 --- a/lib/rules/no-array-prototype-tosorted.js +++ b/lib/rules/no-array-prototype-tosorted.js @@ -9,6 +9,7 @@ module.exports = { docs: { description: "disallow the `Array.prototype.toSorted` method.", category: "ES2023", + proposal: "change-array-by-copy", recommended: false, url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-array-prototype-tosorted.html", }, diff --git a/lib/rules/no-array-prototype-tospliced.js b/lib/rules/no-array-prototype-tospliced.js index cee1721c..54e44c76 100644 --- a/lib/rules/no-array-prototype-tospliced.js +++ b/lib/rules/no-array-prototype-tospliced.js @@ -9,6 +9,7 @@ module.exports = { docs: { description: "disallow the `Array.prototype.toSpliced` method.", category: "ES2023", + proposal: "change-array-by-copy", recommended: false, url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-array-prototype-tospliced.html", }, diff --git a/lib/rules/no-array-prototype-with.js b/lib/rules/no-array-prototype-with.js index 266c1cca..cc4c0bff 100644 --- a/lib/rules/no-array-prototype-with.js +++ b/lib/rules/no-array-prototype-with.js @@ -9,6 +9,7 @@ module.exports = { docs: { description: "disallow the `Array.prototype.with` method.", category: "ES2023", + proposal: "change-array-by-copy", recommended: false, url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-array-prototype-with.html", }, diff --git a/lib/rules/no-array-string-prototype-at.js b/lib/rules/no-array-string-prototype-at.js index 1a968284..486c2c2c 100644 --- a/lib/rules/no-array-string-prototype-at.js +++ b/lib/rules/no-array-string-prototype-at.js @@ -4,12 +4,13 @@ */ "use strict" -const { - definePrototypeMethodHandler, -} = require("../util/define-prototype-method-handler") - +const rules = [ + require("./no-array-prototype-at"), + require("./no-string-prototype-at"), +] module.exports = { meta: { + deprecated: true, docs: { description: "disallow the `{Array,String}.prototype.at()` methods.", @@ -21,6 +22,7 @@ module.exports = { messages: { forbidden: "ES2022 '{{name}}' method is forbidden.", }, + replacedBy: ["no-array-prototype-at", "no-string-prototype-at"], schema: [ { type: "object", @@ -33,20 +35,21 @@ module.exports = { type: "problem", }, create(context) { - return definePrototypeMethodHandler(context, { - Array: ["at"], - String: ["at"], - Int8Array: ["at"], - Uint8Array: ["at"], - Uint8ClampedArray: ["at"], - Int16Array: ["at"], - Uint16Array: ["at"], - Int32Array: ["at"], - Uint32Array: ["at"], - Float32Array: ["at"], - Float64Array: ["at"], - BigInt64Array: ["at"], - BigUint64Array: ["at"], - }) + const visitorEntries = rules.flatMap((rule) => + Object.entries(rule.create(context)), + ) + return Object.fromEntries( + [...new Set(visitorEntries.map(([key]) => key))].map((key) => { + const visitors = visitorEntries.filter(([k]) => k === key) + return [ + key, + (...args) => { + for (const [, visitor] of visitors) { + visitor(...args) + } + }, + ] + }), + ) }, } diff --git a/lib/rules/no-class-fields.js b/lib/rules/no-class-fields.js index e0f30ca5..ad0603c2 100644 --- a/lib/rules/no-class-fields.js +++ b/lib/rules/no-class-fields.js @@ -4,49 +4,15 @@ */ "use strict" -const { - getFunctionNameWithKind, - getPropertyName, -} = require("@eslint-community/eslint-utils") -const { getSourceCode } = require("eslint-compat-utils") - -/** - * Get the name and kind of the given PropertyDefinition node. - * @param {PropertyDefinition} node - The PropertyDefinition node to get. - * @param {SourceCode} sourceCode The source code object to get the code of computed property keys. - * @returns {string} The name and kind of the PropertyDefinition node. - */ -function getFieldNameWithKind(node, sourceCode) { - const tokens = [] - - if (node.static) { - tokens.push("static") - } - if (node.key.type === "PrivateIdentifier") { - tokens.push("private") - } - - tokens.push("field") - - if (node.key.type === "PrivateIdentifier") { - tokens.push(`#${node.key.name}`) - } else { - const name = getPropertyName(node) - if (name) { - tokens.push(`'${name}'`) - } else if (sourceCode) { - const keyText = sourceCode.getText(node.key) - if (!keyText.includes("\n")) { - tokens.push(`[${keyText}]`) - } - } - } - - return tokens.join(" ") -} - +const rules = [ + require("./no-class-instance-fields"), + require("./no-class-private-fields"), + require("./no-class-private-methods"), + require("./no-class-static-fields"), +] module.exports = { meta: { + deprecated: true, docs: { description: "disallow class fields.", category: "ES2022", @@ -57,57 +23,31 @@ module.exports = { messages: { forbidden: "ES2022 {{nameWithKind}} is forbidden.", }, + replacedBy: [ + "no-class-instance-fields", + "no-class-private-fields", + "no-class-private-methods", + "no-class-static-fields", + ], schema: [], type: "problem", }, create(context) { - return { - PropertyDefinition(node) { - if (node.declare || node.parent.parent.declare) { - return - } - context.report({ - node: node.key, - messageId: "forbidden", - data: { - nameWithKind: getFieldNameWithKind( - node, - getSourceCode(context), - ), - }, - }) - }, - "MethodDefinition:exit"(node) { - if (node.key.type !== "PrivateIdentifier") { - return - } - context.report({ - node: node.key, - messageId: "forbidden", - data: { - nameWithKind: getFunctionNameWithKind( - node.value, - getSourceCode(context), - ), - }, - }) - }, - ":not(PropertyDefinition, MethodDefinition) > PrivateIdentifier"( - node, - ) { - const parent = node.parent - context.report({ - node, - messageId: "forbidden", - data: { - nameWithKind: - parent.parent.type === "CallExpression" && - parent.parent.callee === parent - ? `private method call #${node.name}()` - : `private access #${node.name}`, + const visitorEntries = rules.flatMap((rule) => + Object.entries(rule.create(context)), + ) + return Object.fromEntries( + [...new Set(visitorEntries.map(([key]) => key))].map((key) => { + const visitors = visitorEntries.filter(([k]) => k === key) + return [ + key, + (...args) => { + for (const [, visitor] of visitors) { + visitor(...args) + } }, - }) - }, - } + ] + }), + ) }, } diff --git a/lib/rules/no-class-instance-fields.js b/lib/rules/no-class-instance-fields.js new file mode 100644 index 00000000..ed79a20f --- /dev/null +++ b/lib/rules/no-class-instance-fields.js @@ -0,0 +1,50 @@ +/** + * @author Yosuke Ota + * See LICENSE file in root directory for full license. + */ +"use strict" + +const { getSourceCode } = require("eslint-compat-utils") +const { getFieldName } = require("../utils") + +module.exports = { + meta: { + docs: { + description: "disallow instance class fields.", + category: "ES2022", + proposal: "class-fields", + recommended: false, + url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-class-instance-fields.html", + }, + fixable: null, + messages: { + forbidden: "ES2022 {{nameWithKind}} is forbidden.", + }, + schema: [], + type: "problem", + }, + create(context) { + return { + PropertyDefinition(node) { + if (node.static) { + return + } + if (node.declare || node.parent.parent.declare) { + return + } + context.report({ + node: node.key, + messageId: "forbidden", + data: { + nameWithKind: [ + "instance field", + getFieldName(node, getSourceCode(context)), + ] + .filter(Boolean) + .join(" "), + }, + }) + }, + } + }, +} diff --git a/lib/rules/no-class-private-fields.js b/lib/rules/no-class-private-fields.js new file mode 100644 index 00000000..5f68de3a --- /dev/null +++ b/lib/rules/no-class-private-fields.js @@ -0,0 +1,69 @@ +/** + * @author Yosuke Ota + * See LICENSE file in root directory for full license. + */ +"use strict" + +const { getSourceCode } = require("eslint-compat-utils") +const { getFieldName } = require("../utils") + +module.exports = { + meta: { + docs: { + description: "disallow private class fields.", + category: "ES2022", + proposal: "class-fields", + recommended: false, + url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-class-private-fields.html", + }, + fixable: null, + messages: { + forbidden: "ES2022 {{nameWithKind}} is forbidden.", + }, + schema: [], + type: "problem", + }, + create(context) { + return { + PrivateIdentifier(node) { + /** @type {import('estree').Node} */ + const parent = node.parent + if (parent.type === "MethodDefinition" && parent.key === node) { + return + } + if ( + parent.type === "PropertyDefinition" && + parent.key === node + ) { + if (parent.declare || parent.parent.parent.declare) { + return + } + context.report({ + node, + messageId: "forbidden", + data: { + nameWithKind: [ + "private field", + getFieldName(parent, getSourceCode(context)), + ] + .filter(Boolean) + .join(" "), + }, + }) + } else { + context.report({ + node, + messageId: "forbidden", + data: { + nameWithKind: + parent.parent.type === "CallExpression" && + parent.parent.callee === parent + ? `private method call #${node.name}()` + : `private access #${node.name}`, + }, + }) + } + }, + } + }, +} diff --git a/lib/rules/no-class-private-methods.js b/lib/rules/no-class-private-methods.js new file mode 100644 index 00000000..d2fc5456 --- /dev/null +++ b/lib/rules/no-class-private-methods.js @@ -0,0 +1,47 @@ +/** + * @author Yosuke Ota + * See LICENSE file in root directory for full license. + */ +"use strict" + +const { getSourceCode } = require("eslint-compat-utils") +const { getFieldName } = require("../utils") + +module.exports = { + meta: { + docs: { + description: "disallow private class methods.", + category: "ES2022", + proposal: "class-fields", + recommended: false, + url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-class-private-methods.html", + }, + fixable: null, + messages: { + forbidden: "ES2022 {{nameWithKind}} is forbidden.", + }, + schema: [], + type: "problem", + }, + create(context) { + return { + "MethodDefinition:exit"(node) { + if (node.key.type !== "PrivateIdentifier") { + return + } + context.report({ + node: node.key, + messageId: "forbidden", + data: { + nameWithKind: [ + "private method", + getFieldName(node, getSourceCode(context)), + ] + .filter(Boolean) + .join(" "), + }, + }) + }, + } + }, +} diff --git a/lib/rules/no-class-static-fields.js b/lib/rules/no-class-static-fields.js new file mode 100644 index 00000000..4506d18a --- /dev/null +++ b/lib/rules/no-class-static-fields.js @@ -0,0 +1,50 @@ +/** + * @author Yosuke Ota + * See LICENSE file in root directory for full license. + */ +"use strict" + +const { getSourceCode } = require("eslint-compat-utils") +const { getFieldName } = require("../utils") + +module.exports = { + meta: { + docs: { + description: "disallow static class fields.", + category: "ES2022", + proposal: "class-fields", + recommended: false, + url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-class-static-fields.html", + }, + fixable: null, + messages: { + forbidden: "ES2022 {{nameWithKind}} is forbidden.", + }, + schema: [], + type: "problem", + }, + create(context) { + return { + PropertyDefinition(node) { + if (!node.static) { + return + } + if (node.declare || node.parent.parent.declare) { + return + } + context.report({ + node: node.key, + messageId: "forbidden", + data: { + nameWithKind: [ + "static field", + getFieldName(node, getSourceCode(context)), + ] + .filter(Boolean) + .join(" "), + }, + }) + }, + } + }, +} diff --git a/lib/rules/no-intl-numberformat-prototype-formatrange.js b/lib/rules/no-intl-numberformat-prototype-formatrange.js index 888a4006..e34fa735 100644 --- a/lib/rules/no-intl-numberformat-prototype-formatrange.js +++ b/lib/rules/no-intl-numberformat-prototype-formatrange.js @@ -10,6 +10,7 @@ module.exports = { description: "disallow the `NumberFormat.prototype.formatRange` method.", category: "ES2023-Intl-API", + proposal: "intl-numberformat-v3", recommended: false, url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-intl-numberformat-prototype-formatrange.html", }, diff --git a/lib/rules/no-intl-numberformat-prototype-formatrangetoparts.js b/lib/rules/no-intl-numberformat-prototype-formatrangetoparts.js index ac489b2a..24cc28ed 100644 --- a/lib/rules/no-intl-numberformat-prototype-formatrangetoparts.js +++ b/lib/rules/no-intl-numberformat-prototype-formatrangetoparts.js @@ -10,6 +10,7 @@ module.exports = { description: "disallow the `NumberFormat.prototype.formatRangeToParts` method.", category: "ES2023-Intl-API", + proposal: "intl-numberformat-v3", recommended: false, url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-intl-numberformat-prototype-formatrangetoparts.html", }, diff --git a/lib/rules/no-intl-pluralrules-prototype-selectrange.js b/lib/rules/no-intl-pluralrules-prototype-selectrange.js index 8e15b7d5..287c599a 100644 --- a/lib/rules/no-intl-pluralrules-prototype-selectrange.js +++ b/lib/rules/no-intl-pluralrules-prototype-selectrange.js @@ -10,6 +10,7 @@ module.exports = { description: "disallow the `PluralRules.prototype.selectRange` method.", category: "ES2023-Intl-API", + proposal: "intl-numberformat-v3", recommended: false, url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-intl-pluralrules-prototype-selectrange.html", }, diff --git a/lib/rules/no-map-groupby.js b/lib/rules/no-map-groupby.js new file mode 100644 index 00000000..61b689f5 --- /dev/null +++ b/lib/rules/no-map-groupby.js @@ -0,0 +1,43 @@ +"use strict" + +const { ReferenceTracker, READ } = require("@eslint-community/eslint-utils") +const { getSourceCode } = require("eslint-compat-utils") + +module.exports = { + meta: { + docs: { + description: "disallow the `Map.groupBy()` method.", + category: "ES2024", + proposal: "array-grouping", + recommended: false, + url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-map-groupby.html", + }, + fixable: null, + messages: { + forbidden: "ES2024 '{{name}}' is forbidden.", + }, + schema: [], + type: "problem", + }, + create(context) { + return { + "Program:exit"(program) { + const sourceCode = getSourceCode(context) + const tracker = new ReferenceTracker( + sourceCode.getScope(program), + ) + for (const { node, path } of tracker.iterateGlobalReferences({ + Map: { + groupBy: { [READ]: true }, + }, + })) { + context.report({ + node, + messageId: "forbidden", + data: { name: path.join(".") }, + }) + } + }, + } + }, +} diff --git a/lib/rules/no-object-groupby.js b/lib/rules/no-object-groupby.js new file mode 100644 index 00000000..eb49ab56 --- /dev/null +++ b/lib/rules/no-object-groupby.js @@ -0,0 +1,43 @@ +"use strict" + +const { ReferenceTracker, READ } = require("@eslint-community/eslint-utils") +const { getSourceCode } = require("eslint-compat-utils") + +module.exports = { + meta: { + docs: { + description: "disallow the `Object.groupBy()` method.", + category: "ES2024", + proposal: "array-grouping", + recommended: false, + url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-object-groupby.html", + }, + fixable: null, + messages: { + forbidden: "ES2024 '{{name}}' is forbidden.", + }, + schema: [], + type: "problem", + }, + create(context) { + return { + "Program:exit"(program) { + const sourceCode = getSourceCode(context) + const tracker = new ReferenceTracker( + sourceCode.getScope(program), + ) + for (const { node, path } of tracker.iterateGlobalReferences({ + Object: { + groupBy: { [READ]: true }, + }, + })) { + context.report({ + node, + messageId: "forbidden", + data: { name: path.join(".") }, + }) + } + }, + } + }, +} diff --git a/lib/rules/no-object-map-groupby.js b/lib/rules/no-object-map-groupby.js index ba6885be..0e781626 100644 --- a/lib/rules/no-object-map-groupby.js +++ b/lib/rules/no-object-map-groupby.js @@ -1,10 +1,9 @@ "use strict" -const { ReferenceTracker, READ } = require("@eslint-community/eslint-utils") -const { getSourceCode } = require("eslint-compat-utils") - +const rules = [require("./no-object-groupby"), require("./no-map-groupby")] module.exports = { meta: { + deprecated: true, docs: { description: "disallow the `{Object,Map}.groupBy()` function (array grouping).", @@ -16,31 +15,26 @@ module.exports = { messages: { forbidden: "ES2024 '{{name}}' is forbidden.", }, + replacedBy: ["no-object-groupby", "no-map-groupby"], schema: [], type: "problem", }, create(context) { - return { - "Program:exit"(program) { - const sourceCode = getSourceCode(context) - const tracker = new ReferenceTracker( - sourceCode.getScope(program), - ) - for (const { node, path } of tracker.iterateGlobalReferences({ - Object: { - groupBy: { [READ]: true }, - }, - Map: { - groupBy: { [READ]: true }, + const visitorEntries = rules.flatMap((rule) => + Object.entries(rule.create(context)), + ) + return Object.fromEntries( + [...new Set(visitorEntries.map(([key]) => key))].map((key) => { + const visitors = visitorEntries.filter(([k]) => k === key) + return [ + key, + (...args) => { + for (const [, visitor] of visitors) { + visitor(...args) + } }, - })) { - context.report({ - node, - messageId: "forbidden", - data: { name: path.join(".") }, - }) - } - }, - } + ] + }), + ) }, } diff --git a/lib/rules/no-string-prototype-at.js b/lib/rules/no-string-prototype-at.js new file mode 100644 index 00000000..710a8e1e --- /dev/null +++ b/lib/rules/no-string-prototype-at.js @@ -0,0 +1,40 @@ +/** + * @author Yosuke Ota + * See LICENSE file in root directory for full license. + */ +"use strict" + +const { + definePrototypeMethodHandler, +} = require("../util/define-prototype-method-handler") + +module.exports = { + meta: { + docs: { + description: "disallow the `String.prototype.at()` methods.", + category: "ES2022", + proposal: "relative-indexing-method", + recommended: false, + url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-string-prototype-at.html", + }, + fixable: null, + messages: { + forbidden: "ES2022 '{{name}}' method is forbidden.", + }, + schema: [ + { + type: "object", + properties: { + aggressive: { type: "boolean" }, + }, + additionalProperties: false, + }, + ], + type: "problem", + }, + create(context) { + return definePrototypeMethodHandler(context, { + String: ["at"], + }) + }, +} diff --git a/lib/rules/no-string-prototype-iswellformed-towellformed.js b/lib/rules/no-string-prototype-iswellformed-towellformed.js index 10c10419..87e5215b 100644 --- a/lib/rules/no-string-prototype-iswellformed-towellformed.js +++ b/lib/rules/no-string-prototype-iswellformed-towellformed.js @@ -1,11 +1,13 @@ "use strict" -const { - definePrototypeMethodHandler, -} = require("../util/define-prototype-method-handler") +const rules = [ + require("./no-string-prototype-iswellformed"), + require("./no-string-prototype-towellformed"), +] module.exports = { meta: { + deprecated: true, docs: { description: "disallow the `String.prototype.{isWellFormed,toWellFormed}` methods.", @@ -17,6 +19,10 @@ module.exports = { messages: { forbidden: "ES2024 '{{name}}' method is forbidden.", }, + replacedBy: [ + "no-string-prototype-iswellformed", + "no-string-prototype-towellformed", + ], schema: [ { type: "object", @@ -29,8 +35,21 @@ module.exports = { type: "problem", }, create(context) { - return definePrototypeMethodHandler(context, { - String: ["isWellFormed", "toWellFormed"], - }) + const visitorEntries = rules.flatMap((rule) => + Object.entries(rule.create(context)), + ) + return Object.fromEntries( + [...new Set(visitorEntries.map(([key]) => key))].map((key) => { + const visitors = visitorEntries.filter(([k]) => k === key) + return [ + key, + (...args) => { + for (const [, visitor] of visitors) { + visitor(...args) + } + }, + ] + }), + ) }, } diff --git a/lib/rules/no-string-prototype-iswellformed.js b/lib/rules/no-string-prototype-iswellformed.js new file mode 100644 index 00000000..edd53fd2 --- /dev/null +++ b/lib/rules/no-string-prototype-iswellformed.js @@ -0,0 +1,37 @@ +"use strict" + +const { + definePrototypeMethodHandler, +} = require("../util/define-prototype-method-handler") + +module.exports = { + meta: { + docs: { + description: + "disallow the `String.prototype.isWellFormed` methods.", + category: "ES2024", + recommended: false, + proposal: "is-usv-string", + url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-string-prototype-iswellformed.html", + }, + fixable: null, + messages: { + forbidden: "ES2024 '{{name}}' method is forbidden.", + }, + schema: [ + { + type: "object", + properties: { + aggressive: { type: "boolean" }, + }, + additionalProperties: false, + }, + ], + type: "problem", + }, + create(context) { + return definePrototypeMethodHandler(context, { + String: ["isWellFormed"], + }) + }, +} diff --git a/lib/rules/no-string-prototype-towellformed.js b/lib/rules/no-string-prototype-towellformed.js new file mode 100644 index 00000000..81a896c6 --- /dev/null +++ b/lib/rules/no-string-prototype-towellformed.js @@ -0,0 +1,37 @@ +"use strict" + +const { + definePrototypeMethodHandler, +} = require("../util/define-prototype-method-handler") + +module.exports = { + meta: { + docs: { + description: + "disallow the `String.prototype.toWellFormed` methods.", + category: "ES2024", + recommended: false, + proposal: "is-usv-string", + url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-string-prototype-towellformed.html", + }, + fixable: null, + messages: { + forbidden: "ES2024 '{{name}}' method is forbidden.", + }, + schema: [ + { + type: "object", + properties: { + aggressive: { type: "boolean" }, + }, + additionalProperties: false, + }, + ], + type: "problem", + }, + create(context) { + return definePrototypeMethodHandler(context, { + String: ["toWellFormed"], + }) + }, +} diff --git a/lib/utils.js b/lib/utils.js index 19d0627e..3dc698e9 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -10,8 +10,14 @@ const { PatternMatcher, ReferenceTracker, getStringIfConstant, + getPropertyName, } = require("@eslint-community/eslint-utils") +/** + * @typedef {import('estree').PropertyDefinition} PropertyDefinition + * @typedef {import('estree').MethodDefinition} MethodDefinition + */ + module.exports = { /** * Define generator to search pattern. @@ -67,4 +73,26 @@ module.exports = { }, ) }, + + /** + * Get the name of the given node. + * @param {PropertyDefinition|MethodDefinition} node - The node to get. + * @param {SourceCode} sourceCode The source code object to get the code of computed property keys. + * @returns {string} The name of the node. + */ + getFieldName(node, sourceCode) { + if (node.key.type === "PrivateIdentifier") { + return `#${node.key.name}` + } + const name = getPropertyName(node) + if (name) { + return `'${name}'` + } else if (sourceCode) { + const keyText = sourceCode.getText(node.key) + if (!keyText.includes("\n")) { + return `[${keyText}]` + } + } + return "" + }, } diff --git a/scripts/proposals.js b/scripts/proposals.js index 14e4f64f..2ec08779 100644 --- a/scripts/proposals.js +++ b/scripts/proposals.js @@ -1,6 +1,30 @@ "use strict" module.exports = { + "array-grouping": { + title: "Array Grouping", + link: "https://github.com/tc39/proposal-array-grouping", + }, + "change-array-by-copy": { + title: "Change Array by Copy", + link: "https://github.com/tc39/proposal-change-array-by-copy", + }, + "class-fields": { + title: "Class Fields", + link: "https://github.com/tc39/proposal-class-fields", + }, + "intl-numberformat-v3": { + title: "Intl.NumberFormat V3", + link: "https://github.com/tc39/proposal-intl-numberformat-v3", + }, + "is-usv-string": { + title: "Well-Formed Unicode Strings", + link: "https://github.com/tc39/proposal-is-usv-string", + }, + "relative-indexing-method": { + title: "An .at() method on all the built-in indexables", + link: "https://github.com/tc39/proposal-relative-indexing-method", + }, "set-methods": { title: "Set Methods for JavaScript", link: "https://github.com/tc39/proposal-set-methods", diff --git a/scripts/update-docs-rules.js b/scripts/update-docs-rules.js index fc3b40a5..095099b5 100644 --- a/scripts/update-docs-rules.js +++ b/scripts/update-docs-rules.js @@ -59,6 +59,9 @@ async function main() { replacedBy, } of rules) { const filePath = path.join(docsRoot, `${ruleId}.md`) + if (!fs.existsSync(filePath)) { + fs.writeFileSync(filePath, "") + } const originalContent = fs.readFileSync(filePath, "utf8") const since = getSince(originalContent) diff --git a/tests/lib/rules/no-array-prototype-at.js b/tests/lib/rules/no-array-prototype-at.js new file mode 100644 index 00000000..225cfc6e --- /dev/null +++ b/tests/lib/rules/no-array-prototype-at.js @@ -0,0 +1,231 @@ +/** + * @author Yosuke Ota + * See LICENSE file in root directory for full license. + */ +"use strict" + +const path = require("path") +const RuleTester = require("../../tester") +const rule = require("../../../lib/rules/no-array-prototype-at.js") +const ruleId = "no-array-prototype-at" + +new RuleTester().run(ruleId, rule, { + valid: [ + "at(-1)", + "foo.reverse()", + "foo.at(-1)", + { code: "at(-1)", settings: { "es-x": { aggressive: true } } }, + { code: "foo.reverse()", settings: { "es-x": { aggressive: true } } }, + { + code: "foo.at(-1)", + options: [{ aggressive: false }], + settings: { "es-x": { aggressive: true } }, + }, + ], + invalid: [ + { + code: "foo.at(-1)", + errors: ["ES2022 'Array.prototype.at' method is forbidden."], + settings: { "es-x": { aggressive: true } }, + }, + { + code: "foo.at(-1)", + options: [{ aggressive: true }], + errors: ["ES2022 'Array.prototype.at' method is forbidden."], + settings: { "es-x": { aggressive: false } }, + }, + { + code: "[1,2,3].at(-1)", + errors: ["ES2022 'Array.prototype.at' method is forbidden."], + }, + ], +}) + +// ----------------------------------------------------------------------------- +// TypeScript +// ----------------------------------------------------------------------------- +const parser = require("@typescript-eslint/parser") +const tsconfigRootDir = path.resolve(__dirname, "../../fixtures") +const project = "tsconfig.json" +const filename = path.join(tsconfigRootDir, "test.ts") + +new RuleTester({ + languageOptions: { parser, parserOptions: { tsconfigRootDir, project } }, +}).run(`${ruleId} TS Full Type Information`, rule, { + valid: [ + { filename, code: "at(-1)" }, + { filename, code: "foo.reverse()" }, + { filename, code: "foo.at(-1)" }, + { filename, code: "let foo = {}; foo.at(-1)" }, + { + filename, + code: "at(-1)", + settings: { "es-x": { aggressive: true } }, + }, + { + filename, + code: "foo.reverse()", + settings: { "es-x": { aggressive: true } }, + }, + ], + invalid: [ + { + filename, + code: "[1, 2, 3].at(-1)", + errors: ["ES2022 'Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "let foo = []; foo.at(-1)", + errors: ["ES2022 'Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "let foo = Array(); foo.at(-1)", + errors: ["ES2022 'Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "function f(a: T) { a.at(-1) }", + errors: ["ES2022 'Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "function f(a: T) { a.at(-1) }", + errors: ["ES2022 'Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "function f(a: T) { a.at(-1) }", + errors: ["ES2022 'Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "foo.at(-1)", + errors: ["ES2022 'Array.prototype.at' method is forbidden."], + settings: { "es-x": { aggressive: true } }, + }, + { + filename, + code: "let foo = new Int8Array(42); foo.at(-1)", + errors: ["ES2022 'Int8Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "function f(a: T) { a.at(-1) }", + errors: ["ES2022 'Int8Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "let foo = new Uint8Array(42); foo.at(-1)", + errors: ["ES2022 'Uint8Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "function f(a: T) { a.at(-1) }", + errors: ["ES2022 'Uint8Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "let foo = new Uint8ClampedArray(42); foo.at(-1)", + errors: [ + "ES2022 'Uint8ClampedArray.prototype.at' method is forbidden.", + ], + }, + { + filename, + code: "function f(a: T) { a.at(-1) }", + errors: [ + "ES2022 'Uint8ClampedArray.prototype.at' method is forbidden.", + ], + }, + { + filename, + code: "let foo = new Int16Array(42); foo.at(-1)", + errors: ["ES2022 'Int16Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "function f(a: T) { a.at(-1) }", + errors: ["ES2022 'Int16Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "let foo = new Uint16Array(42); foo.at(-1)", + errors: ["ES2022 'Uint16Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "function f(a: T) { a.at(-1) }", + errors: ["ES2022 'Uint16Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "let foo = new Int32Array(42); foo.at(-1)", + errors: ["ES2022 'Int32Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "function f(a: T) { a.at(-1) }", + errors: ["ES2022 'Int32Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "let foo = new Uint32Array(42); foo.at(-1)", + errors: ["ES2022 'Uint32Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "function f(a: T) { a.at(-1) }", + errors: ["ES2022 'Uint32Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "let foo = new Float32Array(42); foo.at(-1)", + errors: ["ES2022 'Float32Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "function f(a: T) { a.at(-1) }", + errors: ["ES2022 'Float32Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "let foo = new Float64Array(42); foo.at(-1)", + errors: ["ES2022 'Float64Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "function f(a: T) { a.at(-1) }", + errors: ["ES2022 'Float64Array.prototype.at' method is forbidden."], + }, + { + filename, + code: "let foo = new BigInt64Array(42); foo.at(-1)", + errors: [ + "ES2022 'BigInt64Array.prototype.at' method is forbidden.", + ], + }, + { + filename, + code: "function f(a: T) { a.at(-1) }", + errors: [ + "ES2022 'BigInt64Array.prototype.at' method is forbidden.", + ], + }, + { + filename, + code: "let foo = new BigUint64Array(42); foo.at(-1)", + errors: [ + "ES2022 'BigUint64Array.prototype.at' method is forbidden.", + ], + }, + { + filename, + code: "function f(a: T) { a.at(-1) }", + errors: [ + "ES2022 'BigUint64Array.prototype.at' method is forbidden.", + ], + }, + ], +}) diff --git a/tests/lib/rules/no-array-string-prototype-at.js b/tests/lib/rules/no-array-string-prototype-at.js index 0e8d80e3..2345e062 100644 --- a/tests/lib/rules/no-array-string-prototype-at.js +++ b/tests/lib/rules/no-array-string-prototype-at.js @@ -25,13 +25,19 @@ new RuleTester().run(ruleId, rule, { invalid: [ { code: "foo.at(-1)", - errors: ["ES2022 'Array.prototype.at' method is forbidden."], + errors: [ + "ES2022 'Array.prototype.at' method is forbidden.", + "ES2022 'String.prototype.at' method is forbidden.", + ], settings: { "es-x": { aggressive: true } }, }, { code: "foo.at(-1)", options: [{ aggressive: true }], - errors: ["ES2022 'Array.prototype.at' method is forbidden."], + errors: [ + "ES2022 'Array.prototype.at' method is forbidden.", + "ES2022 'String.prototype.at' method is forbidden.", + ], settings: { "es-x": { aggressive: false } }, }, { @@ -111,7 +117,10 @@ new RuleTester({ { filename, code: "foo.at(-1)", - errors: ["ES2022 'Array.prototype.at' method is forbidden."], + errors: [ + "ES2022 'Array.prototype.at' method is forbidden.", + "ES2022 'String.prototype.at' method is forbidden.", + ], settings: { "es-x": { aggressive: true } }, }, { diff --git a/tests/lib/rules/no-class-fields.js b/tests/lib/rules/no-class-fields.js index 6c4bba1a..1fecfab8 100644 --- a/tests/lib/rules/no-class-fields.js +++ b/tests/lib/rules/no-class-fields.js @@ -61,50 +61,48 @@ new RuleTester().run(ruleId, rule, { }, { code: "class A { get #foo() {} }", - errors: ["ES2022 private getter #foo is forbidden."], + errors: ["ES2022 private method #foo is forbidden."], }, { code: "class A { set #foo(v) {} }", - errors: ["ES2022 private setter #foo is forbidden."], + errors: ["ES2022 private method #foo is forbidden."], }, { code: "class A { *#foo() {} }", - errors: ["ES2022 private generator method #foo is forbidden."], + errors: ["ES2022 private method #foo is forbidden."], }, { code: "class A { async #foo() {} }", - errors: ["ES2022 private async method #foo is forbidden."], + errors: ["ES2022 private method #foo is forbidden."], }, { code: "class A { static #foo() {} }", - errors: ["ES2022 static private method #foo is forbidden."], + errors: ["ES2022 private method #foo is forbidden."], }, { code: "class A { static get #foo() {} }", - errors: ["ES2022 static private getter #foo is forbidden."], + errors: ["ES2022 private method #foo is forbidden."], }, { code: "class A { static set #foo(v) {} }", - errors: ["ES2022 static private setter #foo is forbidden."], + errors: ["ES2022 private method #foo is forbidden."], }, { code: "class A { static *#foo() {} }", - errors: [ - "ES2022 static private generator method #foo is forbidden.", - ], + errors: ["ES2022 private method #foo is forbidden."], }, { code: "class A { static async #foo() {} }", - errors: ["ES2022 static private async method #foo is forbidden."], + errors: ["ES2022 private method #foo is forbidden."], }, { code: "class A { foo }", - errors: ["ES2022 field 'foo' is forbidden."], + errors: ["ES2022 instance field 'foo' is forbidden."], }, { code: "class A { foo = 42 }", - errors: ["ES2022 field 'foo' is forbidden."], + errors: ["ES2022 instance field 'foo' is forbidden."], }, { code: "class A { static foo }", @@ -116,11 +114,11 @@ new RuleTester().run(ruleId, rule, { }, { code: "class A { [foo] }", - errors: ["ES2022 field [foo] is forbidden."], + errors: ["ES2022 instance field [foo] is forbidden."], }, { code: "class A { [foo] = 42 }", - errors: ["ES2022 field [foo] is forbidden."], + errors: ["ES2022 instance field [foo] is forbidden."], }, { code: "class A { static [foo] }", @@ -132,19 +130,31 @@ new RuleTester().run(ruleId, rule, { }, { code: "class A { #foo }", - errors: ["ES2022 private field #foo is forbidden."], + errors: [ + "ES2022 instance field #foo is forbidden.", + "ES2022 private field #foo is forbidden.", + ], }, { code: "class A { #foo = 42 }", - errors: ["ES2022 private field #foo is forbidden."], + errors: [ + "ES2022 instance field #foo is forbidden.", + "ES2022 private field #foo is forbidden.", + ], }, { code: "class A { static #foo }", - errors: ["ES2022 static private field #foo is forbidden."], + errors: [ + "ES2022 static field #foo is forbidden.", + "ES2022 private field #foo is forbidden.", + ], }, { code: "class A { static #foo = 42 }", - errors: ["ES2022 static private field #foo is forbidden."], + errors: [ + "ES2022 static field #foo is forbidden.", + "ES2022 private field #foo is forbidden.", + ], }, { code: `class A { @@ -161,6 +171,10 @@ new RuleTester().run(ruleId, rule, { } }`, errors: [ + { + message: "ES2022 instance field #a is forbidden.", + line: 2, + }, { message: "ES2022 private field #a is forbidden.", line: 2, @@ -207,11 +221,19 @@ new RuleTester().run(ruleId, rule, { }`, errors: [ { - message: "ES2022 static private field #c is forbidden.", + message: "ES2022 static field #c is forbidden.", line: 2, }, { - message: "ES2022 static private field #d is forbidden.", + message: "ES2022 private field #c is forbidden.", + line: 2, + }, + { + message: "ES2022 static field #d is forbidden.", + line: 3, + }, + { + message: "ES2022 private field #d is forbidden.", line: 3, }, { @@ -238,22 +260,25 @@ new RuleTester().run(ruleId, rule, { }, { code: "class A { readonly foo = '' }", - errors: ["ES2022 field 'foo' is forbidden."], + errors: ["ES2022 instance field 'foo' is forbidden."], languageOptions: { parser: require("@typescript-eslint/parser") }, }, { code: "class A { foo: string }", - errors: ["ES2022 field 'foo' is forbidden."], + errors: ["ES2022 instance field 'foo' is forbidden."], languageOptions: { parser: require("@typescript-eslint/parser") }, }, { code: "class A { foo: string = '' }", - errors: ["ES2022 field 'foo' is forbidden."], + errors: ["ES2022 instance field 'foo' is forbidden."], languageOptions: { parser: require("@typescript-eslint/parser") }, }, { code: "class A { #foo: string }", - errors: ["ES2022 private field #foo is forbidden."], + errors: [ + "ES2022 instance field #foo is forbidden.", + "ES2022 private field #foo is forbidden.", + ], languageOptions: { parser: require("@typescript-eslint/parser") }, }, ], diff --git a/tests/lib/rules/no-class-instance-fields.js b/tests/lib/rules/no-class-instance-fields.js new file mode 100644 index 00000000..cf843501 --- /dev/null +++ b/tests/lib/rules/no-class-instance-fields.js @@ -0,0 +1,153 @@ +/** + * @author Yosuke Ota + * See LICENSE file in root directory for full license. + */ +"use strict" + +const RuleTester = require("../../tester") +const rule = require("../../../lib/rules/no-class-instance-fields.js") +const ruleId = "no-class-instance-fields" + +if (!RuleTester.isSupported(2022)) { + //eslint-disable-next-line no-console + console.log("Skip the tests of no-class-instance-fields.") + return +} + +new RuleTester().run(ruleId, rule, { + valid: [ + "class A {}", + "class A { foo() {} }", + "class A { get foo() {} }", + "class A { set foo(v) {} }", + "class A { *foo() {} }", + "class A { async foo() {} }", + "class A { static foo() {} }", + "class A { static get foo() {} }", + "class A { static set foo(v) {} }", + "class A { static *foo() {} }", + "class A { static async foo() {} }", + "class A { [foo]() {} }", + "class A { get [foo]() {} }", + "class A { set [foo](v) {} }", + "class A { *[foo]() {} }", + "class A { async [foo]() {} }", + "class A { static [foo]() {} }", + "class A { static get [foo]() {} }", + "class A { static set [foo](v) {} }", + "class A { static *[foo]() {} }", + "class A { static async [foo]() {} }", + "class A { #foo() {} }", + "class A { get #foo() {} }", + "class A { set #foo(v) {} }", + "class A { *#foo() {} }", + "class A { async #foo() {} }", + "class A { static #foo() {} }", + "class A { static get #foo() {} }", + "class A { static set #foo(v) {} }", + "class A { static *#foo() {} }", + "class A { static async #foo() {} }", + "class A { static foo }", + "class A { static foo = 42 }", + "class A { static [foo] }", + "class A { static [foo] = 42 }", + "class A { static #foo }", + "class A { static #foo = 42 }", + `class A { + static #c + static #d + + fn() { + A.#c; + x = A.#c; + A.#c++; + A.#c = x; + + A.#d(); + } + }`, + { + code: "class A { declare foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "class A { declare #foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "declare class A { foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "declare class A { #foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + ], + invalid: [ + { + code: "class A { foo }", + errors: ["ES2022 instance field 'foo' is forbidden."], + }, + { + code: "class A { foo = 42 }", + errors: ["ES2022 instance field 'foo' is forbidden."], + }, + { + code: "class A { [foo] }", + errors: ["ES2022 instance field [foo] is forbidden."], + }, + { + code: "class A { [foo] = 42 }", + errors: ["ES2022 instance field [foo] is forbidden."], + }, + { + code: "class A { #foo }", + errors: ["ES2022 instance field #foo is forbidden."], + }, + { + code: "class A { #foo = 42 }", + errors: ["ES2022 instance field #foo is forbidden."], + }, + { + code: `class A { + #a + #b () {} + + fn() { + this.#a; + x = this.#a; + this.#a++; + this.#a = x; + + this.#b(); + } + }`, + errors: [ + { + message: "ES2022 instance field #a is forbidden.", + line: 2, + }, + ], + }, + { + code: "class A { readonly foo = '' }", + errors: ["ES2022 instance field 'foo' is forbidden."], + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "class A { foo: string }", + errors: ["ES2022 instance field 'foo' is forbidden."], + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "class A { foo: string = '' }", + errors: ["ES2022 instance field 'foo' is forbidden."], + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "class A { #foo: string }", + errors: ["ES2022 instance field #foo is forbidden."], + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + ], +}) diff --git a/tests/lib/rules/no-class-private-fields.js b/tests/lib/rules/no-class-private-fields.js new file mode 100644 index 00000000..59529f28 --- /dev/null +++ b/tests/lib/rules/no-class-private-fields.js @@ -0,0 +1,196 @@ +/** + * @author Yosuke Ota + * See LICENSE file in root directory for full license. + */ +"use strict" + +const RuleTester = require("../../tester") +const rule = require("../../../lib/rules/no-class-private-fields.js") +const ruleId = "no-class-private-fields" + +if (!RuleTester.isSupported(2022)) { + //eslint-disable-next-line no-console + console.log("Skip the tests of no-class-private-fields.") + return +} + +new RuleTester().run(ruleId, rule, { + valid: [ + "class A {}", + "class A { foo() {} }", + "class A { get foo() {} }", + "class A { set foo(v) {} }", + "class A { *foo() {} }", + "class A { async foo() {} }", + "class A { static foo() {} }", + "class A { static get foo() {} }", + "class A { static set foo(v) {} }", + "class A { static *foo() {} }", + "class A { static async foo() {} }", + "class A { [foo]() {} }", + "class A { get [foo]() {} }", + "class A { set [foo](v) {} }", + "class A { *[foo]() {} }", + "class A { async [foo]() {} }", + "class A { static [foo]() {} }", + "class A { static get [foo]() {} }", + "class A { static set [foo](v) {} }", + "class A { static *[foo]() {} }", + "class A { static async [foo]() {} }", + "class A { foo }", + "class A { foo = 42 }", + "class A { static foo }", + "class A { static foo = 42 }", + "class A { [foo] }", + "class A { [foo] = 42 }", + "class A { static [foo] }", + "class A { static [foo] = 42 }", + "class A { #foo() {} }", + "class A { get #foo() {} }", + "class A { set #foo(v) {} }", + "class A { *#foo() {} }", + "class A { async #foo() {} }", + "class A { static #foo() {} }", + "class A { static get #foo() {} }", + "class A { static set #foo(v) {} }", + "class A { static *#foo() {} }", + "class A { static async #foo() {} }", + { + code: "class A { declare foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "class A { declare #foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "declare class A { foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "declare class A { #foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "class A { readonly foo = '' }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "class A { foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "class A { foo: string = '' }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + ], + invalid: [ + { + code: "class A { #foo }", + errors: ["ES2022 private field #foo is forbidden."], + }, + { + code: "class A { #foo = 42 }", + errors: ["ES2022 private field #foo is forbidden."], + }, + { + code: "class A { static #foo }", + errors: ["ES2022 private field #foo is forbidden."], + }, + { + code: "class A { static #foo = 42 }", + errors: ["ES2022 private field #foo is forbidden."], + }, + { + code: `class A { + #a + #b () {} + + fn() { + this.#a; + x = this.#a; + this.#a++; + this.#a = x; + + this.#b(); + } + }`, + errors: [ + { + message: "ES2022 private field #a is forbidden.", + line: 2, + }, + { + message: "ES2022 private access #a is forbidden.", + line: 6, + }, + { + message: "ES2022 private access #a is forbidden.", + line: 7, + }, + { + message: "ES2022 private access #a is forbidden.", + line: 8, + }, + { + message: "ES2022 private access #a is forbidden.", + line: 9, + }, + { + message: "ES2022 private method call #b() is forbidden.", + line: 11, + }, + ], + }, + { + code: `class A { + static #c + static #d + + fn() { + A.#c; + x = A.#c; + A.#c++; + A.#c = x; + + A.#d(); + } + }`, + errors: [ + { + message: "ES2022 private field #c is forbidden.", + line: 2, + }, + { + message: "ES2022 private field #d is forbidden.", + line: 3, + }, + { + message: "ES2022 private access #c is forbidden.", + line: 6, + }, + { + message: "ES2022 private access #c is forbidden.", + line: 7, + }, + { + message: "ES2022 private access #c is forbidden.", + line: 8, + }, + { + message: "ES2022 private access #c is forbidden.", + line: 9, + }, + { + message: "ES2022 private method call #d() is forbidden.", + line: 11, + }, + ], + }, + { + code: "class A { #foo: string }", + errors: ["ES2022 private field #foo is forbidden."], + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + ], +}) diff --git a/tests/lib/rules/no-class-private-methods.js b/tests/lib/rules/no-class-private-methods.js new file mode 100644 index 00000000..db7512c6 --- /dev/null +++ b/tests/lib/rules/no-class-private-methods.js @@ -0,0 +1,161 @@ +/** + * @author Yosuke Ota + * See LICENSE file in root directory for full license. + */ +"use strict" + +const RuleTester = require("../../tester") +const rule = require("../../../lib/rules/no-class-private-methods.js") +const ruleId = "no-class-private-methods" + +if (!RuleTester.isSupported(2022)) { + //eslint-disable-next-line no-console + console.log("Skip the tests of no-class-private-methods.") + return +} + +new RuleTester().run(ruleId, rule, { + valid: [ + "class A {}", + "class A { foo() {} }", + "class A { get foo() {} }", + "class A { set foo(v) {} }", + "class A { *foo() {} }", + "class A { async foo() {} }", + "class A { static foo() {} }", + "class A { static get foo() {} }", + "class A { static set foo(v) {} }", + "class A { static *foo() {} }", + "class A { static async foo() {} }", + "class A { [foo]() {} }", + "class A { get [foo]() {} }", + "class A { set [foo](v) {} }", + "class A { *[foo]() {} }", + "class A { async [foo]() {} }", + "class A { static [foo]() {} }", + "class A { static get [foo]() {} }", + "class A { static set [foo](v) {} }", + "class A { static *[foo]() {} }", + "class A { static async [foo]() {} }", + "class A { foo }", + "class A { foo = 42 }", + "class A { static foo }", + "class A { static foo = 42 }", + "class A { [foo] }", + "class A { [foo] = 42 }", + "class A { static [foo] }", + "class A { static [foo] = 42 }", + "class A { #foo }", + "class A { #foo = 42 }", + "class A { static #foo }", + "class A { static #foo = 42 }", + `class A { + static #c + static #d + + fn() { + A.#c; + x = A.#c; + A.#c++; + A.#c = x; + + A.#d(); + } + }`, + { + code: "class A { declare foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "class A { declare #foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "declare class A { foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "declare class A { #foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "class A { readonly foo = '' }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "class A { foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "class A { foo: string = '' }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "class A { #foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + ], + invalid: [ + { + code: "class A { #foo() {} }", + errors: ["ES2022 private method #foo is forbidden."], + }, + { + code: "class A { get #foo() {} }", + errors: ["ES2022 private method #foo is forbidden."], + }, + { + code: "class A { set #foo(v) {} }", + errors: ["ES2022 private method #foo is forbidden."], + }, + { + code: "class A { *#foo() {} }", + errors: ["ES2022 private method #foo is forbidden."], + }, + { + code: "class A { async #foo() {} }", + errors: ["ES2022 private method #foo is forbidden."], + }, + { + code: "class A { static #foo() {} }", + errors: ["ES2022 private method #foo is forbidden."], + }, + { + code: "class A { static get #foo() {} }", + errors: ["ES2022 private method #foo is forbidden."], + }, + { + code: "class A { static set #foo(v) {} }", + errors: ["ES2022 private method #foo is forbidden."], + }, + { + code: "class A { static *#foo() {} }", + errors: ["ES2022 private method #foo is forbidden."], + }, + { + code: "class A { static async #foo() {} }", + errors: ["ES2022 private method #foo is forbidden."], + }, + { + code: `class A { + #a + #b () {} + + fn() { + this.#a; + x = this.#a; + this.#a++; + this.#a = x; + + this.#b(); + } + }`, + errors: [ + { + message: "ES2022 private method #b is forbidden.", + line: 3, + }, + ], + }, + ], +}) diff --git a/tests/lib/rules/no-class-static-fields.js b/tests/lib/rules/no-class-static-fields.js new file mode 100644 index 00000000..f20e6903 --- /dev/null +++ b/tests/lib/rules/no-class-static-fields.js @@ -0,0 +1,153 @@ +/** + * @author Yosuke Ota + * See LICENSE file in root directory for full license. + */ +"use strict" + +const RuleTester = require("../../tester") +const rule = require("../../../lib/rules/no-class-static-fields.js") +const ruleId = "no-class-static-fields" + +if (!RuleTester.isSupported(2022)) { + //eslint-disable-next-line no-console + console.log("Skip the tests of no-class-static-fields.") + return +} + +new RuleTester().run(ruleId, rule, { + valid: [ + "class A {}", + "class A { foo() {} }", + "class A { get foo() {} }", + "class A { set foo(v) {} }", + "class A { *foo() {} }", + "class A { async foo() {} }", + "class A { static foo() {} }", + "class A { static get foo() {} }", + "class A { static set foo(v) {} }", + "class A { static *foo() {} }", + "class A { static async foo() {} }", + "class A { [foo]() {} }", + "class A { get [foo]() {} }", + "class A { set [foo](v) {} }", + "class A { *[foo]() {} }", + "class A { async [foo]() {} }", + "class A { static [foo]() {} }", + "class A { static get [foo]() {} }", + "class A { static set [foo](v) {} }", + "class A { static *[foo]() {} }", + "class A { static async [foo]() {} }", + "class A { #foo }", + "class A { #foo = 42 }", + "class A { foo }", + "class A { foo = 42 }", + "class A { [foo] }", + "class A { [foo] = 42 }", + "class A { #foo() {} }", + "class A { get #foo() {} }", + "class A { set #foo(v) {} }", + "class A { *#foo() {} }", + "class A { async #foo() {} }", + "class A { static #foo() {} }", + "class A { static get #foo() {} }", + "class A { static set #foo(v) {} }", + "class A { static *#foo() {} }", + "class A { static async #foo() {} }", + { + code: "class A { declare foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "class A { declare #foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "declare class A { foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "declare class A { #foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "class A { readonly foo = '' }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "class A { foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "class A { foo: string = '' }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + { + code: "class A { #foo: string }", + languageOptions: { parser: require("@typescript-eslint/parser") }, + }, + `class A { + #a + #b () {} + + fn() { + this.#a; + x = this.#a; + this.#a++; + this.#a = x; + + this.#b(); + } + }`, + ], + invalid: [ + { + code: "class A { static foo }", + errors: ["ES2022 static field 'foo' is forbidden."], + }, + { + code: "class A { static foo = 42 }", + errors: ["ES2022 static field 'foo' is forbidden."], + }, + { + code: "class A { static [foo] }", + errors: ["ES2022 static field [foo] is forbidden."], + }, + { + code: "class A { static [foo] = 42 }", + errors: ["ES2022 static field [foo] is forbidden."], + }, + { + code: "class A { static #foo }", + errors: ["ES2022 static field #foo is forbidden."], + }, + { + code: "class A { static #foo = 42 }", + errors: ["ES2022 static field #foo is forbidden."], + }, + { + code: `class A { + static #c + static #d + + fn() { + A.#c; + x = A.#c; + A.#c++; + A.#c = x; + + A.#d(); + } + }`, + errors: [ + { + message: "ES2022 static field #c is forbidden.", + line: 2, + }, + { + message: "ES2022 static field #d is forbidden.", + line: 3, + }, + ], + }, + ], +}) diff --git a/tests/lib/rules/no-map-groupby.js b/tests/lib/rules/no-map-groupby.js new file mode 100644 index 00000000..93dfe2a5 --- /dev/null +++ b/tests/lib/rules/no-map-groupby.js @@ -0,0 +1,20 @@ +"use strict" + +const RuleTester = require("../../tester") +const rule = require("../../../lib/rules/no-map-groupby.js") + +new RuleTester().run("no-map-groupby", rule, { + valid: [ + "Object", + "Map", + "Object.assign", + "let Object = 0; Object.groupBy", + "let Map = 0; Map.groupBy", + ], + invalid: [ + { + code: "Map.groupBy", + errors: ["ES2024 'Map.groupBy' is forbidden."], + }, + ], +}) diff --git a/tests/lib/rules/no-object-groupby.js b/tests/lib/rules/no-object-groupby.js new file mode 100644 index 00000000..5e47bad5 --- /dev/null +++ b/tests/lib/rules/no-object-groupby.js @@ -0,0 +1,20 @@ +"use strict" + +const RuleTester = require("../../tester") +const rule = require("../../../lib/rules/no-object-groupby.js") + +new RuleTester().run("no-object-groupby", rule, { + valid: [ + "Object", + "Map", + "Object.assign", + "let Object = 0; Object.groupBy", + "let Map = 0; Map.groupBy", + ], + invalid: [ + { + code: "Object.groupBy", + errors: ["ES2024 'Object.groupBy' is forbidden."], + }, + ], +}) diff --git a/tests/lib/rules/no-string-prototype-at.js b/tests/lib/rules/no-string-prototype-at.js new file mode 100644 index 00000000..3def6371 --- /dev/null +++ b/tests/lib/rules/no-string-prototype-at.js @@ -0,0 +1,109 @@ +/** + * @author Yosuke Ota + * See LICENSE file in root directory for full license. + */ +"use strict" + +const path = require("path") +const RuleTester = require("../../tester") +const rule = require("../../../lib/rules/no-string-prototype-at.js") +const ruleId = "no-string-prototype-at" + +new RuleTester().run(ruleId, rule, { + valid: [ + "at(-1)", + "foo.reverse()", + "foo.at(-1)", + { code: "at(-1)", settings: { "es-x": { aggressive: true } } }, + { code: "foo.reverse()", settings: { "es-x": { aggressive: true } } }, + { + code: "foo.at(-1)", + options: [{ aggressive: false }], + settings: { "es-x": { aggressive: true } }, + }, + ], + invalid: [ + { + code: "foo.at(-1)", + errors: ["ES2022 'String.prototype.at' method is forbidden."], + settings: { "es-x": { aggressive: true } }, + }, + { + code: "foo.at(-1)", + options: [{ aggressive: true }], + errors: ["ES2022 'String.prototype.at' method is forbidden."], + settings: { "es-x": { aggressive: false } }, + }, + { + code: "'123'.at(-1)", + errors: ["ES2022 'String.prototype.at' method is forbidden."], + }, + ], +}) + +// ----------------------------------------------------------------------------- +// TypeScript +// ----------------------------------------------------------------------------- +const parser = require("@typescript-eslint/parser") +const tsconfigRootDir = path.resolve(__dirname, "../../fixtures") +const project = "tsconfig.json" +const filename = path.join(tsconfigRootDir, "test.ts") + +new RuleTester({ + languageOptions: { parser, parserOptions: { tsconfigRootDir, project } }, +}).run(`${ruleId} TS Full Type Information`, rule, { + valid: [ + { filename, code: "at(-1)" }, + { filename, code: "foo.reverse()" }, + { filename, code: "foo.at(-1)" }, + { filename, code: "let foo = {}; foo.at(-1)" }, + { + filename, + code: "at(-1)", + settings: { "es-x": { aggressive: true } }, + }, + { + filename, + code: "foo.reverse()", + settings: { "es-x": { aggressive: true } }, + }, + ], + invalid: [ + { + filename, + code: "'123'.at(-1)", + errors: ["ES2022 'String.prototype.at' method is forbidden."], + }, + { + filename, + code: "foo.at(-1)", + errors: ["ES2022 'String.prototype.at' method is forbidden."], + settings: { "es-x": { aggressive: true } }, + }, + { + filename, + code: "let foo = 'str'; foo.at(-1)", + errors: ["ES2022 'String.prototype.at' method is forbidden."], + }, + { + filename, + code: "let foo = String(42); foo.at(-1)", + errors: ["ES2022 'String.prototype.at' method is forbidden."], + }, + { + filename, + code: "function f(a: T) { a.at(-1) }", + errors: ["ES2022 'String.prototype.at' method is forbidden."], + }, + { + filename, + code: "function f(a: T) { a.at(-1) }", + errors: ["ES2022 'String.prototype.at' method is forbidden."], + }, + { + filename, + code: "function f(a: T) { a.at(-1) }", + errors: ["ES2022 'String.prototype.at' method is forbidden."], + }, + ], +}) diff --git a/tests/lib/rules/no-string-prototype-iswellformed.js b/tests/lib/rules/no-string-prototype-iswellformed.js new file mode 100644 index 00000000..ac63ec0e --- /dev/null +++ b/tests/lib/rules/no-string-prototype-iswellformed.js @@ -0,0 +1,140 @@ +"use strict" + +const path = require("path") +const RuleTester = require("../../tester") +const rule = require("../../../lib/rules/no-string-prototype-iswellformed.js") +const ruleId = "no-string-prototype-iswellformed" + +new RuleTester().run(ruleId, rule, { + valid: [ + "isWellFormed()", + "foo.isWellFormed()", + { code: "isWellFormed()", settings: { "es-x": { aggressive: true } } }, + { + code: "foo.isWellFormed()", + options: [{ aggressive: false }], + settings: { "es-x": { aggressive: true } }, + }, + ], + invalid: [ + { + code: "'foo'.isWellFormed()", + errors: [ + "ES2024 'String.prototype.isWellFormed' method is forbidden.", + ], + }, + { + code: "'foo'.isWellFormed()", + errors: [ + "ES2024 'String.prototype.isWellFormed' method is forbidden.", + ], + settings: { "es-x": { aggressive: true } }, + }, + { + code: "'foo'.isWellFormed()", + options: [{ aggressive: true }], + errors: [ + "ES2024 'String.prototype.isWellFormed' method is forbidden.", + ], + settings: { "es-x": { aggressive: true } }, + }, + ], +}) + +// ----------------------------------------------------------------------------- +// TypeScript +// ----------------------------------------------------------------------------- +const parser = require("@typescript-eslint/parser") +const tsconfigRootDir = path.resolve(__dirname, "../../fixtures") +const project = "tsconfig.json" +const filename = path.join(tsconfigRootDir, "test.ts") + +new RuleTester({ languageOptions: { parser } }).run(ruleId, rule, { + valid: [ + { filename, code: "isWellFormed()" }, + { filename, code: "foo.isWellFormed()" }, + { + filename, + code: "isWellFormed()", + settings: { "es-x": { aggressive: true } }, + }, + { + filename, + code: "foo.isWellFormed()", + options: [{ aggressive: false }], + settings: { "es-x": { aggressive: true } }, + }, + ], + invalid: [ + { + filename, + code: "'foo'.isWellFormed()", + errors: [ + "ES2024 'String.prototype.isWellFormed' method is forbidden.", + ], + }, + { + filename, + code: "'foo'.isWellFormed()", + errors: [ + "ES2024 'String.prototype.isWellFormed' method is forbidden.", + ], + settings: { "es-x": { aggressive: true } }, + }, + { + filename, + code: "'foo'.isWellFormed()", + options: [{ aggressive: true }], + errors: [ + "ES2024 'String.prototype.isWellFormed' method is forbidden.", + ], + settings: { "es-x": { aggressive: true } }, + }, + ], +}) + +new RuleTester({ + languageOptions: { parser, parserOptions: { tsconfigRootDir, project } }, +}).run(`${ruleId} TS Full Type Information`, rule, { + valid: [ + { filename, code: "isWellFormed()" }, + { filename, code: "foo.isWellFormed()" }, + { + filename, + code: "isWellFormed()", + settings: { "es-x": { aggressive: true } }, + }, + { + filename, + code: "foo.isWellFormed()", + options: [{ aggressive: false }], + settings: { "es-x": { aggressive: true } }, + }, + ], + invalid: [ + { + filename, + code: "'foo'.isWellFormed()", + errors: [ + "ES2024 'String.prototype.isWellFormed' method is forbidden.", + ], + }, + { + filename, + code: "'foo'.isWellFormed()", + errors: [ + "ES2024 'String.prototype.isWellFormed' method is forbidden.", + ], + settings: { "es-x": { aggressive: true } }, + }, + { + filename, + code: "'foo'.isWellFormed()", + options: [{ aggressive: true }], + errors: [ + "ES2024 'String.prototype.isWellFormed' method is forbidden.", + ], + settings: { "es-x": { aggressive: true } }, + }, + ], +}) diff --git a/tests/lib/rules/no-string-prototype-towelformed.js b/tests/lib/rules/no-string-prototype-towelformed.js new file mode 100644 index 00000000..b2f24fd3 --- /dev/null +++ b/tests/lib/rules/no-string-prototype-towelformed.js @@ -0,0 +1,140 @@ +"use strict" + +const path = require("path") +const RuleTester = require("../../tester") +const rule = require("../../../lib/rules/no-string-prototype-towellformed.js") +const ruleId = "no-string-prototype-towellformed" + +new RuleTester().run(ruleId, rule, { + valid: [ + "toWellFormed()", + "foo.toWellFormed()", + { code: "toWellFormed()", settings: { "es-x": { aggressive: true } } }, + { + code: "foo.toWellFormed()", + options: [{ aggressive: false }], + settings: { "es-x": { aggressive: true } }, + }, + ], + invalid: [ + { + code: "'foo'.toWellFormed()", + errors: [ + "ES2024 'String.prototype.toWellFormed' method is forbidden.", + ], + }, + { + code: "'foo'.toWellFormed()", + errors: [ + "ES2024 'String.prototype.toWellFormed' method is forbidden.", + ], + settings: { "es-x": { aggressive: true } }, + }, + { + code: "'foo'.toWellFormed()", + options: [{ aggressive: true }], + errors: [ + "ES2024 'String.prototype.toWellFormed' method is forbidden.", + ], + settings: { "es-x": { aggressive: true } }, + }, + ], +}) + +// ----------------------------------------------------------------------------- +// TypeScript +// ----------------------------------------------------------------------------- +const parser = require("@typescript-eslint/parser") +const tsconfigRootDir = path.resolve(__dirname, "../../fixtures") +const project = "tsconfig.json" +const filename = path.join(tsconfigRootDir, "test.ts") + +new RuleTester({ languageOptions: { parser } }).run(ruleId, rule, { + valid: [ + { filename, code: "toWellFormed()" }, + { filename, code: "foo.toWellFormed()" }, + { + filename, + code: "toWellFormed()", + settings: { "es-x": { aggressive: true } }, + }, + { + filename, + code: "foo.toWellFormed()", + options: [{ aggressive: false }], + settings: { "es-x": { aggressive: true } }, + }, + ], + invalid: [ + { + filename, + code: "'foo'.toWellFormed()", + errors: [ + "ES2024 'String.prototype.toWellFormed' method is forbidden.", + ], + }, + { + filename, + code: "'foo'.toWellFormed()", + errors: [ + "ES2024 'String.prototype.toWellFormed' method is forbidden.", + ], + settings: { "es-x": { aggressive: true } }, + }, + { + filename, + code: "'foo'.toWellFormed()", + options: [{ aggressive: true }], + errors: [ + "ES2024 'String.prototype.toWellFormed' method is forbidden.", + ], + settings: { "es-x": { aggressive: true } }, + }, + ], +}) + +new RuleTester({ + languageOptions: { parser, parserOptions: { tsconfigRootDir, project } }, +}).run(`${ruleId} TS Full Type Information`, rule, { + valid: [ + { filename, code: "toWellFormed()" }, + { filename, code: "foo.toWellFormed()" }, + { + filename, + code: "toWellFormed()", + settings: { "es-x": { aggressive: true } }, + }, + { + filename, + code: "foo.toWellFormed()", + options: [{ aggressive: false }], + settings: { "es-x": { aggressive: true } }, + }, + ], + invalid: [ + { + filename, + code: "'foo'.toWellFormed()", + errors: [ + "ES2024 'String.prototype.toWellFormed' method is forbidden.", + ], + }, + { + filename, + code: "'foo'.toWellFormed()", + errors: [ + "ES2024 'String.prototype.toWellFormed' method is forbidden.", + ], + settings: { "es-x": { aggressive: true } }, + }, + { + filename, + code: "'foo'.toWellFormed()", + options: [{ aggressive: true }], + errors: [ + "ES2024 'String.prototype.toWellFormed' method is forbidden.", + ], + settings: { "es-x": { aggressive: true } }, + }, + ], +})