Skip to content

Commit

Permalink
feat(linter / no_duplicate_imports): use with_labels instead of with_…
Browse files Browse the repository at this point in the history
…label to give more info
  • Loading branch information
Spoutnik97 committed Nov 23, 2024
1 parent bc9363d commit 9af872c
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 40 deletions.
61 changes: 49 additions & 12 deletions crates/oxc_linter/src/rules/eslint/no_duplicate_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,22 @@ use oxc_syntax::module_record::{ExportImportName, ImportImportName};

use crate::{context::LintContext, rule::Rule};

fn no_duplicate_imports_diagnostic(module_name: &str, span: Span) -> OxcDiagnostic {
fn no_duplicate_imports_diagnostic(module_name: &str, span: Span, span2: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("'{}' import is duplicated", module_name))
.with_help("Merge the duplicated import into a single import statement")
.with_label(span)
.with_labels([
span.label("This import is duplicated"),
span2.label("Can be merged with this import"),
])
}

fn no_duplicate_exports_diagnostic(module_name: &str, span: Span) -> OxcDiagnostic {
fn no_duplicate_exports_diagnostic(module_name: &str, span: Span, span2: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("'{}' export is duplicated", module_name))
.with_help("Merge the duplicated exports into a single export statement")
.with_label(span)
.with_labels([
span.label("This export is duplicated"),
span2.label("Can be merged with this"),
])
}

