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>
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>
We should consider the nullability of the right hand side of a typedef
to be "never", since a `?` is not allowed on there. Instead, we
should allow each use of a typedef to have its own independent
nullability.
Fixes a bug wherein we would erroneously migrate code like this:
typedef F<T> = int Function(T);
F<String> f = null;
Into the following:
typedef F<T> = int Function(T)?;
F<String>? f = null;
(Note the bogus `?` after `int Function(T)`).
Change-Id: I8535645303fc644c73617684b8bb3488462589ee
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/136900
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
This CL fixes several minor bugs:
- In info_builder.dart, we were trying to apply SourceInformation from
the defining library to all its parts.
- In NnbdMigrationTestBase, we were trying to fully migrate each file
before processing any other files. We need to prepare each input,
then process each input, then finalize each input.
- In NodeBuilder, we were failing to send part file sources to
NullabilityGraph.migrating(). As a result, methods declared in part
files were being treated as already migrated, so they were getting
the wrong kinds of nullability nodes.
- In _ProvisionalApiTestBase, we were sometimes visiting parts before
discovering what libraries they were part of, causing inconsistent
resolution results.
I'm hoping this will be sufficient to address
https://github.com/dart-lang/sdk/issues/40670.
Change-Id: I07d693b31b6cf64bc6f72126f5ef4792b29e5029
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/136521
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Usually when migration removes dead code it can just delete it
(e.g. because it's removing a statement from a block and blocks can
contain any number of statements). However, in certain contexts dead
code must be replaced with something else, such as an empty statement.
Change-Id: I65faf017897215d750395dc78a2bf8a157d8dce0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/136441
Reviewed-by: Janice Collins <jcollins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Tests currently pass, so we can close that bug. However, if for some
reason it becomes an issue such that these tests fail, they will link to
a bug with detailed info on a potential cause.
Bug: 40625
Change-Id: I212eb5401622a189de4998247b0ff521077e30e3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/135763
Reviewed-by: Paul Berry <paulberry@google.com>
The target of a property access can be null if it is a cascade. If that
access is then modified, fix aggregator gets a NPE. This issue is not
true for index & method calls, same fix applies.
Change-Id: I98eac3c8f7eba5300b30ff366ee227430726440c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/135963
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Mike Fairhurst <mfairhurst@google.com>
A compound node represents a logical OR ("this node is nullable if and
only if one or more of its components is nullable"). Therefore, if
*all* of the components of a compound node have non-null intent, we
should consider the compound node itself to have non-null intent.
This fixes a problem that was preventing the migration tool from
respecting a "/*!*/" hint applied to the type parameter of a typedef.
Change-Id: Iec2f9d6968378707ba692be7b97f750cf53a8b85
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/135786
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
There were two problems:
1. An info object isn't being properly passed to
NodeChangeForExpression, causing an assertion failure during the
FixAggregator stage. I've modified the assertion check so that it
happens earlier, during the FixBuilder, so that the exception is
caught by permissive mode logic and doesn't cause a hard crash.
I'll work on fixing the assertion in a follow-up CL.
2. The hack described in https://github.com/dart-lang/sdk/issues/40536
was causing a bogus assertion failure in
_PassThroughBuilderImpl._checkParenLogic. I've weakened the
assertion slightly so that for now, the hack won't cause trouble.
See the issue for more information about what's happening--this
should be cleaned up eventually but it's probably not high
priority.
Bug: https://github.com/dart-lang/sdk/issues/40533
Change-Id: Iee832fbd07e54b02d2c52f79a097ff9d973cda9a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134980
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Under NNBD rules, certain function literals have their types inferred
as `Object?` instead of `dynamic`. We need to add explicit `dynamic`
to prevent follow-on errors if those parameters are used in a dynamic
fashion.
Change-Id: I12bfd3a3da2bda1ae11b01a5d029dbea3d512cb6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134567
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Previously, if a function literal was used in a context where a
function returning non-null was expected, but the function literal
might return null, the migration tool inserted a cast that was
guaranteed to fail. Now it propagates non-null intent into the
function literal, so that the appropriate null checks happen inside
the function literal.
Change-Id: Ia62d18bc3b9955e84b09b846ea913607b305677d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134504
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This CL extends ElementTypeProvider so that it also tracks type
parameter bounds. This allows the FixBuilder to reason correctly
about the what generic function types will look like after migration,
and that in turn prevents it from trying to add unnecessary casts.
Change-Id: I3c909a3b5ba14bf9f2aad4e58d0981c1b7b5bdd2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134412
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
We now track decorated type parameter bounds similarly to how we track
ordinary type parameter bounds in the FixBuilder, by having a single
static instance of a DecoratedTypeParameterBounds class that keeps
track of the mapping.
Change-Id: I49196e8a506ca8765857b3d47a355b7aaaa1918e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134411
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Previously, each piece of analyzer code needed during the FixBuilder
stage of migration needed to use the ElementTypeProvider interface to
access element types (rather than reading the types from the elements
directly), in order to ensure that the proper post-migration types
were used when building fixes. This required a lot of plumbing, and
there was a high risk that we would accidentally fail to use the
indirection mechanism in a key location and access the elements
directly.
This CL changes the approach so that the ElementImpl classes
themselves are responsible for indirecting through
ElementTypeProvider. This means that we can back out all the
plumbing, and there is no risk of accidentally failing to use the
indirection mechanism.
Change-Id: Ic1a0acc37f0350fc13b487f73fc1ad5225d7a090
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134360
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
When adding a cast to a function expression like `() => null`, we need
to add parentheses, so that we produce `(() => null) as Type`, rather
than `() => null as Type`, which makes the cast appear to apply to the
function body expression.
Change-Id: Ib5ae93df5b840a832c10941e47fa092a4f764eea
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134044
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
This required adding logic to the `TypeParameterType` case of the
`toFinalType` function, so that we look up the decorated type of the
type parameter bound, and convert it to a final type as well.
(Previously we were just using the bound stored in the element model,
which was in many cases the bounds from prior to migration, and hence
it was a `*` type so it behaved as though it was non-nullable).
This required moving `toFinalType` into the `Variables` class so that
it could look up the decorated types of type parameter bounds.
Fixes#40355.
Change-Id: I53c2636aef6954500589e924b9755a297c2b30f9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134061
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>