Skip to content

Fix missing unnecessary_non_null_assertion (#1270) - #1348

Open
Tulleb wants to merge 1 commit into
rrousselGit:masterfrom
Tulleb:unnecessary_non_null_assertion
Open

Fix missing unnecessary_non_null_assertion (#1270)#1348
Tulleb wants to merge 1 commit into
rrousselGit:masterfrom
Tulleb:unnecessary_non_null_assertion

Conversation

@Tulleb

@Tulleb Tulleb commented May 4, 2026

Copy link
Copy Markdown

Fixes #1270

Summary by CodeRabbit

  • Bug Fixes
    • Improved analyzer lint suppression in generated code to reduce unnecessary warnings related to null assertion operations.

@coderabbitai

coderabbitai Bot commented May 4, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The pull request expands the default list of suppressed Dart analyzer lints in generated copyWith templates from cast_nullable_to_non_nullable to include unnecessary_non_null_assertion. This suppresses analyzer warnings about redundant force unwrap operators in generated code.

Changes

Lint Suppression Enhancement

Layer / File(s) Summary
Suppression Configuration
packages/freezed/lib/src/templates/copy_with.dart
CopyWith._ignoreLints adds unnecessary_non_null_assertion to the default lints list, expanding the generated // ignore: comment from one entry to two.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~5 minutes

Poem

🐰 A force unwrap too strong, the analyzer did cry,
"Unnecessary bang upon a value never null!" we sigh.
So hush the lint with suppression's gentle hand,
And let the copyWith magic gracefully stand. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR suppresses the unnecessary_non_null_assertion lint but does not implement the core fix to prevent generating redundant force-unwrap operators in copyWith methods. Modify the generator to omit the unnecessary '!' operator for non-nullable fields instead of just suppressing the lint warning.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: suppressing the unnecessary_non_null_assertion lint in generated copyWith code.
Out of Scope Changes check ✅ Passed The change is directly related to addressing issue #1270 by suppressing the lint warning for unnecessary non-null assertions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/freezed/lib/src/templates/copy_with.dart (1)

257-266: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

unnecessary_non_null_assertion suppress comment is placed on the wrong line — the lint will still fire.

Dart's // ignore: comment "suppress[es] a specific non-error diagnostic on a specific line" and must be placed above (i.e., immediately before) the offending line.

The _ignoreLints helper wraps the as ${p.typeDisplayString} expression. parameterToValue therefore emits:

Line N:   null == value ? _self.value! : value 
Line N+1: // ignore: cast_nullable_to_non_nullable, unnecessary_non_null_assertion
Line N+2: as String,

The comment on Line N+1 suppresses lints on Line N+2 (as String,). The unnecessary_non_null_assertion diagnostic fires on _self.value! — which is on Line N, one line before the ignore comment. Adding the lint name to this comment has no effect on the actual offending token.

The root cause is in thisPropertyFor (line 296): cast = '!' is unconditionally set whenever the property type differs from the parameter type, even when the property is already non-nullable (String). The ! is only semantically needed when the property itself is nullable. The correct fix is:

🐛 Proposed root-cause fix in `thisPropertyFor`
  var cast = '';
- if (propertyGetterForCopyWithParameter.type != to.type) cast = '!';
+ if (propertyGetterForCopyWithParameter.type != to.type &&
+     propertyGetterForCopyWithParameter.type.isNullable) cast = '!';
  return '$accessor.$propertyName$cast';

Alternatively, if a suppress-only approach is preferred, the ignore comment must be placed on the line that contains the ternary (i.e., wrapping the result of parameterToValue, not just the as cast inside parameterAssignmentFor).

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

In `@packages/freezed/lib/src/templates/copy_with.dart` around lines 257 - 266,
The suppress comment is placed after the cast so it doesn't prevent the
unnecessary_non_null_assertion on the preceding ternary; fix by adjusting
thisPropertyFor to only append the non-null assertion ('!') when the property
type is nullable (i.e., detect property nullability and set cast = '!' only if
propertyTypeIsNullable), so parameterToValue no longer emits an unnecessary '!'
for already non-nullable properties; alternatively (if you prefer a
suppress-only change) move the ignore comment generation in
_ignoreLints/parameterAssignmentFor to be emitted immediately above the entire
ternary expression produced by parameterToValue instead of above just the `as`
cast.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@packages/freezed/lib/src/templates/copy_with.dart`:
- Around line 257-266: The suppress comment is placed after the cast so it
doesn't prevent the unnecessary_non_null_assertion on the preceding ternary; fix
by adjusting thisPropertyFor to only append the non-null assertion ('!') when
the property type is nullable (i.e., detect property nullability and set cast =
'!' only if propertyTypeIsNullable), so parameterToValue no longer emits an
unnecessary '!' for already non-nullable properties; alternatively (if you
prefer a suppress-only change) move the ignore comment generation in
_ignoreLints/parameterAssignmentFor to be emitted immediately above the entire
ternary expression produced by parameterToValue instead of above just the `as`
cast.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7a0b74a3-100e-4813-8d90-0f1bcaf4f2cf

📥 Commits

Reviewing files that changed from the base of the PR and between 6c57a40 and 3687f07.

📒 Files selected for processing (1)
  • packages/freezed/lib/src/templates/copy_with.dart

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Redundant "!" operator for non-nullable fields in copyWIth

1 participant