Commit Graph

763 Commits

Author SHA1 Message Date
Paul Berry a226405a70 [flow analysis] Improve how catch clauses are modeled in tests.
This change updates the mini_ast testing infrastructure so that:

- It properly models the "exception type" part of a catch clause (the
  type named after the `on` keyword).

- It requires an exception variable to be specified if there is a
  stack trace variable (this is required by the Dart grammar).

- It requires an exception type to be specified if there is no
  exception variable (this is required by the Dart grammar).

- During the "pre-visit" stage, the exception variable and stack trace
  variable are registered with the `AssignedVariables` object, so that
  they can be properly handled by type promotion.

- During the main "visit" stage, the exception variable and stack
  trace variable are assigned the appropriate types.

Flow analysis unit tests are updated in order to meet the new
requirements, and flow analysis tests are added to check that stack
trace and exception variables are promotable and appropriately typed.

By ensuring that stack trace and exception variables are properly
typed during flow analysis tests, this paves the way for some
follow-up work, in which I plan to re-work how flow analysis keeps
track of variable types.

There is no behavioral change to the analyzer or compiler pipeline;
these changes are confined to `pkg/_fe_analyzer_shared/test`.

Change-Id: I49c4b894d82d1dc58d62e3d3f25d232c9106922e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/434145
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2025-06-12 20:45:35 -07:00
Paul Berry 0da11d5464 [flow analysis] Share more code in tests of try/finally ordering.
This change introduces some helper functions to avoid duplication
between the enabled/disabled variants of each of the try/finally
ordering tests.

Thanks to Lasse for the suggestion.

Change-Id: I4538d44643fde7954a75bc1b6843fcc805d8afc4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/432782
Reviewed-by: Lasse Nielsen <lrn@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2025-06-06 11:01:42 -07:00
Paul Berry e208c2c636 [flow analysis] Rework tests of try/finally ordering.
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>
2025-06-06 08:47:41 -07:00
Paul Berry eec56c088e [flow analysis] Mark false branches of trivial is tests unreachable.
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>
2025-06-04 05:17:21 -07:00
Paul Berry b0e488fcb2 [flow analysis] In tests, stop rewriting ordinary variable declarations.
During the implementation of flow analysis for patterns, I added a
hack to the flow analysis tests so that all variable declarations were
desugared into the equivalent pattern variable declaration. This had
the advantage of getting some extra testing "for free" during early
development of the patterns feature, but it had a few disadvantages:

- It the caused the shared flow analysis and type inference tests to
  stop exercising flow analysis code paths for ordinary variable
  declarations.

- It forced the testing logic to "support" pattern variable
  declarations that are late or lack an initializer; these are things
  that regular Dart doesn't support, and they made the implementation
  of `PatternVariableDeclaration.visit` much more complicated than it
  needed to be.

