Commit Graph

141 Commits

Author SHA1 Message Date
Paul Berry e3443b9f53 Flow analysis: implement "why not promoted" for binary/unary operator target.
Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: If464a54bdb63fc661db312df5dc10f108049286a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/196240
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-04-22 12:21:46 +00:00
Paul Berry b6fbee21d9 Flow analysis: additional "why not promoted" test cases.
These test cases already work properly, but they weren't previously
covered by tests.

Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: I4fc6506230af203a361631afc542e0db08bd6f27
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/196106
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2021-04-21 13:38:20 +00:00
Konstantin Shcheglov 375e878c35 Update nullability for TypeParameterType in tryPromoteToType()
Change-Id: Ifc8c32e3540577437c6448fa943d8cbbfebf0b62
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/196105
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
2021-04-20 23:02:08 +00:00
Paul Berry add079c222 Flow analysis: Fix test function name.
In a previous commit, I accidentally named these test functions
`test`.  Replace with a more descriptive name.

Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: I662b6003a893dbb05fea88000f39e4e56b0cb725
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/196107
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-04-20 21:59:18 +00:00
Paul Berry 68bb946fc5 Change analyzer ID test offsets for prefixed identifiers.
The ID test offset for a prefixed identifier is now the offset of the
identifier after the `.`.  This makes the analyzer and CFE behaviors
match much more closely, which eliminates a lot of nuisance
differences in the ID test expectations.

Change-Id: Icef1b2bf56b79bcf584d1eb153bdafd575e6cabb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/195483
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2021-04-16 13:07:01 +00:00
Paul Berry 0ccb2771a3 Analyzer: change extent for assignability errors with named arguments
Previously, if a type mismatch occurred on a named argument, e.g.:

    int.fromEnvironment('foo', defaultValue: 'BAD')

the error would be reported on the entire NamedExpression
(`defaultValue: 'BAD'` in this example).  Now, the error is just
reported on the expression (`'BAD'` in this example).  This makes the
analyzer behavior more self-consistent (since now assignability errors
are now consistently reported at the site of the expression that can't
be assigned).  It also makes the analyzer behavior more consistent
with the CFE.

This will make it possible, in a follow-up CL, to eliminate a lot of
the inconsistencies between analyzer and CFE in the "why not promoted"
ID tests.

Change-Id: I17db256959d730a22a5766f65d5c0736b627f244
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/195489
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-04-15 21:38:37 +00:00
Paul Berry 2ee741692f Add "why not promoted" support for explicit extension overrides.
Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: Iea9300cf2cae52355bfa5a71f773c8136da2c644
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/195306
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-04-15 12:13:27 +00:00
Paul Berry ad4faa0e86 Flow analysis: in tests, stop storing type of this. property gets.
This makes the flow analysis tests more similar to the anaylzer and
CFE implementations, which look up the type of a `this.` property get
at the time it is analyzed, rather than storing it in the AST node.

Change-Id: Idee2a9c3ba0acbd2752db511c1aabfdff075b363
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/194544
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2021-04-09 03:42:01 +00:00
Paul Berry 363da90385 Fix "why not promoted" functionality for compound indexed assignment.
Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: I40c6087a0db2c67106f9ce138b79a8a5769b37de
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193834
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2021-04-07 11:39:12 +00:00
Paul Berry 0873d4eb82 Flow analysis: remove branchTarget() construct from unit tests.
Flow analysis unit tests now support implicit branch targets, and use
`LabeledStatement` directly in the case where the branch target is
explicit.  This is more similar to how the language acutally behaves,
and paves the way for adding more sophisticated tests in the future.

Note that at the moment, there are no flow analysis tests where a
`continue` statement has a different target than the innermost loop,
so for now, the `continue_` function doesn't accept a target
parameter.  I plan to add this functionality in the future, at the
time that I add tests that require it.

Change-Id: I2591ee3322ea4adba3e32dc76a29f0b3956058e5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/194040
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-04-05 12:19:07 +00:00
Paul Berry 72bc3134c5 Unify "why not promoted" representations for for-loops and other writes.
This CL changes the responsibility for doing flow analysis of the
implicit variable write in a `for-in` loop as follows: if the `for-in`
loop does not declare a variable, but it assigns to a local variable,
then the flow analysis client is responsible for calling `write` on
entry to the loop.

