Skip to content

feat(lint/js): add useThisForClassMethods#9807

Open
dyc3 wants to merge 1 commit intomainfrom
dyc3/useThisForClassMethods
Open

feat(lint/js): add useThisForClassMethods#9807
dyc3 wants to merge 1 commit intomainfrom
dyc3/useThisForClassMethods

Conversation

@dyc3
Copy link
Copy Markdown
Contributor

@dyc3 dyc3 commented Apr 5, 2026

Summary

This PR adds useThisForClassMethods which is a port of https://eslint.org/docs/latest/rules/class-methods-use-this

I chose to implement these options because they're pretty trivial, and they are useful escape hatches.

Generated by gpt 5.4

Test Plan

snapshots

Docs

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 5, 2026

🦋 Changeset detected

Latest commit: 76e94e3

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

@dyc3 dyc3 force-pushed the dyc3/useThisForClassMethods branch from db3e74a to 0408706 Compare April 5, 2026 15:56
@github-actions github-actions Bot added A-CLI Area: CLI A-Project Area: project A-Linter Area: linter L-JavaScript Language: JavaScript and super languages A-Diagnostic Area: diagnostocis labels Apr 5, 2026
@dyc3 dyc3 force-pushed the dyc3/useThisForClassMethods branch from 0408706 to 3551362 Compare April 5, 2026 15:59
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 5, 2026

Merging this PR will not alter performance

✅ 59 untouched benchmarks
⏩ 195 skipped benchmarks1


Comparing dyc3/useThisForClassMethods (76e94e3) with main (3dce737)

Open in CodSpeed

Footnotes

  1. 195 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.

@dyc3 dyc3 force-pushed the dyc3/useThisForClassMethods branch from 1248d3a to 3e5b87d Compare April 5, 2026 16:36
@dyc3 dyc3 marked this pull request as ready for review April 5, 2026 19:37
@dyc3 dyc3 requested review from a team April 5, 2026 19:37
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 5, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 28f37e95-5e40-4e12-af55-c81ada361e25

📥 Commits

Reviewing files that changed from the base of the PR and between 3e5b87d and 76e94e3.

