From e49cbe4d48a5bd6fbedd5d3767d20edfbfc648a4 Mon Sep 17 00:00:00 2001 From: Denis Bezrukov <6227442+denbezrukov@users.noreply.github.com> Date: Sat, 7 Jan 2023 12:06:43 +0200 Subject: [PATCH] feat(rome_js_analyze): noGlobalObjectCalls, no-obj-calls #3977 (#4103) --- .../src/categories.rs | 1 + .../rome_js_analyze/src/analyzers/nursery.rs | 3 +- .../nursery/no_global_object_calls.rs | 203 +++ .../nursery/noGlobalObjectCalls/invalid.js | 111 ++ .../noGlobalObjectCalls/invalid.js.snap | 1451 +++++++++++++++++ .../nursery/noGlobalObjectCalls/valid.js | 45 + .../nursery/noGlobalObjectCalls/valid.js.snap | 55 + .../noGlobalObjectCalls/valid_import.js | 2 + .../noGlobalObjectCalls/valid_import.js.snap | 12 + crates/rome_js_syntax/src/expr_ext.rs | 14 + .../src/configuration/linter/rules.rs | 25 +- editors/vscode/configuration_schema.json | 11 + npm/backend-jsonrpc/src/workspace.ts | 5 + npm/rome/configuration_schema.json | 11 + website/src/pages/lint/rules/index.mdx | 6 + .../pages/lint/rules/noGlobalObjectCalls.md | 188 +++ 16 files changed, 2132 insertions(+), 11 deletions(-) create mode 100644 crates/rome_js_analyze/src/analyzers/nursery/no_global_object_calls.rs create mode 100644 crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/invalid.js create mode 100644 crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/invalid.js.snap create mode 100644 crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/valid.js create mode 100644 crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/valid.js.snap create mode 100644 crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/valid_import.js create mode 100644 crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/valid_import.js.snap create mode 100644 website/src/pages/lint/rules/noGlobalObjectCalls.md diff --git a/crates/rome_diagnostics_categories/src/categories.rs b/crates/rome_diagnostics_categories/src/categories.rs index 5c0c197b41d..4fd57049c31 100644 --- a/crates/rome_diagnostics_categories/src/categories.rs +++ b/crates/rome_diagnostics_categories/src/categories.rs @@ -94,6 +94,7 @@ define_dategories! { "lint/nursery/useHookAtTopLevel": "https://docs.rome.tools/lint/rules/useHookAtTopLevel", "lint/nursery/noDuplicateJsxProps": "https://docs.rome.tools/lint/rules/noDuplicateJsxProps", "lint/nursery/useYield": "https://docs.rome.tools/lint/rules/useYield", + "lint/nursery/noGlobalObjectCalls": "https://docs.rome.tools/lint/rules/noGlobalObjectCalls", // Insert new nursery rule here // performance diff --git a/crates/rome_js_analyze/src/analyzers/nursery.rs b/crates/rome_js_analyze/src/analyzers/nursery.rs index 2f9ea994520..ddc9e321e3b 100644 --- a/crates/rome_js_analyze/src/analyzers/nursery.rs +++ b/crates/rome_js_analyze/src/analyzers/nursery.rs @@ -14,6 +14,7 @@ mod no_duplicate_object_keys; mod no_empty_interface; mod no_extra_non_null_assertion; mod no_extra_semicolons; +mod no_global_object_calls; mod no_header_scope; mod no_inner_declarations; mod no_invalid_constructor_super; @@ -38,4 +39,4 @@ mod use_is_nan; mod use_media_caption; mod use_numeric_literals; mod use_yield; -declare_group! { pub (crate) Nursery { name : "nursery" , rules : [self :: no_access_key :: NoAccessKey , self :: no_assign_in_expressions :: NoAssignInExpressions , self :: no_banned_types :: NoBannedTypes , self :: no_comma_operator :: NoCommaOperator , self :: no_const_enum :: NoConstEnum , self :: no_constructor_return :: NoConstructorReturn , self :: no_distracting_elements :: NoDistractingElements , self :: no_duplicate_case :: NoDuplicateCase , self :: no_duplicate_jsx_props :: NoDuplicateJsxProps , self :: no_duplicate_object_keys :: NoDuplicateObjectKeys , self :: no_empty_interface :: NoEmptyInterface , self :: no_extra_non_null_assertion :: NoExtraNonNullAssertion , self :: no_extra_semicolons :: NoExtraSemicolons , self :: no_header_scope :: NoHeaderScope , self :: no_inner_declarations :: NoInnerDeclarations , self :: no_invalid_constructor_super :: NoInvalidConstructorSuper , self :: no_non_null_assertion :: NoNonNullAssertion , self :: no_precision_loss :: NoPrecisionLoss , self :: no_redundant_alt :: NoRedundantAlt , self :: no_redundant_use_strict :: NoRedundantUseStrict , self :: no_self_compare :: NoSelfCompare , self :: no_setter_return :: NoSetterReturn , self :: no_string_case_mismatch :: NoStringCaseMismatch , self :: no_unreachable_super :: NoUnreachableSuper , self :: no_unsafe_finally :: NoUnsafeFinally , self :: no_unused_labels :: NoUnusedLabels , self :: no_useless_switch_case :: NoUselessSwitchCase , self :: no_void_type_return :: NoVoidTypeReturn , self :: no_with :: NoWith , self :: use_default_parameter_last :: UseDefaultParameterLast , self :: use_default_switch_clause_last :: UseDefaultSwitchClauseLast , self :: use_enum_initializers :: UseEnumInitializers , self :: use_exponentiation_operator :: UseExponentiationOperator , self :: use_is_nan :: UseIsNan , self :: use_media_caption :: UseMediaCaption , self :: use_numeric_literals :: UseNumericLiterals , self :: use_yield :: UseYield ,] } } +declare_group! { pub (crate) Nursery { name : "nursery" , rules : [self :: no_access_key :: NoAccessKey , self :: no_assign_in_expressions :: NoAssignInExpressions , self :: no_banned_types :: NoBannedTypes , self :: no_comma_operator :: NoCommaOperator , self :: no_const_enum :: NoConstEnum , self :: no_constructor_return :: NoConstructorReturn , self :: no_distracting_elements :: NoDistractingElements , self :: no_duplicate_case :: NoDuplicateCase , self :: no_duplicate_jsx_props :: NoDuplicateJsxProps , self :: no_duplicate_object_keys :: NoDuplicateObjectKeys , self :: no_empty_interface :: NoEmptyInterface , self :: no_extra_non_null_assertion :: NoExtraNonNullAssertion , self :: no_extra_semicolons :: NoExtraSemicolons , self :: no_global_object_calls :: NoGlobalObjectCalls , self :: no_header_scope :: NoHeaderScope , self :: no_inner_declarations :: NoInnerDeclarations , self :: no_invalid_constructor_super :: NoInvalidConstructorSuper , self :: no_non_null_assertion :: NoNonNullAssertion , self :: no_precision_loss :: NoPrecisionLoss , self :: no_redundant_alt :: NoRedundantAlt , self :: no_redundant_use_strict :: NoRedundantUseStrict , self :: no_self_compare :: NoSelfCompare , self :: no_setter_return :: NoSetterReturn , self :: no_string_case_mismatch :: NoStringCaseMismatch , self :: no_unreachable_super :: NoUnreachableSuper , self :: no_unsafe_finally :: NoUnsafeFinally , self :: no_unused_labels :: NoUnusedLabels , self :: no_useless_switch_case :: NoUselessSwitchCase , self :: no_void_type_return :: NoVoidTypeReturn , self :: no_with :: NoWith , self :: use_default_parameter_last :: UseDefaultParameterLast , self :: use_default_switch_clause_last :: UseDefaultSwitchClauseLast , self :: use_enum_initializers :: UseEnumInitializers , self :: use_exponentiation_operator :: UseExponentiationOperator , self :: use_is_nan :: UseIsNan , self :: use_media_caption :: UseMediaCaption , self :: use_numeric_literals :: UseNumericLiterals , self :: use_yield :: UseYield ,] } } diff --git a/crates/rome_js_analyze/src/analyzers/nursery/no_global_object_calls.rs b/crates/rome_js_analyze/src/analyzers/nursery/no_global_object_calls.rs new file mode 100644 index 00000000000..26c63b7cafc --- /dev/null +++ b/crates/rome_js_analyze/src/analyzers/nursery/no_global_object_calls.rs @@ -0,0 +1,203 @@ +use crate::semantic_services::Semantic; +use rome_analyze::{context::RuleContext, declare_rule, Rule, RuleDiagnostic}; +use rome_console::markup; +use rome_js_syntax::{AnyJsExpression, JsCallExpression, JsNewExpression, JsSyntaxToken}; +use rome_rowan::{declare_node_union, AstNode, SyntaxResult}; +use std::str::FromStr; + +declare_rule! { + /// Disallow calling global object properties as functions + /// + /// ECMAScript provides several global objects that are intended to be used as-is. + /// Some of these objects look as if they could be constructors due their capitalization (such as Math and JSON) but will throw an error if you try to execute them as functions. + /// + /// The ECMAScript 5 specification makes it clear that both Math and JSON cannot be invoked: + /// The Math object does not have a [[Call]] internal property; it is not possible to invoke the Math object as a function. + /// + /// The ECMAScript 2015 specification makes it clear that Reflect cannot be invoked: + /// The Reflect object also does not have a [[Call]] internal method; it is not possible to invoke the Reflect object as a function. + /// + /// The ECMAScript 2017 specification 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 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. + /// + /// ## Examples + /// + /// ### Invalid + /// + /// ```js,expect_diagnostic + /// var math = Math(); + /// ``` + /// + /// ```js,expect_diagnostic + /// var newMath = new Math(); + /// ``` + /// + /// ```js,expect_diagnostic + /// var json = JSON(); + /// ``` + /// + /// ```js,expect_diagnostic + /// var newJSON = new JSON(); + /// ``` + /// + /// ```js,expect_diagnostic + /// var reflect = Reflect(); + /// ``` + /// + /// ```js,expect_diagnostic + /// var newReflect = new Reflect(); + /// ``` + /// + /// ```js,expect_diagnostic + /// var atomics = Atomics(); + /// ``` + /// + /// ```js,expect_diagnostic + /// var newAtomics = new Atomics(); + /// ``` + /// + /// ```js,expect_diagnostic + /// var intl = Intl(); + /// ``` + /// + /// ```js,expect_diagnostic + /// var newIntl = new Intl(); + /// ``` + /// + /// ## Valid + /// + /// ```js + /// function area(r) { + /// return Math.PI * r * r; + /// } + /// + /// 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" }); + /// ``` + /// + pub(crate) NoGlobalObjectCalls { + version: "12.0.0", + name: "noGlobalObjectCalls", + recommended: true, + } +} + +impl Rule for NoGlobalObjectCalls { + type Query = Semantic; + type State = JsSyntaxToken; + type Signals = Option; + type Options = (); + + fn run(ctx: &RuleContext) -> Self::Signals { + let node = ctx.query(); + let model = ctx.model(); + + let callee = node.callee().ok()?.omit_parentheses(); + + match callee { + AnyJsExpression::JsIdentifierExpression(expression) => { + let reference = expression.name().ok()?; + let token = reference.value_token().ok()?; + + // verifies that the reference is not a local variable + let is_global_call = is_non_callable_globals(token.text_trimmed()) + && model.binding(&reference).is_none(); + is_global_call.then_some(reference.value_token().ok()?) + } + AnyJsExpression::JsStaticMemberExpression(expression) => { + let object = expression.object().ok()?.omit_parentheses(); + let reference = object.as_reference_identifier()?; + + let member = expression.member().ok()?; + let name = member.as_js_name()?; + let token = name.value_token().ok()?; + + // verifies that the reference is not a local variable + let is_global_call = is_non_callable_globals(token.text_trimmed()) + && reference.is_global_this() + && model.binding(&reference).is_none(); + + is_global_call.then_some(token) + } + AnyJsExpression::JsComputedMemberExpression(expression) => { + let object = expression.object().ok()?.omit_parentheses(); + let reference = object.as_reference_identifier()?; + let member = expression.member().ok()?.omit_parentheses(); + let literal = member + .as_any_js_literal_expression()? + .as_js_string_literal_expression()?; + let name = literal.inner_string_text().ok()?; + + // verifies that the reference is not a local variable + let is_global_call = is_non_callable_globals(name.text()) + && reference.is_global_this() + && model.binding(&reference).is_none(); + + is_global_call.then_some(literal.value_token().ok()?) + } + _ => None, + } + } + + fn diagnostic(ctx: &RuleContext, token: &Self::State) -> Option { + let node = ctx.query(); + let name = token.text_trimmed(); + + Some(RuleDiagnostic::new( + rule_category!(), + node.syntax().text_trimmed_range(), + markup! { + {name}" is not a function." + }, + )) + } +} + +declare_node_union! { + /// Enum for [JsCallExpression] and [JsNewExpression] + pub(crate) QueryNode = JsNewExpression | JsCallExpression +} + +impl QueryNode { + fn callee(&self) -> SyntaxResult { + match self { + QueryNode::JsNewExpression(expression) => expression.callee(), + QueryNode::JsCallExpression(expression) => expression.callee(), + } + } +} + +#[derive(Debug, Eq, PartialEq)] +enum NonCallableGlobals { + Atomics, + Json, + Math, + Reflect, + Intl, +} + +impl FromStr for NonCallableGlobals { + type Err = String; + fn from_str(s: &str) -> Result { + match s { + "Atomics" => Ok(NonCallableGlobals::Atomics), + "JSON" => Ok(NonCallableGlobals::Json), + "Math" => Ok(NonCallableGlobals::Math), + "Reflect" => Ok(NonCallableGlobals::Reflect), + "Intl" => Ok(NonCallableGlobals::Intl), + _ => Err("non callable globals not implemented".to_string()), + } + } +} + +fn is_non_callable_globals(text: &str) -> bool { + NonCallableGlobals::from_str(text).is_ok() +} diff --git a/crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/invalid.js b/crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/invalid.js new file mode 100644 index 00000000000..17b7ba409c3 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/invalid.js @@ -0,0 +1,111 @@ +Atomics(); +JSON(); +Math(); +Reflect(); +Intl(); + +(Atomics)(); +(JSON)(); +(Math)(); +(Reflect)(); +(Intl)(); + +new Atomics(); +new JSON(); +new Math(); +new Reflect(); +new Intl(); + +new (Atomics)(); +new (JSON)(); +new (Math)(); +new (Reflect)(); +new (Intl)(); + +new Atomics; +new JSON; +new Math; +new Reflect; +new Intl; + +// globalThis static member +globalThis.Atomics(); +globalThis.JSON(); +globalThis.Math(); +globalThis.Reflect(); +globalThis.Intl(); + +(globalThis).Atomics(); +(globalThis).JSON(); +(globalThis).Math(); +(globalThis).Reflect(); +(globalThis).Intl(); + +(globalThis.Atomics)(); +(globalThis.JSON)(); +(globalThis.Math)(); +(globalThis.Reflect)(); +(globalThis.Intl)(); + +new globalThis.Atomics(); +new globalThis.JSON(); +new globalThis.Math(); +new globalThis.Reflect(); +new globalThis.Intl(); + +new (globalThis.Atomics)(); +new (globalThis.JSON)(); +new (globalThis.Math)(); +new (globalThis.Reflect)(); +new (globalThis.Intl)(); + +new globalThis.Atomics; +new globalThis.JSON; +new globalThis.Math; +new globalThis.Reflect; +new globalThis.Intl; + +// globalThis computed member +globalThis['Atomics'](); +globalThis['JSON'](); +globalThis['Math'](); +globalThis['Reflect'](); +globalThis['Intl'](); + +(globalThis)['Atomics'](); +(globalThis)['JSON'](); +(globalThis)['Math'](); +(globalThis)['Reflect'](); +(globalThis)['Intl'](); + +(globalThis['Atomics'])(); +(globalThis['JSON'])(); +(globalThis['Math'])(); +(globalThis['Reflect'])(); +(globalThis['Intl'])(); + +(globalThis[('Atomics')])(); +(globalThis[('JSON')])(); +(globalThis[('Math')])(); +(globalThis[('Reflect')])(); +(globalThis[('Intl')])(); + +new globalThis['Atomics'](); +new globalThis['JSON'](); +new globalThis['Math'](); +new globalThis['Reflect'](); +new globalThis['Intl'](); + +new (globalThis['Atomics'])(); +new (globalThis['JSON'])(); +new (globalThis['Math'])(); +new (globalThis['Reflect'])(); +new (globalThis['Intl'])(); + +new globalThis['Atomics']; +new globalThis['JSON']; +new globalThis['Math']; +new globalThis['Reflect']; +new globalThis['Intl']; + + diff --git a/crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/invalid.js.snap b/crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/invalid.js.snap new file mode 100644 index 00000000000..93a096dc85f --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/invalid.js.snap @@ -0,0 +1,1451 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +expression: invalid.js +--- +# Input +```js +Atomics(); +JSON(); +Math(); +Reflect(); +Intl(); + +(Atomics)(); +(JSON)(); +(Math)(); +(Reflect)(); +(Intl)(); + +new Atomics(); +new JSON(); +new Math(); +new Reflect(); +new Intl(); + +new (Atomics)(); +new (JSON)(); +new (Math)(); +new (Reflect)(); +new (Intl)(); + +new Atomics; +new JSON; +new Math; +new Reflect; +new Intl; + +// globalThis static member +globalThis.Atomics(); +globalThis.JSON(); +globalThis.Math(); +globalThis.Reflect(); +globalThis.Intl(); + +(globalThis).Atomics(); +(globalThis).JSON(); +(globalThis).Math(); +(globalThis).Reflect(); +(globalThis).Intl(); + +(globalThis.Atomics)(); +(globalThis.JSON)(); +(globalThis.Math)(); +(globalThis.Reflect)(); +(globalThis.Intl)(); + +new globalThis.Atomics(); +new globalThis.JSON(); +new globalThis.Math(); +new globalThis.Reflect(); +new globalThis.Intl(); + +new (globalThis.Atomics)(); +new (globalThis.JSON)(); +new (globalThis.Math)(); +new (globalThis.Reflect)(); +new (globalThis.Intl)(); + +new globalThis.Atomics; +new globalThis.JSON; +new globalThis.Math; +new globalThis.Reflect; +new globalThis.Intl; + +// globalThis computed member +globalThis['Atomics'](); +globalThis['JSON'](); +globalThis['Math'](); +globalThis['Reflect'](); +globalThis['Intl'](); + +(globalThis)['Atomics'](); +(globalThis)['JSON'](); +(globalThis)['Math'](); +(globalThis)['Reflect'](); +(globalThis)['Intl'](); + +(globalThis['Atomics'])(); +(globalThis['JSON'])(); +(globalThis['Math'])(); +(globalThis['Reflect'])(); +(globalThis['Intl'])(); + +(globalThis[('Atomics')])(); +(globalThis[('JSON')])(); +(globalThis[('Math')])(); +(globalThis[('Reflect')])(); +(globalThis[('Intl')])(); + +new globalThis['Atomics'](); +new globalThis['JSON'](); +new globalThis['Math'](); +new globalThis['Reflect'](); +new globalThis['Intl'](); + +new (globalThis['Atomics'])(); +new (globalThis['JSON'])(); +new (globalThis['Math'])(); +new (globalThis['Reflect'])(); +new (globalThis['Intl'])(); + +new globalThis['Atomics']; +new globalThis['JSON']; +new globalThis['Math']; +new globalThis['Reflect']; +new globalThis['Intl']; + + + +``` + +# Diagnostics +``` +invalid.js:1:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Atomics is not a function. + + > 1 │ Atomics(); + │ ^^^^^^^^^ + 2 │ JSON(); + 3 │ Math(); + + +``` + +``` +invalid.js:2:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! JSON is not a function. + + 1 │ Atomics(); + > 2 │ JSON(); + │ ^^^^^^ + 3 │ Math(); + 4 │ Reflect(); + + +``` + +``` +invalid.js:3:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Math is not a function. + + 1 │ Atomics(); + 2 │ JSON(); + > 3 │ Math(); + │ ^^^^^^ + 4 │ Reflect(); + 5 │ Intl(); + + +``` + +``` +invalid.js:4:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Reflect is not a function. + + 2 │ JSON(); + 3 │ Math(); + > 4 │ Reflect(); + │ ^^^^^^^^^ + 5 │ Intl(); + 6 │ + + +``` + +``` +invalid.js:5:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Intl is not a function. + + 3 │ Math(); + 4 │ Reflect(); + > 5 │ Intl(); + │ ^^^^^^ + 6 │ + 7 │ (Atomics)(); + + +``` + +``` +invalid.js:7:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Atomics is not a function. + + 5 │ Intl(); + 6 │ + > 7 │ (Atomics)(); + │ ^^^^^^^^^^^ + 8 │ (JSON)(); + 9 │ (Math)(); + + +``` + +``` +invalid.js:8:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! JSON is not a function. + + 7 │ (Atomics)(); + > 8 │ (JSON)(); + │ ^^^^^^^^ + 9 │ (Math)(); + 10 │ (Reflect)(); + + +``` + +``` +invalid.js:9:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Math is not a function. + + 7 │ (Atomics)(); + 8 │ (JSON)(); + > 9 │ (Math)(); + │ ^^^^^^^^ + 10 │ (Reflect)(); + 11 │ (Intl)(); + + +``` + +``` +invalid.js:10:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Reflect is not a function. + + 8 │ (JSON)(); + 9 │ (Math)(); + > 10 │ (Reflect)(); + │ ^^^^^^^^^^^ + 11 │ (Intl)(); + 12 │ + + +``` + +``` +invalid.js:11:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Intl is not a function. + + 9 │ (Math)(); + 10 │ (Reflect)(); + > 11 │ (Intl)(); + │ ^^^^^^^^ + 12 │ + 13 │ new Atomics(); + + +``` + +``` +invalid.js:13:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Atomics is not a function. + + 11 │ (Intl)(); + 12 │ + > 13 │ new Atomics(); + │ ^^^^^^^^^^^^^ + 14 │ new JSON(); + 15 │ new Math(); + + +``` + +``` +invalid.js:14:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! JSON is not a function. + + 13 │ new Atomics(); + > 14 │ new JSON(); + │ ^^^^^^^^^^ + 15 │ new Math(); + 16 │ new Reflect(); + + +``` + +``` +invalid.js:15:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Math is not a function. + + 13 │ new Atomics(); + 14 │ new JSON(); + > 15 │ new Math(); + │ ^^^^^^^^^^ + 16 │ new Reflect(); + 17 │ new Intl(); + + +``` + +``` +invalid.js:16:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Reflect is not a function. + + 14 │ new JSON(); + 15 │ new Math(); + > 16 │ new Reflect(); + │ ^^^^^^^^^^^^^ + 17 │ new Intl(); + 18 │ + + +``` + +``` +invalid.js:17:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Intl is not a function. + + 15 │ new Math(); + 16 │ new Reflect(); + > 17 │ new Intl(); + │ ^^^^^^^^^^ + 18 │ + 19 │ new (Atomics)(); + + +``` + +``` +invalid.js:19:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Atomics is not a function. + + 17 │ new Intl(); + 18 │ + > 19 │ new (Atomics)(); + │ ^^^^^^^^^^^^^^^ + 20 │ new (JSON)(); + 21 │ new (Math)(); + + +``` + +``` +invalid.js:20:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! JSON is not a function. + + 19 │ new (Atomics)(); + > 20 │ new (JSON)(); + │ ^^^^^^^^^^^^ + 21 │ new (Math)(); + 22 │ new (Reflect)(); + + +``` + +``` +invalid.js:21:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Math is not a function. + + 19 │ new (Atomics)(); + 20 │ new (JSON)(); + > 21 │ new (Math)(); + │ ^^^^^^^^^^^^ + 22 │ new (Reflect)(); + 23 │ new (Intl)(); + + +``` + +``` +invalid.js:22:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Reflect is not a function. + + 20 │ new (JSON)(); + 21 │ new (Math)(); + > 22 │ new (Reflect)(); + │ ^^^^^^^^^^^^^^^ + 23 │ new (Intl)(); + 24 │ + + +``` + +``` +invalid.js:23:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Intl is not a function. + + 21 │ new (Math)(); + 22 │ new (Reflect)(); + > 23 │ new (Intl)(); + │ ^^^^^^^^^^^^ + 24 │ + 25 │ new Atomics; + + +``` + +``` +invalid.js:25:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Atomics is not a function. + + 23 │ new (Intl)(); + 24 │ + > 25 │ new Atomics; + │ ^^^^^^^^^^^ + 26 │ new JSON; + 27 │ new Math; + + +``` + +``` +invalid.js:26:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! JSON is not a function. + + 25 │ new Atomics; + > 26 │ new JSON; + │ ^^^^^^^^ + 27 │ new Math; + 28 │ new Reflect; + + +``` + +``` +invalid.js:27:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Math is not a function. + + 25 │ new Atomics; + 26 │ new JSON; + > 27 │ new Math; + │ ^^^^^^^^ + 28 │ new Reflect; + 29 │ new Intl; + + +``` + +``` +invalid.js:28:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Reflect is not a function. + + 26 │ new JSON; + 27 │ new Math; + > 28 │ new Reflect; + │ ^^^^^^^^^^^ + 29 │ new Intl; + 30 │ + + +``` + +``` +invalid.js:29:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Intl is not a function. + + 27 │ new Math; + 28 │ new Reflect; + > 29 │ new Intl; + │ ^^^^^^^^ + 30 │ + 31 │ // globalThis static member + + +``` + +``` +invalid.js:32:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Atomics is not a function. + + 31 │ // globalThis static member + > 32 │ globalThis.Atomics(); + │ ^^^^^^^^^^^^^^^^^^^^ + 33 │ globalThis.JSON(); + 34 │ globalThis.Math(); + + +``` + +``` +invalid.js:33:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! JSON is not a function. + + 31 │ // globalThis static member + 32 │ globalThis.Atomics(); + > 33 │ globalThis.JSON(); + │ ^^^^^^^^^^^^^^^^^ + 34 │ globalThis.Math(); + 35 │ globalThis.Reflect(); + + +``` + +``` +invalid.js:34:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Math is not a function. + + 32 │ globalThis.Atomics(); + 33 │ globalThis.JSON(); + > 34 │ globalThis.Math(); + │ ^^^^^^^^^^^^^^^^^ + 35 │ globalThis.Reflect(); + 36 │ globalThis.Intl(); + + +``` + +``` +invalid.js:35:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Reflect is not a function. + + 33 │ globalThis.JSON(); + 34 │ globalThis.Math(); + > 35 │ globalThis.Reflect(); + │ ^^^^^^^^^^^^^^^^^^^^ + 36 │ globalThis.Intl(); + 37 │ + + +``` + +``` +invalid.js:36:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Intl is not a function. + + 34 │ globalThis.Math(); + 35 │ globalThis.Reflect(); + > 36 │ globalThis.Intl(); + │ ^^^^^^^^^^^^^^^^^ + 37 │ + 38 │ (globalThis).Atomics(); + + +``` + +``` +invalid.js:38:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Atomics is not a function. + + 36 │ globalThis.Intl(); + 37 │ + > 38 │ (globalThis).Atomics(); + │ ^^^^^^^^^^^^^^^^^^^^^^ + 39 │ (globalThis).JSON(); + 40 │ (globalThis).Math(); + + +``` + +``` +invalid.js:39:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! JSON is not a function. + + 38 │ (globalThis).Atomics(); + > 39 │ (globalThis).JSON(); + │ ^^^^^^^^^^^^^^^^^^^ + 40 │ (globalThis).Math(); + 41 │ (globalThis).Reflect(); + + +``` + +``` +invalid.js:40:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Math is not a function. + + 38 │ (globalThis).Atomics(); + 39 │ (globalThis).JSON(); + > 40 │ (globalThis).Math(); + │ ^^^^^^^^^^^^^^^^^^^ + 41 │ (globalThis).Reflect(); + 42 │ (globalThis).Intl(); + + +``` + +``` +invalid.js:41:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Reflect is not a function. + + 39 │ (globalThis).JSON(); + 40 │ (globalThis).Math(); + > 41 │ (globalThis).Reflect(); + │ ^^^^^^^^^^^^^^^^^^^^^^ + 42 │ (globalThis).Intl(); + 43 │ + + +``` + +``` +invalid.js:42:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Intl is not a function. + + 40 │ (globalThis).Math(); + 41 │ (globalThis).Reflect(); + > 42 │ (globalThis).Intl(); + │ ^^^^^^^^^^^^^^^^^^^ + 43 │ + 44 │ (globalThis.Atomics)(); + + +``` + +``` +invalid.js:44:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Atomics is not a function. + + 42 │ (globalThis).Intl(); + 43 │ + > 44 │ (globalThis.Atomics)(); + │ ^^^^^^^^^^^^^^^^^^^^^^ + 45 │ (globalThis.JSON)(); + 46 │ (globalThis.Math)(); + + +``` + +``` +invalid.js:45:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! JSON is not a function. + + 44 │ (globalThis.Atomics)(); + > 45 │ (globalThis.JSON)(); + │ ^^^^^^^^^^^^^^^^^^^ + 46 │ (globalThis.Math)(); + 47 │ (globalThis.Reflect)(); + + +``` + +``` +invalid.js:46:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Math is not a function. + + 44 │ (globalThis.Atomics)(); + 45 │ (globalThis.JSON)(); + > 46 │ (globalThis.Math)(); + │ ^^^^^^^^^^^^^^^^^^^ + 47 │ (globalThis.Reflect)(); + 48 │ (globalThis.Intl)(); + + +``` + +``` +invalid.js:47:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Reflect is not a function. + + 45 │ (globalThis.JSON)(); + 46 │ (globalThis.Math)(); + > 47 │ (globalThis.Reflect)(); + │ ^^^^^^^^^^^^^^^^^^^^^^ + 48 │ (globalThis.Intl)(); + 49 │ + + +``` + +``` +invalid.js:48:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Intl is not a function. + + 46 │ (globalThis.Math)(); + 47 │ (globalThis.Reflect)(); + > 48 │ (globalThis.Intl)(); + │ ^^^^^^^^^^^^^^^^^^^ + 49 │ + 50 │ new globalThis.Atomics(); + + +``` + +``` +invalid.js:50:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Atomics is not a function. + + 48 │ (globalThis.Intl)(); + 49 │ + > 50 │ new globalThis.Atomics(); + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + 51 │ new globalThis.JSON(); + 52 │ new globalThis.Math(); + + +``` + +``` +invalid.js:51:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! JSON is not a function. + + 50 │ new globalThis.Atomics(); + > 51 │ new globalThis.JSON(); + │ ^^^^^^^^^^^^^^^^^^^^^ + 52 │ new globalThis.Math(); + 53 │ new globalThis.Reflect(); + + +``` + +``` +invalid.js:52:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Math is not a function. + + 50 │ new globalThis.Atomics(); + 51 │ new globalThis.JSON(); + > 52 │ new globalThis.Math(); + │ ^^^^^^^^^^^^^^^^^^^^^ + 53 │ new globalThis.Reflect(); + 54 │ new globalThis.Intl(); + + +``` + +``` +invalid.js:53:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Reflect is not a function. + + 51 │ new globalThis.JSON(); + 52 │ new globalThis.Math(); + > 53 │ new globalThis.Reflect(); + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + 54 │ new globalThis.Intl(); + 55 │ + + +``` + +``` +invalid.js:54:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Intl is not a function. + + 52 │ new globalThis.Math(); + 53 │ new globalThis.Reflect(); + > 54 │ new globalThis.Intl(); + │ ^^^^^^^^^^^^^^^^^^^^^ + 55 │ + 56 │ new (globalThis.Atomics)(); + + +``` + +``` +invalid.js:56:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Atomics is not a function. + + 54 │ new globalThis.Intl(); + 55 │ + > 56 │ new (globalThis.Atomics)(); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ + 57 │ new (globalThis.JSON)(); + 58 │ new (globalThis.Math)(); + + +``` + +``` +invalid.js:57:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! JSON is not a function. + + 56 │ new (globalThis.Atomics)(); + > 57 │ new (globalThis.JSON)(); + │ ^^^^^^^^^^^^^^^^^^^^^^^ + 58 │ new (globalThis.Math)(); + 59 │ new (globalThis.Reflect)(); + + +``` + +``` +invalid.js:58:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Math is not a function. + + 56 │ new (globalThis.Atomics)(); + 57 │ new (globalThis.JSON)(); + > 58 │ new (globalThis.Math)(); + │ ^^^^^^^^^^^^^^^^^^^^^^^ + 59 │ new (globalThis.Reflect)(); + 60 │ new (globalThis.Intl)(); + + +``` + +``` +invalid.js:59:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Reflect is not a function. + + 57 │ new (globalThis.JSON)(); + 58 │ new (globalThis.Math)(); + > 59 │ new (globalThis.Reflect)(); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ + 60 │ new (globalThis.Intl)(); + 61 │ + + +``` + +``` +invalid.js:60:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Intl is not a function. + + 58 │ new (globalThis.Math)(); + 59 │ new (globalThis.Reflect)(); + > 60 │ new (globalThis.Intl)(); + │ ^^^^^^^^^^^^^^^^^^^^^^^ + 61 │ + 62 │ new globalThis.Atomics; + + +``` + +``` +invalid.js:62:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Atomics is not a function. + + 60 │ new (globalThis.Intl)(); + 61 │ + > 62 │ new globalThis.Atomics; + │ ^^^^^^^^^^^^^^^^^^^^^^ + 63 │ new globalThis.JSON; + 64 │ new globalThis.Math; + + +``` + +``` +invalid.js:63:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! JSON is not a function. + + 62 │ new globalThis.Atomics; + > 63 │ new globalThis.JSON; + │ ^^^^^^^^^^^^^^^^^^^ + 64 │ new globalThis.Math; + 65 │ new globalThis.Reflect; + + +``` + +``` +invalid.js:64:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Math is not a function. + + 62 │ new globalThis.Atomics; + 63 │ new globalThis.JSON; + > 64 │ new globalThis.Math; + │ ^^^^^^^^^^^^^^^^^^^ + 65 │ new globalThis.Reflect; + 66 │ new globalThis.Intl; + + +``` + +``` +invalid.js:65:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Reflect is not a function. + + 63 │ new globalThis.JSON; + 64 │ new globalThis.Math; + > 65 │ new globalThis.Reflect; + │ ^^^^^^^^^^^^^^^^^^^^^^ + 66 │ new globalThis.Intl; + 67 │ + + +``` + +``` +invalid.js:66:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Intl is not a function. + + 64 │ new globalThis.Math; + 65 │ new globalThis.Reflect; + > 66 │ new globalThis.Intl; + │ ^^^^^^^^^^^^^^^^^^^ + 67 │ + 68 │ // globalThis computed member + + +``` + +``` +invalid.js:69:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Atomics' is not a function. + + 68 │ // globalThis computed member + > 69 │ globalThis['Atomics'](); + │ ^^^^^^^^^^^^^^^^^^^^^^^ + 70 │ globalThis['JSON'](); + 71 │ globalThis['Math'](); + + +``` + +``` +invalid.js:70:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'JSON' is not a function. + + 68 │ // globalThis computed member + 69 │ globalThis['Atomics'](); + > 70 │ globalThis['JSON'](); + │ ^^^^^^^^^^^^^^^^^^^^ + 71 │ globalThis['Math'](); + 72 │ globalThis['Reflect'](); + + +``` + +``` +invalid.js:71:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Math' is not a function. + + 69 │ globalThis['Atomics'](); + 70 │ globalThis['JSON'](); + > 71 │ globalThis['Math'](); + │ ^^^^^^^^^^^^^^^^^^^^ + 72 │ globalThis['Reflect'](); + 73 │ globalThis['Intl'](); + + +``` + +``` +invalid.js:72:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Reflect' is not a function. + + 70 │ globalThis['JSON'](); + 71 │ globalThis['Math'](); + > 72 │ globalThis['Reflect'](); + │ ^^^^^^^^^^^^^^^^^^^^^^^ + 73 │ globalThis['Intl'](); + 74 │ + + +``` + +``` +invalid.js:73:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Intl' is not a function. + + 71 │ globalThis['Math'](); + 72 │ globalThis['Reflect'](); + > 73 │ globalThis['Intl'](); + │ ^^^^^^^^^^^^^^^^^^^^ + 74 │ + 75 │ (globalThis)['Atomics'](); + + +``` + +``` +invalid.js:75:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Atomics' is not a function. + + 73 │ globalThis['Intl'](); + 74 │ + > 75 │ (globalThis)['Atomics'](); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^ + 76 │ (globalThis)['JSON'](); + 77 │ (globalThis)['Math'](); + + +``` + +``` +invalid.js:76:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'JSON' is not a function. + + 75 │ (globalThis)['Atomics'](); + > 76 │ (globalThis)['JSON'](); + │ ^^^^^^^^^^^^^^^^^^^^^^ + 77 │ (globalThis)['Math'](); + 78 │ (globalThis)['Reflect'](); + + +``` + +``` +invalid.js:77:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Math' is not a function. + + 75 │ (globalThis)['Atomics'](); + 76 │ (globalThis)['JSON'](); + > 77 │ (globalThis)['Math'](); + │ ^^^^^^^^^^^^^^^^^^^^^^ + 78 │ (globalThis)['Reflect'](); + 79 │ (globalThis)['Intl'](); + + +``` + +``` +invalid.js:78:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Reflect' is not a function. + + 76 │ (globalThis)['JSON'](); + 77 │ (globalThis)['Math'](); + > 78 │ (globalThis)['Reflect'](); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^ + 79 │ (globalThis)['Intl'](); + 80 │ + + +``` + +``` +invalid.js:79:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Intl' is not a function. + + 77 │ (globalThis)['Math'](); + 78 │ (globalThis)['Reflect'](); + > 79 │ (globalThis)['Intl'](); + │ ^^^^^^^^^^^^^^^^^^^^^^ + 80 │ + 81 │ (globalThis['Atomics'])(); + + +``` + +``` +invalid.js:81:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Atomics' is not a function. + + 79 │ (globalThis)['Intl'](); + 80 │ + > 81 │ (globalThis['Atomics'])(); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^ + 82 │ (globalThis['JSON'])(); + 83 │ (globalThis['Math'])(); + + +``` + +``` +invalid.js:82:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'JSON' is not a function. + + 81 │ (globalThis['Atomics'])(); + > 82 │ (globalThis['JSON'])(); + │ ^^^^^^^^^^^^^^^^^^^^^^ + 83 │ (globalThis['Math'])(); + 84 │ (globalThis['Reflect'])(); + + +``` + +``` +invalid.js:83:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Math' is not a function. + + 81 │ (globalThis['Atomics'])(); + 82 │ (globalThis['JSON'])(); + > 83 │ (globalThis['Math'])(); + │ ^^^^^^^^^^^^^^^^^^^^^^ + 84 │ (globalThis['Reflect'])(); + 85 │ (globalThis['Intl'])(); + + +``` + +``` +invalid.js:84:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Reflect' is not a function. + + 82 │ (globalThis['JSON'])(); + 83 │ (globalThis['Math'])(); + > 84 │ (globalThis['Reflect'])(); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^ + 85 │ (globalThis['Intl'])(); + 86 │ + + +``` + +``` +invalid.js:85:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Intl' is not a function. + + 83 │ (globalThis['Math'])(); + 84 │ (globalThis['Reflect'])(); + > 85 │ (globalThis['Intl'])(); + │ ^^^^^^^^^^^^^^^^^^^^^^ + 86 │ + 87 │ (globalThis[('Atomics')])(); + + +``` + +``` +invalid.js:87:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Atomics' is not a function. + + 85 │ (globalThis['Intl'])(); + 86 │ + > 87 │ (globalThis[('Atomics')])(); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 88 │ (globalThis[('JSON')])(); + 89 │ (globalThis[('Math')])(); + + +``` + +``` +invalid.js:88:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'JSON' is not a function. + + 87 │ (globalThis[('Atomics')])(); + > 88 │ (globalThis[('JSON')])(); + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + 89 │ (globalThis[('Math')])(); + 90 │ (globalThis[('Reflect')])(); + + +``` + +``` +invalid.js:89:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Math' is not a function. + + 87 │ (globalThis[('Atomics')])(); + 88 │ (globalThis[('JSON')])(); + > 89 │ (globalThis[('Math')])(); + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + 90 │ (globalThis[('Reflect')])(); + 91 │ (globalThis[('Intl')])(); + + +``` + +``` +invalid.js:90:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Reflect' is not a function. + + 88 │ (globalThis[('JSON')])(); + 89 │ (globalThis[('Math')])(); + > 90 │ (globalThis[('Reflect')])(); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 91 │ (globalThis[('Intl')])(); + 92 │ + + +``` + +``` +invalid.js:91:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Intl' is not a function. + + 89 │ (globalThis[('Math')])(); + 90 │ (globalThis[('Reflect')])(); + > 91 │ (globalThis[('Intl')])(); + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + 92 │ + 93 │ new globalThis['Atomics'](); + + +``` + +``` +invalid.js:93:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Atomics' is not a function. + + 91 │ (globalThis[('Intl')])(); + 92 │ + > 93 │ new globalThis['Atomics'](); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 94 │ new globalThis['JSON'](); + 95 │ new globalThis['Math'](); + + +``` + +``` +invalid.js:94:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'JSON' is not a function. + + 93 │ new globalThis['Atomics'](); + > 94 │ new globalThis['JSON'](); + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + 95 │ new globalThis['Math'](); + 96 │ new globalThis['Reflect'](); + + +``` + +``` +invalid.js:95:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Math' is not a function. + + 93 │ new globalThis['Atomics'](); + 94 │ new globalThis['JSON'](); + > 95 │ new globalThis['Math'](); + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + 96 │ new globalThis['Reflect'](); + 97 │ new globalThis['Intl'](); + + +``` + +``` +invalid.js:96:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Reflect' is not a function. + + 94 │ new globalThis['JSON'](); + 95 │ new globalThis['Math'](); + > 96 │ new globalThis['Reflect'](); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 97 │ new globalThis['Intl'](); + 98 │ + + +``` + +``` +invalid.js:97:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Intl' is not a function. + + 95 │ new globalThis['Math'](); + 96 │ new globalThis['Reflect'](); + > 97 │ new globalThis['Intl'](); + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + 98 │ + 99 │ new (globalThis['Atomics'])(); + + +``` + +``` +invalid.js:99:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Atomics' is not a function. + + 97 │ new globalThis['Intl'](); + 98 │ + > 99 │ new (globalThis['Atomics'])(); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 100 │ new (globalThis['JSON'])(); + 101 │ new (globalThis['Math'])(); + + +``` + +``` +invalid.js:100:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'JSON' is not a function. + + 99 │ new (globalThis['Atomics'])(); + > 100 │ new (globalThis['JSON'])(); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ + 101 │ new (globalThis['Math'])(); + 102 │ new (globalThis['Reflect'])(); + + +``` + +``` +invalid.js:101:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Math' is not a function. + + 99 │ new (globalThis['Atomics'])(); + 100 │ new (globalThis['JSON'])(); + > 101 │ new (globalThis['Math'])(); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ + 102 │ new (globalThis['Reflect'])(); + 103 │ new (globalThis['Intl'])(); + + +``` + +``` +invalid.js:102:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Reflect' is not a function. + + 100 │ new (globalThis['JSON'])(); + 101 │ new (globalThis['Math'])(); + > 102 │ new (globalThis['Reflect'])(); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 103 │ new (globalThis['Intl'])(); + 104 │ + + +``` + +``` +invalid.js:103:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Intl' is not a function. + + 101 │ new (globalThis['Math'])(); + 102 │ new (globalThis['Reflect'])(); + > 103 │ new (globalThis['Intl'])(); + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ + 104 │ + 105 │ new globalThis['Atomics']; + + +``` + +``` +invalid.js:105:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Atomics' is not a function. + + 103 │ new (globalThis['Intl'])(); + 104 │ + > 105 │ new globalThis['Atomics']; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^ + 106 │ new globalThis['JSON']; + 107 │ new globalThis['Math']; + + +``` + +``` +invalid.js:106:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'JSON' is not a function. + + 105 │ new globalThis['Atomics']; + > 106 │ new globalThis['JSON']; + │ ^^^^^^^^^^^^^^^^^^^^^^ + 107 │ new globalThis['Math']; + 108 │ new globalThis['Reflect']; + + +``` + +``` +invalid.js:107:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Math' is not a function. + + 105 │ new globalThis['Atomics']; + 106 │ new globalThis['JSON']; + > 107 │ new globalThis['Math']; + │ ^^^^^^^^^^^^^^^^^^^^^^ + 108 │ new globalThis['Reflect']; + 109 │ new globalThis['Intl']; + + +``` + +``` +invalid.js:108:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Reflect' is not a function. + + 106 │ new globalThis['JSON']; + 107 │ new globalThis['Math']; + > 108 │ new globalThis['Reflect']; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^ + 109 │ new globalThis['Intl']; + 110 │ + + +``` + +``` +invalid.js:109:1 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! 'Intl' is not a function. + + 107 │ new globalThis['Math']; + 108 │ new globalThis['Reflect']; + > 109 │ new globalThis['Intl']; + │ ^^^^^^^^^^^^^^^^^^^^^^ + 110 │ + + +``` + + diff --git a/crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/valid.js b/crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/valid.js new file mode 100644 index 00000000000..8204e2b3d86 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/valid.js @@ -0,0 +1,45 @@ +var x = Math; +var x = Math.random(); +var x = Math.PI; +var x = foo.Math(); +var x = new foo.Math(); +var x = new Math.foo; +var x = new Math.foo(); +JSON.parse(foo); +new JSON.parse; +Reflect.get(foo, 'x'); +new Reflect.foo(a, b); +Atomics.load(foo, 0); +new Atomics.foo(); +new Intl.Segmenter(); +Intl.foo(); + +globalThis.Math.random(); +var x = globalThis.Math.PI; +f(globalThis.Math.log(1)); +globalThis.Math.log2().foo; +var x = globalThis.JSON.parse(); +x = globalThis.JSON.stringify(str); +globalThis.Math.exp( globalThis.JSON.parse(1) ); +var x = globalThis.Reflect.get(123); +/*globals Reflect: true*/ globalThis.Reflect.get(); +var x = globalThis.Atomics.load([]); +var x = globalThis.Intl.Segmenter(); + +// shadowed variables +var Math; Math(); +var Math; new Math(); +let JSON; JSON(); +let JSON; new JSON(); +if (foo) { const Reflect = 1; Reflect(); } +if (foo) { const Reflect = 1; new Reflect(); } +function foo(Math) { Math(); } +function foo(JSON) { new JSON(); } +function foo(Atomics) { Atomics(); } +function foo() { if (bar) { let Atomics; if (baz) { new Atomics(); } } } +function foo() { var JSON; JSON(); } +function foo() { var Atomics = bar(); var baz = Atomics(5); } +var construct = typeof Reflect !== "undefined" ? Reflect.construct : undefined; construct(); +function foo(Intl) { Intl(); } +if (foo) { const Intl = 1; Intl(); } +if (foo) { const Intl = 1; new Intl(); } diff --git a/crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/valid.js.snap b/crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/valid.js.snap new file mode 100644 index 00000000000..69b3f988611 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/valid.js.snap @@ -0,0 +1,55 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +expression: valid.js +--- +# Input +```js +var x = Math; +var x = Math.random(); +var x = Math.PI; +var x = foo.Math(); +var x = new foo.Math(); +var x = new Math.foo; +var x = new Math.foo(); +JSON.parse(foo); +new JSON.parse; +Reflect.get(foo, 'x'); +new Reflect.foo(a, b); +Atomics.load(foo, 0); +new Atomics.foo(); +new Intl.Segmenter(); +Intl.foo(); + +globalThis.Math.random(); +var x = globalThis.Math.PI; +f(globalThis.Math.log(1)); +globalThis.Math.log2().foo; +var x = globalThis.JSON.parse(); +x = globalThis.JSON.stringify(str); +globalThis.Math.exp( globalThis.JSON.parse(1) ); +var x = globalThis.Reflect.get(123); +/*globals Reflect: true*/ globalThis.Reflect.get(); +var x = globalThis.Atomics.load([]); +var x = globalThis.Intl.Segmenter(); + +// shadowed variables +var Math; Math(); +var Math; new Math(); +let JSON; JSON(); +let JSON; new JSON(); +if (foo) { const Reflect = 1; Reflect(); } +if (foo) { const Reflect = 1; new Reflect(); } +function foo(Math) { Math(); } +function foo(JSON) { new JSON(); } +function foo(Atomics) { Atomics(); } +function foo() { if (bar) { let Atomics; if (baz) { new Atomics(); } } } +function foo() { var JSON; JSON(); } +function foo() { var Atomics = bar(); var baz = Atomics(5); } +var construct = typeof Reflect !== "undefined" ? Reflect.construct : undefined; construct(); +function foo(Intl) { Intl(); } +if (foo) { const Intl = 1; Intl(); } +if (foo) { const Intl = 1; new Intl(); } + +``` + + diff --git a/crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/valid_import.js b/crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/valid_import.js new file mode 100644 index 00000000000..c91c3274afa --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/valid_import.js @@ -0,0 +1,2 @@ +import { foo as JSON } from "./somewhere.js" +let result = JSON(); diff --git a/crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/valid_import.js.snap b/crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/valid_import.js.snap new file mode 100644 index 00000000000..4962a0be12e --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/noGlobalObjectCalls/valid_import.js.snap @@ -0,0 +1,12 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +expression: valid_import.js +--- +# Input +```js +import { foo as JSON } from "./somewhere.js" +let result = JSON(); + +``` + + diff --git a/crates/rome_js_syntax/src/expr_ext.rs b/crates/rome_js_syntax/src/expr_ext.rs index d120e5346ee..65ad9ff421b 100644 --- a/crates/rome_js_syntax/src/expr_ext.rs +++ b/crates/rome_js_syntax/src/expr_ext.rs @@ -32,6 +32,20 @@ impl JsReferenceIdentifier { self.has_name("undefined") } + /// Returns `true` if this identifier refers to the `globalThis` symbol. + /// + /// ## Examples + /// + /// ``` + /// use rome_js_factory::make::{js_reference_identifier, ident}; + /// + /// assert!(js_reference_identifier(ident("globalThis")).is_global_this()); + /// assert!(!js_reference_identifier(ident("x")).is_global_this()); + /// ``` + pub fn is_global_this(&self) -> bool { + self.has_name("globalThis") + } + /// Returns `true` if this identifier has the given name. /// /// ## Examples diff --git a/crates/rome_service/src/configuration/linter/rules.rs b/crates/rome_service/src/configuration/linter/rules.rs index b88b14d1a67..3585b272ad8 100644 --- a/crates/rome_service/src/configuration/linter/rules.rs +++ b/crates/rome_service/src/configuration/linter/rules.rs @@ -759,6 +759,8 @@ struct NurserySchema { no_extra_non_null_assertion: Option, #[doc = "Typing mistakes and misunderstandings about where semicolons are required can lead to semicolons that are unnecessary. While not technically an error, extra semicolons can cause confusion when reading code."] no_extra_semicolons: Option, + #[doc = "Disallow calling global object properties as functions"] + no_global_object_calls: Option, #[doc = "Check that the scope attribute is only used on th elements."] no_header_scope: Option, #[doc = "Disallow function and var declarations in nested blocks."] @@ -834,7 +836,7 @@ struct NurserySchema { } impl Nursery { const CATEGORY_NAME: &'static str = "nursery"; - pub(crate) const CATEGORY_RULES: [&'static str; 50] = [ + pub(crate) const CATEGORY_RULES: [&'static str; 51] = [ "noAccessKey", "noAssignInExpressions", "noBannedTypes", @@ -849,6 +851,7 @@ impl Nursery { "noEmptyInterface", "noExtraNonNullAssertion", "noExtraSemicolons", + "noGlobalObjectCalls", "noHeaderScope", "noInnerDeclarations", "noInvalidConstructorSuper", @@ -886,7 +889,7 @@ impl Nursery { "useValidLang", "useYield", ]; - const RECOMMENDED_RULES: [&'static str; 41] = [ + const RECOMMENDED_RULES: [&'static str; 42] = [ "noAssignInExpressions", "noBannedTypes", "noClassAssign", @@ -900,6 +903,7 @@ impl Nursery { "noEmptyInterface", "noExtraNonNullAssertion", "noExtraSemicolons", + "noGlobalObjectCalls", "noHeaderScope", "noInnerDeclarations", "noInvalidConstructorSuper", @@ -929,7 +933,7 @@ impl Nursery { "useValidLang", "useYield", ]; - const RECOMMENDED_RULES_AS_FILTERS: [RuleFilter<'static>; 41] = [ + const RECOMMENDED_RULES_AS_FILTERS: [RuleFilter<'static>; 42] = [ RuleFilter::Rule("nursery", Self::CATEGORY_RULES[1]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[2]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[3]), @@ -946,9 +950,9 @@ impl Nursery { RuleFilter::Rule("nursery", Self::CATEGORY_RULES[14]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[15]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[16]), - RuleFilter::Rule("nursery", Self::CATEGORY_RULES[18]), - RuleFilter::Rule("nursery", Self::CATEGORY_RULES[20]), - RuleFilter::Rule("nursery", Self::CATEGORY_RULES[23]), + RuleFilter::Rule("nursery", Self::CATEGORY_RULES[17]), + RuleFilter::Rule("nursery", Self::CATEGORY_RULES[19]), + RuleFilter::Rule("nursery", Self::CATEGORY_RULES[21]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[24]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[25]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[26]), @@ -958,19 +962,20 @@ impl Nursery { RuleFilter::Rule("nursery", Self::CATEGORY_RULES[30]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[31]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[32]), - RuleFilter::Rule("nursery", Self::CATEGORY_RULES[34]), - RuleFilter::Rule("nursery", Self::CATEGORY_RULES[36]), + RuleFilter::Rule("nursery", Self::CATEGORY_RULES[33]), + RuleFilter::Rule("nursery", Self::CATEGORY_RULES[35]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[37]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[38]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[39]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[40]), - RuleFilter::Rule("nursery", Self::CATEGORY_RULES[43]), + RuleFilter::Rule("nursery", Self::CATEGORY_RULES[41]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[44]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[45]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[46]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[47]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[48]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[49]), + RuleFilter::Rule("nursery", Self::CATEGORY_RULES[50]), ]; pub(crate) fn is_recommended(&self) -> bool { !matches!(self.recommended, Some(false)) } pub(crate) fn get_enabled_rules(&self) -> IndexSet { @@ -997,7 +1002,7 @@ impl Nursery { pub(crate) fn is_recommended_rule(rule_name: &str) -> bool { Self::RECOMMENDED_RULES.contains(&rule_name) } - pub(crate) fn recommended_rules_as_filters() -> [RuleFilter<'static>; 41] { + pub(crate) fn recommended_rules_as_filters() -> [RuleFilter<'static>; 42] { Self::RECOMMENDED_RULES_AS_FILTERS } } diff --git a/editors/vscode/configuration_schema.json b/editors/vscode/configuration_schema.json index 1eee1d16de2..f1bd4ee275c 100644 --- a/editors/vscode/configuration_schema.json +++ b/editors/vscode/configuration_schema.json @@ -742,6 +742,17 @@ } ] }, + "noGlobalObjectCalls": { + "description": "Disallow calling global object properties as functions", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, "noHeaderScope": { "description": "Check that the scope attribute is only used on th elements.", "anyOf": [ diff --git a/npm/backend-jsonrpc/src/workspace.ts b/npm/backend-jsonrpc/src/workspace.ts index e63c166710f..7b7d889da69 100644 --- a/npm/backend-jsonrpc/src/workspace.ts +++ b/npm/backend-jsonrpc/src/workspace.ts @@ -340,6 +340,10 @@ export interface Nursery { * Typing mistakes and misunderstandings about where semicolons are required can lead to semicolons that are unnecessary. While not technically an error, extra semicolons can cause confusion when reading code. */ noExtraSemicolons?: RuleConfiguration; + /** + * Disallow calling global object properties as functions + */ + noGlobalObjectCalls?: RuleConfiguration; /** * Check that the scope attribute is only used on th elements. */ @@ -809,6 +813,7 @@ export type Category = | "lint/nursery/useHookAtTopLevel" | "lint/nursery/noDuplicateJsxProps" | "lint/nursery/useYield" + | "lint/nursery/noGlobalObjectCalls" | "lint/performance/noDelete" | "lint/security/noDangerouslySetInnerHtml" | "lint/security/noDangerouslySetInnerHtmlWithChildren" diff --git a/npm/rome/configuration_schema.json b/npm/rome/configuration_schema.json index 1eee1d16de2..f1bd4ee275c 100644 --- a/npm/rome/configuration_schema.json +++ b/npm/rome/configuration_schema.json @@ -742,6 +742,17 @@ } ] }, + "noGlobalObjectCalls": { + "description": "Disallow calling global object properties as functions", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, "noHeaderScope": { "description": "Check that the scope attribute is only used on th elements.", "anyOf": [ diff --git a/website/src/pages/lint/rules/index.mdx b/website/src/pages/lint/rules/index.mdx index 8f2a0442300..7ff97ca8f35 100644 --- a/website/src/pages/lint/rules/index.mdx +++ b/website/src/pages/lint/rules/index.mdx @@ -569,6 +569,12 @@ Typing mistakes and misunderstandings about where semicolons are required can le While not technically an error, extra semicolons can cause confusion when reading code.
+

