Inspired by some recent code reviews from Lasse, I decided to make
some improvements to flow analysis documentation to bring it more in
line with the Dart style guide.
Change-Id: Ibbda802055d7e17429806b2a4e608005bf761a69
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/433380
Reviewed-by: Lasse Nielsen <lrn@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This change adds test-only methods `propertyPromotionChainForTesting`
and `variablePromotionChainForTesting` to flow analysis; these are
used by the flow analysis unit tests to query the full promotion chain
of a porperty (or variable, respectively). This allows tests to
observe the effect of try/finally ordering on promotion chains without
having to resort to clever control flow joins.
Thanks to Lasse for the suggestion.
Change-Id: Ida5349ecc93dbd4b3392becd20882be3eb101024
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/432800
Reviewed-by: Lasse Nielsen <lrn@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
When an `is` test is trivially satisfied (i.e. `expr is T`, when the
static type of `expr` is a subtype of `T`), the `is` test is
guaranteed by soundness to evaluate to `true`, so any code path that
follows from the `is` test evaluating to `false` is unreachable.
This reasoning wasn't valid prior to sound null safety, because in
mixed mode programs, it was possible for an expression to evaluate to
`null` even if its static type wasn't nullable, and hence `expr is T`
might evaluate to `false` even if the static type of `expr` was a
subtype of `T`. So this change is gated on the `sound-flow-analysis`
language flag (which is enabled in Dart 3.9).
Fixes https://github.com/dart-lang/sdk/issues/60718.
Change-Id: I66a65580b738162f23b6fb468b71fcac66bfbb95
Bug: https://github.com/dart-lang/sdk/issues/60718
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/431740
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Previously, when assiging to a local variable that was promoted, if
the newly assigned value was not compatible with any of the promotions
(i.e., the variable was fully demoted back to its declared type), then
the set of types of interest was cleared.
This behavior was not documented anywhere in the spec, and it seems
oddly inconsistent to me; as far as I can tell, flow analysis doesn't
clear types of interest in any other circumstances. I've looked
through git history as well as my personal notes, and I've been unable
to find any justification for this behavior. So, with the agreement of
the language team, I'm removing it when sound-flow-analysis is
enabled.
Fixes https://github.com/dart-lang/language/issues/4380.
Bug: https://github.com/dart-lang/language/issues/4380
Change-Id: Ic1ca80a61e21482e659afa8796b08fce707db3c5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/429227
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This gets rid of (what is described in commented code as)
InstantiatedTypeWithArgumentsTest, Subtype1TestCacheLookup, BoolTest.
Running this through the benchmarker like this:
```
out/ReleaseX64/dart-sdk/bin/dart pkg/front_end/tool/benchmarker.dart \
--snapshot=pkg/analysis_server/bin/server.aot.1 \
--snapshot=pkg/analysis_server/bin/server.aot.2 \
--arguments="--disable-file-byte-store" \
--arguments="--train-using" \
--arguments="pkg/front_end/lib/"
```
(there `server.aot.1` is without this CL and `server.aot.2` is with)
I get:
```
msec task-clock:u: -0.9614% +/- 0.3557% (-78.23 +/- 28.95) (8136.80 -> 8058.57)
cycles:u: -1.0257% +/- 0.3626% (-348283560.66 +/- 123129577.69) (33955507948.94 -> 33607224388.28)
instructions:u: -1.0595% +/- 0.0662% (-479117043.74 +/- 29935955.93) (45220681554.68 -> 44741564510.94)
seconds time elapsed: -0.9548% +/- 0.3540% (-0.08 +/- 0.03) (8.15 -> 8.07)
seconds user: -1.0649% +/- 0.4031% (-0.08 +/- 0.03) (7.80 -> 7.72)
Scavenge( new space) goes from 130 to 129
Notice combined GC time goes from 2613 ms to 2608 ms (notice only 1 run each).
```
`StackImpl.pop` as reported by `perf report --no-children` goes from
0.81% to 0.34% (and I'm unsure why the apparent change seen as a whole
is quite a bit bigger).
Change-Id: Ife36da11215e0c8aa706d945f0ee5018ad03ab91
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/432340
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
A tricky part of the implementation of flow analysis is the handling
of try/finally statements. Although promotions are tracked separately
in the `try` and `finally` blocks, promotions from both blocks need to
be merged together at the conclusion of the finally block. This
creates an ambiguity, because each type in a promotion chain is
required to be a subtype of the previous, and hence multiple
promotions of the same variable are inherently ordered. The ambiguity
is: when the promotions from the `try` and `finally` block are merged,
which promotions should be applied first?
In discussion with the language team, we've decided that the
promotions from the `try` block should be applied first, because that
matches the order of code execution. This change makes the behavior of
flow analysis more uniform, which should make it easier to reason
about and maintain.
In practice, the difference in behavior is quite subtle, and I don't
expect users to notice. However, to be on the safe side, the change in
behavior is conditioned on the `sound-flow-analysis` flag, so it will
only take effect when the user deliberately upgrades to language
version 3.9, and it will not affect already-published packages.
A test in google3 showed that no internal code would be broken by
force-enabling this change.
Fixes https://github.com/dart-lang/language/issues/4382.
Change-Id: I0e9f6db808a964e0b4325d3020654a9f2be273a2
Bug: https://github.com/dart-lang/language/issues/4382
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/432001
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Previously, flow analysis had the rule that type promotion only
occurred when the type being tested was a subtype of the previously
promoted type (or the declared type, if there was no previous
promotion). This led to counterintuitive behaviors when the type being
tested and the previously promoted type were mutual subtypes (see
https://github.com/dart-lang/language/issues/4368).
With this change, the rule is updated so that type promotion only
occurs when the type being tested is a subtype of the previously
promoted type _and_ the previously promoted type is _not_ a subtype of
the type being tested. The user-visible difference is that promotion
to a mutual subtype no longer occurs.
This change makes flow analysis easier to reason about, and improves
its behavior in corner cases, but I believe it will have minimal
impact on real-world code. But to reduce the risk to existing code,
the change only takes effect when the `sound-flow-analysis` language
feature is enabled.
Fixes https://github.com/dart-lang/language/issues/4368.
Bug: https://github.com/dart-lang/language/issues/4368
Change-Id: I30dab017e043e75603d618df721c8a2683667cd5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/429200
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This PR enables native assets on the main and dev channel by default,
and make native assets available on the beta channel.
This PR removes the flag from invocations.
The helper packages (`package:hooks` and `package:code_assets`) will
stay 0.x for now, until the SDK constraint can be bumped to a beta
release and we're happy with the Dart API.
`dart build` is also made available as preview (without a flag on
the main, dev, and beta channels). We're still finalizing the spec for
this command. (https://github.com/dart-lang/sdk/issues/60730)
`dart test` will need https://github.com/dart-lang/test/pull/2501.
This means users will need to update their `package:test` dependency.
This PR refactors the way that invalid `package_config.json`s are
handled: they are now loaded in the dartdev commands and handled there.
Bug: https://github.com/dart-lang/sdk/issues/50565
Project: https://github.com/orgs/dart-lang/projects/99/
Change-Id: I7db9ff6d7196750cab9379a4605c6bbf89a974d7
Cq-Include-Trybots: luci.dart.try:pkg-linux-debug-try,pkg-linux-release-arm64-try,pkg-linux-release-try,pkg-mac-release-arm64-try,pkg-win-release-arm64-try,pkg-mac-release-try,pkg-win-release-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/429920
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
The way this is accomplished is that in
`_FlowAnalysisImpl.nullAwareAccess_rightBegin`, any expression
reference associated with the target of the null-aware access is
restored, and the corresponding SSA node is associated with the guard
variable (if any). These changes ensure that if the null-aware access
is a property get, the subsequent call to `propertyGet` will pick up
the appropriate SSA node, so it will be able to locate the promotion
key for the property.
This functionality is only enabled when the language feature
`sound-flow-analysis` is enabled.
To prevent test regressions, a few related changes need to be made at
the same time:
- `_FlowAnalysisImpl.nullAwareAccess_end` is changed so that it clears
any expression info or expression reference that was associated with
the null-aware access expression. This prevents flow analysis
information from being erroneously propagated out of a null-aware
expression, which would have led to assertion failures when
analyzing null-aware expressions inside of conditional
expressions. This wasn't previously a problem because the expression
reference used to be consumed by
`_FlowAnalysisImpl.nullAwareAccess_rightBegin`, preventing further
expression references and expression infos from being recorded
further along in the null-aware access.
- The test framework in `mini_ast.dart` is fixed so that `!` is
considered to participate in null shorting. This was a bug in the
test framework that wasn't previously caught because it happened not
to produce any test failures.
- The analyzer's method `PostfixExpressionResolver._resolveNullCheck`
is changed so that it calls `nonNullAssert_end` before terminating
null-aware access. Previously, the order was swapped, causing
`nullAwareAccess_end` to be called before `nonNullAssert_end` when
analyzing expressions like `a?.b!`. This used to be benign, but now
that non-cascaded field accesses participate in field promotion,
flow analysis needs the methods to be called in the correct order.
Fixes https://github.com/dart-lang/language/issues/4344.
Bug: https://github.com/dart-lang/language/issues/4344
Change-Id: I523be1b4be1af3f68654a745187a546728c878fe
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/427820
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
The CFE desugars null-aware expressions such as `a?.b` into equivalent
`let` expressions involving a temporary guard variable (e.g., `let x =
a in x == null ? null : x.b`). This desugaring happens in the body
builder, prior to flow analysis. As a result, the expressions and
variables passed to flow analysis are those of the desugared `let`
expression rather than those of the code the user wrote. So a hack is
needed to ensure that flow analysis produces the correct result; the
hack involves promoting the temporary guard variable in the code path
where it is not null.
Prior to this change, the hack was done entirely in the CFE. Instead
of making a single pair of calls to
`FlowAnalysis.nullAwareAccess_rightBegin` and
`FlowAnalysis.nullAwareAccess_end` for every null-aware expression,
the CFE made two nested pairs of calls: one to promote the true target
of the null-aware access, and the other to promote the temporary guard
variable.
This had the advantage of keeping the hack entirely in the CFE, but
unfortunately it got in the way of fixing
https://github.com/dart-lang/language/issues/4344, because it
prevented flow analysis from properly recognizing field accesses
inside null-aware expressions.
This change adds an optional `guardVariable` parameter to
`FlowAnalysis_nullAwareAccess_rightBegin`, and shifts the
responsibility for promoting the temporary guard variable to the flow
analysis engine itself. With this change, the CFE no longer needs to
make two nested pairs of calls to
`FlowAnalysis.nullAwareAccess_rightBegin` and
`FlowAnalysis.nullAwareAccess_end`, and flow analysis now has the
necessary information to recognize field accesses inside null-aware
expressions.
I will perform the actual fix for
https://github.com/dart-lang/language/issues/4344 in a follow-up CL.
Note that in the future, I would like to change the CFE so that it
desugars null-aware accesses during type inference rather than during
the body builder; this will allow the expressions and variables passed
to flow analysis to be precisely those of the code the user wrote;
that in turn will give us extra confidence that flow analysis produces
the same results in the analyzer and the CFE.
Change-Id: Ie63619a3ca0f011c1ae8e3c0c76b5bc7c1ab8419
Bug: https://github.com/dart-lang/language/issues/4344
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/427341
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This adds reporting of an error in CFE for ?.length in constant expressions and improves the message for the analyzer in the same case. The error in the analyzer was previously the invalid claim that
The property 'length' can't be accessed on the type 'Null' in a constant expression.
Closes#60509
Change-Id: Ibbe0fa1ace3bea9d83efea2ccf3ea9716a125d74
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/421841
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This adds a `debugPrint` method along with methods to support automatic indentation.
The debug helpers are reexported inside package:analyzer and package:front_end for easy access.
Change-Id: I80a4103e6fb30a6b459551184916c3fa26591a20
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/425280
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
Context:
A while back, I inserted a synthetic token in the parser to allow us to parse without crashing the analyzer while I worked on the CFE. Now that both implementations are up and working, we can remove this synthetic token and allow the parser to parse as if we had enabled dot shorthands by default, and produce an error if the experiment isn't enabled.
This change allows a bunch of different language tests to start passing since they were blocked on the weird synthetic token messing up the parsing stream.
Bug: https://github.com/dart-lang/sdk/issues/59758
Change-Id: I792e3b917a76241b04ee708de06f670bbde64036
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/423563
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
Instead of validating the erasure of an extension type,
validate that extension type declaration and type arguments
are specified as callable.
TEST=pkg/dynamic_modules/test/data/extension_type2
Fixes b/411433443
Change-Id: I063f0a622abd0d75594c4095573b29a7888f5afb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/423882
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
When there's exactly a dot shorthand of the RHS of `==`, we use the namespace of the LHS to resolve the shorthand on the RHS.
There's existing CFE work done for the `case ==` case in the type analyzer, so we just have to make sure `isDotShorthand` is properly set. This will take care of the relational pattern `==` behaviour.
Tested using language tests and resolution unit tests.
Bug: https://github.com/dart-lang/sdk/issues/59835
Change-Id: I3823641d1872bca68e344bc323209b58fb5098db
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/422941
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
Allows the resolution of `.new` constructor references and static property accesses, using the existing `PropertyElementResolver` resolution logic.
Testing includes an AST builder test, and the `DotShorthandPropertyAccess` resolution tests. Some property access language tests are now passing.
Bug: https://github.com/dart-lang/sdk/issues/59835
Change-Id: Idb576ef7fa0866bc4b2d155bbf867886ae2b4df6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/421964
Commit-Queue: Kallen Tu <kallentu@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
With this CL, we build the `DotShorthandInvocation` AST as soon as we find a `MethodInvocation` when parsing a dot shorthand head. The context is saved as we encounter ASTs with the `isDotShorthand` flag enabled (which currently is just the invocation and property get head, more will be added later). We pop the context after resolving the dot shorthand head and using the context for resolution.
The resolution of dot shorthand invocations is handled by the `MethodInvocationInferrer` where most of the logic was added in https://dart-review.googlesource.com/c/sdk/+/421560. In this CL, we're calling the `resolveDotShorthand` entry point for the very basic resolving. This is the groundwork that we'll build off of for constructor invocations, extension type invocations and other cases.
Some co19 tests are crashing, as per expected, but I added resolution tests for the .shorthand invocations and ast building tests.
Bug: https://github.com/dart-lang/sdk/issues/59835
Change-Id: I62bcb5fecb3c4fdfcf29d6c079d5d77547c4a21a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/419780
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
This change updates the logic in the flow analysis method
`promoteForPattern`, so that when the language feature
`sound-flow-analysis` is enabled, the following additional behaviors
are added:
- If the matched value type is non-nullable, and the pattern
implicitly performs an `is Null` test, then the pattern is known not
to match.
- If the matched value type is `Null`, and the pattern implicitly
performs an `is T` test, where `T` is a non-nullable type, then the
pattern is known not to match. Note that this reasoning step is
sound regardless of whether the program is running with sound null
safety enabled, but since it is a new reasoning step, it only takes
place if the `sound-flow-analysis` feature is enabled.
There is no behavioral change if the feature `sound-flow-analysis` is
disabled.
Bug: https://github.com/dart-lang/sdk/issues/60438
Change-Id: I5a6e8def050c95b6c1ad01d37584d17a0cd590c8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/421900
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
This change updates the flow analysis logic for map patterns, so that
when the language feature `sound-flow-analysis` is enabled, an empty
map pattern is considered to match a non-nullable map.
There is no behavioral change if the feature `sound-flow-analysis` is
disabled.
Bug: https://github.com/dart-lang/sdk/issues/60438
Change-Id: I3f5a79c00cfe91d37528a3790b5cedb9a8f010fc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/421584
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This change updates the flow analysis logic for null check patterns,
so that when the language feature `sound-flow-analysis` is enabled,
the matched value type is checked for nullability. If it's
non-nullable, then the null check pattern is known to succeed.
There is no behavioral change if the feature `sound-flow-analysis` is
disabled.
Bug: https://github.com/dart-lang/sdk/issues/60438
Change-Id: Ie68d98d95e30053f992a3f8db6ccdd3978960eb7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/421583
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
It turns out that the flow analysis logic for null-aware map entries
has always presumed sound null safety. That is, given a map entry with
a null-aware key (`{?x: y}`), flow analysis assumed that if the key
was non-nullable, then the value was guaranteed to execute.
However, another piece of logic that could have been implemented, and
wasn't, was that if the key had static type `Null`, then the value was
guaranteed _not_ to execute. This logic would have been sound even
without assuming sound null safety (because even in unsound null
safety mode, the type `Null` was only inhabited by the value `null`).
This change implements the missing logic. Even though it doesn't
strictly depend on the assumption sound null safety, it still makes
sense to guard it by the `sound-flow-analysis` flag, because (a) it's
a potentially breaking change, and (b) it brings the flow analysis
behavior of null-aware map entries into alignment with the other
behaviors that are being implemented as part of the
`sound-flow-analysis` feature.
There is no behavioral change if the feature `sound-flow-analysis` is
disabled.
Bug: https://github.com/dart-lang/sdk/issues/60438
Change-Id: Ie711f582660a31a411be0dc339995df140feb04f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/420800
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This change updates the flow analysis logic for `??` and `??=`
expressions, so that when the language feature `sound-flow-analysis`
is enabled, the static type of the left hand side is checked for
nullability. If it's non-nullable, then the right hand side of the
expresison is considered unreachable.
These new behaviors break assumptions made by two pre-existing flow
analysis tests. I changed those tests to run with
`sound-flow-analysis` disabled.
There is no behavioral change if the feature `sound-flow-analysis` is
disabled.
Bug: https://github.com/dart-lang/sdk/issues/60438
Change-Id: I33d6d256bd3c41b764245f50ad34eb5c8b33878e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/420740
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
This change updates the flow analysis logic for `?.` expressions, so
that when the language feature `sound-flow-analysis` is enabled, the
static type of the target is checked for nullability. If it's
non-nullable, then the "shortcut" control flow path (the control flow
path in which the null-aware operation is not executed) is considered
unreachable.
One pre-existing flow analysis test was made redundant by this
change. Another needed a minor tweak to continue passing.
There is no behavioral change if the feature `sound-flow-analysis` is
disabled.
Bug: https://github.com/dart-lang/sdk/issues/60438
Change-Id: I3cd92dd49d4393b40f0ec888b643f0353de5e2d4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/420466
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This change updates the flow analysis logic for `==` and `!=`
expressions, `==` and `!=` patterns, and constant patterns, so that
when the language feature `sound-flow-analysis` is enabled, the static
types of the two expressions being compared are checked for
nullability. If one of the types is non-nullable and the other type is
`Null`, then it is known that the values will be unequal.
Note that these new behaviors break assumptions made by several
pre-existing flow analysis tests. I was able to adjust some of the
tests to preserve their old behavior, either by adjusting expectations
or running the test with `sound-flow-analysis` disabled. Some other
tests became redundant, so I removed them.
There is no behavioral change if the feature `sound-flow-analysis` is
disabled.
Bug: https://github.com/dart-lang/sdk/issues/60438
Change-Id: Ib65477e064bb8dcd761542ebe187843fe265a24b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/420463
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
The class `_EqualityCheckResult`, and its subtypes, were introduced
prior to support for patterns. This change makes
`_EqualityCheckResult` into a sealed class and changes the logic that
consumes it to use `switch` statements rather than `is` tests. The
resulting logic is equivalent, but I believe it's easier to read.
This paves the way for adding a new kind of `_EqualityCheckResult`,
which I'll need to do to support the new `sound-flow-analysis`
feature. (The new kind of `_EqualityCheckResult` will be used in the
circumstance where the two operands of an equality comparison are
guaranteed to be unequal because of their types).
Bug: https://github.com/dart-lang/sdk/issues/60438
Change-Id: I217da37847beff5a43bddb5ed734cc3e4c74970a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/420184
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This change updates the flow analysis logic for `is` and `as`
expressions so that when the language feature `sound-flow-analysis` is
enabled, the static type of the operand is compared to the type to the
right of the `is` or `as` keyword. If one of the types is non-nullable
and the other type is `Null`, then the type test is known to fail. For
an `as` expression, this means that the code path following the
expression will be marked as unreachable. For an `is` expression, this
means that any code paths that assume it evaluates to `true` will be
marked as unreachable.
Note that these new behaviors break assumptions made by three
pre-existing flow analysis tests. I was able to adjust one of the
tests ("equalityOp_end does not set reachability for `this`") to
preserve its old behavior. The other two tests became redundant, so I
removed them.
There is no behavioral change if the feature `sound-flow-analysis` is
disabled.
Bug: https://github.com/dart-lang/sdk/issues/60438
Change-Id: Ib3a9e96bd39cf7df4c6c297568763c0f25bc9e39
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/420164
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Previously, flow analysis was configured by passing a set of named
booleans to its constructor, each to enable or disable a separate
language feature.
This change merges the flow analysis configuration with the
`TypeAnalyzerOptions` class (which was already being used for
configuring the shared `TypeAnalyzer` class). This should make it
easier to add language features to the shared code base in the future,
since there will be one common place where all features will be
configured.
To avoid duplicating the logic that creates `TypeAnalyzerOptions`,
I've had to do a bit of minor surgery to the clients:
- In the test harness in `_fe_analyzer_shared`, there is a common
method (`Harness.computeTypeAnalyzerOptions`) that constructs
`TypeAnalyzerOptions` based on the harness configuration. It is
called from a few different tests.
- In `pkg/analyzer`, there is a common method
(`computeTypeAnalyzerOptions`) that constructs `TypeAnalyzerOptions`
based on a `FeatureSet`. It is used by
`LibraryAnalyzer.analyzeForCompletion`,
`LibraryAnalyzer._resolveFile`, and the late variable
`AstResolver._typeAnalyzerOptions`.
- In `pkg/front_end`, I've moved computation of `TypeAnalyzerOptions`
from the `InferenceVisitorImpl` constructor to the
`TypeInferrerImpl` constructor; the options are then passed to the
`InferenceVisitorImpl` by `_createInferenceVisitor`.
I'm doing this work now as preparation for adding support for sound
flow analysis (https://github.com/dart-lang/sdk/issues/60438), so that
I can add the logic to enable it in a clean way.
Bug: https://github.com/dart-lang/sdk/issues/60438
Change-Id: Ib845194adb404b4c0a3feeff17a14ae641d515eb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/419940
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>