This in turn allows us to use a single code path to track "why not
promoted" information related to all possible local variable writes;
we no longer need as much special case logic to handle for-in loops.

To make the analyzer integration slightly cleaner, we change the
argument type of FlowAnalysis.write to Node rather than Expression, so
that the analyzer can pass in the ForEachParts object when analyzing a
for-in loop.

Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: I24b47be8eac2e276cd291a5b2f2e4444c911138f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193837
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2021-04-03 15:28:36 +00:00
Paul Berry 104e364b5c Flow analysis: in unit tests, look up property get types in harness.
This makes the flow analysis unit tests more similar to the behavior
of the analyzer and CFE, in that the types of various properties are a
property of the program being analyzed, not of the individual property
gets themselves.

Change-Id: I6ea164665093ee285325a64e80f3f52d7a63cf74
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193836
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-04-02 17:38:42 +00:00
Paul Berry c25e74852c Add links to "why not promoted" error messages.
These links are not live yet, but they will be filled in with
documentation explaining subtleties of type promotion in more detail.

Bug: https://github.com/dart-lang/sdk/issues/44900
Change-Id: I3e1865597fc5c56495a8108c8a4de98cab0c3e4b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193749
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
2021-04-01 16:42:12 +00:00
Paul Berry 10d531b5f9 Flow analysis: Minor fixes to "why not promoted" ID tests.
The ID tests for the "why not promoted" feature had some minor
unintentional errors in them.  This CL fixes them:

- The constructor tests in
  argument_type_not_assignable_nullability_error.dart tried to return
  null from functions whose return type didn't allow it.

- The compoundAssignmentRhs test in
  argument_type_not_assignable_nullability_error.dart tried to add an
  `int` to an `int?`.  The CFE considers this to be an error, but also
  reports a follow-on error because it thinks the type of the
  resulting expression is `num` (which is not assignable back to
  `int`).  To avoid the follow-on error, we use `num` for the type of
  the variable to which compound assignment is being applied.

- The forElementInMap test in
  for_in_loop_type_not_iterable_nullability_error.dart wasn't a proper
  map (it contained two `null` elements, rather than a single map
  entry `null: null`, which was what was intended).

There were also several tests for which we *don't* expect "why not
promoted" information; I added comments explaining why.

Change-Id: I91ddb88cb0f25f9b209df3eeb75d57d8270f877b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193561
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2021-03-31 15:20:28 +00:00
Paul Berry 72ffbaa7d7 Rework _fe_analyzer_shared mini-AST to use an L-value abstraction.
Rather than representing an assignment differently depending on what
kind of construct appears on its left hand side (as kernel does), we
represent all assignments as a single `_Write` type, and use an
`LValue` base class to represent the different kinds of constructs
that can appear on the left hand side.  This representation will be
easier to expand into supporting more of the Dart language as we
expand the testing we want to be able to do in _fe_analyzer_shared.