The language team is currently contemplating some changes to how
promotions work in ordinary variable declarations and pattern variable
declarations (see, for example,
https://github.com/dart-lang/language/issues/4347#issuecomment-2861859329). So
in order to be able to experiment with these possibilities, I want to
get rid of this hack.

This CL adds a `VariableDeclaration` class, to represent ordinary
variable declarations, and modifies the `declare` function (which is
used by tests for creating an ordinary variable declaration) so that
it creates a `VariableDeclaration`, rather than rewriting it into a
`PatternVariableDeclaration` containing a `VariablePattern`. It
removes "support" for testing pattern variable declarations that are
late or lack an initializer, simplifying
`PatternVariableDeclaration.visit`.

A few test cases in `type_inference_test.dart` were checking the
generated IR for ordinary variable declarations, verifying that it was
properly desugared into a pattern variable declaration; these
expectations have accordingly changed to no longer expect desugaring.

There is no functional change to the compiler or analyzer
toolchain. These changes only affect tests in
`pkg/_fe_analyzer_shared/test`.

Change-Id: I90f074cd6e7a6ed5ed11afadeadb6131ce1d282f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/432122
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2025-06-03 17:10:44 -07:00
Paul Berry 69428c35cf [flow analysis] Rename code for testing pattern variable declarations.
The following renames are performed:

- The class `Declare` (which is the "mini-AST" representation of a
  pattern variable declaration), is renamed to
  `PatternVariableDeclaration`.

- The top level function `match` (which is used in tests to construct
  a "mini-AST" representation of a pattern variable declaration), is
  renamed to `patternVariableDeclaration`.

The new names should help avoid confusion in a follow-up CL I intend
to create, which will introduce a new `VariableDeclaration` class to
represent ordinary variable declarations.

There is no functional change. These renames only affect tests in
`pkg/_fe_analyzer_shared`.

Change-Id: Ic6b6f75cbb312180273a08f2c3926f83da254bc0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/432120
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2025-06-03 15:21:20 -07:00
Paul Berry 9602464304 [flow analysis] Don't clear types of interest on full demotion.
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>
2025-06-03 14:19:53 -07:00
Paul Berry 9f0e5229fa [flow analysis] Fix layering of type promotions in try/finally.
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>
2025-06-02 13:57:11 -07:00
Paul Berry bf6ddd25c4 [flow analysis] Do not promote to mutual subtypes.
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>
2025-06-02 10:27:03 -07:00
Paul Berry 5dec261948 Fix test group name for sound flow analysis.
I accidentally called the test group "Sound null safety", which is a
related concept, but not the same thing.

Sound null safety is a compilation mode in which no legacy code is
allowed, and so it is sound to assume that an expression with a
non-nullable type cannot evaluate to `null`. It has been the only
allowed way to compile Dart programs for some time.

Sound flow analysis, on the other hand, is a set of improvements to
flow analysis which are possible now that all Dart programs are now
compiled in sound null safety mode. It is a language-versioned feature
that is enabled in Dart 3.9.

Change-Id: Ib13d28be7fecea6d0e931b33d6643afab2349629
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/432004
Auto-Submit: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
2025-05-29 21:53:01 -07:00
Johnni Winther 653502e4cb [analyzer] Compute default types for local functions
Default types are used in the exhaustiveness computation but were not
computed for local functions, leading to a crash during constant
evaluation. This adds computation of default types to
FunctionDeclaration and FunctionExpression.

Closes #54388
Closes #60264

Change-Id: I95eb2ae5b42e4fb5ab77088c915fe6088a1d4060
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/427702
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
2025-05-26 01:23:49 -07:00
Paul Berry 6cea1790bd [flow analysis] Fix invalid type of interest promotion.
This change closes a loophole whereby it was possible for "type of
interest" promotion to promote to a type that was not a subtype of the
declared type.

I've gone ahead and included more extensive tests (both in unit test
and language test form) of demotion and type of interest promotion, to
try to make sure there aren't other loopholes.

Fixes https://github.com/dart-lang/sdk/issues/60620.

Bug: https://github.com/dart-lang/sdk/issues/60620
Change-Id: Ifef04cde6fda2aee80ec002c7ca04f2be6cff987
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/427920
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2025-05-13 06:10:25 -07:00
Paul Berry 7436b97ba4 [flow analysis] Allow non-cascaded field accesses to participate in field promotion.
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>
2025-05-12 08:25:20 -07:00
Paul Berry 4cdb2df303 [flow analysis] Re-work handling of CFE null-aware guards.
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>
2025-05-12 05:30:10 -07:00
Paul Berry d127486b2a Fix up comments in reachability test data.
Turning on the sound-flow-analysis language feature caused a lot of
code to be classified as unreachable. This change updates comments in
the reachability tests to reflect the new behavior.

Bug: https://github.com/dart-lang/sdk/issues/60438
Change-Id: Iec3fd10e4a5d7f890bbe14e0eadd845eeb7a3225
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/427584
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Auto-Submit: Paul Berry <paulberry@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
2025-05-12 00:14:01 -07:00
Paul Berry 0fcd1a6fa1 Bump _fe_analyzer_shared to SDK 3.7 and reformat
Change-Id: I70157caf90c0955c2eb8426f5721ba4ed527eb76
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/427900
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Auto-Submit: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2025-05-10 15:32:50 -07:00
Paul Berry a757d2af41 Enable sound-flow-analysis for Dart 3.9.
Bug: https://github.com/dart-lang/sdk/issues/60438
Change-Id: I908d4e4a9143142281d8198870f40eba6cf6f67f
Tested: trybots
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/427500
Reviewed-by: Ivan Inozemtsev <iinozemtsev@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Morgan :) <davidmorgan@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
2025-05-09 14:50:26 -07:00
Paul Berry 31583a69de Sort declarations in mini_ast.dart and type_analyzer.dart.
There is no functional change.

