Commit Graph

752 Commits

Author SHA1 Message Date
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
Paul Berry 574e54db67 [_fe_analyzer_shared] Add shared logic to support null-shorting.
This change introduces a new mixin, `NullShortingMixin`, with a type
parameter `Guard` for the data structure used by the client to desugar
null-aware accesses. The mixin maintains a stack of these guards, and
provides methods that the client can use to manipulate the stack:

- `startNullShorting` adds an entry to the stack; it should be called
  when the client encounters the `?.` part of a null-aware expression.

It also provides two hooks that the client can override if desired:

- `handleNullShortingStep`, called whenever an entry is removed from
  the stack; this will let the CFE know when it should de-sugar a null
  short using a "let" expression.

- `handleNullShortingFinished`, called whenever a sequence of entries
  is removed from the stack; this will let the analyzer know when it
  should change the static type of an expression as a result of
  null-shorting.

Also, a new optional parameter, `continueNullShorting`, is added to
`TypeAnalyzer.analyzeExpression`. If this parameter is `false` (the
default value), then any null shorting that is started during analysis
of the expression (due to the client calling `startNullShorting`) will
be terminated before returning. If it is `true`, then null shorting
won't be terminated, so it will extend to the containing
expression. For expression types that are able to extend null shorting
that appears in their target subexpression (e.g., method calls and
property accesses), the `visit` or `analyze` method should pass
`false` for this parameter when making a recursive call to analyze the
target.

Finally, the `NullShortingMixin` has a getter `nullShortingDepth`,
that `TypeAnalyzer.analyzeExpression` uses to determine when null
shorting should be terminated, and a method `finishNullShorting`, that
actually does the work of terminating null shorting. In principle,
clients don't need to invoke these parts of the `NullShortingMixin`
API. However, since the CFE doesn't always use
`TypeAnalyzer.analyzeExpression` (favoring its own internal methods
`InferenceVisitorImpl.inferExpression` and
`InferenceVisitorImpl.inferNullAwareExpression`), the CFE will need to
use them.

The "mini_ast" tests of flow analysis formerly used a method called
`nullAwareAccess` to exercise the flow analysis effects of null-aware
constructs. This was hacky and confusing, and is now unnecessary,
since the shared infrastructure now fully supports null-shorting. So
this method has been removed and replaced by the ability to mark a
method invocation or property access as null-aware.

This change only builds the infrastructure for shared analysis of
null-shorting; the analyzer and CFE still handle null shorting on
their own. In follow-up CLs I will change the analyzer and CFE to make
use of the shared mechanism.

Change-Id: Ide25a915c4d06eab751b87c1c2745749d23a8114
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/399480
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2024-12-10 19:07:18 +00:00
Paul Berry 333ba4d754 [_fe_analyzer_shared] Simplify some "mini_ast" check() methods.
Rework the methods `checkIR`, `checkSchema`, and `checkType`, so that
rather wrap the `CollectionElement`, `Expression`, or `Statement` node
in a new node that performs the check, they return the existing node,
and store the value to be checked in a private field. The checks are
now performed as a side effect of `dispatchCollectionElement`,
`dispatchExpression`, or `dispatchStatement`.

The major advantage of this change is that previously, adding one of
these checks to an expression in a "mini_ast" test caused an extra
call to be made to `analyzeParenthesizedExpression`, so that flow
analysis information would be propagated from the wrapped node to the
node that performs the check. At the moment, extra calls to
`analyzeParenthesizedExpression` don't have any effect other than
forwarding flow analysis information, so this is benign. But in a
follow-up CL, I plan to add null-shorting support to "mini_ast" tests,
and this will mean that a side effect of
`analyzeParentehsizedExpression` is to terminate null
shorting. Re-working the checks now will ensure that when
null-shorting support is added, the checks won't terminate null
shorting as an accidental side-effect.

Change-Id: I484f29b3ce63e15ab19100462d6a4b5c6b875d34
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/399025
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2024-12-06 19:37:32 +00:00
Paul Berry 0197beaa8e [flow analysis] Remove _typeContains method.
It wasn't necessary; `List.contains` does the same thing.

Also, remove the plumbing for `typeOperations`, a parameter of
`_typeContains` that was not used.

Change-Id: I688835512e58cb7a24336318b2006c9913c77888
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/398300
Auto-Submit: Paul Berry <paulberry@google.com>
Reviewed-by: Kallen Tu <kallentu@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
2024-12-02 18:54:24 +00:00
Paul Berry 6c4c1cb635 Sort declarations in type_analysis_result.dart and mini_ast.dart
Change-Id: Id7d42c294798b4673d5d37deebce5b8720b38388
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/398280
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
Auto-Submit: Paul Berry <paulberry@google.com>
2024-12-02 14:21:17 +00:00
Paul Berry f601692dd7 [_fe_analyzer_shared] Add SharedNullTypeStructure class.
This is the shared base class for all representations of the type
`Null`. This allows the shared codebase to use `is` tests to tell when
a type is `Null`.

