mirror of
https://github.com/swc-project/swc.git
synced 2024-12-25 06:36:08 +03:00
feat(es/lints): Implement no-sparse-arrays
rule (#4652)
This commit is contained in:
parent
c96cbe9b27
commit
9b226a7026
@ -0,0 +1,9 @@
|
||||
{
|
||||
"jsc": {
|
||||
"lints": {
|
||||
"no-sparse-arrays": [
|
||||
"error"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
var a = [,];
|
||||
var a = [1, , 2];
|
||||
|
||||
var a = [1, 2,];
|
||||
var a = [1, 2];
|
||||
var a = [];
|
@ -0,0 +1,12 @@
|
||||
|
||||
x Unexpected comma in middle of array
|
||||
,----
|
||||
1 | var a = [,];
|
||||
: ^^^
|
||||
`----
|
||||
|
||||
x Unexpected comma in middle of array
|
||||
,----
|
||||
2 | var a = [1, , 2];
|
||||
: ^^^^^^^^
|
||||
`----
|
@ -195,4 +195,8 @@ pub struct LintConfig {
|
||||
#[cfg(feature = "non_critical_lints")]
|
||||
#[serde(default, alias = "noCompareNegZero")]
|
||||
pub no_compare_neg_zero: RuleConfig<()>,
|
||||
|
||||
#[cfg(feature = "non_critical_lints")]
|
||||
#[serde(default, alias = "noSparseArrays")]
|
||||
pub no_sparse_arrays: RuleConfig<()>,
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ pub(crate) mod non_critical_lints {
|
||||
pub mod no_obj_calls;
|
||||
pub mod no_param_reassign;
|
||||
pub mod no_restricted_syntax;
|
||||
pub mod no_sparse_arrays;
|
||||
pub mod no_throw_literal;
|
||||
pub mod no_use_before_define;
|
||||
pub mod no_var;
|
||||
@ -171,6 +172,10 @@ pub fn all(lint_params: LintParams) -> Vec<Box<dyn Rule>> {
|
||||
rules.extend(no_compare_neg_zero::no_compare_neg_zero(
|
||||
&lint_config.no_compare_neg_zero,
|
||||
));
|
||||
|
||||
rules.extend(no_sparse_arrays::no_sparse_arrays(
|
||||
&lint_config.no_sparse_arrays,
|
||||
));
|
||||
}
|
||||
|
||||
rules
|
||||
|
81
crates/swc_ecma_lints/src/rules/no_sparse_arrays.rs
Normal file
81
crates/swc_ecma_lints/src/rules/no_sparse_arrays.rs
Normal file
@ -0,0 +1,81 @@
|
||||
use swc_common::{errors::HANDLER, Span};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Visit, VisitWith};
|
||||
|
||||
use crate::{
|
||||
config::{LintRuleReaction, RuleConfig},
|
||||
rule::{visitor_rule, Rule},
|
||||
};
|
||||
|
||||
const MESSAGE: &str = "Unexpected comma in middle of array";
|
||||
|
||||
pub fn no_sparse_arrays(config: &RuleConfig<()>) -> Option<Box<dyn Rule>> {
|
||||
let rule_reaction = config.get_rule_reaction();
|
||||
|
||||
match rule_reaction {
|
||||
LintRuleReaction::Off => None,
|
||||
_ => Some(visitor_rule(NoSparseArrays::new(rule_reaction))),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct NoSparseArrays {
|
||||
expected_reaction: LintRuleReaction,
|
||||
}
|
||||
|
||||
impl NoSparseArrays {
|
||||
fn new(expected_reaction: LintRuleReaction) -> Self {
|
||||
Self { expected_reaction }
|
||||
}
|
||||
|
||||
fn emit_report(&self, span: Span) {
|
||||
HANDLER.with(|handler| match self.expected_reaction {
|
||||
LintRuleReaction::Error => {
|
||||
handler.struct_span_err(span, MESSAGE).emit();
|
||||
}
|
||||
LintRuleReaction::Warning => {
|
||||
handler.struct_span_warn(span, MESSAGE).emit();
|
||||
}
|
||||
_ => {}
|
||||
});
|
||||
}
|
||||
|
||||
fn check(&self, span: Span, elems: &[Option<ExprOrSpread>]) {
|
||||
let len = elems.len();
|
||||
|
||||
// case
|
||||
// []
|
||||
if len == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
// case
|
||||
// [,]
|
||||
if len == 1 && elems[0].is_none() {
|
||||
self.emit_report(span);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let last_idx = len - 1;
|
||||
|
||||
let is_sparse_array = elems
|
||||
.iter()
|
||||
.enumerate()
|
||||
.any(|(idx, x)| idx != last_idx && x.is_none());
|
||||
|
||||
// cases like
|
||||
// [1,,2]
|
||||
if is_sparse_array {
|
||||
self.emit_report(span);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for NoSparseArrays {
|
||||
fn visit_array_lit(&mut self, n: &ArrayLit) {
|
||||
self.check(n.span, n.elems.as_slice());
|
||||
|
||||
n.visit_children_with(self);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user