Change-Id: I59271a8c385351fb4cea5521041d045f18aa94ea
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/427304
Reviewed-by: Kallen Tu <kallentu@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Auto-Submit: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2025-05-08 11:00:15 -07:00
Chloe Stefantsova a2b2751d7d [model] Define common helper isKnownType and use in inference
This CL is another step towards the unification between
TypeSchemaEnvironment.solveTypeConstraint in the CFE and
GenericInferrer._chooseTypeFromConstraint in the Analyzer.

Part of https://github.com/dart-lang/sdk/issues/54902

Change-Id: I2cfafef6a87b9bde8d1c94f6618e7f633debec0f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/424040
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
2025-04-28 02:19:45 -07:00
Paul Berry 8b4ce0113b [sound flow analysis] Additional unit tests for patterns.
These unit tests exercise flow analysis behaviors for patterns that
one might plausibly assume are part of the `sound-flow-analysis`
feature, but actually have been present ever since the `patterns`
feature was introduced.

Adding these tests helps me be confident that the behavior of flow
analysis after `sound-flow-analysis` has all of the soundness
behaviors I expect; even though some of those behaviors aren't new.

Bug: https://github.com/dart-lang/sdk/issues/60438
Change-Id: I77a269907c67d643d0ef23d4f76545e36761bbfc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/421960
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2025-04-11 08:03:42 -07:00
Paul Berry 12a32f4359 [sound flow analysis] Implement promoteForPattern behaviors.
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>
2025-04-10 12:48:20 -07:00
Paul Berry 9334e8b2db [sound flow analysis] Implement behaviors for map patterns.
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>
2025-04-10 09:50:40 -07:00
Paul Berry de58cf72e0 [sound flow analysis] Implement behaviors for null check patterns.
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>
2025-04-10 09:27:42 -07:00
Johnni Winther b817b1b24e [cfe] Add test for exhaustiveness of != null
Change-Id: I04a34cf6f806a634a2290d8d3c68bbb724b7ebcc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/421183
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
2025-04-10 00:52:31 -07:00
Paul Berry 1540a33f74 [sound flow analysis] Implement behaviors for null-aware map entries.
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>
2025-04-09 12:02:23 -07:00
Paul Berry 4ce0cf3f49 [sound flow analysis] Implement behaviors for null-aware accesses.
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>
2025-04-09 10:13:28 -07:00
Paul Berry 375152e07f [sound flow analysis] Implement behaviors for null-aware operations.
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>
2025-04-09 09:29:32 -07:00
Paul Berry 569c901fef [sound flow analysis] Implement behaviors for equality comparisons.
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>
2025-04-08 13:56:14 -07:00
Paul Berry 6c5c9d384f [sound flow analysis] Implement behaviors for is and as.
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>
2025-04-04 12:11:58 -07:00
Paul Berry 08154451d5 [_fe_analyzer_shared] Use TypeAnalyzerOptions to configure flow analysis.
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>
2025-04-03 11:56:51 -07:00
Paul Berry 6446cce249 [_fe_analyzer_shared] Rename isNever to isBottomType.
This operation was mis-named. Its actual behavior is to check whether
the given type is a bottom type.

