As discussed in
https://github.com/dart-lang/sdk/issues/44031#issuecomment-720967259,
we want to encourage users to publish null safe packages with an SDK
min constraint matching the SDK version that was used for the
migration, e.g. `2.12.0-18.0.beta`. However, we also want to make
sure that users doing migration via internal, dev, or bleeding edge
builds publish their null safe packages don't wind up inadvertently
publishing packages that are un-resolvable with the latest beta SDK,
so if the user is on one of those versions, we'll set their SDK min
constraint to `2.12.0-0`.
And of course, once the feature ships to stable, we'll want users to
publish their null safe packages with an SDK min constraint matching
the version in which null safety shipped to stable.
This CL implements all of that functionality, and tests it by
overriding the `version` file in the analyzer's mock SDK.
Change-Id: Ib9ed97e691271da0ed391a6c1a5fe209aa959dce
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/170380
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Previously, when analyzing a call to an iterable method that could
potentially be transformed into an `OrNull` extension, such as:
allMatches(str).firstWhere(..., orElse: () => null);
the migration tool would erroneously identify some subexpressions of
the call target (`str` in this example) as the argument supplied to
`orElse`, resulting in a crash.
This CL fixes the logic so that we use an `identical` check to verify
when we are looking at the argument to `orElse`.
Fixes#43956.
Bug: https://github.com/dart-lang/sdk/issues/43956
Change-Id: I2f4a0e81becf789cab5334d4926e014bda2772f4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/170162
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Currently the migrator can add `@required` from the preview, which will crash
the preview upon rerunning, if package:meta is not imported.
This change instead adds a /*required*/ hint when meta is not imported.
Additionally, /*required*/ is understood by the migrator just as if it were
`@required`.
Fixes https://github.com/dart-lang/sdk/issues/43751
Change-Id: I1ea532246b956feacedd179146372b13c65003df
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/169900
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
In the beta release, we plan to recommend that people set their
pubspec SDK constraints to `>=2.12.0-0 <2.12.0`, so this change
updates the migration tool to have that behavior.
In the second beta release we'll change switch the upper bound to
`<3.0.0`.
Change-Id: Ib90e893bebaebea968b19e7de663cbbbca570f84
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/169143
Reviewed-by: Samuel Rawlins <srawlins@google.com>
This was causing visual clutter by making informative regions offset
from regular code. Worse yet, there was a "double vision" effect
because the top of the underlying non-offsetted text could sometimes
be seen behind the informative region overlay.
Change-Id: I206c74b3d91f305a21494b767ec27f396a8513b0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/169700
Reviewed-by: Samuel Rawlins <srawlins@google.com>
With this change, the functionality of changing iterable method calls
such as `.firstWhere` into extension method calls such as
`.firstWhereOrNull` is working well enough that I think we can switch
it on.
We don't update the pubspec properly yet; that will be addressed in
follow-up CLs.
Change-Id: I758332e9752b12d399ecb5c70cf37bbc8da77d6c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/168988
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
We don't want inserted lines to receive their own line number for two reasons:
- It makes the line numbers displayed by the migration preview fail to
line up with the line numbers in the user's editor (since the lines
haven't been added yet)
- It makes navigation links within the migration tool point to the
wrong place, since these links are computed based on analysis of the
pre-migration code.
So instead, we supply a line number string of `(new)` for inserted lines.
This required refactoring the algorithm for
`UnitRenderer._computeRegionContent` a bit. Now, instead of trying to
accumulate the output HTML string all at once, we produce it one row
at a time, first accumulating the line text in a StringBuffer, and
then once the end of the line is reached, attaching the line number to
form a table row. Then we join together all the rows into a table
when we're done.
Change-Id: Ie18632186ddd0f4f5f33d4da41b4943759699e1f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/168987
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Previously UnitInfo.regions contained just information about edits
that we wanted to alert the user about; it didn't contain information
about unimportant edits like adjusting whitespace.
This caused problems when trying to make complex edits (like those
necessary to transform a `.firstWhere` call into a `.firstWhereOrNull`
call) because it interfered with UnitRenderer._computeRegionContent's
ability to properly compute file offsets.
So we now include all edits in UnitInfo.regions, and we distinguish
the unimportant ones by seeing that their `kind` and `explanation`
fields are `null`.
To ensure that important edits never wind up with `null` values for
these fields, we add assertions to the `NullabilityFixDescription`
constructor.
Change-Id: I89928150eb507524222d03acfae0b4770363443c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/168985
Reviewed-by: Samuel Rawlins <srawlins@google.com>
The method we use to rename method calls to Iterable
(e.g. `firstWhere` -> `firstWhereOrNull`) causes a pair of consecutive
AtomicEdit objects to be generated: one to remove the old name
followed by one to add the new name. This was causing
InfoBuilder._explainUnit to update its output offsets incorrectly,
because it waited until after processing all of the AtomicEdit objects
pointing to a single source offset before updating the output offset.
What it needs to do instead is update the output offset (in the
variable called `offset`) after processing every single AtomicEdit.
Change-Id: I8ad51e20d4021c62c45542cec7f0f54a9ff3cf26
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/169000
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This logic allows us to migrate code like this:
int firstEven(Iterable<int> values)
=> values.firstWhere((i) => i.isEven, orElse: () => null);
Into:
import 'package:collection/collection.dart' show IterableExtension;
int? firstEven(Iterable<int> values)
=> values.firstWhereOrNull((i) => i.isEven);
Rather than the default behavior, which would migrate it to:
int? firsteven(Iterable<int?> values)
=> values.firstWhere((i) => i!.isEven, orElse: () => null);
(The new migration is far superior because it doesn't require the
input iterable to accept null).
This functionality is disabled at the moment, because:
- The changes it makes don't show up properly in the web preview.
- The pubspec is not yet properly updated.
I will address these issues in follow-up CLs and then enable the
feature.
Change-Id: I96f3b12d682c586631920b38406bad6aa3f4789e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/168500
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
The output the migration tool generates when the web preview is
disabled shows a complete diff of all changes the tool will make, so
it's really a misnomer to call it a "summary".
Change-Id: I8c7d9f9870bf8beffb62f1d10d36a65b66c32657
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/168381
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
The file might be edited in one of a few ways, depending on what it contains.
Previously we read and edited pubspec, which is also YAML, so this
implementation borrows a lot of that, and renames several "pubspec" elements to
be "yaml" elements.
I try to cover in tests various odd existing analysis_options.yaml situations,
so that we try to never crash, or corrupt on weird input here.
Fixes https://github.com/dart-lang/sdk/issues/43806
Change-Id: Ifc57d583e98d798fd7bca748bbe4afef272edab5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/167862
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
This adds some technical debt in form of using writeOrReadElement in
clients, which can be paid incrementally by migrating these places to
handling assignment like expressions one by one. Doing it all in one
CL was too much. But now the underlaying AST resolution will be
sound.
In the next breaking change we will remove
setAssignmentBackwardCompatibility(), so stop setting elements/types
for assignment targets.
Change-Id: I11626876cfed25653edb0cc18544aba51cef5965
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/165622
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This CL unblocks the internal SDK roll by restoring the migration
tool's `MigrationCli.addCoreOptions` method (which is currently used
internally). It also adds a replacement, `MigrationCli.options`,
which is more robust because it allows the client to choose which
options to include and which options to exclude.
Once this CL has rolled in, I'll update the internal code base to use
the new `MigrationCli.options` method and then remove the deprecated
`addCoreOptions` method.
Change-Id: I3ddbd935c3858c3302a2ad2b825b97df96249043
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/167443
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Rather than produce an error immediately upon encountering an
alredy-migrated library, we simply skip processing it; this causes its
elements to be added to the nullability graph on demand, just like for
already-migrated dependencies.
We still check for the possibility that *every* file in the user's
package has already been migrated, and issue an error if so (rather
than just doing nothing); this should help avoid user confusion if the
user tries to re-migrate an already-migrated package.
Bug: https://github.com/dart-lang/sdk/issues/42308
Change-Id: I8dd81a9c6ff2bb23ede91e89d1152bd7726dec32
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/167202
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
The packages 'analyzer' and 'nnbd_migration' tightly depend on each
other via MigrationResolutionHooks. I will publish analyzer 0.40.4
shortly after this CL lands.
Change-Id: I6f5e51f88e0020a1674ffb251712658e896170e7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/164900
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>