fix(rome_js_analyze): remove double negation check
MODIFY
crates/rome_js_analyze/src/analyzers/correctness/use_simplified_logic_expression.rs
crates/rome_js_analyze/src/analyzers/correctness/use_simplified_logic_expression.rs
@@ -2,12 +2,11 @@ use rome_analyze::{context::RuleContext, declare_rule, ActionCategory, Ast, Rule
use rome_console::markup;
use rome_diagnostics::Applicability;
use rome_js_factory::make;
-use rome_js_syntax::JsUnaryOperator::LogicalNot;
use rome_js_syntax::{
JsAnyExpression, JsAnyLiteralExpression, JsBooleanLiteralExpression, JsLogicalExpression,
JsUnaryExpression, JsUnaryOperator, T,
};
-use rome_rowan::{declare_node_union, AstNode, AstNodeExt, BatchMutationExt};
+use rome_rowan::{AstNode, AstNodeExt, BatchMutationExt};
use crate::JsRuleAction;
@@ -39,10 +38,6 @@ declare_rule! {
/// const r4 = !boolExpr1 || !boolExpr2;
/// ```
///
- /// ```js,expect_diagnostic
- /// const boolExp2 = true;
- /// const r2 = !!boolExp2;
- /// ```
/// ### Valid
/// ```js
/// const boolExpr3 = true;
@@ -59,12 +54,8 @@ declare_rule! {
}
}
-declare_node_union! {
- pub(crate) AnyLogicalLikeExpression = JsLogicalExpression | JsUnaryExpression
-}
-
impl Rule for UseSimplifiedLogicExpression {
- type Query = Ast<AnyLogicalLikeExpression>;
+ type Query = Ast<JsLogicalExpression>;
/// First element of tuple is if the expression is simplified by [De Morgan's Law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws) rule, the second element is the expression to replace.
type State = (bool, JsAnyExpression);
type Signals = Option<Self::State>;
@@ -72,8 +63,6 @@ impl Rule for UseSimplifiedLogicExpression {
fn run(ctx: &RuleContext<Self>) -> Option<Self::State> {
let node = ctx.query();
- match node {
- AnyLogicalLikeExpression::JsLogicalExpression(node) => {
let left = node.left().ok()?;
let right = node.right().ok()?;
match node.operator().ok()? {
@@ -92,8 +81,7 @@ impl Rule for UseSimplifiedLogicExpression {
JsAnyLiteralExpression::JsBooleanLiteralExpression(literal),
) = left
{
- return simplify_or_expression(literal, right)
- .map(|expr| (false, expr));
+ return simplify_or_expression(literal, right).map(|expr| (false, expr));
}
if let JsAnyExpression::JsAnyLiteralExpression(
@@ -113,16 +101,14 @@ impl Rule for UseSimplifiedLogicExpression {
JsAnyLiteralExpression::JsBooleanLiteralExpression(literal),
) = left
{
- return simplify_and_expression(literal, right)
- .map(|expr| (false, expr));
+ return simplify_and_expression(literal, right).map(|expr| (false, expr));
}
if let JsAnyExpression::JsAnyLiteralExpression(
JsAnyLiteralExpression::JsBooleanLiteralExpression(literal),
) = right
{
- return simplify_and_expression(literal, left)
- .map(|expr| (false, expr));
+ return simplify_and_expression(literal, left).map(|expr| (false, expr));
}
if could_apply_de_morgan(node).unwrap_or(false) {
@@ -132,18 +118,6 @@ impl Rule for UseSimplifiedLogicExpression {
}
_ => return None,
}
- }
- AnyLogicalLikeExpression::JsUnaryExpression(unary_expression) => {
- if unary_expression.operator().ok()? == LogicalNot {
- let nested_unary = unary_expression.argument().ok()?;
- let nested_unary = nested_unary.as_js_unary_expression()?;
- if nested_unary.operator().ok()? == LogicalNot {
- let expression = nested_unary.argument().ok()?;
- return Some((false, expression));
- }
- }
- }
- }
None
}
@@ -165,18 +139,11 @@ impl Rule for UseSimplifiedLogicExpression {
let mut mutation = ctx.root().begin();
let (is_simplified_by_de_morgan, expr) = state;
- match node {
- AnyLogicalLikeExpression::JsLogicalExpression(node) => {
+
mutation.replace_node(
JsAnyExpression::JsLogicalExpression(node.clone()),
expr.clone(),
);
- }
- AnyLogicalLikeExpression::JsUnaryExpression(unary) => mutation.replace_element(
- unary.clone().into_syntax().into(),
- expr.clone().into_syntax().into(),
- ),
- }
let message = if *is_simplified_by_de_morgan {
"Reduce the complexity of the logical expression."

MODIFY
crates/rome_js_analyze/src/analyzers/style/no_negation_else.rs
crates/rome_js_analyze/src/analyzers/style/no_negation_else.rs
@@ -136,8 +136,18 @@ impl Rule for NoNegationElse {
fn is_negation(node: &JsAnyExpression) -> Option<bool> {
match node {
JsAnyExpression::JsUnaryExpression(expr) => {
- Some(expr.operator().ok()? == JsUnaryOperator::LogicalNot)
+ let argument = expr.argument().ok()?;
+ if expr.operator().ok()? == JsUnaryOperator::LogicalNot {
+ if !JsUnaryExpression::can_cast(argument.syntax().kind()) {
+ Some(true)
+ } else {
+ Some(false)
+ }
+ } else {
+ Some(false)
}
+ }
+
_ => Some(false),
}
}

MODIFY
crates/rome_js_analyze/tests/specs/correctness/useSimplifiedLogicExpression.js
crates/rome_js_analyze/tests/specs/correctness/useSimplifiedLogicExpression.js
@@ -5,6 +5,7 @@ const r5 = !(boolExpr1 && boolExpr2);
const boolExpr5 = true;
const boolExpr6 = false;
const r6 = !!boolExpr1 || !!boolExpr2;
+!!x
// invalid
const boolExp = true;
const r = true && boolExp;
@@ -15,4 +16,3 @@ const r3 = null ?? nonNullExp;
const boolExpr1 = true;
const boolExpr2 = false;
const r4 = !boolExpr1 || !boolExpr2;
-!!x

ADD
crates/rome_js_analyze/tests/specs/style/noNegationElse/issue_3141.js
+// valid
+function f() {
+ return !!specs.variables ? specs.variables(props) : {};
+}
\ No newline at end of file

ADD
crates/rome_js_analyze/tests/specs/style/noNegationElse/issue_3141.js.snap
+---
+source: crates/rome_js_analyze/tests/spec_tests.rs
+expression: issue_3141.js
+---
+# Input
+```js
+// valid
+function f() {
+ return !!specs.variables ? specs.variables(props) : {};
+}
+```
+
+

fix(rome_js_analyze): remove double negation check (#3488)