Thanks to Lasse for pointing this out (see
https://github.com/dart-lang/language/issues/4304#issuecomment-2761576720).

Change-Id: I6bb1ce459c09a16f6b0466f5081977358e21fb74
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/418640
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2025-03-28 10:57:20 -07:00
Paul Berry 5d78579842 [analyzer] Fix dead code reporting for null-aware accesses.
A null-aware access can result in dead code if the target has static
type `Null`. The analyzer wasn't properly accounting for this,
resulting in some confusing ranges reported for the DEAD_CODE warning.

This change causes the following expressions to report dead code for
the code ranges indiced by `^`:

    Null myNullVar = null;
    myNullVar?[index];
    //         ^^^^^^ DEAD_CODE
    myNullVar?[index] = value;
    //         ^^^^^^^^^^^^^^ DEAD_CODE
    myNullVar?.method();
    //         ^^^^^^^^ DEAD_CODE
    myNullVar?.property;
    //         ^^^^^^^^ DEAD_CODE
    myNullVar?.property = value;
    //         ^^^^^^^^^^^^^^^^ DEAD_CODE

Note that the bug was confined solely to the logic that reports the
DEAD_CODE warning; there is no change to the reachability inferred by
flow analysis (and hence, this is a non-breaking change).

Fixes https://github.com/dart-lang/sdk/issues/60364.

Bug: https://github.com/dart-lang/sdk/issues/60364
Change-Id: I068826282fba6b9057e9c27d1d9310c65714e203
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/416723
Auto-Submit: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
2025-03-20 09:08:53 -07:00
Paul Berry c67a80f3f5 Stop using NullabilitySuffix in fe/analyzer shared code.
The getter `SharedType.nullabilitySuffix` is replaced by
`SharedType.isQuestionType`, which returns a boolean.

The method `TypeAnalyzerOperations.withNullabilitySuffixInternal` is
replaced by `SharedType.setNullabilitySuffix`, which accepts a
boolean.

Support for `*` types has been removed from `mini_types.dart`.

A few test cases in `flow_analysis_test.dart` previously used `*`
types as a way of exercising corner cases involving types that were
mutual subtypes of each other. These tests have been changed to take
advantage of the fact that `dynamic` and `Object?` are mutual
subtypes.

Change-Id: Id9904f9570fc738b388192db8536848204af03e9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/414581
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2025-03-19 11:24:21 -07:00
Paul Berry 7d62bddb17 [_fe_analyzer_shared] Sort declarations in mini_ast.dart and shared_type.dart.
There is no functional change.

Change-Id: I1877d29efddd614688cd34506d5a496a472dea7e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/414260
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Auto-Submit: Paul Berry <paulberry@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
2025-03-10 01:54:00 -07:00
Kallen Tu 5883289bb5 [cfe] Handle equality with dot shorthands.
This CL adds the ability to handle == with dot shorthands in regular equality expressions and then in relational patterns.

Bug: https://github.com/dart-lang/sdk/issues/59758
Change-Id: I958bbaf9e8a63ca576024ef2ee287779064e5967
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/413321
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
2025-03-06 11:09:20 -08:00
Paul Berry 7382fe9d0a Remove legacy support from shared type analyzer and flow analysis.
Now that the ability to run in "unsound null safety" mode has been
removed (https://dart-review.googlesource.com/c/sdk/+/412881), it is
safe to start removing the code that implements legacy
(pre-null-safety) analysis.

Change-Id: I7f998a081704030ce630d3c343185d0d41d4349a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/413524
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2025-03-04 14:17:42 -08:00
Paul Berry 274f5639f7 [Flow analysis] Remove PropertyNotPromoted.staticType.
This field was only used to populate expectation strings in "id"
tests; it did not affect any user-visible behavior of the analyzer or
CFE.

Including information in "id" tests that doesn't affect any
user-visible behavior isn't helpful. Removing this field will enable
some upcoming flow analysis refactoring work (I intend to remove the
`ExpressionInfo._type` field, replacing its remaining usages with a
more reliable mechanism).

Change-Id: Id4c6593fae4ef25b8c21f0625e6c1f9eaa766e17
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/406403
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2025-02-08 16:51:15 -08:00
Johnni Winther 7c22f942aa [_fe_analyzer_shared] Remove macro tests and helpers
These are no longer used.

TEST=removed

Change-Id: Ibf5b2de9d1b550c21873b48111161366deb2ddc0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/407980
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Morgan :) <davidmorgan@google.com>
2025-02-05 03:59:31 -08:00
Jens Johansen ca16a4271c [scanner] Replace KeywordState
As bechmarked with the AOT compiles of `scanner_benchmark.dart`
called with
`pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart --bytes`:

```
    N           Min           Max        Median           Avg        Stddev
x  25     138.56434     144.23326     142.64174     142.51626     1.2207074
+  25     148.45681     157.02163     156.44878     155.88958     1.7051997
Difference at 95.0% confidence
        13.3733 +/- 0.843454
        9.38372% +/- 0.59183%
        (Student's t, pooled s = 1.48287)
```

And compiling the CFE from December with the CFE, statistics on 25 runs
each, run with `--cache --silent` (so 2 x 50 runs each) (in AOT mode):

```
msec task-clock:u: -0.9684% +/- 0.3536% (-58.65 +/- 21.42)
page-faults:u: -0.1051% +/- 0.0818% (-125.36 +/- 97.49)
cycles:u: -1.0001% +/- 0.3225% (-252905081.28 +/- 81554799.59)
instructions:u: -0.5915% +/- 0.0007% (-181426590.44 +/- 209346.28)
seconds time elapsed: -0.9657% +/- 0.3525% (-0.06 +/- 0.02)
seconds user: -1.1336% +/- 0.4333% (-0.07 +/- 0.03)

msec task-clock:u: -1.3115% +/- 0.3364% (-79.48 +/- 20.39)
page-faults:u: -0.1900% +/- 0.0774% (-226.72 +/- 92.37)
L1-icache-load-misses: 0.4990% +/- 0.2072% (2422435.64 +/- 1006075.94)
LLC-loads: -2.3896% +/- 0.1707% (-1179245.64 +/- 84228.28)
LLC-load-misses: -1.9244% +/- 0.2041% (-639169.84 +/- 67791.64)
seconds time elapsed: -1.3128% +/- 0.3374% (-0.08 +/- 0.02)
seconds user: -1.3311% +/- 0.4183% (-0.08 +/- 0.02)
```

Combined the 3 CLs ending here gives this result when compiling
the CFE from December with the CFE, statistics on 25 runs each,
run with `--cache --silent` (so 2 x 50 runs each) (in AOT mode):

```
msec task-clock:u: -1.7681% +/- 0.3034% (-106.37 +/- 18.25)
page-faults:u: -0.1834% +/- 0.0863% (-218.80 +/- 103.00)
cycles:u: -1.8163% +/- 0.2668% (-456090610.64 +/- 66985831.74)
instructions:u: -1.1851% +/- 0.0007% (-365653999.24 +/- 220539.29)
branch-misses:u: -2.8468% +/- 1.0580% (-2611811.72 +/- 970666.69)
seconds time elapsed: -1.7687% +/- 0.3026% (-0.11 +/- 0.02)
seconds user: -1.9723% +/- 0.4480% (-0.11 +/- 0.03)

msec task-clock:u: -1.7787% +/- 0.3042% (-107.07 +/- 18.31)
page-faults:u: -0.2413% +/- 0.1050% (-288.12 +/- 125.39)
L1-icache-load-misses: 0.5218% +/- 0.1599% (2523027.12 +/- 773363.93)
LLC-loads: -2.2917% +/- 0.1613% (-1125147.16 +/- 79181.20)
LLC-load-misses: -2.0256% +/- 0.2667% (-670484.64 +/- 88293.18)
seconds time elapsed: -1.7793% +/- 0.3036% (-0.11 +/- 0.02)
seconds user: -1.7392% +/- 0.3752% (-0.10 +/- 0.02)
```

And for the scanner benchmark, in AOT mode, called with
`pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart --bytes` for bytes per microsecond:

```
    N           Min           Max        Median           Avg        Stddev
x  25     114.87867     117.70322     117.10106        116.85    0.67188864
+  25       153.512     156.99315     156.38671     155.95981    0.98376554
Difference at 95.0% confidence
        39.1098 +/- 0.479146
        33.4701% +/- 0.410053%
        (Student's t, pooled s = 0.842386)
```

Change-Id: Ica6d47d92ab0fb4c3a06aa6686b8c71f52a6aef8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/407480
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2025-02-05 03:12:26 -08:00
Jens Johansen 95265c319c [scanner] Optimize scanning of identifiers, comments, spaces etc.
In bytes per microsecond, statistics on 25 runs each of an AOT compile
scanner_benchmarker run with
`pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart --bytes`:

```
    N           Min           Max        Median           Avg        Stddev
x  25     116.01859     118.24483     117.63414     117.41239     0.6246963
+  25      136.5563     139.73077     138.82117     138.72373    0.75137577
Difference at 95.0% confidence
        21.3113 +/- 0.393007
        18.1508% +/- 0.334724%
        (Student's t, pooled s = 0.690945)
```

With `--string`:

```
    N           Min           Max        Median           Avg        Stddev
x  25     104.77452     118.00444     115.83707     115.04005     2.8653416
+  25      120.1637     125.80937     123.84278     123.88533     1.2858698
Difference at 95.0% confidence
        8.84528 +/- 1.26317
        7.68887% +/- 1.09802%
        (Student's t, pooled s = 2.22077)
```

And running it through the benchmarker
(`pkg/front_end/tool/benchmarker.dart --cache --silent
--iterations=25`):

`--bytes`:

```
msec task-clock:u: -15.4177% +/- 0.3838% (-515.18 +/- 12.83)
cycles:u: -15.5303% +/- 0.3716% (-2263042219.68 +/- 54143984.97)
instructions:u: -11.8786% +/- 0.0000% (-3721971162.16 +/- 292.14)
branch-misses:u: -13.0375% +/- 0.8048% (-10550278.80 +/- 651299.13)
seconds time elapsed: -15.4170% +/- 0.3820% (-0.52 +/- 0.01)
seconds user: -15.4936% +/- 0.3859% (-0.51 +/- 0.01)

msec task-clock:u: -15.1724% +/- 0.3173% (-505.72 +/- 10.58)
L1-icache-load-misses: 42.3794% +/- 6.4906% (1901929.52 +/- 291287.30)
LLC-loads: 3.2837% +/- 0.7535% (40264.52 +/- 9239.86)
LLC-load-misses: -2.2808% +/- 1.3789% (-3647.96 +/- 2205.39)
seconds time elapsed: -15.1722% +/- 0.3201% (-0.51 +/- 0.01)
seconds user: -15.1811% +/- 0.3196% (-0.50 +/- 0.01)
```

`--string`:

```
msec task-clock:u: -6.2018% +/- 0.3384% (-207.18 +/- 11.31)
cycles:u: -6.2315% +/- 0.3257% (-907517140.20 +/- 47432247.03)
instructions:u: -7.2693% +/- 0.0000% (-2325765423.72 +/- 491.22)
branch-misses:u: -2.6467% +/- 0.6289% (-2198552.96 +/- 522409.28)
seconds time elapsed: -6.1995% +/- 0.3378% (-0.21 +/- 0.01)
seconds user: -6.2612% +/- 0.3705% (-0.21 +/- 0.01)

msec task-clock:u: -6.1645% +/- 0.4224% (-206.18 +/- 14.13)
L1-icache-load-misses: 40.5703% +/- 6.3952% (1945020.52 +/- 306599.42)
LLC-loads: 1.5464% +/- 0.8925% (20130.04 +/- 11618.51)
seconds time elapsed: -6.1656% +/- 0.4197% (-0.21 +/- 0.01)
seconds user: -6.1980% +/- 0.4240% (-0.21 +/- 0.01)
```

And compiling the CFE from December with the CFE, statistics on 50 runs
each, again run with `--cache --silent` (so 2 x 50 runs each):

```
msec task-clock:u: -0.7401% +/- 0.1900% (-45.01 +/- 11.56)
cycles:u: -0.7971% +/- 0.1917% (-202488820.10 +/- 48684812.34)
instructions:u: -0.5975% +/- 0.0004% (-184367556.38 +/- 137673.23)
branch-misses:u: -2.9490% +/- 0.8146% (-2788427.60 +/- 770259.65)
seconds time elapsed: -0.7428% +/- 0.1901% (-0.05 +/- 0.01)
seconds user: -0.7148% +/- 0.2895% (-0.04 +/- 0.02)

L1-icache-load-misses: 0.1974% +/- 0.1457% (954253.92 +/- 704297.81)
LLC-loads: 0.1988% +/- 0.1244% (97594.22 +/- 61084.80)
```

Change-Id: I0550596f5320a1ff00d85765c121d012f55bec61
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/407400
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
2025-02-05 03:04:24 -08:00
Johnni Winther 938d9c0dc8 [cfe] Create synthesized super classes late
This moves the creation of class builders for anonymous mixin application to after the creation of the normal class builders.

A ClassDeclaration interface is added to support class builders from different fragments. This is also a step towards creating class builders fully through fragments.

TEST=existing

Change-Id: Ia6b4a17648bdc89b89fd3cfdfe39d24d347b6341
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/407420
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
2025-02-04 07:08:41 -08:00
Johnni Winther c27cec63aa [cfe] Remove macro support
This removes the support running macros in the CFE.

The scanner and package:kernel still have support for the macro modifier. This will be removed in a follow-up.

The metadata expression parser is deliberately left in, since it might serve as the basis for a parser AST.

Change-Id: I06d91eb0fac2e7a71e6afde647b03be3814dbd5f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/406963
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Morgan :) <davidmorgan@google.com>
2025-02-03 07:13:51 -08:00
Johnni Winther 7f46b33019 [_fe_analyzer_shared] Return the shortest witness
This updates the exhaustiveness checking to return the shortest witness when no more cases match a value.

