diff --git a/.nycrc b/.nycrc
index b9d7b70b..27772eac 100644
--- a/.nycrc
+++ b/.nycrc
@@ -4,7 +4,6 @@
],
"exclude": [
"lib/rules/no-hide-core-modules.js",
- "lib/rules/no-unsupported-features.js",
"lib/converted-esm/*.js"
],
"reporter": [
diff --git a/README.md b/README.md
index 021ce524..60b4b531 100644
--- a/README.md
+++ b/README.md
@@ -133,7 +133,6 @@ For [Shareable Configs](https://eslint.org/docs/latest/developer-guide/shareable
| [no-unpublished-bin](docs/rules/no-unpublished-bin.md) | disallow `bin` files that npm ignores | ☑️ 🟢 ✅ ☑️ 🟢 ✅ | | |
| [no-unpublished-import](docs/rules/no-unpublished-import.md) | disallow `import` declarations which import private modules | ☑️ 🟢 ✅ ☑️ 🟢 ✅ | | |
| [no-unpublished-require](docs/rules/no-unpublished-require.md) | disallow `require()` expressions which import private modules | ☑️ 🟢 ✅ ☑️ 🟢 ✅ | | |
-| [no-unsupported-features](docs/rules/no-unsupported-features.md) | disallow unsupported ECMAScript features on the specified version | | | ❌ |
| [no-unsupported-features/es-builtins](docs/rules/no-unsupported-features/es-builtins.md) | disallow unsupported ECMAScript built-ins on the specified version | ☑️ 🟢 ✅ ☑️ 🟢 ✅ | | |
| [no-unsupported-features/es-syntax](docs/rules/no-unsupported-features/es-syntax.md) | disallow unsupported ECMAScript syntax on the specified version | ☑️ 🟢 ✅ ☑️ 🟢 ✅ | | |
| [no-unsupported-features/node-builtins](docs/rules/no-unsupported-features/node-builtins.md) | disallow unsupported Node.js built-in APIs on the specified version | ☑️ 🟢 ✅ ☑️ 🟢 ✅ | | |
diff --git a/docs/rules/no-unsupported-features.md b/docs/rules/no-unsupported-features.md
deleted file mode 100644
index 69a62a27..00000000
--- a/docs/rules/no-unsupported-features.md
+++ /dev/null
@@ -1,308 +0,0 @@
-# Disallow unsupported ECMAScript features on the specified version (`n/no-unsupported-features`)
-
-❌ This rule is deprecated. It was replaced by [`n/no-unsupported-features/es-syntax`](no-unsupported-features/es-syntax.md),[`n/no-unsupported-features/es-builtins`](no-unsupported-features/es-builtins.md).
-
-
-
-Node.js doesn't support all ECMAScript standard features.
-This rule reports when you used unsupported ECMAScript 2015-2018 features on the specified Node.js version.
-
-> ※ About ECMAScript 2018, this rule reports only features which have arrived at stage 4 until 2018-02-01.
-> It needs a major version bump in order to cover newer features.
-
-## 📖 Rule Details
-
-⚠️ This rule expects to be used with the following configuration:
-
-```json
-{
- "env": {"es6": true},
- "parserOptions": {"ecmaVersion": 2018}
-}
-```
-
-⚠️ This rule reads the [engines] field of `package.json` to detect Node.js version.
-
-I recommend a use of the [engines] field since it's the official way to indicate what Node.js versions your module is supporting.
-For example of `package.json`:
-
-```json
-{
- "name": "your-module",
- "version": "1.0.0",
- "engines": {
- "node": ">=6.0.0"
- }
-}
-```
-
-If the [engines] field is omitted, this rule chooses `4` since it's the minimum version the community is maintaining.
-
-Examples of 👎 **incorrect** code for this rule:
-
-```js
-/*eslint n/no-unsupported-features: ["error", {version: 4}]*/
-/*eslint-env es6*/
-
-function foo(a = 1) { /*error Default Parameters are not supported yet on Node v4.*/
- //...
-}
-
-function foo(...a) { /*error Rest Parameters are not supported yet on Node v4.*/
- //...
-}
-
-var a = [...b]; /*error Spread Operators are not supported yet on Node v4.*/
-var a = /foo/y; /*error RegExp 'y' Flags are not supported yet on Node v4.*/
-var a = /foo/u; /*error RegExp 'u' Flags are not supported yet on Node v4.*/
-var {a, b} = c; /*error Destructuring are not supported yet on Node v4.*/
-var {a, b} = c; /*error Destructuring are not supported yet on Node v4.*/
-
-let a = 1; /*error 'let' Declarations in non-strict mode are not supported yet on Node v4.*/
-const a = 1; /*error 'const' Declarations in non-strict mode are not supported yet on Node v4.*/
-class A {} /*error Classes in non-strict mode are not supported yet on Node v4.*/
-
-if (a) {
- function foo() { /*error Block-Scoped Functions in non-strict mode are not supported yet on Node v4.*/
- //...
- }
-}
-
-var p = new Proxy(o, { /*error Proxy is not supported yet on Node v4.*/
- //...
-});
-```
-
-Examples of 👍 **correct** code for this rule:
-
-```js
-/*eslint n/no-unsupported-features: ["error", {version: 4}]*/
-/*eslint-env es6*/
-
-for (var a of list) {
- //...
-}
-
-var a = `hello, ${world}!`;
-
-function foo() {
- "use strict";
-
- let a = 1;
- const b = 2;
-
- class A {
- //...
- }
-
- if (c) {
- function bar() {
- //...
- }
- }
-}
-
-var p = new Promise((resolve, reject) => {
- //...
-});
-```
-
-### Options
-
-```json
-{
- "n/no-unsupported-features": ["error", {
- "version": 4,
- "ignores": []
- }]
-}
-```
-
-#### version
-
-As mentioned above, this rule reads the [engines] field of `package.json` to detect Node.js version.
-Also, you can overwrite the version by `version` option.
-The `version` option accepts the following version number:
-
-- `0.10`
-- `0.12`
-- `4`
-- `5`
-- `6`
-- `6.5` ... `Symbol.hasInstance` and `Symbol.species`.
-- `7` ... Exponential operators, `Object.values`, `Object.entries`, and `Object.getOwnPropertyDescriptors`.
-- `7.6` ... Async functions.
-- `8` ... Trailing commas in functions.
-- `8.3` ... Rest/Spread proeprties.
-- `9.0` ... Illegal escape sequences in taggled templates, RegExp 's' flags, RegExp lookbehind assertions, `SharedArrayBuffer`, and `Atomics`.
-- `10.0` ... RegExp named capture groups, RegExp Unicode property escapes, Async generators, and `for-await-of` loops.
-
-#### ignores
-
-If you are using transpilers, maybe you want to ignore the warnings about some features.
-You can use this `ignores` option to ignore the given features.
-The `"ignores"` option accepts an array of the following strings.
-
-- `"syntax"` (group)
- - `"defaultParameters"`
- - `"restParameters"`
- - `"spreadOperators"`
- - `"objectLiteralExtensions"`
- - `"forOf"`
- - `"binaryNumberLiterals"`
- - `"octalNumberLiterals"`
- - `"templateStrings"`
- - `"regexpY"`
- - `"regexpU"`
- - `"destructuring"`
- - `"unicodeCodePointEscapes"`
- - `"new.target"`
- - `"const"`
- - `"let"`
- - `"blockScopedFunctions"`
- - `"arrowFunctions"`
- - `"generatorFunctions"`
- - `"classes"`
- - `"modules"`
- - `"exponentialOperators"`
- - `"asyncAwait"`
- - `"trailingCommasInFunctions"`
- - `"templateLiteralRevision"`
- - `"regexpS"`
- - `"regexpNamedCaptureGroups"`
- - `"regexpLookbehind"`
- - `"regexpUnicodeProperties"`
- - `"restProperties"`
- - `"spreadProperties"`
- - `"asyncGenerators"`
- - `"forAwaitOf"`
-- `"runtime"` (group)
- - `"globalObjects"` (group)
- - `"typedArrays"` (group)
- - `"Int8Array"`
- - `"Uint8Array"`
- - `"Uint8ClampedArray"`
- - `"Int16Array"`
- - `"Uint16Array"`
- - `"Int32Array"`
- - `"Uint32Array"`
- - `"Float32Array"`
- - `"Float64Array"`
- - `"DataView"`
- - `"Map"`
- - `"Set"`
- - `"WeakMap"`
- - `"WeakSet"`
- - `"Proxy"`
- - `"Reflect"`
- - `"Promise"`
- - `"Symbol"`
- - `"SharedArrayBuffer"`
- - `"Atomics"`
- - `"staticMethods"` (group)
- - `"Object.*"` (group)
- - `"Object.assign"`
- - `"Object.is"`
- - `"Object.getOwnPropertySymbols"`
- - `"Object.setPrototypeOf"`
- - `"Object.values"`
- - `"Object.entries"`
- - `"Object.getOwnPropertyDescriptors"`
- - `"String.*"` (group)
- - `"String.raw"`
- - `"String.fromCodePoint"`
- - `"Array.*"` (group)
- - `"Array.from"`
- - `"Array.of"`
- - `"Number.*"` (group)
- - `"Number.isFinite"`
- - `"Number.isInteger"`
- - `"Number.isSafeInteger"`
- - `"Number.isNaN"`
- - `"Number.EPSILON"`
- - `"Number.MIN_SAFE_INTEGER"`
- - `"Number.MAX_SAFE_INTEGER"`
- - `"Math.*"` (group)
- - `"Math.clz32"`
- - `"Math.imul"`
- - `"Math.sign"`
- - `"Math.log10"`
- - `"Math.log2"`
- - `"Math.log1p"`
- - `"Math.expm1"`
- - `"Math.cosh"`
- - `"Math.sinh"`
- - `"Math.tanh"`
- - `"Math.acosh"`
- - `"Math.asinh"`
- - `"Math.atanh"`
- - `"Math.trunc"`
- - `"Math.fround"`
- - `"Math.cbrt"`
- - `"Math.hypot"`
- - `"Symbol.*"` (group)
- - `"Symbol.hasInstance"`
- - `"Symbol.isConcatSpreadablec"`
- - `"Symbol.iterator"`
- - `"Symbol.species"`
- - `"Symbol.replace"`
- - `"Symbol.search"`
- - `"Symbol.split"`
- - `"Symbol.match"`
- - `"Symbol.toPrimitive"`
- - `"Symbol.toStringTag"`
- - `"Symbol.unscopables"`
- - `"Atomics.*"` (group)
- - `"Atomics.add"`
- - `"Atomics.and"`
- - `"Atomics.compareExchange"`
- - `"Atomics.exchange"`
- - `"Atomics.wait"`
- - `"Atomics.wake"`
- - `"Atomics.isLockFree"`
- - `"Atomics.load"`
- - `"Atomics.or"`
- - `"Atomics.store"`
- - `"Atomics.sub"`
- - `"Atomics.xor"`
- - `"extends"` (group)
- - `"extendsArray"`
- - `"extendsRegExp"`
- - `"extendsFunction"`
- - `"extendsPromise"`
- - `"extendsBoolean"`
- - `"extendsNumber"`
- - `"extendsString"`
- - `"extendsMap"`
- - `"extendsSet"`
- - `"extendsNull"`
-
-If a group value is given, all sub items of the value are ignored.
-e.g. if `"String.*"` is given then `"String.raw"` and `"String.fromCodePoint"` are ignored.
-
-Examples of 👍 **correct** code for the `"ignores"` option:
-
-```js
-/*eslint n/no-unsupported-features: ["error", {version: 4, ignores: ["defaultParameters"]}]*/
-/*eslint-env es6*/
-
-function foo(a = 1) {
- //...
-}
-```
-
-## ⚠️ Known Limitations
-
-This rule cannot report non-static things.
-E.g., a use of instance methods.
-
-## 📚 Further Reading
-
--
-
-[engines]: https://docs.npmjs.com/files/package.json#engines
-
-## 🔎 Implementation
-
-- [Rule source](../../lib/rules/no-unsupported-features.js)
-- [Test source](../../tests/lib/rules/no-unsupported-features.js)
diff --git a/lib/index.js b/lib/index.js
index def1bbf6..23cd1937 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -46,7 +46,6 @@ const rules = {
// Deprecated rules.
"no-hide-core-modules": require("./rules/no-hide-core-modules"),
- "no-unsupported-features": require("./rules/no-unsupported-features"),
}
const mod = {
diff --git a/lib/rules/no-unsupported-features.js b/lib/rules/no-unsupported-features.js
deleted file mode 100644
index 810945ef..00000000
--- a/lib/rules/no-unsupported-features.js
+++ /dev/null
@@ -1,1552 +0,0 @@
-/**
- * @author Toru Nagashima
- * See LICENSE file in root directory for full license.
- */
-"use strict"
-
-const semver = require("semver")
-const {
- getInnermostScope,
- getPropertyName,
-} = require("@eslint-community/eslint-utils")
-const getPackageJson = require("../util/get-package-json")
-
-const VERSION_MAP = new Map([
- [0.1, "0.10.0"],
- [0.12, "0.12.0"],
- [4, "4.0.0"],
- [5, "5.0.0"],
- [6, "6.0.0"],
- [6.5, "6.5.0"],
- [7, "7.0.0"],
- [7.6, "7.6.0"],
- [8, "8.0.0"],
- [8.3, "8.3.0"],
- [9, "9.0.0"],
- [10, "10.0.0"],
-])
-const VERSION_SCHEMA = {
- anyOf: [
- { enum: Array.from(VERSION_MAP.keys()) },
- {
- type: "string",
- pattern: "^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)$",
- },
- ],
-}
-const DEFAULT_VERSION = "4.0.0"
-const FUNC_TYPE = /^(?:Arrow)?Function(?:Declaration|Expression)$/u
-const CLASS_TYPE = /^Class(?:Declaration|Expression)$/u
-const DESTRUCTURING_PARENT_TYPE =
- /^(?:Function(?:Declaration|Expression)|ArrowFunctionExpression|AssignmentExpression|VariableDeclarator)$/u
-const TOPLEVEL_SCOPE_TYPE = /^(?:global|function|module)$/u
-const BINARY_NUMBER = /^0[bB]/u
-const OCTAL_NUMBER = /^0[oO]/u
-const UNICODE_ESC = /(\\+)u\{[0-9a-fA-F]+?\}/gu
-const GET_OR_SET = /^(?:g|s)et$/u
-const NEW_BUILTIN_TYPES = [
- "Int8Array",
- "Uint8Array",
- "Uint8ClampedArray",
- "Int16Array",
- "Uint16Array",
- "Int32Array",
- "Uint32Array",
- "Float32Array",
- "Float64Array",
- "DataView",
- "Map",
- "Set",
- "WeakMap",
- "WeakSet",
- "Proxy",
- "Reflect",
- "Promise",
- "Symbol",
- "SharedArrayBuffer",
- "Atomics",
-]
-const SUBCLASSING_TEST_TARGETS = [
- "Array",
- "RegExp",
- "Function",
- "Promise",
- "Boolean",
- "Number",
- "String",
- "Map",
- "Set",
-]
-const PROPERTY_TEST_TARGETS = {
- Object: [
- "assign",
- "is",
- "getOwnPropertySymbols",
- "setPrototypeOf",
- "values",
- "entries",
- "getOwnPropertyDescriptors",
- ],
- String: ["raw", "fromCodePoint"],
- Array: ["from", "of"],
- Number: [
- "isFinite",
- "isInteger",
- "isSafeInteger",
- "isNaN",
- "EPSILON",
- "MIN_SAFE_INTEGER",
- "MAX_SAFE_INTEGER",
- ],
- Math: [
- "clz32",
- "imul",
- "sign",
- "log10",
- "log2",
- "log1p",
- "expm1",
- "cosh",
- "sinh",
- "tanh",
- "acosh",
- "asinh",
- "atanh",
- "trunc",
- "fround",
- "cbrt",
- "hypot",
- ],
- Symbol: [
- "hasInstance",
- "isConcatSpreadablec",
- "iterator",
- "species",
- "replace",
- "search",
- "split",
- "match",
- "toPrimitive",
- "toStringTag",
- "unscopables",
- ],
- Atomics: [
- "add",
- "and",
- "compareExchange",
- "exchange",
- "wait",
- "wake",
- "isLockFree",
- "load",
- "or",
- "store",
- "sub",
- "xor",
- ],
-}
-const REGEXP_NAMED_GROUP = /(\\*)\(\?<[_$\w]/u
-const REGEXP_LOOKBEHIND = /(\\*)\(\?<[=!]/u
-const REGEXP_UNICODE_PROPERTY = /(\\*)\\[pP]\{.+?\}/u
-const FEATURES = {
- defaultParameters: {
- alias: ["syntax"],
- name: "Default parameters",
- node: "6.0.0",
- },
- restParameters: {
- alias: ["syntax"],
- name: "Rest parameters",
- node: "6.0.0",
- },
- spreadOperators: {
- alias: ["syntax"],
- name: "Spread operators",
- node: "5.0.0",
- },
- objectLiteralExtensions: {
- alias: ["syntax"],
- name: "Object literal extensions",
- node: "4.0.0",
- },
- objectPropertyShorthandOfGetSet: {
- alias: ["syntax", "objectLiteralExtensions"],
- name: "Property shorthand of 'get' and 'set'",
- node: "6.0.0",
- },
- forOf: {
- alias: ["syntax"],
- name: "'for..of' loops",
- node: "0.12.0",
- },
- binaryNumberLiterals: {
- alias: ["syntax"],
- name: "Binary number literals",
- node: "4.0.0",
- },
- octalNumberLiterals: {
- alias: ["syntax"],
- name: "Octal number literals",
- node: "4.0.0",
- },
- templateStrings: {
- alias: ["syntax"],
- name: "Template strings",
- node: "4.0.0",
- },
- regexpY: {
- alias: ["syntax"],
- name: "RegExp 'y' flags",
- node: "6.0.0",
- },
- regexpU: {
- alias: ["syntax"],
- name: "RegExp 'u' flags",
- node: "6.0.0",
- },
- destructuring: {
- alias: ["syntax"],
- name: "Destructuring",
- node: "6.0.0",
- },
- unicodeCodePointEscapes: {
- alias: ["syntax"],
- name: "Unicode code point escapes",
- node: "4.0.0",
- },
- "new.target": {
- alias: ["syntax"],
- name: "'new.target'",
- node: "5.0.0",
- },
- const: {
- alias: ["syntax"],
- name: "'const' declarations",
- node: {
- sloppy: "6.0.0",
- strict: "4.0.0",
- },
- },
- let: {
- alias: ["syntax"],
- name: "'let' declarations",
- node: {
- sloppy: "6.0.0",
- strict: "4.0.0",
- },
- },
- blockScopedFunctions: {
- alias: ["syntax"],
- name: "Block-scoped functions",
- node: {
- sloppy: "6.0.0",
- strict: "4.0.0",
- },
- },
- arrowFunctions: {
- alias: ["syntax"],
- name: "Arrow functions",
- node: "4.0.0",
- },
- generatorFunctions: {
- alias: ["syntax"],
- name: "Generator functions",
- node: "4.0.0",
- },
- classes: {
- alias: ["syntax"],
- name: "Classes",
- node: {
- sloppy: "6.0.0",
- strict: "4.0.0",
- },
- },
- modules: {
- alias: ["syntax"],
- name: "Import and export declarations",
- node: null,
- },
- exponentialOperators: {
- alias: ["syntax"],
- name: "Exponential operators (**)",
- node: "7.0.0",
- },
- asyncAwait: {
- alias: ["syntax"],
- name: "Async functions",
- node: "7.6.0",
- },
- trailingCommasInFunctions: {
- alias: ["syntax"],
- name: "Trailing commas in functions",
- node: "8.0.0",
- },
- //------------------------------------------
- templateLiteralRevision: {
- alias: ["syntax"],
- name: "Illegal escape sequences in taggled templates",
- node: "9.0.0",
- },
- regexpS: {
- alias: ["syntax"],
- name: "RegExp 's' flags",
- node: "9.0.0",
- },
- regexpNamedCaptureGroups: {
- alias: ["syntax"],
- name: "RegExp named capture groups",
- node: "10.0.0",
- },
- regexpLookbehind: {
- alias: ["syntax"],
- name: "RegExp lookbehind assertions",
- node: "9.0.0",
- },
- regexpUnicodeProperties: {
- alias: ["syntax"],
- name: "RegExp Unicode property escapes",
- node: "10.0.0",
- },
- restProperties: {
- alias: ["syntax"],
- name: "Rest properties",
- node: "8.3.0",
- },
- spreadProperties: {
- alias: ["syntax"],
- name: "Spread properties",
- node: "8.3.0",
- },
- asyncGenerators: {
- alias: ["syntax"],
- name: "Async generators",
- node: "10.0.0",
- },
- forAwaitOf: {
- alias: ["syntax"],
- name: "for-await-of loops",
- node: "10.0.0",
- },
-
- Int8Array: {
- alias: ["runtime", "globalObjects", "typedArrays"],
- name: "'Int8Array'",
- singular: true,
- node: "0.12.0",
- },
- Uint8Array: {
- alias: ["runtime", "globalObjects", "typedArrays"],
- name: "'Uint8Array'",
- singular: true,
- node: "0.12.0",
- },
- Uint8ClampedArray: {
- alias: ["runtime", "globalObjects", "typedArrays"],
- name: "'Uint8ClampedArray'",
- singular: true,
- node: "0.12.0",
- },
- Int16Array: {
- alias: ["runtime", "globalObjects", "typedArrays"],
- name: "'Int16Array'",
- singular: true,
- node: "0.12.0",
- },
- Uint16Array: {
- alias: ["runtime", "globalObjects", "typedArrays"],
- name: "'Uint16Array'",
- singular: true,
- node: "0.12.0",
- },
- Int32Array: {
- alias: ["runtime", "globalObjects", "typedArrays"],
- name: "'Int32Array'",
- singular: true,
- node: "0.12.0",
- },
- Uint32Array: {
- alias: ["runtime", "globalObjects", "typedArrays"],
- name: "'Uint32Array'",
- singular: true,
- node: "0.12.0",
- },
- Float32Array: {
- alias: ["runtime", "globalObjects", "typedArrays"],
- name: "'Float32Array'",
- singular: true,
- node: "0.12.0",
- },
- Float64Array: {
- alias: ["runtime", "globalObjects", "typedArrays"],
- name: "'Float64Array'",
- singular: true,
- node: "0.12.0",
- },
- DataView: {
- alias: ["runtime", "globalObjects", "typedArrays"],
- name: "'DataView'",
- singular: true,
- node: "0.12.0",
- },
- Map: {
- alias: ["runtime", "globalObjects"],
- name: "'Map'",
- singular: true,
- node: "0.12.0",
- },
- Set: {
- alias: ["runtime", "globalObjects"],
- name: "'Set'",
- singular: true,
- node: "0.12.0",
- },
- WeakMap: {
- alias: ["runtime", "globalObjects"],
- name: "'WeakMap'",
- singular: true,
- node: "0.12.0",
- },
- WeakSet: {
- alias: ["runtime", "globalObjects"],
- name: "'WeakSet'",
- singular: true,
- node: "0.12.0",
- },
- Proxy: {
- alias: ["runtime", "globalObjects"],
- name: "'Proxy'",
- singular: true,
- node: "6.0.0",
- },
- Reflect: {
- alias: ["runtime", "globalObjects"],
- name: "'Reflect'",
- singular: true,
- node: "6.0.0",
- },
- Promise: {
- alias: ["runtime", "globalObjects"],
- name: "'Promise'",
- singular: true,
- node: "0.12.0",
- },
- Symbol: {
- alias: ["runtime", "globalObjects"],
- name: "'Symbol'",
- singular: true,
- node: "0.12.0",
- },
- SharedArrayBuffer: {
- alias: ["runtime", "globalObjects"],
- name: "'SharedArrayBuffer'",
- singular: true,
- node: "9.0.0",
- },
- Atomics: {
- alias: ["runtime", "globalObjects"],
- name: "'Atomics'",
- singular: true,
- node: "9.0.0",
- },
-
- "Object.assign": {
- alias: ["runtime", "staticMethods", "Object.*"],
- name: "'Object.assign'",
- singular: true,
- node: "4.0.0",
- },
- "Object.is": {
- alias: ["runtime", "staticMethods", "Object.*"],
- name: "'Object.is'",
- singular: true,
- node: "0.12.0",
- },
- "Object.getOwnPropertySymbols": {
- alias: ["runtime", "staticMethods", "Object.*"],
- name: "'Object.getOwnPropertySymbols'",
- singular: true,
- node: "0.12.0",
- },
- "Object.setPrototypeOf": {
- alias: ["runtime", "staticMethods", "Object.*"],
- name: "'Object.setPrototypeOf'",
- singular: true,
- node: "0.12.0",
- },
- "Object.values": {
- alias: ["runtime", "staticMethods", "Object.*"],
- name: "'Object.values'",
- singular: true,
- node: "7.0.0",
- },
- "Object.entries": {
- alias: ["runtime", "staticMethods", "Object.*"],
- name: "'Object.entries'",
- singular: true,
- node: "7.0.0",
- },
- "Object.getOwnPropertyDescriptors": {
- alias: ["runtime", "staticMethods", "Object.*"],
- name: "'Object.getOwnPropertyDescriptors'",
- singular: true,
- node: "7.0.0",
- },
-
- "String.raw": {
- alias: ["runtime", "staticMethods", "String.*"],
- name: "'String.raw'",
- singular: true,
- node: "4.0.0",
- },
- "String.fromCodePoint": {
- alias: ["runtime", "staticMethods", "String.*"],
- name: "'String.fromCodePoint'",
- singular: true,
- node: "4.0.0",
- },
-
- "Array.from": {
- alias: ["runtime", "staticMethods", "Array.*"],
- name: "'Array.from'",
- singular: true,
- node: "4.0.0",
- },
- "Array.of": {
- alias: ["runtime", "staticMethods", "Array.*"],
- name: "'Array.of'",
- singular: true,
- node: "4.0.0",
- },
-
- "Number.isFinite": {
- alias: ["runtime", "staticMethods", "Number.*"],
- name: "'Number.isFinite'",
- singular: true,
- node: "0.10.0",
- },
- "Number.isInteger": {
- alias: ["runtime", "staticMethods", "Number.*"],
- name: "'Number.isInteger'",
- singular: true,
- node: "0.12.0",
- },
- "Number.isSafeInteger": {
- alias: ["runtime", "staticMethods", "Number.*"],
- name: "'Number.isSafeInteger'",
- singular: true,
- node: "0.12.0",
- },
- "Number.isNaN": {
- alias: ["runtime", "staticMethods", "Number.*"],
- name: "'Number.isNaN'",
- singular: true,
- node: "0.10.0",
- },
- "Number.EPSILON": {
- alias: ["runtime", "staticMethods", "Number.*"],
- name: "'Number.EPSILON'",
- singular: true,
- node: "0.12.0",
- },
- "Number.MIN_SAFE_INTEGER": {
- alias: ["runtime", "staticMethods", "Number.*"],
- name: "'Number.MIN_SAFE_INTEGER'",
- singular: true,
- node: "0.12.0",
- },
- "Number.MAX_SAFE_INTEGER": {
- alias: ["runtime", "staticMethods", "Number.*"],
- name: "'Number.MAX_SAFE_INTEGER'",
- singular: true,
- node: "0.12.0",
- },
-
- "Math.clz32": {
- alias: ["runtime", "staticMethods", "Math.*"],
- name: "'Math.clz32'",
- singular: true,
- node: "0.12.0",
- },
- "Math.imul": {
- alias: ["runtime", "staticMethods", "Math.*"],
- name: "'Math.imul'",
- singular: true,
- node: "0.12.0",
- },
- "Math.sign": {
- alias: ["runtime", "staticMethods", "Math.*"],
- name: "'Math.sign'",
- singular: true,
- node: "0.12.0",
- },
- "Math.log10": {
- alias: ["runtime", "staticMethods", "Math.*"],
- name: "'Math.log10'",
- singular: true,
- node: "0.12.0",
- },
- "Math.log2": {
- alias: ["runtime", "staticMethods", "Math.*"],
- name: "'Math.log2'",
- singular: true,
- node: "0.12.0",
- },
- "Math.log1p": {
- alias: ["runtime", "staticMethods", "Math.*"],
- name: "'Math.log1p'",
- singular: true,
- node: "0.12.0",
- },
- "Math.expm1": {
- alias: ["runtime", "staticMethods", "Math.*"],
- name: "'Math.expm1'",
- singular: true,
- node: "0.12.0",
- },
- "Math.cosh": {
- alias: ["runtime", "staticMethods", "Math.*"],
- name: "'Math.cosh'",
- singular: true,
- node: "0.12.0",
- },
- "Math.sinh": {
- alias: ["runtime", "staticMethods", "Math.*"],
- name: "'Math.sinh'",
- singular: true,
- node: "0.12.0",
- },
- "Math.tanh": {
- alias: ["runtime", "staticMethods", "Math.*"],
- name: "'Math.tanh'",
- singular: true,
- node: "0.12.0",
- },
- "Math.acosh": {
- alias: ["runtime", "staticMethods", "Math.*"],
- name: "'Math.acosh'",
- singular: true,
- node: "0.12.0",
- },
- "Math.asinh": {
- alias: ["runtime", "staticMethods", "Math.*"],
- name: "'Math.asinh'",
- singular: true,
- node: "0.12.0",
- },
- "Math.atanh": {
- alias: ["runtime", "staticMethods", "Math.*"],
- name: "'Math.atanh'",
- singular: true,
- node: "0.12.0",
- },
- "Math.trunc": {
- alias: ["runtime", "staticMethods", "Math.*"],
- name: "'Math.trunc'",
- singular: true,
- node: "0.12.0",
- },
- "Math.fround": {
- alias: ["runtime", "staticMethods", "Math.*"],
- name: "'Math.fround'",
- singular: true,
- node: "0.12.0",
- },
- "Math.cbrt": {
- alias: ["runtime", "staticMethods", "Math.*"],
- name: "'Math.cbrt'",
- singular: true,
- node: "0.12.0",
- },
- "Math.hypot": {
- alias: ["runtime", "staticMethods", "Math.*"],
- name: "'Math.hypot'",
- singular: true,
- node: "0.12.0",
- },
-
- "Symbol.hasInstance": {
- alias: ["runtime", "staticMethods", "Symbol.*"],
- name: "'Symbol.hasInstance'",
- singular: true,
- node: "6.5.0",
- },
- "Symbol.isConcatSpreadablec": {
- alias: ["runtime", "staticMethods", "Symbol.*"],
- name: "'Symbol.isConcatSpreadablec'",
- singular: true,
- node: "6.0.0",
- },
- "Symbol.iterator": {
- alias: ["runtime", "staticMethods", "Symbol.*"],
- name: "'Symbol.iterator'",
- singular: true,
- node: "0.12.0",
- },
- "Symbol.species": {
- alias: ["runtime", "staticMethods", "Symbol.*"],
- name: "'Symbol.species'",
- singular: true,
- node: "6.5.0",
- },
- "Symbol.replace": {
- alias: ["runtime", "staticMethods", "Symbol.*"],
- name: "'Symbol.replace'",
- singular: true,
- node: "6.0.0",
- },
- "Symbol.search": {
- alias: ["runtime", "staticMethods", "Symbol.*"],
- name: "'Symbol.search'",
- singular: true,
- node: "6.0.0",
- },
- "Symbol.split": {
- alias: ["runtime", "staticMethods", "Symbol.*"],
- name: "'Symbol.split'",
- singular: true,
- node: "6.0.0",
- },
- "Symbol.match": {
- alias: ["runtime", "staticMethods", "Symbol.*"],
- name: "'Symbol.match'",
- singular: true,
- node: "6.0.0",
- },
- "Symbol.toPrimitive": {
- alias: ["runtime", "staticMethods", "Symbol.*"],
- name: "'Symbol.toPrimitive'",
- singular: true,
- node: "6.0.0",
- },
- "Symbol.toStringTag": {
- alias: ["runtime", "staticMethods", "Symbol.*"],
- name: "'Symbol.toStringTag'",
- singular: true,
- node: "6.0.0",
- },
- "Symbol.unscopables": {
- alias: ["runtime", "staticMethods", "Symbol.*"],
- name: "'Symbol.unscopables'",
- singular: true,
- node: "4.0.0",
- },
-
- "Atomics.add": {
- alias: ["runtime", "staticMethods", "Atomics.*"],
- name: "'Atomics.add'",
- singular: true,
- node: "9.0.0",
- },
- "Atomics.and": {
- alias: ["runtime", "staticMethods", "Atomics.*"],
- name: "'Atomics.and'",
- singular: true,
- node: "9.0.0",
- },
- "Atomics.compareExchange": {
- alias: ["runtime", "staticMethods", "Atomics.*"],
- name: "'Atomics.compareExchange'",
- singular: true,
- node: "9.0.0",
- },
- "Atomics.exchange": {
- alias: ["runtime", "staticMethods", "Atomics.*"],
- name: "'Atomics.exchange'",
- singular: true,
- node: "9.0.0",
- },
- "Atomics.wait": {
- alias: ["runtime", "staticMethods", "Atomics.*"],
- name: "'Atomics.wait'",
- singular: true,
- node: "9.0.0",
- },
- "Atomics.wake": {
- alias: ["runtime", "staticMethods", "Atomics.*"],
- name: "'Atomics.wake'",
- singular: true,
- node: "9.0.0",
- },
- "Atomics.isLockFree": {
- alias: ["runtime", "staticMethods", "Atomics.*"],
- name: "'Atomics.isLockFree'",
- singular: true,
- node: "9.0.0",
- },
- "Atomics.load": {
- alias: ["runtime", "staticMethods", "Atomics.*"],
- name: "'Atomics.load'",
- singular: true,
- node: "9.0.0",
- },
- "Atomics.or": {
- alias: ["runtime", "staticMethods", "Atomics.*"],
- name: "'Atomics.or'",
- singular: true,
- node: "9.0.0",
- },
- "Atomics.store": {
- alias: ["runtime", "staticMethods", "Atomics.*"],
- name: "'Atomics.store'",
- singular: true,
- node: "9.0.0",
- },
- "Atomics.sub": {
- alias: ["runtime", "staticMethods", "Atomics.*"],
- name: "'Atomics.sub'",
- singular: true,
- node: "9.0.0",
- },
- "Atomics.xor": {
- alias: ["runtime", "staticMethods", "Atomics.*"],
- name: "'Atomics.xor'",
- singular: true,
- node: "9.0.0",
- },
-
- extendsArray: {
- alias: ["runtime", "extends"],
- name: "Subclassing of 'Array'",
- singular: true,
- node: "6.0.0",
- },
- extendsRegExp: {
- alias: ["runtime", "extends"],
- name: "Subclassing of 'RegExp'",
- singular: true,
- node: "5.0.0",
- },
- extendsFunction: {
- alias: ["runtime", "extends"],
- name: "Subclassing of 'Function'",
- singular: true,
- node: "6.0.0",
- },
- extendsPromise: {
- alias: ["runtime", "extends"],
- name: "Subclassing of 'Promise'",
- singular: true,
- node: "5.0.0",
- },
- extendsBoolean: {
- alias: ["runtime", "extends"],
- name: "Subclassing of 'Boolean'",
- singular: true,
- node: "4.0.0",
- },
- extendsNumber: {
- alias: ["runtime", "extends"],
- name: "Subclassing of 'Number'",
- singular: true,
- node: "4.0.0",
- },
- extendsString: {
- alias: ["runtime", "extends"],
- name: "Subclassing of 'String'",
- singular: true,
- node: "4.0.0",
- },
- extendsMap: {
- alias: ["runtime", "extends"],
- name: "Subclassing of 'Map'",
- singular: true,
- node: "4.0.0",
- },
- extendsSet: {
- alias: ["runtime", "extends"],
- name: "Subclassing of 'Set'",
- singular: true,
- node: "4.0.0",
- },
- extendsNull: {
- alias: ["runtime", "extends"],
- name: "'extends null'",
- singular: true,
- node: null,
- },
-}
-const OPTIONS = Object.keys(FEATURES)
-
-/**
- * Gets default version configuration of this rule.
- *
- * This finds and reads 'package.json' file, then parses 'engines.node' field.
- * If it's nothing, this returns null.
- *
- * @param {string} filename - The file name of the current linting file.
- * @returns {string} The default version configuration.
- */
-function getDefaultVersion(filename) {
- const info = getPackageJson(filename)
- const nodeVersion = info && info.engines && info.engines.node
-
- return semver.validRange(nodeVersion) || DEFAULT_VERSION
-}
-
-/**
- * Gets values of the `ignores` option.
- *
- * @returns {string[]} Values of the `ignores` option.
- */
-function getIgnoresEnum() {
- return Object.keys(
- OPTIONS.reduce((retv, key) => {
- for (const alias of FEATURES[key].alias) {
- retv[alias] = true
- }
- retv[key] = true
- return retv
- }, Object.create(null))
- )
-}
-
-/**
- * Checks whether a given key should be ignored or not.
- *
- * @param {string} key - A key to check.
- * @param {string[]} ignores - An array of keys and aliases to be ignored.
- * @returns {boolean} `true` if the key should be ignored.
- */
-function isIgnored(key, ignores) {
- return (
- ignores.indexOf(key) !== -1 ||
- FEATURES[key].alias.some(alias => ignores.indexOf(alias) !== -1)
- )
-}
-
-/**
- * Parses the options.
- *
- * @param {number|string|object|undefined} options - An option object to parse.
- * @param {number} defaultVersion - The default version to use if the version option was omitted.
- * @returns {object} Parsed value.
- */
-function parseOptions(options, defaultVersion) {
- let version = null
- let range = null
- let ignores = []
-
- if (typeof options === "number") {
- version = VERSION_MAP.get(options)
- } else if (typeof options === "string") {
- version = options
- } else if (typeof options === "object") {
- version =
- typeof options.version === "number"
- ? VERSION_MAP.get(options.version)
- : options.version
-
- ignores = options.ignores || []
- }
-
- range = semver.validRange(version ? `>=${version}` : defaultVersion)
- if (!version) {
- version = defaultVersion
- }
-
- return Object.freeze({
- version,
- features: Object.freeze(
- OPTIONS.reduce((retv, key) => {
- const feature = FEATURES[key]
-
- if (isIgnored(key, ignores)) {
- retv[key] = Object.freeze({
- name: feature.name,
- singular: Boolean(feature.singular),
- supported: true,
- supportedInStrict: true,
- })
- } else if (typeof feature.node === "string") {
- retv[key] = Object.freeze({
- name: feature.name,
- singular: Boolean(feature.singular),
- supported: !semver.intersects(
- range,
- `<${feature.node}`
- ),
- supportedInStrict: !semver.intersects(
- range,
- `<${feature.node}`
- ),
- })
- } else {
- retv[key] = Object.freeze({
- name: feature.name,
- singular: Boolean(feature.singular),
- supported:
- feature.node != null &&
- feature.node.sloppy != null &&
- !semver.intersects(
- range,
- `<${feature.node.sloppy}`
- ),
- supportedInStrict:
- feature.node != null &&
- feature.node.strict != null &&
- !semver.intersects(
- range,
- `<${feature.node.strict}`
- ),
- })
- }
-
- return retv
- }, Object.create(null))
- ),
- })
-}
-
-/**
- * Find the scope that a given node belongs to.
- * @param {Scope} initialScope The initial scope to find.
- * @param {Node} node The AST node.
- * @returns {Scope} The scope that the node belongs to.
- */
-function normalizeScope(initialScope, node) {
- let scope = getInnermostScope(initialScope, node)
-
- while (scope && scope.block === node) {
- scope = scope.upper
- }
-
- return scope
-}
-
-/**
- * Checks whether the given string has `\u{90ABCDEF}`-like escapes.
- *
- * @param {string} raw - The string to check.
- * @returns {boolean} `true` if the string has Unicode code point escapes.
- */
-function hasUnicodeCodePointEscape(raw) {
- let match = null
-
- UNICODE_ESC.lastIndex = 0
- while ((match = UNICODE_ESC.exec(raw)) != null) {
- if (match[1].length % 2 === 1) {
- return true
- }
- }
-
- return false
-}
-
-/**
- * Check a given string has a given pattern.
- * @param {string} s A string to check.
- * @param {RegExp} pattern A RegExp object to check.
- * @returns {boolean} `true` if the string has the pattern.
- */
-function hasPattern(s, pattern) {
- const m = pattern.exec(s)
- return m != null && (m[1] || "").length % 2 === 0
-}
-
-module.exports = {
- meta: {
- docs: {
- description:
- "disallow unsupported ECMAScript features on the specified version",
- recommended: false,
-
- url: "https://github.com/eslint-community/eslint-plugin-n/blob/HEAD/docs/rules/no-unsupported-features.md",
- },
- type: "problem",
- deprecated: true,
- replacedBy: [
- "n/no-unsupported-features/es-syntax",
- "n/no-unsupported-features/es-builtins",
- ],
- fixable: null,
- schema: [
- {
- anyOf: [
- VERSION_SCHEMA.anyOf[0],
- VERSION_SCHEMA.anyOf[1],
- {
- type: "object",
- properties: {
- version: VERSION_SCHEMA,
- ignores: {
- type: "array",
- items: { enum: getIgnoresEnum() },
- uniqueItems: true,
- },
- },
- additionalProperties: false,
- },
- ],
- },
- ],
- messages: {
- unsupported:
- "{{feature}} {{be}} not supported yet on Node {{version}}.",
- },
- },
- create(context) {
- const sourceCode = context.sourceCode ?? context.getSourceCode() // TODO: just use context.sourceCode when dropping eslint < v9
- const supportInfo = parseOptions(
- context.options[0],
- getDefaultVersion(context.filename ?? context.getFilename())
- )
-
- /**
- * Gets the references of the specified global variables.
- *
- * @param {string[]} names - Variable names to get.
- * @returns {void}
- */
- function* getReferences(names) {
- const globalScope =
- sourceCode.getScope?.(sourceCode.ast) ?? context.getScope() //TODO: remove context.getScope() when dropping support for ESLint < v9
-
- for (const name of names) {
- const variable = globalScope.set.get(name)
-
- if (variable && variable.defs.length === 0) {
- yield* variable.references
- }
- }
- }
-
- /**
- * Checks whether the given function has trailing commas or not.
- *
- * @param {ASTNode} node - The function node to check.
- * @returns {boolean} `true` if the function has trailing commas.
- */
- function hasTrailingCommaForFunction(node) {
- const length = node.params.length
-
- return (
- length >= 1 &&
- sourceCode.getTokenAfter(node.params[length - 1]).value === ","
- )
- }
-
- /**
- * Checks whether the given call expression has trailing commas or not.
- *
- * @param {ASTNode} node - The call expression node to check.
- * @returns {boolean} `true` if the call expression has trailing commas.
- */
- function hasTrailingCommaForCall(node) {
- return (
- node.arguments.length >= 1 &&
- sourceCode.getLastToken(node, 1).value === ","
- )
- }
-
- /**
- * Checks whether the given class extends from null or not.
- *
- * @param {ASTNode} node - The class node to check.
- * @returns {boolean} `true` if the class extends from null.
- */
- function extendsNull(node) {
- return (
- node.superClass != null &&
- node.superClass.type === "Literal" &&
- node.superClass.value === null
- )
- }
-
- /**
- * Reports a given node if the specified feature is not supported.
- *
- * @param {ASTNode} node - A node to be reported.
- * @param {string} key - A feature name to report.
- * @returns {void}
- */
- function report(node, key) {
- const globalScope =
- sourceCode.getScope?.(node) ?? context.getScope() //TODO: remove context.getScope() when dropping support for ESLint < v9
- const version = supportInfo.version
- const feature = supportInfo.features[key]
- if (feature.supported) {
- return
- }
-
- if (!feature.supportedInStrict) {
- context.report({
- node,
- messageId: "unsupported",
- data: {
- feature: feature.name,
- be: feature.singular ? "is" : "are",
- version,
- },
- })
- } else if (!normalizeScope(globalScope, node).isStrict) {
- context.report({
- node,
- messageId: "unsupported",
- data: {
- feature: `${feature.name} in non-strict mode`,
- be: feature.singular ? "is" : "are",
- version,
- },
- })
- }
- }
-
- /**
- * Validate RegExp syntax.
- * @param {string} pattern A RegExp pattern to check.
- * @param {string} flags A RegExp flags to check.
- * @param {ASTNode} node A node to report.
- * @returns {void}
- */
- function validateRegExp(pattern, flags, node) {
- if (typeof pattern === "string") {
- if (hasPattern(pattern, REGEXP_NAMED_GROUP)) {
- report(node, "regexpNamedCaptureGroups")
- }
- if (hasPattern(pattern, REGEXP_LOOKBEHIND)) {
- report(node, "regexpLookbehind")
- }
- if (hasPattern(pattern, REGEXP_UNICODE_PROPERTY)) {
- report(node, "regexpUnicodeProperties")
- }
- }
- if (typeof flags === "string") {
- if (flags.indexOf("y") !== -1) {
- report(node, "regexpY")
- }
- if (flags.indexOf("u") !== -1) {
- report(node, "regexpU")
- }
- if (flags.indexOf("s") !== -1) {
- report(node, "regexpS")
- }
- }
- }
-
- /**
- * Validate RegExp syntax in a RegExp literal.
- * @param {ASTNode} node A Literal node to check.
- * @returns {void}
- */
- function validateRegExpLiteral(node) {
- validateRegExp(node.regex.pattern, node.regex.flags, node)
- }
-
- /**
- * Validate RegExp syntax in the first argument of `new RegExp()`.
- * @param {ASTNode} node A NewExpression node to check.
- * @returns {void}
- */
- function validateRegExpString(node) {
- const patternNode = node.arguments[0]
- const flagsNode = node.arguments[1]
- const pattern =
- patternNode &&
- patternNode.type === "Literal" &&
- typeof patternNode.value === "string"
- ? patternNode.value
- : null
- const flags =
- flagsNode &&
- flagsNode.type === "Literal" &&
- typeof flagsNode.value === "string"
- ? flagsNode.value
- : null
- validateRegExp(pattern, flags, node)
- }
-
- return {
- "Program:exit"() {
- // Check new global variables.
- for (const name of NEW_BUILTIN_TYPES) {
- for (const reference of getReferences([name])) {
- // Ignore if it's using new static methods.
- const node = reference.identifier
- const parentNode = node.parent
- const properties = PROPERTY_TEST_TARGETS[name]
- if (
- properties &&
- parentNode.type === "MemberExpression"
- ) {
- const propertyName = getPropertyName(parentNode)
- if (properties.indexOf(propertyName) !== -1) {
- continue
- }
- }
-
- report(reference.identifier, name)
- }
- }
-
- // Check static methods.
- for (const reference of getReferences(
- Object.keys(PROPERTY_TEST_TARGETS)
- )) {
- const node = reference.identifier
- const parentNode = node.parent
- if (
- parentNode.type !== "MemberExpression" ||
- parentNode.object !== node
- ) {
- continue
- }
-
- const objectName = node.name
- const properties = PROPERTY_TEST_TARGETS[objectName]
- const propertyName = getPropertyName(parentNode)
- if (
- propertyName &&
- properties.indexOf(propertyName) !== -1
- ) {
- report(parentNode, `${objectName}.${propertyName}`)
- }
- }
-
- // Check subclassing
- for (const reference of getReferences(
- SUBCLASSING_TEST_TARGETS
- )) {
- const node = reference.identifier
- const parentNode = node.parent
- if (
- CLASS_TYPE.test(parentNode.type) &&
- parentNode.superClass === node
- ) {
- report(node, `extends${node.name}`)
- }
- }
- },
-
- ArrowFunctionExpression(node) {
- report(node, "arrowFunctions")
- if (node.async) {
- report(node, "asyncAwait")
- }
- if (hasTrailingCommaForFunction(node)) {
- report(node, "trailingCommasInFunctions")
- }
- },
-
- AssignmentPattern(node) {
- if (FUNC_TYPE.test(node.parent.type)) {
- report(node, "defaultParameters")
- }
- },
-
- FunctionDeclaration(node) {
- const scope = (
- sourceCode.getScope?.(node) ?? context.getScope()
- ).upper //TODO: remove context.getScope() when dropping support for ESLint < v9
- if (!TOPLEVEL_SCOPE_TYPE.test(scope.type)) {
- report(node, "blockScopedFunctions")
- }
- if (node.generator) {
- report(node, "generatorFunctions")
- }
- if (node.async) {
- report(node, "asyncAwait")
- }
- if (hasTrailingCommaForFunction(node)) {
- report(node, "trailingCommasInFunctions")
- }
- if (node.async && node.generator) {
- report(node, "asyncGenerators")
- }
- },
-
- FunctionExpression(node) {
- if (node.generator) {
- report(node, "generatorFunctions")
- }
- if (node.async) {
- report(node, "asyncAwait")
- }
- if (hasTrailingCommaForFunction(node)) {
- report(node, "trailingCommasInFunctions")
- }
- if (node.async && node.generator) {
- report(node, "asyncGenerators")
- }
- },
-
- MetaProperty(node) {
- const meta = node.meta.name || node.meta
- const property = node.property.name || node.property
- if (meta === "new" && property === "target") {
- report(node, "new.target")
- }
- },
-
- ClassDeclaration(node) {
- report(node, "classes")
-
- if (extendsNull(node)) {
- report(node, "extendsNull")
- }
- },
-
- ClassExpression(node) {
- report(node, "classes")
-
- if (extendsNull(node)) {
- report(node, "extendsNull")
- }
- },
-
- ForOfStatement(node) {
- report(node, "forOf")
- if (node.await) {
- report(node, "forAwaitOf")
- }
- },
-
- VariableDeclaration(node) {
- if (node.kind === "const") {
- report(node, "const")
- } else if (node.kind === "let") {
- report(node, "let")
- }
- },
-
- ArrayPattern(node) {
- if (DESTRUCTURING_PARENT_TYPE.test(node.parent.type)) {
- report(node, "destructuring")
- }
- },
-
- AssignmentExpression(node) {
- if (node.operator === "**=") {
- report(node, "exponentialOperators")
- }
- },
-
- AwaitExpression(node) {
- report(node, "asyncAwait")
- },
-
- BinaryExpression(node) {
- if (node.operator === "**") {
- report(node, "exponentialOperators")
- }
- },
-
- CallExpression(node) {
- if (hasTrailingCommaForCall(node)) {
- report(node, "trailingCommasInFunctions")
- }
- },
-
- Identifier(node) {
- const raw = sourceCode.getText(node)
- if (hasUnicodeCodePointEscape(raw)) {
- report(node, "unicodeCodePointEscapes")
- }
- },
-
- Literal(node) {
- if (typeof node.value === "number") {
- if (BINARY_NUMBER.test(node.raw)) {
- report(node, "binaryNumberLiterals")
- } else if (OCTAL_NUMBER.test(node.raw)) {
- report(node, "octalNumberLiterals")
- }
- } else if (typeof node.value === "string") {
- if (hasUnicodeCodePointEscape(node.raw)) {
- report(node, "unicodeCodePointEscapes")
- }
- } else if (node.regex) {
- validateRegExpLiteral(node)
- }
- },
-
- NewExpression(node) {
- if (
- node.callee.type === "Identifier" &&
- node.callee.name === "RegExp"
- ) {
- validateRegExpString(node)
- }
- if (hasTrailingCommaForCall(node)) {
- report(node, "trailingCommasInFunctions")
- }
- },
-
- ObjectPattern(node) {
- if (DESTRUCTURING_PARENT_TYPE.test(node.parent.type)) {
- report(node, "destructuring")
- }
- },
-
- Property(node) {
- if (
- node.parent.type === "ObjectExpression" &&
- (node.computed || node.shorthand || node.method)
- ) {
- if (node.shorthand && GET_OR_SET.test(node.key.name)) {
- report(node, "objectPropertyShorthandOfGetSet")
- } else {
- report(node, "objectLiteralExtensions")
- }
- }
- },
-
- RestElement(node) {
- if (FUNC_TYPE.test(node.parent.type)) {
- report(node, "restParameters")
- } else if (node.parent.type === "ObjectPattern") {
- report(node, "restProperties")
- }
- },
-
- SpreadElement(node) {
- if (node.parent.type === "ObjectExpression") {
- report(node, "spreadProperties")
- } else {
- report(node, "spreadOperators")
- }
- },
-
- TemplateElement(node) {
- if (node.value.cooked == null) {
- report(node, "templateLiteralRevision")
- }
- },
-
- TemplateLiteral(node) {
- report(node, "templateStrings")
- },
-
- ExperimentalRestProperty(node) {
- report(node, "restProperties")
- },
-
- ExperimentalSpreadProperty(node) {
- report(node, "spreadProperties")
- },
-
- RestProperty(node) {
- report(node, "restProperties")
- },
-
- SpreadProperty(node) {
- report(node, "spreadProperties")
- },
-
- ExportAllDeclaration(node) {
- report(node, "modules")
- },
-
- ExportDefaultDeclaration(node) {
- report(node, "modules")
- },
-
- ExportNamedDeclaration(node) {
- report(node, "modules")
- },
-
- ImportDeclaration(node) {
- report(node, "modules")
- },
- }
- },
-}
diff --git a/tests/lib/rules/no-unsupported-features.js b/tests/lib/rules/no-unsupported-features.js
deleted file mode 100644
index 8351e7f9..00000000
--- a/tests/lib/rules/no-unsupported-features.js
+++ /dev/null
@@ -1,1395 +0,0 @@
-/**
- * @author Toru Nagashima
- * See LICENSE file in root directory for full license.
- */
-"use strict"
-
-const path = require("path")
-const RuleTester = require("#eslint-rule-tester").RuleTester
-const rule = require("../../../lib/rules/no-unsupported-features")
-
-const VERSION_MAP = new Map([
- [0.1, "0.10.0"],
- [0.12, "0.12.0"],
- [4, "4.0.0"],
- [5, "5.0.0"],
- [6, "6.0.0"],
- [6.5, "6.5.0"],
- [7, "7.0.0"],
- [7.6, "7.6.0"],
- [8, "8.0.0"],
- [8.3, "8.3.0"],
- [9, "9.0.0"],
- [10, "10.0.0"],
-])
-
-/**
- * Creates test pattern.
- *
- * @param {{valid: object[], invalid: object[]}} retv - Actual test patterns.
- * @param {object} pattern - Original test pattern.
- * @returns {{valid: object[], invalid: object[]}} retv.
- */
-function convertPattern(retv, pattern) {
- let i = 0
-
- // If this test is on script mode, it should do this test on module mode as well.
- if (
- !pattern.modules &&
- pattern.code.indexOf("'use strict'") !== 0 &&
- pattern.name.indexOf("non-strict") === -1
- ) {
- convertPattern(
- retv,
- Object.create(pattern, { modules: { value: true } })
- )
- }
-
- // Creates error messages.
- const errors = []
- for (i = 0; i < pattern.errors; ++i) {
- errors.push(
- `${pattern.name} ${
- pattern.singular ? "is" : "are"
- } not supported yet on Node `
- )
- }
-
- // Creates each pattern of Node versions.
- for (const version of VERSION_MAP.keys()) {
- const versionText = VERSION_MAP.get(version)
-
- // Skips if ignored
- if (pattern.ignores && pattern.ignores.indexOf(version) !== -1) {
- continue
- }
-
- if (version >= pattern.supported) {
- // If this is supported, add to a valid pattern.
- retv.valid.push({
- code: `/*${pattern.name}: ${versionText}*/ ${pattern.code}`,
- options: [version],
- languageOptions: {
- ecmaVersion: 2018,
- sourceType: pattern.modules ? "module" : "script",
- globals: { SharedArrayBuffer: false, Atomics: false },
- },
- })
- } else {
- // If this is not supported, add to a valid pattern with a "ignores" option.
- ;[].push.apply(
- retv.valid,
- pattern.keys.map(key => ({
- code: `/*${pattern.name}: ${versionText}, ignores: ["${key}"]*/ ${pattern.code}`,
- options: [{ version, ignores: [key] }],
- languageOptions: {
- ecmaVersion: 2018,
- sourceType: pattern.modules ? "module" : "script",
- globals: { SharedArrayBuffer: false, Atomics: false },
- },
- }))
- )
-
- // If this is not supported, add to a invalid pattern.
- retv.invalid.push({
- code: `/*${pattern.name}: ${versionText}*/ ${pattern.code}`,
- options: [version],
- languageOptions: {
- ecmaVersion: 2018,
- sourceType: pattern.modules ? "module" : "script",
- globals: { SharedArrayBuffer: false, Atomics: false },
- },
- errors: errors.map(message => `${message + versionText}.`),
- })
- }
- }
-
- return retv
-}
-
-/**
- * Makes a file path to a fixture.
- * @param {string} name - A name.
- * @returns {string} A file path to a fixture.
- */
-function fixture(name) {
- return path.resolve(
- __dirname,
- "../../fixtures/no-unsupported-features",
- name
- )
-}
-
-const ruleTester = new RuleTester()
-ruleTester.run(
- "no-unsupported-features",
- rule,
- [
- {
- keys: ["defaultParameters", "syntax"],
- name: "Default parameters",
- code: "function foo(a = 1) {} ;(function(a = 1) {})()",
- errors: 2,
- supported: 6,
- },
- {
- keys: ["restParameters", "syntax"],
- name: "Rest parameters",
- code: "function foo(a, ...b) {} ;(function(a, ...b) {})()",
- errors: 2,
- supported: 6,
- },
- {
- keys: ["spreadOperators", "syntax"],
- name: "Spread operators",
- code: "foo(...a); foo([...a, ...b])",
- errors: 3,
- supported: 5,
- },
- {
- keys: ["objectLiteralExtensions", "syntax"],
- name: "Object literal extensions",
- code: "var obj = {[a]: 0, b, c() {}, get [d]() {}, set [d](v) {}}",
- errors: 5,
- supported: 4,
- },
- {
- keys: [
- "objectPropertyShorthandOfGetSet",
- "objectLiteralExtensions",
- "syntax",
- ],
- name: "Property shorthand of 'get' and 'set'",
- code: "var obj = {get, set}",
- errors: 2,
- supported: 6,
- },
- {
- keys: ["forOf", "syntax"],
- name: "'for..of' loops",
- code: "for (var a of []) {}",
- errors: 1,
- supported: 0.12,
- },
- {
- keys: ["binaryNumberLiterals", "syntax"],
- name: "Binary number literals",
- code: "var a = 0b10 === 2 && 0B10 === 2",
- errors: 2,
- supported: 4,
- },
- {
- keys: ["octalNumberLiterals", "syntax"],
- name: "Octal number literals",
- code: "var a = 0o10 === 8 && 0O10 === 8",
- errors: 2,
- supported: 4,
- },
- {
- keys: ["templateStrings", "syntax"],
- name: "Template strings",
- code: "`hello, ${world}!`; foo`tagged`;",
- errors: 2,
- supported: 4,
- },
- {
- keys: ["regexpY", "syntax"],
- name: "RegExp 'y' flags",
- code: "new RegExp('', 'y'); (/a/y)",
- errors: 2,
- supported: 6,
- },
- {
- keys: ["regexpU", "syntax"],
- name: "RegExp 'u' flags",
- code: "new RegExp('', 'u'); (/a/u)",
- errors: 2,
- supported: 6,
- },
- {
- keys: ["destructuring", "syntax"],
- name: "Destructuring",
- code: "var [[a], [b = 1]] = [], {c: {c}, d: {d = 1}} = {};",
- errors: 2,
- supported: 6,
- },
- {
- keys: ["destructuring", "syntax"],
- name: "Destructuring",
- code: "[[a], [b = 1]] = []; ({c: {c}, d: {d = 1}} = {})",
- errors: 2,
- supported: 6,
- },
- {
- keys: ["destructuring", "syntax"],
- name: "Destructuring",
- code: "function foo([[a], [b = 1]], {c: {c}, d: {d = 1}}) {}",
- errors: 2,
- supported: 6,
- },
- {
- keys: ["unicodeCodePointEscapes", "syntax"],
- name: "Unicode code point escapes",
- code: "var \\u{102C0} = { \\u{102C0} : '\\u{1d306}' };",
- errors: 3,
- supported: 4,
- },
- {
- keys: ["new.target", "syntax"],
- name: "'new.target'",
- code: "function Foo() { new.target; } ;(function() { new.target; })()",
- errors: 2,
- supported: 5,
- },
- {
- keys: ["const", "syntax"],
- name: "'const' declarations",
- code: "'use strict'; const a = 0;",
- errors: 1,
- supported: 4,
- },
- {
- keys: ["const", "syntax"],
- name: "'const' declarations",
- code: "const a = 0;",
- errors: 1,
- supported: 4,
- modules: true,
- },
- {
- keys: ["const", "syntax"],
- name: "'const' declarations in non-strict mode",
- code: "const a = 0;",
- errors: 1,
- supported: 6,
- ignores: [0.1, 0.12],
- },
- {
- keys: ["let", "syntax"],
- name: "'let' declarations",
- code: "'use strict'; let a = 0;",
- errors: 1,
- supported: 4,
- },
- {
- keys: ["let", "syntax"],
- name: "'let' declarations",
- code: "let a = 0;",
- errors: 1,
- supported: 4,
- modules: true,
- },
- {
- keys: ["let", "syntax"],
- name: "'let' declarations in non-strict mode",
- code: "let a = 0;",
- errors: 1,
- supported: 6,
- ignores: [0.1, 0.12],
- },
- {
- keys: ["blockScopedFunctions", "syntax"],
- name: "Block-scoped functions",
- code: "'use strict'; { function foo() {} } if (a) { function foo() {} }",
- errors: 2,
- supported: 4,
- },
- {
- keys: ["blockScopedFunctions", "syntax"],
- name: "Block-scoped functions",
- code: "{ function foo() {} } if (a) { function foo() {} }",
- errors: 2,
- supported: 4,
- modules: true,
- },
- {
- keys: ["blockScopedFunctions", "syntax"],
- name: "Block-scoped functions in non-strict mode",
- code: "{ function foo() {} } if (a) { function foo() {} }",
- errors: 2,
- supported: 6,
- ignores: [0.1, 0.12],
- },
- {
- keys: ["arrowFunctions", "syntax"],
- name: "Arrow functions",
- code: "var a = () => 1",
- errors: 1,
- supported: 4,
- },
- {
- keys: ["classes", "syntax"],
- name: "Classes",
- code: "'use strict'; class A {} new (class{})()",
- errors: 2,
- supported: 4,
- },
- {
- keys: ["classes", "syntax"],
- name: "Classes",
- code: "class A {} new (class{})()",
- errors: 2,
- supported: 4,
- modules: true,
- },
- {
- keys: ["classes", "syntax"],
- name: "Classes in non-strict mode",
- code: "class A {} new (class{})()",
- errors: 2,
- supported: 6,
- ignores: [0.1, 0.12],
- },
- {
- keys: ["generatorFunctions", "syntax"],
- name: "Generator functions",
- code: "function* foo() {} ;(function*() {})();",
- errors: 2,
- supported: 4,
- },
- {
- keys: ["modules", "syntax"],
- name: "Import and export declarations",
- code: "import foo from 'foo'; export default 0; export {foo}; export * from 'foo';",
- errors: 4,
- supported: NaN,
- modules: true,
- },
- {
- keys: ["exponentialOperators", "syntax"],
- name: "Exponential operators (**)",
- code: "var a = 2 ** 10; a **= 10;",
- errors: 2,
- supported: 7,
- },
- {
- keys: ["asyncAwait", "syntax"],
- name: "Async functions",
- code: [
- "async function foo() { await obj; };",
- "(async function() { await obj; });",
- "(async () => { await obj; });",
- "({async foo() { await obj; }});",
- "class A { async foo() { await obj; } };",
- ].join("\n"),
- errors: 10,
- supported: 7.6,
- ignores: [0.1, 0.12, 4, 5],
- },
- {
- keys: ["trailingCommasInFunctions", "syntax"],
- name: "Trailing commas in functions",
- code: [
- "function foo(a,) {}",
- "(function(a,) {});",
- "((a,) => {});",
- "({ foo(a,) {} });",
- "class A { foo(a,) {} };",
- "foo(a,);",
- "new Foo(a,);",
- ].join("\n"),
- errors: 7,
- supported: 8,
- ignores: [0.1, 0.12, 4, 5],
- },
- {
- keys: ["templateLiteralRevision", "syntax"],
- name: "Illegal escape sequences in taggled templates",
- code: [
- "tag`\\01\\1\\xg\\xAg\\u0\\u0g\\u00g\\u000g\\u{g\\u{0\\u{110000}${0}\\0`",
- ].join("\n"),
- errors: 1,
- supported: 9,
- ignores: [0.1, 0.12, 4, 5],
- },
- {
- keys: ["regexpS", "syntax"],
- name: "RegExp 's' flags",
- code: "new RegExp('', 's'); (/a/s)",
- errors: 2,
- supported: 9,
- },
- {
- keys: ["regexpNamedCaptureGroups", "syntax"],
- name: "RegExp named capture groups",
- code: [
- "new RegExp('(?b)');",
- //TODO: Espree has not supported this syntax yet.
- // ";(/(?b)/)",
- ].join("\n"),
- errors: 1,
- supported: 10,
- },
- {
- keys: ["regexpLookbehind", "syntax"],
- name: "RegExp lookbehind assertions",
- code: [
- "new RegExp('(?<=a)b')",
- "new RegExp('(? 1",
- },
- {
- filename: fixture("gte-4.4.0-lt-5.0.0/a.js"),
- code: "var a = () => 1",
- },
- {
- filename: fixture("hat-4.1.2/a.js"),
- code: "var a = () => 1",
- },
- {
- code: "'\\\\u{0123}'",
- },
- {
- filename: fixture("gte-4.0.0/a.js"),
- code: "var a = async () => 1",
- languageOptions: { ecmaVersion: 2017 },
- options: [{ ignores: ["asyncAwait"] }],
- },
- {
- filename: fixture("gte-7.6.0/a.js"),
- code: "var a = async () => 1",
- languageOptions: { ecmaVersion: 2017 },
- },
- {
- filename: fixture("gte-7.10.0/a.js"),
- code: "var a = async () => 1",
- languageOptions: { ecmaVersion: 2017 },
- },
- {
- filename: fixture("invalid/a.js"),
- code: "var a = () => 1",
- },
- {
- filename: fixture("nothing/a.js"),
- code: "var a = () => 1",
- },
- {
- code: "var a = async () => 1",
- languageOptions: { ecmaVersion: 2017 },
- options: ["7.10.0"],
- },
- {
- filename: fixture("without-node/a.js"),
- code: "var a = () => 1",
- },
- ],
- invalid: [
- {
- filename: fixture("gte-0.12.8/a.js"),
- code: "var a = () => 1",
- errors: [
- "Arrow functions are not supported yet on Node >=0.12.8.",
- ],
- },
- {
- filename: fixture("invalid/a.js"),
- code: "var a = (b,) => 1",
- languageOptions: { ecmaVersion: 2017 },
- errors: [
- "Trailing commas in functions are not supported yet on Node 4.0.0.",
- ],
- },
- {
- filename: fixture("lt-6.0.0/a.js"),
- code: "var a = () => 1",
- languageOptions: { ecmaVersion: 2017 },
- errors: [
- "Arrow functions are not supported yet on Node <6.0.0.",
- ],
- },
- {
- filename: fixture("nothing/a.js"),
- code: "var a = (b,) => 1",
- languageOptions: { ecmaVersion: 2017 },
- errors: [
- "Trailing commas in functions are not supported yet on Node 4.0.0.",
- ],
- },
- {
- filename: fixture("gte-7.5.0/a.js"),
- code: "var a = async () => 1",
- languageOptions: { ecmaVersion: 2017 },
- errors: [
- "Async functions are not supported yet on Node >=7.5.0.",
- ],
- },
- {
- code: "var a = async () => 1",
- languageOptions: { ecmaVersion: 2017 },
- options: ["7.1.0"],
- errors: [
- "Async functions are not supported yet on Node 7.1.0.",
- ],
- },
- ],
- })
-)