feat(lint): add new options and if-statement detection to useNullishCoalescing#9841
feat(lint): add new options and if-statement detection to useNullishCoalescing#9841pkallos wants to merge 2 commits intobiomejs:mainfrom
Conversation
…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 detectedLatest commit: 9702fe3 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 |
Merging this PR will not alter performance
Comparing Footnotes
|
|
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 |
This PR was implemented with AI assistance (Claude).
Summary
Closes #9232.
this gets
useNullishCoalescingto feature parity with eslint'sprefer-nullish-coalescing. adds the remaining options that were missing and if-statement detection with autofix.changes:
ignoreMixedLogicalExpressions,ignorePrimitives,ignoreBooleanCoercion,ignoreIfStatementsignoreMixedLogicalExpressionsdefaults tofalseto match eslintignorePrimitivessupports bothtrue(all primitives) and a per-type object like{ string: true, number: true }if (x == null) { x = bar; },if (!x) x = bar;, strict equality, reversed operands, member access,||=/??=inside bodiesx ??= bar;ignorePrimitivesnow applies to ternary and if-statement paths too (was previously only||and||=)inspiredtosameaction()into per-variant helper functionsignoreMixedLogicalExpressionsboolfalse||when mixed with&&in the same expressionignorePrimitivesboolor{ string, number, bigint, boolean }falseignoreBooleanCoercionboolfalse||insideBoolean()callsignoreIfStatementsboolfalseTest Plan
test files per option for easier review. to verify manually:
if (x == null) { x = value; }gets a diagnostic and autofix tox ??= value;if (!x) x = value;(bare expression, no block) also gets diagnosed and fixedignorePrimitives: true, verify thatif (s == null) { s = 'default'; }wheres: string | nullproduces no diagnosticignoreIfStatements: true, verify all if-statement patterns are suppressedignoreBooleanCoercion: true, verifyBoolean(x || y)is suppressedignoreMixedLogicalExpressionsdefaults to false (mixed&&/||expressions should trigger by default)Docs
all options are documented in rustdoc with
json,options+ts,use_optionsexamples following codebase conventions. no website PR needed since rule is still in nursery.