This also fixes an exponential case that occurred when checking for reachability.

Closes #59927

Change-Id: I82ede75113ca5d361875620287f7ce3c5fb2f5d2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/405120
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
2025-01-21 00:24:33 -08:00
Chloe Stefantsova dcd410efd4 [analyzer][cfe] Remove TypeStructure variable from shared classes
Part of https://github.com/dart-lang/sdk/issues/54902

Change-Id: Ia70f2afd321e9b4a4762b6ed860611dee1399d87
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/404622
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
2025-01-20 01:58:43 -08:00
Paul Berry e1ba3ea504 [_fe_analyzer_shared] Move TypeConstraintGatherer to its own file.
Since the class `TypeConstraintGatherer` (which is only used in
`_fe_analyzer_shared`'s unit tests) is now used both by
`type_constraint_gatherer_test.dart` and by `mini_ast.dart`, it makes
sense for it to live in its own file.

Change-Id: I7c8a58cfbf3724e2c8313b701345bc47ce032522
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/404060
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
2025-01-14 06:40:18 -08:00
Jens Johansen c075d939e0 [parser/scanner] Remove ScannerConfig enableNonNullable
Change-Id: If6bfbb65a02ac1a4f5708ab9e8c4d66c19ecff86
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/403984
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
2025-01-13 00:32:35 -08:00
Jens Johansen 5dfce919cd [parser/scanner] Remove ScannerConfig enableExtensionMethods
Extension methods can no longer be disabled. This CL removes the option
from the scanner config and the parser related specific recovery.
It also removes any specific (triggered) test of the functionality.
A follow-up CL will do the same for NNBD.

Change-Id: Ia385008e5ed1333fb37697b8fe424b8759bce198
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/403581
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
2025-01-13 00:32:25 -08:00
Paul Berry 9a472930e5 [_fe_analyzer_shared] Renames to prepare for analyzer refactoring.
The following shared getters are renamed so that their names are
distinct from the corresponding getters in the analyzer:

- `SharedFunctionTypeStructure.positionalParameterTypes` is renamed to
  `positionalParameterTypesShared` to be distinct from the analyzer's
  public getter `FunctionType.positionalParameterTypes`.*

- `SharedFunctionTypeStructure.returnType` is renamed to
  `returnTypeShared` to be distinct from the analyzer's public getter
  `FunctionType.returnType`.

- `SharedNamedFunctionParameterStructure.type` is renamed to
  `typeShared` to be distinct from the analyzer's public getter
  `FormalParameterElement.type`.

- `SharedNamedTypeStructure.type` is renamed to `typeShared` to be
  distinct from the analyzer's public getter
  `RecordTypeNamedField.type`.

- `SharedRecordTypeStructure.positionalTypes` is renamed to
  `positionalTypesShared` to be distinct from the analyzer's public
  getter `RecordType.positionalTypes`.*

- `SharedRecordTypeStructure.sortedNamedTypes` is renamed to
  `sortedNamedTypesShared` to be distinct from the analyzer's public
  getter `RecordType.sortedNamedTypes`.

- `SharedTypeParameterStructure.bound` is renamed to `boundShared` to
  be distinct from the analyzer's public getter
  `TypeParameterElement2.bound`.

*Note that `FunctionType.positionalParameterTypes`,
 `RecordType.positionalTypes`, and `RecordType.sortedNamedTypes` were
 unintentionally exposed as part of the analyzer's public API. In a
 previous CL I marked them as deprecated.

These renames pave the way for changing the analyzer's `DartType`
class so that it implements `SharedTypeStructure<TypeImpl>` rather
than `SharedTypeStructure<DartType>` (without the renames, the public
getters mentioned above would all have to be changed to have type
`TypeImpl`, and that in turn would expose `TypeImpl` through the
analyzer public API, which we don't want to do).

Once `DartType` implements `SharedTypeStructure<TypeImpl>`, that will
allow all the other uses of `SharedTypeStructure<DartType>` in the
analyzer to be gradually migrated to
`SharedTypeStructure<TypeImpl>`. Once that is done, `DartType` can be
changed so that it no longer implements
`SharedTypeStructure<TypeImpl>` at all (`TypeImpl` will implement
`SharedTypeStructure<TypeImpl> instead). This will free us up to make
future changes to the `SharedTypeStructure` base class without
inadvertently exposing those changes through the analyzer public API.

This is part of a larger arc of work to change the analyzer's use of
the shared code so that the type parameters it supplies are not part
of the analyzer public API. See
https://github.com/dart-lang/sdk/issues/59763.

Change-Id: I0686fdeae304f8948484516f0249841b79e7da6c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/403625
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2025-01-10 14:32:47 -08:00
Chloe Stefantsova f49c620ab3 [analyzer][cfe] Share inference-using-bounds routines
Part of https://github.com/dart-lang/sdk/issues/54902

Change-Id: I12282c2492ed9f1220b47fcf8b0d73c93bbfc432
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/401660
Reviewed-by: Erik Ernst <eernst@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
2025-01-09 03:13:06 -08:00
Paul Berry a8b8df2e45 [_fe_analyzer_shared] Renames to prepare for analyzer refactoring.
The following shared getters are renamed so that their names are
distinct from the corresponding getters in the analyzer:

- `SharedFunctionTypeStructure.sortedNamedParameters` is renamed to
  `sortedNamedParametersShared` to be distinct from the analyzer's
  getter `FunctionTypeImpl.sortedNamedParameters`.

- `SharedFunctionTypeStructure.typeFormals` is renamed to
  `typeParametersShared` to be distinct from the analyzer's getter
  `FunctionTypeImpl.typeFormals`.

- `SharedNamedFunctionParameterStructure.name` is renamed to
  `nameShared` to be distinct from the analyzer's getter
  `ParameterElement.name`.

- `SharedNamedTypeStructure.name` is renamed to `nameShared` to be
  distinct from the analyzer's getter `RecordTypeNamedFieldImpl.name`.

These renames pave the way for switching the analyzer's use of these
shared types over to the new element model. They're necessary because
when the analyzer switches over to the new element model:

- `FunctionTypeImpl.sortedNamedParameters` will no longer have the
  correct type to override
  `SharedFunctionTypeStructure.sortedNamedParameters`; instead, it
  will be necessary to convert each named parameter to a corresponding
  element in the new element model (`FormalParameterElementImpl` or
  `ParameterMember`).

- `FunctionTypeImpl.typeFormals` will no longer have the correct type
  to override `SharedFunctionTypeStructure.typeParametersShared`;
  instead, it will be necessary to use
  `FunctionTypeImpl.typeParameters` (which is a list of
  new element model type parameters).

- `ParameterElementMixin` will no longer implement
  `SharedNamedFunctionParameterStructure`; instead,
  `FormalParameterElementImpl` and `ParameterMember` (which are
  classes in the new element model) will implement it. The class
  `FormalParameterElementImpl` deliberately doesn't have a `name`
  getter; instead it has a `name3` getter, with slightly different
  semantics (it returns `null` rather than the empty string when there
  is no name).

Change-Id: I629e45b6fc588e6a86f7590aab853064e31ab661
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/402220
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2025-01-06 06:12:22 -08:00