Skip to content

feat(js/lint): implement rule useDisposables#8651

Merged
ematipico merged 6 commits into
biomejs:mainfrom
siketyan:feat/use-disposables
Apr 6, 2026
Merged

feat(js/lint): implement rule useDisposables#8651
ematipico merged 6 commits into
biomejs:mainfrom
siketyan:feat/use-disposables

Conversation

@siketyan

@siketyan siketyan commented Jan 2, 2026

Copy link
Copy Markdown
Member

Summary

Closes #8421

Add a new rule that detects an assigned disposable object which is never disposed later (using using syntax). The rule reports an error even if the object is disposed using normal [Symbol.dispose]() call for consistency. If the code is not targeted to the modern environment, the rule should be disabled. This can be improved with an option later.

This rule is powered by our type inference engine, so it will be in the Project domain.

Test Plan

Added some snapshot tests.

Docs

Rule description is written in the rustdoc as usual.

@siketyan siketyan self-assigned this Jan 2, 2026
@changeset-bot

changeset-bot Bot commented Jan 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: ce1fa34

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 13 packages
Name Type
@biomejs/biome Patch
@biomejs/cli-win32-x64 Patch
@biomejs/cli-win32-arm64 Patch
@biomejs/cli-darwin-x64 Patch
@biomejs/cli-darwin-arm64 Patch
@biomejs/cli-linux-x64 Patch
@biomejs/cli-linux-arm64 Patch
@biomejs/cli-linux-x64-musl Patch
@biomejs/cli-linux-arm64-musl Patch
@biomejs/wasm-web Patch
@biomejs/wasm-bundler Patch
@biomejs/wasm-nodejs Patch
@biomejs/backend-jsonrpc Patch

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

@github-actions github-actions Bot added A-Project Area: project A-Linter Area: linter L-JavaScript Language: JavaScript and super languages A-Diagnostic Area: diagnostocis A-Type-Inference Area: type inference labels Jan 2, 2026
@siketyan siketyan force-pushed the feat/use-disposables branch from 0f08994 to fa5b09b Compare January 2, 2026 11:54
@codspeed-hq

codspeed-hq Bot commented Jan 2, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 58 untouched benchmarks
⏩ 196 skipped benchmarks1


Comparing siketyan:feat/use-disposables (ce1fa34) with main (49f00a3)

Open in CodSpeed

Footnotes

  1. 196 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@siketyan siketyan force-pushed the feat/use-disposables branch 3 times, most recently from 336aa5d to a23a47e Compare January 2, 2026 12:17
@siketyan siketyan marked this pull request as ready for review January 2, 2026 12:24
@siketyan siketyan requested review from a team January 2, 2026 12:26
@coderabbitai

coderabbitai Bot commented Jan 2, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 403de880-a453-4ec5-9af7-0dbe2d9619b9

📥 Commits

Reviewing files that changed from the base of the PR and between 9dbfa51 and ce1fa34.

📒 Files selected for processing (1)
  • .changeset/fast-glasses-ask.md

Walkthrough

Adds a new JS/TS lint rule useDisposables that detects assignments of values implementing Disposable or AsyncDisposable when not declared with using/await using, and supplies automatic fixes. Introduces global symbol and disposable TypeIds and resolver entries, adds type-query helpers (is_disposable, is_async_disposable) and qualifier checks, updates class-member name handling to support computed names, exposes UseDisposablesOptions, and adds matching valid/invalid tests and a changeset entry.

Possibly related PRs

Suggested reviewers

  • dyc3
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: implementing a new JavaScript lint rule named useDisposables.
Description check ✅ Passed The description is directly related to the changeset, explaining the rule's purpose, domain, and testing approach.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
.changeset/fast-glasses-ask.md (1)

5-5: Polish the rule description sentence

Tiny grammar tweak to make the description read more naturally:

Disposable objects, which implement Disposable or AsyncDisposable interfaces, are intended to be disposed after use. Not disposing them can lead to resource or memory leaks, depending on the implementation.

Feel free to adjust the wording, but fixing the verb agreement and missing preposition would be nice.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5b4bdbf and a23a47e.

