mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
fix(linter): explicit-length-check inside ternary (#2165)
This commit is contained in:
parent
3d184d56a8
commit
26022322ff
3 changed files with 21 additions and 2 deletions
|
|
@ -348,6 +348,8 @@ fn test() {
|
||||||
// need getStaticValue
|
// need getStaticValue
|
||||||
// ("const A_NUMBER = 2; const x = foo.length || A_NUMBER", None),
|
// ("const A_NUMBER = 2; const x = foo.length || A_NUMBER", None),
|
||||||
("class A { a(){ if(this.length); while(!this.size || foo);}}", None),
|
("class A { a(){ if(this.length); while(!this.size || foo);}}", None),
|
||||||
|
// Use of .size but not in conditional "test" position
|
||||||
|
("const totalCount = tests.reduce((count, test) => count + (test.enabled ? test.maxSize : test.size), 0)", None),
|
||||||
];
|
];
|
||||||
|
|
||||||
let fail = vec![
|
let fail = vec![
|
||||||
|
|
@ -361,7 +363,10 @@ fn test() {
|
||||||
("const x = foo.length || bar()", None),
|
("const x = foo.length || bar()", None),
|
||||||
("() => foo.length && bar()", None),
|
("() => foo.length && bar()", None),
|
||||||
("alert(foo.length && bar())", None),
|
("alert(foo.length && bar())", None),
|
||||||
|
// Use of .size in conditional "test" position
|
||||||
|
("let foo = arr.length ? 'non-empty' : 'empty'", None),
|
||||||
];
|
];
|
||||||
|
|
||||||
let fixes = vec![
|
let fixes = vec![
|
||||||
(
|
(
|
||||||
r"if ( !!!( !foo.length && foo.length == 0 && foo.length < 1 && 0 === foo.length && 0 == foo.length && 1 > foo.length ) ||
|
r"if ( !!!( !foo.length && foo.length == 0 && foo.length < 1 && 0 === foo.length && 0 == foo.length && 1 > foo.length ) ||
|
||||||
|
|
|
||||||
|
|
@ -64,4 +64,10 @@ expression: explicit_length_check
|
||||||
╰────
|
╰────
|
||||||
help: Replace `.length` with `.length > 0`.
|
help: Replace `.length` with `.length > 0`.
|
||||||
|
|
||||||
|
⚠ eslint-plugin-unicorn(explicit-length-check): Use `.length > 0` when checking length is not zero.
|
||||||
|
╭─[explicit_length_check.tsx:1:1]
|
||||||
|
1 │ let foo = arr.length ? 'non-empty' : 'empty'
|
||||||
|
· ──────────
|
||||||
|
╰────
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
use oxc_ast::{
|
use oxc_ast::{
|
||||||
ast::{CallExpression, Expression},
|
ast::{CallExpression, ConditionalExpression, Expression},
|
||||||
AstKind,
|
AstKind,
|
||||||
};
|
};
|
||||||
use oxc_semantic::AstNode;
|
use oxc_semantic::AstNode;
|
||||||
|
use oxc_span::GetSpan;
|
||||||
use oxc_syntax::operator::UnaryOperator;
|
use oxc_syntax::operator::UnaryOperator;
|
||||||
|
|
||||||
use crate::{ast_util::outermost_paren_parent, LintContext};
|
use crate::{ast_util::outermost_paren_parent, LintContext};
|
||||||
|
|
@ -48,7 +49,6 @@ pub fn is_boolean_node<'a, 'b>(node: &'b AstNode<'a>, ctx: &'b LintContext<'a>)
|
||||||
if matches!(
|
if matches!(
|
||||||
parent.kind(),
|
parent.kind(),
|
||||||
AstKind::IfStatement(_)
|
AstKind::IfStatement(_)
|
||||||
| AstKind::ConditionalExpression(_)
|
|
||||||
| AstKind::WhileStatement(_)
|
| AstKind::WhileStatement(_)
|
||||||
| AstKind::DoWhileStatement(_)
|
| AstKind::DoWhileStatement(_)
|
||||||
| AstKind::ForStatement(_)
|
| AstKind::ForStatement(_)
|
||||||
|
|
@ -56,6 +56,14 @@ pub fn is_boolean_node<'a, 'b>(node: &'b AstNode<'a>, ctx: &'b LintContext<'a>)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let AstKind::ConditionalExpression(ConditionalExpression {
|
||||||
|
test: conditional_test, ..
|
||||||
|
}) = parent.kind()
|
||||||
|
{
|
||||||
|
let expr_span = conditional_test.get_inner_expression().without_parenthesized().span();
|
||||||
|
return expr_span == node.kind().span();
|
||||||
|
}
|
||||||
|
|
||||||
if is_logical_expression(parent) {
|
if is_logical_expression(parent) {
|
||||||
return is_boolean_node(parent, ctx);
|
return is_boolean_node(parent, ctx);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue