mirror of
https://github.com/danbulant/oxc
synced 2026-05-22 05:38:54 +00:00
feat(linter): check duplicated bound names in ImportDeclaration
This commit is contained in:
parent
89f28e9f93
commit
ee31f5cc6f
2 changed files with 36 additions and 12 deletions
|
|
@ -39,7 +39,12 @@ impl Rule for EarlyErrorJavaScript {
|
|||
AstKind::RegExpLiteral(lit) => check_regexp_literal(lit, ctx),
|
||||
|
||||
AstKind::Directive(dir) => check_directive(dir, node, ctx),
|
||||
AstKind::ModuleDeclaration(decl) => check_module_declaration(decl, node, ctx),
|
||||
AstKind::ModuleDeclaration(decl) => {
|
||||
check_module_declaration(decl, node, ctx);
|
||||
if let ModuleDeclarationKind::ImportDeclaration(import_decl) = &decl.kind {
|
||||
check_import_declaration(import_decl, ctx);
|
||||
}
|
||||
}
|
||||
AstKind::MetaProperty(prop) => check_meta_property(prop, node, ctx),
|
||||
|
||||
AstKind::WithStatement(stmt) => check_with_statement(stmt, node, ctx),
|
||||
|
|
@ -70,6 +75,18 @@ impl Rule for EarlyErrorJavaScript {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_duplicate_bound_names<T: BoundNames>(bound_names: &T, ctx: &LintContext) {
|
||||
// bound_names are usually small, a simple loop should be more performant checking with a hashmap
|
||||
let mut idents = bound_names.bound_names();
|
||||
idents.sort_unstable_by_key(|ident| ident.name.as_str());
|
||||
for i in 1..idents.len() {
|
||||
let ident = &idents[i - 1];
|
||||
if let Some(found) = idents[i..].iter().find(|i| i.name == ident.name) {
|
||||
ctx.diagnostic(Redeclaration(ident.name.clone(), ident.span, found.span));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
#[error("Cannot use await in class static initialization block")]
|
||||
#[diagnostic()]
|
||||
|
|
@ -393,6 +410,13 @@ fn check_module_declaration<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
fn check_import_declaration(decl: &ImportDeclaration, ctx: &LintContext) {
|
||||
// ModuleItem : ImportDeclaration
|
||||
// It is a Syntax Error if the BoundNames of ImportDeclaration contains any duplicate entries.
|
||||
// bound_names are usually small, a simple loop should be more performant checking with a hashmap
|
||||
check_duplicate_bound_names(decl, ctx);
|
||||
}
|
||||
|
||||
fn check_meta_property<'a>(prop: &MetaProperty, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
||||
#[derive(Debug, Error, Diagnostic)]
|
||||
#[error("Unexpected new.target expression")]
|
||||
|
|
@ -868,15 +892,7 @@ fn check_formal_parameters<'a>(
|
|||
return;
|
||||
}
|
||||
|
||||
// bound_names are usually small, a simple loop should be more performant checking with a hashmap
|
||||
let mut idents = params.bound_names();
|
||||
idents.sort_unstable_by_key(|ident| ident.name.as_str());
|
||||
for i in 1..idents.len() {
|
||||
let ident = &idents[i - 1];
|
||||
if let Some(found) = idents[i..].iter().find(|i| i.name == ident.name) {
|
||||
ctx.diagnostic(Redeclaration(ident.name.clone(), ident.span, found.span));
|
||||
}
|
||||
}
|
||||
check_duplicate_bound_names(params, ctx);
|
||||
}
|
||||
|
||||
fn check_formal_parameter(param: &FormalParameter, ctx: &LintContext) {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
Test262 Summary:
|
||||
AST Parsed : 44015/44034 (99.96%)
|
||||
Positive Passed: 44015/44034 (99.96%)
|
||||
Negative Passed: 3907/3917 (99.74%)
|
||||
Expect Syntax Error: "language/import/dup-bound-names.js"
|
||||
Negative Passed: 3908/3917 (99.77%)
|
||||
Expect Syntax Error: "language/import/json-invalid.js"
|
||||
Expect Syntax Error: "language/import/json-named-bindings.js"
|
||||
Expect Syntax Error: "language/module-code/early-dup-export-as-star-as.js"
|
||||
|
|
@ -18949,6 +18948,15 @@ Expect to Parse: "language/statements/function/S14_A5_T2.js"
|
|||
· ╰── Invalid Character `ⸯ`
|
||||
╰────
|
||||
|
||||
× Identifier `x` has already been declared
|
||||
╭─[language/import/dup-bound-names.js:15:1]
|
||||
15 │
|
||||
16 │ import { x, y as x } from 'z';
|
||||
· ┬ ┬
|
||||
· │ ╰── It can not be redeclared here
|
||||
· ╰── `x` has already been declared here
|
||||
╰────
|
||||
|
||||
× Keywords cannot contain escape characters
|
||||
╭─[language/import/escaped-as-import-specifier.js:25:1]
|
||||
25 │
|
||||
|
|
|
|||
Loading…
Reference in a new issue