It is not a huge improvement, because it does not add static safety,
for this we would need to distinguish between unresolved and resolved
expressions, as separate types.
But it is still an improvement.
1. We get to know the node that was not resolved.
Maybe not enough, in case if it was because of the enclosing
now that this node was not resolved. But still something.
2. We group this use case into one place.
Change-Id: I2e8f029e8a5fcd8ccecdd1b6bc9d78ee9eaf12a1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/184103
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
The CL to add why_not_promoted_test.dart and the CL to remove
NullSafetyUnderstandingFlag landed around the same time, so we failed
to notice the conflict between them. The fix is easy: since
NullSafetyUnderstandingFlag doesn't exist anymore (and isn't needed
anymore), we can just remove this use of it.
Fixes bot failures with the test
`pkg/analyzer/test/id_tests/why_not_promoted_test`.
Change-Id: Icec2d57d371229f103b42c5e25d49aab952adc1a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182340
Auto-Submit: Paul Berry <paulberry@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
This CL implements the core flow analysis infrastructure for tracking
reasons why an expression was not promoted. It supports the following
reasons:
- Expression was a property access
- Expression has been written to since it was promoted
I expect to add support for other non-promotion reasons in the future,
for example:
- `this` cannot be promoted
- Expression has been write captured
- Expression was a reference to a static field or top level variable
These non-promotion reasons are plumbed through to the CFE and
analyzer for the purpose of making errors easier for the user to
understand. For example, given the following code:
class C {
int? i;
f() {
if (i == null) return;
print(i.isEven);
}
}
The front end now prints:
../../tmp/test.dart:5:13: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null.
Try accessing using ?. instead.
print(i.isEven);
^^^^^^
Context: 'i' refers to a property so it could not be promoted.
Much work still needs to be done to round out this feature, for example:
- Currently the analyzer only shows the new "why not promoted"
messages when the "--verbose" flag is specified; this means the
feature is unlikely to be noticed by users.
- Currently the analyzer doesn't show a "why not promoted" message
when the non-promotion reason is that the expression is a property
access.
- We need one or more web pages explaining non-promotion reasons in
more detail so that the error messages can contain pointers to them.
- The analyzer and front end currently only show non-promotion reasons
for expressions of the form `x.y` where `x` fails to be promoted to
non-nullable. There are many other scenarios that should be
handled.
Change-Id: I0a12df74d0fc6274dfb3cb555abea81a75884231
Bug: https://github.com/dart-lang/sdk/issues/38773
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/181741
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
We now track the following additional information:
- All local variable reads and read captures (previously we only
tracked writes)
- For any conditional expression (`?:`) or if-test, the variables
written in the "then" branch
- For any logical and expression (`&&`), the variables written in the
right hand side of the expression
Tracking this information will allow us to implement legacy type
promotion as part of _fe_analyzer_shared, using the same API as flow
anaylsis, which will in turn allow a lot of front end and analyzer
code to be removed and simplified.
Change-Id: I01aaf64cefb989a4450c8e6d3a8373c1ca2b6dec
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/179980
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@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>
Adds support for pretty printing verbose annotations.
Adds support for force updating annotation texts useful for applying
the pretty printing to valid annotations.
Change-Id: I8fe9b6d2f8198bd5e160854053c8d964ef832a8d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/129710
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This handles (un)assigned state in try-statement that do not
complete normally. In this case we could create a variable model
for an unreachable state that would be both assigned and unassigned
leading to an assertion failure.
Closes#41284
Change-Id: Id4c7689bc7c614338af3542eb342c964696fca1e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/141981
Auto-Submit: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
DartType.== implementations ignore nullability if the flag is not true.
TypeSystem APIs eliminate nullability from types before doing anything.
Internally analyzer continues using actual nullability for types.
Package nnbd_migration opted into NullSafetyUnderstandingFlag.
Bug: https://github.com/dart-lang/sdk/issues/40500
Change-Id: Ifeea28c01adf1dc59ed2da675b4a62c6334d529a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134865
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
No change in functionality. Just changing the analyzer's
nullability_test.dart so that it generates the `nonNullable`
annotation for a promotion from type parameter `E` to `E&Object`.
This makes it consistent with the front end test runner behavior.
Change-Id: I9b74222257b432e361fbe46aa7d4d7070225a5e5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/133322
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This moves the five test suites for flow analysis along with the
constants test suite.
Note that a few files have formatting errors. I'll fix those in a
follow-up CL.
Change-Id: Ie9bba74c7d91e49ac6c9d3c64a96be007b6a94c6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/123680
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Previously such shared code was in the front_end package, but that
created problems because there is a lot of code in front_end that
isn't intended to be shared with the analyzer (including, notably, the
dependency on kernel).
This CL just moves over the flow_analysis logic to the new shared
package. Follow-up CLs will move over other shared logic and tests.
The end goal is that the analyzer package will no longer have a
dependency on front_end.
Change-Id: I5642d6565204422d79808ca47648462db85e442a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/123624
Reviewed-by: Jens Johansen <jensj@google.com>
This avoids the need to special case test expectations for CFE in
pkg/front_end/test/flow_analysis/reachability/data/never_return_type.dart.
Change-Id: Ib754a76c96e73c8183b5ff10a2e7d2908e653a31
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/123420
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This should make it easier to verify that the CFE implementation is
correct.
Note that this effort encountered a few bugs in the analyzer
implementation, which are marked with TODOs. I will fix them in
follow-up CLs.
Change-Id: Ic164a1cf214b5730f848b17db2838c29d25b00d0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122850
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
These data structures are only used for testing (and are not even
created in normal production use). Add "ForTesting" to their names so
that we are less likely to use them by accident.
Change-Id: Ic719d66089a692362957e257c9bbb2f632bfd174
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122980
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Previously, we were using `DartType.toString` to check test
expectations, but `DartType.toString` currently doesn't show
nullabilities. This isn't currently a problem because at the moment
all the type promotion tests use non-nullable types, but I will soon
be adding type promotion tests that use nullable types.
This CL fixes the problem by using `TypeImpl.toString` and passing in
`true` for the optional argument `withNullability`.
Change-Id: I6a2c6057c27c9205657143aa56088cc30a6510d9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122822
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This was already working, it just needed some updates to the test
infrastructure so we could test it properly.
Change-Id: Ie838fb50cf90aabd19c6e0c637df546ddcda16d7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122584
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
When promoting a type parameter, we need to create an intersection
type (e.g. "T & int"). Such a type is represented in the analyzer and
the front end as a type parameter type pointing to the same type
variable, but with a different bound.
Change-Id: I1655f9242d913ca958c279cc80c3f6329f6b396d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122581
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Previously, in the flow analysis reachability tests, we only annotated
a node as unreachable if it wasn't "covered" by a parent node that was
already marked as unreachable. This made the tests more compact, but
it meant that the testing was less complete, because it meant that we
weren't verifying that the nodes inside of unreachable nodes were also
unreachable.
This CL changes the tests so that we mark every unreachable node as
unreachable, with one small exception: for an expression statement, we
don't mark the expression; we just mark the statement as unreachable,
and we have an assertion in the data extractor to verify that the
expression's reachability matches that of the statement.
Change-Id: I92454c72e9704b34e2dbafb9f5f19a8ee31f8f15
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122583
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>