fix(linter): improve import/no-named-as-default (#2494)

This commit is contained in:
Boshen 2024-02-25 21:24:08 +08:00 committed by GitHub
parent f5aadc767f
commit fba66dcc75
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 16 additions and 32 deletions

View file

@ -9,8 +9,8 @@ use oxc_syntax::module_record::ImportImportName;
use crate::{context::LintContext, rule::Rule};
#[derive(Debug, Error, Diagnostic)]
#[error("eslint-plugin-import(no-named-as-default): Module {2:?} has named export {1:?}. Using default import as {1:?} can be confusing")]
#[diagnostic(severity(warning), help("Use another name for default import to avoid confusion"))]
#[error("eslint-plugin-import(no-named-as-default): Module {2:?} has named export {1:?}")]
#[diagnostic(severity(warning), help("Using default import as {1:?} can be confusing. Use another name for default import to avoid confusion."))]
struct NoNamedAsDefaultDiagnostic(#[label] pub Span, String, String);
/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-named-as-default-member.md>
@ -46,14 +46,7 @@ impl Rule for NoNamedAsDefault {
fn run_once(&self, ctx: &LintContext<'_>) {
let module_record = ctx.semantic().module_record();
for import_entry in &module_record.import_entries {
let ImportImportName::Default(import_span) = import_entry.import_name else {
continue;
};
let Some(import_name) = ctx
.symbols()
.get_symbol_id_from_span(&import_span)
.map(|it| ctx.symbols().get_name(it))
else {
let ImportImportName::Default(import_span) = &import_entry.import_name else {
continue;
};
@ -62,9 +55,10 @@ impl Rule for NoNamedAsDefault {
continue;
};
let import_name = import_entry.local_name.name();
if remote_module_record_ref.exported_bindings.contains_key(import_name) {
ctx.diagnostic(NoNamedAsDefaultDiagnostic(
import_span,
*import_span,
import_name.to_string(),
import_entry.module_request.name().to_string(),
));
@ -81,7 +75,7 @@ fn test() {
r#"import "./malformed.js""#,
r#"import bar, { foo } from "./bar";"#,
r#"import bar, { foo } from "./empty-folder";"#,
// TODO: parser error
// unsupported syntax
// r#"export default from "./bar";"#,
r#"import bar, { foo } from "./export-default-string-and-named""#,
];
@ -89,7 +83,7 @@ fn test() {
let fail = vec![
r#"import foo from "./bar";"#,
r#"import foo, { foo as bar } from "./bar";"#,
// TODO: parser error
// unsupported syntax
// r#"export default, { foo as bar } from "./bar";"#,
// r#"import foo from "./malformed.js""#,
r#"import foo from "./export-default-string-and-named""#,

View file

@ -2,30 +2,30 @@
source: crates/oxc_linter/src/tester.rs
expression: no_named_as_default
---
⚠ eslint-plugin-import(no-named-as-default): Module "./bar" has named export "foo". Using default import as "foo" can be confusing
⚠ eslint-plugin-import(no-named-as-default): Module "./bar" has named export "foo"
╭─[index.js:1:8]
1 │ import foo from "./bar";
· ───
╰────
help: Use another name for default import to avoid confusion
help: Using default import as "foo" can be confusing. Use another name for default import to avoid confusion.
⚠ eslint-plugin-import(no-named-as-default): Module "./bar" has named export "foo". Using default import as "foo" can be confusing
⚠ eslint-plugin-import(no-named-as-default): Module "./bar" has named export "foo"
╭─[index.js:1:8]
1 │ import foo, { foo as bar } from "./bar";
· ───
╰────
help: Use another name for default import to avoid confusion
help: Using default import as "foo" can be confusing. Use another name for default import to avoid confusion.
⚠ eslint-plugin-import(no-named-as-default): Module "./export-default-string-and-named" has named export "foo". Using default import as "foo" can be confusing
⚠ eslint-plugin-import(no-named-as-default): Module "./export-default-string-and-named" has named export "foo"
╭─[index.js:1:8]
1 │ import foo from "./export-default-string-and-named"
· ───
╰────
help: Use another name for default import to avoid confusion
help: Using default import as "foo" can be confusing. Use another name for default import to avoid confusion.
⚠ eslint-plugin-import(no-named-as-default): Module "./export-default-string-and-named" has named export "foo". Using default import as "foo" can be confusing
⚠ eslint-plugin-import(no-named-as-default): Module "./export-default-string-and-named" has named export "foo"
╭─[index.js:1:8]
1 │ import foo, { foo as bar } from "./export-default-string-and-named"
· ───
╰────
help: Use another name for default import to avoid confusion
help: Using default import as "foo" can be confusing. Use another name for default import to avoid confusion.

View file

@ -257,9 +257,6 @@ impl ModuleRecordBuilder {
..ExportEntry::default()
};
self.add_export_entry(export_entry);
if let Some(id) = id {
self.add_export_binding(id.name.clone(), id.span);
}
}
fn visit_export_named_declaration(&mut self, decl: &ExportNamedDeclaration) {

View file

@ -12,13 +12,6 @@ fn test_class_simple() {
.is_exported()
.test();
SemanticTester::js("export default class Foo {};")
.has_root_symbol("Foo")
.contains_flags(SymbolFlags::Class | SymbolFlags::Export)
.has_number_of_references(0)
.is_exported()
.test();
SemanticTester::js("class Foo {}; let f = new Foo()")
.has_root_symbol("Foo")
.has_number_of_reads(1)

View file

@ -258,7 +258,7 @@ mod test {
assert!(!ImportImportName::NamespaceObject.is_default());
assert!(ImportImportName::Default(Span::new(0, 0)).is_default());
assert!(!ImportImportName::Name(name).is_namespace_object());
assert!(!ImportImportName::Name(name.clone()).is_namespace_object());
assert!(ImportImportName::NamespaceObject.is_namespace_object());
assert!(!ImportImportName::Default(Span::new(0, 0)).is_namespace_object());
}