From 5b0ceb4abee0a381c3cc867537aec43bd6ea07bd Mon Sep 17 00:00:00 2001 From: wenzhe Date: Thu, 6 Apr 2023 23:04:35 +0800 Subject: [PATCH 1/5] feat(linter): if statement --- crates/oxc_linter/src/rules.rs | 1 + .../src/rules/no_constant_condition.rs | 344 +++++++++ .../src/snapshots/no_constant_condition.snap | 726 ++++++++++++++++++ 3 files changed, 1071 insertions(+) create mode 100644 crates/oxc_linter/src/rules/no_constant_condition.rs create mode 100644 crates/oxc_linter/src/snapshots/no_constant_condition.snap diff --git a/crates/oxc_linter/src/rules.rs b/crates/oxc_linter/src/rules.rs index 94d7f202f8dfe..aeb9df9807968 100644 --- a/crates/oxc_linter/src/rules.rs +++ b/crates/oxc_linter/src/rules.rs @@ -23,6 +23,7 @@ oxc_macros::declare_all_lint_rules! { no_self_compare, no_mixed_operators, no_constant_binary_expression, + no_constant_condition, no_compare_neg_zero, no_unsafe_negation, no_bitwise, diff --git a/crates/oxc_linter/src/rules/no_constant_condition.rs b/crates/oxc_linter/src/rules/no_constant_condition.rs new file mode 100644 index 0000000000000..76587bf1075c9 --- /dev/null +++ b/crates/oxc_linter/src/rules/no_constant_condition.rs @@ -0,0 +1,344 @@ +use oxc_ast::{ + ast::{BinaryOperator, Expression}, + AstKind, Span, +}; +use oxc_diagnostics::{ + miette::{self, Diagnostic}, + thiserror::Error, +}; +use oxc_macros::declare_oxc_lint; + +use crate::{ast_util::IsConstant, context::LintContext, rule::Rule, AstNode}; + +#[derive(Debug, Error, Diagnostic)] +#[error("eslint(no-constant-condition): Unexpected constant condition")] +#[diagnostic(severity(warning), help("A constant expression are not allowed as a test condition"))] +struct NoConstantConditionDiagnostic(#[label] pub Span); + +#[derive(Debug, Default, Clone)] +pub struct NoConstantCondition { + check_loops: bool, +} + +declare_oxc_lint!( + /// ### What it does + /// + /// Disallow constant expressions in conditions + /// + /// ### Why is this bad? + /// + /// A constant expression (for example, a literal) as a test condition might be a typo or development trigger for a specific behavior. + /// + /// ### Example + /// + /// ```javascript + /// if (false) { + /// doSomethingUnfinished(); + /// } + /// ``` + NoConstantCondition, + nursery +); + +impl Rule for NoConstantCondition { + fn from_configuration(value: serde_json::Value) -> Self { + let obj = value.get(0); + + Self { + check_loops: obj + .and_then(|v| v.get("checkLoops")) + .and_then(serde_json::Value::as_bool) + .unwrap_or_default(), + } + } + + fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { + match node.get().kind() { + AstKind::IfStatement(if_stmt) => { + if if_stmt.test.is_constant(true, ctx) { + diagnose_constant_expr(&if_stmt.test, ctx); + } + } + _ => {} + } + } +} + +fn diagnose_constant_expr(expr: &Expression, ctx: &LintContext) { + let diagnose = |span: Span| { + ctx.diagnostic(NoConstantConditionDiagnostic(span)); + }; + + match expr { + Expression::ArrowFunctionExpression(expr) => diagnose(expr.span), + Expression::FunctionExpression(expr) => diagnose(expr.span), + Expression::ClassExpression(expr) => diagnose(expr.span), + Expression::ObjectExpression(expr) => diagnose(expr.span), + Expression::TemplateLiteral(expr) => diagnose(expr.span), + Expression::ArrayExpression(expr) => diagnose(expr.span), + Expression::UnaryExpression(expr) => diagnose(expr.span), + Expression::BinaryExpression(expr) => diagnose(expr.span), + Expression::LogicalExpression(expr) => diagnose(expr.span), + Expression::NewExpression(expr) => diagnose(expr.span), + Expression::AssignmentExpression(expr) => diagnose(expr.span), + Expression::SequenceExpression(expr) => diagnose(expr.span), + Expression::CallExpression(expr) => diagnose(expr.span), + Expression::ParenthesizedExpression(expr) => diagnose(expr.span), + Expression::Identifier(expr) => diagnose(expr.span), + Expression::BooleanLiteral(expr) => diagnose(expr.span), + Expression::NullLiteral(expr) => diagnose(expr.span), + Expression::NumberLiteral(expr) => diagnose(expr.span), + Expression::BigintLiteral(expr) => diagnose(expr.span), + Expression::RegExpLiteral(expr) => diagnose(expr.span), + Expression::StringLiteral(expr) => diagnose(expr.span), + _ => {} + } +} + +#[test] +fn test_no_constant() { + use crate::tester::Tester; + + let pass = vec![ + ("if(a);", None), + ("if(a == 0);", None), + ("if(a = f());", None), + ("if(a += 1);", None), + ("if(a |= 1);", None), + ("if(a |= true);", None), + ("if(a |= false);", None), + ("if(a &= 1);", None), + ("if(a &= true);", None), + ("if(a &= false);", None), + ("if(a >>= 1);", None), + ("if(a >>= true);", None), + ("if(a >>= false);", None), + ("if(a >>>= 1);", None), + ("if(a ??= 1);", None), + ("if(a ??= true);", None), + ("if(a ??= false);", None), + ("if(a ||= b);", None), + ("if(a ||= false);", None), + ("if(a ||= 0);", None), + ("if(a ||= void 0);", None), + ("if(+(a ||= 1));", None), + ("if(f(a ||= true));", None), + ("if((a ||= 1) + 2);", None), + ("if(1 + (a ||= true));", None), + ("if(a ||= '' || false);", None), + ("if(a ||= void 0 || null);", None), + ("if((a ||= false) || b);", None), + ("if(a || (b ||= false));", None), + ("if((a ||= true) && b);", None), + ("if(a && (b ||= true));", None), + ("if(a &&= b);", None), + ("if(a &&= true);", None), + ("if(a &&= 1);", None), + ("if(a &&= 'foo');", None), + ("if((a &&= '') + false);", None), + ("if('' + (a &&= null));", None), + ("if(a &&= 1 && 2);", None), + ("if((a &&= true) && b);", None), + ("if(a && (b &&= true));", None), + ("if((a &&= false) || b);", None), + ("if(a || (b &&= false));", None), + ("if(a ||= b ||= false);", None), + ("if(a &&= b &&= true);", None), + ("if(a ||= b &&= false);", None), + ("if(a ||= b &&= true);", None), + ("if(a &&= b ||= false);", None), + ("if(a &&= b ||= true);", None), + ("if(1, a);", None), + ("if ('every' in []);", None), + ("if (`\\\n${a}`) {}", None), + ("if (`${a}`);", None), + ("if (`${foo()}`);", None), + ("if (`${a === 'b' && b==='a'}`);", None), + ("if (`foo${a}` === 'fooa');", None), + ("if (tag`a`);", None), + ("if (tag`${a}`);", None), + ("if (+(a || true));", None), + ("if (-(a || true));", None), + ("if (~(a || 1));", None), + ("if (+(a && 0) === +(b && 0));", None), + ("if(typeof x === 'undefined'){}", None), + ("if(`${typeof x}` === 'undefined'){}", None), + ("if(a === 'str' && typeof b){}", None), + ("typeof a == typeof b", None), + ("typeof 'a' === 'string'|| typeof b === 'string'", None), + ("`${typeof 'a'}` === 'string'|| `${typeof b}` === 'string'", None), + ("if (void a || a);", None), + ("if (a || void a);", None), + ("if(xyz === 'str1' && abc==='str2'){}", None), + ("if(xyz === 'str1' || abc==='str2'){}", None), + ("if(xyz === 'str1' || abc==='str2' && pqr === 5){}", None), + ("if(typeof abc === 'string' && abc==='str2'){}", None), + ("if(false || abc==='str'){}", None), + ("if(true && abc==='str'){}", None), + ("if(typeof 'str' && abc==='str'){}", None), + ("if(abc==='str' || false || def ==='str'){}", None), + ("if(true && abc==='str' || def ==='str'){}", None), + ("if(true && typeof abc==='string'){}", None), + ("if('str1' && a){}", None), + ("if(a && 'str'){}", None), + ("if ((foo || true) === 'baz') {}", None), + ("if ((foo || 'bar') === 'baz') {}", None), + ("if ((foo || 'bar') !== 'baz') {}", None), + ("if ((foo || 'bar') == 'baz') {}", None), + ("if ((foo || 'bar') != 'baz') {}", None), + ("if ((foo || 233) > 666) {}", None), + ("if ((foo || 233) < 666) {}", None), + ("if ((foo || 233) >= 666) {}", None), + ("if ((foo || 233) <= 666) {}", None), + ("if ((key || 'k') in obj) {}", None), + ("if ((foo || {}) instanceof obj) {}", None), + ("if ((foo || 'bar' || 'bar') === 'bar');", None), + ("if ((foo || 1n) === 'baz') {}", None), + ("if (a && 0n || b);", None), + ("if(1n && a){};", None), + ("if ('' + [y] === '' + [ty]) {}", None), + ("if ('a' === '' + [ty]) {}", None), + ("if ('' + [y, m, d] === 'a') {}", None), + ("if ('' + [y, 'm'] === '' + [ty, 'tm']) {}", None), + ("if ('' + [y, 'm'] === '' + ['ty']) {}", None), + ("if ([,] in\n\n($2))\n ;\nelse\n ;", None), + ("if ([...x]+'' === 'y'){}", None), + ("if([a]==[b]) {}", None), + ("if (+[...a]) {}", None), + ("if (+[...[...a]]) {}", None), + ("if (`${[...a]}`) {}", None), + ("if (`${[a]}`) {}", None), + ("if (+[a]) {}", None), + ("if (0 - [a]) {}", None), + ("if (1 * [a]) {}", None), + ("if (Boolean(a)) {}", None), + ("if (Boolean(...args)) {}", None), + ("if (foo.Boolean(1)) {}", None), + // TODO + // ("const undefined = 'lol'; if (undefined) {}", None), + // ("function foo(Boolean) { if (Boolean(1)) {} }", None), + // ("const Boolean = () => {}; if (Boolean(1)) {}", None), + // "if (Boolean()) {}", + // "if (undefined) {}", + ]; + + let fail = vec![ + ("if(-2);", None), + ("if(-2);", None), + ("if(true);", None), + ("if(1);", None), + ("if({});", None), + ("if(0 < 1);", None), + ("if(0 || 1);", None), + ("if(a, 1);", None), + ("if(`foo`);", None), + ("if(``);", None), + ( + "if(`\ + `);", + None, + ), + ("if(`${'bar'}`);", None), + ("if(`${'bar' + `foo`}`);", None), + ("if(`foo${false || true}`);", None), + ("if(`foo${0 || 1}`);", None), + ("if(`foo${bar}`);", None), + ("if(`${bar}foo`);", None), + ("if(!(true || a));", None), + ("if(!(a && void b && c));", None), + ("if(0 || !(a && null));", None), + ("if(1 + !(a || true));", None), + ("if(!(null && a) > 1);", None), + ("if(+(!(a && 0)));", None), + ("if(!typeof a === 'string');", None), + ("if(-('foo' || a));", None), + ("if(+(void a && b) === ~(1 || c));", None), + ("if(a ||= true);", None), + ("if(a ||= 5);", None), + ("if(a ||= 'foo' || b);", None), + ("if(a ||= b || /regex/);", None), + ("if(a ||= b ||= true);", None), + ("if(a ||= b ||= c || 1);", None), + ("if(!(a ||= true));", None), + ("if(!(a ||= 'foo') === true);", None), + ("if(!(a ||= 'foo') === false);", None), + ("if(a || (b ||= true));", None), + ("if((a ||= 1) || b);", None), + ("if((a ||= true) && true);", None), + ("if(true && (a ||= true));", None), + ("if(a &&= false);", None), + ("if(a &&= null);", None), + ("if(a &&= void b);", None), + ("if(a &&= 0 && b);", None), + ("if(a &&= b && '');", None), + ("if(a &&= b &&= false);", None), + ("if(a &&= b &&= c && false);", None), + ("if(!(a &&= false));", None), + ("if(!(a &&= 0) + 1);", None), + ("if(a && (b &&= false));", None), + ("if((a &&= null) && b);", None), + ("if(false || (a &&= false));", None), + ("if((a &&= false) || false);", None), + ("if(typeof x){}", None), + ("if(typeof 'abc' === 'string'){}", None), + ("if(a = typeof b){}", None), + ("if(a, typeof b){}", None), + ("if(typeof 'a' == 'string' || typeof 'b' == 'string'){}", None), + ("if(1 || void x);", None), + ("if(void x);", None), + ("if(y = void x);", None), + ("if(x, void x);", None), + ("if(void x === void y);", None), + ("if(void x && a);", None), + ("if(a && void x);", None), + ("if(false && abc==='str'){}", None), + ("if(true || abc==='str'){}", None), + ("if(1 || abc==='str'){}", None), + ("if(abc==='str' || true){}", None), + ("if(abc==='str' || true || def ==='str'){}", None), + ("if(false || true){}", None), + ("if(typeof abc==='str' || true){}", None), + ("if('str' || a){}", None), + ("if('str' || abc==='str'){}", None), + ("if('str1' || 'str2'){}", None), + ("if('str1' && 'str2'){}", None), + ("if(abc==='str' || 'str'){}", None), + ("if(a || 'str'){}", None), + ("if([a]) {}", None), + ("if([]) {}", None), + ("if(''+['a']) {}", None), + ("if(''+[]) {}", None), + ("if(+1) {}", None), + ("if ([,] + ''){}", None), + ("if(/foo/ui);", None), + ("if(0n);", None), + ("if(0b0n);", None), + ("if(0o0n);", None), + ("if(0x0n);", None), + ("if(0b1n);", None), + ("if(0o1n);", None), + ("if(0x1n);", None), + ("if(0x1n || foo);", None), + // Classes and instances are always truthy + ("if(class {}) {}", None), + ("if(new Foo()) {}", None), + // Boxed primitives are always truthy + ("if(new Boolean(foo)) {}", None), + ("if(new String(foo)) {}", None), + ("if(new Number(foo)) {}", None), + // Spreading a constant array + ("if(`${[...['a']]}`) {}", None), + /* + * undefined is always falsy (except in old browsers that let you + * re-assign, but that's an obscure enough edge case to not worry about) + */ + ("if (undefined) {}", None), + // Coercion to boolean via Boolean function + ("if (Boolean(1)) {}", None), + ("if (Boolean()) {}", None), + ("if (Boolean([a])) {}", None), + ("if (Boolean(1)) { function Boolean() {}}", None), + ]; + + Tester::new(NoConstantCondition::NAME, pass, fail).test_and_snapshot(); +} diff --git a/crates/oxc_linter/src/snapshots/no_constant_condition.snap b/crates/oxc_linter/src/snapshots/no_constant_condition.snap new file mode 100644 index 0000000000000..d0d461c6c0fa1 --- /dev/null +++ b/crates/oxc_linter/src/snapshots/no_constant_condition.snap @@ -0,0 +1,726 @@ +--- +source: crates/oxc_linter/src/tester.rs +expression: no_constant_condition +--- + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(-2); + · ── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(-2); + · ── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(true); + · ──── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(1); + · ─ + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if({}); + · ── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(0 < 1); + · ───── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(0 || 1); + · ────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a, 1); + · ──── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(`foo`); + · ───── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(``); + · ── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(``); + · ── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(`${'bar'}`); + · ────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(`${'bar' + `foo`}`); + · ────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(`foo${false || true}`); + · ───────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(`foo${0 || 1}`); + · ────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(`foo${bar}`); + · ─────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(`${bar}foo`); + · ─────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(!(true || a)); + · ──────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(!(a && void b && c)); + · ─────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(0 || !(a && null)); + · ───────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(1 + !(a || true)); + · ──────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(!(null && a) > 1); + · ──────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(+(!(a && 0))); + · ──────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(!typeof a === 'string'); + · ────────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(-('foo' || a)); + · ───────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(+(void a && b) === ~(1 || c)); + · ──────────────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a ||= true); + · ────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a ||= 5); + · ─────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a ||= 'foo' || b); + · ──────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a ||= b || /regex/); + · ────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a ||= b ||= true); + · ──────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a ||= b ||= c || 1); + · ────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(!(a ||= true)); + · ───────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(!(a ||= 'foo') === true); + · ─────────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(!(a ||= 'foo') === false); + · ──────────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a || (b ||= true)); + · ───────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if((a ||= 1) || b); + · ────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if((a ||= true) && true); + · ──────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(true && (a ||= true)); + · ──────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a &&= false); + · ─────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a &&= null); + · ────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a &&= void b); + · ──────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a &&= 0 && b); + · ──────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a &&= b && ''); + · ───────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a &&= b &&= false); + · ───────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a &&= b &&= c && false); + · ────────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(!(a &&= false)); + · ────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(!(a &&= 0) + 1); + · ────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a && (b &&= false)); + · ────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if((a &&= null) && b); + · ───────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(false || (a &&= false)); + · ────────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if((a &&= false) || false); + · ────────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(typeof x){} + · ──────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(typeof 'abc' === 'string'){} + · ───────────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a = typeof b){} + · ──────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a, typeof b){} + · ─────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(typeof 'a' == 'string' || typeof 'b' == 'string'){} + · ──────────────────────────────────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(1 || void x); + · ─────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(void x); + · ────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(y = void x); + · ────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(x, void x); + · ───────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(void x === void y); + · ───────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(void x && a); + · ─────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a && void x); + · ─────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(false && abc==='str'){} + · ──────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(true || abc==='str'){} + · ─────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(1 || abc==='str'){} + · ──────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(abc==='str' || true){} + · ─────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(abc==='str' || true || def ==='str'){} + · ─────────────────────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(false || true){} + · ───────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(typeof abc==='str' || true){} + · ────────────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if('str' || a){} + · ────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if('str' || abc==='str'){} + · ──────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if('str1' || 'str2'){} + · ──────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if('str1' && 'str2'){} + · ──────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(abc==='str' || 'str'){} + · ──────────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(a || 'str'){} + · ────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if([a]) {} + · ─── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if([]) {} + · ── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(''+['a']) {} + · ──────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(''+[]) {} + · ───── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(+1) {} + · ── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if ([,] + ''){} + · ──────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(/foo/ui); + · ─────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(0n); + · ── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(0b0n); + · ──── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(0o0n); + · ──── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(0x0n); + · ──── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(0b1n); + · ──── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(0o1n); + · ──── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(0x1n); + · ──── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(0x1n || foo); + · ─────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(class {}) {} + · ──────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(new Foo()) {} + · ───────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(new Boolean(foo)) {} + · ──────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(new String(foo)) {} + · ─────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(new Number(foo)) {} + · ─────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if(`${[...['a']]}`) {} + · ─────────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if (undefined) {} + · ───────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if (Boolean(1)) {} + · ────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if (Boolean()) {} + · ───────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if (Boolean([a])) {} + · ──────────── + ╰──── + help: A constant expression are not allowed as a test condition + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ if (Boolean(1)) { function Boolean() {}} + · ────────── + ╰──── + help: A constant expression are not allowed as a test condition + From abf0e88ec5bde272d37f1616650aac0dc105debd Mon Sep 17 00:00:00 2001 From: wenzhe Date: Fri, 7 Apr 2023 22:08:11 +0800 Subject: [PATCH 2/5] feat: add conditionalExpression --- .../src/rules/no_constant_condition.rs | 40 +-- .../src/snapshots/no_constant_condition.snap | 259 +++++++++++------- 2 files changed, 178 insertions(+), 121 deletions(-) diff --git a/crates/oxc_linter/src/rules/no_constant_condition.rs b/crates/oxc_linter/src/rules/no_constant_condition.rs index 76587bf1075c9..34ecd7d0d6ef5 100644 --- a/crates/oxc_linter/src/rules/no_constant_condition.rs +++ b/crates/oxc_linter/src/rules/no_constant_condition.rs @@ -1,7 +1,4 @@ -use oxc_ast::{ - ast::{BinaryOperator, Expression}, - AstKind, Span, -}; +use oxc_ast::{ast::Expression, AstKind, Span}; use oxc_diagnostics::{ miette::{self, Diagnostic}, thiserror::Error, @@ -12,12 +9,12 @@ use crate::{ast_util::IsConstant, context::LintContext, rule::Rule, AstNode}; #[derive(Debug, Error, Diagnostic)] #[error("eslint(no-constant-condition): Unexpected constant condition")] -#[diagnostic(severity(warning), help("A constant expression are not allowed as a test condition"))] +#[diagnostic(severity(warning), help("Constant expression as a test condition is not allowed"))] struct NoConstantConditionDiagnostic(#[label] pub Span); #[derive(Debug, Default, Clone)] pub struct NoConstantCondition { - check_loops: bool, + _check_loops: bool, } declare_oxc_lint!( @@ -45,7 +42,7 @@ impl Rule for NoConstantCondition { let obj = value.get(0); Self { - check_loops: obj + _check_loops: obj .and_then(|v| v.get("checkLoops")) .and_then(serde_json::Value::as_bool) .unwrap_or_default(), @@ -59,6 +56,11 @@ impl Rule for NoConstantCondition { diagnose_constant_expr(&if_stmt.test, ctx); } } + AstKind::ConditionalExpression(cond_expr) => { + if cond_expr.test.is_constant(true, ctx) { + diagnose_constant_expr(&cond_expr.test, ctx); + } + } _ => {} } } @@ -220,6 +222,11 @@ fn test_no_constant() { // ("const Boolean = () => {}; if (Boolean(1)) {}", None), // "if (Boolean()) {}", // "if (undefined) {}", + ("q > 0 ? 1 : 2;", None), + ("`${a}` === a ? 1 : 2", None), + ("`foo${a}` === a ? 1 : 2", None), + ("tag`a` === a ? 1 : 2", None), + ("tag`${a}` === a ? 1 : 2", None), ]; let fail = vec![ @@ -233,11 +240,7 @@ fn test_no_constant() { ("if(a, 1);", None), ("if(`foo`);", None), ("if(``);", None), - ( - "if(`\ - `);", - None, - ), + ("if(`\\\n`);", None), ("if(`${'bar'}`);", None), ("if(`${'bar' + `foo`}`);", None), ("if(`foo${false || true}`);", None), @@ -328,16 +331,21 @@ fn test_no_constant() { ("if(new Number(foo)) {}", None), // Spreading a constant array ("if(`${[...['a']]}`) {}", None), - /* - * undefined is always falsy (except in old browsers that let you - * re-assign, but that's an obscure enough edge case to not worry about) - */ + // undefined is always falsy (except in old browsers that let you + // re-assign, but that's an obscure enough edge case to not worry about) ("if (undefined) {}", None), // Coercion to boolean via Boolean function ("if (Boolean(1)) {}", None), ("if (Boolean()) {}", None), ("if (Boolean([a])) {}", None), ("if (Boolean(1)) { function Boolean() {}}", None), + ("true ? 1 : 2;", None), + ("1 ? 1 : 2;", None), + ("q = 0 ? 1 : 2;", None), + ("(q = 0) ? 1 : 2;", None), + ("`` ? 1 : 2;", None), + ("`foo` ? 1 : 2;", None), + ("`foo${bar}` ? 1 : 2;", None), ]; Tester::new(NoConstantCondition::NAME, pass, fail).test_and_snapshot(); diff --git a/crates/oxc_linter/src/snapshots/no_constant_condition.snap b/crates/oxc_linter/src/snapshots/no_constant_condition.snap index d0d461c6c0fa1..3a7a7eb7b324e 100644 --- a/crates/oxc_linter/src/snapshots/no_constant_condition.snap +++ b/crates/oxc_linter/src/snapshots/no_constant_condition.snap @@ -8,719 +8,768 @@ expression: no_constant_condition 1 │ if(-2); · ── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(-2); · ── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(true); · ──── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(1); · ─ ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if({}); · ── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(0 < 1); · ───── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(0 || 1); · ────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a, 1); · ──── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(`foo`); · ───── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(``); · ── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] - 1 │ if(``); - · ── + 1 │ ╭─▶ if(`\ + 2 │ ╰─▶ `); ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(`${'bar'}`); · ────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(`${'bar' + `foo`}`); · ────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(`foo${false || true}`); · ───────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(`foo${0 || 1}`); · ────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(`foo${bar}`); · ─────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(`${bar}foo`); · ─────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(!(true || a)); · ──────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(!(a && void b && c)); · ─────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(0 || !(a && null)); · ───────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(1 + !(a || true)); · ──────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(!(null && a) > 1); · ──────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(+(!(a && 0))); · ──────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(!typeof a === 'string'); · ────────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(-('foo' || a)); · ───────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(+(void a && b) === ~(1 || c)); · ──────────────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a ||= true); · ────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a ||= 5); · ─────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a ||= 'foo' || b); · ──────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a ||= b || /regex/); · ────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a ||= b ||= true); · ──────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a ||= b ||= c || 1); · ────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(!(a ||= true)); · ───────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(!(a ||= 'foo') === true); · ─────────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(!(a ||= 'foo') === false); · ──────────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a || (b ||= true)); · ───────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if((a ||= 1) || b); · ────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if((a ||= true) && true); · ──────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(true && (a ||= true)); · ──────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a &&= false); · ─────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a &&= null); · ────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a &&= void b); · ──────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a &&= 0 && b); · ──────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a &&= b && ''); · ───────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a &&= b &&= false); · ───────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a &&= b &&= c && false); · ────────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(!(a &&= false)); · ────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(!(a &&= 0) + 1); · ────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a && (b &&= false)); · ────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if((a &&= null) && b); · ───────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(false || (a &&= false)); · ────────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if((a &&= false) || false); · ────────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(typeof x){} · ──────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(typeof 'abc' === 'string'){} · ───────────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a = typeof b){} · ──────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a, typeof b){} · ─────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(typeof 'a' == 'string' || typeof 'b' == 'string'){} · ──────────────────────────────────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(1 || void x); · ─────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(void x); · ────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(y = void x); · ────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(x, void x); · ───────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(void x === void y); · ───────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(void x && a); · ─────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a && void x); · ─────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(false && abc==='str'){} · ──────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(true || abc==='str'){} · ─────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(1 || abc==='str'){} · ──────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(abc==='str' || true){} · ─────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(abc==='str' || true || def ==='str'){} · ─────────────────────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(false || true){} · ───────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(typeof abc==='str' || true){} · ────────────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if('str' || a){} · ────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if('str' || abc==='str'){} · ──────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if('str1' || 'str2'){} · ──────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if('str1' && 'str2'){} · ──────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(abc==='str' || 'str'){} · ──────────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(a || 'str'){} · ────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if([a]) {} · ─── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if([]) {} · ── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(''+['a']) {} · ──────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(''+[]) {} · ───── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(+1) {} · ── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if ([,] + ''){} · ──────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(/foo/ui); · ─────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(0n); · ── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(0b0n); · ──── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(0o0n); · ──── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(0x0n); · ──── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(0b1n); · ──── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(0o1n); · ──── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(0x1n); · ──── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(0x1n || foo); · ─────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(class {}) {} · ──────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(new Foo()) {} · ───────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(new Boolean(foo)) {} · ──────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(new String(foo)) {} · ─────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(new Number(foo)) {} · ─────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if(`${[...['a']]}`) {} · ─────────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if (undefined) {} · ───────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if (Boolean(1)) {} · ────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if (Boolean()) {} · ───────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if (Boolean([a])) {} · ──────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed ⚠ eslint(no-constant-condition): Unexpected constant condition ╭─[no_constant_condition.tsx:1:1] 1 │ if (Boolean(1)) { function Boolean() {}} · ────────── ╰──── - help: A constant expression are not allowed as a test condition + help: Constant expression as a test condition is not allowed + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ true ? 1 : 2; + · ──── + ╰──── + help: Constant expression as a test condition is not allowed + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ 1 ? 1 : 2; + · ─ + ╰──── + help: Constant expression as a test condition is not allowed + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ q = 0 ? 1 : 2; + · ─ + ╰──── + help: Constant expression as a test condition is not allowed + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ (q = 0) ? 1 : 2; + · ─────── + ╰──── + help: Constant expression as a test condition is not allowed + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ `` ? 1 : 2; + · ── + ╰──── + help: Constant expression as a test condition is not allowed + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ `foo` ? 1 : 2; + · ───── + ╰──── + help: Constant expression as a test condition is not allowed + + ⚠ eslint(no-constant-condition): Unexpected constant condition + ╭─[no_constant_condition.tsx:1:1] + 1 │ `foo${bar}` ? 1 : 2; + · ─────────── + ╰──── + help: Constant expression as a test condition is not allowed From c59ce895cc0eea8529ca8f5def8192278bbc3a33 Mon Sep 17 00:00:00 2001 From: wenzhe Date: Fri, 7 Apr 2023 23:52:59 +0800 Subject: [PATCH 3/5] feat(linter): add test for loop --- .../src/rules/no_constant_condition.rs | 61 ++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/crates/oxc_linter/src/rules/no_constant_condition.rs b/crates/oxc_linter/src/rules/no_constant_condition.rs index 34ecd7d0d6ef5..0626dbc64b8e5 100644 --- a/crates/oxc_linter/src/rules/no_constant_condition.rs +++ b/crates/oxc_linter/src/rules/no_constant_condition.rs @@ -98,7 +98,7 @@ fn diagnose_constant_expr(expr: &Expression, ctx: &LintContext) { } #[test] -fn test_no_constant() { +fn test() { use crate::tester::Tester; let pass = vec![ @@ -205,6 +205,7 @@ fn test_no_constant() { ("if ('' + [y, 'm'] === '' + ['ty']) {}", None), ("if ([,] in\n\n($2))\n ;\nelse\n ;", None), ("if ([...x]+'' === 'y'){}", None), + ("if (new Number(x) + 1 === 2) {}", None), ("if([a]==[b]) {}", None), ("if (+[...a]) {}", None), ("if (+[...[...a]]) {}", None), @@ -227,6 +228,30 @@ fn test_no_constant() { ("`foo${a}` === a ? 1 : 2", None), ("tag`a` === a ? 1 : 2", None), ("tag`${a}` === a ? 1 : 2", None), + //TODO + // ("while(~!a);", None), + // ("while(a = b);", None), + // ("while(`${a}`);", None), + // ("for(;x < 10;);", None), + // ("for(;;);", None), + // ("for(;`${a}`;);", None), + // ("do{ }while(x)", None), + // ("while(x += 3) {}", None), + // ("while(tag`a`) {}", None), + // ("while(tag`${a}`) {}", None), + // ("while(`\\\n${a}`) {}", None), + // ("while(true);", Some(json!([{"checkLoops":false}]))), + // ("for(;true;);", Some(json!([{"checkLoops":false}]))), + // ("do{}while(true)", Some(json!([{"checkLoops":false}]))), + // ("function* foo(){while(true){yield 'foo';}}", None), + // ("function* foo(){for(;true;){yield 'foo';}}", None), + // ("function* foo(){do{yield 'foo';}while(true)}", None), + // ("function* foo(){while (true) { while(true) {yield;}}}", None), + // ("function* foo() {for (; yield; ) {}}", None), + // ("function* foo() {for (; ; yield) {}}", None), + // ("function* foo() {while (true) {function* foo() {yield;}yield;}}", None), + // ("function* foo() { for (let x = yield; x < 10; x++) {yield;}yield;}", None), + // ("function* foo() { for (let x = yield; ; x++) { yield; }}", None), ]; let fail = vec![ @@ -346,6 +371,40 @@ fn test_no_constant() { ("`` ? 1 : 2;", None), ("`foo` ? 1 : 2;", None), ("`foo${bar}` ? 1 : 2;", None), + // TODO + // ("for(;true;);", None), + // ("for(;``;);", None), + // ("for(;`foo`;);", None), + // ("for(;`foo${bar}`;);", None), + // ("do{}while(true)", None), + // ("do{}while('1')", None), + // ("do{}while(0)", None), + // ("do{}while(t = -2)", None), + // ("do{}while(``)", None), + // ("do{}while(`foo`)", None), + // ("do{}while(`foo${bar}`)", None), + // ("while([]);", None), + // ("while(~!0);", None), + // ("while(x = 1);", None), + // ("while(function(){});", None), + // ("while(true);", None), + // ("while(1);", None), + // ("while(() => {});", None), + // ("while(`foo`);", None), + // ("while(``);", None), + // ("while(`${'foo'}`);", None), + // ("while(`${'foo' + 'bar'}`);", None), + // ("function* foo(){while(true){} yield 'foo';}", None), + // ("function* foo(){while(true){if (true) {yield 'foo';}}}", None), + // ("function* foo(){while(true){yield 'foo';} while(true) {}}", None), + // ("var a = function* foo(){while(true){} yield 'foo';}", None), + // ("while (true) { function* foo() {yield;}}", None), + // ("function* foo(){if (true) {yield 'foo';}}", None), + // ("function* foo() {for (let foo = yield; true;) {}}", None), + // ("function* foo() {for (foo = yield; true;) {}}", None), + // ("function foo() {while (true) {function* bar() {while (true) {yield;}}}}", None), + // ("function foo() {while (true) {const bar = function*() {while (true) {yield;}}}}", None), + // ("function* foo() { for (let foo = 1 + 2 + 3 + (yield); true; baz) {}}", None), ]; Tester::new(NoConstantCondition::NAME, pass, fail).test_and_snapshot(); From 11dac39431a35941c3eb918c56a9ed3a0c0599af Mon Sep 17 00:00:00 2001 From: wenzhe Date: Sun, 9 Apr 2023 11:16:54 +0800 Subject: [PATCH 4/5] chore(linter): allow too many lines --- crates/oxc_linter/src/rules/no_constant_condition.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/oxc_linter/src/rules/no_constant_condition.rs b/crates/oxc_linter/src/rules/no_constant_condition.rs index 0626dbc64b8e5..d6e8977035265 100644 --- a/crates/oxc_linter/src/rules/no_constant_condition.rs +++ b/crates/oxc_linter/src/rules/no_constant_condition.rs @@ -98,6 +98,7 @@ fn diagnose_constant_expr(expr: &Expression, ctx: &LintContext) { } #[test] +#[allow(clippy::too_many_lines)] fn test() { use crate::tester::Tester; From bbcca86ade971c7d2aef18ec79d83e34f6e63209 Mon Sep 17 00:00:00 2001 From: wenzhe Date: Sun, 9 Apr 2023 17:05:04 +0800 Subject: [PATCH 5/5] refactor(linter): use GetSpan trait --- .../src/rules/no_constant_condition.rs | 42 +++---------------- 1 file changed, 6 insertions(+), 36 deletions(-) diff --git a/crates/oxc_linter/src/rules/no_constant_condition.rs b/crates/oxc_linter/src/rules/no_constant_condition.rs index d6e8977035265..e1da0e6d171d3 100644 --- a/crates/oxc_linter/src/rules/no_constant_condition.rs +++ b/crates/oxc_linter/src/rules/no_constant_condition.rs @@ -1,4 +1,5 @@ -use oxc_ast::{ast::Expression, AstKind, Span}; +use oxc_ast::GetSpan; +use oxc_ast::{AstKind, Span}; use oxc_diagnostics::{ miette::{self, Diagnostic}, thiserror::Error, @@ -53,12 +54,12 @@ impl Rule for NoConstantCondition { match node.get().kind() { AstKind::IfStatement(if_stmt) => { if if_stmt.test.is_constant(true, ctx) { - diagnose_constant_expr(&if_stmt.test, ctx); + ctx.diagnostic(NoConstantConditionDiagnostic(if_stmt.test.span())); } } - AstKind::ConditionalExpression(cond_expr) => { - if cond_expr.test.is_constant(true, ctx) { - diagnose_constant_expr(&cond_expr.test, ctx); + AstKind::ConditionalExpression(condition_expr) => { + if condition_expr.test.is_constant(true, ctx) { + ctx.diagnostic(NoConstantConditionDiagnostic(condition_expr.test.span())); } } _ => {} @@ -66,37 +67,6 @@ impl Rule for NoConstantCondition { } } -fn diagnose_constant_expr(expr: &Expression, ctx: &LintContext) { - let diagnose = |span: Span| { - ctx.diagnostic(NoConstantConditionDiagnostic(span)); - }; - - match expr { - Expression::ArrowFunctionExpression(expr) => diagnose(expr.span), - Expression::FunctionExpression(expr) => diagnose(expr.span), - Expression::ClassExpression(expr) => diagnose(expr.span), - Expression::ObjectExpression(expr) => diagnose(expr.span), - Expression::TemplateLiteral(expr) => diagnose(expr.span), - Expression::ArrayExpression(expr) => diagnose(expr.span), - Expression::UnaryExpression(expr) => diagnose(expr.span), - Expression::BinaryExpression(expr) => diagnose(expr.span), - Expression::LogicalExpression(expr) => diagnose(expr.span), - Expression::NewExpression(expr) => diagnose(expr.span), - Expression::AssignmentExpression(expr) => diagnose(expr.span), - Expression::SequenceExpression(expr) => diagnose(expr.span), - Expression::CallExpression(expr) => diagnose(expr.span), - Expression::ParenthesizedExpression(expr) => diagnose(expr.span), - Expression::Identifier(expr) => diagnose(expr.span), - Expression::BooleanLiteral(expr) => diagnose(expr.span), - Expression::NullLiteral(expr) => diagnose(expr.span), - Expression::NumberLiteral(expr) => diagnose(expr.span), - Expression::BigintLiteral(expr) => diagnose(expr.span), - Expression::RegExpLiteral(expr) => diagnose(expr.span), - Expression::StringLiteral(expr) => diagnose(expr.span), - _ => {} - } -} - #[test] #[allow(clippy::too_many_lines)] fn test() {