#[derive(Debug, Default, Clone)]
Expand Down Expand Up @@ -102,7 +108,11 @@ impl Rule for NoDuplicateImports {
if let Some(existing) = import_map.get(source) {
let can_merge = can_merge_imports(&import_type, existing, same_statement);
if can_merge {
ctx.diagnostic(no_duplicate_imports_diagnostic(source, span));
ctx.diagnostic(no_duplicate_imports_diagnostic(
source,
span,
existing.first().unwrap().1,
));
continue;
}
}
Expand All @@ -127,7 +137,14 @@ impl Rule for NoDuplicateImports {
side_effect_import_map.iter().for_each(|(source, spans)| {
if spans.len() > 1 {
spans.iter().for_each(|span| {
ctx.diagnostic(no_duplicate_imports_diagnostic(source, *span));
let i = spans.iter().position(|s| s == span).unwrap();
if i > 0 {
ctx.diagnostic(no_duplicate_imports_diagnostic(
source,
*span,
spans.first().unwrap().clone(),
));
}
});
}
});
Expand All @@ -144,12 +161,20 @@ impl Rule for NoDuplicateImports {
.iter()
.any(|(t, _, _)| matches!(t, ImportType::AllButDefault))
{
ctx.diagnostic(no_duplicate_exports_diagnostic(source, span));
ctx.diagnostic(no_duplicate_exports_diagnostic(
source,
span,
existing.first().unwrap().1,
));
continue;
}
}
if side_effect_import_map.get(source).is_some() {
ctx.diagnostic(no_duplicate_exports_diagnostic(source, span));
if let Some(existing) = side_effect_import_map.get(source) {
ctx.diagnostic(no_duplicate_exports_diagnostic(
source,
span,
*existing.first().unwrap(),
));
continue;
}
import_map.entry(source).or_default().push((
Expand All @@ -163,7 +188,11 @@ impl Rule for NoDuplicateImports {
if existing.iter().any(|(t, _, _)| {
matches!(t, ImportType::Named | ImportType::SideEffect)
}) {
ctx.diagnostic(no_duplicate_exports_diagnostic(source, span));
ctx.diagnostic(no_duplicate_exports_diagnostic(
source,
span,
existing.first().unwrap().1,
));
continue;
}
}
Expand All @@ -186,7 +215,11 @@ impl Rule for NoDuplicateImports {
if existing.iter().any(|(t, _, _)| {
matches!(t, ImportType::Default | ImportType::Namespace)
}) {
ctx.diagnostic(no_duplicate_exports_diagnostic(source, span));
ctx.diagnostic(no_duplicate_exports_diagnostic(
source,
span,
existing.first().unwrap().1,
));
continue;
}

Expand All @@ -201,7 +234,11 @@ impl Rule for NoDuplicateImports {
|| (matches!(t, ImportType::Default)
&& *module_type == ModuleType::Import)
}) {
ctx.diagnostic(no_duplicate_exports_diagnostic(source, span));
ctx.diagnostic(no_duplicate_exports_diagnostic(
source,
span,
existing.first().unwrap().1,
));
continue;
}
}
Expand Down
108 changes: 80 additions & 28 deletions crates/oxc_linter/src/snapshots/no_duplicate_imports.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,107 +3,159 @@ source: crates/oxc_linter/src/tester.rs
snapshot_kind: text
---
eslint(no-duplicate-imports): 'fs' import is duplicated
╭─[no_duplicate_imports.tsx:2:9]
╭─[no_duplicate_imports.tsx:1:8]
1import "fs";
· ──┬─
· ╰── Can be merged with this import
2import "fs"
· ───────────
· ──┬─
· ╰── This import is duplicated
╰────
help: Merge the duplicated import into a single import statement

eslint(no-duplicate-imports): 'lodash-es' import is duplicated
╭─[no_duplicate_imports.tsx:2:9]
╭─[no_duplicate_imports.tsx:1:23]
1import { merge } from "lodash-es";
· ─────┬─────
· ╰── Can be merged with this import
2import { find } from "lodash-es";
· ─────────────────────────────────
· ─────┬─────
· ╰── This import is duplicated
╰────
help: Merge the duplicated import into a single import statement

eslint(no-duplicate-imports): 'lodash-es' import is duplicated
╭─[no_duplicate_imports.tsx:2:11]
╭─[no_duplicate_imports.tsx:1:23]
1import { merge } from "lodash-es";
· ─────┬─────
· ╰── Can be merged with this import
2import _ from "lodash-es";
· ──────────────────────────
· ─────┬─────
· ╰── This import is duplicated
╰────
help: Merge the duplicated import into a single import statement

eslint(no-duplicate-imports): 'os' import is duplicated
╭─[no_duplicate_imports.tsx:2:11]
╭─[no_duplicate_imports.tsx:1:16]
1import os from "os";
· ──┬─
· ╰── Can be merged with this import
2import { something } from "os";
· ───────────────────────────────
3import * as foobar from "os";
· ──┬─
· ╰── This import is duplicated
╰────
help: Merge the duplicated import into a single import statement

eslint(no-duplicate-imports): 'lodash-es' import is duplicated
╭─[no_duplicate_imports.tsx:3:11]
╭─[no_duplicate_imports.tsx:1:24]
1import * as modns from "lodash-es";
· ─────┬─────
· ╰── Can be merged with this import
2import { merge } from "lodash-es";
3import { baz } from "lodash-es";
· ────────────────────────────────
· ─────┬─────
· ╰── This import is duplicated
╰────
help: Merge the duplicated import into a single import statement

eslint(no-duplicate-imports): 'os' export is duplicated
╭─[no_duplicate_imports.tsx:2:11]
╭─[no_duplicate_imports.tsx:1:10]
1export { os } from "os";
· ─┬
· ╰── Can be merged with this
2export { something } from "os";
· ───────────────────────────────
· ────┬────
· ╰── This export is duplicated
╰────
help: Merge the duplicated exports into a single export statement

eslint(no-duplicate-imports): 'os' export is duplicated
╭─[no_duplicate_imports.tsx:2:11]
╭─[no_duplicate_imports.tsx:1:16]
1import os from "os";
· ──┬─
· ╰── Can be merged with this
2export { os as foobar } from "os";
· ──────────────────────────────────
· ──────┬─────
· ╰── This export is duplicated
3export { something } from "os";
╰────
help: Merge the duplicated exports into a single export statement

eslint(no-duplicate-imports): 'os' export is duplicated
╭─[no_duplicate_imports.tsx:3:11]
╭─[no_duplicate_imports.tsx:1:16]
1import os from "os";
· ──┬─
· ╰── Can be merged with this
2export { os as foobar } from "os";
3export { something } from "os";
· ───────────────────────────────
· ────┬────
· ╰── This export is duplicated
╰────
help: Merge the duplicated exports into a single export statement

eslint(no-duplicate-imports): 'os' export is duplicated
╭─[no_duplicate_imports.tsx:2:11]
╭─[no_duplicate_imports.tsx:1:16]
1import os from "os";
· ──┬─
· ╰── Can be merged with this
2export { something } from "os";
· ───────────────────────────────
· ────┬────
· ╰── This export is duplicated
╰────
help: Merge the duplicated exports into a single export statement

eslint(no-duplicate-imports): 'os' export is duplicated
╭─[no_duplicate_imports.tsx:2:9]
╭─[no_duplicate_imports.tsx:1:16]
1import os from "os";
· ──┬─
· ╰── Can be merged with this
2export * as os from "os";
· ─────────────────────────
· ────────────┬────────────
· ╰── This export is duplicated
╰────
help: Merge the duplicated exports into a single export statement

eslint(no-duplicate-imports): 'os' import is duplicated
╭─[no_duplicate_imports.tsx:2:9]
eslint(no-duplicate-imports): 'os' export is duplicated
╭─[no_duplicate_imports.tsx:1:1]
1export * as os from "os";
· ────────────┬────────────
· ╰── This export is duplicated
2import os from "os";
· ────────────────────
· ──┬─
· ╰── Can be merged with this
╰────
help: Merge the duplicated import into a single import statement
help: Merge the duplicated exports into a single export statement

eslint(no-duplicate-imports): 'mod' export is duplicated
╭─[no_duplicate_imports.tsx:1:24]
1import * as modns from "mod";
· ──┬──
· ╰── Can be merged with this
2export * as modns from "mod";
· ───────────────┬──────────────
· ╰── This export is duplicated
╰────
help: Merge the duplicated exports into a single export statement

eslint(no-duplicate-imports): 'os' export is duplicated
╭─[no_duplicate_imports.tsx:2:9]
╭─[no_duplicate_imports.tsx:1:1]
1export * from "os";
· ─────────┬─────────
· ╰── Can be merged with this
2export * from "os";
· ───────────────────
· ─────────┬─────────
· ╰── This export is duplicated
╰────
help: Merge the duplicated exports into a single export statement

eslint(no-duplicate-imports): 'os' export is duplicated
╭─[no_duplicate_imports.tsx:2:9]
╭─[no_duplicate_imports.tsx:1:8]
1import "os";
· ──┬─
· ╰── Can be merged with this
2export * from "os";
· ───────────────────
· ─────────┬─────────
· ╰── This export is duplicated
╰────
help: Merge the duplicated exports into a single export statement

0 comments on commit 9af872c

Please sign in to comment.