⛔ Files ignored due to path filters (13)
  • crates/biome_configuration/src/analyzer/linter/rules.rs is excluded by !**/rules.rs and included by **
  • crates/biome_configuration/src/generated/domain_selector.rs is excluded by !**/generated/**, !**/generated/** and included by **
  • crates/biome_diagnostics_categories/src/categories.rs is excluded by !**/categories.rs and included by **
  • crates/biome_js_analyze/src/lint/nursery.rs is excluded by !**/nursery.rs and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useDisposables/invalid.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useDisposables/valid.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_type_info/tests/snapshots/infer_resolved_type_of_async_disposable_object.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_type_info/tests/snapshots/infer_resolved_type_of_async_disposable_returning_function.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_type_info/tests/snapshots/infer_resolved_type_of_disposable_object.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_type_info/tests/snapshots/infer_resolved_type_of_disposable_returning_function.snap is excluded by !**/*.snap and included by **
  • crates/biome_unicode_table/src/tables.rs is excluded by !**/biome_unicode_table/src/tables.rs and included by **
  • packages/@biomejs/backend-jsonrpc/src/workspace.ts is excluded by !**/backend-jsonrpc/src/workspace.ts and included by **
  • packages/@biomejs/biome/configuration_schema.json is excluded by !**/configuration_schema.json and included by **
📒 Files selected for processing (12)
  • .changeset/fast-glasses-ask.md
  • crates/biome_js_analyze/src/lint/nursery/use_disposables.rs
  • crates/biome_js_analyze/tests/specs/nursery/useDisposables/invalid.ts
  • crates/biome_js_analyze/tests/specs/nursery/useDisposables/valid.ts
  • crates/biome_js_type_info/src/globals.rs
  • crates/biome_js_type_info/src/globals_ids.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/tests/resolver.rs
  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_disposables.rs
🧰 Additional context used
📓 Path-based instructions (3)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.rs: Use inline rustdoc documentation for rules, assists, and their options
Use the dbg!() macro for debugging output in Rust tests and code
Use doc tests (doctest) format with code blocks in rustdoc comments; ensure assertions pass in tests

Files:

  • crates/biome_rule_options/src/lib.rs
  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_analyze/src/lint/nursery/use_disposables.rs
  • crates/biome_rule_options/src/use_disposables.rs
  • crates/biome_js_type_info/tests/resolver.rs
  • crates/biome_js_type_info/src/globals_ids.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/globals.rs
crates/biome_js_type_info/**/*.rs

📄 CodeRabbit inference engine (crates/biome_js_type_info/CONTRIBUTING.md)

crates/biome_js_type_info/**/*.rs: No module may copy or clone data from another module in the module graph, not even behind an Arc
Use TypeReference instead of Arc for types that reference other types to avoid stale cache issues when modules are replaced
Store type data in linear vectors instead of using recursive data structures with Arc for improved data locality and performance
Use TypeReference variants (Qualifier, Resolved, Import, Unknown) to represent different phases of type resolution
Use TypeData::Unknown to indicate when type inference falls short or is not implemented
Distinguish between TypeData::Unknown and TypeData::UnknownKeyword to measure inference effectiveness versus explicit user-provided unknown types
When using ResolvedTypeData, track the ResolverId to ensure subsequent resolver calls use the correct context
Always apply the correct ResolverId when retrieving raw type data from ResolvedTypeData.as_raw_data() to prevent panics during subsequent resolution calls

Files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_type_info/tests/resolver.rs
  • crates/biome_js_type_info/src/globals_ids.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/globals.rs
crates/biome_js_type_info/**/local_inference.rs

📄 CodeRabbit inference engine (crates/biome_js_type_info/CONTRIBUTING.md)

Implement local inference in dedicated modules to derive type definitions from expressions without context of surrounding scopes

Files:

  • crates/biome_js_type_info/src/local_inference.rs
🧠 Learnings (42)
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/lib/**/*.rs : Wrap rule options fields in `Option<>` to properly track set and unset options during merge

Applied to files:

  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_disposables.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/lib/**/*.rs : Rule options must be placed inside the `biome_rule_options` crate

Applied to files:

  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_disposables.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/lib/**/*.rs : Use `deny_unknown_fields` in serde derive macro for rule options

Applied to files:

  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_disposables.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/lib/**/*.rs : Use `Box<[T]>` instead of `Vec<T>` for rule options arrays to save memory

Applied to files:

  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_disposables.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/lib/**/*.rs : Implement `Merge` trait for rule options to support configuration inheritance

Applied to files:

  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_disposables.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/lib/**/*.rs : Use `rename_all = "camelCase"` in serde derive macro for rule options

Applied to files:

  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_disposables.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Add `deprecated` field to `declare_lint_rule!` macro when deprecating a rule