+ noGlobalObjectCalls +

+Disallow calling global object properties as functions +
+

noHeaderScope

diff --git a/website/src/pages/lint/rules/noGlobalObjectCalls.md b/website/src/pages/lint/rules/noGlobalObjectCalls.md new file mode 100644 index 00000000000..dfa50ba4fdd --- /dev/null +++ b/website/src/pages/lint/rules/noGlobalObjectCalls.md @@ -0,0 +1,188 @@ +--- +title: Lint Rule noGlobalObjectCalls +parent: lint/rules/index +--- + +# noGlobalObjectCalls (since v12.0.0) + +Disallow calling global object properties as functions + +ECMAScript provides several global objects that are intended to be used as-is. +Some of these objects look as if they could be constructors due their capitalization (such as Math and JSON) but will throw an error if you try to execute them as functions. + +The ECMAScript 5 specification makes it clear that both Math and JSON cannot be invoked: +The Math object does not have a [[Call]] internal property; it is not possible to invoke the Math object as a function. + +The ECMAScript 2015 specification makes it clear that Reflect cannot be invoked: +The Reflect object also does not have a [[Call]] internal method; it is not possible to invoke the Reflect object as a function. + +The ECMAScript 2017 specification 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 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. + +## Examples + +### Invalid + +```jsx +var math = Math(); +``` + +
nursery/noGlobalObjectCalls.js:1:12 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+   Math is not a function.
+  
+  > 1 │ var math = Math();
+              ^^^^^^
+    2 │ 
+  
+
+ +```jsx +var newMath = new Math(); +``` + +
nursery/noGlobalObjectCalls.js:1:15 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+   Math is not a function.
+  
+  > 1 │ var newMath = new Math();
+                 ^^^^^^^^^^
+    2 │ 
+  
+
+ +```jsx +var json = JSON(); +``` + +
nursery/noGlobalObjectCalls.js:1:12 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+   JSON is not a function.
+  
+  > 1 │ var json = JSON();
+              ^^^^^^
+    2 │ 
+  
+
+ +```jsx +var newJSON = new JSON(); +``` + +
nursery/noGlobalObjectCalls.js:1:15 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+   JSON is not a function.
+  
+  > 1 │ var newJSON = new JSON();
+                 ^^^^^^^^^^
+    2 │ 
+  
+
+ +```jsx +var reflect = Reflect(); +``` + +
nursery/noGlobalObjectCalls.js:1:15 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+   Reflect is not a function.
+  
+  > 1 │ var reflect = Reflect();
+                 ^^^^^^^^^
+    2 │ 
+  
+
+ +```jsx +var newReflect = new Reflect(); +``` + +
nursery/noGlobalObjectCalls.js:1:18 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+   Reflect is not a function.
+  
+  > 1 │ var newReflect = new Reflect();
+                    ^^^^^^^^^^^^^
+    2 │ 
+  
+
+ +```jsx +var atomics = Atomics(); +``` + +
nursery/noGlobalObjectCalls.js:1:15 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+   Atomics is not a function.
+  
+  > 1 │ var atomics = Atomics();
+                 ^^^^^^^^^
+    2 │ 
+  
+
+ +```jsx +var newAtomics = new Atomics(); +``` + +
nursery/noGlobalObjectCalls.js:1:18 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+   Atomics is not a function.
+  
+  > 1 │ var newAtomics = new Atomics();
+                    ^^^^^^^^^^^^^
+    2 │ 
+  
+
+ +```jsx +var intl = Intl(); +``` + +
nursery/noGlobalObjectCalls.js:1:12 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+   Intl is not a function.
+  
+  > 1 │ var intl = Intl();
+              ^^^^^^
+    2 │ 
+  
+
+ +```jsx +var newIntl = new Intl(); +``` + +
nursery/noGlobalObjectCalls.js:1:15 lint/nursery/noGlobalObjectCalls ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+   Intl is not a function.
+  
+  > 1 │ var newIntl = new Intl();
+                 ^^^^^^^^^^
+    2 │ 
+  
+
+ +## Valid + +```jsx +function area(r) { + return Math.PI * r * r; +} + +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" }); +``` + +## Related links + +- [Disable a rule](/linter/#disable-a-lint-rule) +- [Rule options](/linter/#rule-options)