-
-
Notifications
You must be signed in to change notification settings - Fork 714
fix(useImportType): inline import type
into import { type }
when style=inlineType
#7316
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🦋 Changeset detectedLatest commit: 2a464f4 The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
WalkthroughThe PR updates the useImportType lint to support the inlineType style by inlining per‑specifier Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Suggested reviewers
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
Status, Documentation and Community
|
…'style=inlineType'
CodSpeed Performance ReportMerging #7316 will not alter performanceComparing Summary
|
50bb8be
to
49a1c52
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
crates/biome_js_analyze/src/lint/style/use_import_type.rs (2)
180-184
: Bug: guard now disables the rule in far too many files.
is_none_or(|ext| ext != "cts")
returns true for “no extension” and for any non-cts
extension, so the rule bails out whenever import attributes are present in almost all cases. The intended behaviour (per prior discussion) is to bail only when the extension is explicitly present and notcts
, leaving “no extension” paths unaffected.Switch to
is_some_and
so “no extension” no longer short-circuits the rule.Apply this diff:
- if import_clause.attribute().is_some() - && ctx.file_path().extension().is_none_or(|extension| extension != "cts") - && !matches!(ctx.root(), AnyJsRoot::JsScript(_)) - { + if import_clause.attribute().is_some() + && ctx.file_path() + .extension() + .is_some_and(|extension| extension != "cts") + && !matches!(ctx.root(), AnyJsRoot::JsScript(_)) + { return None; }
756-771
: Fixer can silently no-op when a specifier has no leading trivia.
specifier.syntax().first_leading_trivia()?
may beNone
(e.g.import type {A} from "mod";
). The?
then aborts the whole action, so no fix is produced. Also, moving the specifier’s leading trivia onto the newly insertedtype
token risks mangling comments.Prefer a simpler, safer insertion that doesn’t depend on existing trivia.
Apply this diff:
- for specifier in specifiers { - let new_specifier = specifier - .clone() - .with_leading_trivia_pieces([])? - .with_type_token(Some( - make::token(T![type]) - .with_leading_trivia_pieces( - specifier.syntax().first_leading_trivia()?.pieces(), - ) - .with_trailing_trivia([(TriviaPieceKind::Whitespace, " ")]), - )); - mutation.replace_node(specifier.clone(), new_specifier); - } + for specifier in specifiers { + let new_specifier = specifier.clone().with_type_token(Some( + make::token(T![type]) + .with_trailing_trivia([(TriviaPieceKind::Whitespace, " ")]), + )); + mutation.replace_node(specifier.clone(), new_specifier); + }If you want to preserve comments strictly before the identifier (e.g.
/* id */ A
), keep them attached to the specifier (not thetype
token). The formatter will normalise spacing betweentype
and the identifier.
🧹 Nitpick comments (1)
crates/biome_js_analyze/src/lint/style/use_import_type.rs (1)
413-421
: Tighter diagnostic span for clarity.When suggesting “Use import { type } instead of import type”, anchor the diagnostic to the actual
type
keyword, not the whole clause. This improves UX in editors.Apply this diff:
- if import_clause.type_token().is_some() { - RuleDiagnostic::new( - rule_category!(), - import_clause.range(), - markup! { - "Use "<Emphasis>"import { type }"</Emphasis>" instead of "<Emphasis>"import type"</Emphasis>"." - }, - ) - } else { + if let Some(type_kw) = import_clause.type_token() { + RuleDiagnostic::new( + rule_category!(), + type_kw.text_trimmed_range(), + markup! { + "Use "<Emphasis>"import { type }"</Emphasis>" instead of "<Emphasis>"import type"</Emphasis>"." + }, + ) + } else {Optional follow-up: consider updating the trailing note (below Line 453) to mention both forms remove types at emit time, to avoid confusing users on the inline path.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (2)
crates/biome_js_analyze/tests/specs/style/useImportType/invalid-inline-type.ts.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/style/useImportType/valid-inline-type.ts.snap
is excluded by!**/*.snap
and included by**
📒 Files selected for processing (4)
.changeset/chatty-ravens-agree.md
(1 hunks)crates/biome_js_analyze/src/lint/style/use_import_type.rs
(4 hunks)crates/biome_js_analyze/tests/specs/style/useImportType/invalid-inline-type.ts
(1 hunks)crates/biome_js_analyze/tests/specs/style/useImportType/valid-inline-type.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- .changeset/chatty-ravens-agree.md
- crates/biome_js_analyze/tests/specs/style/useImportType/invalid-inline-type.ts
🧰 Additional context used
📓 Path-based instructions (4)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**
📄 CodeRabbit inference engine (CLAUDE.md)
Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}
Files:
crates/biome_js_analyze/tests/specs/style/useImportType/valid-inline-type.ts
crates/biome_js_analyze/src/lint/style/use_import_type.rs
crates/biome_*/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place core crates under /crates/biome_*/
Files:
crates/biome_js_analyze/tests/specs/style/useImportType/valid-inline-type.ts
crates/biome_js_analyze/src/lint/style/use_import_type.rs
**/tests/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place test files under a tests/ directory in each crate
Files:
crates/biome_js_analyze/tests/specs/style/useImportType/valid-inline-type.ts
**/*.{rs,toml}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Format Rust and TOML files before committing (use
just f
/just format
).
Files:
crates/biome_js_analyze/src/lint/style/use_import_type.rs
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Use TypeData::Unknown for unimplemented inference and TypeData::UnknownKeyword for the explicit TypeScript unknown keyword; treat them semantically the same but keep them distinct for measurement
Applied to files:
crates/biome_js_analyze/src/lint/style/use_import_type.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors
Applied to files:
crates/biome_js_analyze/src/lint/style/use_import_type.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : For new JavaScript lint rules generated by `just new-js-lintrule`, implement the rule in the generated file under `biome_js_analyze/lib/src/lint/nursery/`
Applied to files:
crates/biome_js_analyze/src/lint/style/use_import_type.rs
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Specify category and severity using #[diagnostic(...)] on the type or derive them from fields
Applied to files:
crates/biome_js_analyze/src/lint/style/use_import_type.rs
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/lint/style/use_import_type.rs (2)
crates/biome_js_syntax/src/import_ext.rs (2)
import_clause
(169-171)named_specifiers
(78-94)crates/biome_service/src/workspace.rs (1)
markup
(1130-1132)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
- GitHub Check: Test Node.js API
- GitHub Check: Bench (biome_configuration)
- GitHub Check: Bench (biome_module_graph)
- GitHub Check: Bench (biome_graphql_parser)
- GitHub Check: Bench (biome_html_formatter)
- GitHub Check: Bench (biome_graphql_formatter)
- GitHub Check: Bench (biome_json_analyze)
- GitHub Check: Bench (biome_css_analyze)
- GitHub Check: Bench (biome_html_parser)
- GitHub Check: Bench (biome_json_formatter)
- GitHub Check: Bench (biome_css_formatter)
- GitHub Check: Bench (biome_css_parser)
- GitHub Check: Bench (biome_json_parser)
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: Bench (biome_js_analyze)
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: autofix
🔇 Additional comments (3)
crates/biome_js_analyze/tests/specs/style/useImportType/valid-inline-type.ts (1)
9-11
: Good edge-case coverage.Adding
import type {} from "mod";
under a “valid” test is sensible and protects the fixer from trying to inline when there are no specifiers. Nice one.crates/biome_js_analyze/src/lint/style/use_import_type.rs (2)
287-304
: Early inlining path looks correct.Short-circuiting for
Style::InlineType
when a top-leveltype
exists keeps the logic simple and makes the fixer’s intent obvious. Good call.
308-309
: Minor: good reuse oftype_token
.Passing
type_token.is_some()
avoids recomputing; tidy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
crates/biome_js_analyze/src/lint/style/use_import_type.rs (1)
764-775
: Handle specifiers without leading trivia; current code can noop the fix.specifier.syntax().first_leading_trivia()? can be absent (e.g. import type {A} without spaces). The ? will abort the whole action, so no fix is applied. Use a best-effort approach: steal trivia when present; otherwise, just insert type with no extra leading trivia.
Suggested change:
- let new_specifier = specifier - .clone() - .with_leading_trivia_pieces([])? - .with_type_token(Some( - make::token(T![type]) - .with_leading_trivia_pieces( - specifier.syntax().first_leading_trivia()?.pieces(), - ) - .with_trailing_trivia([(TriviaPieceKind::Whitespace, " ")]), - )); + let mut type_tok = make::token(T![type]) + .with_trailing_trivia([(TriviaPieceKind::Whitespace, " ")]); + if let Some(trivia) = specifier.syntax().first_leading_trivia() { + type_tok = type_tok.with_leading_trivia_pieces(trivia.pieces()); + } + let new_specifier = specifier + .clone() + // Drop the specifier's original leading trivia so it becomes owned by `type` + .with_leading_trivia_pieces([])? + .with_type_token(Some(type_tok));Would you like me to add a test case for import type {A} (no spaces) to ensure this path is covered?
♻️ Duplicate comments (1)
crates/biome_js_analyze/src/lint/style/use_import_type.rs (1)
180-184
: Good fix for the short-circuit; watch MSRV for Option::is_none_or.This addresses the earlier early-return bug. However, Option::is_none_or may be newer than your MSRV. Using map_or keeps MSRV friction-free.
Proposed MSRV-safe tweak:
- .is_none_or(|extension| extension != "cts") + .map_or(true, |extension| extension != "cts")
🧹 Nitpick comments (1)
crates/biome_js_analyze/src/lint/style/use_import_type.rs (1)
290-307
: InlineType fast path: avoid bailing when any specifier node is Err.collect::<Result<Vec<_>, _>>().ok()? drops the whole signal if any specifier fails to cast. Prefer skipping the bad node(s) as other paths in this rule already do.
- let specifiers = clause - .named_specifiers() - .ok()? - .specifiers() - .iter() - .collect::<Result<Vec<_>, _>>() - .ok()?; + let specifiers: Vec<_> = clause + .named_specifiers() + .ok()? + .specifiers() + .iter() + .filter_map(Result::ok) + .collect();
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
crates/biome_js_analyze/src/lint/style/use_import_type.rs
(4 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{rs,toml}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Format Rust and TOML files before committing (use
just f
/just format
).
Files:
crates/biome_js_analyze/src/lint/style/use_import_type.rs
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**
📄 CodeRabbit inference engine (CLAUDE.md)
Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}
Files:
crates/biome_js_analyze/src/lint/style/use_import_type.rs
crates/biome_*/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place core crates under /crates/biome_*/
Files:
crates/biome_js_analyze/src/lint/style/use_import_type.rs
🧠 Learnings (3)
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Use TypeData::Unknown for unimplemented inference and TypeData::UnknownKeyword for the explicit TypeScript unknown keyword; treat them semantically the same but keep them distinct for measurement
Applied to files:
crates/biome_js_analyze/src/lint/style/use_import_type.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors
Applied to files:
crates/biome_js_analyze/src/lint/style/use_import_type.rs
📚 Learning: 2025-08-11T11:46:05.836Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:46:05.836Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : Specify category and severity using #[diagnostic(...)] on the type or derive them from fields
Applied to files:
crates/biome_js_analyze/src/lint/style/use_import_type.rs
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/lint/style/use_import_type.rs (1)
crates/biome_js_syntax/src/import_ext.rs (2)
import_clause
(169-171)named_specifiers
(78-94)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (25)
- GitHub Check: Documentation
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Check Dependencies
- GitHub Check: End-to-end tests
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
- GitHub Check: Test Node.js API
- GitHub Check: Bench (biome_graphql_formatter)
- GitHub Check: Bench (biome_module_graph)
- GitHub Check: Bench (biome_html_formatter)
- GitHub Check: Bench (biome_graphql_parser)
- GitHub Check: Bench (biome_json_analyze)
- GitHub Check: Bench (biome_html_parser)
- GitHub Check: Bench (biome_package)
- GitHub Check: Bench (biome_json_parser)
- GitHub Check: Bench (biome_configuration)
- GitHub Check: Bench (biome_json_formatter)
- GitHub Check: Bench (biome_css_analyze)
- GitHub Check: Bench (biome_js_analyze)
- GitHub Check: Bench (biome_css_formatter)
- GitHub Check: Bench (biome_css_parser)
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: autofix
🔇 Additional comments (3)
crates/biome_js_analyze/src/lint/style/use_import_type.rs (3)
311-312
: Minor readability win.Reusing the local type_token is tidy and avoids duplicate lookups. LGTM.
415-435
: Clearer diagnostic when converting import type → import { type }.Nice touch: the message now points precisely at the preferred inline form.
759-763
: Necessary removal of the clause-level type before inlining.This prevents producing import { type A } with a stray top-level type. All good.
…`style=inlineType` (#7316)
…`style=inlineType` (biomejs#7316)
…`style=inlineType` (biomejs#7316)
Summary
Fix #7289
Test Plan
I added a test
Docs
No change.