Repository: eslint-community/eslint-plugin-es-x
Pull request #49 (2023-01-20 09:32:17)

Add rules for ES2022 Intl API
related to #45
~~PR #50 must be merged before this PR.~~ Done


Patch:
diff --git a/docs/rules/index.md b/docs/rules/index.md
index 478bb64..88b62fa 100644
--- a/docs/rules/index.md
+++ b/docs/rules/index.md
@@ -30,6 +30,15 @@ There are multiple configs that enable all rules in this category: `plugin:es-x/
 | [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-top-level-await](./no-top-level-await.md) | disallow top-level `await`. |  |
 
+## ES2022 Intl API
+
+There are multiple configs that enable all rules in this category: `plugin:es-x/no-new-in-es2022-intl-api`, `plugin:es-x/restrict-to-es-intl-api-1st-edition`, `plugin:es-x/restrict-to-es2015-intl-api`, `plugin:es-x/restrict-to-es2016-intl-api`, `plugin:es-x/restrict-to-es2017-intl-api`, `plugin:es-x/restrict-to-es2018-intl-api`, `plugin:es-x/restrict-to-es2019-intl-api`, `plugin:es-x/restrict-to-es2020-intl-api`, and `plugin:es-x/restrict-to-es2021-intl-api`
+
+| Rule ID | Description |    |
+|:--------|:------------|:--:|
+| [es-x/no-intl-segmenter](./no-intl-segmenter.md) | disallow the `Intl.Segmenter` object. |  |
+| [es-x/no-intl-supportedvaluesof](./no-intl-supportedvaluesof.md) | disallow the `Intl.supportedValuesOf` method. |  |
+
 ## ES2021
 
 There are multiple configs that enable all rules in this category: `plugin:es-x/no-new-in-es2021`, `plugin:es-x/restrict-to-es3`, `plugin:es-x/restrict-to-es5`, `plugin:es-x/restrict-to-es2015`, `plugin:es-x/restrict-to-es2016`, `plugin:es-x/restrict-to-es2017`, `plugin:es-x/restrict-to-es2018`, `plugin:es-x/restrict-to-es2019`, and `plugin:es-x/restrict-to-es2020`
diff --git a/docs/rules/no-intl-segmenter.md b/docs/rules/no-intl-segmenter.md
new file mode 100644
index 0000000..f6d0d4f
--- /dev/null
+++ b/docs/rules/no-intl-segmenter.md
@@ -0,0 +1,30 @@
+---
+title: "es-x/no-intl-segmenter"
+description: "disallow the `Intl.Segmenter` object"
+---
+
+# es-x/no-intl-segmenter
+> disallow the `Intl.Segmenter` object
+
+- ❗ <badge text="This rule has not been released yet." vertical="middle" type="error"> ***This rule has not been released yet.*** </badge>
+- ✅ The following configurations enable this rule: `plugin:es-x/no-new-in-es2022-intl-api`, `plugin:es-x/restrict-to-es-intl-api-1st-edition`, `plugin:es-x/restrict-to-es2015-intl-api`, `plugin:es-x/restrict-to-es2016-intl-api`, `plugin:es-x/restrict-to-es2017-intl-api`, `plugin:es-x/restrict-to-es2018-intl-api`, `plugin:es-x/restrict-to-es2019-intl-api`, `plugin:es-x/restrict-to-es2020-intl-api`, and `plugin:es-x/restrict-to-es2021-intl-api`
+
+This rule reports ES2022 Intl API `Intl.Segmenter` object as errors.
+
+## 💡 Examples
+
+⛔ Examples of **incorrect** code for this rule:
+
+<eslint-playground type="bad">
+
+```js
+/*eslint es-x/no-intl-segmenter: error */
+const segmenter = new Intl.Segmenter('fr', { granularity: 'word' });
+```
+
+</eslint-playground>
+
+## 📚 References
+
+- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-intl-segmenter.js)
+- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-intl-segmenter.js)
diff --git a/docs/rules/no-intl-supportedvaluesof.md b/docs/rules/no-intl-supportedvaluesof.md
new file mode 100644
index 0000000..08a0f74
--- /dev/null
+++ b/docs/rules/no-intl-supportedvaluesof.md
@@ -0,0 +1,30 @@
+---
+title: "es-x/no-intl-supportedvaluesof"
+description: "disallow the `Intl.supportedValuesOf` method"
+---
+
+# es-x/no-intl-supportedvaluesof
+> disallow the `Intl.supportedValuesOf` method
+
+- ❗ <badge text="This rule has not been released yet." vertical="middle" type="error"> ***This rule has not been released yet.*** </badge>
+- ✅ The following configurations enable this rule: `plugin:es-x/no-new-in-es2022-intl-api`, `plugin:es-x/restrict-to-es-intl-api-1st-edition`, `plugin:es-x/restrict-to-es2015-intl-api`, `plugin:es-x/restrict-to-es2016-intl-api`, `plugin:es-x/restrict-to-es2017-intl-api`, `plugin:es-x/restrict-to-es2018-intl-api`, `plugin:es-x/restrict-to-es2019-intl-api`, `plugin:es-x/restrict-to-es2020-intl-api`, and `plugin:es-x/restrict-to-es2021-intl-api`
+
+This rule reports  ES2022 Intl API `Intl.supportedValuesOf` method as errors.
+
+## 💡 Examples
+
+⛔ Examples of **incorrect** code for this rule:
+
+<eslint-playground type="bad">
+
+```js
+/*eslint es-x/no-intl-supportedvaluesof: error */
+const collation = Intl.supportedValuesOf("collation")
+```
+
+</eslint-playground>
+
+## 📚 References
+
+- [Rule source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/lib/rules/no-intl-supportedvaluesof.js)
+- [Test source](https://github.com/eslint-community/eslint-plugin-es-x/blob/master/tests/lib/rules/no-intl-supportedvaluesof.js)
diff --git a/lib/configs/no-new-in-es2022-intl-api.js b/lib/configs/no-new-in-es2022-intl-api.js
index f42c599..ffe1c9e 100644
--- a/lib/configs/no-new-in-es2022-intl-api.js
+++ b/lib/configs/no-new-in-es2022-intl-api.js
@@ -4,4 +4,10 @@
  */
 "use strict"
 
-module.exports = { plugins: ["es-x"], rules: {} }
+module.exports = {
+    plugins: ["es-x"],
+    rules: {
+        "es-x/no-intl-segmenter": "error",
+        "es-x/no-intl-supportedvaluesof": "error",
+    },
+}
diff --git a/lib/index.js b/lib/index.js
index c6855e6..8667538 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -125,6 +125,8 @@ module.exports = {
         "no-hashbang": require("./rules/no-hashbang"),
         "no-import-meta": require("./rules/no-import-meta"),
         "no-initializers-in-for-in": require("./rules/no-initializers-in-for-in"),
+        "no-intl-segmenter": require("./rules/no-intl-segmenter"),
+        "no-intl-supportedvaluesof": require("./rules/no-intl-supportedvaluesof"),
         "no-json": require("./rules/no-json"),
         "no-json-superset": require("./rules/no-json-superset"),
         "no-keyword-properties": require("./rules/no-keyword-properties"),
diff --git a/lib/rules/no-intl-segmenter.js b/lib/rules/no-intl-segmenter.js
new file mode 100644
index 0000000..31ca3a2
--- /dev/null
+++ b/lib/rules/no-intl-segmenter.js
@@ -0,0 +1,38 @@
+"use strict"
+
+const { READ, ReferenceTracker } = require("@eslint-community/eslint-utils")
+
+module.exports = {
+    meta: {
+        docs: {
+            description: "disallow the `Intl.Segmenter` object.",
+            category: "ES2022-Intl-API",
+            recommended: false,
+            url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-intl-segmenter.html",
+        },
+        fixable: null,
+        messages: {
+            forbidden: "ES2022 Intl API '{{name}}' object is forbidden.",
+        },
+        schema: [],
+        type: "problem",
+    },
+    create(context) {
+        return {
+            "Program:exit"() {
+                const tracker = new ReferenceTracker(context.getScope())
+                for (const { node, path } of tracker.iterateGlobalReferences({
+                    Intl: {
+                        Segmenter: { [READ]: true },
+                    },
+                })) {
+                    context.report({
+                        node,
+                        messageId: "forbidden",
+                        data: { name: path.join(".") },
+                    })
+                }
+            },
+        }
+    },
+}
diff --git a/lib/rules/no-intl-supportedvaluesof.js b/lib/rules/no-intl-supportedvaluesof.js
new file mode 100644
index 0000000..2dc3432
--- /dev/null
+++ b/lib/rules/no-intl-supportedvaluesof.js
@@ -0,0 +1,38 @@
+"use strict"
+
+const { READ, ReferenceTracker } = require("@eslint-community/eslint-utils")
+
+module.exports = {
+    meta: {
+        docs: {
+            description: "disallow the `Intl.supportedValuesOf` method.",
+            category: "ES2022-Intl-API",
+            recommended: false,
+            url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-intl-supportedvaluesof.html",
+        },
+        fixable: null,
+        messages: {
+            forbidden: "ES2022 Intl API '{{name}}' method is forbidden.",
+        },
+        schema: [],
+        type: "problem",
+    },
+    create(context) {
+        return {
+            "Program:exit"() {
+                const tracker = new ReferenceTracker(context.getScope())
+                for (const { node, path } of tracker.iterateGlobalReferences({
+                    Intl: {
+                        supportedValuesOf: { [READ]: true },
+                    },
+                })) {
+                    context.report({
+                        node,
+                        messageId: "forbidden",
+                        data: { name: path.join(".") },
+                    })
+                }
+            },
+        }
+    },
+}


Test patch:
diff --git a/tests/lib/rules/no-intl-segmenter.js b/tests/lib/rules/no-intl-segmenter.js
new file mode 100644
index 0000000..76db94d
--- /dev/null
+++ b/tests/lib/rules/no-intl-segmenter.js
@@ -0,0 +1,19 @@
+"use strict"
+
+const RuleTester = require("../../tester")
+const rule = require("../../../lib/rules/no-intl-segmenter.js")
+
+new RuleTester().run("no-intl-segmenter", rule, {
+    valid: [
+        "Intl",
+        "Intl.DateTimeFormat",
+        "Intl.NumberFormat",
+        "let Intl = 0; Intl.Segmenter",
+    ],
+    invalid: [
+        {
+            code: "Intl.Segmenter",
+            errors: ["ES2022 Intl API 'Intl.Segmenter' object is forbidden."],
+        },
+    ],
+})
diff --git a/tests/lib/rules/no-intl-supportedvaluesof.js b/tests/lib/rules/no-intl-supportedvaluesof.js
new file mode 100644
index 0000000..ff91cbc
--- /dev/null
+++ b/tests/lib/rules/no-intl-supportedvaluesof.js
@@ -0,0 +1,21 @@
+"use strict"
+
+const RuleTester = require("../../tester")
+const rule = require("../../../lib/rules/no-intl-supportedvaluesof.js")
+
+new RuleTester().run("no-intl-supportedvaluesof", rule, {
+    valid: [
+        "Intl",
+        "Intl.DateTimeFormat",
+        "Intl.NumberFormat",
+        "let Intl = 0; Intl.supportedValuesOf",
+    ],
+    invalid: [
+        {
+            code: "Intl.supportedValuesOf",
+            errors: [
+                "ES2022 Intl API 'Intl.supportedValuesOf' method is forbidden.",
+            ],
+        },
+    ],
+})