mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
feat(parser): more friendly error for duplicate import attribute key (#28262)
The message felt a bit confusing for me.
**Before**
```
× Identifier `type` has already been declared
╭─[babel/packages/babel-parser/test/fixtures/es2025/import-attributes/invalid-syntax-export-with-repeated-type/input.js:1:50]
1 │ export { default as foo } from "foo.json" with { type: "json", type: "html" };
· ──┬─ ──┬─
· │ ╰── It can not be redeclared here
· ╰── `type` has already been declared here
╰────
```
**After**
```
× Duplicate import attribute key `type`
╭─[babel/packages/babel-parser/test/fixtures/es2025/import-attributes/invalid-syntax-export-with-repeated-type/input.js:1:50]
1 │ export { default as foo } from "foo.json" with { type: "json", type: "html" };
· ──┬─ ──┬─
· │ ╰── This key is repeated
· ╰── `type` was first specified here
╰────
help: Each import attribute key must be unique
```
This commit is contained in:
4 files changed
+38
-29
No files matched your search
@@ -87,13 +87,6 @@ macro_rules! parser_diagnostics {
|
||||
}
|
||||
|
||||
parser_diagnostics! {
|
||||
redeclaration(name: &'a str, declare_span: Span, redeclare_span: Span) => {
|
||||
OxcDiagnostic::error(format!("Identifier `{name}` has already been declared")).with_labels([
|
||||
declare_span.label(format!("`{name}` has already been declared here")),
|
||||
redeclare_span.label("It can not be redeclared here"),
|
||||
])
|
||||
};
|
||||
|
||||
overlong_source() => {
|
||||
OxcDiagnostic::error("Source length exceeds 4 GiB limit")
|
||||
};
|
||||
@@ -1359,6 +1352,15 @@ parser_diagnostics! {
|
||||
.with_help("Wrap this with quotes")
|
||||
};
|
||||
|
||||
duplicate_import_attribute_key(name: &'a str, previous_span: Span, duplicate_span: Span) => {
|
||||
OxcDiagnostic::error(format!("Duplicate import attribute key `{name}`"))
|
||||
.with_labels([
|
||||
previous_span.label(format!("`{name}` was already specified here")),
|
||||
duplicate_span.label("This key is repeated"),
|
||||
])
|
||||
.with_help("Each import attribute key must be unique")
|
||||
};
|
||||
|
||||
// TS18058
|
||||
default_import_not_allowed_in_defer(span: Span) => {
|
||||
ts_error("18058", "Default imports are not allowed in a deferred import.").with_label(span)
|
||||
|
||||
@@ -392,7 +392,7 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
let span = e.key.span();
|
||||
if let Some(old_span) = keys.insert(key, span) {
|
||||
let name = key.as_str().unwrap_or_else(|| span.source_text(self.source_text));
|
||||
self.error(diagnostics::redeclaration(name, old_span, span));
|
||||
self.error(diagnostics::duplicate_import_attribute_key(name, old_span, span));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9493,13 +9493,14 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
|
||||
· ───
|
||||
╰────
|
||||
|
||||
× Identifier `type` has already been declared
|
||||
× Duplicate import attribute key `type`
|
||||
╭─[babel/packages/babel-parser/test/fixtures/es2025/import-attributes/invalid-syntax-export-with-repeated-type/input.js:1:50]
|
||||
1 │ export { default as foo } from "foo.json" with { type: "json", type: "html" };
|
||||
· ──┬─ ──┬─
|
||||
· │ ╰── It can not be redeclared here
|
||||
· ╰── `type` has already been declared here
|
||||
· │ ╰── This key is repeated
|
||||
· ╰── `type` was already specified here
|
||||
╰────
|
||||
help: Each import attribute key must be unique
|
||||
|
||||
× Expected `{` but found `;`
|
||||
╭─[babel/packages/babel-parser/test/fixtures/es2025/import-attributes/invalid-syntax-export-without-attributes-identifier/input.js:1:29]
|
||||
@@ -9508,29 +9509,32 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
|
||||
· ╰── `{` expected
|
||||
╰────
|
||||
|
||||
× Identifier `type` has already been declared
|
||||
× Duplicate import attribute key `type`
|
||||
╭─[babel/packages/babel-parser/test/fixtures/es2025/import-attributes/invalid-syntax-with-repeated-type/input.js:1:35]
|
||||
1 │ import foo from "foo.json" with { type: "json", type: "html" };
|
||||
· ──┬─ ──┬─
|
||||
· │ ╰── It can not be redeclared here
|
||||
· ╰── `type` has already been declared here
|
||||
· │ ╰── This key is repeated
|
||||
· ╰── `type` was already specified here
|
||||
╰────
|
||||
help: Each import attribute key must be unique
|
||||
|
||||
× Identifier `type` has already been declared
|
||||
× Duplicate import attribute key `type`
|
||||
╭─[babel/packages/babel-parser/test/fixtures/es2025/import-attributes/invalid-syntax-with-repeated-type-string/input.js:1:35]
|
||||
1 │ import foo from "foo.json" with { "type": "json", type: "html", "type": "js" };
|
||||
· ───┬── ──┬─
|
||||
· │ ╰── It can not be redeclared here
|
||||
· ╰── `type` has already been declared here
|
||||
· │ ╰── This key is repeated
|
||||
· ╰── `type` was already specified here
|
||||
╰────
|
||||
help: Each import attribute key must be unique
|
||||
|
||||
× Identifier `type` has already been declared
|
||||
× Duplicate import attribute key `type`
|
||||
╭─[babel/packages/babel-parser/test/fixtures/es2025/import-attributes/invalid-syntax-with-repeated-type-string/input.js:1:51]
|
||||
1 │ import foo from "foo.json" with { "type": "json", type: "html", "type": "js" };
|
||||
· ──┬─ ───┬──
|
||||
· │ ╰── It can not be redeclared here
|
||||
· ╰── `type` has already been declared here
|
||||
· │ ╰── This key is repeated
|
||||
· ╰── `type` was already specified here
|
||||
╰────
|
||||
help: Each import attribute key must be unique
|
||||
|
||||
× Expected `{` but found `;`
|
||||
╭─[babel/packages/babel-parser/test/fixtures/es2025/import-attributes/invalid-syntax-without-attributes-identifier/input.js:1:16]
|
||||
|
||||
@@ -25811,41 +25811,44 @@ Negative Passed: 4653/4653 (100.00%)
|
||||
22 │
|
||||
╰────
|
||||
|
||||
× Identifier `type` has already been declared
|
||||
× Duplicate import attribute key `type`
|
||||
╭─[test262/test/language/module-code/import-attributes/early-dup-attribute-key-export.js:21:3]
|
||||
20 │ export * from './import-attribute-3_FIXTURE.js' with {
|
||||
21 │ type: 'json',
|
||||
· ──┬─
|
||||
· ╰── `type` has already been declared here
|
||||
· ╰── `type` was already specified here
|
||||
22 │ 'typ\u0065': ''
|
||||
· ─────┬─────
|
||||
· ╰── It can not be redeclared here
|
||||
· ╰── This key is repeated
|
||||
23 │ };
|
||||
╰────
|
||||
help: Each import attribute key must be unique
|
||||
|
||||
× Identifier `type` has already been declared
|
||||
× Duplicate import attribute key `type`
|
||||
╭─[test262/test/language/module-code/import-attributes/early-dup-attribute-key-import-nobinding.js:22:3]
|
||||
21 │ import './import-attribute-2_FIXTURE.js' with {
|
||||
22 │ type: 'json',
|
||||
· ──┬─
|
||||
· ╰── `type` has already been declared here
|
||||
· ╰── `type` was already specified here
|
||||
23 │ 'typ\u0065': ''
|
||||
· ─────┬─────
|
||||
· ╰── It can not be redeclared here
|
||||
· ╰── This key is repeated
|
||||
24 │ };
|
||||
╰────
|
||||
help: Each import attribute key must be unique
|
||||
|
||||
× Identifier `type` has already been declared
|
||||
× Duplicate import attribute key `type`
|
||||
╭─[test262/test/language/module-code/import-attributes/early-dup-attribute-key-import-withbinding.js:22:3]
|
||||
21 │ import x from './import-attribute-1_FIXTURE.js' with {
|
||||
22 │ type: 'json',
|
||||
· ──┬─
|
||||
· ╰── `type` has already been declared here
|
||||
· ╰── `type` was already specified here
|
||||
23 │ 'typ\u0065': ''
|
||||
· ─────┬─────
|
||||
· ╰── It can not be redeclared here
|
||||
· ╰── This key is repeated
|
||||
24 │ };
|
||||
╰────
|
||||
help: Each import attribute key must be unique
|
||||
|
||||
× Private identifier '#x' is not allowed outside class bodies
|
||||
╭─[test262/test/language/module-code/invalid-private-names-call-expression-bad-reference.js:40:14]
|
||||
|
||||
Reference in new issue
Block a user