The values discardCondition, discardElse, discardIf, discardThen, and
removeNullAwareness are all variants of dead code removal and there's
no reason to distinguish them.
Change-Id: Id55035486e07f52e6ef7b5a2485dcb0cadb153e1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/142060
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Previously, when handling an override such as:
abstract class A {
int/*?*/ f();
}
class C implements A {
f() => 0;
}
we would create a union edge between the implicit return type of C.f
and the explicit return type of A.f. This was a problem because
nullability information can propagate bidirectionally through union
edges, so it could result in types unnecessarily becoming nullable,
e.g.:
abstract class A {
int/*?*/ f();
}
abstract class B {
int f(); // Should not need to be made nullable
}
class C implements A, B {
f() => 0;
}
This CL fixes the problem by just making ordinary unidirectional edges
for overrides involving inferred types.
Change-Id: I63a5f1f640b5543fcf39304087592e984aa66694
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/141853
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
Previously, null check hints were only affecting the behavior of
EdgeBuilder, which meant that we handled simple cases like:
int f(int/*?*/ x) => x/*!*/;
(because the EdgeBuilder wouldn't build an edge from the type of `x`
to the return type of `f`, so the return type of `f` would be
non-nullable int, and hence the FixBuilder would insert a `!` in order
to prevent an error).
But if there were some *other* reason for the destination type to be
nullable, then no `!` would get inserted.
This CL adds explicit logic to the FixBuilder to ensure that a `/*!*/`
hint causes a `!` to be inserted whether it's necessary or not.
Change-Id: I283bb9793d8d01408333f5b56562286bf19d8773
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/140904
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
The only purpose of these interfaces was to enforce an artificial
separation of concerns between the methods of Variables used by
NodeBuilder and EdgeBuilder; this separation was never really very
useful, and it's getting in the way of adding features to FixBuilder.
It seems better to just use the Variables class directly everywhere.
Change-Id: I7b9c6c08c09a466bbcc1e3f72f9aa05db0d1a7b1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/140884
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
Previously, when analyzing code like:
int f() {}
We assigned a NullabilityNodeTarget for `int` that simply said it was
the return type of the element for `f`; the location of `int` in the
source code was lost. With this CL, we produce the same target, but
we preserve the location information.
Change-Id: Ibfe11485aedf208a39947e5a4903b4fa738e86a7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/139954
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Breadth first is theoretically slightly slower due to less locality of
reference, however it has the benefit of ensuring that the user sees
the shortest possible trace when investigating the cause of a change.
Without this change, it's possible to get some really confusing
traces, e.g. a trace suggesting that a type in some
previously-migrated library is nullable due to a cause within the
library currently being migrated.
This CL also adds tracking of why a node was determined to have
non-null intent, which I plan to expose to the user in follow-up CLs.
Change-Id: I43025ca0ab825d178a28555f85ad9eea43eadfe9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/139140
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Previously, we only included edges in the trace view, which resulted
in a lot of missing information. Generally the reasoning process
looks like "type at A is nullable because of an expression at B, which
propagates nullability from a type at C, which is nullable because of
an expression at D, etc." This change makes the trace reflect that
reasoning process better.
Change-Id: I27d1b7aac736529b6f1fa2f7be8dea0d3eca9a6c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/139064
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This establishes the base functionality. A lot of follow-up work is
needed from here:
- Each trace should have an entry at the top of it pointing to the
thing that was made nullable.
- The source code links in traces don't include lengths, so we can't
highlight whole identifiers when the user clicks on a link.
- Description strings are currently generated by running toString() on
the individual nullability nodes and edges, resulting in long-winded
and useless descriptions.
Change-Id: Ibb370bae6bedc7a8c86092462785023002a48ac3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/138481
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
The principal cause may be displayed by invoking the "postmortem" tool
using the "trace" subcommand, followed by the id of the node for which
a trace is desired.
Change-Id: I5868b4bc979320bb46698b02c7b43b317205c487
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/137429
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>