Change-Id: I98059b60c7eaab9c9f1e3f7addb7913dffc9cf9d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/396380
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2024-11-20 14:55:00 +00:00
Chloe Stefantsova d79fcdf4cd [analyzer][cfe] Remove unnecessary use of shared views
This CL removes the unnecessary conversion from `TypeStructure` types
to `SharedTypeView` and `SharedTypeSchemaView` and back. By design,
the shared constraint generation method is operating on
`TypeStructure` types and uses the shared procedures named with the
'Internal' suffix to transform those types. In this CL the shared
procedures that are only used in the shared constraint generation
method or in 'Internal' procedures are converted to 'Internal'
themselves, and the corresponding update in the parameters accepted
and returned by those procedures is made.

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

Change-Id: Ic8596b342bde7e78093e990fc0f12f705ff6dee1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/395962
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
2024-11-19 17:17:13 +00:00
Paul Berry 5ec81d0801 [mini_types] Add support for type parameters of function types with bounds.
This required improving the implementation of `operator == ` for
function types, to check that the bounds match (after performing
appropriate substitutions). It also required modifiying
`FunctionType.substitute` to apply the substitution to the bounds.

The API for `TypeParameter` was changed slightly, so that it's
possible to distinguish between an explicit bound of `Object?` an an
implicit one. This allows `FunctionType.toString()` to avoid
outputting `extends Object?` next to a type parameter that has an
implicit bound.

Change-Id: Iad31a44a1f87ca0cd830b8c802495b7ce2c1caab
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/396141
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2024-11-19 16:52:40 +00:00
Chloe Stefantsova e2c17b938f Enable 'inference-using-bounds' flag in 3.7
TEST=existing

Change-Id: If7f143ab6c60cfda962c1ceba78fdbfdd949a3cc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/394140
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
2024-11-19 08:54:03 +00:00
Paul Berry 6f4cf5631a [mini_types] Add support for generic function types.
Generic function types have the following special behaviors:

- Their implementations of `hashCode` and `==` take care to ensure
  that if two generic types differ only in the names of their type
  parameters (i.e. they are alpha-equivalent), they will compare equal
  and have the same hash code. For example, `T Function<T>()` and `U
  Function<U>()` represent the same type. This logic takes advantage
  of `Type.substitute` and `Type.gatherUsedIdentifiers`, added in
  recent CLs.

- When parsing a generic function type, references to type formals can
  appear in the return type or parameter types. E.g. in the function
  type `T Function<T>()`, the return type `T` refers to the type
  formal `T` declared by the function type. It doesn't refer to a `T`
  declared elsewhere. To make this possible, the parameter
  `typeFormalScope` has been added to `Type.materialize`; this carries
  the meaning of type formals through the recursive process of
  transforming a `_PreType` into a corresponding `Type`.

In a follow-up CL, I will use this new support to unit test the
generic function type logic that's recently been added to
`TypeConstraintGenerator` (see
https://dart-review.googlesource.com/c/sdk/+/393860).

Change-Id: Ib5e392f844990185b2602d22809eac5599505aff
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/395687
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2024-11-18 20:23:20 +00:00
Paul Berry 2a4ce143f3 [mini_types] Introduce _PreType class hierarchy.
The `_PreType` class (and its subclasses) mirrors the `Type` class,
except that it represents types in a more raw form, before identifiers
have been resolved to their associated meanings. For example, the
`_PreType` representing `int` is a `_PrePrimaryType` whose `typeName`
field is the string `int`, whereas the `Type` representing `int` is a
`PrimaryType` whose `nameInfo` field points to the `TypeNameInfo`
object representing the class `int`.

Parsing of `Type` objects is now a two-step process: the string is
first converted to a `_PreType`, and then the `_PreType` is
materialized into a `Type` by looking up each identifier in it in the
`TypeRegistry`.

This will be needed in a follow-up CL that introduces support for
generic function types, to support the possiblity that a generic
function type's return type refers to one of its type parameters
(e.g. `List<T> Function<T>()`). The reason this is will be needed is
because the meaning of the return type (`List<T>`) can't be determined
until the `TypeParameter` object representing the type parameter `T`
has been created.

Change-Id: I9f4a73bdc0f38380518a9c39db8c788234adb806
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/395686
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2024-11-18 19:05:17 +00:00
Paul Berry ae0b50d62b [mini_types] Add a Type.gatherUsedIdentifiers method.
This method will be used by a follow-up CL that adds support for
generic functions, since the implementation of `==` and `hashCode` for
generic functions needs to perform substitutions in order to recognize
that alpha-equivalent types (such as `T Function<T>()` and `U
Function<U>`) are equal, and those substitutions need to avoid name
collisions with identifier names that already appear in the type.

Change-Id: Ifd237a9842791f440e285d89e9d80b898e996411
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/395685
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2024-11-18 18:27:11 +00:00