I have a Flutter application that was written before null safety was introduced to Dart.
I heard of a Null Safety Migration Tooling. How could I use it to convert my code from pre-NNBD to non-nullable by default?
With sound null safety variables are 'non-nullable' by default: They can be assigned only values of the declared type (e.g. int i=42 ), and never be assigned null . You can specify that a type of a variable is nullable (e.g. int? i ), and only then can they contain either a null or a value of the defined type.
You can enable the experiment using the '--enable-experiment=non-nullable' command line option.
You need at least Dart 2.9
. At the time of writing, you can use 2.9.0-10.0.dev
, i.e. put the following SDK constraint in your pubspec.yaml
:
environment:
sdk: ">=2.9.0-10.0.dev <3.0.0"
/*?*/
& /*!*/
)The /*?*/
hint means that something should explicitly be nullable. /*!*/
means that something should be non-nullable.
You can already add these hints manually before using NNBD. Otherwise, you can add them with the tool during migration (see below).
There are ?
, !
, and _
edits. ?
makes a type nullable after migration. _
makes it non-nullable (meaning no character is changed because non-nullable is the default). !
makes an expression non-nullable.
These edits are previewed in the migration tool.
Dart 2.9
comes with an nnbd_migration
package.
This tool can be used to interactively convert code to NNBD.
I will cover the migration steps described in the README and try to simplify them:
Go to your project in your command line and run pub get
or flutter pub get
when using Flutter. (Note that at the time of writing, the Flutter SDK is not yet supported)
Run dart migrate
. (Note that at the time of writing, I need to use --skip-pub-outdated
)
Wait for analysis and migration to complete and then view migration suggestions by opening the URL you see in the command line in your browser (of format http://localhost:<port>/<project path>?authToken=<token>
). You should see something like this:
Select a file to begin with. It should look something like this:
View the proposed edits on the right (matching the highlighted characters):
If you find edits that you think are not correct, find the root cause in Edit Details:
You can scroll down to trace the root expression that led to the edit proposal. When you find some wrong decision somewhere along the way, you either Add /*?*/ hint
or Add /*!*/ hint
as explained above (you can also add them manually in your IDE).
If an edit looks right, you do not need to do anything.
You will probably need to Rerun From Sources
a lot. This will apply the new hints you added and any other edits you made to the code and generate new edits. Do this until all edits look right.
Now, you might see your hints highlighted in red, which means that the tool will remove the hints and convert them to either ?
, !
, or blank.
You should probably save your project at this point (e.g. git commit
).
Note: at this point, your code has a bunch of added /*?*/
and /*!*/
hints and has not yet been migrated.
Apply Migration
: this will apply the proposed edits and remove all hints.
Probably leave the migration tool open for now.
Now, you do not have any hints in your code anymore.
Test your project (pub get
or flutter pub get
and then run).
If something went wrong, it is helpful to have left the migration tool open. Potentially, you want to revert your version to before the migration and repeat the steps.
Success! Your project is now null safe 🙌🏽
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With