diff --git a/docs/src/rules/no-obj-calls.md b/docs/src/rules/no-obj-calls.md index da4383989d8..8d72e4ce277 100644 --- a/docs/src/rules/no-obj-calls.md +++ b/docs/src/rules/no-obj-calls.md @@ -17,13 +17,17 @@ The [ECMAScript 2015 specification](https://www.ecma-international.org/ecma-262/ > The Reflect object also does not have a `[[Call]]` internal method; it is not possible to invoke the Reflect object as a function. -And the [ECMAScript 2017 specification](https://www.ecma-international.org/ecma-262/8.0/index.html#sec-atomics-object) makes it clear that `Atomics` cannot be invoked: +The [ECMAScript 2017 specification](https://www.ecma-international.org/ecma-262/8.0/index.html#sec-atomics-object) makes it clear that `Atomics` cannot be invoked: > The Atomics object does not have a `[[Call]]` internal method; it is not possible to invoke the Atomics object as a function. +And the [ECMAScript Internationalization API Specification](https://tc39.es/ecma402/#intl-object) makes it clear that `Intl` cannot be invoked: + +> The Intl object does not have a `[[Call]]` internal method; it is not possible to invoke the Intl object as a function. + ## Rule Details -This rule disallows calling the `Math`, `JSON`, `Reflect` and `Atomics` objects as functions. +This rule disallows calling the `Math`, `JSON`, `Reflect`, `Atomics` and `Intl` objects as functions. This rule also disallows using these objects as constructors with the `new` operator. @@ -33,7 +37,7 @@ Examples of **incorrect** code for this rule: ```js /*eslint no-obj-calls: "error"*/ -/*eslint-env es2017*/ +/*eslint-env es2017, browser */ var math = Math(); @@ -50,6 +54,10 @@ var newReflect = new Reflect(); var atomics = Atomics(); var newAtomics = new Atomics(); + +var intl = Intl(); + +var newIntl = new Intl(); ``` ::: @@ -60,7 +68,7 @@ Examples of **correct** code for this rule: ```js /*eslint no-obj-calls: "error"*/ -/*eslint-env es2017*/ +/*eslint-env es2017, browser*/ function area(r) { return Math.PI * r * r; @@ -71,6 +79,8 @@ var object = JSON.parse("{}"); var value = Reflect.get({ x: 1, y: 2 }, "x"); var first = Atomics.load(foo, 0); + +var segmenterFr = new Intl.Segmenter("fr", { granularity: "word" }); ``` ::: diff --git a/lib/rules/no-obj-calls.js b/lib/rules/no-obj-calls.js index 86355d85d36..d24d28589f3 100644 --- a/lib/rules/no-obj-calls.js +++ b/lib/rules/no-obj-calls.js @@ -16,7 +16,7 @@ const getPropertyName = require("./utils/ast-utils").getStaticPropertyName; // Helpers //------------------------------------------------------------------------------ -const nonCallableGlobals = ["Atomics", "JSON", "Math", "Reflect"]; +const nonCallableGlobals = ["Atomics", "JSON", "Math", "Reflect", "Intl"]; /** * Returns the name of the node to report diff --git a/tests/lib/rules/no-obj-calls.js b/tests/lib/rules/no-obj-calls.js index 6270e7a7280..febb13fda03 100644 --- a/tests/lib/rules/no-obj-calls.js +++ b/tests/lib/rules/no-obj-calls.js @@ -45,6 +45,14 @@ ruleTester.run("no-obj-calls", rule, { code: "new Atomics.foo()", env: { es2017: true } }, + { + code: "new Intl.Segmenter()", + env: { browser: true } + }, + { + code: "Intl.foo()", + env: { browser: true } + }, { code: "globalThis.Math();", env: { es6: true } }, { code: "var x = globalThis.Math();", env: { es6: true } }, @@ -58,6 +66,8 @@ ruleTester.run("no-obj-calls", rule, { { code: "/*globals Reflect: true*/ globalThis.Reflect();", env: { es2017: true } }, { code: "var x = globalThis.Atomics();", env: { es2017: true } }, { code: "var x = globalThis.Atomics();", globals: { Atomics: false }, env: { es2017: true } }, + { code: "var x = globalThis.Intl();", env: { browser: true } }, + { code: "var x = globalThis.Intl();", globals: { Intl: false }, env: { browser: true } }, // non-existing variables "/*globals Math: off*/ Math();", @@ -78,6 +88,8 @@ ruleTester.run("no-obj-calls", rule, { code: "Atomics();", env: { es6: true } }, + "Intl()", + "new Intl()", // shadowed variables "var Math; Math();", @@ -119,6 +131,20 @@ ruleTester.run("no-obj-calls", rule, { { code: "var construct = typeof Reflect !== \"undefined\" ? Reflect.construct : undefined; construct();", globals: { Reflect: false } + }, + { + code: "function foo(Intl) { Intl(); }", + env: { browser: true } + }, + { + code: "if (foo) { const Intl = 1; Intl(); }", + parserOptions: { ecmaVersion: 2015 }, + env: { browser: true } + }, + { + code: "if (foo) { const Intl = 1; new Intl(); }", + parserOptions: { ecmaVersion: 2015 }, + env: { browser: true } } ], invalid: [ @@ -225,6 +251,24 @@ ruleTester.run("no-obj-calls", rule, { globals: { Atomics: "writable" }, errors: [{ messageId: "unexpectedCall", data: { name: "Atomics" }, type: "NewExpression" }] }, + { + code: "var x = Intl();", + env: { browser: true }, + errors: [{ messageId: "unexpectedCall", data: { name: "Intl" }, type: "CallExpression" }] + }, + { + code: "var x = new Intl();", + env: { browser: true }, + errors: [{ messageId: "unexpectedCall", data: { name: "Intl" }, type: "NewExpression" }] + }, + { + code: "/*globals Intl: true*/ Intl();", + errors: [{ messageId: "unexpectedCall", data: { name: "Intl" }, type: "CallExpression" }] + }, + { + code: "/*globals Intl: true*/ new Intl();", + errors: [{ messageId: "unexpectedCall", data: { name: "Intl" }, type: "NewExpression" }] + }, { code: "var x = globalThis.Math();", env: { es2020: true }, @@ -288,6 +332,21 @@ ruleTester.run("no-obj-calls", rule, { env: { es2020: true }, errors: [{ messageId: "unexpectedCall", data: { name: "Atomics" }, type: "CallExpression" }] }, + { + code: "var x = globalThis.Intl();", + env: { browser: true, es2020: true }, + errors: [{ messageId: "unexpectedCall", data: { name: "Intl" }, type: "CallExpression" }] + }, + { + code: "var x = new globalThis.Intl;", + env: { browser: true, es2020: true }, + errors: [{ messageId: "unexpectedCall", data: { name: "Intl" }, type: "NewExpression" }] + }, + { + code: "/*globals Intl: true*/ Intl();", + env: { browser: true, es2020: true }, + errors: [{ messageId: "unexpectedCall", data: { name: "Intl" }, type: "CallExpression" }] + }, { code: "var foo = bar ? baz: JSON; foo();", errors: [{ messageId: "unexpectedRefCall", data: { name: "foo", ref: "JSON" }, type: "CallExpression" }] @@ -316,6 +375,16 @@ ruleTester.run("no-obj-calls", rule, { env: { es2020: true, browser: true }, errors: [{ messageId: "unexpectedRefCall", data: { name: "foo", ref: "Atomics" }, type: "NewExpression" }] }, + { + code: "var foo = window.Intl; foo();", + env: { es2020: true, browser: true }, + errors: [{ messageId: "unexpectedRefCall", data: { name: "foo", ref: "Intl" }, type: "CallExpression" }] + }, + { + code: "var foo = window.Intl; new foo;", + env: { es2020: true, browser: true }, + errors: [{ messageId: "unexpectedRefCall", data: { name: "foo", ref: "Intl" }, type: "NewExpression" }] + }, // Optional chaining {