fix: collect readonly class property arrow writes#10201
Conversation
🦋 Changeset detectedLatest commit: b0f8a5a 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 |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughClass property initializer traversal was refactored to collect Suggested reviewers
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 👉 Get your free trial and get 200 agent minutes per Slack user (a $50 value). Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.Comment |
There was a problem hiding this comment.
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_js_analyze/src/services/semantic_class.rs`:
- Around line 598-664: collect_references_from_arrow_function currently only
handles block-bodied arrows via body().and_then(|b| b.as_js_function_body()), so
concise expression-bodied arrows (e.g. "() => this.x = 1") are skipped; update
collect_references_from_arrow_function to also accept expression-bodied arrows
by checking arrow_function.body() for an expression (use body.as_js_expression()
or equivalent) when as_js_function_body() is None and then traverse that
expression the same way you do the function body (so reads/writes and
inherited_this_references are processed), ensuring you still return early only
when there is truly no body to inspect.
🪄 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: 7c452095-ca03-4ed5-9276-d52f68a64316
⛔ Files ignored due to path filters (1)
crates/biome_js_analyze/tests/specs/style/useReadonlyClassProperties/valid.ts.snapis excluded by!**/*.snapand included by**
📒 Files selected for processing (3)
.changeset/fix-readonly-class-property-arrow-callback.mdcrates/biome_js_analyze/src/services/semantic_class.rscrates/biome_js_analyze/tests/specs/style/useReadonlyClassProperties/valid.ts
Merging this PR will not alter performance
Comparing Footnotes
|
276a4e8 to
7e49ef7
Compare
| fn function_body_syntax(body: &AnyJsFunctionBody) -> &JsSyntaxNode { | ||
| match body { | ||
| AnyJsFunctionBody::AnyJsExpression(expression) => expression.syntax(), | ||
| AnyJsFunctionBody::JsFunctionBody(body) => body.syntax(), | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
you shouldn't need this function. pretty sure you should be able to just do .syntax() on the AnyJsFunctionBody and get the same thing
There was a problem hiding this comment.
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_js_analyze/src/services/semantic_class.rs`:
- Around line 590-641: In collect_references_from_property_initializer,
top-level writes to this inside the initializer itself (e.g., field =
this.other++ or field = (this.other = 1)) are not being captured because the
current traversal only seeds arrow-function scopes; modify the function so the
traversal is seeded with a scope rooted at the initializer expression itself
(i.e., treat expression.syntax() as an initial scope) and run the same
reference-harvesting logic used for arrow functions (reusing
collect_references_from_arrow_function behavior where appropriate) so that
direct initializer-side reads/writes to this are collected into the
ClassMemberReferences { reads, writes } result; keep the existing skipped_ranges
logic for nested functions/classes and preserve block-bodied arrow recursion for
inner scopes.
🪄 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: 2b7fe5f1-3685-44fe-a987-4af2089953ce
📒 Files selected for processing (1)
crates/biome_js_analyze/src/services/semantic_class.rs
| fn collect_references_from_property_initializer( | ||
| expression: &AnyJsExpression, | ||
| ) -> Option<ClassMemberReferences> { | ||
| let mut reads = FxHashSet::default(); | ||
| let mut writes = FxHashSet::default(); | ||
| let mut skipped_ranges = vec![]; | ||
|
|
||
| for event in expression.syntax().preorder() { | ||
| match event { | ||
| WalkEvent::Enter(node) => { | ||
| if skipped_ranges | ||
| .iter() | ||
| .any(|range: &TextRange| range.contains_range(node.text_range())) | ||
| { | ||
| continue; | ||
| } | ||
|
|
||
| if let Some(arrow_function) = JsArrowFunctionExpression::cast_ref(&node) { | ||
| collect_references_from_arrow_function( | ||
| &arrow_function, | ||
| &[], | ||
| &mut writes, | ||
| &mut reads, | ||
| ); | ||
| skipped_ranges.push(node.text_range()); | ||
| continue; | ||
| } | ||
|
|
||
| if matches!( | ||
| node.kind(), | ||
| JsSyntaxKind::JS_CLASS_EXPRESSION | ||
| | JsSyntaxKind::JS_CLASS_DECLARATION | ||
| | JsSyntaxKind::JS_CLASS_EXPORT_DEFAULT_DECLARATION | ||
| | JsSyntaxKind::JS_FUNCTION_EXPRESSION | ||
| | JsSyntaxKind::JS_FUNCTION_DECLARATION | ||
| | JsSyntaxKind::JS_FUNCTION_EXPORT_DEFAULT_DECLARATION | ||
| | JsSyntaxKind::JS_FUNCTION_BODY | ||
| ) { | ||
| skipped_ranges.push(node.text_range()); | ||
| } | ||
| } | ||
| WalkEvent::Leave(node) => { | ||
| if let Some(last) = skipped_ranges.last() | ||
| && *last == node.text_range() | ||
| { | ||
| skipped_ranges.pop(); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Some(ClassMemberReferences { reads, writes }) |
There was a problem hiding this comment.
Top-level this writes in property initialisers still slip through.
collect_references_from_property_initializer only harvests nested arrow callbacks. Direct initializer-side mutations like field = (this.other = 1) or field = this.other++ still produce no references here, so useReadonlyClassProperties can keep reporting a false positive on non-arrow initialisers. I’d seed the traversal with a scope rooted at the initializer expression itself, then keep the current arrow-specific recursion for block-bodied arrows.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@crates/biome_js_analyze/src/services/semantic_class.rs` around lines 590 -
641, In collect_references_from_property_initializer, top-level writes to this
inside the initializer itself (e.g., field = this.other++ or field = (this.other
= 1)) are not being captured because the current traversal only seeds
arrow-function scopes; modify the function so the traversal is seeded with a
scope rooted at the initializer expression itself (i.e., treat
expression.syntax() as an initial scope) and run the same reference-harvesting
logic used for arrow functions (reusing collect_references_from_arrow_function
behavior where appropriate) so that direct initializer-side reads/writes to this
are collected into the ClassMemberReferences { reads, writes } result; keep the
existing skipped_ranges logic for nested functions/classes and preserve
block-bodied arrow recursion for inner scopes.
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@biomejs/biome](https://biomejs.dev) ([source](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome)) | imports | patch | [`2.4.14` -> `2.4.15`](https://renovatebot.com/diffs/npm/@biomejs%2fbiome/2.4.14/2.4.15) | --- ### Release Notes <details> <summary>biomejs/biome (@​biomejs/biome)</summary> ### [`v2.4.15`](https://github.com/biomejs/biome/blob/HEAD/packages/@​biomejs/biome/CHANGELOG.md#2415) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.4.14...@biomejs/biome@2.4.15) ##### Patch Changes - [#​9394](biomejs/biome#9394) [`ba3480e`](biomejs/biome@ba3480e) Thanks [@​dyc3](https://github.com/dyc3)! - Added the nursery rule [`useTestHooksInOrder`](https://biomejs.dev/linter/rules/use-test-hooks-in-order) in the `test` domain. The rule enforces that Jest/Vitest lifecycle hooks (`beforeAll`, `beforeEach`, `afterEach`, `afterAll`) are declared in the order they execute, making test setup and teardown easier to reason about. - [#​10254](biomejs/biome#10254) [`e0a54cc`](biomejs/biome@e0a54cc) Thanks [@​dyc3](https://github.com/dyc3)! - Added a new nursery rule [`useVueNextTickPromise`](https://biomejs.dev/linter/rules/use-vue-next-tick-promise/), which enforces Promise syntax when using Vue `nextTick`. For example, the following snippet triggers the rule: ```js import { nextTick } from "vue"; nextTick(() => { updateDom(); }); ``` - [#​10219](biomejs/biome#10219) [`64aee45`](biomejs/biome@64aee45) Thanks [@​dyc3](https://github.com/dyc3)! - Added a new nursery rule [`noVueVOnNumberValues`](https://biomejs.dev/linter/rules/no-vue-v-on-number-values/), that disallows deprecated number modifiers on Vue `v-on` directives. For example, the following snippet triggers the rule: ```vue <input @​keyup.13="submit" /> ``` - [#​10195](biomejs/biome#10195) [`7b8d4e1`](biomejs/biome@7b8d4e1) Thanks [@​dyc3](https://github.com/dyc3)! - Added the new nursery rule [`useVueValidVFor`](https://biomejs.dev/linter/rules/use-vue-valid-v-for/), which validates Vue `v-for` directives and reports invalid aliases, missing component keys, and keys that do not use iteration variables. - [#​10238](biomejs/biome#10238) [`1110256`](biomejs/biome@1110256) Thanks [@​dyc3](https://github.com/dyc3)! - Added the recommended nursery rule [`noVueImportCompilerMacros`](https://biomejs.dev/linter/rules/no-vue-import-compiler-macros/), which disallows importing Vue compiler macros such as `defineProps` from `vue` because they are automatically available. - [#​10201](biomejs/biome#10201) [`1a08f89`](biomejs/biome@1a08f89) Thanks [@​realknove](https://github.com/realknove)! - Fixed [#​10193](biomejs/biome#10193): `style/useReadonlyClassProperties` no longer reports class properties as readonly-able when they are assigned inside arrow callbacks nested in class property initializers. - [#​9574](biomejs/biome#9574) [`3bd2b6a`](biomejs/biome@3bd2b6a) Thanks [@​Conaclos](https://github.com/Conaclos)! - Fixed [#​9530](biomejs/biome#9530). The diagnostics of [`organizeImports`](https://biomejs.dev/assist/actions/organize-imports/) are now more detailed and more precise. They are also better at localizing where the issue is. - [#​10205](biomejs/biome#10205) [`a704a6c`](biomejs/biome@a704a6c) Thanks [@​Conaclos](https://github.com/Conaclos)! - Fixed [#​10185](biomejs/biome#10185). [\`organizeImports](https://biomejs.dev/assist/actions/organize-imports/) now errors when it encounters an unknown predefined group. The following configuration is now reported as invalid because `:INEXISTENT:` is an unknown predefined group. ```json { "assist": { "actions": { "source": { "organizeImports": { "options": { "groups": [":INEXISTENT:"] } } } } } } ``` - [#​10052](biomejs/biome#10052) [`b565bed`](biomejs/biome@b565bed) Thanks [@​minseong0324](https://github.com/minseong0324)! - Improved [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/): it now flags union annotations whose extra variants are never returned, and suggests the narrower type (e.g. `string | null` → `string`). These functions are now reported because `null` and `number` are included in the return annotations but never returned: ```ts function getUser(): string | null { return "hello"; } // null is never returned function getCode(): string | number { return "hello"; } // number is never returned ``` - [#​10213](biomejs/biome#10213) [`ac30057`](biomejs/biome@ac30057) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​9450](biomejs/biome#9450): HTML and Vue element formatting now preserves child line breaks when an element contains another element child on its own line, instead of collapsing the child element onto the same line. - [#​10275](biomejs/biome#10275) [`9ee6c03`](biomejs/biome@9ee6c03) Thanks [@​solithcy](https://github.com/solithcy)! - Fixed [#​10274](biomejs/biome#10274): Svelte templates with missing expressions no longer parsed as `HtmlBogusElement` - [#​10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/) now detects misleading return type annotations when object literal properties are initialized with `as const`. This function is now reported because the return annotation widens a property initialized with `as const`: ```ts function f(): { value: string } { return { value: "text" as const }; } ``` - [#​10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`noUselessTypeConversion`](https://biomejs.dev/linter/rules/no-useless-type-conversion/) now detects redundant conversions on object literal properties initialized with `as const`. This conversion is now reported because `message.value` is inferred as a string literal: ```ts const message = { value: "text" as const }; String(message.value); ``` - [#​9807](biomejs/biome#9807) [`0ae5840`](biomejs/biome@0ae5840) Thanks [@​dyc3](https://github.com/dyc3)! - Added the new nursery rule [`useThisInClassMethods`](https://biomejs.dev/linter/rules/use-this-in-class-methods/), based on ESLint's `class-methods-use-this`. The rule now reports instance methods, getters, setters, and function-valued instance fields that do not use `this`, and `biome migrate eslint` preserves the supported `ignoreMethods`, `ignoreOverrideMethods`, and `ignoreClassesWithImplements` options. **Invalid**: ```js class Foo { bar() { // does not use `this`, invalid console.log("Hello Biome"); } } ``` - [#​10258](biomejs/biome#10258) [`e7b18f7`](biomejs/biome@e7b18f7) Thanks [@​ematipico](https://github.com/ematipico)! - Improved linter performance by narrowing the query nodes for several lint rules, reducing how often they are evaluated. - [#​10273](biomejs/biome#10273) [`04e22a1`](biomejs/biome@04e22a1) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​10271](biomejs/biome#10271): The HTML parser now correctly parses `of` as text content when in text contexts. - [#​9838](biomejs/biome#9838) [`83f7385`](biomejs/biome@83f7385) Thanks [@​dyc3](https://github.com/dyc3)! - Added the nursery rule [`noBaseToString`](https://biomejs.dev/linter/rules/no-base-to-string/), which reports stringification sites that fall back to Object's default `"[object Object]"` formatting. The rule also supports the `ignoredTypeNames` option. - [#​10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`useExhaustiveSwitchCases`](https://biomejs.dev/linter/rules/use-exhaustive-switch-cases/) now checks switch statements over object literal properties initialized with `as const`. This switch is now reported because `status.kind` is inferred as the string literal `"ready"` but no case handles it: ```ts const status = { kind: "ready" as const }; switch (status.kind) { } ``` - [#​10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`useStringStartsEndsWith`](https://biomejs.dev/linter/rules/use-string-starts-ends-with/) now detects string index comparisons on object literal properties initialized with `as const`. This comparison is now reported because `message.value` is inferred as a string literal: ```ts const message = { value: "hello" as const }; message.value[0] === "h"; ``` </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNzMuMyIsInVwZGF0ZWRJblZlciI6IjQzLjE3My4zIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Reviewed-on: https://git.oirnoir.dev/OIRNOIR/YouTube-Helper-Server/pulls/12
This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@biomejs/biome](https://biomejs.dev) ([source](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome)) | imports | patch | [`2.4.14` -> `2.4.15`](https://renovatebot.com/diffs/npm/@biomejs%2fbiome/2.4.14/2.4.15) | --- ### Release Notes <details> <summary>biomejs/biome (@​biomejs/biome)</summary> ### [`v2.4.15`](https://github.com/biomejs/biome/blob/HEAD/packages/@​biomejs/biome/CHANGELOG.md#2415) [Compare Source](https://github.com/biomejs/biome/compare/@biomejs/biome@2.4.14...@biomejs/biome@2.4.15) ##### Patch Changes - [#​9394](biomejs/biome#9394) [`ba3480e`](biomejs/biome@ba3480e) Thanks [@​dyc3](https://github.com/dyc3)! - Added the nursery rule [`useTestHooksInOrder`](https://biomejs.dev/linter/rules/use-test-hooks-in-order) in the `test` domain. The rule enforces that Jest/Vitest lifecycle hooks (`beforeAll`, `beforeEach`, `afterEach`, `afterAll`) are declared in the order they execute, making test setup and teardown easier to reason about. - [#​10254](biomejs/biome#10254) [`e0a54cc`](biomejs/biome@e0a54cc) Thanks [@​dyc3](https://github.com/dyc3)! - Added a new nursery rule [`useVueNextTickPromise`](https://biomejs.dev/linter/rules/use-vue-next-tick-promise/), which enforces Promise syntax when using Vue `nextTick`. For example, the following snippet triggers the rule: ```js import { nextTick } from "vue"; nextTick(() => { updateDom(); }); ``` - [#​10219](biomejs/biome#10219) [`64aee45`](biomejs/biome@64aee45) Thanks [@​dyc3](https://github.com/dyc3)! - Added a new nursery rule [`noVueVOnNumberValues`](https://biomejs.dev/linter/rules/no-vue-v-on-number-values/), that disallows deprecated number modifiers on Vue `v-on` directives. For example, the following snippet triggers the rule: ```vue <input @​keyup.13="submit" /> ``` - [#​10195](biomejs/biome#10195) [`7b8d4e1`](biomejs/biome@7b8d4e1) Thanks [@​dyc3](https://github.com/dyc3)! - Added the new nursery rule [`useVueValidVFor`](https://biomejs.dev/linter/rules/use-vue-valid-v-for/), which validates Vue `v-for` directives and reports invalid aliases, missing component keys, and keys that do not use iteration variables. - [#​10238](biomejs/biome#10238) [`1110256`](biomejs/biome@1110256) Thanks [@​dyc3](https://github.com/dyc3)! - Added the recommended nursery rule [`noVueImportCompilerMacros`](https://biomejs.dev/linter/rules/no-vue-import-compiler-macros/), which disallows importing Vue compiler macros such as `defineProps` from `vue` because they are automatically available. - [#​10201](biomejs/biome#10201) [`1a08f89`](biomejs/biome@1a08f89) Thanks [@​realknove](https://github.com/realknove)! - Fixed [#​10193](biomejs/biome#10193): `style/useReadonlyClassProperties` no longer reports class properties as readonly-able when they are assigned inside arrow callbacks nested in class property initializers. - [#​9574](biomejs/biome#9574) [`3bd2b6a`](biomejs/biome@3bd2b6a) Thanks [@​Conaclos](https://github.com/Conaclos)! - Fixed [#​9530](biomejs/biome#9530). The diagnostics of [`organizeImports`](https://biomejs.dev/assist/actions/organize-imports/) are now more detailed and more precise. They are also better at localizing where the issue is. - [#​10205](biomejs/biome#10205) [`a704a6c`](biomejs/biome@a704a6c) Thanks [@​Conaclos](https://github.com/Conaclos)! - Fixed [#​10185](biomejs/biome#10185). [\`organizeImports](https://biomejs.dev/assist/actions/organize-imports/) now errors when it encounters an unknown predefined group. The following configuration is now reported as invalid because `:INEXISTENT:` is an unknown predefined group. ```json { "assist": { "actions": { "source": { "organizeImports": { "options": { "groups": [":INEXISTENT:"] } } } } } } ``` - [#​10052](biomejs/biome#10052) [`b565bed`](biomejs/biome@b565bed) Thanks [@​minseong0324](https://github.com/minseong0324)! - Improved [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/): it now flags union annotations whose extra variants are never returned, and suggests the narrower type (e.g. `string | null` → `string`). These functions are now reported because `null` and `number` are included in the return annotations but never returned: ```ts function getUser(): string | null { return "hello"; } // null is never returned function getCode(): string | number { return "hello"; } // number is never returned ``` - [#​10213](biomejs/biome#10213) [`ac30057`](biomejs/biome@ac30057) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​9450](biomejs/biome#9450): HTML and Vue element formatting now preserves child line breaks when an element contains another element child on its own line, instead of collapsing the child element onto the same line. - [#​10275](biomejs/biome#10275) [`9ee6c03`](biomejs/biome@9ee6c03) Thanks [@​solithcy](https://github.com/solithcy)! - Fixed [#​10274](biomejs/biome#10274): Svelte templates with missing expressions no longer parsed as `HtmlBogusElement` - [#​10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`noMisleadingReturnType`](https://biomejs.dev/linter/rules/no-misleading-return-type/) now detects misleading return type annotations when object literal properties are initialized with `as const`. This function is now reported because the return annotation widens a property initialized with `as const`: ```ts function f(): { value: string } { return { value: "text" as const }; } ``` - [#​10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`noUselessTypeConversion`](https://biomejs.dev/linter/rules/no-useless-type-conversion/) now detects redundant conversions on object literal properties initialized with `as const`. This conversion is now reported because `message.value` is inferred as a string literal: ```ts const message = { value: "text" as const }; String(message.value); ``` - [#​9807](biomejs/biome#9807) [`0ae5840`](biomejs/biome@0ae5840) Thanks [@​dyc3](https://github.com/dyc3)! - Added the new nursery rule [`useThisInClassMethods`](https://biomejs.dev/linter/rules/use-this-in-class-methods/), based on ESLint's `class-methods-use-this`. The rule now reports instance methods, getters, setters, and function-valued instance fields that do not use `this`, and `biome migrate eslint` preserves the supported `ignoreMethods`, `ignoreOverrideMethods`, and `ignoreClassesWithImplements` options. **Invalid**: ```js class Foo { bar() { // does not use `this`, invalid console.log("Hello Biome"); } } ``` - [#​10258](biomejs/biome#10258) [`e7b18f7`](biomejs/biome@e7b18f7) Thanks [@​ematipico](https://github.com/ematipico)! - Improved linter performance by narrowing the query nodes for several lint rules, reducing how often they are evaluated. - [#​10273](biomejs/biome#10273) [`04e22a1`](biomejs/biome@04e22a1) Thanks [@​dyc3](https://github.com/dyc3)! - Fixed [#​10271](biomejs/biome#10271): The HTML parser now correctly parses `of` as text content when in text contexts. - [#​9838](biomejs/biome#9838) [`83f7385`](biomejs/biome@83f7385) Thanks [@​dyc3](https://github.com/dyc3)! - Added the nursery rule [`noBaseToString`](https://biomejs.dev/linter/rules/no-base-to-string/), which reports stringification sites that fall back to Object's default `"[object Object]"` formatting. The rule also supports the `ignoredTypeNames` option. - [#​10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`useExhaustiveSwitchCases`](https://biomejs.dev/linter/rules/use-exhaustive-switch-cases/) now checks switch statements over object literal properties initialized with `as const`. This switch is now reported because `status.kind` is inferred as the string literal `"ready"` but no case handles it: ```ts const status = { kind: "ready" as const }; switch (status.kind) { } ``` - [#​10143](biomejs/biome#10143) [`56798a7`](biomejs/biome@56798a7) Thanks [@​minseong0324](https://github.com/minseong0324)! - [`useStringStartsEndsWith`](https://biomejs.dev/linter/rules/use-string-starts-ends-with/) now detects string index comparisons on object literal properties initialized with `as const`. This comparison is now reported because `message.value` is inferred as a string literal: ```ts const message = { value: "hello" as const }; message.value[0] === "h"; ``` </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNzMuMyIsInVwZGF0ZWRJblZlciI6IjQzLjE3My4zIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> Reviewed-on: https://git.oirnoir.dev/OIRNOIR/YouTube-Helper-Client/pulls/3
Summary
Fixes #10193.
This PR fixes a false positive in
useReadonlyClassProperties.The rule could incorrectly report a class property as eligible for
readonlywhen that property was reassigned inside an arrow callback nested in another class property initializer.For example:
In this case, notReadonlyMember should not be reported as readonly-able because it is written inside the _.debounce arrow callback.
The root cause was that class property initializer references were only collected when the initializer itself was an arrow function. This missed cases where the arrow function was nested inside another expression, such as a call expression.
This PR updates the class member reference collection so that writes inside nested arrow callbacks in property initializers are collected, while preserving JavaScript lexical this semantics. Normal function () {} callbacks and nested class scopes are still ignored so they are not treated as using the class instance this.
A changeset was added for this bug fix.
Test Plan
Added regression coverage for the exact issue reported in #10193.
The new tests verify that:
writes to this.x inside an arrow callback nested in a class property initializer are collected;
normal function () {} callbacks are not treated as using the class initializer's lexical this;
the original _.debounce(() => { this.notReadonlyMember = ... }) repro is accepted as valid and no longer reports useReadonlyClassProperties.
Commands run:
cargo fmt
cargo fmt --check
cargo test -p biome_js_analyze semantic_class
cargo test -p biome_js_analyze use_readonly_class_properties -- --show-output
cargo insta accept
Docs
No documentation changes are required.
This is a bug fix for an existing lint rule and does not add a new rule, action, or user-facing option.