Skip to content

Conversation

ematipico
Copy link
Member

Summary

Closes #6835

I tracked down the issue inside the semantic model. The issue, however, caused a regression inside another snapshot, which I believe makes sense. What do you think?

If you agree, I will make the use case valid

Test Plan

Added a new test

Docs

Copy link

changeset-bot bot commented Aug 21, 2025

⚠️ No Changeset found

Latest commit: 3a4017d

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

coderabbitai bot commented Aug 21, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Changes adjust semantic event handling so identifier bindings in type-only positions are recorded as Type bindings and allow additional events to be emitted when popping scopes (removing an early continue). A new test (issue_6835.tsx) exercising a type-only namespace import is added. The quick-test harness is updated to configure JSX runtime and switch its diagnostic to correctness/noUnusedImports. A typo in an internal visitor type name in no_unused_imports.rs was corrected (rename only). No public API changes in core crates are present in the provided diffs.

Assessment against linked issues

Objective Addressed Explanation
Fix false positive: noUnusedImports with import * as name used only in type positions (#6835)

Assessment — Out-of-scope changes

Code Change Explanation
Rename of internal visitor type (JsDocTypeCollectorVisitior → JsDocTypeCollectorVisitor) (crates/biome_js_analyze/src/lint/correctness/no_unused_imports.rs) Typo-only rename unrelated to the issue objective (behaviour unchanged).
Test harness API additions/configuration changes: introducing AnalyzerConfiguration/JsxRuntime and using AnalyzerOptions::with_configuration (crates/biome_js_analyze/tests/quick_test.rs and related biome_analyze API surface) Expands test configuration surface and public test-API usage not required to address the noUnusedImports false-positive; appears to be test infra/option changes rather than the core fix.

Possibly related PRs

Suggested labels

A-Core, A-Diagnostic

Suggested reviewers

  • Conaclos
  • arendjr
  • dyc3

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

Configuration used: .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.

📥 Commits

Reviewing files that changed from the base of the PR and between f05fe4d and 3a4017d.

⛔ Files ignored due to path filters (1)
  • crates/biome_js_analyze/tests/specs/correctness/noUnusedImports/valid-import-namespace.ts.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (1)
  • crates/biome_js_analyze/tests/specs/correctness/noUnusedImports/valid-import-namespace.ts (1 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/semantic-model-reference

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@ematipico ematipico requested review from a team August 21, 2025 10:02
@github-actions github-actions bot added A-Linter Area: linter L-JavaScript Language: JavaScript and super languages labels Aug 21, 2025
Copy link
Contributor

Parser conformance results on

js/262

Test result main count This PR count Difference
Total 50631 50631 0
Passed 49361 49361 0
Failed 1270 1270 0
Panics 0 0 0
Coverage 97.49% 97.49% 0.00%

jsx/babel

Test result main count This PR count Difference
Total 40 40 0
Passed 37 37 0
Failed 3 3 0
Panics 0 0 0
Coverage 92.50% 92.50% 0.00%

symbols/microsoft

Test result main count This PR count Difference
Total 6706 6706 0
Passed 2245 2245 0
Failed 4461 4461 0
Panics 0 0 0
Coverage 33.48% 33.48% 0.00%

ts/babel

Test result main count This PR count Difference
Total 825 825 0
Passed 732 732 0
Failed 93 93 0
Panics 0 0 0
Coverage 88.73% 88.73% 0.00%

ts/microsoft

Test result main count This PR count Difference
Total 18786 18786 0
Passed 14413 14413 0
Failed 4373 4373 0
Panics 0 0 0
Coverage 76.72% 76.72% 0.00%

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

🧹 Nitpick comments (2)
crates/biome_js_analyze/tests/specs/correctness/noUnusedImports/issue_6835.tsx (1)

1-7: Consider mirroring the original repro more closely (qualified type use).

The issue used a qualified reference (e.g. Parameters<ns.Member>[0]). Using the bare namespace as a type argument is atypical in TS and may not reflect real-world usage. Recommend adding a qualified member case to ensure the semantic events also cover ns.Member in type position.

Would you like me to add an extra assertion-only test that references a qualified name (e.g. type T = Parameters<postcssModules.SomeFn>[0] or type U = postcssModules.SomeType) so we exercise both forms?

crates/biome_js_analyze/tests/quick_test.rs (1)

32-39: Tiny consistency nit: use .tsx extension to match JsFileSource::tsx().

You parse as TSX; make the filename extension match for fewer head-scratches later.

-    const FILENAME: &str = "dummyFile.ts";
+    const FILENAME: &str = "dummyFile.tsx";
📜 Review details

Configuration used: .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.

📥 Commits

Reviewing files that changed from the base of the PR and between 6436180 and f05fe4d.

⛔ Files ignored due to path filters (2)
  • crates/biome_js_analyze/tests/specs/correctness/noUnusedImports/invalid-import-namespace.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/correctness/noUnusedImports/issue_6835.tsx.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (4)
  • crates/biome_js_analyze/src/lint/correctness/no_unused_imports.rs (2 hunks)
  • crates/biome_js_analyze/tests/quick_test.rs (3 hunks)
  • crates/biome_js_analyze/tests/specs/correctness/noUnusedImports/issue_6835.tsx (1 hunks)
  • crates/biome_js_semantic/src/events.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{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/correctness/no_unused_imports.rs
  • crates/biome_js_analyze/tests/quick_test.rs
  • crates/biome_js_semantic/src/events.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/correctness/no_unused_imports.rs
  • crates/biome_js_analyze/tests/specs/correctness/noUnusedImports/issue_6835.tsx
  • crates/biome_js_analyze/tests/quick_test.rs
  • crates/biome_js_semantic/src/events.rs
crates/biome_*/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place core crates under /crates/biome_*/

Files:

  • crates/biome_js_analyze/src/lint/correctness/no_unused_imports.rs
  • crates/biome_js_analyze/tests/specs/correctness/noUnusedImports/issue_6835.tsx
  • crates/biome_js_analyze/tests/quick_test.rs
  • crates/biome_js_semantic/src/events.rs
**/tests/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files under a tests/ directory in each crate

Files:

  • crates/biome_js_analyze/tests/specs/correctness/noUnusedImports/issue_6835.tsx
  • crates/biome_js_analyze/tests/quick_test.rs
🧠 Learnings (6)
📓 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 : 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
📚 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/biome_module_graph/src/js_module_info/collector.rs : Thin (module-level) inference may resolve qualifiers to local declarations or globals (TypeReference::Resolved), mark imported bindings as TypeReference::Import, and set unresolved to TypeReference::Unknown; it must not look beyond the current module

Applied to files:

  • crates/biome_js_analyze/src/lint/correctness/no_unused_imports.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/tests/quick_test.rs : Use `biome_js_analyze/tests/quick_test.rs` for quick, ad-hoc testing; un-ignore the test and adjust the rule filter as needed

Applied to files:

  • crates/biome_js_analyze/tests/quick_test.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_rule_options/lib/**/*.rs : Define per-rule options in the `biome_rule_options` crate under `lib/`, with serde- and schemars-compatible derives and `#[serde(rename_all = "camelCase", deny_unknown_fields, default)]`

Applied to files:

  • crates/biome_js_analyze/tests/quick_test.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/tests/quick_test.rs
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/tests/spec_test.rs : Create tests/spec_test.rs implementing the run(spec_input_file, _expected_file, test_directory, _file_type) function as shown and include!("language.rs")

Applied to files:

  • crates/biome_js_analyze/tests/quick_test.rs
⏰ 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). (26)
  • GitHub Check: Bench (biome_css_analyze)
  • GitHub Check: Bench (biome_graphql_parser)
  • GitHub Check: Bench (biome_graphql_formatter)
  • GitHub Check: Bench (biome_package)
  • GitHub Check: Bench (biome_html_formatter)
  • GitHub Check: Bench (biome_json_analyze)
  • GitHub Check: Bench (biome_configuration)
  • GitHub Check: Bench (biome_module_graph)
  • GitHub Check: Bench (biome_html_parser)
  • GitHub Check: Bench (biome_css_formatter)
  • GitHub Check: Documentation
  • GitHub Check: Bench (biome_json_parser)
  • GitHub Check: Bench (biome_json_formatter)
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_css_parser)
  • GitHub Check: End-to-end tests
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Test Node.js API
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Check Dependencies
  • GitHub Check: Parser conformance
  • GitHub Check: autofix
🔇 Additional comments (5)
crates/biome_js_analyze/src/lint/correctness/no_unused_imports.rs (3)

129-131: Typo fix looks good — consistent rename to Visitor.

The struct name correction to JsDocTypeCollectorVisitor is tidy and improves clarity.


137-157: Impl matches the rename; no behavioural change.

Consistent with the struct rename; finish hook still wires JsDocTypeModel into services as before.


245-252: Visitor wiring order is sensible.

Adding JsDocTypeCollectorVisitor in the Syntax phase after SemanticModelBuilderVisitor keeps JSDoc harvesting cheap and independent. No objections.

crates/biome_js_semantic/src/events.rs (1)

646-655: Verification of double-report risk for extra Read + UnresolvedReference events

I ran your grep across all lint rules in crates/biome_js_analyze/src/lint and found these that consume all_references or match on UnresolvedReference:

  • correctness/no_unused_imports.rs
  • correctness/no_unused_variables.rs
  • correctness/no_unused_function_parameters.rs
  • complexity/no_useless_this_alias.rs
  • correctness/no_react_prop_assignments.rs
  • correctness/no_unused_private_class_members.rs
  • correctness/no_invalid_use_before_declaration.rs
  • style/use_for_of.rs
  • style/use_import_type.rs
  • style/use_const.rs
  • style/no_shouty_constants.rs

Quick take:

  • no_unused_imports only does binding.all_references(model).next().is_none(), so it won’t double-report (it merely checks for any reference)
  • The other rules apply filters (.is_read(), AST parent checks, .count() > 1, .is_only_type(), range comparisons, etc.), which should either ignore UnresolvedReference or collapse multiple events

However, given the variety of filters, I recommend a quick manual check in each rule to ensure they:

  1. Don’t inadvertently count both the HoistedRead and the UnresolvedReference as separate usages
  2. Properly filter out type-only UnresolvedReference events when irrelevant

Also, the inline nitpick comment you suggested can be applied verbatim:

                     if type_token.is_none() {
                         self.push_binding(None, BindingName::Value(name.clone()), info.clone());
+                        // Also record a Type binding so type-only references to the namespace
+                        // (e.g. in `Parameters<ns>` or `ns.Member`) count as usages for lints
+                        // like `noUnusedImports`. `pop_scope` still emits an UnresolvedReference
+                        // for `ns`-as-type to preserve other diagnostics.
                         self.push_binding(None, BindingName::Type(name.clone()), info.clone());

Let me know if you’d like me to deep-dive into any specific rule!

crates/biome_js_analyze/tests/quick_test.rs (1)

50-56: JSX runtime configuration: good call.

Configuring ReactClassic here is appropriate and keeps this quick test aligned with runtime-sensitive rules.

Copy link
Member

@Conaclos Conaclos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Just invalid-import-namespace to rename valid-import-namespace.

Copy link

codspeed-hq bot commented Aug 21, 2025

CodSpeed Performance Report

Merging #7282 will not alter performance

Comparing fix/semantic-model-reference (3a4017d) with main (1316ae7)1

Summary

✅ 132 untouched benchmarks

Footnotes

  1. No successful run was found on main (6436180) during the generation of this report, so 1316ae7 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@ematipico ematipico merged commit 1316ae7 into main Aug 21, 2025
28 of 29 checks passed
@ematipico ematipico deleted the fix/semantic-model-reference branch August 21, 2025 11:34
@flying-sheep
Copy link

Thank you very much!

ematipico added a commit that referenced this pull request Aug 26, 2025
SkyBird233 pushed a commit to SkyBird233/biomejs that referenced this pull request Aug 28, 2025
SkyBird233 pushed a commit to SkyBird233/biomejs that referenced this pull request Aug 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Linter Area: linter L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

💅 False positive for noUnusedImports when using import * as name in a type-only position

3 participants