Applied to files:

  • crates/biome_rule_options/src/lib.rs
  • crates/biome_js_analyze/src/lint/nursery/use_disposables.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/biome_rule_options/lib/**/*.rs : Rule options struct must derive `Deserializable`, `Serialize`, `Deserialize`, and optionally `JsonSchema`

Applied to files:

  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_disposables.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `options` code block property for rule-specific configuration snippets in documentation

Applied to files:

  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_disposables.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Rule documentation must include `## Options` section if the rule has options

Applied to files:

  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_disposables.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : Use `TypeReference` variants (`Qualifier`, `Resolved`, `Import`, `Unknown`) to represent different phases of type resolution

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_type_info/tests/resolver.rs
  • crates/biome_js_type_info/src/globals_ids.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/globals.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : Use `TypeReference` instead of `Arc` for types that reference other types to avoid stale cache issues when modules are replaced

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_type_info/src/globals_ids.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/globals.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/js_module_info/collector.rs : Implement module-level (thin) inference to resolve `TypeReference::Qualifier` variants by looking up declarations in module scopes and handling import statements

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/globals.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : Distinguish between `TypeData::Unknown` and `TypeData::UnknownKeyword` to measure inference effectiveness versus explicit user-provided unknown types

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_type_info/src/globals_ids.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/globals.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : Use `TypeData::Unknown` to indicate when type inference falls short or is not implemented

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_type_info/src/globals_ids.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/globals.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : Always apply the correct `ResolverId` when retrieving raw type data from `ResolvedTypeData.as_raw_data()` to prevent panics during subsequent resolution calls

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_type_info/tests/resolver.rs
  • crates/biome_js_type_info/src/globals_ids.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/globals.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : When using `ResolvedTypeData`, track the `ResolverId` to ensure subsequent resolver calls use the correct context

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_type_info/tests/resolver.rs
  • crates/biome_js_type_info/src/globals_ids.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/globals.rs
📚 Learning: 2025-08-20T16:24:59.781Z
Learnt from: arendjr
Repo: biomejs/biome PR: 7266
File: crates/biome_js_type_info/src/type.rs:94-102
Timestamp: 2025-08-20T16:24:59.781Z
Learning: In crates/biome_js_type_info/src/type.rs, the flattened_union_variants() method returns TypeReference instances that already have the correct module IDs applied to them. These references should be used directly with resolver.resolve_reference() without applying additional module ID transformations, as variant references may originate from nested unions in different modules.

Applied to files:

  • crates/biome_js_type_info/src/type_data.rs
  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_type_info/src/globals_ids.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/globals.rs
📚 Learning: 2025-09-09T18:10:05.095Z
Learnt from: arendjr
Repo: biomejs/biome PR: 6710
File: crates/biome_js_type_info/src/helpers.rs:102-124
Timestamp: 2025-09-09T18:10:05.095Z
Learning: Global constants like GLOBAL_ARRAY_ID are stored by the global resolver and should never have module IDs applied to them. Module IDs only apply to module resolvers, not global resolvers. When working with global type constants, use them directly without module ID transformations.

Applied to files:

  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_type_info/src/globals_ids.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/scoped_resolver.rs : Implement full inference to resolve `TypeReference::Import` variants across the entire module graph

Applied to files:

  • crates/biome_js_type_info/src/type.rs
  • crates/biome_js_type_info/tests/resolver.rs
  • crates/biome_js_type_info/src/globals_ids.rs
  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/globals.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : Place new rules inside the `nursery` group during development

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_disposables.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set `version` field to `next` in `declare_lint_rule!` macro

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_disposables.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `declare_lint_rule!` macro to declare analyzer rule types and implement the RuleMeta trait

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_disposables.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Specify `fix_kind: FixKind::Safe` in `declare_lint_rule!` for safe code actions

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_disposables.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Specify `fix_kind: FixKind::Unsafe` in `declare_lint_rule!` for unsafe code actions

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_disposables.rs
📚 Learning: 2025-12-22T09:26:56.943Z
Learnt from: ematipico
Repo: biomejs/biome PR: 8537
File: crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs:167-210
Timestamp: 2025-12-22T09:26:56.943Z
Learning: When defining lint rules (declare_lint_rule!), only specify fix_kind if the rule implements an action(...) function. Rules that only emit diagnostics without a code fix should omit fix_kind. This applies to all Rust lint rule definitions under crates/.../src/lint (e.g., crates/biome_js_analyze/src/lint/...).

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_disposables.rs
📚 Learning: 2025-12-31T15:35:32.899Z
Learnt from: dyc3
Repo: biomejs/biome PR: 8639
File: crates/biome_js_analyze/src/lint/nursery/no_excessive_lines_per_file.rs:101-108
Timestamp: 2025-12-31T15:35:32.899Z
Learning: In Rust lint rules under the nursery category, the issue_number field in declare_lint_rule! is optional and should not be added unless there is a compelling reason. In code reviews, verify that no unnecessary issue_number is included in nursery lint declarations. Only add issue_number if there is an explicit, justified reason (e.g., tracked issue for external observers). This guidance broadly applies to all nursery lint rule files, not just the single file.

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_disposables.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Lint rules should perform static analysis of source code to detect invalid or error-prone patterns and emit diagnostics with proposed fixes

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_disposables.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `domains` field in `declare_lint_rule!` to tag rules that belong to specific concepts like testing or frameworks

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_disposables.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `RuleSource::Eslint(...).same()` when implementing a rule that matches the behavior of an ESLint rule