⛔ Files ignored due to path filters (4)
  • crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs is excluded by !**/migrate/eslint_any_rule_to_biome.rs and included by **
  • crates/biome_cli/tests/snapshots/main_commands_migrate_eslint/migrate_eslintrcjson_class_methods_use_this_options.snap is excluded by !**/*.snap and included by **
  • crates/biome_configuration/src/analyzer/linter/rules.rs is excluded by !**/rules.rs and included by **
  • crates/biome_configuration/src/generated/linter_options_check.rs is excluded by !**/generated/**, !**/generated/** and included by **
📒 Files selected for processing (5)
  • .changeset/rich-cases-cheat.md
  • .claude/skills/lint-rule-development/SKILL.md
  • crates/biome_cli/src/execute/migrate/eslint_eslint.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
  • crates/biome_cli/tests/commands/migrate_eslint.rs
✅ Files skipped from review due to trivial changes (3)
  • .claude/skills/lint-rule-development/SKILL.md
  • .changeset/rich-cases-cheat.md
  • crates/biome_cli/tests/commands/migrate_eslint.rs

Walkthrough

This pull request adds support for migrating ESLint's class-methods-use-this rule to Biome's new useThisInClassMethods nursery rule. Changes include a changeset entry, ESLint configuration deserialization logic with option mapping (exceptMethods, enforceForClassFields, ignoreOverrideMethods, ignoreClassesWithImplements), conversion from ESLint options to Biome options, migration logic to apply the rule under the nursery ruleset, test coverage with fixture files, and a module export in the rule options crate.

Possibly related PRs

  • biomejs/biome#9836 – Shares ESLint migration infrastructure modifications in crates/biome_cli and test updates for the migration pipeline.
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately describes the main change: adding a new linter rule useThisForClassMethods for JavaScript.
Description check ✅ Passed The description clearly explains the motivation (porting ESLint's class-methods-use-this rule), mentions implementation details, and includes appropriate test plan and AI disclosure.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dyc3/useThisForClassMethods

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

Copy link
Copy Markdown
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: 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 `@crates/biome_cli/src/execute/migrate/eslint_eslint.rs`:
- Around line 625-648: The code in
ClassMethodsUseThisOptions::into_biome_options currently ignores the
enforce_for_class_fields field (the let _ = self.enforce_for_class_fields;)
which silently tightens behaviour; update into_biome_options to handle
enforce_for_class_fields: if
biome_rule_options::use_this_for_class_methods::UseThisForClassMethodsOptions
supports an equivalent toggle, map self.enforce_for_class_fields into the
options (e.g., set a matching field or invert as needed), otherwise emit a
migration diagnostic/warning when enforce_for_class_fields is present (false) so
users are informed of the behavioural change; locate ClassMethodsUseThisOptions,
the enforce_for_class_fields field and the into_biome_options function and
either add mapping into
biome_rule_options::use_this_for_class_methods::UseThisForClassMethodsOptions or
add a diagnostic emission path when that field is Some(false).
🪄 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: 15b1a5b1-206b-480c-8dc5-2ae3b92c43d1

📥 Commits

Reviewing files that changed from the base of the PR and between 1d09f0f and 3e5b87d.

⛔ Files ignored due to path filters (17)
  • .opencode/package-lock.json is excluded by !**/package-lock.json and included by **
  • crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs is excluded by !**/migrate/eslint_any_rule_to_biome.rs and included by **
  • crates/biome_cli/tests/snapshots/main_commands_migrate_eslint/migrate_eslintrcjson_class_methods_use_this_options.snap is excluded by !**/*.snap and included by **
  • crates/biome_configuration/src/analyzer/linter/rules.rs is excluded by !**/rules.rs and included by **
  • crates/biome_configuration/src/generated/linter_options_check.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/tests/specs/nursery/useThisForClassMethods/invalid.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/invalid.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/invalidClassFields.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/invalidExceptMethods.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/invalidIgnoreClassesWithImplementsPublicFields.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/valid.js.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/validClassFields.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/validIgnoreClassesWithImplementsAll.ts.snap is excluded by !**/*.snap and included by **
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/validIgnoreOverrideMethods.ts.snap is excluded by !**/*.snap 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 (20)
  • .changeset/rich-cases-cheat.md
  • crates/biome_cli/src/execute/migrate/eslint_eslint.rs
  • crates/biome_cli/src/execute/migrate/eslint_to_biome.rs
  • crates/biome_cli/tests/commands/migrate_eslint.rs
  • crates/biome_js_analyze/src/lint/nursery/use_this_for_class_methods.rs
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/invalid.js
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/invalid.ts
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/invalidClassFields.ts
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/invalidExceptMethods.js
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/invalidExceptMethods.options.json
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/invalidIgnoreClassesWithImplementsPublicFields.options.json
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/invalidIgnoreClassesWithImplementsPublicFields.ts
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/valid.js
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/validClassFields.ts
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/validIgnoreClassesWithImplementsAll.options.json
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/validIgnoreClassesWithImplementsAll.ts
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/validIgnoreOverrideMethods.options.json
  • crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods/validIgnoreOverrideMethods.ts
  • crates/biome_rule_options/src/lib.rs
  • crates/biome_rule_options/src/use_this_for_class_methods.rs

