mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
refactor(linter/import): better diagnostic messages for import/no-duplicates (#6693)
## What This PR Does - Include the offending module in the diagnostic's message - Add a help message - Add label text to the first module request It also includes these minor refactors: - Move `check_request` closure into a separate function - Move diagnostics creation to a separate function (same as every other rule)
This commit is contained in:
parent
85e69a11ef
commit
23f88b3e18
2 changed files with 243 additions and 124 deletions
|
|
@ -1,10 +1,36 @@
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
|
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
|
||||||
use oxc_macros::declare_oxc_lint;
|
use oxc_macros::declare_oxc_lint;
|
||||||
|
use oxc_span::Span;
|
||||||
use oxc_syntax::module_record::{ImportImportName, RequestedModule};
|
use oxc_syntax::module_record::{ImportImportName, RequestedModule};
|
||||||
|
|
||||||
use crate::{context::LintContext, rule::Rule};
|
use crate::{context::LintContext, rule::Rule};
|
||||||
|
|
||||||
|
fn no_duplicates_diagnostic<I>(
|
||||||
|
module_name: &str,
|
||||||
|
first_import: Span,
|
||||||
|
other_imports: I,
|
||||||
|
) -> OxcDiagnostic
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = Span>,
|
||||||
|
{
|
||||||
|
const MAX_MODULE_LEN: usize = 16;
|
||||||
|
|
||||||
|
let message = if module_name.len() > MAX_MODULE_LEN {
|
||||||
|
Cow::Borrowed("Modules should not be imported multiple times in the same file")
|
||||||
|
} else {
|
||||||
|
Cow::Owned(format!("Module '{module_name}' is imported more than once in this file"))
|
||||||
|
};
|
||||||
|
let labels = std::iter::once(first_import.primary_label("It is first imported here"))
|
||||||
|
.chain(other_imports.into_iter().map(LabeledSpan::underline));
|
||||||
|
|
||||||
|
OxcDiagnostic::warn(message)
|
||||||
|
.with_labels(labels)
|
||||||
|
.with_help("Merge these imports into a single import statement")
|
||||||
|
}
|
||||||
|
|
||||||
/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-duplicates.md>
|
/// <https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-duplicates.md>
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub struct NoDuplicates {
|
pub struct NoDuplicates {
|
||||||
|
|
@ -64,23 +90,6 @@ impl Rule for NoDuplicates {
|
||||||
})
|
})
|
||||||
.chunk_by(|r| r.0.clone());
|
.chunk_by(|r| r.0.clone());
|
||||||
|
|
||||||
let check_duplicates = |requested_modules: Option<&Vec<&RequestedModule>>| {
|
|
||||||
if let Some(requested_modules) = requested_modules {
|
|
||||||
if requested_modules.len() > 1 {
|
|
||||||
let labels = requested_modules
|
|
||||||
.iter()
|
|
||||||
.map(|requested_module| LabeledSpan::underline(requested_module.span()))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
ctx.diagnostic(
|
|
||||||
OxcDiagnostic::warn(
|
|
||||||
"Forbid repeated import of the same module in multiple places",
|
|
||||||
)
|
|
||||||
.with_labels(labels),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (_path, group) in &groups {
|
for (_path, group) in &groups {
|
||||||
let has_type_import = module_record.import_entries.iter().any(|entry| entry.is_type);
|
let has_type_import = module_record.import_entries.iter().any(|entry| entry.is_type);
|
||||||
// When prefer_inline is false, 0 is value, 1 is type named, 2 is type namespace and 3 is type default
|
// When prefer_inline is false, 0 is value, 1 is type named, 2 is type namespace and 3 is type default
|
||||||
|
|
@ -110,10 +119,20 @@ impl Rule for NoDuplicates {
|
||||||
0
|
0
|
||||||
});
|
});
|
||||||
|
|
||||||
check_duplicates(import_entries_maps.get(&0));
|
for i in 0..4 {
|
||||||
check_duplicates(import_entries_maps.get(&1));
|
check_duplicates(ctx, import_entries_maps.get(&i));
|
||||||
check_duplicates(import_entries_maps.get(&2));
|
}
|
||||||
check_duplicates(import_entries_maps.get(&3));
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_duplicates(ctx: &LintContext, requested_modules: Option<&Vec<&RequestedModule>>) {
|
||||||
|
if let Some(requested_modules) = requested_modules {
|
||||||
|
if requested_modules.len() > 1 {
|
||||||
|
let mut labels = requested_modules.iter().map(|m| m.span());
|
||||||
|
let first = labels.next().unwrap(); // we know there is at least one
|
||||||
|
let module_name = ctx.source_range(first).trim_matches('\'').trim_matches('"');
|
||||||
|
ctx.diagnostic(no_duplicates_diagnostic(module_name, first, labels));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,68 +1,88 @@
|
||||||
---
|
---
|
||||||
source: crates/oxc_linter/src/tester.rs
|
source: crates/oxc_linter/src/tester.rs
|
||||||
---
|
---
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:19]
|
╭─[index.ts:1:19]
|
||||||
1 │ import { x } from './foo'; import { y } from './foo'
|
1 │ import { x } from './foo'; import { y } from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import {x} from './foo'; import {y} from './foo'; import { z } from './foo'
|
1 │ import {x} from './foo'; import {y} from './foo'; import { z } from './foo'
|
||||||
· ─────── ─────── ───────
|
· ───┬─── ─────── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './bar?optionX' is imported more than once in this file
|
||||||
╭─[index.ts:1:15]
|
╭─[index.ts:1:49]
|
||||||
1 │ import x from './bar.js?optionX'; import y from './bar?optionX';
|
1 │ import x from './bar.js?optionX'; import y from './bar?optionX';
|
||||||
· ────────────────── ───────────────
|
· ────────────────── ───────┬───────
|
||||||
|
· │ ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './bar?optionY' is imported more than once in this file
|
||||||
╭─[index.ts:1:15]
|
╭─[index.ts:1:46]
|
||||||
1 │ import x from './bar?optionX'; import y from './bar?optionY';
|
1 │ import x from './bar?optionX'; import y from './bar?optionY';
|
||||||
· ─────────────── ───────────────
|
· ─────────────── ───────┬───────
|
||||||
|
· │ ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './bar.js?optionX' is imported more than once in this file
|
||||||
╭─[index.ts:1:15]
|
╭─[index.ts:1:46]
|
||||||
1 │ import x from './bar?optionX'; import y from './bar.js?optionX';
|
1 │ import x from './bar?optionX'; import y from './bar.js?optionX';
|
||||||
· ─────────────── ──────────────────
|
· ─────────────── ─────────┬────────
|
||||||
|
· │ ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module 'non-existent' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import foo from 'non-existent'; import bar from 'non-existent';
|
1 │ import foo from 'non-existent'; import bar from 'non-existent';
|
||||||
· ────────────── ──────────────
|
· ───────┬────── ──────────────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:24]
|
╭─[index.ts:1:24]
|
||||||
1 │ import type { x } from './foo'; import type { y } from './foo'
|
1 │ import type { x } from './foo'; import type { y } from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:8]
|
╭─[index.ts:1:8]
|
||||||
1 │ import './foo'; import './foo'
|
1 │ import './foo'; import './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:28]
|
╭─[index.ts:1:28]
|
||||||
1 │ import { x, /* x */ } from './foo'; import {//y
|
1 │ import { x, /* x */ } from './foo'; import {//y
|
||||||
· ───────
|
· ───┬───
|
||||||
|
· ╰── It is first imported here
|
||||||
2 │ y//y2
|
2 │ y//y2
|
||||||
3 │ } from './foo'
|
3 │ } from './foo'
|
||||||
· ───────
|
· ───────
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import {x} from './foo'; import {} from './foo'
|
1 │ import {x} from './foo'; import {} from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
× Identifier `a` has already been declared
|
× Identifier `a` has already been declared
|
||||||
╭─[index.ts:1:9]
|
╭─[index.ts:1:9]
|
||||||
|
|
@ -144,221 +164,279 @@ source: crates/oxc_linter/src/tester.rs
|
||||||
· ╰── `a` has already been declared here
|
· ╰── `a` has already been declared here
|
||||||
╰────
|
╰────
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import {x} from './foo'; import {} from './foo'; import {/*c*/} from './foo'; import {y} from './foo'
|
1 │ import {x} from './foo'; import {} from './foo'; import {/*c*/} from './foo'; import {y} from './foo'
|
||||||
· ─────── ─────── ─────── ───────
|
· ───┬─── ─────── ─────── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import { } from './foo'; import {x} from './foo'
|
1 │ import { } from './foo'; import {x} from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:8]
|
╭─[index.ts:1:8]
|
||||||
1 │ import './foo'; import {x} from './foo'
|
1 │ import './foo'; import {x} from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:7]
|
╭─[index.ts:1:7]
|
||||||
1 │ import'./foo'; import {x} from './foo'
|
1 │ import'./foo'; import {x} from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:8]
|
╭─[index.ts:1:8]
|
||||||
1 │ import './foo'; import { /*x*/} from './foo'; import {//y
|
1 │ import './foo'; import { /*x*/} from './foo'; import {//y
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
2 │ } from './foo'; import {z} from './foo'
|
2 │ } from './foo'; import {z} from './foo'
|
||||||
· ─────── ───────
|
· ─────── ───────
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:8]
|
╭─[index.ts:1:8]
|
||||||
1 │ import './foo'; import def, {x} from './foo'
|
1 │ import './foo'; import def, {x} from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:8]
|
╭─[index.ts:1:8]
|
||||||
1 │ import './foo'; import def from './foo'
|
1 │ import './foo'; import def from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import def from './foo'; import {x} from './foo'
|
1 │ import def from './foo'; import {x} from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import {x} from './foo'; import def from './foo'
|
1 │ import {x} from './foo'; import def from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:16]
|
╭─[index.ts:1:16]
|
||||||
1 │ import{x} from './foo'; import def from './foo'
|
1 │ import{x} from './foo'; import def from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import {x} from './foo'; import def, {y} from './foo'
|
1 │ import {x} from './foo'; import def, {y} from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:22]
|
╭─[index.ts:1:22]
|
||||||
1 │ import * as ns1 from './foo'; import * as ns2 from './foo'
|
1 │ import * as ns1 from './foo'; import * as ns2 from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:21]
|
╭─[index.ts:1:21]
|
||||||
1 │ import * as ns from './foo'; import {x} from './foo'; import {y} from './foo'
|
1 │ import * as ns from './foo'; import {x} from './foo'; import {y} from './foo'
|
||||||
· ─────── ─────── ───────
|
· ───┬─── ─────── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import {x} from './foo'; import * as ns from './foo'; import {y} from './foo'; import './foo'
|
1 │ import {x} from './foo'; import * as ns from './foo'; import {y} from './foo'; import './foo'
|
||||||
· ─────── ─────── ─────── ───────
|
· ───┬─── ─────── ─────── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:2:29]
|
╭─[index.ts:2:29]
|
||||||
1 │ // some-tool-disable-next-line
|
1 │ // some-tool-disable-next-line
|
||||||
2 │ import {x} from './foo'
|
2 │ import {x} from './foo'
|
||||||
· ───────
|
· ───┬───
|
||||||
|
· ╰── It is first imported here
|
||||||
3 │ import {//y
|
3 │ import {//y
|
||||||
4 │ y} from './foo'
|
4 │ y} from './foo'
|
||||||
· ───────
|
· ───────
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import {x} from './foo'
|
1 │ import {x} from './foo'
|
||||||
· ───────
|
· ───┬───
|
||||||
|
· ╰── It is first imported here
|
||||||
2 │ // some-tool-disable-next-line
|
2 │ // some-tool-disable-next-line
|
||||||
3 │ import {y} from './foo'
|
3 │ import {y} from './foo'
|
||||||
· ───────
|
· ───────
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import {x} from './foo' // some-tool-disable-line
|
1 │ import {x} from './foo' // some-tool-disable-line
|
||||||
· ───────
|
· ───┬───
|
||||||
|
· ╰── It is first imported here
|
||||||
2 │ import {y} from './foo'
|
2 │ import {y} from './foo'
|
||||||
· ───────
|
· ───────
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import {x} from './foo'
|
1 │ import {x} from './foo'
|
||||||
· ───────
|
· ───┬───
|
||||||
|
· ╰── It is first imported here
|
||||||
2 │ import {y} from './foo' // some-tool-disable-line
|
2 │ import {y} from './foo' // some-tool-disable-line
|
||||||
· ───────
|
· ───────
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import {x} from './foo'
|
1 │ import {x} from './foo'
|
||||||
· ───────
|
· ───┬───
|
||||||
|
· ╰── It is first imported here
|
||||||
2 │ /* comment */ import {y} from './foo'
|
2 │ /* comment */ import {y} from './foo'
|
||||||
· ───────
|
· ───────
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import {x} from './foo'
|
1 │ import {x} from './foo'
|
||||||
· ───────
|
· ───┬───
|
||||||
|
· ╰── It is first imported here
|
||||||
2 │ import {y} from './foo' /* comment
|
2 │ import {y} from './foo' /* comment
|
||||||
· ───────
|
· ───────
|
||||||
3 │ multiline */
|
3 │ multiline */
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import {x} from './foo'
|
1 │ import {x} from './foo'
|
||||||
· ───────
|
· ───┬───
|
||||||
|
· ╰── It is first imported here
|
||||||
2 │ import {y} from './foo'
|
2 │ import {y} from './foo'
|
||||||
· ───────
|
· ───────
|
||||||
3 │ // some-tool-disable-next-line
|
3 │ // some-tool-disable-next-line
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import {x} from './foo'
|
1 │ import {x} from './foo'
|
||||||
· ───────
|
· ───┬───
|
||||||
|
· ╰── It is first imported here
|
||||||
2 │ // comment
|
2 │ // comment
|
||||||
3 │
|
3 │
|
||||||
4 │ import {y} from './foo'
|
4 │ import {y} from './foo'
|
||||||
· ───────
|
· ───────
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import {x} from './foo'
|
1 │ import {x} from './foo'
|
||||||
· ───────
|
· ───┬───
|
||||||
|
· ╰── It is first imported here
|
||||||
2 │ import/* comment */{y} from './foo'
|
2 │ import/* comment */{y} from './foo'
|
||||||
· ───────
|
· ───────
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import {x} from './foo'
|
1 │ import {x} from './foo'
|
||||||
· ───────
|
· ───┬───
|
||||||
|
· ╰── It is first imported here
|
||||||
2 │ import/* comment */'./foo'
|
2 │ import/* comment */'./foo'
|
||||||
· ───────
|
· ───────
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import {x} from './foo'
|
1 │ import {x} from './foo'
|
||||||
· ───────
|
· ───┬───
|
||||||
|
· ╰── It is first imported here
|
||||||
2 │ import{y}/* comment */from './foo'
|
2 │ import{y}/* comment */from './foo'
|
||||||
· ───────
|
· ───────
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:17]
|
╭─[index.ts:1:17]
|
||||||
1 │ import {x} from './foo'
|
1 │ import {x} from './foo'
|
||||||
· ───────
|
· ───┬───
|
||||||
|
· ╰── It is first imported here
|
||||||
2 │ import{y}from/* comment */'./foo'
|
2 │ import{y}from/* comment */'./foo'
|
||||||
· ───────
|
· ───────
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:3:13]
|
╭─[index.ts:3:13]
|
||||||
2 │ // some-tool-disable-next-line
|
2 │ // some-tool-disable-next-line
|
||||||
3 │ './foo'
|
3 │ './foo'
|
||||||
· ───────
|
· ───┬───
|
||||||
|
· ╰── It is first imported here
|
||||||
4 │ import {y} from './foo'
|
4 │ import {y} from './foo'
|
||||||
· ───────
|
· ───────
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:21]
|
╭─[index.ts:1:21]
|
||||||
1 │ import { Foo } from './foo';
|
1 │ import { Foo } from './foo';
|
||||||
· ───────
|
· ───┬───
|
||||||
|
· ╰── It is first imported here
|
||||||
2 │ import { Bar } from './foo';
|
2 │ import { Bar } from './foo';
|
||||||
· ───────
|
· ───────
|
||||||
3 │ export const value = {}
|
3 │ export const value = {}
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:21]
|
╭─[index.ts:1:21]
|
||||||
1 │ import { Foo } from './foo';
|
1 │ import { Foo } from './foo';
|
||||||
· ───────
|
· ───┬───
|
||||||
|
· ╰── It is first imported here
|
||||||
2 │ import Bar from './foo';
|
2 │ import Bar from './foo';
|
||||||
· ───────
|
· ───────
|
||||||
3 │ export const value = {}
|
3 │ export const value = {}
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
× Unexpected token
|
× Unexpected token
|
||||||
╭─[index.ts:12:16]
|
╭─[index.ts:12:16]
|
||||||
|
|
@ -368,22 +446,25 @@ source: crates/oxc_linter/src/tester.rs
|
||||||
13 │ }
|
13 │ }
|
||||||
╰────
|
╰────
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module 'foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:19]
|
╭─[index.ts:1:19]
|
||||||
1 │ import {A1,} from 'foo';
|
1 │ import {A1,} from 'foo';
|
||||||
· ─────
|
· ──┬──
|
||||||
|
· ╰── It is first imported here
|
||||||
2 │ import {B1,} from 'foo';
|
2 │ import {B1,} from 'foo';
|
||||||
· ─────
|
· ─────
|
||||||
3 │ import {C1,} from 'foo';
|
3 │ import {C1,} from 'foo';
|
||||||
· ─────
|
· ─────
|
||||||
4 │
|
4 │
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module 'bar' is imported more than once in this file
|
||||||
╭─[index.ts:7:20]
|
╭─[index.ts:7:20]
|
||||||
6 │ A2,
|
6 │ A2,
|
||||||
7 │ } from 'bar';
|
7 │ } from 'bar';
|
||||||
· ─────
|
· ──┬──
|
||||||
|
· ╰── It is first imported here
|
||||||
8 │ import {
|
8 │ import {
|
||||||
9 │ B2,
|
9 │ B2,
|
||||||
10 │ } from 'bar';
|
10 │ } from 'bar';
|
||||||
|
|
@ -393,12 +474,15 @@ source: crates/oxc_linter/src/tester.rs
|
||||||
13 │ } from 'bar';
|
13 │ } from 'bar';
|
||||||
· ─────
|
· ─────
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:20]
|
╭─[index.ts:1:20]
|
||||||
1 │ import type x from './foo'; import type y from './foo'
|
1 │ import type x from './foo'; import type y from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
× Identifier `x` has already been declared
|
× Identifier `x` has already been declared
|
||||||
╭─[index.ts:1:13]
|
╭─[index.ts:1:13]
|
||||||
|
|
@ -408,50 +492,66 @@ source: crates/oxc_linter/src/tester.rs
|
||||||
· ╰── `x` has already been declared here
|
· ╰── `x` has already been declared here
|
||||||
╰────
|
╰────
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:22]
|
╭─[index.ts:1:22]
|
||||||
1 │ import type {x} from './foo'; import type {y} from './foo'
|
1 │ import type {x} from './foo'; import type {y} from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:22]
|
╭─[index.ts:1:22]
|
||||||
1 │ import {type x} from './foo'; import type {y} from './foo'
|
1 │ import {type x} from './foo'; import type {y} from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module 'foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:22]
|
╭─[index.ts:1:22]
|
||||||
1 │ import {type x} from 'foo'; import type {y} from 'foo'
|
1 │ import {type x} from 'foo'; import type {y} from 'foo'
|
||||||
· ───── ─────
|
· ──┬── ─────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module 'foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:22]
|
╭─[index.ts:1:22]
|
||||||
1 │ import {type x} from 'foo'; import type {y} from 'foo'
|
1 │ import {type x} from 'foo'; import type {y} from 'foo'
|
||||||
· ───── ─────
|
· ──┬── ─────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:22]
|
╭─[index.ts:1:22]
|
||||||
1 │ import {type x} from './foo'; import {type y} from './foo'
|
1 │ import {type x} from './foo'; import {type y} from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:22]
|
╭─[index.ts:1:22]
|
||||||
1 │ import {type x} from './foo'; import {type y} from './foo'
|
1 │ import {type x} from './foo'; import {type y} from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:38]
|
╭─[index.ts:1:38]
|
||||||
1 │ import {AValue, type x, BValue} from './foo'; import {type y} from './foo'
|
1 │ import {AValue, type x, BValue} from './foo'; import {type y} from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
||||||
⚠ eslint-plugin-import(no-duplicates): Forbid repeated import of the same module in multiple places
|
⚠ eslint-plugin-import(no-duplicates): Module './foo' is imported more than once in this file
|
||||||
╭─[index.ts:1:22]
|
╭─[index.ts:1:22]
|
||||||
1 │ import {AValue} from './foo'; import type {AType} from './foo'
|
1 │ import {AValue} from './foo'; import type {AType} from './foo'
|
||||||
· ─────── ───────
|
· ───┬─── ───────
|
||||||
|
· ╰── It is first imported here
|
||||||
╰────
|
╰────
|
||||||
|
help: Merge these imports into a single import statement
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue