From 58a8e381b7fb7955174f9c79a46d81a85f94977b Mon Sep 17 00:00:00 2001 From: Kaio Duarte Date: Mon, 5 Dec 2022 10:42:58 +0000 Subject: [PATCH] feat(rome_js_analyze): `useExponentiationOperator` rule (#3848) Co-authored-by: Micha Reiser --- .../src/categories.rs | 1 + .../rome_js_analyze/src/analyzers/nursery.rs | 3 +- .../nursery/use_exponentiation_operator.rs | 316 +++++ .../useExponentiationOperator/invalid.js | 60 + .../useExponentiationOperator/invalid.js.snap | 1014 +++++++++++++++++ .../invalidAdjacentTokens.js | 19 + .../invalidAdjacentTokens.js.snap | 431 +++++++ .../invalidBaseExpoentHigherPrecedence.js | 10 + ...invalidBaseExpoentHigherPrecedence.js.snap | 234 ++++ .../invalidBaseExpoentLowerPrecedence.js | 12 + .../invalidBaseExpoentLowerPrecedence.js.snap | 284 +++++ .../useExponentiationOperator/invalidClass.ts | 5 + .../invalidClass.ts.snap | 109 ++ .../invalidParentsWithHigherPrecedence.js | 21 + ...invalidParentsWithHigherPrecedence.js.snap | 480 ++++++++ .../invalidParentsWithLowerPrecedence.js | 13 + .../invalidParentsWithLowerPrecedence.js.snap | 309 +++++ .../invalidUnaryExpression.js | 9 + .../invalidUnaryExpression.js.snap | 209 ++++ .../invalidWithoutAutofix.js | 19 + .../invalidWithoutAutofix.js.snap | 246 ++++ .../useExponentiationOperator/valid.js | 16 + .../useExponentiationOperator/valid.js.snap | 27 + .../validLocalMath.js | 25 + .../validLocalMath.js.snap | 36 + .../src/configuration/linter/rules.rs | 7 +- 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 + .../lint/rules/useExponentiationOperator.md | 111 ++ 31 files changed, 4056 insertions(+), 3 deletions(-) create mode 100644 crates/rome_js_analyze/src/analyzers/nursery/use_exponentiation_operator.rs create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalid.js create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalid.js.snap create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidAdjacentTokens.js create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidAdjacentTokens.js.snap create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidBaseExpoentHigherPrecedence.js create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidBaseExpoentHigherPrecedence.js.snap create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidBaseExpoentLowerPrecedence.js create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidBaseExpoentLowerPrecedence.js.snap create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidClass.ts create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidClass.ts.snap create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidParentsWithHigherPrecedence.js create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidParentsWithHigherPrecedence.js.snap create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidParentsWithLowerPrecedence.js create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidParentsWithLowerPrecedence.js.snap create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidUnaryExpression.js create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidUnaryExpression.js.snap create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidWithoutAutofix.js create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidWithoutAutofix.js.snap create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/valid.js create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/valid.js.snap create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/validLocalMath.js create mode 100644 crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/validLocalMath.js.snap create mode 100644 website/src/pages/lint/rules/useExponentiationOperator.md diff --git a/crates/rome_diagnostics_categories/src/categories.rs b/crates/rome_diagnostics_categories/src/categories.rs index 78a7a28c0aa..32af1938935 100644 --- a/crates/rome_diagnostics_categories/src/categories.rs +++ b/crates/rome_diagnostics_categories/src/categories.rs @@ -100,6 +100,7 @@ define_dategories! { "lint/nursery/useDefaultSwitchClauseLast":"https://docs.rome.tools/lint/rules/useDefaultSwitchClauseLast", "lint/nursery/useEnumInitializers":"https://docs.rome.tools/lint/rules/useEnumInitializers", "lint/nursery/useExhaustiveDependencies": "https://docs.rome.tools/lint/rules/useExhaustiveDependencies", + "lint/nursery/useExponentiationOperator": "https://docs.rome.tools/lint/rules/useExponentiationOperator", "lint/nursery/useFlatMap": "https://docs.rome.tools/lint/rules/useFlatMap", "lint/nursery/useNumericLiterals": "https://docs.rome.tools/lint/rules/useNumericLiterals", "lint/nursery/useValidForDirection": "https://docs.rome.tools/lint/rules/useValidForDirection", diff --git a/crates/rome_js_analyze/src/analyzers/nursery.rs b/crates/rome_js_analyze/src/analyzers/nursery.rs index 45abdc87ed7..e438714d3f3 100644 --- a/crates/rome_js_analyze/src/analyzers/nursery.rs +++ b/crates/rome_js_analyze/src/analyzers/nursery.rs @@ -22,7 +22,8 @@ mod no_unsafe_finally; mod no_void_type_return; mod use_default_switch_clause_last; mod use_enum_initializers; +mod use_exponentiation_operator; mod use_flat_map; mod use_numeric_literals; mod use_valid_for_direction; -declare_group! { pub (crate) Nursery { name : "nursery" , rules : [self :: no_access_key :: NoAccessKey , self :: no_banned_types :: NoBannedTypes , self :: no_conditional_assignment :: NoConditionalAssignment , self :: no_const_enum :: NoConstEnum , self :: no_constructor_return :: NoConstructorReturn , self :: no_distracting_elements :: NoDistractingElements , self :: no_dupe_keys :: NoDupeKeys , self :: no_empty_interface :: NoEmptyInterface , self :: no_explicit_any :: NoExplicitAny , self :: no_extra_non_null_assertion :: NoExtraNonNullAssertion , self :: no_header_scope :: NoHeaderScope , self :: no_invalid_constructor_super :: NoInvalidConstructorSuper , self :: no_non_null_assertion :: NoNonNullAssertion , self :: no_precision_loss :: NoPrecisionLoss , self :: no_redundant_use_strict :: NoRedundantUseStrict , self :: no_setter_return :: NoSetterReturn , self :: no_string_case_mismatch :: NoStringCaseMismatch , self :: no_unsafe_finally :: NoUnsafeFinally , self :: no_void_type_return :: NoVoidTypeReturn , self :: use_default_switch_clause_last :: UseDefaultSwitchClauseLast , self :: use_enum_initializers :: UseEnumInitializers , self :: use_flat_map :: UseFlatMap , self :: use_numeric_literals :: UseNumericLiterals , self :: use_valid_for_direction :: UseValidForDirection ,] } } +declare_group! { pub (crate) Nursery { name : "nursery" , rules : [self :: no_access_key :: NoAccessKey , self :: no_banned_types :: NoBannedTypes , self :: no_conditional_assignment :: NoConditionalAssignment , self :: no_const_enum :: NoConstEnum , self :: no_constructor_return :: NoConstructorReturn , self :: no_distracting_elements :: NoDistractingElements , self :: no_dupe_keys :: NoDupeKeys , self :: no_empty_interface :: NoEmptyInterface , self :: no_explicit_any :: NoExplicitAny , self :: no_extra_non_null_assertion :: NoExtraNonNullAssertion , self :: no_header_scope :: NoHeaderScope , self :: no_invalid_constructor_super :: NoInvalidConstructorSuper , self :: no_non_null_assertion :: NoNonNullAssertion , self :: no_precision_loss :: NoPrecisionLoss , self :: no_redundant_use_strict :: NoRedundantUseStrict , self :: no_setter_return :: NoSetterReturn , self :: no_string_case_mismatch :: NoStringCaseMismatch , self :: no_unsafe_finally :: NoUnsafeFinally , self :: no_void_type_return :: NoVoidTypeReturn , self :: use_default_switch_clause_last :: UseDefaultSwitchClauseLast , self :: use_enum_initializers :: UseEnumInitializers , self :: use_exponentiation_operator :: UseExponentiationOperator , self :: use_flat_map :: UseFlatMap , self :: use_numeric_literals :: UseNumericLiterals , self :: use_valid_for_direction :: UseValidForDirection ,] } } diff --git a/crates/rome_js_analyze/src/analyzers/nursery/use_exponentiation_operator.rs b/crates/rome_js_analyze/src/analyzers/nursery/use_exponentiation_operator.rs new file mode 100644 index 00000000000..ab5c3162363 --- /dev/null +++ b/crates/rome_js_analyze/src/analyzers/nursery/use_exponentiation_operator.rs @@ -0,0 +1,316 @@ +use crate::semantic_services::Semantic; +use crate::JsRuleAction; +use rome_analyze::context::RuleContext; +use rome_analyze::{declare_rule, ActionCategory, Rule, RuleDiagnostic}; +use rome_console::markup; +use rome_diagnostics::Applicability; +use rome_js_factory::{make, syntax::T}; +use rome_js_syntax::{ + AnyJsExpression, JsBinaryOperator, JsCallExpression, JsClassDeclaration, JsClassExpression, + JsExtendsClause, JsInExpression, OperatorPrecedence, +}; +use rome_rowan::{AstNode, AstSeparatedList, BatchMutationExt}; + +declare_rule! { + /// Disallow the use of `Math.pow` in favor of the `**` operator. + /// + /// > Introduced in ES2016, the infix exponentiation operator ** is an alternative for the standard Math.pow function. + /// > Infix notation is considered to be more readable and thus more preferable than the function notation. + /// + /// Source: https://eslint.org/docs/latest/rules/prefer-exponentiation-operator + /// + /// ## Examples + /// + /// ### Invalid + /// + /// ```js,expect_diagnostic + /// const foo = Math.pow(2, 8); + /// ``` + /// + /// ```js,expect_diagnostic + /// const bar = Math.pow(a, b); + /// ``` + /// + /// ```js,expect_diagnostic + /// let baz = Math.pow(a + b, c + d); + /// ``` + /// + /// ```js,expect_diagnostic + /// let quux = Math.pow(-1, n); + /// ``` + /// + /// ### Valid + /// + /// ```js + /// const foo = 2 ** 8; + /// + /// const bar = a ** b; + /// + /// let baz = (a + b) ** (c + d); + /// + /// let quux = (-1) ** n; + /// ``` + /// + pub(crate) UseExponentiationOperator { + version: "11.0.0", + name: "useExponentiationOperator", + recommended: false, + } +} + +pub struct MathPowCall { + base: AnyJsExpression, + exponent: AnyJsExpression, +} + +impl MathPowCall { + fn make_base(&self) -> Option { + Some(if self.does_base_need_parens()? { + parenthesize_any_js_expression(&self.base) + } else { + self.base.clone() + }) + } + + fn make_exponent(&self) -> Option { + Some(if self.does_exponent_need_parens()? { + parenthesize_any_js_expression(&self.exponent) + } else { + self.exponent.clone() + }) + } + + /// Determines whether the base expression needs parens in an exponentiation binary expression. + fn does_base_need_parens(&self) -> Option { + Some( + // '**' is right-associative, parens are needed when Math.pow(a ** b, c) is converted to (a ** b) ** c + self.base.precedence().ok()? <= OperatorPrecedence::Exponential + // An unary operator cannot be used immediately before an exponentiation expression + || self.base.as_js_unary_expression().is_some() + || self.base.as_js_await_expression().is_some(), + ) + } + + /// Determines whether the exponent expression needs parens in an exponentiation binary expression. + fn does_exponent_need_parens(&self) -> Option { + Some(self.exponent.precedence().ok()? < OperatorPrecedence::Exponential) + } +} + +impl Rule for UseExponentiationOperator { + type Query = Semantic; + type State = (); + type Signals = Option; + type Options = (); + + fn run(ctx: &RuleContext) -> Self::Signals { + let node = ctx.query(); + let model = ctx.model(); + + let object = match node.callee().ok()?.omit_parentheses() { + AnyJsExpression::JsStaticMemberExpression(static_member_expr) => { + if static_member_expr + .member() + .ok()? + .as_js_name()? + .value_token() + .ok()? + .token_text_trimmed() + != "pow" + { + return None; + } + + static_member_expr.object() + } + AnyJsExpression::JsComputedMemberExpression(computed_member_expr) => { + if !computed_member_expr + .member() + .ok()? + .is_string_constant("pow") + { + return None; + } + + computed_member_expr.object() + } + _ => return None, + }; + + let reference = object.ok()?.omit_parentheses().as_reference_identifier()?; + + // verifies that the Math reference is not a local variable + let has_math_pow = reference.has_name("Math") && model.binding(&reference).is_none(); + has_math_pow.then_some(()) + } + + fn diagnostic(ctx: &RuleContext, _: &Self::State) -> Option { + let diagnostic = RuleDiagnostic::new( + rule_category!(), + ctx.query().range(), + "Use the '**' operator instead of 'Math.pow'.", + ); + + Some(diagnostic) + } + + fn action(ctx: &RuleContext, _: &Self::State) -> Option { + let node = ctx.query(); + + if !should_suggest_fix(node)? { + return None; + } + + let mut mutation = ctx.root().begin(); + let [base, exponent] = node.get_arguments_by_index([0, 1]); + + let math_pow_call = MathPowCall { + base: base?.as_any_js_expression()?.clone().omit_parentheses(), + exponent: exponent?.as_any_js_expression()?.clone().omit_parentheses(), + }; + + let new_node = make::js_binary_expression( + math_pow_call.make_base()?, + make::token(T![**]), + math_pow_call.make_exponent()?, + ); + + if let Some((needs_parens, parent)) = does_exponentiation_expression_need_parens(node) { + if needs_parens && parent.is_some() { + mutation.replace_node(parent.clone()?, parenthesize_any_js_expression(&parent?)); + } + + mutation.replace_node( + AnyJsExpression::from(node.clone()), + parenthesize_any_js_expression(&AnyJsExpression::from(new_node)), + ); + } else { + mutation.replace_node( + AnyJsExpression::from(node.clone()), + AnyJsExpression::from(new_node), + ); + } + + Some(JsRuleAction { + category: ActionCategory::QuickFix, + applicability: Applicability::MaybeIncorrect, + message: markup! { "Use the '**' operator instead of 'Math.pow'." }.to_owned(), + mutation, + }) + } +} + +/// Verify if the autofix is safe to be applied and won't remove comments. +/// Argument list is considered valid if there's no spread arg and leading/trailing comments. +fn should_suggest_fix(node: &JsCallExpression) -> Option { + let arguments = node.arguments().ok()?; + let args_count = arguments.args().len(); + + Some( + args_count == 2 + && !arguments.l_paren_token().ok()?.has_leading_comments() + && !arguments.l_paren_token().ok()?.has_trailing_comments() + && !arguments.r_paren_token().ok()?.has_leading_comments() + && !arguments.r_paren_token().ok()?.has_trailing_comments() + && arguments.args().into_iter().flatten().all(|arg| { + !arg.syntax().has_leading_comments() + && !arg.syntax().has_trailing_comments() + && arg.as_js_spread().is_none() + }), + ) +} + +/// Wraps a [AnyJsExpression] in paretheses +fn parenthesize_any_js_expression(expr: &AnyJsExpression) -> AnyJsExpression { + AnyJsExpression::from(make::js_parenthesized_expression( + make::token(T!['(']), + expr.clone(), + make::token(T![')']), + )) +} + +/// Determines whether the given parent node needs parens if used as the exponent in an exponentiation binary expression. +fn does_exponentiation_expression_need_parens( + node: &JsCallExpression, +) -> Option<(bool, Option)> { + if let Some(parent) = node.parent::() { + if does_expression_need_parens(node, &parent)? { + return Some((true, Some(parent))); + } + } else if let Some(extends_clause) = node.parent::() { + if extends_clause.parent::().is_some() { + return Some((true, None)); + } + + if let Some(class_expr) = extends_clause.parent::() { + let class_expr = AnyJsExpression::from(class_expr); + if does_expression_need_parens(node, &class_expr)? { + return Some((true, Some(class_expr))); + } + } + } + + None +} + +/// Determines whether the given expression needs parens when used in an exponentiation binary expression. +fn does_expression_need_parens( + node: &JsCallExpression, + expression: &AnyJsExpression, +) -> Option { + let needs_parentheses = match &expression { + // Skips already parenthesized expressions + AnyJsExpression::JsParenthesizedExpression(_) => return None, + AnyJsExpression::JsBinaryExpression(bin_expr) => { + if bin_expr.parent::().is_some() { + return Some(true); + } + + let binding = bin_expr.right().ok()?; + let call_expr = binding.as_js_call_expression(); + + bin_expr.operator().ok()? != JsBinaryOperator::Exponent + || call_expr.is_none() + || call_expr? != node + } + AnyJsExpression::JsCallExpression(call_expr) => !call_expr + .arguments() + .ok()? + .args() + .iter() + .filter_map(|arg| { + let binding = arg.ok()?; + return binding + .as_any_js_expression()? + .as_js_call_expression() + .cloned(); + }) + .any(|arg| &arg == node), + AnyJsExpression::JsNewExpression(new_expr) => !new_expr + .arguments()? + .args() + .iter() + .filter_map(|arg| { + let binding = arg.ok()?; + return binding + .as_any_js_expression()? + .as_js_call_expression() + .cloned(); + }) + .any(|arg| &arg == node), + AnyJsExpression::JsComputedMemberExpression(member_expr) => { + let binding = member_expr.member().ok()?; + let call_expr = binding.as_js_call_expression(); + + call_expr.is_none() || call_expr? != node + } + AnyJsExpression::JsInExpression(_) => return Some(true), + AnyJsExpression::JsClassExpression(_) + | AnyJsExpression::JsStaticMemberExpression(_) + | AnyJsExpression::JsUnaryExpression(_) + | AnyJsExpression::JsTemplateExpression(_) => true, + _ => false, + }; + + Some(needs_parentheses && expression.precedence().ok()? >= OperatorPrecedence::Exponential) +} diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalid.js b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalid.js new file mode 100644 index 00000000000..456fa7714ca --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalid.js @@ -0,0 +1,60 @@ +Math.pow(a, b); +(Math).pow(a, b); + +// able to catch some workarounds +Math[`pow`](a, b); +(Math)['pow'](a, b); +(Math)["pow"](a, b); +(Math)[`pow`](a, b); + +// non-expression parents that don't require parens +var x = Math.pow(a, b); +if(Math.pow(a, b)){} +for(;Math.pow(a, b);){} +switch(foo){ case Math.pow(a, b): break; } +{ foo: Math.pow(a, b) } +function foo(bar, baz = Math.pow(a, b), quux){} +`${Math.pow(a, b)}` + +// non-expression parents that do require parens +class C extends Math.pow(a, b) {} + +// already parenthesised, shouldn't insert extra parens ++(Math.pow(a, b)) +(Math.pow(a, b)).toString() +(class extends (Math.pow(a, b)) {}) +class C extends (Math.pow(a, b)) {} + +// '**' is right-associative, that applies to both parent and child nodes +a ** Math.pow(b, c); +Math.pow(a, b) ** c; +Math.pow(a, b ** c); +Math.pow(a ** b, c); +a ** Math.pow(b ** c, d ** e) ** f; + +// doesn't remove already existing unnecessary parens around the whole expression +(Math.pow(a, b)); +foo + (Math.pow(a, b)); +(Math.pow(a, b)) + foo; +`${(Math.pow(a, b))}`; + +// doesn't preserve unnecessary parens around base and exponent +Math.pow((a), (b)) +Math.pow(((a)), ((b))) +Math.pow((a.foo), b) +Math.pow(a, (b.foo)) +Math.pow((a()), b) +Math.pow(a, (b())) + +// Optional chaining +Math.pow?.(a, b) +Math?.pow(a, b) +Math?.pow?.(a, b) +;(Math?.pow)(a, b) +;(Math?.pow)?.(a, b) + +// doesn't put extra parens +Math.pow((a + b), (c + d)) + +// tokens that can be adjacent +a+Math.pow(b, c)+d diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalid.js.snap b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalid.js.snap new file mode 100644 index 00000000000..c2b32cfe9de --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalid.js.snap @@ -0,0 +1,1014 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +assertion_line: 73 +expression: invalid.js +--- +# Input +```js +Math.pow(a, b); +(Math).pow(a, b); + +// able to catch some workarounds +Math[`pow`](a, b); +(Math)['pow'](a, b); +(Math)["pow"](a, b); +(Math)[`pow`](a, b); + +// non-expression parents that don't require parens +var x = Math.pow(a, b); +if(Math.pow(a, b)){} +for(;Math.pow(a, b);){} +switch(foo){ case Math.pow(a, b): break; } +{ foo: Math.pow(a, b) } +function foo(bar, baz = Math.pow(a, b), quux){} +`${Math.pow(a, b)}` + +// non-expression parents that do require parens +class C extends Math.pow(a, b) {} + +// already parenthesised, shouldn't insert extra parens ++(Math.pow(a, b)) +(Math.pow(a, b)).toString() +(class extends (Math.pow(a, b)) {}) +class C extends (Math.pow(a, b)) {} + +// '**' is right-associative, that applies to both parent and child nodes +a ** Math.pow(b, c); +Math.pow(a, b) ** c; +Math.pow(a, b ** c); +Math.pow(a ** b, c); +a ** Math.pow(b ** c, d ** e) ** f; + +// doesn't remove already existing unnecessary parens around the whole expression +(Math.pow(a, b)); +foo + (Math.pow(a, b)); +(Math.pow(a, b)) + foo; +`${(Math.pow(a, b))}`; + +// doesn't preserve unnecessary parens around base and exponent +Math.pow((a), (b)) +Math.pow(((a)), ((b))) +Math.pow((a.foo), b) +Math.pow(a, (b.foo)) +Math.pow((a()), b) +Math.pow(a, (b())) + +// Optional chaining +Math.pow?.(a, b) +Math?.pow(a, b) +Math?.pow?.(a, b) +;(Math?.pow)(a, b) +;(Math?.pow)?.(a, b) + +// doesn't put extra parens +Math.pow((a + b), (c + d)) + +// tokens that can be adjacent +a+Math.pow(b, c)+d + +``` + +# Diagnostics +``` +invalid.js:1:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + > 1 │ Math.pow(a, b); + │ ^^^^^^^^^^^^^^ + 2 │ (Math).pow(a, b); + 3 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 1 │ - Math.pow(a,·b); + 1 │ + a**b; + 2 2 │ (Math).pow(a, b); + 3 3 │ + + +``` + +``` +invalid.js:2:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 1 │ Math.pow(a, b); + > 2 │ (Math).pow(a, b); + │ ^^^^^^^^^^^^^^^^ + 3 │ + 4 │ // able to catch some workarounds + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 1 1 │ Math.pow(a, b); + 2 │ - (Math).pow(a,·b); + 2 │ + a**b; + 3 3 │ + 4 4 │ // able to catch some workarounds + + +``` + +``` +invalid.js:5:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 4 │ // able to catch some workarounds + > 5 │ Math[`pow`](a, b); + │ ^^^^^^^^^^^^^^^^^ + 6 │ (Math)['pow'](a, b); + 7 │ (Math)["pow"](a, b); + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 3 3 │ + 4 4 │ // able to catch some workarounds + 5 │ - Math[`pow`](a,·b); + 5 │ + a**b; + 6 6 │ (Math)['pow'](a, b); + 7 7 │ (Math)["pow"](a, b); + + +``` + +``` +invalid.js:6:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 4 │ // able to catch some workarounds + 5 │ Math[`pow`](a, b); + > 6 │ (Math)['pow'](a, b); + │ ^^^^^^^^^^^^^^^^^^^ + 7 │ (Math)["pow"](a, b); + 8 │ (Math)[`pow`](a, b); + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 4 4 │ // able to catch some workarounds + 5 5 │ Math[`pow`](a, b); + 6 │ - (Math)['pow'](a,·b); + 6 │ + a**b; + 7 7 │ (Math)["pow"](a, b); + 8 8 │ (Math)[`pow`](a, b); + + +``` + +``` +invalid.js:7:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 5 │ Math[`pow`](a, b); + 6 │ (Math)['pow'](a, b); + > 7 │ (Math)["pow"](a, b); + │ ^^^^^^^^^^^^^^^^^^^ + 8 │ (Math)[`pow`](a, b); + 9 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 5 5 │ Math[`pow`](a, b); + 6 6 │ (Math)['pow'](a, b); + 7 │ - (Math)["pow"](a,·b); + 7 │ + a**b; + 8 8 │ (Math)[`pow`](a, b); + 9 9 │ + + +``` + +``` +invalid.js:8:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 6 │ (Math)['pow'](a, b); + 7 │ (Math)["pow"](a, b); + > 8 │ (Math)[`pow`](a, b); + │ ^^^^^^^^^^^^^^^^^^^ + 9 │ + 10 │ // non-expression parents that don't require parens + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 6 6 │ (Math)['pow'](a, b); + 7 7 │ (Math)["pow"](a, b); + 8 │ - (Math)[`pow`](a,·b); + 8 │ + a**b; + 9 9 │ + 10 10 │ // non-expression parents that don't require parens + + +``` + +``` +invalid.js:11:9 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 10 │ // non-expression parents that don't require parens + > 11 │ var x = Math.pow(a, b); + │ ^^^^^^^^^^^^^^ + 12 │ if(Math.pow(a, b)){} + 13 │ for(;Math.pow(a, b);){} + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 9 9 │ + 10 10 │ // non-expression parents that don't require parens + 11 │ - var·x·=·Math.pow(a,·b); + 11 │ + var·x·=·a**b; + 12 12 │ if(Math.pow(a, b)){} + 13 13 │ for(;Math.pow(a, b);){} + + +``` + +``` +invalid.js:12:4 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 10 │ // non-expression parents that don't require parens + 11 │ var x = Math.pow(a, b); + > 12 │ if(Math.pow(a, b)){} + │ ^^^^^^^^^^^^^^ + 13 │ for(;Math.pow(a, b);){} + 14 │ switch(foo){ case Math.pow(a, b): break; } + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 10 10 │ // non-expression parents that don't require parens + 11 11 │ var x = Math.pow(a, b); + 12 │ - if(Math.pow(a,·b)){} + 12 │ + if(a**b){} + 13 13 │ for(;Math.pow(a, b);){} + 14 14 │ switch(foo){ case Math.pow(a, b): break; } + + +``` + +``` +invalid.js:13:6 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 11 │ var x = Math.pow(a, b); + 12 │ if(Math.pow(a, b)){} + > 13 │ for(;Math.pow(a, b);){} + │ ^^^^^^^^^^^^^^ + 14 │ switch(foo){ case Math.pow(a, b): break; } + 15 │ { foo: Math.pow(a, b) } + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 11 11 │ var x = Math.pow(a, b); + 12 12 │ if(Math.pow(a, b)){} + 13 │ - for(;Math.pow(a,·b);){} + 13 │ + for(;a**b;){} + 14 14 │ switch(foo){ case Math.pow(a, b): break; } + 15 15 │ { foo: Math.pow(a, b) } + + +``` + +``` +invalid.js:14:19 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 12 │ if(Math.pow(a, b)){} + 13 │ for(;Math.pow(a, b);){} + > 14 │ switch(foo){ case Math.pow(a, b): break; } + │ ^^^^^^^^^^^^^^ + 15 │ { foo: Math.pow(a, b) } + 16 │ function foo(bar, baz = Math.pow(a, b), quux){} + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 12 12 │ if(Math.pow(a, b)){} + 13 13 │ for(;Math.pow(a, b);){} + 14 │ - switch(foo){·case·Math.pow(a,·b):·break;·} + 14 │ + switch(foo){·case·a**b:·break;·} + 15 15 │ { foo: Math.pow(a, b) } + 16 16 │ function foo(bar, baz = Math.pow(a, b), quux){} + + +``` + +``` +invalid.js:15:8 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 13 │ for(;Math.pow(a, b);){} + 14 │ switch(foo){ case Math.pow(a, b): break; } + > 15 │ { foo: Math.pow(a, b) } + │ ^^^^^^^^^^^^^^ + 16 │ function foo(bar, baz = Math.pow(a, b), quux){} + 17 │ `${Math.pow(a, b)}` + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 13 13 │ for(;Math.pow(a, b);){} + 14 14 │ switch(foo){ case Math.pow(a, b): break; } + 15 │ - {·foo:·Math.pow(a,·b)·} + 15 │ + {·foo:·a**b·} + 16 16 │ function foo(bar, baz = Math.pow(a, b), quux){} + 17 17 │ `${Math.pow(a, b)}` + + +``` + +``` +invalid.js:16:25 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 14 │ switch(foo){ case Math.pow(a, b): break; } + 15 │ { foo: Math.pow(a, b) } + > 16 │ function foo(bar, baz = Math.pow(a, b), quux){} + │ ^^^^^^^^^^^^^^ + 17 │ `${Math.pow(a, b)}` + 18 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 14 14 │ switch(foo){ case Math.pow(a, b): break; } + 15 15 │ { foo: Math.pow(a, b) } + 16 │ - function·foo(bar,·baz·=·Math.pow(a,·b),·quux){} + 16 │ + function·foo(bar,·baz·=·a**b,·quux){} + 17 17 │ `${Math.pow(a, b)}` + 18 18 │ + + +``` + +``` +invalid.js:17:4 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 15 │ { foo: Math.pow(a, b) } + 16 │ function foo(bar, baz = Math.pow(a, b), quux){} + > 17 │ `${Math.pow(a, b)}` + │ ^^^^^^^^^^^^^^ + 18 │ + 19 │ // non-expression parents that do require parens + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 15 15 │ { foo: Math.pow(a, b) } + 16 16 │ function foo(bar, baz = Math.pow(a, b), quux){} + 17 │ - `${Math.pow(a,·b)}` + 17 │ + `${a**b}` + 18 18 │ + 19 19 │ // non-expression parents that do require parens + + +``` + +``` +invalid.js:20:17 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 19 │ // non-expression parents that do require parens + > 20 │ class C extends Math.pow(a, b) {} + │ ^^^^^^^^^^^^^^ + 21 │ + 22 │ // already parenthesised, shouldn't insert extra parens + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 18 18 │ + 19 19 │ // non-expression parents that do require parens + 20 │ - class·C·extends·Math.pow(a,·b)·{} + 20 │ + class·C·extends·(a**b)·{} + 21 21 │ + 22 22 │ // already parenthesised, shouldn't insert extra parens + + +``` + +``` +invalid.js:23:3 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 22 │ // already parenthesised, shouldn't insert extra parens + > 23 │ +(Math.pow(a, b)) + │ ^^^^^^^^^^^^^^ + 24 │ (Math.pow(a, b)).toString() + 25 │ (class extends (Math.pow(a, b)) {}) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 21 21 │ + 22 22 │ // already parenthesised, shouldn't insert extra parens + 23 │ - +(Math.pow(a,·b)) + 23 │ + +(a**b) + 24 24 │ (Math.pow(a, b)).toString() + 25 25 │ (class extends (Math.pow(a, b)) {}) + + +``` + +``` +invalid.js:24:2 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 22 │ // already parenthesised, shouldn't insert extra parens + 23 │ +(Math.pow(a, b)) + > 24 │ (Math.pow(a, b)).toString() + │ ^^^^^^^^^^^^^^ + 25 │ (class extends (Math.pow(a, b)) {}) + 26 │ class C extends (Math.pow(a, b)) {} + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 22 22 │ // already parenthesised, shouldn't insert extra parens + 23 23 │ +(Math.pow(a, b)) + 24 │ - (Math.pow(a,·b)).toString() + 24 │ + (a**b).toString() + 25 25 │ (class extends (Math.pow(a, b)) {}) + 26 26 │ class C extends (Math.pow(a, b)) {} + + +``` + +``` +invalid.js:25:17 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 23 │ +(Math.pow(a, b)) + 24 │ (Math.pow(a, b)).toString() + > 25 │ (class extends (Math.pow(a, b)) {}) + │ ^^^^^^^^^^^^^^ + 26 │ class C extends (Math.pow(a, b)) {} + 27 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 23 23 │ +(Math.pow(a, b)) + 24 24 │ (Math.pow(a, b)).toString() + 25 │ - (class·extends·(Math.pow(a,·b))·{}) + 25 │ + (class·extends·(a**b)·{}) + 26 26 │ class C extends (Math.pow(a, b)) {} + 27 27 │ + + +``` + +``` +invalid.js:26:18 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 24 │ (Math.pow(a, b)).toString() + 25 │ (class extends (Math.pow(a, b)) {}) + > 26 │ class C extends (Math.pow(a, b)) {} + │ ^^^^^^^^^^^^^^ + 27 │ + 28 │ // '**' is right-associative, that applies to both parent and child nodes + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 24 24 │ (Math.pow(a, b)).toString() + 25 25 │ (class extends (Math.pow(a, b)) {}) + 26 │ - class·C·extends·(Math.pow(a,·b))·{} + 26 │ + class·C·extends·(a**b)·{} + 27 27 │ + 28 28 │ // '**' is right-associative, that applies to both parent and child nodes + + +``` + +``` +invalid.js:29:6 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 28 │ // '**' is right-associative, that applies to both parent and child nodes + > 29 │ a ** Math.pow(b, c); + │ ^^^^^^^^^^^^^^ + 30 │ Math.pow(a, b) ** c; + 31 │ Math.pow(a, b ** c); + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 27 27 │ + 28 28 │ // '**' is right-associative, that applies to both parent and child nodes + 29 │ - a·**·Math.pow(b,·c); + 29 │ + a·**·b**c; + 30 30 │ Math.pow(a, b) ** c; + 31 31 │ Math.pow(a, b ** c); + + +``` + +``` +invalid.js:30:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 28 │ // '**' is right-associative, that applies to both parent and child nodes + 29 │ a ** Math.pow(b, c); + > 30 │ Math.pow(a, b) ** c; + │ ^^^^^^^^^^^^^^ + 31 │ Math.pow(a, b ** c); + 32 │ Math.pow(a ** b, c); + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 28 28 │ // '**' is right-associative, that applies to both parent and child nodes + 29 29 │ a ** Math.pow(b, c); + 30 │ - Math.pow(a,·b)·**·c; + 30 │ + (a**b)·**·c; + 31 31 │ Math.pow(a, b ** c); + 32 32 │ Math.pow(a ** b, c); + + +``` + +``` +invalid.js:31:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 29 │ a ** Math.pow(b, c); + 30 │ Math.pow(a, b) ** c; + > 31 │ Math.pow(a, b ** c); + │ ^^^^^^^^^^^^^^^^^^^ + 32 │ Math.pow(a ** b, c); + 33 │ a ** Math.pow(b ** c, d ** e) ** f; + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 29 29 │ a ** Math.pow(b, c); + 30 30 │ Math.pow(a, b) ** c; + 31 │ - Math.pow(a,·b·**·c); + 31 │ + a**b·**·c; + 32 32 │ Math.pow(a ** b, c); + 33 33 │ a ** Math.pow(b ** c, d ** e) ** f; + + +``` + +``` +invalid.js:32:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 30 │ Math.pow(a, b) ** c; + 31 │ Math.pow(a, b ** c); + > 32 │ Math.pow(a ** b, c); + │ ^^^^^^^^^^^^^^^^^^^ + 33 │ a ** Math.pow(b ** c, d ** e) ** f; + 34 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 30 30 │ Math.pow(a, b) ** c; + 31 31 │ Math.pow(a, b ** c); + 32 │ - Math.pow(a·**·b,·c); + 32 │ + (a·**·b)**c; + 33 33 │ a ** Math.pow(b ** c, d ** e) ** f; + 34 34 │ + + +``` + +``` +invalid.js:33:6 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 31 │ Math.pow(a, b ** c); + 32 │ Math.pow(a ** b, c); + > 33 │ a ** Math.pow(b ** c, d ** e) ** f; + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + 34 │ + 35 │ // doesn't remove already existing unnecessary parens around the whole expression + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 31 31 │ Math.pow(a, b ** c); + 32 32 │ Math.pow(a ** b, c); + 33 │ - a·**·Math.pow(b·**·c,·d·**·e)·**·f; + 33 │ + a·**·((b·**·c)**d·**·e)·**·f; + 34 34 │ + 35 35 │ // doesn't remove already existing unnecessary parens around the whole expression + + +``` + +``` +invalid.js:36:2 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 35 │ // doesn't remove already existing unnecessary parens around the whole expression + > 36 │ (Math.pow(a, b)); + │ ^^^^^^^^^^^^^^ + 37 │ foo + (Math.pow(a, b)); + 38 │ (Math.pow(a, b)) + foo; + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 34 34 │ + 35 35 │ // doesn't remove already existing unnecessary parens around the whole expression + 36 │ - (Math.pow(a,·b)); + 36 │ + (a**b); + 37 37 │ foo + (Math.pow(a, b)); + 38 38 │ (Math.pow(a, b)) + foo; + + +``` + +``` +invalid.js:37:8 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 35 │ // doesn't remove already existing unnecessary parens around the whole expression + 36 │ (Math.pow(a, b)); + > 37 │ foo + (Math.pow(a, b)); + │ ^^^^^^^^^^^^^^ + 38 │ (Math.pow(a, b)) + foo; + 39 │ `${(Math.pow(a, b))}`; + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 35 35 │ // doesn't remove already existing unnecessary parens around the whole expression + 36 36 │ (Math.pow(a, b)); + 37 │ - foo·+·(Math.pow(a,·b)); + 37 │ + foo·+·(a**b); + 38 38 │ (Math.pow(a, b)) + foo; + 39 39 │ `${(Math.pow(a, b))}`; + + +``` + +``` +invalid.js:38:2 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 36 │ (Math.pow(a, b)); + 37 │ foo + (Math.pow(a, b)); + > 38 │ (Math.pow(a, b)) + foo; + │ ^^^^^^^^^^^^^^ + 39 │ `${(Math.pow(a, b))}`; + 40 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 36 36 │ (Math.pow(a, b)); + 37 37 │ foo + (Math.pow(a, b)); + 38 │ - (Math.pow(a,·b))·+·foo; + 38 │ + (a**b)·+·foo; + 39 39 │ `${(Math.pow(a, b))}`; + 40 40 │ + + +``` + +``` +invalid.js:39:5 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 37 │ foo + (Math.pow(a, b)); + 38 │ (Math.pow(a, b)) + foo; + > 39 │ `${(Math.pow(a, b))}`; + │ ^^^^^^^^^^^^^^ + 40 │ + 41 │ // doesn't preserve unnecessary parens around base and exponent + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 37 37 │ foo + (Math.pow(a, b)); + 38 38 │ (Math.pow(a, b)) + foo; + 39 │ - `${(Math.pow(a,·b))}`; + 39 │ + `${(a**b)}`; + 40 40 │ + 41 41 │ // doesn't preserve unnecessary parens around base and exponent + + +``` + +``` +invalid.js:42:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 41 │ // doesn't preserve unnecessary parens around base and exponent + > 42 │ Math.pow((a), (b)) + │ ^^^^^^^^^^^^^^^^^^ + 43 │ Math.pow(((a)), ((b))) + 44 │ Math.pow((a.foo), b) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 40 40 │ + 41 41 │ // doesn't preserve unnecessary parens around base and exponent + 42 │ - Math.pow((a),·(b)) + 42 │ + a**b + 43 43 │ Math.pow(((a)), ((b))) + 44 44 │ Math.pow((a.foo), b) + + +``` + +``` +invalid.js:43:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 41 │ // doesn't preserve unnecessary parens around base and exponent + 42 │ Math.pow((a), (b)) + > 43 │ Math.pow(((a)), ((b))) + │ ^^^^^^^^^^^^^^^^^^^^^^ + 44 │ Math.pow((a.foo), b) + 45 │ Math.pow(a, (b.foo)) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 41 41 │ // doesn't preserve unnecessary parens around base and exponent + 42 42 │ Math.pow((a), (b)) + 43 │ - Math.pow(((a)),·((b))) + 43 │ + a**b + 44 44 │ Math.pow((a.foo), b) + 45 45 │ Math.pow(a, (b.foo)) + + +``` + +``` +invalid.js:44:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 42 │ Math.pow((a), (b)) + 43 │ Math.pow(((a)), ((b))) + > 44 │ Math.pow((a.foo), b) + │ ^^^^^^^^^^^^^^^^^^^^ + 45 │ Math.pow(a, (b.foo)) + 46 │ Math.pow((a()), b) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 42 42 │ Math.pow((a), (b)) + 43 43 │ Math.pow(((a)), ((b))) + 44 │ - Math.pow((a.foo),·b) + 44 │ + a.foo**b + 45 45 │ Math.pow(a, (b.foo)) + 46 46 │ Math.pow((a()), b) + + +``` + +``` +invalid.js:45:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 43 │ Math.pow(((a)), ((b))) + 44 │ Math.pow((a.foo), b) + > 45 │ Math.pow(a, (b.foo)) + │ ^^^^^^^^^^^^^^^^^^^^ + 46 │ Math.pow((a()), b) + 47 │ Math.pow(a, (b())) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 43 43 │ Math.pow(((a)), ((b))) + 44 44 │ Math.pow((a.foo), b) + 45 │ - Math.pow(a,·(b.foo)) + 45 │ + a**b.foo + 46 46 │ Math.pow((a()), b) + 47 47 │ Math.pow(a, (b())) + + +``` + +``` +invalid.js:46:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 44 │ Math.pow((a.foo), b) + 45 │ Math.pow(a, (b.foo)) + > 46 │ Math.pow((a()), b) + │ ^^^^^^^^^^^^^^^^^^ + 47 │ Math.pow(a, (b())) + 48 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 44 44 │ Math.pow((a.foo), b) + 45 45 │ Math.pow(a, (b.foo)) + 46 │ - Math.pow((a()),·b) + 46 │ + a()**b + 47 47 │ Math.pow(a, (b())) + 48 48 │ + + +``` + +``` +invalid.js:47:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 45 │ Math.pow(a, (b.foo)) + 46 │ Math.pow((a()), b) + > 47 │ Math.pow(a, (b())) + │ ^^^^^^^^^^^^^^^^^^ + 48 │ + 49 │ // Optional chaining + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 45 45 │ Math.pow(a, (b.foo)) + 46 46 │ Math.pow((a()), b) + 47 │ - Math.pow(a,·(b())) + 47 │ + a**b() + 48 48 │ + 49 49 │ // Optional chaining + + +``` + +``` +invalid.js:50:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 49 │ // Optional chaining + > 50 │ Math.pow?.(a, b) + │ ^^^^^^^^^^^^^^^^ + 51 │ Math?.pow(a, b) + 52 │ Math?.pow?.(a, b) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 48 48 │ + 49 49 │ // Optional chaining + 50 │ - Math.pow?.(a,·b) + 50 │ + a**b + 51 51 │ Math?.pow(a, b) + 52 52 │ Math?.pow?.(a, b) + + +``` + +``` +invalid.js:51:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 49 │ // Optional chaining + 50 │ Math.pow?.(a, b) + > 51 │ Math?.pow(a, b) + │ ^^^^^^^^^^^^^^^ + 52 │ Math?.pow?.(a, b) + 53 │ ;(Math?.pow)(a, b) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 49 49 │ // Optional chaining + 50 50 │ Math.pow?.(a, b) + 51 │ - Math?.pow(a,·b) + 51 │ + a**b + 52 52 │ Math?.pow?.(a, b) + 53 53 │ ;(Math?.pow)(a, b) + + +``` + +``` +invalid.js:52:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 50 │ Math.pow?.(a, b) + 51 │ Math?.pow(a, b) + > 52 │ Math?.pow?.(a, b) + │ ^^^^^^^^^^^^^^^^^ + 53 │ ;(Math?.pow)(a, b) + 54 │ ;(Math?.pow)?.(a, b) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 50 50 │ Math.pow?.(a, b) + 51 51 │ Math?.pow(a, b) + 52 │ - Math?.pow?.(a,·b) + 52 │ + a**b + 53 53 │ ;(Math?.pow)(a, b) + 54 54 │ ;(Math?.pow)?.(a, b) + + +``` + +``` +invalid.js:53:2 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 51 │ Math?.pow(a, b) + 52 │ Math?.pow?.(a, b) + > 53 │ ;(Math?.pow)(a, b) + │ ^^^^^^^^^^^^^^^^^ + 54 │ ;(Math?.pow)?.(a, b) + 55 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 51 51 │ Math?.pow(a, b) + 52 52 │ Math?.pow?.(a, b) + 53 │ - ;(Math?.pow)(a,·b) + 53 │ + ;a**b + 54 54 │ ;(Math?.pow)?.(a, b) + 55 55 │ + + +``` + +``` +invalid.js:54:2 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 52 │ Math?.pow?.(a, b) + 53 │ ;(Math?.pow)(a, b) + > 54 │ ;(Math?.pow)?.(a, b) + │ ^^^^^^^^^^^^^^^^^^^ + 55 │ + 56 │ // doesn't put extra parens + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 52 52 │ Math?.pow?.(a, b) + 53 53 │ ;(Math?.pow)(a, b) + 54 │ - ;(Math?.pow)?.(a,·b) + 54 │ + ;a**b + 55 55 │ + 56 56 │ // doesn't put extra parens + + +``` + +``` +invalid.js:57:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 56 │ // doesn't put extra parens + > 57 │ Math.pow((a + b), (c + d)) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ + 58 │ + 59 │ // tokens that can be adjacent + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 55 55 │ + 56 56 │ // doesn't put extra parens + 57 │ - Math.pow((a·+·b),·(c·+·d)) + 57 │ + (a·+·b)**(c·+·d) + 58 58 │ + 59 59 │ // tokens that can be adjacent + + +``` + +``` +invalid.js:60:3 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 59 │ // tokens that can be adjacent + > 60 │ a+Math.pow(b, c)+d + │ ^^^^^^^^^^^^^^ + 61 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 58 58 │ + 59 59 │ // tokens that can be adjacent + 60 │ - a+Math.pow(b,·c)+d + 60 │ + a+b**c+d + 61 61 │ + + +``` + + diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidAdjacentTokens.js b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidAdjacentTokens.js new file mode 100644 index 00000000000..aa3279d66ed --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidAdjacentTokens.js @@ -0,0 +1,19 @@ +// tokens that cannot be adjacent +a+Math.pow(++b, c); +(a)+(Math).pow((++b), c); +Math.pow(a, b)in c +Math.pow(a, (b))in (c) +a+Math.pow(++b, c)in d +a+Math.pow( ++b, c )in d + +// tokens that cannot be adjacent, but there is already space or something else between +a+ Math.pow(++b, c) in d +// a+/**/Math.pow(++b, c)/**/in d // ignored because of comments +a+(Math.pow(++b, c))in d + +// tokens that cannot be adjacent, but the autofix inserts parens required for precedence ++Math.pow(++a, b) +Math.pow(a, b + c)in d +Math.pow(a, b) + Math.pow(c, d) +Math.pow(Math.pow(a, b), Math.pow(c, d)) +Math.pow(a, b)**Math.pow(c, d) diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidAdjacentTokens.js.snap b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidAdjacentTokens.js.snap new file mode 100644 index 00000000000..d390782ed03 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidAdjacentTokens.js.snap @@ -0,0 +1,431 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +assertion_line: 73 +expression: invalidAdjacentTokens.js +--- +# Input +```js +// tokens that cannot be adjacent +a+Math.pow(++b, c); +(a)+(Math).pow((++b), c); +Math.pow(a, b)in c +Math.pow(a, (b))in (c) +a+Math.pow(++b, c)in d +a+Math.pow( ++b, c )in d + +// tokens that cannot be adjacent, but there is already space or something else between +a+ Math.pow(++b, c) in d +// a+/**/Math.pow(++b, c)/**/in d // ignored because of comments +a+(Math.pow(++b, c))in d + +// tokens that cannot be adjacent, but the autofix inserts parens required for precedence ++Math.pow(++a, b) +Math.pow(a, b + c)in d +Math.pow(a, b) + Math.pow(c, d) +Math.pow(Math.pow(a, b), Math.pow(c, d)) +Math.pow(a, b)**Math.pow(c, d) + +``` + +# Diagnostics +``` +invalidAdjacentTokens.js:2:3 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 1 │ // tokens that cannot be adjacent + > 2 │ a+Math.pow(++b, c); + │ ^^^^^^^^^^^^^^^^ + 3 │ (a)+(Math).pow((++b), c); + 4 │ Math.pow(a, b)in c + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 1 1 │ // tokens that cannot be adjacent + 2 │ - a+Math.pow(++b,·c); + 2 │ + a+++b**c; + 3 3 │ (a)+(Math).pow((++b), c); + 4 4 │ Math.pow(a, b)in c + + +``` + +``` +invalidAdjacentTokens.js:3:5 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 1 │ // tokens that cannot be adjacent + 2 │ a+Math.pow(++b, c); + > 3 │ (a)+(Math).pow((++b), c); + │ ^^^^^^^^^^^^^^^^^^^^ + 4 │ Math.pow(a, b)in c + 5 │ Math.pow(a, (b))in (c) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 1 1 │ // tokens that cannot be adjacent + 2 2 │ a+Math.pow(++b, c); + 3 │ - (a)+(Math).pow((++b),·c); + 3 │ + (a)+++b**c; + 4 4 │ Math.pow(a, b)in c + 5 5 │ Math.pow(a, (b))in (c) + + +``` + +``` +invalidAdjacentTokens.js:4:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 2 │ a+Math.pow(++b, c); + 3 │ (a)+(Math).pow((++b), c); + > 4 │ Math.pow(a, b)in c + │ ^^^^^^^^^^^^^^ + 5 │ Math.pow(a, (b))in (c) + 6 │ a+Math.pow(++b, c)in d + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 2 2 │ a+Math.pow(++b, c); + 3 3 │ (a)+(Math).pow((++b), c); + 4 │ - Math.pow(a,·b)in·c + 4 │ + (a**b)in·c + 5 5 │ Math.pow(a, (b))in (c) + 6 6 │ a+Math.pow(++b, c)in d + + +``` + +``` +invalidAdjacentTokens.js:5:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 3 │ (a)+(Math).pow((++b), c); + 4 │ Math.pow(a, b)in c + > 5 │ Math.pow(a, (b))in (c) + │ ^^^^^^^^^^^^^^^^ + 6 │ a+Math.pow(++b, c)in d + 7 │ a+Math.pow( ++b, c )in d + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 3 3 │ (a)+(Math).pow((++b), c); + 4 4 │ Math.pow(a, b)in c + 5 │ - Math.pow(a,·(b))in·(c) + 5 │ + (a**b)in·(c) + 6 6 │ a+Math.pow(++b, c)in d + 7 7 │ a+Math.pow( ++b, c )in d + + +``` + +``` +invalidAdjacentTokens.js:6:3 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 4 │ Math.pow(a, b)in c + 5 │ Math.pow(a, (b))in (c) + > 6 │ a+Math.pow(++b, c)in d + │ ^^^^^^^^^^^^^^^^ + 7 │ a+Math.pow( ++b, c )in d + 8 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 4 4 │ Math.pow(a, b)in c + 5 5 │ Math.pow(a, (b))in (c) + 6 │ - a+Math.pow(++b,·c)in·d + 6 │ + a+(++b**c)in·d + 7 7 │ a+Math.pow( ++b, c )in d + 8 8 │ + + +``` + +``` +invalidAdjacentTokens.js:7:3 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 5 │ Math.pow(a, (b))in (c) + 6 │ a+Math.pow(++b, c)in d + > 7 │ a+Math.pow( ++b, c )in d + │ ^^^^^^^^^^^^^^^^^^ + 8 │ + 9 │ // tokens that cannot be adjacent, but there is already space or something else between + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 5 5 │ Math.pow(a, (b))in (c) + 6 6 │ a+Math.pow(++b, c)in d + 7 │ - a+Math.pow(·++b,·c·)in·d + 7 │ + a+(++b**c·)in·d + 8 8 │ + 9 9 │ // tokens that cannot be adjacent, but there is already space or something else between + + +``` + +``` +invalidAdjacentTokens.js:10:4 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 9 │ // tokens that cannot be adjacent, but there is already space or something else between + > 10 │ a+ Math.pow(++b, c) in d + │ ^^^^^^^^^^^^^^^^ + 11 │ // a+/**/Math.pow(++b, c)/**/in d // ignored because of comments + 12 │ a+(Math.pow(++b, c))in d + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 8 8 │ + 9 9 │ // tokens that cannot be adjacent, but there is already space or something else between + 10 │ - a+·Math.pow(++b,·c)·in·d + 10 │ + a+·(++b**c)·in·d + 11 11 │ // a+/**/Math.pow(++b, c)/**/in d // ignored because of comments + 12 12 │ a+(Math.pow(++b, c))in d + + +``` + +``` +invalidAdjacentTokens.js:12:4 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 10 │ a+ Math.pow(++b, c) in d + 11 │ // a+/**/Math.pow(++b, c)/**/in d // ignored because of comments + > 12 │ a+(Math.pow(++b, c))in d + │ ^^^^^^^^^^^^^^^^ + 13 │ + 14 │ // tokens that cannot be adjacent, but the autofix inserts parens required for precedence + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 10 10 │ a+ Math.pow(++b, c) in d + 11 11 │ // a+/**/Math.pow(++b, c)/**/in d // ignored because of comments + 12 │ - a+(Math.pow(++b,·c))in·d + 12 │ + a+(++b**c)in·d + 13 13 │ + 14 14 │ // tokens that cannot be adjacent, but the autofix inserts parens required for precedence + + +``` + +``` +invalidAdjacentTokens.js:15:2 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 14 │ // tokens that cannot be adjacent, but the autofix inserts parens required for precedence + > 15 │ +Math.pow(++a, b) + │ ^^^^^^^^^^^^^^^^ + 16 │ Math.pow(a, b + c)in d + 17 │ Math.pow(a, b) + Math.pow(c, d) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 13 13 │ + 14 14 │ // tokens that cannot be adjacent, but the autofix inserts parens required for precedence + 15 │ - +Math.pow(++a,·b) + 15 │ + +(++a**b) + 16 16 │ Math.pow(a, b + c)in d + 17 17 │ Math.pow(a, b) + Math.pow(c, d) + + +``` + +``` +invalidAdjacentTokens.js:16:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 14 │ // tokens that cannot be adjacent, but the autofix inserts parens required for precedence + 15 │ +Math.pow(++a, b) + > 16 │ Math.pow(a, b + c)in d + │ ^^^^^^^^^^^^^^^^^^ + 17 │ Math.pow(a, b) + Math.pow(c, d) + 18 │ Math.pow(Math.pow(a, b), Math.pow(c, d)) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 14 14 │ // tokens that cannot be adjacent, but the autofix inserts parens required for precedence + 15 15 │ +Math.pow(++a, b) + 16 │ - Math.pow(a,·b·+·c)in·d + 16 │ + (a**(b·+·c))in·d + 17 17 │ Math.pow(a, b) + Math.pow(c, d) + 18 18 │ Math.pow(Math.pow(a, b), Math.pow(c, d)) + + +``` + +``` +invalidAdjacentTokens.js:17:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 15 │ +Math.pow(++a, b) + 16 │ Math.pow(a, b + c)in d + > 17 │ Math.pow(a, b) + Math.pow(c, d) + │ ^^^^^^^^^^^^^^ + 18 │ Math.pow(Math.pow(a, b), Math.pow(c, d)) + 19 │ Math.pow(a, b)**Math.pow(c, d) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 15 15 │ +Math.pow(++a, b) + 16 16 │ Math.pow(a, b + c)in d + 17 │ - Math.pow(a,·b)·+·Math.pow(c,·d) + 17 │ + a**b·+·Math.pow(c,·d) + 18 18 │ Math.pow(Math.pow(a, b), Math.pow(c, d)) + 19 19 │ Math.pow(a, b)**Math.pow(c, d) + + +``` + +``` +invalidAdjacentTokens.js:17:18 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 15 │ +Math.pow(++a, b) + 16 │ Math.pow(a, b + c)in d + > 17 │ Math.pow(a, b) + Math.pow(c, d) + │ ^^^^^^^^^^^^^^ + 18 │ Math.pow(Math.pow(a, b), Math.pow(c, d)) + 19 │ Math.pow(a, b)**Math.pow(c, d) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 15 15 │ +Math.pow(++a, b) + 16 16 │ Math.pow(a, b + c)in d + 17 │ - Math.pow(a,·b)·+·Math.pow(c,·d) + 17 │ + Math.pow(a,·b)·+·c**d + 18 18 │ Math.pow(Math.pow(a, b), Math.pow(c, d)) + 19 19 │ Math.pow(a, b)**Math.pow(c, d) + + +``` + +``` +invalidAdjacentTokens.js:18:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 16 │ Math.pow(a, b + c)in d + 17 │ Math.pow(a, b) + Math.pow(c, d) + > 18 │ Math.pow(Math.pow(a, b), Math.pow(c, d)) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 19 │ Math.pow(a, b)**Math.pow(c, d) + 20 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 16 16 │ Math.pow(a, b + c)in d + 17 17 │ Math.pow(a, b) + Math.pow(c, d) + 18 │ - Math.pow(Math.pow(a,·b),·Math.pow(c,·d)) + 18 │ + Math.pow(a,·b)**Math.pow(c,·d) + 19 19 │ Math.pow(a, b)**Math.pow(c, d) + 20 20 │ + + +``` + +``` +invalidAdjacentTokens.js:18:10 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 16 │ Math.pow(a, b + c)in d + 17 │ Math.pow(a, b) + Math.pow(c, d) + > 18 │ Math.pow(Math.pow(a, b), Math.pow(c, d)) + │ ^^^^^^^^^^^^^^ + 19 │ Math.pow(a, b)**Math.pow(c, d) + 20 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 16 16 │ Math.pow(a, b + c)in d + 17 17 │ Math.pow(a, b) + Math.pow(c, d) + 18 │ - Math.pow(Math.pow(a,·b),·Math.pow(c,·d)) + 18 │ + Math.pow(a**b,·Math.pow(c,·d)) + 19 19 │ Math.pow(a, b)**Math.pow(c, d) + 20 20 │ + + +``` + +``` +invalidAdjacentTokens.js:18:26 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 16 │ Math.pow(a, b + c)in d + 17 │ Math.pow(a, b) + Math.pow(c, d) + > 18 │ Math.pow(Math.pow(a, b), Math.pow(c, d)) + │ ^^^^^^^^^^^^^^ + 19 │ Math.pow(a, b)**Math.pow(c, d) + 20 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 16 16 │ Math.pow(a, b + c)in d + 17 17 │ Math.pow(a, b) + Math.pow(c, d) + 18 │ - Math.pow(Math.pow(a,·b),·Math.pow(c,·d)) + 18 │ + Math.pow(Math.pow(a,·b),·c**d) + 19 19 │ Math.pow(a, b)**Math.pow(c, d) + 20 20 │ + + +``` + +``` +invalidAdjacentTokens.js:19:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 17 │ Math.pow(a, b) + Math.pow(c, d) + 18 │ Math.pow(Math.pow(a, b), Math.pow(c, d)) + > 19 │ Math.pow(a, b)**Math.pow(c, d) + │ ^^^^^^^^^^^^^^ + 20 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 17 17 │ Math.pow(a, b) + Math.pow(c, d) + 18 18 │ Math.pow(Math.pow(a, b), Math.pow(c, d)) + 19 │ - Math.pow(a,·b)**Math.pow(c,·d) + 19 │ + (a**b)**Math.pow(c,·d) + 20 20 │ + + +``` + +``` +invalidAdjacentTokens.js:19:17 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 17 │ Math.pow(a, b) + Math.pow(c, d) + 18 │ Math.pow(Math.pow(a, b), Math.pow(c, d)) + > 19 │ Math.pow(a, b)**Math.pow(c, d) + │ ^^^^^^^^^^^^^^ + 20 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 17 17 │ Math.pow(a, b) + Math.pow(c, d) + 18 18 │ Math.pow(Math.pow(a, b), Math.pow(c, d)) + 19 │ - Math.pow(a,·b)**Math.pow(c,·d) + 19 │ + Math.pow(a,·b)**c**d + 20 20 │ + + +``` + + diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidBaseExpoentHigherPrecedence.js b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidBaseExpoentHigherPrecedence.js new file mode 100644 index 00000000000..91ddb73c1c1 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidBaseExpoentHigherPrecedence.js @@ -0,0 +1,10 @@ + // base and exponent with a higher precedence + Math.pow(2, 3) + Math.pow(a.foo, b) + Math.pow(a, b.foo) + Math.pow(a(), b) + Math.pow(a, b()) + Math.pow(++a, ++b) + Math.pow(a++, ++b) + Math.pow(a--, b--) + Math.pow(--a, b--) diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidBaseExpoentHigherPrecedence.js.snap b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidBaseExpoentHigherPrecedence.js.snap new file mode 100644 index 00000000000..1926c6f67ea --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidBaseExpoentHigherPrecedence.js.snap @@ -0,0 +1,234 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +assertion_line: 74 +expression: invalidBaseExpoentHigherPrecedence.js +--- +# Input +```js + // base and exponent with a higher precedence + Math.pow(2, 3) + Math.pow(a.foo, b) + Math.pow(a, b.foo) + Math.pow(a(), b) + Math.pow(a, b()) + Math.pow(++a, ++b) + Math.pow(a++, ++b) + Math.pow(a--, b--) + Math.pow(--a, b--) + +``` + +# Diagnostics +``` +invalidBaseExpoentHigherPrecedence.js:2:2 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 1 │ // base and exponent with a higher precedence + > 2 │ Math.pow(2, 3) + │ ^^^^^^^^^^^^^^ + 3 │ Math.pow(a.foo, b) + 4 │ Math.pow(a, b.foo) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 1 1 │ // base and exponent with a higher precedence + 2 │ - ·Math.pow(2,·3) + 2 │ + ·2**3 + 3 3 │ Math.pow(a.foo, b) + 4 4 │ Math.pow(a, b.foo) + + +``` + +``` +invalidBaseExpoentHigherPrecedence.js:3:2 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 1 │ // base and exponent with a higher precedence + 2 │ Math.pow(2, 3) + > 3 │ Math.pow(a.foo, b) + │ ^^^^^^^^^^^^^^^^^^ + 4 │ Math.pow(a, b.foo) + 5 │ Math.pow(a(), b) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 1 1 │ // base and exponent with a higher precedence + 2 2 │ Math.pow(2, 3) + 3 │ - ·Math.pow(a.foo,·b) + 3 │ + ·a.foo**b + 4 4 │ Math.pow(a, b.foo) + 5 5 │ Math.pow(a(), b) + + +``` + +``` +invalidBaseExpoentHigherPrecedence.js:4:2 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 2 │ Math.pow(2, 3) + 3 │ Math.pow(a.foo, b) + > 4 │ Math.pow(a, b.foo) + │ ^^^^^^^^^^^^^^^^^^ + 5 │ Math.pow(a(), b) + 6 │ Math.pow(a, b()) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 2 2 │ Math.pow(2, 3) + 3 3 │ Math.pow(a.foo, b) + 4 │ - ·Math.pow(a,·b.foo) + 4 │ + ·a**b.foo + 5 5 │ Math.pow(a(), b) + 6 6 │ Math.pow(a, b()) + + +``` + +``` +invalidBaseExpoentHigherPrecedence.js:5:2 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 3 │ Math.pow(a.foo, b) + 4 │ Math.pow(a, b.foo) + > 5 │ Math.pow(a(), b) + │ ^^^^^^^^^^^^^^^^ + 6 │ Math.pow(a, b()) + 7 │ Math.pow(++a, ++b) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 3 3 │ Math.pow(a.foo, b) + 4 4 │ Math.pow(a, b.foo) + 5 │ - ·Math.pow(a(),·b) + 5 │ + ·a()**b + 6 6 │ Math.pow(a, b()) + 7 7 │ Math.pow(++a, ++b) + + +``` + +``` +invalidBaseExpoentHigherPrecedence.js:6:2 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 4 │ Math.pow(a, b.foo) + 5 │ Math.pow(a(), b) + > 6 │ Math.pow(a, b()) + │ ^^^^^^^^^^^^^^^^ + 7 │ Math.pow(++a, ++b) + 8 │ Math.pow(a++, ++b) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 4 4 │ Math.pow(a, b.foo) + 5 5 │ Math.pow(a(), b) + 6 │ - ·Math.pow(a,·b()) + 6 │ + ·a**b() + 7 7 │ Math.pow(++a, ++b) + 8 8 │ Math.pow(a++, ++b) + + +``` + +``` +invalidBaseExpoentHigherPrecedence.js:7:2 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 5 │ Math.pow(a(), b) + 6 │ Math.pow(a, b()) + > 7 │ Math.pow(++a, ++b) + │ ^^^^^^^^^^^^^^^^^^ + 8 │ Math.pow(a++, ++b) + 9 │ Math.pow(a--, b--) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 5 5 │ Math.pow(a(), b) + 6 6 │ Math.pow(a, b()) + 7 │ - ·Math.pow(++a,·++b) + 7 │ + ·++a**++b + 8 8 │ Math.pow(a++, ++b) + 9 9 │ Math.pow(a--, b--) + + +``` + +``` +invalidBaseExpoentHigherPrecedence.js:8:2 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 6 │ Math.pow(a, b()) + 7 │ Math.pow(++a, ++b) + > 8 │ Math.pow(a++, ++b) + │ ^^^^^^^^^^^^^^^^^^ + 9 │ Math.pow(a--, b--) + 10 │ Math.pow(--a, b--) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 6 6 │ Math.pow(a, b()) + 7 7 │ Math.pow(++a, ++b) + 8 │ - ·Math.pow(a++,·++b) + 8 │ + ·a++**++b + 9 9 │ Math.pow(a--, b--) + 10 10 │ Math.pow(--a, b--) + + +``` + +``` +invalidBaseExpoentHigherPrecedence.js:9:2 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 7 │ Math.pow(++a, ++b) + 8 │ Math.pow(a++, ++b) + > 9 │ Math.pow(a--, b--) + │ ^^^^^^^^^^^^^^^^^^ + 10 │ Math.pow(--a, b--) + 11 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 7 7 │ Math.pow(++a, ++b) + 8 8 │ Math.pow(a++, ++b) + 9 │ - ·Math.pow(a--,·b--) + 9 │ + ·a--**b-- + 10 10 │ Math.pow(--a, b--) + 11 11 │ + + +``` + +``` +invalidBaseExpoentHigherPrecedence.js:10:2 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 8 │ Math.pow(a++, ++b) + 9 │ Math.pow(a--, b--) + > 10 │ Math.pow(--a, b--) + │ ^^^^^^^^^^^^^^^^^^ + 11 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 8 8 │ Math.pow(a++, ++b) + 9 9 │ Math.pow(a--, b--) + 10 │ - ·Math.pow(--a,·b--) + 10 │ + ·--a**b-- + 11 11 │ + + +``` + + diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidBaseExpoentLowerPrecedence.js b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidBaseExpoentLowerPrecedence.js new file mode 100644 index 00000000000..266d02490b4 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidBaseExpoentLowerPrecedence.js @@ -0,0 +1,12 @@ +// base and exponent with a lower precedence +Math.pow(a * b, c) +Math.pow(a, b * c) +Math.pow(a / b, c) +Math.pow(a, b / c) +Math.pow(a + b, 3) +Math.pow(2, a - b) +Math.pow(a + b, c + d) +Math.pow(a = b, c = d) +Math.pow(a += b, c -= d) +Math.pow((a, b), (c, d)) +function *f() { Math.pow(yield, yield) } diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidBaseExpoentLowerPrecedence.js.snap b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidBaseExpoentLowerPrecedence.js.snap new file mode 100644 index 00000000000..f29bfb0e4b4 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidBaseExpoentLowerPrecedence.js.snap @@ -0,0 +1,284 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +assertion_line: 74 +expression: invalidBaseExpoentLowerPrecedence.js +--- +# Input +```js +// base and exponent with a lower precedence +Math.pow(a * b, c) +Math.pow(a, b * c) +Math.pow(a / b, c) +Math.pow(a, b / c) +Math.pow(a + b, 3) +Math.pow(2, a - b) +Math.pow(a + b, c + d) +Math.pow(a = b, c = d) +Math.pow(a += b, c -= d) +Math.pow((a, b), (c, d)) +function *f() { Math.pow(yield, yield) } + +``` + +# Diagnostics +``` +invalidBaseExpoentLowerPrecedence.js:2:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 1 │ // base and exponent with a lower precedence + > 2 │ Math.pow(a * b, c) + │ ^^^^^^^^^^^^^^^^^^ + 3 │ Math.pow(a, b * c) + 4 │ Math.pow(a / b, c) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 1 1 │ // base and exponent with a lower precedence + 2 │ - Math.pow(a·*·b,·c) + 2 │ + (a·*·b)**c + 3 3 │ Math.pow(a, b * c) + 4 4 │ Math.pow(a / b, c) + + +``` + +``` +invalidBaseExpoentLowerPrecedence.js:3:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 1 │ // base and exponent with a lower precedence + 2 │ Math.pow(a * b, c) + > 3 │ Math.pow(a, b * c) + │ ^^^^^^^^^^^^^^^^^^ + 4 │ Math.pow(a / b, c) + 5 │ Math.pow(a, b / c) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 1 1 │ // base and exponent with a lower precedence + 2 2 │ Math.pow(a * b, c) + 3 │ - Math.pow(a,·b·*·c) + 3 │ + a**(b·*·c) + 4 4 │ Math.pow(a / b, c) + 5 5 │ Math.pow(a, b / c) + + +``` + +``` +invalidBaseExpoentLowerPrecedence.js:4:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 2 │ Math.pow(a * b, c) + 3 │ Math.pow(a, b * c) + > 4 │ Math.pow(a / b, c) + │ ^^^^^^^^^^^^^^^^^^ + 5 │ Math.pow(a, b / c) + 6 │ Math.pow(a + b, 3) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 2 2 │ Math.pow(a * b, c) + 3 3 │ Math.pow(a, b * c) + 4 │ - Math.pow(a·/·b,·c) + 4 │ + (a·/·b)**c + 5 5 │ Math.pow(a, b / c) + 6 6 │ Math.pow(a + b, 3) + + +``` + +``` +invalidBaseExpoentLowerPrecedence.js:5:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 3 │ Math.pow(a, b * c) + 4 │ Math.pow(a / b, c) + > 5 │ Math.pow(a, b / c) + │ ^^^^^^^^^^^^^^^^^^ + 6 │ Math.pow(a + b, 3) + 7 │ Math.pow(2, a - b) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 3 3 │ Math.pow(a, b * c) + 4 4 │ Math.pow(a / b, c) + 5 │ - Math.pow(a,·b·/·c) + 5 │ + a**(b·/·c) + 6 6 │ Math.pow(a + b, 3) + 7 7 │ Math.pow(2, a - b) + + +``` + +``` +invalidBaseExpoentLowerPrecedence.js:6:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 4 │ Math.pow(a / b, c) + 5 │ Math.pow(a, b / c) + > 6 │ Math.pow(a + b, 3) + │ ^^^^^^^^^^^^^^^^^^ + 7 │ Math.pow(2, a - b) + 8 │ Math.pow(a + b, c + d) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 4 4 │ Math.pow(a / b, c) + 5 5 │ Math.pow(a, b / c) + 6 │ - Math.pow(a·+·b,·3) + 6 │ + (a·+·b)**3 + 7 7 │ Math.pow(2, a - b) + 8 8 │ Math.pow(a + b, c + d) + + +``` + +``` +invalidBaseExpoentLowerPrecedence.js:7:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 5 │ Math.pow(a, b / c) + 6 │ Math.pow(a + b, 3) + > 7 │ Math.pow(2, a - b) + │ ^^^^^^^^^^^^^^^^^^ + 8 │ Math.pow(a + b, c + d) + 9 │ Math.pow(a = b, c = d) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 5 5 │ Math.pow(a, b / c) + 6 6 │ Math.pow(a + b, 3) + 7 │ - Math.pow(2,·a·-·b) + 7 │ + 2**(a·-·b) + 8 8 │ Math.pow(a + b, c + d) + 9 9 │ Math.pow(a = b, c = d) + + +``` + +``` +invalidBaseExpoentLowerPrecedence.js:8:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 6 │ Math.pow(a + b, 3) + 7 │ Math.pow(2, a - b) + > 8 │ Math.pow(a + b, c + d) + │ ^^^^^^^^^^^^^^^^^^^^^^ + 9 │ Math.pow(a = b, c = d) + 10 │ Math.pow(a += b, c -= d) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 6 6 │ Math.pow(a + b, 3) + 7 7 │ Math.pow(2, a - b) + 8 │ - Math.pow(a·+·b,·c·+·d) + 8 │ + (a·+·b)**(c·+·d) + 9 9 │ Math.pow(a = b, c = d) + 10 10 │ Math.pow(a += b, c -= d) + + +``` + +``` +invalidBaseExpoentLowerPrecedence.js:9:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 7 │ Math.pow(2, a - b) + 8 │ Math.pow(a + b, c + d) + > 9 │ Math.pow(a = b, c = d) + │ ^^^^^^^^^^^^^^^^^^^^^^ + 10 │ Math.pow(a += b, c -= d) + 11 │ Math.pow((a, b), (c, d)) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 7 7 │ Math.pow(2, a - b) + 8 8 │ Math.pow(a + b, c + d) + 9 │ - Math.pow(a·=·b,·c·=·d) + 9 │ + (a·=·b)**(c·=·d) + 10 10 │ Math.pow(a += b, c -= d) + 11 11 │ Math.pow((a, b), (c, d)) + + +``` + +``` +invalidBaseExpoentLowerPrecedence.js:10:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 8 │ Math.pow(a + b, c + d) + 9 │ Math.pow(a = b, c = d) + > 10 │ Math.pow(a += b, c -= d) + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + 11 │ Math.pow((a, b), (c, d)) + 12 │ function *f() { Math.pow(yield, yield) } + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 8 8 │ Math.pow(a + b, c + d) + 9 9 │ Math.pow(a = b, c = d) + 10 │ - Math.pow(a·+=·b,·c·-=·d) + 10 │ + (a·+=·b)**(c·-=·d) + 11 11 │ Math.pow((a, b), (c, d)) + 12 12 │ function *f() { Math.pow(yield, yield) } + + +``` + +``` +invalidBaseExpoentLowerPrecedence.js:11:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 9 │ Math.pow(a = b, c = d) + 10 │ Math.pow(a += b, c -= d) + > 11 │ Math.pow((a, b), (c, d)) + │ ^^^^^^^^^^^^^^^^^^^^^^^^ + 12 │ function *f() { Math.pow(yield, yield) } + 13 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 9 9 │ Math.pow(a = b, c = d) + 10 10 │ Math.pow(a += b, c -= d) + 11 │ - Math.pow((a,·b),·(c,·d)) + 11 │ + (a,·b)**(c,·d) + 12 12 │ function *f() { Math.pow(yield, yield) } + 13 13 │ + + +``` + +``` +invalidBaseExpoentLowerPrecedence.js:12:17 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 10 │ Math.pow(a += b, c -= d) + 11 │ Math.pow((a, b), (c, d)) + > 12 │ function *f() { Math.pow(yield, yield) } + │ ^^^^^^^^^^^^^^^^^^^^^^ + 13 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 10 10 │ Math.pow(a += b, c -= d) + 11 11 │ Math.pow((a, b), (c, d)) + 12 │ - function·*f()·{·Math.pow(yield,·yield)·} + 12 │ + function·*f()·{·(yield)**(yield)·} + 13 13 │ + + +``` + + diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidClass.ts b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidClass.ts new file mode 100644 index 00000000000..b39b13fe88a --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidClass.ts @@ -0,0 +1,5 @@ +// @ts-nocheck +class C extends Math.pow(a, b) implements Foo {} +(class A extends Math.pow(a, b) implements Foo {}) +(class A extends (Math.pow(a, b)) {}) +class C extends (Math.pow(a, b)) implements Foo, Bar {} diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidClass.ts.snap b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidClass.ts.snap new file mode 100644 index 00000000000..4d9e4be653e --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidClass.ts.snap @@ -0,0 +1,109 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +assertion_line: 73 +expression: invalidClass.ts +--- +# Input +```js +// @ts-nocheck +class C extends Math.pow(a, b) implements Foo {} +(class A extends Math.pow(a, b) implements Foo {}) +(class A extends (Math.pow(a, b)) {}) +class C extends (Math.pow(a, b)) implements Foo, Bar {} + +``` + +# Diagnostics +``` +invalidClass.ts:2:20 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 1 │ // @ts-nocheck + > 2 │ class C extends Math.pow(a, b) implements Foo {} + │ ^^^^^^^^^^^^^^ + 3 │ (class A extends Math.pow(a, b) implements Foo {}) + 4 │ (class A extends (Math.pow(a, b)) {}) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 1 1 │ // @ts-nocheck + 2 │ - class·C·extends·Math.pow(a,·b)·implements·Foo·{} + 2 │ + class·C·extends·(a**b)·implements·Foo·{} + 3 3 │ (class A extends Math.pow(a, b) implements Foo {}) + 4 4 │ (class A extends (Math.pow(a, b)) {}) + + +``` + +``` +invalidClass.ts:3:18 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 1 │ // @ts-nocheck + 2 │ class C extends Math.pow(a, b) implements Foo {} + > 3 │ (class A extends Math.pow(a, b) implements Foo {}) + │ ^^^^^^^^^^^^^^ + 4 │ (class A extends (Math.pow(a, b)) {}) + 5 │ class C extends (Math.pow(a, b)) implements Foo, Bar {} + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 1 1 │ // @ts-nocheck + 2 2 │ class C extends Math.pow(a, b) implements Foo {} + 3 │ - (class·A·extends·Math.pow(a,·b)·implements·Foo·{}) + 3 │ + (class·A·extends·(a**b)·implements·Foo·{}) + 4 4 │ (class A extends (Math.pow(a, b)) {}) + 5 5 │ class C extends (Math.pow(a, b)) implements Foo, Bar {} + + +``` + +``` +invalidClass.ts:4:22 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 2 │ class C extends Math.pow(a, b) implements Foo {} + 3 │ (class A extends Math.pow(a, b) implements Foo {}) + > 4 │ (class A extends (Math.pow(a, b)) {}) + │ ^^^^^^^^^^^^^^ + 5 │ class C extends (Math.pow(a, b)) implements Foo, Bar {} + 6 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 2 2 │ class C extends Math.pow(a, b) implements Foo {} + 3 3 │ (class A extends Math.pow(a, b) implements Foo {}) + 4 │ - (class·A·extends·(Math.pow(a,·b))·{}) + 4 │ + (class·A·extends·(a**b)·{}) + 5 5 │ class C extends (Math.pow(a, b)) implements Foo, Bar {} + 6 6 │ + + +``` + +``` +invalidClass.ts:5:21 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 3 │ (class A extends Math.pow(a, b) implements Foo {}) + 4 │ (class A extends (Math.pow(a, b)) {}) + > 5 │ class C extends (Math.pow(a, b)) implements Foo, Bar {} + │ ^^^^^^^^^^^^^^ + 6 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 3 3 │ (class A extends Math.pow(a, b) implements Foo {}) + 4 4 │ (class A extends (Math.pow(a, b)) {}) + 5 │ - class·C·extends·(Math.pow(a,·b))·implements·Foo,·Bar·{} + 5 │ + class·C·extends·(a**b)·implements·Foo,·Bar·{} + 6 6 │ + + +``` + + diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidParentsWithHigherPrecedence.js b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidParentsWithHigherPrecedence.js new file mode 100644 index 00000000000..6aa6b6f80fa --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidParentsWithHigherPrecedence.js @@ -0,0 +1,21 @@ ++ Math.pow(a, b); +- Math.pow(a, b); +! Math.pow(a, b); +typeof Math.pow(a, b); +void Math.pow(a, b); +Math.pow(a, b) .toString(); +Math.pow(a, b) (); +Math.pow(a, b) ``; +(class extends Math.pow(a, b) {}) + +// parents with a higher precedence, but the expression's role doesn't require parens +f(Math.pow(a, b)) +f(foo, Math.pow(a, b)) +f(Math.pow(a, b), foo) +f(foo, Math.pow(a, b), bar) +new F(Math.pow(a, b)) +new F(foo, Math.pow(a, b)) +new F(Math.pow(a, b), foo) +new F(foo, Math.pow(a, b), bar) +obj[Math.pow(a, b)] +[foo, Math.pow(a, b), bar] diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidParentsWithHigherPrecedence.js.snap b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidParentsWithHigherPrecedence.js.snap new file mode 100644 index 00000000000..d2909c6a7f3 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidParentsWithHigherPrecedence.js.snap @@ -0,0 +1,480 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +assertion_line: 73 +expression: invalidParentsWithHigherPrecedence.js +--- +# Input +```js ++ Math.pow(a, b); +- Math.pow(a, b); +! Math.pow(a, b); +typeof Math.pow(a, b); +void Math.pow(a, b); +Math.pow(a, b) .toString(); +Math.pow(a, b) (); +Math.pow(a, b) ``; +(class extends Math.pow(a, b) {}) + +// parents with a higher precedence, but the expression's role doesn't require parens +f(Math.pow(a, b)) +f(foo, Math.pow(a, b)) +f(Math.pow(a, b), foo) +f(foo, Math.pow(a, b), bar) +new F(Math.pow(a, b)) +new F(foo, Math.pow(a, b)) +new F(Math.pow(a, b), foo) +new F(foo, Math.pow(a, b), bar) +obj[Math.pow(a, b)] +[foo, Math.pow(a, b), bar] + +``` + +# Diagnostics +``` +invalidParentsWithHigherPrecedence.js:1:3 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + > 1 │ + Math.pow(a, b); + │ ^^^^^^^^^^^^^^ + 2 │ - Math.pow(a, b); + 3 │ ! Math.pow(a, b); + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 1 │ - +·Math.pow(a,·b); + 1 │ + +·(a**b); + 2 2 │ - Math.pow(a, b); + 3 3 │ ! Math.pow(a, b); + + +``` + +``` +invalidParentsWithHigherPrecedence.js:2:3 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 1 │ + Math.pow(a, b); + > 2 │ - Math.pow(a, b); + │ ^^^^^^^^^^^^^^ + 3 │ ! Math.pow(a, b); + 4 │ typeof Math.pow(a, b); + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 1 1 │ + Math.pow(a, b); + 2 │ - -·Math.pow(a,·b); + 2 │ + -·(a**b); + 3 3 │ ! Math.pow(a, b); + 4 4 │ typeof Math.pow(a, b); + + +``` + +``` +invalidParentsWithHigherPrecedence.js:3:3 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 1 │ + Math.pow(a, b); + 2 │ - Math.pow(a, b); + > 3 │ ! Math.pow(a, b); + │ ^^^^^^^^^^^^^^ + 4 │ typeof Math.pow(a, b); + 5 │ void Math.pow(a, b); + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 1 1 │ + Math.pow(a, b); + 2 2 │ - Math.pow(a, b); + 3 │ - !·Math.pow(a,·b); + 3 │ + !·(a**b); + 4 4 │ typeof Math.pow(a, b); + 5 5 │ void Math.pow(a, b); + + +``` + +``` +invalidParentsWithHigherPrecedence.js:4:8 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 2 │ - Math.pow(a, b); + 3 │ ! Math.pow(a, b); + > 4 │ typeof Math.pow(a, b); + │ ^^^^^^^^^^^^^^ + 5 │ void Math.pow(a, b); + 6 │ Math.pow(a, b) .toString(); + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 2 2 │ - Math.pow(a, b); + 3 3 │ ! Math.pow(a, b); + 4 │ - typeof·Math.pow(a,·b); + 4 │ + typeof·(a**b); + 5 5 │ void Math.pow(a, b); + 6 6 │ Math.pow(a, b) .toString(); + + +``` + +``` +invalidParentsWithHigherPrecedence.js:5:6 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 3 │ ! Math.pow(a, b); + 4 │ typeof Math.pow(a, b); + > 5 │ void Math.pow(a, b); + │ ^^^^^^^^^^^^^^ + 6 │ Math.pow(a, b) .toString(); + 7 │ Math.pow(a, b) (); + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 3 3 │ ! Math.pow(a, b); + 4 4 │ typeof Math.pow(a, b); + 5 │ - void·Math.pow(a,·b); + 5 │ + void·(a**b); + 6 6 │ Math.pow(a, b) .toString(); + 7 7 │ Math.pow(a, b) (); + + +``` + +``` +invalidParentsWithHigherPrecedence.js:6:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 4 │ typeof Math.pow(a, b); + 5 │ void Math.pow(a, b); + > 6 │ Math.pow(a, b) .toString(); + │ ^^^^^^^^^^^^^^ + 7 │ Math.pow(a, b) (); + 8 │ Math.pow(a, b) ``; + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 4 4 │ typeof Math.pow(a, b); + 5 5 │ void Math.pow(a, b); + 6 │ - Math.pow(a,·b)·.toString(); + 6 │ + (a**b)·.toString(); + 7 7 │ Math.pow(a, b) (); + 8 8 │ Math.pow(a, b) ``; + + +``` + +``` +invalidParentsWithHigherPrecedence.js:7:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 5 │ void Math.pow(a, b); + 6 │ Math.pow(a, b) .toString(); + > 7 │ Math.pow(a, b) (); + │ ^^^^^^^^^^^^^^ + 8 │ Math.pow(a, b) ``; + 9 │ (class extends Math.pow(a, b) {}) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 5 5 │ void Math.pow(a, b); + 6 6 │ Math.pow(a, b) .toString(); + 7 │ - Math.pow(a,·b)·(); + 7 │ + (a**b)·(); + 8 8 │ Math.pow(a, b) ``; + 9 9 │ (class extends Math.pow(a, b) {}) + + +``` + +``` +invalidParentsWithHigherPrecedence.js:8:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 6 │ Math.pow(a, b) .toString(); + 7 │ Math.pow(a, b) (); + > 8 │ Math.pow(a, b) ``; + │ ^^^^^^^^^^^^^^ + 9 │ (class extends Math.pow(a, b) {}) + 10 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 6 6 │ Math.pow(a, b) .toString(); + 7 7 │ Math.pow(a, b) (); + 8 │ - Math.pow(a,·b)·``; + 8 │ + (a**b)·``; + 9 9 │ (class extends Math.pow(a, b) {}) + 10 10 │ + + +``` + +``` +invalidParentsWithHigherPrecedence.js:9:16 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 7 │ Math.pow(a, b) (); + 8 │ Math.pow(a, b) ``; + > 9 │ (class extends Math.pow(a, b) {}) + │ ^^^^^^^^^^^^^^ + 10 │ + 11 │ // parents with a higher precedence, but the expression's role doesn't require parens + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 7 7 │ Math.pow(a, b) (); + 8 8 │ Math.pow(a, b) ``; + 9 │ - (class·extends·Math.pow(a,·b)·{}) + 9 │ + (class·extends·(a**b)·{}) + 10 10 │ + 11 11 │ // parents with a higher precedence, but the expression's role doesn't require parens + + +``` + +``` +invalidParentsWithHigherPrecedence.js:12:3 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 11 │ // parents with a higher precedence, but the expression's role doesn't require parens + > 12 │ f(Math.pow(a, b)) + │ ^^^^^^^^^^^^^^ + 13 │ f(foo, Math.pow(a, b)) + 14 │ f(Math.pow(a, b), foo) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 10 10 │ + 11 11 │ // parents with a higher precedence, but the expression's role doesn't require parens + 12 │ - f(Math.pow(a,·b)) + 12 │ + f(a**b) + 13 13 │ f(foo, Math.pow(a, b)) + 14 14 │ f(Math.pow(a, b), foo) + + +``` + +``` +invalidParentsWithHigherPrecedence.js:13:8 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 11 │ // parents with a higher precedence, but the expression's role doesn't require parens + 12 │ f(Math.pow(a, b)) + > 13 │ f(foo, Math.pow(a, b)) + │ ^^^^^^^^^^^^^^ + 14 │ f(Math.pow(a, b), foo) + 15 │ f(foo, Math.pow(a, b), bar) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 11 11 │ // parents with a higher precedence, but the expression's role doesn't require parens + 12 12 │ f(Math.pow(a, b)) + 13 │ - f(foo,·Math.pow(a,·b)) + 13 │ + f(foo,·a**b) + 14 14 │ f(Math.pow(a, b), foo) + 15 15 │ f(foo, Math.pow(a, b), bar) + + +``` + +``` +invalidParentsWithHigherPrecedence.js:14:3 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 12 │ f(Math.pow(a, b)) + 13 │ f(foo, Math.pow(a, b)) + > 14 │ f(Math.pow(a, b), foo) + │ ^^^^^^^^^^^^^^ + 15 │ f(foo, Math.pow(a, b), bar) + 16 │ new F(Math.pow(a, b)) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 12 12 │ f(Math.pow(a, b)) + 13 13 │ f(foo, Math.pow(a, b)) + 14 │ - f(Math.pow(a,·b),·foo) + 14 │ + f(a**b,·foo) + 15 15 │ f(foo, Math.pow(a, b), bar) + 16 16 │ new F(Math.pow(a, b)) + + +``` + +``` +invalidParentsWithHigherPrecedence.js:15:8 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 13 │ f(foo, Math.pow(a, b)) + 14 │ f(Math.pow(a, b), foo) + > 15 │ f(foo, Math.pow(a, b), bar) + │ ^^^^^^^^^^^^^^ + 16 │ new F(Math.pow(a, b)) + 17 │ new F(foo, Math.pow(a, b)) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 13 13 │ f(foo, Math.pow(a, b)) + 14 14 │ f(Math.pow(a, b), foo) + 15 │ - f(foo,·Math.pow(a,·b),·bar) + 15 │ + f(foo,·a**b,·bar) + 16 16 │ new F(Math.pow(a, b)) + 17 17 │ new F(foo, Math.pow(a, b)) + + +``` + +``` +invalidParentsWithHigherPrecedence.js:16:7 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 14 │ f(Math.pow(a, b), foo) + 15 │ f(foo, Math.pow(a, b), bar) + > 16 │ new F(Math.pow(a, b)) + │ ^^^^^^^^^^^^^^ + 17 │ new F(foo, Math.pow(a, b)) + 18 │ new F(Math.pow(a, b), foo) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 14 14 │ f(Math.pow(a, b), foo) + 15 15 │ f(foo, Math.pow(a, b), bar) + 16 │ - new·F(Math.pow(a,·b)) + 16 │ + new·F(a**b) + 17 17 │ new F(foo, Math.pow(a, b)) + 18 18 │ new F(Math.pow(a, b), foo) + + +``` + +``` +invalidParentsWithHigherPrecedence.js:17:12 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 15 │ f(foo, Math.pow(a, b), bar) + 16 │ new F(Math.pow(a, b)) + > 17 │ new F(foo, Math.pow(a, b)) + │ ^^^^^^^^^^^^^^ + 18 │ new F(Math.pow(a, b), foo) + 19 │ new F(foo, Math.pow(a, b), bar) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 15 15 │ f(foo, Math.pow(a, b), bar) + 16 16 │ new F(Math.pow(a, b)) + 17 │ - new·F(foo,·Math.pow(a,·b)) + 17 │ + new·F(foo,·a**b) + 18 18 │ new F(Math.pow(a, b), foo) + 19 19 │ new F(foo, Math.pow(a, b), bar) + + +``` + +``` +invalidParentsWithHigherPrecedence.js:18:7 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 16 │ new F(Math.pow(a, b)) + 17 │ new F(foo, Math.pow(a, b)) + > 18 │ new F(Math.pow(a, b), foo) + │ ^^^^^^^^^^^^^^ + 19 │ new F(foo, Math.pow(a, b), bar) + 20 │ obj[Math.pow(a, b)] + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 16 16 │ new F(Math.pow(a, b)) + 17 17 │ new F(foo, Math.pow(a, b)) + 18 │ - new·F(Math.pow(a,·b),·foo) + 18 │ + new·F(a**b,·foo) + 19 19 │ new F(foo, Math.pow(a, b), bar) + 20 20 │ obj[Math.pow(a, b)] + + +``` + +``` +invalidParentsWithHigherPrecedence.js:19:12 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 17 │ new F(foo, Math.pow(a, b)) + 18 │ new F(Math.pow(a, b), foo) + > 19 │ new F(foo, Math.pow(a, b), bar) + │ ^^^^^^^^^^^^^^ + 20 │ obj[Math.pow(a, b)] + 21 │ [foo, Math.pow(a, b), bar] + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 17 17 │ new F(foo, Math.pow(a, b)) + 18 18 │ new F(Math.pow(a, b), foo) + 19 │ - new·F(foo,·Math.pow(a,·b),·bar) + 19 │ + new·F(foo,·a**b,·bar) + 20 20 │ obj[Math.pow(a, b)] + 21 21 │ [foo, Math.pow(a, b), bar] + + +``` + +``` +invalidParentsWithHigherPrecedence.js:20:5 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 18 │ new F(Math.pow(a, b), foo) + 19 │ new F(foo, Math.pow(a, b), bar) + > 20 │ obj[Math.pow(a, b)] + │ ^^^^^^^^^^^^^^ + 21 │ [foo, Math.pow(a, b), bar] + 22 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 18 18 │ new F(Math.pow(a, b), foo) + 19 19 │ new F(foo, Math.pow(a, b), bar) + 20 │ - obj[Math.pow(a,·b)] + 20 │ + obj[a**b] + 21 21 │ [foo, Math.pow(a, b), bar] + 22 22 │ + + +``` + +``` +invalidParentsWithHigherPrecedence.js:21:7 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 19 │ new F(foo, Math.pow(a, b), bar) + 20 │ obj[Math.pow(a, b)] + > 21 │ [foo, Math.pow(a, b), bar] + │ ^^^^^^^^^^^^^^ + 22 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 19 19 │ new F(foo, Math.pow(a, b), bar) + 20 20 │ obj[Math.pow(a, b)] + 21 │ - [foo,·Math.pow(a,·b),·bar] + 21 │ + [foo,·a**b,·bar] + 22 22 │ + + +``` + + diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidParentsWithLowerPrecedence.js b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidParentsWithLowerPrecedence.js new file mode 100644 index 00000000000..6a2a5567555 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidParentsWithLowerPrecedence.js @@ -0,0 +1,13 @@ +// parents with a lower precedence +a * Math.pow(b, c); +Math.pow(a, b) * c; +a + Math.pow(b, c); +Math.pow(a, b)/c; +a < Math.pow(b, c); +Math.pow(a, b) > c; +a === Math.pow(b, c); +a ? Math.pow(b, c) : d; +a = Math.pow(b, c); +a += Math.pow(b, c); +function *f() { yield Math.pow(a, b) } +a, Math.pow(b, c), d diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidParentsWithLowerPrecedence.js.snap b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidParentsWithLowerPrecedence.js.snap new file mode 100644 index 00000000000..806af270d67 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidParentsWithLowerPrecedence.js.snap @@ -0,0 +1,309 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +assertion_line: 73 +expression: invalidParentsWithLowerPrecedence.js +--- +# Input +```js +// parents with a lower precedence +a * Math.pow(b, c); +Math.pow(a, b) * c; +a + Math.pow(b, c); +Math.pow(a, b)/c; +a < Math.pow(b, c); +Math.pow(a, b) > c; +a === Math.pow(b, c); +a ? Math.pow(b, c) : d; +a = Math.pow(b, c); +a += Math.pow(b, c); +function *f() { yield Math.pow(a, b) } +a, Math.pow(b, c), d + +``` + +# Diagnostics +``` +invalidParentsWithLowerPrecedence.js:2:5 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 1 │ // parents with a lower precedence + > 2 │ a * Math.pow(b, c); + │ ^^^^^^^^^^^^^^ + 3 │ Math.pow(a, b) * c; + 4 │ a + Math.pow(b, c); + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 1 1 │ // parents with a lower precedence + 2 │ - a·*·Math.pow(b,·c); + 2 │ + a·*·b**c; + 3 3 │ Math.pow(a, b) * c; + 4 4 │ a + Math.pow(b, c); + + +``` + +``` +invalidParentsWithLowerPrecedence.js:3:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 1 │ // parents with a lower precedence + 2 │ a * Math.pow(b, c); + > 3 │ Math.pow(a, b) * c; + │ ^^^^^^^^^^^^^^ + 4 │ a + Math.pow(b, c); + 5 │ Math.pow(a, b)/c; + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 1 1 │ // parents with a lower precedence + 2 2 │ a * Math.pow(b, c); + 3 │ - Math.pow(a,·b)·*·c; + 3 │ + a**b·*·c; + 4 4 │ a + Math.pow(b, c); + 5 5 │ Math.pow(a, b)/c; + + +``` + +``` +invalidParentsWithLowerPrecedence.js:4:5 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 2 │ a * Math.pow(b, c); + 3 │ Math.pow(a, b) * c; + > 4 │ a + Math.pow(b, c); + │ ^^^^^^^^^^^^^^ + 5 │ Math.pow(a, b)/c; + 6 │ a < Math.pow(b, c); + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 2 2 │ a * Math.pow(b, c); + 3 3 │ Math.pow(a, b) * c; + 4 │ - a·+·Math.pow(b,·c); + 4 │ + a·+·b**c; + 5 5 │ Math.pow(a, b)/c; + 6 6 │ a < Math.pow(b, c); + + +``` + +``` +invalidParentsWithLowerPrecedence.js:5:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 3 │ Math.pow(a, b) * c; + 4 │ a + Math.pow(b, c); + > 5 │ Math.pow(a, b)/c; + │ ^^^^^^^^^^^^^^ + 6 │ a < Math.pow(b, c); + 7 │ Math.pow(a, b) > c; + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 3 3 │ Math.pow(a, b) * c; + 4 4 │ a + Math.pow(b, c); + 5 │ - Math.pow(a,·b)/c; + 5 │ + a**b/c; + 6 6 │ a < Math.pow(b, c); + 7 7 │ Math.pow(a, b) > c; + + +``` + +``` +invalidParentsWithLowerPrecedence.js:6:5 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 4 │ a + Math.pow(b, c); + 5 │ Math.pow(a, b)/c; + > 6 │ a < Math.pow(b, c); + │ ^^^^^^^^^^^^^^ + 7 │ Math.pow(a, b) > c; + 8 │ a === Math.pow(b, c); + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 4 4 │ a + Math.pow(b, c); + 5 5 │ Math.pow(a, b)/c; + 6 │ - a·<·Math.pow(b,·c); + 6 │ + a·<·b**c; + 7 7 │ Math.pow(a, b) > c; + 8 8 │ a === Math.pow(b, c); + + +``` + +``` +invalidParentsWithLowerPrecedence.js:7:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 5 │ Math.pow(a, b)/c; + 6 │ a < Math.pow(b, c); + > 7 │ Math.pow(a, b) > c; + │ ^^^^^^^^^^^^^^ + 8 │ a === Math.pow(b, c); + 9 │ a ? Math.pow(b, c) : d; + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 5 5 │ Math.pow(a, b)/c; + 6 6 │ a < Math.pow(b, c); + 7 │ - Math.pow(a,·b)·>·c; + 7 │ + a**b·>·c; + 8 8 │ a === Math.pow(b, c); + 9 9 │ a ? Math.pow(b, c) : d; + + +``` + +``` +invalidParentsWithLowerPrecedence.js:8:7 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 6 │ a < Math.pow(b, c); + 7 │ Math.pow(a, b) > c; + > 8 │ a === Math.pow(b, c); + │ ^^^^^^^^^^^^^^ + 9 │ a ? Math.pow(b, c) : d; + 10 │ a = Math.pow(b, c); + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 6 6 │ a < Math.pow(b, c); + 7 7 │ Math.pow(a, b) > c; + 8 │ - a·===·Math.pow(b,·c); + 8 │ + a·===·b**c; + 9 9 │ a ? Math.pow(b, c) : d; + 10 10 │ a = Math.pow(b, c); + + +``` + +``` +invalidParentsWithLowerPrecedence.js:9:5 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 7 │ Math.pow(a, b) > c; + 8 │ a === Math.pow(b, c); + > 9 │ a ? Math.pow(b, c) : d; + │ ^^^^^^^^^^^^^^ + 10 │ a = Math.pow(b, c); + 11 │ a += Math.pow(b, c); + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 7 7 │ Math.pow(a, b) > c; + 8 8 │ a === Math.pow(b, c); + 9 │ - a·?·Math.pow(b,·c)·:·d; + 9 │ + a·?·b**c·:·d; + 10 10 │ a = Math.pow(b, c); + 11 11 │ a += Math.pow(b, c); + + +``` + +``` +invalidParentsWithLowerPrecedence.js:10:5 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 8 │ a === Math.pow(b, c); + 9 │ a ? Math.pow(b, c) : d; + > 10 │ a = Math.pow(b, c); + │ ^^^^^^^^^^^^^^ + 11 │ a += Math.pow(b, c); + 12 │ function *f() { yield Math.pow(a, b) } + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 8 8 │ a === Math.pow(b, c); + 9 9 │ a ? Math.pow(b, c) : d; + 10 │ - a·=·Math.pow(b,·c); + 10 │ + a·=·b**c; + 11 11 │ a += Math.pow(b, c); + 12 12 │ function *f() { yield Math.pow(a, b) } + + +``` + +``` +invalidParentsWithLowerPrecedence.js:11:6 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 9 │ a ? Math.pow(b, c) : d; + 10 │ a = Math.pow(b, c); + > 11 │ a += Math.pow(b, c); + │ ^^^^^^^^^^^^^^ + 12 │ function *f() { yield Math.pow(a, b) } + 13 │ a, Math.pow(b, c), d + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 9 9 │ a ? Math.pow(b, c) : d; + 10 10 │ a = Math.pow(b, c); + 11 │ - a·+=·Math.pow(b,·c); + 11 │ + a·+=·b**c; + 12 12 │ function *f() { yield Math.pow(a, b) } + 13 13 │ a, Math.pow(b, c), d + + +``` + +``` +invalidParentsWithLowerPrecedence.js:12:23 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 10 │ a = Math.pow(b, c); + 11 │ a += Math.pow(b, c); + > 12 │ function *f() { yield Math.pow(a, b) } + │ ^^^^^^^^^^^^^^ + 13 │ a, Math.pow(b, c), d + 14 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 10 10 │ a = Math.pow(b, c); + 11 11 │ a += Math.pow(b, c); + 12 │ - function·*f()·{·yield·Math.pow(a,·b)·} + 12 │ + function·*f()·{·yield·a**b·} + 13 13 │ a, Math.pow(b, c), d + 14 14 │ + + +``` + +``` +invalidParentsWithLowerPrecedence.js:13:4 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 11 │ a += Math.pow(b, c); + 12 │ function *f() { yield Math.pow(a, b) } + > 13 │ a, Math.pow(b, c), d + │ ^^^^^^^^^^^^^^ + 14 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 11 11 │ a += Math.pow(b, c); + 12 12 │ function *f() { yield Math.pow(a, b) } + 13 │ - a,·Math.pow(b,·c),·d + 13 │ + a,·b**c,·d + 14 14 │ + + +``` + + diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidUnaryExpression.js b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidUnaryExpression.js new file mode 100644 index 00000000000..624305ec994 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidUnaryExpression.js @@ -0,0 +1,9 @@ +// unary expressions are exception by the language - parens are required for the base to disambiguate operator precedence +Math.pow(+a, b) +Math.pow(a, +b) +Math.pow(-a, b) +Math.pow(a, -b) +Math.pow(-2, 3) +Math.pow(2, -3) +async () => Math.pow(await a, b) +async () => Math.pow(a, await b) diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidUnaryExpression.js.snap b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidUnaryExpression.js.snap new file mode 100644 index 00000000000..e34c0be71e7 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidUnaryExpression.js.snap @@ -0,0 +1,209 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +assertion_line: 74 +expression: invalidUnaryExpression.js +--- +# Input +```js +// unary expressions are exception by the language - parens are required for the base to disambiguate operator precedence +Math.pow(+a, b) +Math.pow(a, +b) +Math.pow(-a, b) +Math.pow(a, -b) +Math.pow(-2, 3) +Math.pow(2, -3) +async () => Math.pow(await a, b) +async () => Math.pow(a, await b) + +``` + +# Diagnostics +``` +invalidUnaryExpression.js:2:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 1 │ // unary expressions are exception by the language - parens are required for the base to disambiguate operator precedence + > 2 │ Math.pow(+a, b) + │ ^^^^^^^^^^^^^^^ + 3 │ Math.pow(a, +b) + 4 │ Math.pow(-a, b) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 1 1 │ // unary expressions are exception by the language - parens are required for the base to disambiguate operator precedence + 2 │ - Math.pow(+a,·b) + 2 │ + (+a)**b + 3 3 │ Math.pow(a, +b) + 4 4 │ Math.pow(-a, b) + + +``` + +``` +invalidUnaryExpression.js:3:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 1 │ // unary expressions are exception by the language - parens are required for the base to disambiguate operator precedence + 2 │ Math.pow(+a, b) + > 3 │ Math.pow(a, +b) + │ ^^^^^^^^^^^^^^^ + 4 │ Math.pow(-a, b) + 5 │ Math.pow(a, -b) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 1 1 │ // unary expressions are exception by the language - parens are required for the base to disambiguate operator precedence + 2 2 │ Math.pow(+a, b) + 3 │ - Math.pow(a,·+b) + 3 │ + a**+b + 4 4 │ Math.pow(-a, b) + 5 5 │ Math.pow(a, -b) + + +``` + +``` +invalidUnaryExpression.js:4:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 2 │ Math.pow(+a, b) + 3 │ Math.pow(a, +b) + > 4 │ Math.pow(-a, b) + │ ^^^^^^^^^^^^^^^ + 5 │ Math.pow(a, -b) + 6 │ Math.pow(-2, 3) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 2 2 │ Math.pow(+a, b) + 3 3 │ Math.pow(a, +b) + 4 │ - Math.pow(-a,·b) + 4 │ + (-a)**b + 5 5 │ Math.pow(a, -b) + 6 6 │ Math.pow(-2, 3) + + +``` + +``` +invalidUnaryExpression.js:5:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 3 │ Math.pow(a, +b) + 4 │ Math.pow(-a, b) + > 5 │ Math.pow(a, -b) + │ ^^^^^^^^^^^^^^^ + 6 │ Math.pow(-2, 3) + 7 │ Math.pow(2, -3) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 3 3 │ Math.pow(a, +b) + 4 4 │ Math.pow(-a, b) + 5 │ - Math.pow(a,·-b) + 5 │ + a**-b + 6 6 │ Math.pow(-2, 3) + 7 7 │ Math.pow(2, -3) + + +``` + +``` +invalidUnaryExpression.js:6:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 4 │ Math.pow(-a, b) + 5 │ Math.pow(a, -b) + > 6 │ Math.pow(-2, 3) + │ ^^^^^^^^^^^^^^^ + 7 │ Math.pow(2, -3) + 8 │ async () => Math.pow(await a, b) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 4 4 │ Math.pow(-a, b) + 5 5 │ Math.pow(a, -b) + 6 │ - Math.pow(-2,·3) + 6 │ + (-2)**3 + 7 7 │ Math.pow(2, -3) + 8 8 │ async () => Math.pow(await a, b) + + +``` + +``` +invalidUnaryExpression.js:7:1 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 5 │ Math.pow(a, -b) + 6 │ Math.pow(-2, 3) + > 7 │ Math.pow(2, -3) + │ ^^^^^^^^^^^^^^^ + 8 │ async () => Math.pow(await a, b) + 9 │ async () => Math.pow(a, await b) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 5 5 │ Math.pow(a, -b) + 6 6 │ Math.pow(-2, 3) + 7 │ - Math.pow(2,·-3) + 7 │ + 2**-3 + 8 8 │ async () => Math.pow(await a, b) + 9 9 │ async () => Math.pow(a, await b) + + +``` + +``` +invalidUnaryExpression.js:8:13 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 6 │ Math.pow(-2, 3) + 7 │ Math.pow(2, -3) + > 8 │ async () => Math.pow(await a, b) + │ ^^^^^^^^^^^^^^^^^^^^ + 9 │ async () => Math.pow(a, await b) + 10 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 6 6 │ Math.pow(-2, 3) + 7 7 │ Math.pow(2, -3) + 8 │ - async·()·=>·Math.pow(await·a,·b) + 8 │ + async·()·=>·(await·a)**b + 9 9 │ async () => Math.pow(a, await b) + 10 10 │ + + +``` + +``` +invalidUnaryExpression.js:9:13 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 7 │ Math.pow(2, -3) + 8 │ async () => Math.pow(await a, b) + > 9 │ async () => Math.pow(a, await b) + │ ^^^^^^^^^^^^^^^^^^^^ + 10 │ + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 7 7 │ Math.pow(2, -3) + 8 8 │ async () => Math.pow(await a, b) + 9 │ - async·()·=>·Math.pow(a,·await·b) + 9 │ + async·()·=>·a**await·b + 10 10 │ + + +``` + + diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidWithoutAutofix.js b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidWithoutAutofix.js new file mode 100644 index 00000000000..83287ea52ff --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidWithoutAutofix.js @@ -0,0 +1,19 @@ +// shouldn't autofix if the call doesn't have exactly two arguments +Math.pow() +Math.pow(a) +Math.pow(a, b, c) +Math.pow(a, b, c, d) + +// shouldn't autofix if any of the arguments is spread +Math.pow(...a) +Math.pow(...a, b) +Math.pow(a, ...b) +Math.pow(a, b, ...c) + +// shouldn't autofix if that would remove comments +/* comment */Math.pow(a, b) +Math.pow(/**/a, b) +Math.pow(a, b/**/) +Math.pow(a, b)/* comment */; +Math.pow(a, b)// comment; +Math.pow(/**/a/**/, /**/b/**/) diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidWithoutAutofix.js.snap b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidWithoutAutofix.js.snap new file mode 100644 index 00000000000..5febba49cea --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/invalidWithoutAutofix.js.snap @@ -0,0 +1,246 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +assertion_line: 74 +expression: invalidWithoutAutofix.js +--- +# Input +```js +// shouldn't autofix if the call doesn't have exactly two arguments +Math.pow() +Math.pow(a) +Math.pow(a, b, c) +Math.pow(a, b, c, d) + +// shouldn't autofix if any of the arguments is spread +Math.pow(...a) +Math.pow(...a, b) +Math.pow(a, ...b) +Math.pow(a, b, ...c) + +// shouldn't autofix if that would remove comments +/* comment */Math.pow(a, b) +Math.pow(/**/a, b) +Math.pow(a, b/**/) +Math.pow(a, b)/* comment */; +Math.pow(a, b)// comment; +Math.pow(/**/a/**/, /**/b/**/) + +``` + +# Diagnostics +``` +invalidWithoutAutofix.js:2:1 lint/nursery/useExponentiationOperator ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 1 │ // shouldn't autofix if the call doesn't have exactly two arguments + > 2 │ Math.pow() + │ ^^^^^^^^^^ + 3 │ Math.pow(a) + 4 │ Math.pow(a, b, c) + + +``` + +``` +invalidWithoutAutofix.js:3:1 lint/nursery/useExponentiationOperator ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 1 │ // shouldn't autofix if the call doesn't have exactly two arguments + 2 │ Math.pow() + > 3 │ Math.pow(a) + │ ^^^^^^^^^^^ + 4 │ Math.pow(a, b, c) + 5 │ Math.pow(a, b, c, d) + + +``` + +``` +invalidWithoutAutofix.js:4:1 lint/nursery/useExponentiationOperator ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 2 │ Math.pow() + 3 │ Math.pow(a) + > 4 │ Math.pow(a, b, c) + │ ^^^^^^^^^^^^^^^^^ + 5 │ Math.pow(a, b, c, d) + 6 │ + + +``` + +``` +invalidWithoutAutofix.js:5:1 lint/nursery/useExponentiationOperator ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 3 │ Math.pow(a) + 4 │ Math.pow(a, b, c) + > 5 │ Math.pow(a, b, c, d) + │ ^^^^^^^^^^^^^^^^^^^^ + 6 │ + 7 │ // shouldn't autofix if any of the arguments is spread + + +``` + +``` +invalidWithoutAutofix.js:8:1 lint/nursery/useExponentiationOperator ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 7 │ // shouldn't autofix if any of the arguments is spread + > 8 │ Math.pow(...a) + │ ^^^^^^^^^^^^^^ + 9 │ Math.pow(...a, b) + 10 │ Math.pow(a, ...b) + + +``` + +``` +invalidWithoutAutofix.js:9:1 lint/nursery/useExponentiationOperator ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 7 │ // shouldn't autofix if any of the arguments is spread + 8 │ Math.pow(...a) + > 9 │ Math.pow(...a, b) + │ ^^^^^^^^^^^^^^^^^ + 10 │ Math.pow(a, ...b) + 11 │ Math.pow(a, b, ...c) + + +``` + +``` +invalidWithoutAutofix.js:10:1 lint/nursery/useExponentiationOperator ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 8 │ Math.pow(...a) + 9 │ Math.pow(...a, b) + > 10 │ Math.pow(a, ...b) + │ ^^^^^^^^^^^^^^^^^ + 11 │ Math.pow(a, b, ...c) + 12 │ + + +``` + +``` +invalidWithoutAutofix.js:11:1 lint/nursery/useExponentiationOperator ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 9 │ Math.pow(...a, b) + 10 │ Math.pow(a, ...b) + > 11 │ Math.pow(a, b, ...c) + │ ^^^^^^^^^^^^^^^^^^^^ + 12 │ + 13 │ // shouldn't autofix if that would remove comments + + +``` + +``` +invalidWithoutAutofix.js:14:14 lint/nursery/useExponentiationOperator FIXABLE ━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 13 │ // shouldn't autofix if that would remove comments + > 14 │ /* comment */Math.pow(a, b) + │ ^^^^^^^^^^^^^^ + 15 │ Math.pow(/**/a, b) + 16 │ Math.pow(a, b/**/) + + i Suggested fix: Use the '**' operator instead of 'Math.pow'. + + 12 12 │ + 13 13 │ // shouldn't autofix if that would remove comments + 14 │ - /*·comment·*/Math.pow(a,·b) + 14 │ + /*·comment·*/a**b + 15 15 │ Math.pow(/**/a, b) + 16 16 │ Math.pow(a, b/**/) + + +``` + +``` +invalidWithoutAutofix.js:15:1 lint/nursery/useExponentiationOperator ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 13 │ // shouldn't autofix if that would remove comments + 14 │ /* comment */Math.pow(a, b) + > 15 │ Math.pow(/**/a, b) + │ ^^^^^^^^^^^^^^^^^^ + 16 │ Math.pow(a, b/**/) + 17 │ Math.pow(a, b)/* comment */; + + +``` + +``` +invalidWithoutAutofix.js:16:1 lint/nursery/useExponentiationOperator ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 14 │ /* comment */Math.pow(a, b) + 15 │ Math.pow(/**/a, b) + > 16 │ Math.pow(a, b/**/) + │ ^^^^^^^^^^^^^^^^^^ + 17 │ Math.pow(a, b)/* comment */; + 18 │ Math.pow(a, b)// comment; + + +``` + +``` +invalidWithoutAutofix.js:17:1 lint/nursery/useExponentiationOperator ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 15 │ Math.pow(/**/a, b) + 16 │ Math.pow(a, b/**/) + > 17 │ Math.pow(a, b)/* comment */; + │ ^^^^^^^^^^^^^^ + 18 │ Math.pow(a, b)// comment; + 19 │ Math.pow(/**/a/**/, /**/b/**/) + + +``` + +``` +invalidWithoutAutofix.js:18:1 lint/nursery/useExponentiationOperator ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 16 │ Math.pow(a, b/**/) + 17 │ Math.pow(a, b)/* comment */; + > 18 │ Math.pow(a, b)// comment; + │ ^^^^^^^^^^^^^^ + 19 │ Math.pow(/**/a/**/, /**/b/**/) + 20 │ + + +``` + +``` +invalidWithoutAutofix.js:19:1 lint/nursery/useExponentiationOperator ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Use the '**' operator instead of 'Math.pow'. + + 17 │ Math.pow(a, b)/* comment */; + 18 │ Math.pow(a, b)// comment; + > 19 │ Math.pow(/**/a/**/, /**/b/**/) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 20 │ + + +``` + + diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/valid.js b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/valid.js new file mode 100644 index 00000000000..682ff4dbb62 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/valid.js @@ -0,0 +1,16 @@ +// not Math.pow() +Object.pow(a, b) +Math.max(a, b) +Math +Math(a, b) +pow +pow(a, b) +Math.pow +Math.Pow(a, b) +math.pow(a, b) +foo.Math.pow(a, b) +new Math.pow(a, b) +Math[pow](a, b) +globalThis.Object.pow(a, b) +globalThis.Math.max(a, b) +class C { #pow; foo() { Math.#pow(a, b); } } diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/valid.js.snap b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/valid.js.snap new file mode 100644 index 00000000000..954fc4feaf2 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/valid.js.snap @@ -0,0 +1,27 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +assertion_line: 73 +expression: valid.js +--- +# Input +```js +// not Math.pow() +Object.pow(a, b) +Math.max(a, b) +Math +Math(a, b) +pow +pow(a, b) +Math.pow +Math.Pow(a, b) +math.pow(a, b) +foo.Math.pow(a, b) +new Math.pow(a, b) +Math[pow](a, b) +globalThis.Object.pow(a, b) +globalThis.Math.max(a, b) +class C { #pow; foo() { Math.#pow(a, b); } } + +``` + + diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/validLocalMath.js b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/validLocalMath.js new file mode 100644 index 00000000000..88aaac7022c --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/validLocalMath.js @@ -0,0 +1,25 @@ +// not the global Math +function case1() { + let Math; + Math.pow(a, b); +} + +function case2(Math) { + Math.pow(a, b); +} + +var case3 = function Math() { + Math.pow(a, b); +} + +function case4() { + Math.pow(a, b); + var Math; +} + +function case5() { + if (foo) { + const Math = 1; + Math.pow(a, b); + } +} diff --git a/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/validLocalMath.js.snap b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/validLocalMath.js.snap new file mode 100644 index 00000000000..165d3561297 --- /dev/null +++ b/crates/rome_js_analyze/tests/specs/nursery/useExponentiationOperator/validLocalMath.js.snap @@ -0,0 +1,36 @@ +--- +source: crates/rome_js_analyze/tests/spec_tests.rs +assertion_line: 83 +expression: validLocalMath.js +--- +# Input +```js +// not the global Math +function case1() { + let Math; + Math.pow(a, b); +} + +function case2(Math) { + Math.pow(a, b); +} + +var case3 = function Math() { + Math.pow(a, b); +} + +function case4() { + Math.pow(a, b); + var Math; +} + +function case5() { + if (foo) { + const Math = 1; + Math.pow(a, b); + } +} + +``` + + diff --git a/crates/rome_service/src/configuration/linter/rules.rs b/crates/rome_service/src/configuration/linter/rules.rs index b00c03e7fa1..70b83d3dabe 100644 --- a/crates/rome_service/src/configuration/linter/rules.rs +++ b/crates/rome_service/src/configuration/linter/rules.rs @@ -785,6 +785,8 @@ struct NurserySchema { use_enum_initializers: Option, #[doc = "Enforce all dependencies are correctly specified."] use_exhaustive_dependencies: Option, + #[doc = "Disallow the use of Math.pow in favor of the ** operator."] + use_exponentiation_operator: Option, #[doc = "Promotes the use of .flatMap() when map().flat() are used together."] use_flat_map: Option, #[doc = "Disallow parseInt() and Number.parseInt() in favor of binary, octal, and hexadecimal literals"] @@ -794,7 +796,7 @@ struct NurserySchema { } impl Nursery { const CATEGORY_NAME: &'static str = "nursery"; - pub(crate) const CATEGORY_RULES: [&'static str; 31] = [ + pub(crate) const CATEGORY_RULES: [&'static str; 32] = [ "noAccessKey", "noBannedTypes", "noConditionalAssignment", @@ -823,6 +825,7 @@ impl Nursery { "useDefaultSwitchClauseLast", "useEnumInitializers", "useExhaustiveDependencies", + "useExponentiationOperator", "useFlatMap", "useNumericLiterals", "useValidForDirection", @@ -879,9 +882,9 @@ impl Nursery { RuleFilter::Rule("nursery", Self::CATEGORY_RULES[25]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[26]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[27]), - RuleFilter::Rule("nursery", Self::CATEGORY_RULES[28]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[29]), RuleFilter::Rule("nursery", Self::CATEGORY_RULES[30]), + RuleFilter::Rule("nursery", Self::CATEGORY_RULES[31]), ]; pub(crate) fn is_recommended(&self) -> bool { !matches!(self.recommended, Some(false)) } pub(crate) fn get_enabled_rules(&self) -> IndexSet { diff --git a/editors/vscode/configuration_schema.json b/editors/vscode/configuration_schema.json index 7267a325d32..779180c5288 100644 --- a/editors/vscode/configuration_schema.json +++ b/editors/vscode/configuration_schema.json @@ -1068,6 +1068,17 @@ } ] }, + "useExponentiationOperator": { + "description": "Disallow the use of Math.pow in favor of the ** operator.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, "useFlatMap": { "description": "Promotes the use of .flatMap() when map().flat() are used together.", "anyOf": [ diff --git a/npm/backend-jsonrpc/src/workspace.ts b/npm/backend-jsonrpc/src/workspace.ts index 08f26ab6539..e37ff47ba02 100644 --- a/npm/backend-jsonrpc/src/workspace.ts +++ b/npm/backend-jsonrpc/src/workspace.ts @@ -463,6 +463,10 @@ export interface Nursery { * Enforce all dependencies are correctly specified. */ useExhaustiveDependencies?: RuleConfiguration; + /** + * Disallow the use of Math.pow in favor of the ** operator. + */ + useExponentiationOperator?: RuleConfiguration; /** * Promotes the use of .flatMap() when map().flat() are used together. */ @@ -704,6 +708,7 @@ export type Category = | "lint/nursery/useDefaultSwitchClauseLast" | "lint/nursery/useEnumInitializers" | "lint/nursery/useExhaustiveDependencies" + | "lint/nursery/useExponentiationOperator" | "lint/nursery/useFlatMap" | "lint/nursery/useNumericLiterals" | "lint/nursery/useValidForDirection" diff --git a/npm/rome/configuration_schema.json b/npm/rome/configuration_schema.json index 7267a325d32..779180c5288 100644 --- a/npm/rome/configuration_schema.json +++ b/npm/rome/configuration_schema.json @@ -1068,6 +1068,17 @@ } ] }, + "useExponentiationOperator": { + "description": "Disallow the use of Math.pow in favor of the ** operator.", + "anyOf": [ + { + "$ref": "#/definitions/RuleConfiguration" + }, + { + "type": "null" + } + ] + }, "useFlatMap": { "description": "Promotes the use of .flatMap() when map().flat() are used together.", "anyOf": [ diff --git a/website/src/pages/lint/rules/index.mdx b/website/src/pages/lint/rules/index.mdx index a7f50017938..4b176e24d01 100644 --- a/website/src/pages/lint/rules/index.mdx +++ b/website/src/pages/lint/rules/index.mdx @@ -614,6 +614,12 @@ Require that each enum member value be explicitly initialized. Enforce all dependencies are correctly specified.
+

+ useExponentiationOperator +

+Disallow the use of Math.pow in favor of the ** operator. +
+

useFlatMap

diff --git a/website/src/pages/lint/rules/useExponentiationOperator.md b/website/src/pages/lint/rules/useExponentiationOperator.md new file mode 100644 index 00000000000..49e2e3c6a06 --- /dev/null +++ b/website/src/pages/lint/rules/useExponentiationOperator.md @@ -0,0 +1,111 @@ +--- +title: Lint Rule useExponentiationOperator +parent: lint/rules/index +--- + +# useExponentiationOperator (since v11.0.0) + +Disallow the use of `Math.pow` in favor of the `**` operator. + +>Introduced in ES2016, the infix exponentiation operator ** is an alternative for the standard Math.pow function. +Infix notation is considered to be more readable and thus more preferable than the function notation. + + +Source: https://eslint.org/docs/latest/rules/prefer-exponentiation-operator + +## Examples + +### Invalid + +```jsx +const foo = Math.pow(2, 8); +``` + +
nursery/useExponentiationOperator.js:1:13 lint/nursery/useExponentiationOperator  FIXABLE  ━━━━━━━━━━
+
+   Use the '**' operator instead of 'Math.pow'.
+  
+  > 1 │ const foo = Math.pow(2, 8);
+               ^^^^^^^^^^^^^^
+    2 │ 
+  
+   Suggested fix: Use the '**' operator instead of 'Math.pow'.
+  
+    1  - const·foo·=·Math.pow(2,·8);
+      1+ const·foo·=·2**8;
+    2 2  
+  
+
+ +```jsx +const bar = Math.pow(a, b); +``` + +
nursery/useExponentiationOperator.js:1:13 lint/nursery/useExponentiationOperator  FIXABLE  ━━━━━━━━━━
+
+   Use the '**' operator instead of 'Math.pow'.
+  
+  > 1 │ const bar = Math.pow(a, b);
+               ^^^^^^^^^^^^^^
+    2 │ 
+  
+   Suggested fix: Use the '**' operator instead of 'Math.pow'.
+  
+    1  - const·bar·=·Math.pow(a,·b);
+      1+ const·bar·=·a**b;
+    2 2  
+  
+
+ +```jsx +let baz = Math.pow(a + b, c + d); +``` + +
nursery/useExponentiationOperator.js:1:11 lint/nursery/useExponentiationOperator  FIXABLE  ━━━━━━━━━━
+
+   Use the '**' operator instead of 'Math.pow'.
+  
+  > 1 │ let baz = Math.pow(a + b, c + d);
+             ^^^^^^^^^^^^^^^^^^^^^^
+    2 │ 
+  
+   Suggested fix: Use the '**' operator instead of 'Math.pow'.
+  
+    1  - let·baz·=·Math.pow(a·+·b,·c·+·d);
+      1+ let·baz·=·(a·+·b)**(c·+·d);
+    2 2  
+  
+
+ +```jsx +let quux = Math.pow(-1, n); +``` + +
nursery/useExponentiationOperator.js:1:12 lint/nursery/useExponentiationOperator  FIXABLE  ━━━━━━━━━━
+
+   Use the '**' operator instead of 'Math.pow'.
+  
+  > 1 │ let quux = Math.pow(-1, n);
+              ^^^^^^^^^^^^^^^
+    2 │ 
+  
+   Suggested fix: Use the '**' operator instead of 'Math.pow'.
+  
+    1  - let·quux·=·Math.pow(-1,·n);
+      1+ let·quux·=·(-1)**n;
+    2 2  
+  
+
+ +### Valid + +```jsx +const foo = 2 ** 8; + +const bar = a ** b; + +let baz = (a + b) ** (c + d); + +let quux = (-1) ** n; +``` +