This is a reland of fd2a6c6815
Original change's description:
> Flow analysis: Track expression variables separately from promotion info.
>
> Previously, we used a single class hierarchy, ExpressionInfo, to store
> all the information that flow analysis needs to know about a variable,
> including:
>
> 1. What is known about the program state if the expression evaluates
> to true/false
>
> 2. Whether the expression is a `null` literal
>
> 3. Whether the expression is a reference to a variable.
>
> However, in order to address
> https://github.com/dart-lang/language/issues/1274 (Infer
> non-nullability from local boolean variables), we'll need #3 to be
> tracked orthogonally from #1, so that when a local boolean is referred
> to later, we can track information of type #1 and #3 simultaneously.
>
> However, it makes sense to keep #1 and #2 in the same data structure,
> because future work is planned to represent them in a more uniform
> way, as part of addressing
> https://github.com/dart-lang/language/issues/1224 (Using `if (foo?.bar
> == somethingNotNull)` should promote `foo`).
>
> Change-Id: I432f6e2e80543bb1d565b49403180c520eef66a5
> Bug: https://github.com/dart-lang/language/issues/1274
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175008
> Reviewed-by: Johnni Winther <johnniwinther@google.com>
> Commit-Queue: Paul Berry <paulberry@google.com>
Bug: https://github.com/dart-lang/language/issues/1274
Change-Id: I002adbde782887def50dc80ab6673411b321c341
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175362
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Emphasize that the operation is going away,
and mark constructor as deprecated.
TEST= Refactoring+deprecation only, covered by existing tests.
Change-Id: I82aa044cd2cf7bf347b624371399f44bda8f4a07
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/173261
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Nate Bosch <nbosch@google.com>
Previously, we used a single class hierarchy, ExpressionInfo, to store
all the information that flow analysis needs to know about a variable,
including:
1. What is known about the program state if the expression evaluates
to true/false
2. Whether the expression is a `null` literal
3. Whether the expression is a reference to a variable.
However, in order to address
https://github.com/dart-lang/language/issues/1274 (Infer
non-nullability from local boolean variables), we'll need #3 to be
tracked orthogonally from #1, so that when a local boolean is referred
to later, we can track information of type #1 and #3 simultaneously.
However, it makes sense to keep #1 and #2 in the same data structure,
because future work is planned to represent them in a more uniform
way, as part of addressing
https://github.com/dart-lang/language/issues/1224 (Using `if (foo?.bar
== somethingNotNull)` should promote `foo`).
Change-Id: I432f6e2e80543bb1d565b49403180c520eef66a5
Bug: https://github.com/dart-lang/language/issues/1274
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175008
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Previously, the unit tests for flow analysis re-used the logic from
the _WrappedExpression class, which uses
FlowAnalysis.forwardExpression rather than
FlowAnalysis.parenthesizedExpression. As a result,
FlowAnalysis.parenthesizedExpression wasn't being unit tested.
Change-Id: I1905808fd3a7788cb15d28c82d773369c061da59
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175164
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Previously, we didn't have a unit test to verify that variable
captures in nested contexts are propagated to enclosing contexts.
Change-Id: I579bce6d07f61119f44259f1fbf1da7f0800adde
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175102
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
The FlowModel._freshVariableInfo field was an optimization with
dubious benefit (it avoided a single allocation when seeing a variable
for the first time). And it is getting in the way of changes I have
planned for https://github.com/dart-lang/language/issues/1274 (which
will require each fresh variable to be allocated different
information).
Removing FlowModel._freshVariableInfo means that now we have a call to
VariableModel.fresh() whenever we see a variable for the first time,
so we can take advantage of this to elimiate the
VariableModel.initialize() method, and simply allocate the
VariableModel in the initialized state when it's appropriate to do so.
Change-Id: I4b6f7d004fff72eaa4025fdf79e9ca29a81d7f96
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/174566
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
In preparation for some flow anaylsis work I intend to do this month,
I want to make the flow analysis unit tests easier to understand and
maintain. This CL creates an AST representation that models just
enough of the Dart language to be able to do flow analysis testing, so
that when reading or writing a flow analysis unit test, instead of
having to remember the correct sequence of calls to FlowAnalysis to
model a given construct, you can just create a mini-AST representation
of the given construct and pass it to the flow analysis test harness.
The mini-AST model for expressions contains methods that can be used
to build larger expressions out of smaller ones, so a lot of code can
be modeled compactly. For example, to create a mini-AST model of the
statement `x = y && z == null;`, call
`x.write(y.read.and(z.read.eq(nullLiteral()))).stmt`.
Change-Id: I11e3882078fdc5797176019398db48011232cf35
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/174560
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
It started as a way to speed up IgnoreValidator, becaus computing
uniqueName as a concatenation of 'runtimeType' and 'name' was expensive.
We solved it in a better way, but I think this change is still useful.
Change-Id: I7d3cb8c91f4ca27a0aa3b93f8572cf12c6757bae
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/174322
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
The creation of the shorting stop expression was done lazily
in NullAwareExpressionInferenceResult.expression. Since the shorting
calls flow analysis to stop null promotion doing this out of order
let to inconsistent flow analysis state.
This CL introduces an `inferNullAwareExpression` the allows to
caller to continue the shorting (if in an opt-in library). The
inferExpression method, used everywhere else, stops any shorting
currently in progress.
Closes#43275
Change-Id: I448163e29bdb0de8e493e5c62aa0474d0c9a593f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/173729
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This CL fixes the wrong message, so - when in the process of fixing
the package nnbd settings - one gets the correct message, mentioning the
right packages and no longer mentioning the fixed ones.
Change-Id: Ied26094055e56b44dfdd2e942b98eb9e1e7968fb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/170423
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This fixes the issue of the error not going away, but can (see added
test) give a wrong error message when in the process of fixing the issues.
A follow-up CL will (try to) correct the wrong error message.
Change-Id: I3547fe5fb5cfd179897996029a00a4995a967e54
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/170422
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
The `bool` return types were added to `FlowAnalysis` methods
`nullAwareAccess_rightBegin`, `ifNullExpression_rightBegin`,
`equalityOp_end`, and `isExpression_end` in September as part of an
effort to fix mixed-mode unsoundness loopholes by having the front end
throw exceptions if "impossible" conditions arose. We later decided
that we would prefer to allow these conditions to arise without
generating exceptions, because that makes it easier for the user to
write defensive mixed-mode code. So the booleans stopped being used.
This CL removes them entirely.
Change-Id: Ia0ff91a22fe79c2df1dea89bbb286c84a3603821
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/170125
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
The added messages handle the situation in which null safety is enabled
by default but is turned off either by language version or by explicitly
passing --enable-experiment=no-non-nullable
Change-Id: Iec43daf19a80f555e838635c83542fdb243b8ed4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/168647
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
- make sure nested blocks scopes are visited
- make sure variable definitions do not leak beyond block scopes
- properly collect scopes for loops, if statements, constructors
- add calculation of fileEndOffsets for blocks
- save block file offsets to dill
- update binary format version
- change kernel readers and writers to read and write block offsets
- change vm readers to read and block offsets for new version
- add missing fileOffsets and fileEndOffsets on functions for
late fields
- add missing fileOffsets and fileEndOffsets on functions for
extensions
- add errors on failures to find scope
- find libraries for private fields correctly
- add more expression compilation tests
- add test to verify fileOffsets and fileEndOffsets are set for
SDK summary (will add full dill tests later)
Closes: https://github.com/dart-lang/sdk/issues/40278
Related: https://github.com/dart-lang/sdk/issues/34942
Change-Id: I5bc1bb645543045b689d8d61069ee77dc4ee9025
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/167541
Commit-Queue: Anna Gringauze <annagrin@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
The recent changes to `for` statements were necessary to ensure that
if a `for` statement causes type promotion due to an unreachable
branch without type promotion joining a reachable one with type
promotion, the type promotion would still happen properly even if the
top of the `for` statement was itself unreachable. There is no need
for a similar change to `for each` statements, because they are simple
enough that this situation cannot arise. But it's still worth making
the corresponding change for consistency.
Bug: https://github.com/dart-lang/sdk/issues/40009
Change-Id: Idabf7745f04a99152e688bf050a8d80e07b004e2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/166520
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>