Change-Id: I87b811176b2ba132fb992414c277cf2c6b81e03c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193180
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-03-30 21:07:01 +00:00
Paul Berry 6c30a7d582 Flow analysis: implement "why not promoted" logic for index expressions.
Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: I52a0fa33dbeb4f6382dd8b3154ead25ca2065878
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193088
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-03-30 18:24:11 +00:00
Johnni Winther 13556d623f [cfe] Add DartType.toNonNull
Add helper on DartType to compute the `NonNull` of a type and use this
instead of `withDeclaredNullability(Nullability.nonNullable).

Includes a fix in the computation of NonNull of FutureOr.

TEST=existing

Change-Id: I3399cbf89c7d3f3e90f1315b01f40957e798a1b1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193400
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
2021-03-30 10:25:28 +00:00
Paul Berry a7b0f5108d Flow analysis: implement "why not promoted" logic for compound assignments.
Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: I57a2c62b8450c313887b516d6fe2ef85fdd0d92b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193084
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-03-26 00:29:24 +00:00
Paul Berry 52a1fb3de2 Flow analysis: refactor handling of try/catch/finally in unit tests.
We now use a single AST node to represent try/catch/finally rather
than separate try/catch and try/finally nodes.  This more closely
parallels the data structures used by the analyzer and CFE.

Change-Id: Ic4c1f1e4ac9e10ebf36afa4047c9c8b9ce151a1f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193093
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-03-26 00:16:54 +00:00
Paul Berry e32ddc132f Flow analysis: refactor handling of this in unit tests.
The type of `this` is now stored in the test harness rather than in
the individual `this` AST objects.  This more closely parallels how
`this` is handled in the analyzer and CFE.

Change-Id: I7c60aec8a14680beecca161ad25d681b82f79a2b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193092
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2021-03-26 00:16:54 +00:00
Paul Berry f7419efa93 Fix some mismatched variable names in a flow analysis test.
Change-Id: I69f9822f9fe0e935a40fac0fced2d1512c234a64
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193089
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2021-03-26 00:16:54 +00:00
Paul Berry b59bca4dc9 Flow analysis: Move mini_ast implementation to a shared location.
This will make it possible to use the same "mini AST" representation
to test other shared FE/analyzer code.

Change-Id: I8140bf1770f3bfe0ca8a959ba2c41babcb7852bb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193000
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-03-25 17:55:34 +00:00
Paul Berry f161e228e4 Flow analysis: implement "why not promoted" logic for assignments.
This CL handles ordinary assignment expressions, variable declaration
initializers, and constructor field initializers.

Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: I06bae2c7d57213bd7769c931a03080d148af3dbe
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/192724
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2021-03-25 02:01:33 +00:00
Paul Berry 20d9c6eb3a Flow analysis: implement "why not promoted" logic for boolean conditions
Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: Ia8f3a5ad2971dfb6baeefb0d2f9c6998af0d897e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/192611
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2021-03-24 12:10:09 +00:00
Paul Berry eb37227666 Flow analysis: implement "why not promoted" logic for logical binary operators.
Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: If03750edf6bdf13fc2677e0c09f49f70d0da744e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/192608
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2021-03-24 12:10:09 +00:00
Paul Berry 6c665c4607 Flow analysis: implement "why not promoted" logic for most binary operators.
`&&` and `||` will be addressed in a follow-up CL go through a
different code path in the analyzer.

Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: I20732ceceb113017a0b1e77134b1e28c4c924fbb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/192607
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2021-03-24 12:10:09 +00:00
Paul Berry dd91769e90 Flow analysis: implement "why not promoted" functionality for arguments.
Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: Ib39ef04aadc2340c269878763e19a4a97001e2b5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/191989
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-03-22 17:31:54 +00:00
Paul Berry 00c188bb2e Flow analysis: Improve unit test failure output for _CheckPromoted.
The failure message now includes the stacktrace from when the
_CheckPromoted node was constructed; this makes it possible to quickly
find the line in the source code that encodes the expectation, which
is often much more useful than the stacktrace from the time the
failure was detected.

The stacktrace from the time the failure was detected still appears,
after the stacktrace from when the node was constructed.

Change-Id: If375e141a32b371e806399e42ff7cfaae9cf7873
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/192290
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-03-22 17:29:14 +00:00
Paul Berry 681d3e2a43 Allow the expensive parts of "why not promoted" computation to be deferred.
This is necessary because `whyNotPromoted` needs to be called right
after visiting a subexpression, but it's not always possible to tell
that the type of that subexpression will result in an error until more
code has been visited.

Change-Id: If44e2bb55612c1ba7996b523c3ec078d7b80c865
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/191601
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2021-03-18 19:52:13 +00:00
Paul Berry 217cd49aaf More "why not promoted" test cases for for-in loops
Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: Iea44cd482f21ef4406b28e264046025ce3f87695
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/191385
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-03-16 17:22:33 +00:00
Paul Berry 01ad9f1e8d Make flow analysis tests use a more sophisticated Type data structure.
Rather than represent types by strings in the flow analysis tests, we
have a "mini type" language that can represent function types, type
parameters, nullabilities, and promotions.  This should make it easier
to build more sophisticated tests for shared code.

Change-Id: I66d15ad3dc6a871958ed01654600aea749fa0e65
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/190340
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2021-03-10 14:53:58 +00:00
Paul Berry b661bf12c5 Front end: Additional "why not promoted" functionality.
This CL implements "why not promoted" functionality in the front end
for the following scenarios:
- null iterable in for-loop
- null iterable in yield* statement
- null iterable or map after spread (`...`) operator

Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: I471b8bf558341514207fad527dde009f1372182c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/188160
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-03-10 14:52:19 +00:00
Paul Berry 73f9d0cd26 Flow analysis: Remove unnecessary argument from tryFinallyStatement_end.
Flow analysis stopped using this argument (the AST node for the
finally block) some time ago, but I kept it around so I could assert
that clients didn't unnecessarily store assigned variables info for
it.  It's been long enough now that we can eliminate this code
entirely.

Change-Id: I8c64e2b4fc5b154f441ec2d057637f3dc9ced277
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/190060
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-03-10 13:14:08 +00:00
Paul Berry 8be535350d Flow analysis: improve handling of types in "why not promoted" logic.
This CL plumbs the types of `this` and property get expression from
the CFE and analyzer into flow analysis, so that flow analysis will be
able to create more accurate "why not promoted" information for those
expression types.  This made it possible to eliminate a clumsy aspect
of the previous implementation, namely that we would consider a
promotion attempt like `if (x.y == null) return;` as an attempt to
promote the type of `x.y` to `Object`; now we compute the type the
user is actually trying to promote to, so we will be able to generate
more accurate "why not promoted" messages.

Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: I67f9fc59e72103194a1ea6b1c4dfeae8aeb194a2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/187064
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-03-03 23:16:55 +00:00
Paul Berry 085529d58d Flow analysis: hardcode allowLocalBooleanVarsToPromote flag.
This flag was being kept around in case the corresponding feature
(https://github.com/dart-lang/language/issues/1274) wound up having
bugs and needed to be switched off.  It's now had sufficient bake time
that we no longer need the flag.

Removing the flag allows us to remove a bunch of flow analysis code
that's no longer needed.

Bug: https://github.com/dart-lang/language/issues/1274
Change-Id: Ib91fa09a560bb0ebc6bff280ffc37d6037816ef9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/187981
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-02-26 18:28:57 +00:00
Paul Berry 265f6fca2d Flow analysis: Fix "why not promoted" functionality for implicit this
Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: Ief6014c34aef329e5f408916f5d8ffe14a62effd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/187940
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-02-26 18:14:47 +00:00
Paul Berry 4e67a67d06 Flow analysis: fix constness in unit tests.
The Node class hierarchy shouldn't be const constructible, because
flow analysis assumes it can distinguish nodes by identity, and we
don't want const canonicalization to prevent this.

Change-Id: I60f70a0ece77c8efbeaa001cbddb21d1dc8b4d6e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/187980
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-02-26 17:55:57 +00:00
Paul Berry 588fadcd49 Flow analysis: expand analyzer support for "why not promoted" messages.
This CL adds support for the following scenarios to the analyzer:

- Attempt to use a non-promoted nullable expression as the iterable of
  a for-in loop

- Attempt to use a non-promoted nullable expression as the argument of
  a `yield *` statement

- Attempt to implicitly invoke `.call` on a non-promoted nullable
  expression

- Attempt to use a non-promoted nullable expression as the argument of
  a spread operator (`...`) that is not null-aware

Some of these cases are already handled by the CFE.  Others will be
addressed in a follow-up CL.

Change-Id: I3cf31b1496e1bd92fdd3f8192f04c98dff15077c
Bug: https://github.com/dart-lang/sdk/issues/44898
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/186320
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-02-23 17:51:16 +00:00
Paul Berry 1d191a1374 Implement more "why not promoted" functionality in the front end.
This CL ensures that we produce appropriate "why not promoted" context
messages in all the scenarios where the CFE reports the error code
`NullableExpressionCallError`.

Analyzer support for these scenarios will be in a follow-up CL.

Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: Id1407b28a97fc917189e885f995a4efc0bf0c250
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/185920
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-02-22 14:41:09 +00:00
Paul Berry c2eb847697 Add "why not promoted" support for method invocations to CFE.
This required moving the logic for computing the context messages from
the inference visitor to the type inferrer.

This includes support for extension method invocations and invocation
of `.call` on a function type.

Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: Icda160f69cc815953c43edc92be910c5f49f9401
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/184842
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2021-02-13 15:39:17 +00:00
Paul Berry 957c0a1c9d Improve "why not promoted" info for field/property reference.
When reporting that a null check is needed due to a lack of type
promotion, and the thing that was not promoted was a reference to a
field or property, the CFE and analyzer now report "why not promoted"
using a context message that points to the definition of the field or
getter.  (Previously the CFE reported a context message with no
location, and the analyzer didn't report "why not promoted").

Bug: https://github.com/dart-lang/sdk/issues/44898
Change-Id: If1841727b8b60dd87c43f239e6a06b98f363801f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/184522
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-02-12 22:43:55 +00:00
Paul Berry a42244f73b Flow analysis: begin tracking non-promotion reasons.
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>
2021-02-02 16:15:34 +00:00
Paul Berry 4ee861b7d0 Flow analysis: Track additional assigned variables information.
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>
2021-01-21 19:48:22 +00:00
Paul Berry 75aea30724 Add an implementation of legacy type promotion to _fe_analyzer_shared.
The new implementation uses the same API as flow analysis.  This
should allow us to significantly simplify the CFE and analyzer, by
dropping their implementations of legacy type promotion in favor of
the shared implementation.

This CL just introduces the new implementation and unit tests for it;
it does not integrate it with the analyzer or CFE.  I will follow up
with a CL that does the integration.

Change-Id: Ie07b3b39604d6a022ad42f3ae6b648a317c8af28
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/179560
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2021-01-16 17:07:23 +00:00
Paul Berry f452e763e0 Add a class to represent references tracked by flow analysis.
The only references that are promotable are references to variables,
however in the near future I'll be adding logic to flor analysis to
keep track of attempts to promote fields; this will require tracking
references to property gets as well as references to `this`, so we
need to start building up data structures to track those references.

Bug: https://github.com/dart-lang/sdk/issues/38773
Change-Id: I0e3fd44f580bb85db3e8f405675b66aa4069e455
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/179280
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2021-01-15 17:55:02 +00:00
Paul Berry 10917ffd55 Don't promote this inside extension methods.
Bug: https://github.com/dart-lang/sdk/issues/44652
Change-Id: I05e5acfbff1d498fa3ad513d956510909ec7d24f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/178920
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2021-01-13 16:48:08 +00:00
Paul Berry 6f40248275 Simplify usage of addFactor and addSubtype.
These test harness methods now take strings rather than Type objects,
which should make the tests easier to read (and less work to write).

Change-Id: I160bb7a7a61116e18736d414d5a549971d851c02
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/178883
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2021-01-12 21:47:04 +00:00
Paul Berry 88cd4739b8 Flow analysis: switch on inference based on local boolean variables.
The implementation was completed in previous CLs, but hidden behind a
flag.  This CL switches on the feature and adds integration tests.

Bug: https://github.com/dart-lang/language/issues/1274
Change-Id: I0e2d7ac96d3a6d68d33d49f1eab5c341c9167f6f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175500
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2021-01-08 18:57:02 +00:00
Paul Berry 474edbe27f Flow analysis: do not treat null vars as equivalent to null.
When analyzing code like this with the
`allowLocalBooleanVarsToPromote` flag enabled, don't treat a variable
containing `null` as equivalent to a literal `null`.  For example:

    f(int? x) {
      var y = null;
      if (x != y) {
        print(x + 1); // ERROR: x must be null checked.
      }
    }

The rationale is that flow analysis doesn't promote variables that are
known to be `null` to the `Null` type, so it seems like it would be
inconsistent if we used the fact that they're `null` to promote other
variables.

Bug: https://github.com/dart-lang/language/issues/1274
Change-Id: Icfa14104936a26732353921e3a29a840c53d4d52
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/176560
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2020-12-17 19:31:34 +00:00
Paul Berry 4510f1dc98 Flow analysis: add the ability to promote based on local boolean vars.
This CL adds functionality to FlowAnalysis.variableRead so that if the
truth value of the variable is known to be correlated with other flow
analysis state, that state can be restored.  This allows promotion
based on boolean variables in addition to boolean expressions, e.g.:

    int? x = ...;
    var xIsNotNull = x != null;
    if (xIsNotNull) {
      print(x + 1); // Ok; x is known to be non-null.
    }

This functionality is not enabled yet; it is hidden behind the flag
`allowLocalBooleanVarsToPromoteByDefault`.

Bug: https://github.com/dart-lang/language/issues/1274
Change-Id: I2a0183b69d285193db7acb36cc6af5c34e165c2c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/176500
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2020-12-17 15:16:04 +00:00