diff --git a/docs/.vuepress/components/eslint-playground.vue b/docs/.vuepress/components/eslint-playground.vue
index 52f47685..fa7a60cd 100644
--- a/docs/.vuepress/components/eslint-playground.vue
+++ b/docs/.vuepress/components/eslint-playground.vue
@@ -67,7 +67,7 @@ export default {
},
rules: {},
parserOptions: {
- ecmaVersion: 2020,
+ ecmaVersion: 2021,
sourceType: "module",
},
},
diff --git a/docs/rules/README.md b/docs/rules/README.md
index 16601a6c..c9e72310 100644
--- a/docs/rules/README.md
+++ b/docs/rules/README.md
@@ -6,11 +6,11 @@ This plugin provides the following rules.
## ES2021
-There is no config which enables the rules in this category.
+There is no config which enables all rules in this category.
| Rule ID | Description | |
|:--------|:------------|:--:|
-
+| [es/no-numeric-separators](./no-numeric-separators.md) | disallow numeric separators. | |
## ES2020
diff --git a/docs/rules/no-numeric-separators.md b/docs/rules/no-numeric-separators.md
new file mode 100644
index 00000000..cbad893f
--- /dev/null
+++ b/docs/rules/no-numeric-separators.md
@@ -0,0 +1,18 @@
+# disallow numeric separators (es/no-numeric-separators)
+
+- 🔧 The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
+
+This rule reports ES2021 [numeric separators](https://github.com/tc39/proposal-numeric-separator) as errors.
+
+## Examples
+
+â›” Examples of **incorrect** code for this rule:
+
+
+
+## 📚 References
+
+- [Rule source](https://github.com/mysticatea/eslint-plugin-es/blob/v3.0.1/lib/rules/no-numeric-separators.js)
+- [Test source](https://github.com/mysticatea/eslint-plugin-es/blob/v3.0.1/tests/lib/rules/no-numeric-separators.js)
diff --git a/lib/index.js b/lib/index.js
index b11d6bbc..19d420a4 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -106,6 +106,7 @@ module.exports = {
"no-number-minsafeinteger": require("./rules/no-number-minsafeinteger"),
"no-number-parsefloat": require("./rules/no-number-parsefloat"),
"no-number-parseint": require("./rules/no-number-parseint"),
+ "no-numeric-separators": require("./rules/no-numeric-separators"),
"no-object-assign": require("./rules/no-object-assign"),
"no-object-defineproperties": require("./rules/no-object-defineproperties"),
"no-object-defineproperty": require("./rules/no-object-defineproperty"),
diff --git a/lib/rules/no-numeric-separators.js b/lib/rules/no-numeric-separators.js
new file mode 100644
index 00000000..bfc94081
--- /dev/null
+++ b/lib/rules/no-numeric-separators.js
@@ -0,0 +1,52 @@
+/**
+ * @author Yosuke Ota
+ * See LICENSE file in root directory for full license.
+ */
+"use strict"
+
+/**
+ * Remove the numeric separators.
+ * @param {string} raw The raw string of numeric literals
+ * @returns {string} The string with the separators removed.
+ */
+function removeNumericSeparators(raw) {
+ return raw.replace(/_/gu, "")
+}
+
+module.exports = {
+ meta: {
+ docs: {
+ description: "disallow numeric separators.",
+ category: "ES2021",
+ recommended: false,
+ url:
+ "http://mysticatea.github.io/eslint-plugin-es/rules/no-numeric-separators.html",
+ },
+ fixable: "code",
+ messages: {
+ forbidden: "ES2021 numeric separators are forbidden.",
+ },
+ schema: [],
+ type: "problem",
+ },
+ create(context) {
+ return {
+ Literal(node) {
+ if (
+ (typeof node.value === "number" || node.bigint != null) &&
+ node.raw.includes("_")
+ ) {
+ context.report({
+ node,
+ messageId: "forbidden",
+ fix: fixer =>
+ fixer.replaceText(
+ node,
+ removeNumericSeparators(node.raw)
+ ),
+ })
+ }
+ },
+ }
+ },
+}
diff --git a/package.json b/package.json
index cc744b88..59d84fcb 100644
--- a/package.json
+++ b/package.json
@@ -17,13 +17,13 @@
"regexpp": "^3.0.0"
},
"devDependencies": {
- "@mysticatea/eslint-plugin": "^11.0.0",
+ "@mysticatea/eslint-plugin": "^13.0.0",
"@vuepress/plugin-pwa": "^1.2.0",
"acorn": "^7.1.0",
"babel-eslint": "^10.0.1",
- "codecov": "^3.5.0",
- "eslint": "^6.2.2",
- "eslint4b": "^6.2.2",
+ "codecov": "3.7.0",
+ "eslint": "^7.10.0",
+ "eslint4b": "^7.10.0",
"espree": "^7.0.0",
"globals": "^12.0.0",
"mocha": "^6.2.0",
diff --git a/tests/lib/rules/no-numeric-separators.js b/tests/lib/rules/no-numeric-separators.js
new file mode 100644
index 00000000..901406cb
--- /dev/null
+++ b/tests/lib/rules/no-numeric-separators.js
@@ -0,0 +1,72 @@
+/**
+ * @author Toru Nagashima
+ * See LICENSE file in root directory for full license.
+ */
+"use strict"
+
+const RuleTester = require("../../tester")
+const rule = require("../../../lib/rules/no-numeric-separators.js")
+
+if (!RuleTester.isSupported(2021)) {
+ //eslint-disable-next-line no-console
+ console.log("Skip the tests of no-numeric-separators.")
+ return
+}
+
+new RuleTester().run("no-numeric-separators", rule, {
+ valid: [
+ "123456",
+ "-123",
+ "123.456",
+ "123.0",
+ "NaN",
+ "123e-1",
+ "0x11",
+ "0b11",
+ "0o11",
+ "Infinity",
+ "123456n",
+ ],
+ invalid: [
+ {
+ code: "123_456",
+ output: "123456",
+ errors: ["ES2021 numeric separators are forbidden."],
+ },
+ {
+ code: "5_000",
+ output: "5000",
+ errors: ["ES2021 numeric separators are forbidden."],
+ },
+ {
+ code: "1_234_56",
+ output: "123456",
+ errors: ["ES2021 numeric separators are forbidden."],
+ },
+ {
+ code: "5.00_00",
+ output: "5.0000",
+ errors: ["ES2021 numeric separators are forbidden."],
+ },
+ {
+ code: "0b11_01",
+ output: "0b1101",
+ errors: ["ES2021 numeric separators are forbidden."],
+ },
+ {
+ code: "5e1_000",
+ output: "5e1000",
+ errors: ["ES2021 numeric separators are forbidden."],
+ },
+ {
+ code: "0xBE_EF",
+ output: "0xBEEF",
+ errors: ["ES2021 numeric separators are forbidden."],
+ },
+ {
+ code: "123_456n",
+ output: "123456n",
+ errors: ["ES2021 numeric separators are forbidden."],
+ },
+ ],
+})
diff --git a/tests/tester.js b/tests/tester.js
index edb2ab00..b054a1f7 100644
--- a/tests/tester.js
+++ b/tests/tester.js
@@ -11,6 +11,7 @@ const semver = require("semver")
const eslintVersion = new Linter().version
const ecmaVersion =
/*eslint-disable @mysticatea/prettier */
+ semver.gte(eslintVersion, "7.8.0") ? 2021 :
semver.gte(eslintVersion, "6.2.0") ? 2020 :
semver.gte(eslintVersion, "5.0.0") ? 2019 :
2018