Comment on lines +625 to +648
#[deserializable(rename = "enforceForClassFields")]
enforce_for_class_fields: Option<bool>,
#[deserializable(rename = "ignoreOverrideMethods")]
ignore_override_methods: Option<bool>,
#[deserializable(rename = "ignoreClassesWithImplements")]
ignore_classes_with_implements: Option<EslintIgnoreClassesWithImplements>,
}
impl ClassMethodsUseThisOptions {
pub(crate) fn into_biome_options(
self,
) -> Option<biome_rule_options::use_this_for_class_methods::UseThisForClassMethodsOptions> {
let options =
biome_rule_options::use_this_for_class_methods::UseThisForClassMethodsOptions {
except_methods: (!self.except_methods.is_empty()).then_some(self.except_methods),
ignore_override_methods: self.ignore_override_methods,
ignore_classes_with_implements: self.ignore_classes_with_implements.map(Into::into),
};

let _ = self.enforce_for_class_fields;

(options.except_methods.is_some()
|| options.ignore_override_methods.is_some()
|| options.ignore_classes_with_implements.is_some())
.then_some(options)
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.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

In ESLint's class-methods-use-thisrule, what doesenforceForClassFieldsdo, what is its default, and what behaviour changes when it is set tofalse?

💡 Result:

The enforceForClassFields option in ESLint's class-methods-use-this rule enforces that arrow functions and function expressions used as instance field initializers (class fields) utilize this. It also applies to auto-accessor fields declared with the accessor keyword. Its default value is true. When set to false, the rule does not check class fields for this usage, allowing functions in class field initializers that do not reference this without flagging them as violations. With the default true, such fields are flagged unless this is used.

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check where the option is parsed, dropped, or asserted in migration/tests.
rg -n -C3 '\benforceForClassFields\b|\benforce_for_class_fields\b|class-methods-use-this|useThisForClassMethods' \
  crates/biome_cli/src/execute/migrate \
  crates/biome_cli/tests \
  crates/biome_js_analyze/src/lint/nursery/use_this_for_class_methods.rs \
  crates/biome_js_analyze/tests/specs/nursery/useThisForClassMethods

# Check whether migration currently emits diagnostics/warnings for unsupported option semantics.
rg -n -C3 'unsupported|not supported|cannot migrate|warning|diagnostic' crates/biome_cli/src/execute/migrate

Repository: biomejs/biome

Length of output: 50371


Silently dropping enforceForClassFields changes rule behaviour.

When a user sets enforceForClassFields: false in ESLint (disabling class field checks), the migration discards this option without warning. Biome's useThisForClassMethods always checks class fields, so users unknowingly get stricter enforcement post-migration—behaviour tightening disguised as migration.

Line 643 silently discards the value. Consider either:

  • Emitting a diagnostic informing users of the behaviour change
  • Mapping the option (if Biome's rule supports runtime disabling)

Check whether Biome's rule can support a similar toggle.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/biome_cli/src/execute/migrate/eslint_eslint.rs` around lines 625 -
648, The code in ClassMethodsUseThisOptions::into_biome_options currently
ignores the enforce_for_class_fields field (the let _ =
self.enforce_for_class_fields;) which silently tightens behaviour; update
into_biome_options to handle enforce_for_class_fields: if
biome_rule_options::use_this_for_class_methods::UseThisForClassMethodsOptions
supports an equivalent toggle, map self.enforce_for_class_fields into the
options (e.g., set a matching field or invert as needed), otherwise emit a
migration diagnostic/warning when enforce_for_class_fields is present (false) so
users are informed of the behavioural change; locate ClassMethodsUseThisOptions,
the enforce_for_class_fields field and the into_biome_options function and
either add mapping into
biome_rule_options::use_this_for_class_methods::UseThisForClassMethodsOptions or
add a diagnostic emission path when that field is Some(false).

Copy link
Copy Markdown
Member

@ematipico ematipico left a comment

Choose a reason for hiding this comment

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

I am a bit biased against this rule (their semantics and name), let me know what you think about the suggestion I gave.

Apart from that, the docs need more work, and code can be improved.

Comment thread .changeset/rich-cases-cheat.md Outdated
Comment thread crates/biome_js_analyze/src/lint/nursery/use_this_for_class_methods.rs Outdated
Comment thread crates/biome_js_analyze/src/lint/nursery/use_this_for_class_methods.rs Outdated
Comment thread crates/biome_js_analyze/src/lint/nursery/use_this_for_class_methods.rs Outdated
Comment thread crates/biome_js_analyze/src/lint/nursery/use_this_for_class_methods.rs Outdated
Comment thread crates/biome_rule_options/src/use_this_for_class_methods.rs Outdated
Comment thread .opencode/package-lock.json Outdated
Comment thread crates/biome_js_analyze/src/lint/nursery/use_this_for_class_methods.rs Outdated
@dyc3 dyc3 force-pushed the dyc3/useThisForClassMethods branch from 3e5b87d to 76e94e3 Compare April 18, 2026 17:07
@dyc3 dyc3 requested a review from ematipico April 18, 2026 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-CLI Area: CLI A-Diagnostic Area: diagnostocis A-Linter Area: linter A-Project Area: project L-JavaScript Language: JavaScript and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants