Remove obsolete null checks from style guide#181703
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates code examples in the style guide to remove obsolete null checks, aligning them with modern null-safe Dart. The changes are generally good, but one of the examples is left in a state that is not valid under null safety. I've provided a suggestion to correct the example by using the required keyword for non-nullable named parameters, which makes the code valid and achieves the goal of removing the explicit null check.
Piinks
left a comment
There was a problem hiding this comment.
Thanks for contributing some tweaks here.
| TheType get theProperty => _theProperty; | ||
| TheType _theProperty; |
There was a problem hiding this comment.
I could see how TheType could be a nullable property. Maybe we should make it explicit as TheType?? I think it's a good example to have the assertion in the setter body.
There was a problem hiding this comment.
In this example _theProperty is non-nullable, but you're right that the property could just as easily have been created as a nullable one.
However, I don't think it's good to have the assertion in the setter body; based on how this example is currently written, there's no way for the non-nullable value to be null.
There was a problem hiding this comment.
Yes. What I was suggesting was that you update this to be an explicitly nullable type to remove the ambiguity and keep the assertion.
There was a problem hiding this comment.
Okay, so then it would look like this:
TheType? get theProperty => _theProperty;
TheType? _theProperty;
void set theProperty(TheType? value) {
assert(value != null);
if (_theProperty == value) {
return;
}
_theProperty = value;
markNeedsWhatever(); // the method to mark the object dirty
}This would work, though it has the downside of being a bit more verbose. (In my opinion, being concise & readable is even more important in the style guide than anywhere else in this repo.)
Is there a downside to how I have it currently?
There was a problem hiding this comment.
Similar to the other example, I would consider the intention of the guidance here. This is about providing guidelines for performing dirty checks in setters. Does this change improve on that guidance? IMO, I don't think verbosity is a bad thing in docs meant to educate for working on the framework.
There was a problem hiding this comment.
IMO, I don't think verbosity is a bad thing in docs meant to educate for working on the framework.
I suppose we could agree to disagree here. There's a good reason "TL;DR" is so prevalent throughout the internet: if something is more verbose, the opportunity cost of reading & understanding is higher, ergo people become less likely to do it. In the case of this example, removing irrelevant code is a straight improvement IMO.
I really appreciate the time you've spent helping me out here. Since this PR would require two approvals to merge, maybe now would be a good time for another reviewer to step in with a fresh perspective.
There was a problem hiding this comment.
There's a good reason "TL;DR" is so prevalent throughout the internet: if something is more verbose, the opportunity cost of reading & understanding is higher, ergo people become less likely to do it. In the case of this example, removing irrelevant code is a straight improvement IMO.
I am not sure this is really relevant. This is a change specifically within the context of the Flutter org. Not the internet at large. :)
I will leave this to another reviewer to make a pass. Honestly, I don't know this change is worth this much debate.
There was a problem hiding this comment.
I agree that this example should change one way or another, because the assertion is no longer necessary and could confuse people. Also, the assertion is not important to this section of the style guide. My interpretation of the two options are:
Option 1:
TheType _theProperty;
void set theProperty(TheType value) {
- assert(value != null);
if (_theProperty == value) {
return;
}
_theProperty = value;
markNeedsWhatever(); // the method to mark the object dirty
}Option 2:
-TheType _theProperty;
+TheType? _theProperty;
-void set theProperty(TheType value) {
+void set theProperty(TheType? value) {
assert(value != null);
if (_theProperty == value) {
return;
}
_theProperty = value;
markNeedsWhatever(); // the method to mark the object dirty
}I like option 1. Option 2 is oddly specific and could distract from the point of this section. You might do something like it if _theProperty was supposed to be null during initialization or something and then never nonnull again... but then why assert instead of making the setter nonnullable? These are questions that the reader shouldn't be thinking about :)
| /// The [bar] argument allows the baz to quux. | ||
| /// | ||
| /// The `baz` argument must be greater than zero. | ||
| Foo({ this.bar, int baz }) : assert(bar != null), assert(baz > 0); |
There was a problem hiding this comment.
These could also be nullable, the sample code here does not provide enough information to determine if they are or not. IMO, I think this one is ok as is.
There was a problem hiding this comment.
I disagree here as well: the best practice is to avoid null-asserts in constructors.
class Foo {
Foo({this.bar}) : assert(bar != null); // BAD
Object? bar;
}Let's say that bar is a nullable field but you still want the constructor argument to be non-nullable. You could do it like so:
class Foo {
Foo({required Object this.bar}); // GOOD
Object? bar;
}It's much better for null-safety to be enforced by a type annotation than by using an assert, since the latter makes it much easier for mistakes to go unnoticed until runtime.
There was a problem hiding this comment.
Right, I think we might be over-indexing on code that lacks enough context to actually suggest this.
There was a problem hiding this comment.
Fair enough haha
But the point I was trying to make is: validating a constructor argument with an assert(bar != null) is never a good practice, so I'd like this example to be changed to reflect that.
There was a problem hiding this comment.
I appreciate you want to make the code snippet as accurate as possible. Given that this code snippet is meant to facilitate guidance around documenting parameters, and not to illustrate best practices around unnecessary null-asserts, does this change improve on the intended guidance?
There was a problem hiding this comment.
Yes it does!
Originally, this example documentation said:
/// The [bar] argument must not be null.At the time it was written, there wasn't a good way to enforce that a non-null argument is passed into a class constructor, so the best practice was to include this advice where applicable.
But thanks to null safety, this advice is no longer warranted: setting the class member as non-nullable means that static analysis will enforce it.
There was a problem hiding this comment.
I think that assert(bar != null) should go since it is not best practice. I don't want to confuse users or LLMs that might read it.
The conversation in #181703 got me thinking about whether there were any `assert(value != null)` statements in our codebase that were written prior to Dart's null safety era and could be factored out. It turns out that there are! This PR updates a few setters so that incorrect `null` assignments are caught by static analysis instead of potentially going unnoticed until runtime. Co-authored-by: Victor Sanni <victorsanniay@gmail.com>
justinmc
left a comment
There was a problem hiding this comment.
LGTM 👍 . I say let's update these to modern Dart and move on, no need to debate these too much. Even if the examples aren't perfect they will now avoid being outdated.
| TheType get theProperty => _theProperty; | ||
| TheType _theProperty; |
There was a problem hiding this comment.
I agree that this example should change one way or another, because the assertion is no longer necessary and could confuse people. Also, the assertion is not important to this section of the style guide. My interpretation of the two options are:
Option 1:
TheType _theProperty;
void set theProperty(TheType value) {
- assert(value != null);
if (_theProperty == value) {
return;
}
_theProperty = value;
markNeedsWhatever(); // the method to mark the object dirty
}Option 2:
-TheType _theProperty;
+TheType? _theProperty;
-void set theProperty(TheType value) {
+void set theProperty(TheType? value) {
assert(value != null);
if (_theProperty == value) {
return;
}
_theProperty = value;
markNeedsWhatever(); // the method to mark the object dirty
}I like option 1. Option 2 is oddly specific and could distract from the point of this section. You might do something like it if _theProperty was supposed to be null during initialization or something and then never nonnull again... but then why assert instead of making the setter nonnullable? These are questions that the reader shouldn't be thinking about :)
| /// The [bar] argument allows the baz to quux. | ||
| /// | ||
| /// The `baz` argument must be greater than zero. | ||
| Foo({ this.bar, int baz }) : assert(bar != null), assert(baz > 0); |
There was a problem hiding this comment.
I think that assert(bar != null) should go since it is not best practice. I don't want to confuse users or LLMs that might read it.
The conversation in flutter#181703 got me thinking about whether there were any `assert(value != null)` statements in our codebase that were written prior to Dart's null safety era and could be factored out. It turns out that there are! This PR updates a few setters so that incorrect `null` assignments are caught by static analysis instead of potentially going unnoticed until runtime. Co-authored-by: Victor Sanni <victorsanniay@gmail.com>
The conversation in flutter#181703 got me thinking about whether there were any `assert(value != null)` statements in our codebase that were written prior to Dart's null safety era and could be factored out. It turns out that there are! This PR updates a few setters so that incorrect `null` assignments are caught by static analysis instead of potentially going unnoticed until runtime. Co-authored-by: Victor Sanni <victorsanniay@gmail.com>
04cd59e to
c0ab8ae
Compare
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
c0ab8ae to
38ce8f7
Compare
flutter/flutter@d117642...dd64978 2026-03-18 engine-flutter-autoroll@skia.org Roll Skia from 2fb5fa71eb12 to f0a13e5efbad (2 revisions) (flutter/flutter#183830) 2026-03-18 engine-flutter-autoroll@skia.org Roll Skia from ae3d36cb9e29 to 2fb5fa71eb12 (3 revisions) (flutter/flutter#183823) 2026-03-18 94012149+richardexfo@users.noreply.github.com Linux reuse sibling (flutter/flutter#183653) 2026-03-18 engine-flutter-autoroll@skia.org Roll Skia from 84a180a1fa80 to ae3d36cb9e29 (4 revisions) (flutter/flutter#183812) 2026-03-18 1961493+harryterkelsen@users.noreply.github.com fix(web): handle asynchronously disposed platform views (flutter/flutter#183666) 2026-03-17 87018443+mayanksharma9@users.noreply.github.com (Test cross-imports) Remove legacy Material import from sliver_constraints_test (flutter/flutter#183351) 2026-03-17 74057391+jhonathanqz@users.noreply.github.com Fix Android Studio pluginsPath when version is unknown (do not use 0.0) (flutter/flutter#182681) 2026-03-17 50643541+Mairramer@users.noreply.github.com Fixes animation glitch into bottom sheet (flutter/flutter#183303) 2026-03-17 ahmedsameha1@gmail.com Handle#6537 second grouped test (flutter/flutter#182529) 2026-03-17 ahmedsameha1@gmail.com Add a Clarification for the docs of suggestionsBuilder of SearchAnchor (flutter/flutter#183106) 2026-03-17 nate.w5687@gmail.com Remove obsolete null checks from style guide (flutter/flutter#181703) 2026-03-17 jason-simmons@users.noreply.github.com [Impeller] Do not delete the GL object in a HandleGLES if the handle has a cleanup callback (flutter/flutter#183561) 2026-03-17 jason-simmons@users.noreply.github.com Encode source file patches as UTF-8 in the code formatter script (flutter/flutter#183761) 2026-03-17 82673815+gktirkha@users.noreply.github.com Fix widget inspector control layout and add safe area regression test (flutter/flutter#180789) 2026-03-17 43054281+camsim99@users.noreply.github.com Reland "[Android] Add mechanism for setting Android engine flags via Android manifest (take 2)" (flutter/flutter#182522) 2026-03-17 1961493+harryterkelsen@users.noreply.github.com fix(web): fix crash in Skwasm when transferring non-transferable texture sources (flutter/flutter#183799) 2026-03-17 engine-flutter-autoroll@skia.org Roll Skia from dba893a44d7a to 84a180a1fa80 (7 revisions) (flutter/flutter#183803) 2026-03-17 brunocorona.alcantar@gmail.com Framework: Improve DropdownButton selectedItemBuilder assertion (flutter/flutter#183732) 2026-03-17 brunocorona.alcantar@gmail.com Add mainAxisAlignment to NavigationRail (flutter/flutter#183514) 2026-03-17 34871572+gmackall@users.noreply.github.com Update android triage process to not look at unassigned p1s every week (flutter/flutter#183805) 2026-03-17 30870216+gaaclarke@users.noreply.github.com Adds macos impeller new gallery transition perf test. (flutter/flutter#183802) 2026-03-17 1961493+harryterkelsen@users.noreply.github.com fix(web_ui): move prepareToDraw after raster to improve concurrency and stability (flutter/flutter#183791) 2026-03-17 rmacnak@google.com [build] Generate debug info for assembly. (flutter/flutter#183425) 2026-03-17 mdebbar@google.com [web] Fix occasional failure to find Chrome tab (flutter/flutter#183737) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC boetger@google.com,stuartmorgan@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…r#11281) flutter/flutter@d117642...dd64978 2026-03-18 engine-flutter-autoroll@skia.org Roll Skia from 2fb5fa71eb12 to f0a13e5efbad (2 revisions) (flutter/flutter#183830) 2026-03-18 engine-flutter-autoroll@skia.org Roll Skia from ae3d36cb9e29 to 2fb5fa71eb12 (3 revisions) (flutter/flutter#183823) 2026-03-18 94012149+richardexfo@users.noreply.github.com Linux reuse sibling (flutter/flutter#183653) 2026-03-18 engine-flutter-autoroll@skia.org Roll Skia from 84a180a1fa80 to ae3d36cb9e29 (4 revisions) (flutter/flutter#183812) 2026-03-18 1961493+harryterkelsen@users.noreply.github.com fix(web): handle asynchronously disposed platform views (flutter/flutter#183666) 2026-03-17 87018443+mayanksharma9@users.noreply.github.com (Test cross-imports) Remove legacy Material import from sliver_constraints_test (flutter/flutter#183351) 2026-03-17 74057391+jhonathanqz@users.noreply.github.com Fix Android Studio pluginsPath when version is unknown (do not use 0.0) (flutter/flutter#182681) 2026-03-17 50643541+Mairramer@users.noreply.github.com Fixes animation glitch into bottom sheet (flutter/flutter#183303) 2026-03-17 ahmedsameha1@gmail.com Handle#6537 second grouped test (flutter/flutter#182529) 2026-03-17 ahmedsameha1@gmail.com Add a Clarification for the docs of suggestionsBuilder of SearchAnchor (flutter/flutter#183106) 2026-03-17 nate.w5687@gmail.com Remove obsolete null checks from style guide (flutter/flutter#181703) 2026-03-17 jason-simmons@users.noreply.github.com [Impeller] Do not delete the GL object in a HandleGLES if the handle has a cleanup callback (flutter/flutter#183561) 2026-03-17 jason-simmons@users.noreply.github.com Encode source file patches as UTF-8 in the code formatter script (flutter/flutter#183761) 2026-03-17 82673815+gktirkha@users.noreply.github.com Fix widget inspector control layout and add safe area regression test (flutter/flutter#180789) 2026-03-17 43054281+camsim99@users.noreply.github.com Reland "[Android] Add mechanism for setting Android engine flags via Android manifest (take 2)" (flutter/flutter#182522) 2026-03-17 1961493+harryterkelsen@users.noreply.github.com fix(web): fix crash in Skwasm when transferring non-transferable texture sources (flutter/flutter#183799) 2026-03-17 engine-flutter-autoroll@skia.org Roll Skia from dba893a44d7a to 84a180a1fa80 (7 revisions) (flutter/flutter#183803) 2026-03-17 brunocorona.alcantar@gmail.com Framework: Improve DropdownButton selectedItemBuilder assertion (flutter/flutter#183732) 2026-03-17 brunocorona.alcantar@gmail.com Add mainAxisAlignment to NavigationRail (flutter/flutter#183514) 2026-03-17 34871572+gmackall@users.noreply.github.com Update android triage process to not look at unassigned p1s every week (flutter/flutter#183805) 2026-03-17 30870216+gaaclarke@users.noreply.github.com Adds macos impeller new gallery transition perf test. (flutter/flutter#183802) 2026-03-17 1961493+harryterkelsen@users.noreply.github.com fix(web_ui): move prepareToDraw after raster to improve concurrency and stability (flutter/flutter#183791) 2026-03-17 rmacnak@google.com [build] Generate debug info for assembly. (flutter/flutter#183425) 2026-03-17 mdebbar@google.com [web] Fix occasional failure to find Chrome tab (flutter/flutter#183737) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC boetger@google.com,stuartmorgan@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
The conversation in flutter#181703 got me thinking about whether there were any `assert(value != null)` statements in our codebase that were written prior to Dart's null safety era and could be factored out. It turns out that there are! This PR updates a few setters so that incorrect `null` assignments are caught by static analysis instead of potentially going unnoticed until runtime. Co-authored-by: Victor Sanni <victorsanniay@gmail.com>
A couple of the style guide examples were written prior to Dart's null safety era, so this PR aims to update those examples. [Test-exempt](https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests) because it only affects the `.md` file. --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
A couple of the style guide examples were written prior to Dart's null safety era, so this PR aims to update those examples. [Test-exempt](https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests) because it only affects the `.md` file. --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…r#11281) flutter/flutter@d117642...dd64978 2026-03-18 engine-flutter-autoroll@skia.org Roll Skia from 2fb5fa71eb12 to f0a13e5efbad (2 revisions) (flutter/flutter#183830) 2026-03-18 engine-flutter-autoroll@skia.org Roll Skia from ae3d36cb9e29 to 2fb5fa71eb12 (3 revisions) (flutter/flutter#183823) 2026-03-18 94012149+richardexfo@users.noreply.github.com Linux reuse sibling (flutter/flutter#183653) 2026-03-18 engine-flutter-autoroll@skia.org Roll Skia from 84a180a1fa80 to ae3d36cb9e29 (4 revisions) (flutter/flutter#183812) 2026-03-18 1961493+harryterkelsen@users.noreply.github.com fix(web): handle asynchronously disposed platform views (flutter/flutter#183666) 2026-03-17 87018443+mayanksharma9@users.noreply.github.com (Test cross-imports) Remove legacy Material import from sliver_constraints_test (flutter/flutter#183351) 2026-03-17 74057391+jhonathanqz@users.noreply.github.com Fix Android Studio pluginsPath when version is unknown (do not use 0.0) (flutter/flutter#182681) 2026-03-17 50643541+Mairramer@users.noreply.github.com Fixes animation glitch into bottom sheet (flutter/flutter#183303) 2026-03-17 ahmedsameha1@gmail.com Handle#6537 second grouped test (flutter/flutter#182529) 2026-03-17 ahmedsameha1@gmail.com Add a Clarification for the docs of suggestionsBuilder of SearchAnchor (flutter/flutter#183106) 2026-03-17 nate.w5687@gmail.com Remove obsolete null checks from style guide (flutter/flutter#181703) 2026-03-17 jason-simmons@users.noreply.github.com [Impeller] Do not delete the GL object in a HandleGLES if the handle has a cleanup callback (flutter/flutter#183561) 2026-03-17 jason-simmons@users.noreply.github.com Encode source file patches as UTF-8 in the code formatter script (flutter/flutter#183761) 2026-03-17 82673815+gktirkha@users.noreply.github.com Fix widget inspector control layout and add safe area regression test (flutter/flutter#180789) 2026-03-17 43054281+camsim99@users.noreply.github.com Reland "[Android] Add mechanism for setting Android engine flags via Android manifest (take 2)" (flutter/flutter#182522) 2026-03-17 1961493+harryterkelsen@users.noreply.github.com fix(web): fix crash in Skwasm when transferring non-transferable texture sources (flutter/flutter#183799) 2026-03-17 engine-flutter-autoroll@skia.org Roll Skia from dba893a44d7a to 84a180a1fa80 (7 revisions) (flutter/flutter#183803) 2026-03-17 brunocorona.alcantar@gmail.com Framework: Improve DropdownButton selectedItemBuilder assertion (flutter/flutter#183732) 2026-03-17 brunocorona.alcantar@gmail.com Add mainAxisAlignment to NavigationRail (flutter/flutter#183514) 2026-03-17 34871572+gmackall@users.noreply.github.com Update android triage process to not look at unassigned p1s every week (flutter/flutter#183805) 2026-03-17 30870216+gaaclarke@users.noreply.github.com Adds macos impeller new gallery transition perf test. (flutter/flutter#183802) 2026-03-17 1961493+harryterkelsen@users.noreply.github.com fix(web_ui): move prepareToDraw after raster to improve concurrency and stability (flutter/flutter#183791) 2026-03-17 rmacnak@google.com [build] Generate debug info for assembly. (flutter/flutter#183425) 2026-03-17 mdebbar@google.com [web] Fix occasional failure to find Chrome tab (flutter/flutter#183737) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC boetger@google.com,stuartmorgan@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
A couple of the style guide examples were written prior to Dart's null safety era, so this PR aims to update those examples.
Test-exempt because it only affects the
.mdfile.