Applied to files:

  • crates/biome_js_analyze/src/lint/nursery/use_disposables.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `use_options` code block property for code examples that follow an options configuration in documentation

Applied to files:

  • crates/biome_rule_options/src/use_disposables.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Check if a variable is global using the semantic model to avoid false positives

Applied to files:

  • crates/biome_js_type_info/src/globals_ids.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/*.rs : Store type data in linear vectors instead of using recursive data structures with `Arc` for improved data locality and performance

Applied to files:

  • crates/biome_js_type_info/src/globals_ids.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/local_inference.rs : Implement local inference in dedicated modules to derive type definitions from expressions without context of surrounding scopes

Applied to files:

  • crates/biome_js_type_info/src/local_inference.rs
📚 Learning: 2025-11-24T18:05:27.810Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:27.810Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Import the `FormatNode` trait and implement it for your Node when creating formatters in biome_js_formatter

Applied to files:

  • crates/biome_js_type_info/src/local_inference.rs
📚 Learning: 2025-11-24T18:05:42.356Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:42.356Z
Learning: Applies to crates/biome_js_type_info/**/flattening.rs : Implement type flattening to simplify `TypeofExpression` variants once all component types are resolved

Applied to files:

  • crates/biome_js_type_info/src/local_inference.rs
  • crates/biome_js_type_info/src/globals.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Set `language` to `jsx`, `ts`, or `tsx` for rules that only apply to specific JavaScript dialects

Applied to files:

  • crates/biome_js_type_info/src/local_inference.rs
📚 Learning: 2025-11-24T18:05:27.810Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:27.810Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : When formatting AST nodes, use mandatory tokens from the AST instead of hardcoding token strings (e.g., use `node.l_paren_token().format()` instead of `token("(")`)

Applied to files:

  • crates/biome_js_type_info/src/local_inference.rs
📚 Learning: 2025-11-24T18:06:03.545Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:06:03.545Z
Learning: Applies to crates/biome_parser/**/src/**/*.rs : Use `ConditionalParsedSyntax` for syntax that is only valid in specific contexts (e.g., strict mode, file types, language versions) and call `or_invalid_to_bogus()` to convert to a bogus node if not supported

Applied to files:

  • crates/biome_js_type_info/src/local_inference.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/**/*.rs : Use `Semantic<>` query type to access semantic model information like scopes and declarations

Applied to files:

  • crates/biome_js_type_info/src/globals.rs
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/tests/specs/**/*valid* : Create test files prefixed with `valid` for code that should not trigger the rule

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/useDisposables/valid.ts
  • crates/biome_js_analyze/tests/specs/nursery/useDisposables/invalid.ts
📚 Learning: 2025-12-19T12:53:30.413Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-12-19T12:53:30.413Z
Learning: Applies to crates/biome_analyze/**/*analyze/tests/specs/**/*invalid* : Create test files prefixed with `invalid` for code that should trigger the rule

Applied to files:

  • crates/biome_js_analyze/tests/specs/nursery/useDisposables/invalid.ts
🧬 Code graph analysis (5)
crates/biome_js_type_info/src/type_data.rs (1)
crates/biome_js_type_info/src/type.rs (2)
  • is_disposable (252-266)
  • is_async_disposable (268-282)
crates/biome_js_type_info/src/type.rs (1)
crates/biome_js_type_info/src/type_data.rs (3)
  • is_disposable (1455-1457)
  • ty (566-571)
  • is_async_disposable (1466-1468)
