Skip to content

feat(lint): add new options and if-statement detection to useNullishCoalescing#9841

Closed
pkallos wants to merge 2 commits intobiomejs:mainfrom
pkallos:fix-9232
Closed

feat(lint): add new options and if-statement detection to useNullishCoalescing#9841
pkallos wants to merge 2 commits intobiomejs:mainfrom
pkallos:fix-9232

Conversation

@pkallos
Copy link
Copy Markdown
Contributor

@pkallos pkallos commented Apr 6, 2026

This PR was implemented with AI assistance (Claude).

Summary

Closes #9232.

this gets useNullishCoalescing to feature parity with eslint's prefer-nullish-coalescing. adds the remaining options that were missing and if-statement detection with autofix.

changes:

  • new options: ignoreMixedLogicalExpressions, ignorePrimitives, ignoreBooleanCoercion, ignoreIfStatements
  • ignoreMixedLogicalExpressions defaults to false to match eslint
  • ignorePrimitives supports both true (all primitives) and a per-type object like { string: true, number: true }
  • if-statement detection for patterns like if (x == null) { x = bar; }, if (!x) x = bar;, strict equality, reversed operands, member access, ||=/??= inside bodies
  • autofix for if-statements to x ??= bar;
  • ignorePrimitives now applies to ternary and if-statement paths too (was previously only || and ||=)
  • rule source changed from inspired to same
  • refactored action() into per-variant helper functions
option type default what it does
ignoreMixedLogicalExpressions bool false skip || when mixed with && in the same expression
ignorePrimitives bool or { string, number, bigint, boolean } false skip when the non-nullish type is a primitive
ignoreBooleanCoercion bool false skip || inside Boolean() calls
ignoreIfStatements bool false skip if-statement patterns

Test Plan

test files per option for easier review. to verify manually:

  1. check that if (x == null) { x = value; } gets a diagnostic and autofix to x ??= value;
  2. check that if (!x) x = value; (bare expression, no block) also gets diagnosed and fixed
  3. enable ignorePrimitives: true, verify that if (s == null) { s = 'default'; } where s: string | null produces no diagnostic
  4. enable ignoreIfStatements: true, verify all if-statement patterns are suppressed
  5. enable ignoreBooleanCoercion: true, verify Boolean(x || y) is suppressed
  6. verify ignoreMixedLogicalExpressions defaults to false (mixed &&/|| expressions should trigger by default)

Docs

all options are documented in rustdoc with json,options + ts,use_options examples following codebase conventions. no website PR needed since rule is still in nursery.

…oalescing (biomejs#9232)

- adds options from the eslint rule that were missing:
    - ignoreMixedLogicalExpressions (default: true)
    - ignorePrimitives (bool or per-type object)
    - ignoreBooleanCoercion (default: false)
    - ignoreIfStatements (default: false)
- detects if-statement patterns like `if (!foo) { foo = bar; }` and
    `if (foo == null) { foo = bar; }` that can be simplified to `foo ??= bar`
- handles reversed operands, strict equality, member access, bare
    expression statements, and ||=/??= inside if bodies
- detects || in template literal interpolations
- refactors duplicated option-checking into shared helpers
- adds rustdoc with json,options + ts,use_options examples for each option
- test files per option following codebase conventions
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 6, 2026

🦋 Changeset detected

Latest commit: 9702fe3

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 Apr 6, 2026
@github-actions github-actions Bot added the A-CLI Area: CLI label Apr 6, 2026
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 6, 2026

Merging this PR will not alter performance

✅ 58 untouched benchmarks
⏩ 196 skipped benchmarks1


Comparing pkallos:fix-9232 (9702fe3) with main (2af8efd)2

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.

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

@ematipico
Copy link
Copy Markdown
Member

ematipico commented Apr 7, 2026

I do believe that a PR for each option would be better for both of us. We can have better reviews for each option.

@pkallos
Copy link
Copy Markdown
Contributor Author

pkallos commented Apr 7, 2026

I do believe that a PR for each option would be better for both of us. We can have better reviews for each option.

@ematipico ok good idea! will break this out into several PRs, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

📎 useNullishCoalescing: add ignoreMixedLogicalExpressions, ignorePrimitives, and ignoreBooleanCoercion options

2 participants