Skip to content

Conversation

@hirokiokada77
Copy link
Contributor

Summary

The noParameterAssign rule with propertyAssignment: "deny" was incorrectly reporting an error when a function parameter was used on the right-hand side (R-value) of an assignment to a local variable's property.

The rule should only flag assignments that modify the parameter binding or its properties (L-value), not the use of its value.

Closes #8254.

Test Plan

Added:

  • tests/specs/style/noParameterAssign/parameterMutationDenyValid.js
  • tests/specs/style/noParameterAssign/parameterMutationDenyValid.js.snap
  • tests/specs/style/noParameterAssign/parameterMutationDenyValid.options.json

Docs

@changeset-bot
Copy link

changeset-bot bot commented Nov 25, 2025

🦋 Changeset detected

Latest commit: 837cc7e

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-Linter Area: linter L-JavaScript Language: JavaScript and super languages labels Nov 25, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 25, 2025

Walkthrough

Adds a changelog patch and tightens the noParameterAssign linter logic for propertyAssignment: "deny". The Rust code now only treats member assignments as parameter mutations when the callee object name exactly matches the parameter binding. Adds a test (parameterMutationDenyValid.js) and an options file to verify that assigning a parameter's value to a local object's properties is not reported. No exported/public API changes.

Pre-merge checks and finishing touches

✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarises the main fix: preventing false positives when a parameter is used as an R-value in the noParameterAssign rule.
Description check ✅ Passed The description directly addresses the bug, explains the distinction between L-value and R-value usage, references the closed issue (#8254), and documents the test additions.
Linked Issues check ✅ Passed The PR fully implements the requirements from #8254: it fixes the rule logic to distinguish L-value (parameter mutation) from R-value (parameter usage), and adds test cases demonstrating the corrected behaviour.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the noParameterAssign rule logic, updating test fixtures, and adding configuration—all aligned with the stated objective of #8254.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

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

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 (4)
crates/biome_js_analyze/tests/specs/style/noParameterAssign/parameterMutationDenyValid.js (1)

1-6: Good coverage of the false-positive scenario; consider aligning filename with spec conventions

The test nicely exercises both static and computed member assignments with the parameter only on the RHS, which is exactly what bit this rule before – good stuff.

One minor consistency nit: test specs under biome_*_analyze/tests/specs generally use valid/invalid as filename prefixes to signal expectation; you might consider something like valid.parameterMutationDeny.js (and updating the snapshot name accordingly) for easier scanning.

Based on learnings, this folder prefers valid/invalid prefixes for spec files.

.changeset/light-mugs-speak.md (1)

1-16: Nice concise changeset; tiny wording/link polish

This reads well and is very user-facing. Two small nits you may want to tweak:

  • “The rule should only flag…” could be tightened to something like “Biome now only flags…” to state the current behaviour rather than the intention.
  • Consider adding a link to the noParameterAssign rule docs alongside the issue link for quick reference.

As per coding guidelines, changesets prefer present tense for Biome’s behaviour and include both issue and rule links where handy.

crates/biome_js_analyze/src/lint/style/no_parameter_assign.rs (2)

151-175: Guarding on the callee object name fixes the false positive; small DRY opportunity

The get_callee_object_name() equality check against binding.name_token() is exactly what was missing to stop RHS-only usages (local.a = param) from being treated as parameter property assignments. This should narrow diagnostics to genuine param.* writes.

The two arms for JsComputedMemberAssignment and JsStaticMemberAssignment duplicate the same object/name logic and call binding.name_token() twice each; if you feel like a tiny tidy-up, you could factor out the parameter name and reuse a helper along these lines:

-AnyJsAssignment::JsComputedMemberAssignment(assignment) => {
-    if assignment
-        .object()
-        .ok()?
-        .get_callee_object_name()?
-        .token_text_trimmed()
-        == binding.name_token().ok()?.token_text_trimmed()
-    {
-        return assignment.object().ok();
-    }
-
-    None
-}
+AnyJsAssignment::JsComputedMemberAssignment(assignment) => {
+    let param_name = binding.name_token().ok()?.token_text_trimmed();
+    let object = assignment.object().ok()?;
+
+    if object
+        .get_callee_object_name()?
+        .token_text_trimmed()
+        == param_name
+    {
+        return Some(object);
+    }
+
+    None
+}

and mirror that pattern in the static-member arm. Entirely optional, but it does make the intent a bit crisper.


24-26: Rule docs still claim property assignments cannot be configured

The doc block still says this rule “cannot be configured to report assignments to a property of a parameter”, which now contradicts the propertyAssignment option documented just below and exercised in this PR.

Might be worth updating these lines to avoid confusion, for example:

-/// In contrast to the _ESLint_ rule, this rule cannot be configured to report
-/// assignments to a property of a parameter.
+/// Property assignments on function parameters can be additionally controlled
+/// via the `propertyAssignment` option described below.

That keeps the comment aligned with the current options without having to restate all the details here.

📜 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 98ca2ae and 0625bff.

⛔ Files ignored due to path filters (1)
  • crates/biome_js_analyze/tests/specs/style/noParameterAssign/parameterMutationDenyValid.js.snap is excluded by !**/*.snap and included by **
📒 Files selected for processing (4)
  • .changeset/light-mugs-speak.md (1 hunks)
  • crates/biome_js_analyze/src/lint/style/no_parameter_assign.rs (1 hunks)
  • crates/biome_js_analyze/tests/specs/style/noParameterAssign/parameterMutationDenyValid.js (1 hunks)
  • crates/biome_js_analyze/tests/specs/style/noParameterAssign/parameterMutationDenyValid.options.json (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.rs: Use the Rust dbg!() macro for debugging output during test execution, and pass the --show-output flag to cargo test to display debug output.
Use snapshot testing with the insta crate for testing in Rust projects. Accept or reject snapshots using cargo insta accept, cargo insta reject, or cargo insta review.
Write doc comments as doc tests in Rust using code blocks with assertions that will be executed during the testing phase.
Use rustdoc inline documentation for rules, assists, and their options. Create corresponding documentation PRs for other documentation updates against the next branch of the website repository.
Set the version metadata field in linter rule implementations to 'next' for newly created rules. Update this field to the new version number when releasing a minor or major version.

Files:

  • crates/biome_js_analyze/src/lint/style/no_parameter_assign.rs
**/.changeset/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Changeset descriptions should be user-facing, use past tense for actions taken (e.g., 'Added new feature'), and present tense for Biome behavior (e.g., 'Biome now supports...'). Include issue links, rule links, and code examples where applicable.

Files:

  • .changeset/light-mugs-speak.md
🧠 Learnings (12)
📚 Learning: 2025-11-24T18:04:42.146Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:42.146Z
Learning: Applies to crates/biome_analyze/**/biome_*_analyze/tests/specs/**/*.{js,ts,tsx,jsx,json,css,graphql} : Test files should use 'invalid' or 'valid' prefixes to indicate whether they contain code reported by the rule

Applied to files:

  • crates/biome_js_analyze/tests/specs/style/noParameterAssign/parameterMutationDenyValid.options.json
  • crates/biome_js_analyze/tests/specs/style/noParameterAssign/parameterMutationDenyValid.js
📚 Learning: 2025-08-05T14:43:29.581Z
Learnt from: dyc3
Repo: biomejs/biome PR: 7081
File: packages/@biomejs/biome/configuration_schema.json:7765-7781
Timestamp: 2025-08-05T14:43:29.581Z
Learning: The file `packages/biomejs/biome/configuration_schema.json` is auto-generated and should not be manually edited or reviewed for schema issues; any changes should be made at the code generation source.

Applied to files:

  • crates/biome_js_analyze/tests/specs/style/noParameterAssign/parameterMutationDenyValid.options.json
📚 Learning: 2025-11-24T18:05:20.343Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:20.343Z
Learning: Applies to crates/biome_formatter/**/biome_*_formatter/tests/specs/**/options.json : Create an `options.json` file (formatted as `biome.json`) in test specification folders to apply non-default formatting options to all test files in that folder

Applied to files:

  • crates/biome_js_analyze/tests/specs/style/noParameterAssign/parameterMutationDenyValid.options.json
📚 Learning: 2025-11-24T18:04:42.146Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:42.146Z
Learning: Applies to crates/biome_analyze/**/biome_*_analyze/tests/specs/**/*.{js,ts,tsx,jsx,json,css,graphql} : Test files for rules should be placed inside 'tests/specs/' directory organized by group and rule name (e.g., 'tests/specs/nursery/myRuleName/')

Applied to files:

  • crates/biome_js_analyze/tests/specs/style/noParameterAssign/parameterMutationDenyValid.options.json
📚 Learning: 2025-11-24T18:04:42.146Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:42.146Z
Learning: Applies to crates/biome_analyze/**/biome_*_analyze/lib/src/**/!(mod).rs : Code blocks in documentation marked with 'options' should contain only rule-specific options in JSON/JSONC format, while 'full_options' contains complete biome.json configuration

Applied to files:

  • crates/biome_js_analyze/tests/specs/style/noParameterAssign/parameterMutationDenyValid.options.json
📚 Learning: 2025-11-24T18:04:42.146Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:42.146Z
Learning: Applies to crates/biome_analyze/**/biome_*_analyze/lib/src/**/!(mod).rs : The 'language' field in 'declare_lint_rule!' should be set to the specific JavaScript dialect (jsx, ts, tsx) if the rule only applies to that dialect, otherwise use 'js'

Applied to files:

  • crates/biome_js_analyze/tests/specs/style/noParameterAssign/parameterMutationDenyValid.options.json
  • crates/biome_js_analyze/src/lint/style/no_parameter_assign.rs
  • .changeset/light-mugs-speak.md
📚 Learning: 2025-11-21T01:10:53.036Z
Learnt from: dyc3
Repo: biomejs/biome PR: 8171
File: crates/biome_js_analyze/src/lint/nursery/no_leaked_render.rs:125-137
Timestamp: 2025-11-21T01:10:53.036Z
Learning: In the Biome codebase, each lint rule has its own options type declaration (e.g., `type Options = RuleNameOptions`) as part of the codegen process, even if the options struct is empty or unused. This is standard practice and should not be flagged as an issue.

Applied to files:

  • crates/biome_js_analyze/tests/specs/style/noParameterAssign/parameterMutationDenyValid.options.json
📚 Learning: 2025-11-24T18:04:42.146Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:42.146Z
Learning: Applies to crates/biome_analyze/**/biome_*_analyze/lib/src/**/!(mod).rs : Rules that ban functions or variables should use the semantic model to check if the variable is global before reporting, to avoid false positives on locally redeclared variables

Applied to files:

  • crates/biome_js_analyze/src/lint/style/no_parameter_assign.rs
📚 Learning: 2025-11-24T18:05:27.784Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:27.784Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Do not attempt to 'fix' the code; if a token/node is known to be mandatory but is missing, return `None` instead

Applied to files:

  • crates/biome_js_analyze/src/lint/style/no_parameter_assign.rs
📚 Learning: 2025-11-24T18:04:42.146Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:42.146Z
Learning: Applies to crates/biome_analyze/**/biome_*_analyze/lib/src/**/!(mod).rs : Rules that promote equivalent compact syntax should use the 'useShorthand<Concept>' naming convention (e.g., `useShorthandAssign`)

Applied to files:

  • crates/biome_js_analyze/src/lint/style/no_parameter_assign.rs
📚 Learning: 2025-11-24T18:05:27.784Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:05:27.784Z
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_analyze/src/lint/style/no_parameter_assign.rs
📚 Learning: 2025-11-24T18:03:52.013Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:03:52.013Z
Learning: Applies to **/.changeset/*.md : Changeset descriptions should be user-facing, use past tense for actions taken (e.g., 'Added new feature'), and present tense for Biome behavior (e.g., 'Biome now supports...'). Include issue links, rule links, and code examples where applicable.

Applied to files:

  • .changeset/light-mugs-speak.md
⏰ 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). (13)
  • GitHub Check: Validate rules documentation
  • GitHub Check: Test Node.js API
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Documentation
  • GitHub Check: Check Dependencies
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: End-to-end tests
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: autofix
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Bench (biome_js_parser)
🔇 Additional comments (1)
crates/biome_js_analyze/tests/specs/style/noParameterAssign/parameterMutationDenyValid.options.json (1)

1-15: Config matches the intended repro

The options file cleanly scopes noParameterAssign with propertyAssignment: "deny" for this spec, and the schema reference looks correct. Nothing to change here from my side.

@codspeed-hq
Copy link

codspeed-hq bot commented Nov 25, 2025

CodSpeed Performance Report

Merging #8259 will not alter performance

Comparing hirokiokada77:fix/no-parameter-assign-false-positive (837cc7e) with main (98ca2ae)

Summary

✅ 58 untouched
⏩ 95 skipped1

Footnotes

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

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 (1)
.changeset/light-mugs-speak.md (1)

5-7: Changeset looks solid.

The description is user-facing, uses appropriate tense (past for action, present for Biome behaviour), includes the issue link, and provides a clear code example demonstrating the fixed scenario.

As an optional enhancement, consider adding an explicit link to the rule documentation (e.g., [noParameterAssign](https://biomejs.dev/linter/rules/no-parameter-assign/#propertyassignment)) to help users navigate to the full rule reference.

📜 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 0625bff and 837cc7e.

📒 Files selected for processing (1)
  • .changeset/light-mugs-speak.md (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/.changeset/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Changeset descriptions should be user-facing, use past tense for actions taken (e.g., 'Added new feature'), and present tense for Biome behavior (e.g., 'Biome now supports...'). Include issue links, rule links, and code examples where applicable.

Files:

  • .changeset/light-mugs-speak.md
🧠 Learnings (5)
📚 Learning: 2025-11-24T18:03:52.013Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:03:52.013Z
Learning: Applies to **/.changeset/*.md : Changeset descriptions should be user-facing, use past tense for actions taken (e.g., 'Added new feature'), and present tense for Biome behavior (e.g., 'Biome now supports...'). Include issue links, rule links, and code examples where applicable.

Applied to files:

  • .changeset/light-mugs-speak.md
📚 Learning: 2025-11-24T18:04:42.146Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:42.146Z
Learning: Applies to crates/biome_analyze/**/biome_*_analyze/lib/src/**/!(mod).rs : The 'language' field in 'declare_lint_rule!' should be set to the specific JavaScript dialect (jsx, ts, tsx) if the rule only applies to that dialect, otherwise use 'js'

Applied to files:

  • .changeset/light-mugs-speak.md
📚 Learning: 2025-11-24T18:03:52.014Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:03:52.014Z
Learning: For bugfix/feature PRs visible to Biome toolchain users or affecting published crates, create a changeset using the `just new-changeset` command with appropriate package selection, change type (major/minor/patch), and description.

Applied to files:

  • .changeset/light-mugs-speak.md
📚 Learning: 2025-11-24T18:04:42.146Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:42.146Z
Learning: Applies to crates/biome_analyze/**/biome_*_analyze/lib/src/**/!(mod).rs : Rules that ban functions or variables should use the semantic model to check if the variable is global before reporting, to avoid false positives on locally redeclared variables

Applied to files:

  • .changeset/light-mugs-speak.md
📚 Learning: 2025-11-24T18:04:42.146Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T18:04:42.146Z
Learning: Applies to crates/biome_analyze/**/biome_*_analyze/lib/src/**/!(mod).rs : Rule names should follow the 'no<Concept>' prefix when a rule's sole intention is to forbid a single concept (e.g., `noDebugger` for disallowing debugger statements)

Applied to files:

  • .changeset/light-mugs-speak.md
⏰ 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). (12)
  • GitHub Check: Test Node.js API
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: autofix
  • GitHub Check: Documentation
  • GitHub Check: End-to-end tests
  • GitHub Check: Bench (biome_js_analyze)
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Check Dependencies
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Bench (biome_js_formatter)
  • GitHub Check: Bench (biome_js_parser)

@dyc3 dyc3 merged commit 4a9139b into biomejs:main Nov 25, 2025
18 checks passed
@github-actions github-actions bot mentioned this pull request Nov 25, 2025
@hirokiokada77 hirokiokada77 deleted the fix/no-parameter-assign-false-positive branch November 25, 2025 13:56
@github-actions github-actions bot mentioned this pull request Nov 25, 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.

🐛 options.propertyAssignment in lint/style/noParameterAssign misunderstand assignment

2 participants