crates/biome_js_analyze/src/lint/nursery/use_disposables.rs (3)
crates/biome_service/src/workspace.rs (1)
  • markup (1195-1197)
crates/biome_analyze/src/rule.rs (2)
  • recommended (619-622)
  • domains (649-652)
crates/biome_js_factory/src/make.rs (1)
  • token_with_trailing_space (116-122)
crates/biome_js_type_info/src/local_inference.rs (3)
crates/biome_js_type_info/src/type_data.rs (5)
  • name (972-974)
  • name (1020-1026)
  • ty (566-571)
  • is_static (968-970)
  • is_static (1016-1018)
crates/biome_js_type_info/src/resolver.rs (5)
  • name (503-505)
  • ty (522-524)
  • is_static (493-495)
  • kind (498-500)
  • id (72-74)
crates/biome_js_type_info/src/type.rs (1)
  • id (76-78)
crates/biome_js_type_info/src/globals.rs (3)
crates/biome_js_type_info/src/type_data.rs (22)
  • name (972-974)
  • name (1020-1026)
  • new (40-44)
  • new (1490-1494)
  • new (1525-1535)
  • instance_of (296-298)
  • from (175-177)
  • from (181-183)
  • from (187-189)
  • from (193-195)
  • from (199-201)
  • from (205-207)
  • from (211-213)
  • from (217-219)
  • from (223-225)
  • from (229-231)
  • from (235-237)
  • from (241-243)
  • default (169-171)
  • default (555-562)
  • default (831-833)
  • default (1245-1247)
crates/biome_js_type_info/src/resolver.rs (8)
  • name (503-505)
  • id (72-74)
  • new (55-57)
  • new (294-299)
  • from (326-328)
  • from (333-335)
  • from (405-410)
  • from (415-420)
crates/biome_js_type_info/src/type.rs (2)
  • id (76-78)
  • default (50-55)
🪛 LanguageTool
.changeset/fast-glasses-ask.md

[uncategorized] ~5-~5: Possible missing preposition found.
Context: ... after use. Not disposing them can lead some resource or memory leak depending on th...

(AI_HYDRA_LEO_MISSING_TO)


[uncategorized] ~5-~5: Possible missing comma found.
Context: ...g them can lead some resource or memory leak depending on the implementation. **Inv...

(AI_HYDRA_LEO_MISSING_COMMA)

⏰ 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). (6)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Test Node.js API
  • GitHub Check: Bench (biome_js_parser)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_formatter)
🔇 Additional comments (13)
crates/biome_rule_options/src/lib.rs (1)

303-303: New use_disposables module export looks spot on

The module is wired in alongside the other use_* rules in alphabetical order and exposes the options from the right crate; no further action needed.

crates/biome_rule_options/src/use_disposables.rs (1)

1-6: UseDisposablesOptions follows the rule-options conventions

Derives, serde attributes, and placement in biome_rule_options all match the documented pattern; an empty struct is a good starting point until the rule grows real options.

crates/biome_js_type_info/src/globals.rs (1)

95-102: Symbol/Disposable globals and qualifier wiring look consistent

The new global IDs, helper closures (member/static_member), Array/Promise/RegExp member updates, and the extra qualifier branches for Symbol, Disposable, and AsyncDisposable all mirror the existing patterns for Array/Promise/RegExp nicely. I don’t see any issues in how these are hooked up.

Also applies to: 118-124, 196-198, 251-260, 404-405, 569-574

crates/biome_js_type_info/src/local_inference.rs (1)

1813-1833: Computed-name handling for class/object members looks solid

The refactor to route Js/TS class members and object members through from_class_member_info, plus the new IndexSignature modelling for computed [expr] names, keeps static/optional handling consistent and gives you exactly the shape you need for [Symbol.dispose]/[Symbol.asyncDispose] detection. The use of TypeReference::from_any_js_expression for the key type aligns with the rest of local inference. No issues spotted here.

Also applies to: 1865-1895, 1919-1939, 1941-1965, 2002-2068, 2234-2267

crates/biome_js_analyze/tests/specs/nursery/useDisposables/valid.ts (1)

1-48: Nice spread of non-diagnostic disposable patterns

These cases cover inline objects, factory functions, and classes for both Disposable and AsyncDisposable, all used with using / await using. That’s a solid baseline for “no diagnostics” coverage for the new rule.

crates/biome_js_type_info/src/type_data.rs (1)

1437-1468: New qualifier helpers for Symbol/Disposable align with existing ones

