To avoid inserting unnecessarily complex casts, we want to normalize a
type like `void Function<T extends Object?>()` to the equivalent `void
Function<T>()`.
Change-Id: Ied10e7735511b732eaeca027e621b4ef6997df59
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/133820
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This eliminates a lot of really noisy boilerplate in the upcoming
FantasyRepo implementation. The test only verifies that the pathway
works, we rely on MultiFutureTracker working to actually restrict
properly.
Change-Id: Ia88d0b24dd739ab1cd4a661325214395bf37eef3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/133742
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Janice Collins <jcollins@google.com>
Previously, FixAggregator provided one NodeChange-derived class for
each possible kind of fix; if multiple fixes had to be made to a
single AST node, its client (FixBuilder) was required to nest them in
the appropriate order. FixBuilder accomplished this by carefully
controlling the order in which it decided on fixes. Unfortunately,
this careful control of order is becoming burdensome for FixBuilder to
maintain.
With this change, the class hierarchy of NodeChange mirrors the class
hierarchy of AstNode, with different fields for each possible kind of
fix. This means that FixBuilder can decide on fixes in whatever order
is convenient.
Change-Id: I1c79cfc37b6289051b3927c67867b77a1dbb5ebf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/133541
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
I realized that I can use the same "pass through" infrastructure for
these kinds of edits. This should help prepare for a future CL in
which we can aggregate together more complex changes, such as
introducing an "as" cast at the same time as changing `?.` into `.`.
Change-Id: Ie3af07a3563c44d62d4ed34d2a477eef6fae358f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/133540
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
Since https://dart-review.googlesource.com/c/sdk/+/133422 has
introduced the possibility that a node previously marked as
non-nullable would later be marked as nullable, we need to make sure
that doesn't happen for types that have been explicitly marked as
non-nullable using a "/*!*/" hint, or types that are non-nullable in
an already-migrated library.
This required refactoring the state of nullability nodes slightly.
Nodes can now be in six states:
1. Non-nullable (previously called "undetermined")
2. Non-nullable, with non-nullable intent (previously called
"nonNullable")
3. Nullable
4. Nullable, with non-nullable intent (previously indistinguishable
from 3)
5. Exact nullable
6. Exact nullable, with non-nullable intent (previously
indistinguishable from 5)
To allow all these states to be distinguished, we separate the state
into two orthogonal parts: a "nullability" part and a "non-null
intent" part.
Change-Id: I588a2e63eaa76e3992fdfbaaa2e8b212cc1f60d1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/133440
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
It didn't wind up being used, and its presence limits our ability to
modify the graph propagation algorithm (which I plan to do in a
follow-up CL).
Change-Id: I48a9b879f25295075e8d95eb3fb0185839303957
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/133425
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
Shifted some minor things around in the design as well -- particularly
the symlink is moved to being owned by the workspace as not all
workspace implementation will create symlinks in the original directory.
I've also dropped most of the public interface to FantasyWorkspace.
Will add that back in when I'm more sure what it will be.
Change-Id: I19d1b1c8ad4063868ff7c10869c4561d4db64bf2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/133435
Commit-Queue: Janice Collins <jcollins@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
This prevents a non-null assertion in a callback function from marking
the parameter type as non-nullable, if that would make the callback
function fail to meet the requirements of its use site. For example,
when migrating:
f(List<int/*?*/> myList) => myList.map((int x) => x + 1);
We previously would produce:
f(List<int?> myList) => myList.map((int x) => x + 1);
(Which would fail immediately due to the callback `(int x) => x + 1`
not accepting `int?`). We now produce:
f(List<int?> myList) => myList.map((int? x) => x! + 1);
(Which only fails if there is actually a null value in the list,
matching the behavior of the code prior to migration).
Addresses another manifestation of
https://github.com/dart-lang/sdk/issues/38699.
Change-Id: Iffe9fbdace00ff1edea0f6d125c86b06fad7bbcb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/133423
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
This serves two purposes:
1. It makes it easier to be confident that we're resetting the
necessary state when re-running graph computation in
`NullabilityGraph.update`.
2. I'm planning some changes to the graph propagation algorithm (in an
upcoming CL). Having the propagation state separate from the rest
of the graph state will make it easier to reason about these
changes.
Change-Id: I5e101bbce6e5ad382dd754bfbb9b72e20df23fd1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/133337
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
The visitSimpleIdentifier method was failing to return a DecoratedType
for the case where the identifier was `void`.
In practice this didn't matter, since the only time the type returned
from visitSimpleIdentifier is used is when the the identifier is used
as an expression, and `void` can't be used an expression (i.e. `var
voidType = void;` is illegal).
Nonetheless, it's nice to silence the warning, and it seems like it
increases safety to return a value from visitSimpleIdentifier in all
cases.
Change-Id: I239b98b9e5932195e6884738728d26d86c6ab519
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/133336
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
When migrating, we'll need to change some null-aware property accesses
and method calls to non-null-aware (due to the fact that the receiver
is non-nullable, or due to the new `?.` shortcut rules), so when
migration re-resolves, it will need to be able to override
resolution's determination of whether a given property access or
method call is null-aware.
Change-Id: I411f43fb937431e757d4dd9b968874db84158e47
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/133240
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
The new FixBuilder infrastructure has the ability to remove dead code
either by commenting it out or by deleting it entirely. Previous to
FixBuilder all we could do is comment it out. My intention when
landing FixBuilder was to keep this behavior so that we could make a
deliberate switch at a later time (when everything was well tested).
But I accidentally set the flag wrong for some code paths, and so
currently we delete code.
This has caused some bugs in the preview tool (which I will file in
the issue tracker shortly). In order to avoid causing problems for
members of the language team who intend to try out the tool this week,
I'm switching back to "comment code out" as a temporary measure.
Change-Id: I0ca8674b6a8d9ab23cf6726a15fa3dc1919085b4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/133081
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Fixes https://github.com/dart-lang/sdk/issues/40181
As long as its possible to union a bound to a node involved in a
substitution, its possible to make a bound "exact nullable." This
implies that all instantiations of that type must be with a nullable
version of that parameter, which is not desirable for any program.
This marks new failing tests due to
https://github.com/dart-lang/sdk/issues/39404. However, re-running this
on package:collection resulted in a better migration result (no issues
from the non-nullable inferred types being made explicit or not). So my
personal feeling is this is worth landing now, however, we could land it
later.
Change-Id: I63479c5e4edecf301c27e21b5ba57508d625e8ab
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/132748
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Mike Fairhurst <mfairhurst@google.com>
When migrating an unnecessary "if" test like this one:
if (x != null) {
Do something;
} else {
Do something else;
}
We make two modifications to the user's file:
- Drop "if (x != null) {"
- Drop "} else { Do something else; }"
With this change, the first modification has a description of
NullabilityFixDescription.discardCondition and the second has a
description of NullabilityFixDescription.discardElse. Previously,
both modifications had a description of
NullabilityFixDescription.discardElse, which was confusing.
Change-Id: I6407d7616b7a2d2c8af853ab48c3480959c4fdb9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/132682
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>