From 9ccc5c6c4179bc18e669845ed602717ccb51a0c7 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Sat, 1 Oct 2022 02:02:57 +0900 Subject: [PATCH 01/14] feat: add `no-new-noconstructor` rule --- lib/rules/no-new-noconstructor.js | 63 +++++++++++++++++++++++++ tests/lib/rules/no-new-noconstructor.js | 60 +++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 lib/rules/no-new-noconstructor.js create mode 100644 tests/lib/rules/no-new-noconstructor.js diff --git a/lib/rules/no-new-noconstructor.js b/lib/rules/no-new-noconstructor.js new file mode 100644 index 00000000000..9d380eb3ffc --- /dev/null +++ b/lib/rules/no-new-noconstructor.js @@ -0,0 +1,63 @@ +/** + * @fileoverview Rule to disallow use of the new operator with global no constructor functions + * @author Sosuke Suzuki + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const noConstructorGlobalFunctionNames = ["Symbol", "BigInt"]; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +/** @type {import('../shared/types').Rule} */ +module.exports = { + meta: { + type: "problem", + + docs: { + description: "Disallow `new` operators with global no constructor functions", + recommended: true, + url: "https://eslint.org/docs/rules/no-new-noconstructor" + }, + + schema: [], + + messages: { + noNewNoconstructor: "`{{name}}` cannot be called as a constructor." + } + }, + + create(context) { + + return { + "Program:exit"() { + const globalScope = context.getScope(); + + for (const noConstructorName of noConstructorGlobalFunctionNames) { + const variable = globalScope.set.get(noConstructorName); + + if (variable && variable.defs.length === 0) { + variable.references.forEach(ref => { + const node = ref.identifier; + const parent = node.parent; + + if (parent && parent.type === "NewExpression" && parent.callee === node) { + context.report({ + node, + messageId: "noNewNoconstructor" + }); + } + }); + } + } + } + }; + + } +}; diff --git a/tests/lib/rules/no-new-noconstructor.js b/tests/lib/rules/no-new-noconstructor.js new file mode 100644 index 00000000000..98af1a77fcd --- /dev/null +++ b/tests/lib/rules/no-new-noconstructor.js @@ -0,0 +1,60 @@ +/** + * @fileoverview Tests for the no-new-noconstructor rule + * @author Sosuke Suzuki + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const rule = require("../../../lib/rules/no-new-noconstructor"), + { RuleTester } = require("../../../lib/rule-tester"); + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +const ruleTester = new RuleTester({ env: { es2022: true } }); + +ruleTester.run("no-new-noconstructor", rule, { + valid: [ + + // Symbol + "var foo = Symbol('foo');", + "function bar(Symbol) { var baz = new Symbol('baz');}", + "function Symbol() {} new Symbol();", + "new foo(Symbol);", + "new foo(bar, Symbol);", + + // BigInt + "var foo = BigInt(9007199254740991);", + "function bar(BigInt) { var baz = new BigInt(9007199254740991);}", + "function BigInt() {} new BigInt();", + "new foo(BigInt);", + "new foo(bar, BigInt);" + ], + invalid: [ + + // Symbol + { + code: "var foo = new Symbol('foo');", + errors: [{ messageId: "noNewNoconstructor" }] + }, + { + code: "function bar() { return function Symbol() {}; } var baz = new Symbol('baz');", + errors: [{ messageId: "noNewNoconstructor" }] + }, + + // BigInt + { + code: "var foo = new BigInt(9007199254740991);", + errors: [{ messageId: "noNewNoconstructor" }] + }, + { + code: "function bar() { return function BigInt() {}; } var baz = new BigInt(9007199254740991);", + errors: [{ messageId: "noNewNoconstructor" }] + } + ] +}); From 6cde95aaebe1028cef64ad14e9e5e024c7eafc8f Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Sat, 1 Oct 2022 02:51:10 +0900 Subject: [PATCH 02/14] docs: add docs for `no-new-noconstructor` --- docs/src/_data/further_reading_links.json | 14 +++++ docs/src/rules/no-new-noconstructor.md | 72 +++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 docs/src/rules/no-new-noconstructor.md diff --git a/docs/src/_data/further_reading_links.json b/docs/src/_data/further_reading_links.json index dc81f7f1640..2c6d0513230 100644 --- a/docs/src/_data/further_reading_links.json +++ b/docs/src/_data/further_reading_links.json @@ -698,5 +698,19 @@ "logo": "https://eslint.org/apple-touch-icon.png", "title": "Interesting bugs caught by no-constant-binary-expression - ESLint - Pluggable JavaScript Linter", "description": "A pluggable and configurable linter tool for identifying and reporting on patterns in JavaScript. Maintain your code quality with ease." + }, + "https://tc39.es/ecma262/#sec-symbol-object": { + "domain": "tc39.es", + "url": "https://tc39.es/ecma262/#sec-symbol-object", + "logo": "https://tc39.es/ecma262/img/favicon.ico", + "title": "ECMAScript® 2023 Language Specification", + "description": null + }, + "https://tc39.es/ecma262/#sec-bigint-object": { + "domain": "tc39.es", + "url": "https://tc39.es/ecma262/#sec-bigint-object", + "logo": "https://tc39.es/ecma262/img/favicon.ico", + "title": "ECMAScript® 2023 Language Specification", + "description": null } } \ No newline at end of file diff --git a/docs/src/rules/no-new-noconstructor.md b/docs/src/rules/no-new-noconstructor.md new file mode 100644 index 00000000000..1a0073ec94b --- /dev/null +++ b/docs/src/rules/no-new-noconstructor.md @@ -0,0 +1,72 @@ +--- +title: no-new-noconstructor +layout: doc +rule_type: problem +further_reading: +- https://tc39.es/ecma262/#sec-symbol-object +- https://tc39.es/ecma262/#sec-bigint-object +--- + + + +Certain functions are not intended to be used with the `new` operator, but to be called as a function. + +```js +var foo = new Symbol("foo"); +``` + +```js +var bar = new BigInt(9007199254740991) +``` + +These throw a `TypeError` exception. + +## Rule Details + +This rule is aimed at preventing the accidental calling of certain functions with the `new` operator. These functions are: + +* `Symbol` +* `BigInt` + +## Examples + +Examples of **incorrect** code for this rule: + +::: incorrect + +```js +/*eslint no-new-noconstructor: "error"*/ +/*eslint-env es2022*/ + +var foo = new Symbol('foo'); +var bar = new BigInt(9007199254740991); +``` + +::: + +Examples of **correct** code for this rule: + +::: correct + +```js +/*eslint no-new-symbol: "error"*/ +/*eslint-env es2022*/ + +var foo = Symbol('foo'); +var bar = new BigInt(9007199254740991); + +// Ignores shadowed Symbol. +function baz(Symbol) { + const qux = new Symbol("baz"); +} +function quux(BigInt) { + const corge = new BigInt(9007199254740991); +} + +``` + +::: + +## When Not To Use It + +This rule should not be used in ES3/5 environments. From 9263431b8e8e8a4cf01137499a203883dd42a95a Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Sat, 1 Oct 2022 02:53:43 +0900 Subject: [PATCH 03/14] fix: pass constructor name to message --- lib/rules/no-new-noconstructor.js | 3 ++- tests/lib/rules/no-new-noconstructor.js | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/rules/no-new-noconstructor.js b/lib/rules/no-new-noconstructor.js index 9d380eb3ffc..263ce49e1d0 100644 --- a/lib/rules/no-new-noconstructor.js +++ b/lib/rules/no-new-noconstructor.js @@ -50,7 +50,8 @@ module.exports = { if (parent && parent.type === "NewExpression" && parent.callee === node) { context.report({ node, - messageId: "noNewNoconstructor" + messageId: "noNewNoconstructor", + data: { name: noConstructorName } }); } }); diff --git a/tests/lib/rules/no-new-noconstructor.js b/tests/lib/rules/no-new-noconstructor.js index 98af1a77fcd..949934de711 100644 --- a/tests/lib/rules/no-new-noconstructor.js +++ b/tests/lib/rules/no-new-noconstructor.js @@ -40,21 +40,29 @@ ruleTester.run("no-new-noconstructor", rule, { // Symbol { code: "var foo = new Symbol('foo');", - errors: [{ messageId: "noNewNoconstructor" }] + errors: [{ + message: "`Symbol` cannot be called as a constructor." + }] }, { code: "function bar() { return function Symbol() {}; } var baz = new Symbol('baz');", - errors: [{ messageId: "noNewNoconstructor" }] + errors: [{ + message: "`Symbol` cannot be called as a constructor." + }] }, // BigInt { code: "var foo = new BigInt(9007199254740991);", - errors: [{ messageId: "noNewNoconstructor" }] + errors: [{ + message: "`BigInt` cannot be called as a constructor." + }] }, { code: "function bar() { return function BigInt() {}; } var baz = new BigInt(9007199254740991);", - errors: [{ messageId: "noNewNoconstructor" }] + errors: [{ + message: "`BigInt` cannot be called as a constructor." + }] } ] }); From ab55170ecf6a6ff5395c4318649a2806d0c589ad Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Sat, 1 Oct 2022 02:55:02 +0900 Subject: [PATCH 04/14] docs: add `related_rules` --- docs/src/rules/no-new-noconstructor.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/src/rules/no-new-noconstructor.md b/docs/src/rules/no-new-noconstructor.md index 1a0073ec94b..9233935cc72 100644 --- a/docs/src/rules/no-new-noconstructor.md +++ b/docs/src/rules/no-new-noconstructor.md @@ -2,6 +2,8 @@ title: no-new-noconstructor layout: doc rule_type: problem +related_rules: +- no-new-symbol further_reading: - https://tc39.es/ecma262/#sec-symbol-object - https://tc39.es/ecma262/#sec-bigint-object From 48ef5e5861360959835e1717fde35fda4bba9c25 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Sat, 1 Oct 2022 03:03:52 +0900 Subject: [PATCH 05/14] chore: add new rule --- lib/rules/index.js | 1 + tools/rule-types.json | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/rules/index.js b/lib/rules/index.js index 565648c09e8..e86446b852d 100644 --- a/lib/rules/index.js +++ b/lib/rules/index.js @@ -167,6 +167,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({ "no-nested-ternary": () => require("./no-nested-ternary"), "no-new": () => require("./no-new"), "no-new-func": () => require("./no-new-func"), + "no-new-noconstructor": () => require("./no-new-noconstructor"), "no-new-object": () => require("./no-new-object"), "no-new-require": () => require("./no-new-require"), "no-new-symbol": () => require("./no-new-symbol"), diff --git a/tools/rule-types.json b/tools/rule-types.json index 9867d6b2f33..064a2f3f5f7 100644 --- a/tools/rule-types.json +++ b/tools/rule-types.json @@ -154,6 +154,7 @@ "no-nested-ternary": "suggestion", "no-new": "suggestion", "no-new-func": "suggestion", + "no-new-noconstructor": "problem", "no-new-object": "suggestion", "no-new-require": "suggestion", "no-new-symbol": "problem", From 1467efe5cdbca23594512df18ba37bf843a5e5d6 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Sat, 1 Oct 2022 03:08:20 +0900 Subject: [PATCH 06/14] fix: rename `noconstructor` -> `nonconstructor` --- ...w-noconstructor.md => no-new-nonconstructor.md} | 4 ++-- lib/rules/index.js | 2 +- ...w-noconstructor.js => no-new-nonconstructor.js} | 14 +++++++------- ...w-noconstructor.js => no-new-nonconstructor.js} | 6 +++--- tools/rule-types.json | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) rename docs/src/rules/{no-new-noconstructor.md => no-new-nonconstructor.md} (94%) rename lib/rules/{no-new-noconstructor.js => no-new-nonconstructor.js} (74%) rename tests/lib/rules/{no-new-noconstructor.js => no-new-nonconstructor.js} (91%) diff --git a/docs/src/rules/no-new-noconstructor.md b/docs/src/rules/no-new-nonconstructor.md similarity index 94% rename from docs/src/rules/no-new-noconstructor.md rename to docs/src/rules/no-new-nonconstructor.md index 9233935cc72..5c4e4d26803 100644 --- a/docs/src/rules/no-new-noconstructor.md +++ b/docs/src/rules/no-new-nonconstructor.md @@ -1,5 +1,5 @@ --- -title: no-new-noconstructor +title: no-new-nonconstructor layout: doc rule_type: problem related_rules: @@ -37,7 +37,7 @@ Examples of **incorrect** code for this rule: ::: incorrect ```js -/*eslint no-new-noconstructor: "error"*/ +/*eslint no-new-nonconstructor: "error"*/ /*eslint-env es2022*/ var foo = new Symbol('foo'); diff --git a/lib/rules/index.js b/lib/rules/index.js index e86446b852d..02eed58e590 100644 --- a/lib/rules/index.js +++ b/lib/rules/index.js @@ -167,7 +167,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({ "no-nested-ternary": () => require("./no-nested-ternary"), "no-new": () => require("./no-new"), "no-new-func": () => require("./no-new-func"), - "no-new-noconstructor": () => require("./no-new-noconstructor"), + "no-new-nonconstructor": () => require("./no-new-nonconstructor"), "no-new-object": () => require("./no-new-object"), "no-new-require": () => require("./no-new-require"), "no-new-symbol": () => require("./no-new-symbol"), diff --git a/lib/rules/no-new-noconstructor.js b/lib/rules/no-new-nonconstructor.js similarity index 74% rename from lib/rules/no-new-noconstructor.js rename to lib/rules/no-new-nonconstructor.js index 263ce49e1d0..4889f191009 100644 --- a/lib/rules/no-new-noconstructor.js +++ b/lib/rules/no-new-nonconstructor.js @@ -9,7 +9,7 @@ // Helpers //------------------------------------------------------------------------------ -const noConstructorGlobalFunctionNames = ["Symbol", "BigInt"]; +const nonConstructorGlobalFunctionNames = ["Symbol", "BigInt"]; //------------------------------------------------------------------------------ // Rule Definition @@ -23,13 +23,13 @@ module.exports = { docs: { description: "Disallow `new` operators with global no constructor functions", recommended: true, - url: "https://eslint.org/docs/rules/no-new-noconstructor" + url: "https://eslint.org/docs/rules/no-new-nonconstructor" }, schema: [], messages: { - noNewNoconstructor: "`{{name}}` cannot be called as a constructor." + noNewNonconstructor: "`{{name}}` cannot be called as a constructor." } }, @@ -39,8 +39,8 @@ module.exports = { "Program:exit"() { const globalScope = context.getScope(); - for (const noConstructorName of noConstructorGlobalFunctionNames) { - const variable = globalScope.set.get(noConstructorName); + for (const nonConstructorName of nonConstructorGlobalFunctionNames) { + const variable = globalScope.set.get(nonConstructorName); if (variable && variable.defs.length === 0) { variable.references.forEach(ref => { @@ -50,8 +50,8 @@ module.exports = { if (parent && parent.type === "NewExpression" && parent.callee === node) { context.report({ node, - messageId: "noNewNoconstructor", - data: { name: noConstructorName } + messageId: "noNewNonconstructor", + data: { name: nonConstructorName } }); } }); diff --git a/tests/lib/rules/no-new-noconstructor.js b/tests/lib/rules/no-new-nonconstructor.js similarity index 91% rename from tests/lib/rules/no-new-noconstructor.js rename to tests/lib/rules/no-new-nonconstructor.js index 949934de711..120724ed9f5 100644 --- a/tests/lib/rules/no-new-noconstructor.js +++ b/tests/lib/rules/no-new-nonconstructor.js @@ -1,5 +1,5 @@ /** - * @fileoverview Tests for the no-new-noconstructor rule + * @fileoverview Tests for the no-new-nonconstructor rule * @author Sosuke Suzuki */ @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -const rule = require("../../../lib/rules/no-new-noconstructor"), +const rule = require("../../../lib/rules/no-new-nonconstructor"), { RuleTester } = require("../../../lib/rule-tester"); //------------------------------------------------------------------------------ @@ -18,7 +18,7 @@ const rule = require("../../../lib/rules/no-new-noconstructor"), const ruleTester = new RuleTester({ env: { es2022: true } }); -ruleTester.run("no-new-noconstructor", rule, { +ruleTester.run("no-new-nonconstructor", rule, { valid: [ // Symbol diff --git a/tools/rule-types.json b/tools/rule-types.json index 064a2f3f5f7..8ee5c958110 100644 --- a/tools/rule-types.json +++ b/tools/rule-types.json @@ -154,7 +154,7 @@ "no-nested-ternary": "suggestion", "no-new": "suggestion", "no-new-func": "suggestion", - "no-new-noconstructor": "problem", + "no-new-nonconstructor": "problem", "no-new-object": "suggestion", "no-new-require": "suggestion", "no-new-symbol": "problem", From e1138b4f06d592db55399e23b47b5c0d5343b7b7 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Sat, 1 Oct 2022 03:37:27 +0900 Subject: [PATCH 07/14] fix: set `recommended: false` --- lib/rules/no-new-nonconstructor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rules/no-new-nonconstructor.js b/lib/rules/no-new-nonconstructor.js index 4889f191009..5215d45fc0f 100644 --- a/lib/rules/no-new-nonconstructor.js +++ b/lib/rules/no-new-nonconstructor.js @@ -22,7 +22,7 @@ module.exports = { docs: { description: "Disallow `new` operators with global no constructor functions", - recommended: true, + recommended: false, url: "https://eslint.org/docs/rules/no-new-nonconstructor" }, From b79aac499e9de0d9ea743e11af6fb8e4c1dd6e59 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Wed, 26 Oct 2022 11:45:15 +0900 Subject: [PATCH 08/14] fix: rename `no-new-nonconstructor` -> `no-new-native-nonconstructor` --- ...ew-nonconstructor.md => no-new-native-nonconstructor.md} | 4 ++-- lib/rules/index.js | 2 +- ...ew-nonconstructor.js => no-new-native-nonconstructor.js} | 2 +- ...ew-nonconstructor.js => no-new-native-nonconstructor.js} | 6 +++--- tools/rule-types.json | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) rename docs/src/rules/{no-new-nonconstructor.md => no-new-native-nonconstructor.md} (93%) rename lib/rules/{no-new-nonconstructor.js => no-new-native-nonconstructor.js} (96%) rename tests/lib/rules/{no-new-nonconstructor.js => no-new-native-nonconstructor.js} (90%) diff --git a/docs/src/rules/no-new-nonconstructor.md b/docs/src/rules/no-new-native-nonconstructor.md similarity index 93% rename from docs/src/rules/no-new-nonconstructor.md rename to docs/src/rules/no-new-native-nonconstructor.md index 5c4e4d26803..580e0aed7d1 100644 --- a/docs/src/rules/no-new-nonconstructor.md +++ b/docs/src/rules/no-new-native-nonconstructor.md @@ -1,5 +1,5 @@ --- -title: no-new-nonconstructor +title: no-new-native-nonconstructor layout: doc rule_type: problem related_rules: @@ -37,7 +37,7 @@ Examples of **incorrect** code for this rule: ::: incorrect ```js -/*eslint no-new-nonconstructor: "error"*/ +/*eslint no-new-native-nonconstructor: "error"*/ /*eslint-env es2022*/ var foo = new Symbol('foo'); diff --git a/lib/rules/index.js b/lib/rules/index.js index 02eed58e590..ddd28b49a18 100644 --- a/lib/rules/index.js +++ b/lib/rules/index.js @@ -167,7 +167,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({ "no-nested-ternary": () => require("./no-nested-ternary"), "no-new": () => require("./no-new"), "no-new-func": () => require("./no-new-func"), - "no-new-nonconstructor": () => require("./no-new-nonconstructor"), + "no-new-native-nonconstructor": () => require("./no-new-native-nonconstructor"), "no-new-object": () => require("./no-new-object"), "no-new-require": () => require("./no-new-require"), "no-new-symbol": () => require("./no-new-symbol"), diff --git a/lib/rules/no-new-nonconstructor.js b/lib/rules/no-new-native-nonconstructor.js similarity index 96% rename from lib/rules/no-new-nonconstructor.js rename to lib/rules/no-new-native-nonconstructor.js index 5215d45fc0f..b4e870e5375 100644 --- a/lib/rules/no-new-nonconstructor.js +++ b/lib/rules/no-new-native-nonconstructor.js @@ -23,7 +23,7 @@ module.exports = { docs: { description: "Disallow `new` operators with global no constructor functions", recommended: false, - url: "https://eslint.org/docs/rules/no-new-nonconstructor" + url: "https://eslint.org/docs/rules/no-new-native-nonconstructor" }, schema: [], diff --git a/tests/lib/rules/no-new-nonconstructor.js b/tests/lib/rules/no-new-native-nonconstructor.js similarity index 90% rename from tests/lib/rules/no-new-nonconstructor.js rename to tests/lib/rules/no-new-native-nonconstructor.js index 120724ed9f5..9637ad79959 100644 --- a/tests/lib/rules/no-new-nonconstructor.js +++ b/tests/lib/rules/no-new-native-nonconstructor.js @@ -1,5 +1,5 @@ /** - * @fileoverview Tests for the no-new-nonconstructor rule + * @fileoverview Tests for the no-new-native-nonconstructor rule * @author Sosuke Suzuki */ @@ -9,7 +9,7 @@ // Requirements //------------------------------------------------------------------------------ -const rule = require("../../../lib/rules/no-new-nonconstructor"), +const rule = require("../../../lib/rules/no-new-native-nonconstructor"), { RuleTester } = require("../../../lib/rule-tester"); //------------------------------------------------------------------------------ @@ -18,7 +18,7 @@ const rule = require("../../../lib/rules/no-new-nonconstructor"), const ruleTester = new RuleTester({ env: { es2022: true } }); -ruleTester.run("no-new-nonconstructor", rule, { +ruleTester.run("no-new-native-nonconstructor", rule, { valid: [ // Symbol diff --git a/tools/rule-types.json b/tools/rule-types.json index 8ee5c958110..2ce5a326960 100644 --- a/tools/rule-types.json +++ b/tools/rule-types.json @@ -154,7 +154,7 @@ "no-nested-ternary": "suggestion", "no-new": "suggestion", "no-new-func": "suggestion", - "no-new-nonconstructor": "problem", + "no-new-native-nonconstructor": "problem", "no-new-object": "suggestion", "no-new-require": "suggestion", "no-new-symbol": "problem", From 0349065c1cdcc3e05f7ac9c9acbbab95470f2083 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Thu, 27 Oct 2022 15:34:35 +0900 Subject: [PATCH 09/14] docs: fix correct example --- docs/src/rules/no-new-native-nonconstructor.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/rules/no-new-native-nonconstructor.md b/docs/src/rules/no-new-native-nonconstructor.md index 580e0aed7d1..87b95f54a05 100644 --- a/docs/src/rules/no-new-native-nonconstructor.md +++ b/docs/src/rules/no-new-native-nonconstructor.md @@ -55,7 +55,7 @@ Examples of **correct** code for this rule: /*eslint-env es2022*/ var foo = Symbol('foo'); -var bar = new BigInt(9007199254740991); +var bar = BigInt(9007199254740991); // Ignores shadowed Symbol. function baz(Symbol) { From f15fd209516d4c76d0de0355a5e5683c84cfe378 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Thu, 27 Oct 2022 15:35:33 +0900 Subject: [PATCH 10/14] Update docs/src/rules/no-new-native-nonconstructor.md Co-authored-by: Milos Djermanovic --- docs/src/rules/no-new-native-nonconstructor.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/rules/no-new-native-nonconstructor.md b/docs/src/rules/no-new-native-nonconstructor.md index 87b95f54a05..62c6bd04790 100644 --- a/docs/src/rules/no-new-native-nonconstructor.md +++ b/docs/src/rules/no-new-native-nonconstructor.md @@ -5,8 +5,8 @@ rule_type: problem related_rules: - no-new-symbol further_reading: -- https://tc39.es/ecma262/#sec-symbol-object -- https://tc39.es/ecma262/#sec-bigint-object +- https://tc39.es/ecma262/#sec-symbol-constructor +- https://tc39.es/ecma262/#sec-bigint-constructor --- From 5eed2d68dd26524eae840caf990ed643d49f94c4 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Sat, 29 Oct 2022 15:52:39 +0900 Subject: [PATCH 11/14] docs: update links --- docs/src/_data/further_reading_links.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/src/_data/further_reading_links.json b/docs/src/_data/further_reading_links.json index 2c6d0513230..938b40fb6f3 100644 --- a/docs/src/_data/further_reading_links.json +++ b/docs/src/_data/further_reading_links.json @@ -699,16 +699,16 @@ "title": "Interesting bugs caught by no-constant-binary-expression - ESLint - Pluggable JavaScript Linter", "description": "A pluggable and configurable linter tool for identifying and reporting on patterns in JavaScript. Maintain your code quality with ease." }, - "https://tc39.es/ecma262/#sec-symbol-object": { + "https://tc39.es/ecma262/#sec-symbol-constructor": { "domain": "tc39.es", - "url": "https://tc39.es/ecma262/#sec-symbol-object", + "url": "https://tc39.es/ecma262/#sec-symbol-constructor", "logo": "https://tc39.es/ecma262/img/favicon.ico", "title": "ECMAScript® 2023 Language Specification", "description": null }, - "https://tc39.es/ecma262/#sec-bigint-object": { + "https://tc39.es/ecma262/#sec-bigint-constructor": { "domain": "tc39.es", - "url": "https://tc39.es/ecma262/#sec-bigint-object", + "url": "https://tc39.es/ecma262/#sec-bigint-constructor", "logo": "https://tc39.es/ecma262/img/favicon.ico", "title": "ECMAScript® 2023 Language Specification", "description": null From 410b3480b7e992a30e63d17287d4bd118c64d7e6 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Sun, 30 Oct 2022 11:58:44 +0900 Subject: [PATCH 12/14] docs: address reviews --- docs/src/rules/no-new-native-nonconstructor.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/rules/no-new-native-nonconstructor.md b/docs/src/rules/no-new-native-nonconstructor.md index 62c6bd04790..ba45b464be2 100644 --- a/docs/src/rules/no-new-native-nonconstructor.md +++ b/docs/src/rules/no-new-native-nonconstructor.md @@ -3,7 +3,7 @@ title: no-new-native-nonconstructor layout: doc rule_type: problem related_rules: -- no-new-symbol +- no-obj-calls further_reading: - https://tc39.es/ecma262/#sec-symbol-constructor - https://tc39.es/ecma262/#sec-bigint-constructor @@ -18,7 +18,7 @@ var foo = new Symbol("foo"); ``` ```js -var bar = new BigInt(9007199254740991) +var bar = new BigInt(9007199254740991); ``` These throw a `TypeError` exception. @@ -51,7 +51,7 @@ Examples of **correct** code for this rule: ::: correct ```js -/*eslint no-new-symbol: "error"*/ +/*eslint no-new-native-nonconstructor: "error"*/ /*eslint-env es2022*/ var foo = Symbol('foo'); From aa6f7014656529b05c29018acf77afcb215bce56 Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Sun, 30 Oct 2022 12:00:48 +0900 Subject: [PATCH 13/14] fix: `no constructor` -> `non-constructor` --- lib/rules/no-new-native-nonconstructor.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rules/no-new-native-nonconstructor.js b/lib/rules/no-new-native-nonconstructor.js index b4e870e5375..a8405002b7f 100644 --- a/lib/rules/no-new-native-nonconstructor.js +++ b/lib/rules/no-new-native-nonconstructor.js @@ -1,5 +1,5 @@ /** - * @fileoverview Rule to disallow use of the new operator with global no constructor functions + * @fileoverview Rule to disallow use of the new operator with global non-constructor functions * @author Sosuke Suzuki */ @@ -21,7 +21,7 @@ module.exports = { type: "problem", docs: { - description: "Disallow `new` operators with global no constructor functions", + description: "Disallow `new` operators with global non-constructor functions", recommended: false, url: "https://eslint.org/docs/rules/no-new-native-nonconstructor" }, From 14489ad99a63433ff83e77592e9c171aee235b8d Mon Sep 17 00:00:00 2001 From: Sosuke Suzuki Date: Wed, 2 Nov 2022 02:07:31 +0900 Subject: [PATCH 14/14] Apply suggestions from code review Co-authored-by: Nicholas C. Zakas --- docs/src/rules/no-new-native-nonconstructor.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/src/rules/no-new-native-nonconstructor.md b/docs/src/rules/no-new-native-nonconstructor.md index ba45b464be2..18a73a22bf9 100644 --- a/docs/src/rules/no-new-native-nonconstructor.md +++ b/docs/src/rules/no-new-native-nonconstructor.md @@ -11,21 +11,20 @@ further_reading: -Certain functions are not intended to be used with the `new` operator, but to be called as a function. +It is a convention in JavaScript that global variables beginning with an uppercase letter typically represent classes that can be instantiated using the `new` operator, such as `new Array` and `new Map`. Confusingly, JavaScript also provides some global variables that begin with an uppercase letter that cannot be called using the `new` operator and will throw an error if you attempt to do so. These are typically functions that are related to data types and are easy to mistake for classes. Consider the following example: ```js -var foo = new Symbol("foo"); -``` +// throws a TypeError +let foo = new Symbol("foo"); -```js -var bar = new BigInt(9007199254740991); -``` +// throws a TypeError +let result = new BigInt(9007199254740991); -These throw a `TypeError` exception. +Both `new Symbol` and `new BigInt` throw a type error because they are functions and not classes. It is easy to make this mistake by assuming the uppercase letters indicate classes. ## Rule Details -This rule is aimed at preventing the accidental calling of certain functions with the `new` operator. These functions are: +This rule is aimed at preventing the accidental calling of native JavaScript global functions with the `new` operator. These functions are: * `Symbol` * `BigInt`