is_symbol, is_disposable, and is_async_disposable mirror the existing is_array/is_promise/is_regex helpers and give GlobalsResolver::resolve_qualifier a straightforward way to recognise these built-ins. Looks correct and in line with the type-info guidelines.

crates/biome_js_analyze/tests/specs/nursery/useDisposables/invalid.ts (1)

1-48: Solid test coverage for invalid disposable patterns.

The test cases comprehensively cover object literals, factory functions, and class implementations for both Disposable and AsyncDisposable. All cases correctly omit the using/await using syntax, ensuring they trigger the diagnostic. Based on learnings, this aligns with the convention of prefixing invalid test files appropriately.

crates/biome_js_type_info/tests/resolver.rs (1)

214-304: Well-structured tests for disposable type resolution.

The new tests follow the established patterns in this file: parse TypeScript code, obtain declarations, create a GlobalsResolver, derive TypeData, and snapshot the results. The coverage for both object literals with Symbol.dispose/Symbol.asyncDispose and functions returning Disposable/AsyncDisposable is appropriate.

crates/biome_js_type_info/src/type.rs (1)

252-282: Clean implementation of disposable type detection.

The two-stage check (fast path via ID comparison, then member lookup for index signatures) is sensible. The use of global IDs directly without module ID transformations aligns with the learnings for global type constants.

One observation: TypeReferenceQualifier in type_data.rs also has is_disposable() and is_async_disposable() methods that check by identifier name. These are complementary — qualifiers check unresolved names whilst this implementation checks resolved types.

crates/biome_js_analyze/src/lint/nursery/use_disposables.rs (2)

97-104: Consider order of disposable checks.

If a type implements both Disposable and AsyncDisposable, the current logic (checking is_disposable() first) would suggest using using rather than await using. This is fine if the intention is to prefer synchronous disposal when available, but it's worth confirming this is the desired behaviour.


159-162: Enum visibility is appropriate.

The DisposableKind enum being pub follows the pattern used by other lint rules for their state types. Since it's only used as internal rule state and not in configuration, no derives are needed.

crates/biome_js_type_info/src/globals_ids.rs (2)

73-88: Type IDs are correctly sequential and count is updated.

The eight new IDs (44-51) continue correctly from the previous highest ID. NUM_PREDEFINED_TYPES = 52 accurately reflects the total count (indices 0-51).


129-136: Some TypeIds lack corresponding GLOBAL_ constants.*

INSTANCEOF_SYMBOL_ID, DISPOSABLE_DISPOSE_ID, and ASYNC_DISPOSABLE_ASYNC_DISPOSE_ID are defined but have no corresponding GLOBAL_* resolved IDs. If these are only used internally for member lookups and not for external type comparisons, this is fine. Otherwise, you may need to add them.

Comment thread crates/biome_js_type_info/src/globals.rs
@siketyan siketyan requested a review from dyc3 January 2, 2026 15:54
@ematipico

Copy link
Copy Markdown
Member

I just merged #8564 into next, so I wonder if we could merge this PR into next too and use the new domain

@ematipico ematipico force-pushed the feat/use-disposables branch from c0bac4f to e13e80b Compare April 6, 2026 16:52

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.changeset/fast-glasses-ask.md:
- Line 5: Polish the copy on the changeset line describing the new lint rule
`useDisposables`: correct grammar and clarity by changing “implements
`Disposable` or `AsyncDisposable` interface” to “implements the `Disposable` or
`AsyncDisposable` interface”, change “dispose after use” to “be disposed of
after use”, and add the missing “to” in “lead to” so the sentence reads
something like: “Disposable objects, which implement the `Disposable` or
`AsyncDisposable` interface, are intended to be disposed of after use; not
disposing them can lead to resource or memory leaks depending on the
implementation.” Update the `.changeset/fast-glasses-ask.md` text accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0fe641f6-bdac-488e-8b58-3857b3def719

📥 Commits

Reviewing files that changed from the base of the PR and between a64e632 and e13e80b.

📒 Files selected for processing (1)
  • .changeset/fast-glasses-ask.md

Comment thread .changeset/fast-glasses-ask.md Outdated
autofix-ci Bot and others added 2 commits April 6, 2026 17:01
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@ematipico ematipico merged commit aafca2d into biomejs:main Apr 6, 2026
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Diagnostic Area: diagnostocis A-Linter Area: linter A-Project Area: project A-Type-Inference Area: type inference L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants