feat(linter): improve no_redeclare rule implementation (#2084)

This commit is contained in:
Dunqing 2024-01-19 20:10:06 +08:00 committed by GitHub
parent a9e2158362
commit 721a869b6e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 51 additions and 17 deletions

View file

@ -58,7 +58,7 @@ declare_oxc_lint!(
/// var a = 10;
/// ```
NoRedeclare,
nursery // There are false positives within TypeScript files (e.g. redeclare on interface)
pedantic
);
impl Rule for NoRedeclare {
@ -81,13 +81,17 @@ impl Rule for NoRedeclare {
match ctx.nodes().kind(decl) {
AstKind::VariableDeclarator(var) => {
if let BindingPatternKind::BindingIdentifier(ident) = &var.id.kind {
self.report_diagnostic(ctx, variable, ident);
if *symbol_table.get_name(variable.symbol_id) == ident.name {
self.report_diagnostic(ctx, variable, ident);
}
}
}
AstKind::FormalParameters(params) => {
for item in &params.items {
if let BindingPatternKind::BindingIdentifier(ident) = &item.pattern.kind {
self.report_diagnostic(ctx, variable, ident);
if *symbol_table.get_name(variable.symbol_id) == ident.name {
self.report_diagnostic(ctx, variable, ident);
}
}
}
}
@ -106,7 +110,7 @@ impl NoRedeclare {
) {
if self.built_in_globals && BUILTINS.get(&ident.name).is_some() {
ctx.diagnostic(NoRedeclareAsBuiltiInDiagnostic(ident.name.clone(), ident.span));
} else if variable.name == ident.name && variable.span != ident.span {
} else if variable.span != ident.span {
ctx.diagnostic(NoRedeclareDiagnostic(ident.name.clone(), ident.span, variable.span));
}
}
@ -153,12 +157,10 @@ fn test() {
("var a = 3; var a = 10; var a = 15;", None),
("var a; var a;", None),
("export var a; var a;", None),
// `var` redeclaration in class static blocks. Redeclaration of functions is not allowed in class static blocks.
("class C { static { var a; var a; } }", None),
// Todo: Fix me
// ("class C { static { var a; { var a; } } }", None),
// ("class C { static { { var a; } var a; } }", None),
// ("class C { static { { var a; } { var a; } } }", None),
("class C { static { var a; { var a; } } }", None),
("class C { static { { var a; } var a; } }", None),
("class C { static { { var a; } { var a; } } }", None),
// ("var Object = 0;", Some(serde_json::json!([{ "builtinGlobals": true }]))),
(
"var a; var {a = 0, b: Object = 0} = {};",
@ -171,7 +173,7 @@ fn test() {
),
("function f() { var a; var a; }", None),
("function f(a) { var a; }", None),
// ("function f() { var a; if (test) { var a; } }", None),
("function f() { var a; if (test) { var a; } }", None),
("for (var a, a;;);", None),
];

View file

@ -100,6 +100,30 @@ expression: no_redeclare
· ╰── 'a' is already defined.
╰────
⚠ eslint(no-redeclare): 'a' is already defined.
╭─[no_redeclare.tsx:1:1]
1 │ class C { static { var a; { var a; } } }
· ┬ ┬
· │ ╰── It can not be redeclare here.
· ╰── 'a' is already defined.
╰────
⚠ eslint(no-redeclare): 'a' is already defined.
╭─[no_redeclare.tsx:1:1]
1 │ class C { static { { var a; } var a; } }
· ┬ ┬
· │ ╰── It can not be redeclare here.
· ╰── 'a' is already defined.
╰────
⚠ eslint(no-redeclare): 'a' is already defined.
╭─[no_redeclare.tsx:1:1]
1 │ class C { static { { var a; } { var a; } } }
· ┬ ┬
· │ ╰── It can not be redeclare here.
· ╰── 'a' is already defined.
╰────
⚠ eslint(no-redeclare): 'a' is already defined.
╭─[no_redeclare.tsx:1:1]
1 │ var a; var {a = 0, b: Object = 0} = {};
@ -132,6 +156,14 @@ expression: no_redeclare
· ╰── 'a' is already defined.
╰────
⚠ eslint(no-redeclare): 'a' is already defined.
╭─[no_redeclare.tsx:1:1]
1 │ function f() { var a; if (test) { var a; } }
· ┬ ┬
· │ ╰── It can not be redeclare here.
· ╰── 'a' is already defined.
╰────
⚠ eslint(no-redeclare): 'a' is already defined.
╭─[no_redeclare.tsx:1:1]
1 │ for (var a, a;;);

View file

@ -60,11 +60,10 @@ impl<'a> Binder for VariableDeclarator<'a> {
builder.check_redeclaration(*scope_id, span, name, excludes, true)
{
ident.symbol_id.set(Some(symbol_id));
builder.add_redeclared_variables(VariableInfo {
name: ident.name.clone(),
span: ident.span,
symbol_id,
});
if self.kind.is_var() {
builder
.add_redeclared_variables(VariableInfo { span: ident.span, symbol_id });
}
return;
}
}

View file

@ -38,7 +38,6 @@ struct UnusedLabels<'a> {
#[derive(Debug, Clone)]
pub struct VariableInfo {
pub name: Atom,
pub span: Span,
pub symbol_id: SymbolId,
}
@ -253,7 +252,9 @@ impl<'a> SemanticBuilder<'a> {
) -> SymbolId {
if let Some(symbol_id) = self.check_redeclaration(scope_id, span, name, excludes, true) {
self.symbols.union_flag(symbol_id, includes);
self.add_redeclared_variables(VariableInfo { name: name.clone(), span, symbol_id });
if includes.is_function_scoped_declaration() {
self.add_redeclared_variables(VariableInfo { span, symbol_id });
}
return symbol_id;
}