Commit Graph

1027 Commits

Author SHA1 Message Date
Jake Macdonald 1b99100e2e Add API for resolving any identifier in the final macro phase.
- Rename declarationOf to typeDeclarationOf.
- Add declarationOf api for general declarations.
- Tighten the type of typeDeclarationOf in the final phase to avoid unnecessary
  casts in user code.
- Refactor message handling a bit to unify the error handling.

Bug: https://github.com/dart-lang/language/issues/3216
Change-Id: Ia61da19374abec77853d37e110a08f7dfe0d3b10
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/314280
Commit-Queue: Jake Macdonald <jakemac@google.com>
Auto-Submit: Jake Macdonald <jakemac@google.com>
Reviewed-by: Bob Nystrom <rnystrom@google.com>
2023-07-19 13:56:08 +00:00
Joshua Litt 9e37c2b480 [dart2wasm] Add JS compatibility mode.
The purpose of the wasm_js_compatibility target is to facilitate experiments with a JS compatibility mode for Dart2Wasm. Initially, we're just going to focus on typed data, but this will give us a place to experiment with moving List and String to JS as well.

In addition, someday down the road we hope to experiment with two additional compatibility changes:
1) Exclusively using double for all Dart numbers
2) Allowing undefined to flow as null.

The two major benefits of this approach are:
1) Much faster JS interop
2) To make it easier to bring up Dart2JS applications on Dart2Wasm

The only downside will be access overhead on the Wasm side, but the JS builtins proposal could potentially bring us close to parity with Wasm builtins someday.

Tested: Wasm specific trivial refactor.
Change-Id: I2c09426b6999507c1de6e584e9bc7072a088bda9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/313240
Commit-Queue: Joshua Litt <joshualitt@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
Reviewed-by: William Hesse <whesse@google.com>
2023-07-18 19:34:38 +00:00
Paul Berry 130d6199c3 Field promotion: make the core promotability algorithm sharable; fix bugs
In the following code, it's not safe for the field `C._f` to undergo
type promotion, because a variable with static type `C` might have
type `D` at runtime, in which case `C._f` will get dispatched to
`noSuchMethod`, which is not guaranteed to return a stable result.

    class C {
      final int? _f;
    }
    class D implements C {
      noSuchMethod(_) => ...;
    }
    foo(C c) {
      if (c._f != null) {
        print(c._f + 1); // UNSAFE!
      }
    }

Therefore, in order to determine which fields are promotable, the
implementations need to analyze enough of the class hierarchy to
figure out which field accesses might get dispatched to
`noSuchMethod`.

Currently, the CFE does this by following its usual algorithm for
generating `noSuchMethod` forwarders before trying to determine which
fields are promotable. The analyzer, on the other hand, doesn't have
an algorithm for generating `noSuchMethod` forwarders (since it
doesn't implement execution semantics); so instead it has its own
logic to figure out when a `noSuchMethod` forwarder is needed for a
field, and disable promotion for that field.

But there's a chicken-and-egg problem in the CFE: the CFE needs to
determine which fields are promotable before doing top-level inference
(since the initializers of top-level fields might make use of field
promotion, affecting their inferred types--see #50522). But it doesn't
decide where `noSuchMethod` forwarders are needed until after
top-level inference (because the same phase that generates
`noSuchMethod` forwarders also generates forwarders that do runtime
covariant type-checking, and so it has to run after all top level
types have been inferred).

To fix the chicken-and-egg problem, I plan to rework the CFE so that
it uses the same algorithm as the analyzer to determine which fields
are promotable. This CL makes a first step towards that goal, by
reworking the analyzer's field promotability algorithm into a form
where it can be shared with the CFE, and moving it to
`package:_fe_analyzer_shared`.  Since this required a fairly
substantial rewrite, I went ahead and fixed #52938 in the process.

Fixes #52938.

Change-Id: I9e68f51b3ea9a967f55f15bdc445cc1c0efdabdd
Bug: https://github.com/dart-lang/sdk/issues/52938
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/313293
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2023-07-18 18:54:26 +00:00
Jake Macdonald c5bd32bac2 Major refactor to simplify the macro introspection interfaces.
Each phase now only has a single interface, instead of several of them. This
reduces the number of classes dramatically and also reduces the number of
objects actually sent over the wire.

It also means fewer things to name and a less polluted namespace.

Change-Id: Ib84b76ac4c0a04abfac5fd5650a228046b1bf1d4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/313721
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Jake Macdonald <jakemac@google.com>
2023-07-17 17:28:35 +00:00
Konstantin Shcheglov 57ac271bf1 Verify that 'utf8.encode()' is not used in the analyzer.
To be removed after Dart SDK 3.1 is published, and the analyzer
SDK constraints updated.

See
https://dart-review.googlesource.com/c/sdk/+/254903

Change-Id: I2c3321d991cd3e123f08c5a360487362be16f258
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/313920
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
2023-07-17 17:28:31 +00:00
Jake Macdonald 4f8061da63 Add MetadataAnnotation class and metadata fields to relevant objects
Bug: https://github.com/dart-lang/language/issues/1930
Change-Id: I3ba6facd4c0487b0af18108c8d1db21ee6d5a498
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/313640
Auto-Submit: Jake Macdonald <jakemac@google.com>
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Jake Macdonald <jakemac@google.com>
2023-07-14 15:55:20 +00:00
Paul Berry 3ae6793469 Flow analysis: remove redundant assertion from constructor.
The assertion in the `_FlowAnalysisImpl` constructor was unnecessary
because it was checking that all variables that are reported to
`AssignedVariables` as read or written must also be reported as
declared. This is already checked by assertions in
`AssignedVariables.finish`, which is called by the `_FlowAnalysisImpl`
constructor.

I've added tests to `assigned_variables_test.dart` to confirm that
these assertions work, and I've also cleaned up the assertions a bit,
eliminating some redundancy and ensuring that in the event of a
failure the assertion failure message will be comprehensible.

Change-Id: Ife827c91d944707f093f4cb8421385f5355d11fa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/313140
Auto-Submit: Paul Berry <paulberry@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2023-07-11 21:03:29 +00:00
Johnni Winther 0d47ba6890 [_fe_analyzer_shared] Remove RecordStaticType.isSubtypeOfInternal
This method caused invalid exhaustiveness checking by seeing
record types as related based solely on the structure.

The original purpose of the methods has been removed in the mean time
by the change to restrict the created spaces by the matched value
type.

Closes #52800

Change-Id: I8fb581374a4813dc63261d9e1354c4eea94f212c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/312982
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
2023-07-11 12:19:39 +00:00
Jake Macdonald 1a13ea6c05 Add a disposeMacro api, with TODOs in the implementations to call it.
Change-Id: I38049ca8b851c2203ddaaa729ef651e7802a1d2b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/312860
Auto-Submit: Jake Macdonald <jakemac@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2023-07-10 12:01:49 +00:00
Jake Macdonald 658de58b4f move the majority of the client bootstrap code into a real library to make it more maintainable
Change-Id: Id84981b236176c7831cece61692ec895ba2ac1e2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/312723
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Jake Macdonald <jakemac@google.com>
Auto-Submit: Jake Macdonald <jakemac@google.com>
2023-07-06 21:12:58 +00:00
Jake Macdonald f254c8a4ba Add library macro definitions and support for executing them.
These are intended to be applied by annotating a library directive.

Note that some parameter types had to be widened since `Library` is not a subtype of `Declaration`. Ultimately I think that is fine though.

Bug:https://github.com/dart-lang/language/issues/2839
Change-Id: Ia1311c8aea729f2bd8b76173ce4c7595a6a37a42
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/312140
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Auto-Submit: Jake Macdonald <jakemac@google.com>
Commit-Queue: Jake Macdonald <jakemac@google.com>
2023-07-05 18:56:53 +00:00
Jake Macdonald 34f25c4a28 Add library introspection apis for macros.
Allows you to ask for the types in a library in the declarations phase, and all
the top level declarations in the definitions phase.

Bug: https://github.com/dart-lang/language/issues/2839
Change-Id: If0f8fb777fd8a006d686d457cf5d5ca11fcca9ee
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311900
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Jake Macdonald <jakemac@google.com>
Reviewed-by: Bob Nystrom <rnystrom@google.com>
2023-06-29 22:05:58 +00:00
Jake Macdonald d1ecf01f71 Cache remote objects by ID, only send IDs for already sent objects
This is done through a synchronized cache between the server and client. When serializing a remote instance, if the server has already serialized that object then it will only send the ID in the future.

These caches currently only live as long as a single macro application in a given phase, but could live longer in the future. They do need to get reliably cleared out to avoid memory leaks though, and the shorter lifetime is easier to manage consistently.

This also allowed me to remove the specialized server/client modes (clients would always only send back IDs previously).

Change-Id: I4e8a102403153829d66b0ac379636f5a95a70cea
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311420
Commit-Queue: Jake Macdonald <jakemac@google.com>
Reviewed-by: Bob Nystrom <rnystrom@google.com>
2023-06-26 22:36:37 +00:00
Martin Kustermann bee46896d8 [cfe] Use Uint8List instead of List<int> for representing bytes
Seems to reduce instruction count by 4% (when using AOT-compiled
pkg/vm/bin/gen_kernel.dart to compile pkg/compiler/lib/src/dart2js.)

Change-Id: Ica88716bd9c06ea446258cd3eb4f26ca1890805b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311121
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
2023-06-26 08:07:13 +00:00
Jake Macdonald b9bcfa7004 add Library and LanguageVersion classes, all declarations now have a library
Bug: https://github.com/dart-lang/language/issues/2839
Change-Id: Id09b2da070302b67f7c9921f1ad8a6d91a129f77
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/311000
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Jake Macdonald <jakemac@google.com>
2023-06-22 20:37:14 +00:00
Aske Simon Christensen 5838562040 [dart2wasm] Add option and target for stringref.
This adds basic infrastructure for a stringref implementation in
dart2wasm:

- A `--[no-]stringref` option to the compiler
- An option in the `WasmTarget`, controlling the name of the target
- Separate sets of patch files for the two targets
- Separate platform dill files for the two targets

For now, the patch file contents are the same, and the compiler flag
is not used by the backend (only by the `dart2wasm` script to select
the appropriate platform dill file). Both of these will change as the
implementation progresses.

Tested: ci + manual check that the option selects the correct dill
Change-Id: I2c9bb95ba06fd3de3f7007703ef545e3f0c728ba
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/310621
Commit-Queue: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
2023-06-21 14:25:38 +00:00
Johnni Winther 9059949ce9 [cfe] Initial check of macro annotations
This adds a check that all annotations of macro classes correspond
to applied macro applications. This should be improved in the future
to detect what the problem with the annotation was. For now it helps
avoid inadvertently using invalid/unrecognized annotations in the
macro feature development.

Change-Id: I9574e2e24150d2febfc5489ab4ebf0ae2627e3fd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/310101
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
2023-06-20 07:36:21 +00:00
Paul Berry 80bc65bb0b Flow analysis: add field promotion support for cascades.
This change updates the flow analysis support for field promotion
(which is not yet switched on by default) so that it supports field
accesses inside cascade expressions. The key moving parts are:

- The type hierarchy `PropertyTarget` (which is used by the client to
  tell flow analysis whether the target of a property access is
  `this`, `super`, or an ordinary expression) now has a new class,
  `CascadePropertyTarget`, to represent the situation where the target
  of the property access is an implicit reference to the target of the
  innermost enclosing cascade expression.

- Flow analysis has two new methods on its API:
  `cascadeExpression_afterTarget` and `cascadeExpression_end`, so that
  the client can inform flow analysis when a cascade expression is
  being analyzed.

- Flow analysis uses its `_makeTemporaryReference` method to track the
  implicit temporary variable that stores the target of cascade
  expressions. (This method was developed as part of flow analysis
  support for patterns, where it creates the data structures necessary
  to track the implicit variables that are created as part of pattern
  desugaring).

- The "mini-AST" pseudo-language used by flow analysis unit tests now
  has a way to represent cascade expressions and method invocations.

- In addition to unit tests for `_fe_analyzer_shared`, `analyzer`, and
  `front_end`, there are new language tests in
  `tests/language/inference_update_2` to test cascaded field
  promotions in end-to-end fashion.

Bug: https://github.com/dart-lang/language/issues/2020
Change-Id: I21353bbc884ed599cb1739cecfb68ad1d975d18b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/309220
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2023-06-17 08:13:20 +00:00
Jake Macdonald 96dcb2a5ab add support for type annotations and code arguments
Change-Id: I14ad05e810494de94f7935b7ca11b1922f90ecda
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/309021
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Jake Macdonald <jakemac@google.com>
2023-06-16 16:59:06 +00:00
Jake Macdonald 4590fc83e7 Reland "Add wrappers for macro arguments to help with serialization."
The type arguments have to be explicitly given for collection types,
but this should be doable given they are all constants and only certain
types are allowed.

Change-Id: I2721f37d194d73de1df81302298101adeb87534c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/309460
Commit-Queue: Jake Macdonald <jakemac@google.com>
Reviewed-by: Bob Nystrom <rnystrom@google.com>
2023-06-16 14:02:05 +00:00
Paul Berry 788a3a95c2 Flow analysis: clean up public method call to functionExpression_begin.
In a future CL, I plan to refactor some of the flow analysis API so
that the CFE can supply subexpressions to flow analysis before they
are lowered, rather than after. This should help reduce the risk of
bugs where lowering leads to type promotion being lost
(e.g. https://github.com/dart-lang/sdk/issues/52183).

The refactor I'm planning will be easier if there are no calls to the
flow analysis API within flow analysis itself, so to prepare for it,
this CL moves the body of `FlowAnalysisImpl.functionExpression_begin`
to a private method, and updates both `functionExpression_begin` and
`lateInitializer_begin` (which use the same underlying logic) to call
that private method.

Bug: https://github.com/dart-lang/sdk/issues/52189
Change-Id: I1185418225b8a402670e6eece6599c326fdc234a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/309440
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2023-06-16 10:18:05 +00:00
Ilya Yanok 396ed71267 Revert "Add wrappers for macro arguments to help with serialization."
This reverts commit ea7e014c3c.

Reason for revert: breaks Analyzer tests, CBuild regression.

Original change's description:
> Add wrappers for macro arguments to help with serialization.
>
> In particular this allows us to reproduce type arguments for collections in the
> macro expansion isolate.
>
> The type arguments have to be explicitly given for collection types,
> but this should be doable given they are all constants and only certain
> types are allowed.
>
> Bug: https://github.com/dart-lang/language/issues/2212
> Change-Id: I14a688ed294cf060c004849efa975b5bef053d5b
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/308202
> Reviewed-by: Bob Nystrom <rnystrom@google.com>
> Reviewed-by: Johnni Winther <johnniwinther@google.com>
> Commit-Queue: Jake Macdonald <jakemac@google.com>
> Reviewed-by: Konstantin Shcheglov <scheglov@google.com>

Bug: https://github.com/dart-lang/language/issues/2212
Change-Id: I402802c7a1c27f9aee3f23baef8c0deb71ec06e9
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/309284
Commit-Queue: Ilya Yanok <yanok@google.com>
Reviewed-by: Alexander Thomas <athom@google.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
2023-06-14 15:34:37 +00:00
Jake Macdonald ea7e014c3c Add wrappers for macro arguments to help with serialization.
In particular this allows us to reproduce type arguments for collections in the
macro expansion isolate.

The type arguments have to be explicitly given for collection types,
but this should be doable given they are all constants and only certain
types are allowed.

Bug: https://github.com/dart-lang/language/issues/2212
Change-Id: I14a688ed294cf060c004849efa975b5bef053d5b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/308202
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jake Macdonald <jakemac@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2023-06-14 14:54:30 +00:00
Kallen Tu 0b03e711bf [cfe] Change error message for mixin subtype restriction.
Make better error message for mixins since they can't be final nor
sealed.

Bug: https://github.com/dart-lang/sdk/issues/52697
Change-Id: I56a9cb66131c0a47ea1c91b95dcf70d12835134e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/308964
Commit-Queue: Kallen Tu <kallentu@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2023-06-14 14:28:48 +00:00
Johnni Winther e5a68252e3 [parser] Use endInvalidYieldStatement for async methods
This changes the parser to call endInvalidYieldStatement for
yield statement both in sync and async methods. This ensures that
the CFE creates an invalid expression for yield in async methods,
making the generated AST verifiable.

Change-Id: I1bfe922878fcf3dc19c823cb89ee869af3dd2ce3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/309200
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
2023-06-14 12:10:59 +00:00
Srujan Gaddam 8f48ac3723 [dart:js_interop] Allow interop inline classes to elide @JS
Determines the ultimate representation type of an inline class to
determine if it can use external members. This allows users to
elide @JS if they don't need renaming. This CL adds some static
errors around inline interop members so its clearer that the
inline class should have an interop representation type.

There's a bit of cleanup in this CL too around interop members,
where extension members on @Native classes are now correctly
considered as interop members by the error checker.

Change-Id: I4d870d204933ea11b347ab5bb2e3de1b962f5ea3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/308249
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
2023-06-13 23:27:23 +00:00
Johnni Winther e831cb8510 [cfe] Check @patch annotations
This normalizes the checking of patches so that it matches the checking
of augmentations. This means that the @patch annotation must and can
only be used on patches.

The dart: libraries and patches have been updated accordingly.

TEST=ffi

Change-Id: I78767eebd1a8861859067ae5ff9c0339f0985bb4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/306041
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
Reviewed-by: Lasse Nielsen <lrn@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2023-06-13 07:27:08 +00:00
Paul Berry 9b3f2bc525 Fix comments in flow_analysis.dart.
This addresses code review feedback from
https://dart-review.googlesource.com/c/sdk/+/307140.

Change-Id: I3caa0230f249d22375565b004aafcf775e900fd5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/308250
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2023-06-09 09:11:48 +00:00
Johnni Winther 82e3a751a9 [cfe] Remove unnecessary_null_comparison code
The frontend is now run with sound null safety so these are no longer needed.

TEST=existing

Change-Id: I6c1776845854695ff34e310a3bb5bc9d86715f06
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/307901
Reviewed-by: Jens Johansen <jensj@google.com>
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
2023-06-08 08:46:47 +00:00
Srujan Gaddam 0784c4d868 [dart:js_interop] Warn on initializers when using static interop
Non-strict mode static interop can still use initializers on types
like String. We should warn in this case so users don't think that
the initializers will be used with invocation-level lowering. Note
that strict mode does not need to worry about this as JS types can
not have a const initializer.

TEST=Manual as our static error checking doesn't handle warnings.
Change-Id: I4e2eeda35ca82b86adf75f6eaf069764b3c13ae7

Change-Id: Ic23bd69e652ff4f083157021777d9cf46f4a7f7e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/307512
Reviewed-by: Joshua Litt <joshualitt@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
2023-06-07 17:11:56 +00:00
Paul Berry 39de3f2e5b Field promotion: track field accesses via SSA node.
If a user promotes a field and then subsequently changes the variable
used to access it, the promotion must be discarded. For example, in
this code:

    class C {
      int? _i;
    }
    test(C c1, C c2) {
      C c = c1;           // (1)
      if (c._i != null) { // (2)
        print(c._i + 1);  // (3)
        c = c2;           // (4)
        print(c._i + 1);  // (5)
      }
    }

The test at (2) promotes `c._i` to non-null, so (3) is ok. But since
`c` is reassigned at (4), (5) should be a compile-time error.

Previously, flow analysis used one promotion key to track `c` and one
promotion key to track `c._i`. The `PromotionKeyStore` associated each
promotion key with a map containing the promotion keys of all of its
properties. So, for example, if the promotion key for `c` was 10 and
the promotion key for `c._i` was 11, the `PromotionKeyStore` would
associate promotion key 10 with the map `{'_i': 11}`, so that each
time `c._i` was accessed, promotion key 11 would be found. In order to
detect the compile-time error at (5), it had to keep track of the fact
that keys 10 and 11 were related, so that the assignment to `c` at (4)
could invalidate the promotion of `c._i`. It accomplished this by
linking together all the related promotion keys in a circularly linked
list, which it would walk at the time of any variable assignment.

This worked, but it required a lot of complex bookkeeping. Also, it
posed problems for integrating field promotion with cascades, for
example, in the following code:

    class B {
      void f([_]) { ... }
    }
    class C {
      B? _b;
    }
    test(C c1, C c2) {
      C c = c1;           // (6)
      if (c._b != null) { // (7)
        c.._b.f(          // (8)
	    [
              c = c2,     // (9)
	      c._b.f(),   // (10)
	    ])
         .._b.f();        // (11)
      }
    }

The cascaded access `.._b.f` at (8) should be ok, since `c._b` has
been promoted. But since there is an assignment to `c` at (9), the
promotion should not carry over to (10), and an error should be
reported. However, no error should be reported at (11) because the
cascaded access to `.._b.f` at that location is using the old value of
`c` that was captured at the beginning of the cascade, prior to the
assignment. There's no way to achieve this by invalidation alone,
since the code locations at which the promotion is valid ((8) and
(11), but not (10)) aren't even contiguous.

The solution to the problem is to store property promotion keys in
`SsaNode`s used by flow analysis, rather than in the
`PromotionKeyStore`. Since a fresh `SsaNode` is allocated each time a
variable is assigned, this automatically invalidates any previous
property promotions without the need for any extra bookkeeping. So, in
the first example, at (1), an `SsaNode` is allocated and associated
with the promotion key for `c`. At (2), a promotion key is created for
`c._i` and stored in `c`'s `SsaNode`, and the flow model is updated to
indicate that that key has been promoted to non-null. At (3), that
promotion key is reacalled from the `c`'s `SsaNode`, so the promotion
is still in effect. At (4), a fresh `SsaNode` is associated with
`c`. Since that `SsaNode` doesn't contain any promotion keys yet, at
(5), the access to `c._i` causes a fresh promotion key to be
allocated, with no associated promotions. So the invalidation happens
automatically due to the fact that a new `SsaNode` was created.

Flow analysis doesn't yet support cascades, but here's how the second
example is intended to work: as before, at (6), an `SsaNode` is
allocated and associated with the promotion key for `c`. At (7), a
promotion key is created for `c._b` and stored in `c`'s `SsaNode`, and
the flow model is updated to indicate that `c._b` has been promoted to
non-null. At (8), the `SsaNode` for `c` is captured and saved for
later use. At (9), a fresh `SsaNode` is created and associated with
`c`. That fresh `SsaNode` is consulted at (10), so `c._b` is not
promoted at this point. However, at (11), the previously stored
`SsaNode` is used, so the promotion of `._b` still works.

Change-Id: I64519fbcb2368a37aa18adf35cee0ffd290db9b9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/307140
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2023-06-04 19:41:54 +00:00
Paul Berry f180b7037c Shared analysis: remove bogus support for late variable patterns.
When I was first developing the shared analysis logic for patterns, I
imagined that ordinary variable declaration statements would
eventually be re-interpreted as pattern variable declarations, where
the pattern was simply a variable pattern. In order to facilitate
this, I added support for late variable patterns, so that a
decalration of a late variable could be interpreted as a pattern
variable declaration where the pattern was a "late variable pattern".

In the final implementation, however, this functionality never got
used, except in flow analysis unit tests. Both the analyzer and the
CFE continue to use their old logic for analyzing ordinary variable
declarations (including late variable declarations), and only invoke
the shared logic when the declaration in question is truly a pattern
variable declaration.

In retrospect I believe this is the right approach; ordinary
(non-patterned) variable declarations are common enough that it makes
sense to have separate logic for analyzing theem; invoking the full
generality of pattern variable declarations would simply waste CPU
cycles.

So this CL removes support for late variable patterns from the shared
implementation; this will make future refactoring of flow analysis
logic easier.

Since the flow analysis unit tests *were* taking advantage of the
shared logic for late variable patterns, I had to add some separate
logic to the tests to replicate the old functionality when analyzing
an ordinary late variable declaration. This new logic is only used in
tests.

Change-Id: If51efab3c63bdc20d1f2772c2d2dd1e3f487bb00
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/307183
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2023-06-04 19:40:37 +00:00
Srujan Gaddam c98ec26c91 [dart:js_interop] Disallow external extension members with 'static'
There is no lowering for these members today, so this moves a runtime
error to a static error. We may choose to add support when we can
add 'static' extension members that use the on-type for their
invocation, instead of the extension name.

Change-Id: I6e054cc4445292dd952dfd7601d10d871eae187d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/303060
Reviewed-by: Joshua Litt <joshualitt@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2023-06-02 19:14:15 +00:00
Paul Berry b7ea982bea Flow analysis: Simplify ExpressionInfo class hierarchy.
After landing https://dart-review.googlesource.com/c/sdk/+/304211, I
did some testing using `pkg/front_end/tool/benchmarker.dart`, and
found that it regressed performance of the CFE more than I was
comfortable with:

instructions:u: 0.2097% +/- 0.0004%
branches:u: 0.2310% +/- 0.0006%

The culprit seemed to be the complex class hieararchy of
ExpressionInfo. This change simplifies down to just 4 classes:

- ExpressionInfo (the root),

- _Reference (for references to variables, properties, `this`, and
  `super`),

- TrivialVariableReference (for references to variables that don't
  contain a boolean value that influences the flow model), and

- _NullInfo (for `null` literals).

Notably, the simplified class hierarchy doesn't contain any diamond
shapes (which should simplify `is` testing), and the only overrides
are `toString` and `isNull`, so many methods should now be possible to
inline.

This change results in the following performance improvement:

instructions:u: -0.2768% +/- 0.0003%
branches:u: -0.2950% +/- 0.0004%

Which more than offsets the previous regression.

Change-Id: I02f55a621ca6601ddc1d59bf79e386c1703e09bd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/306907
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2023-06-02 00:46:07 +00:00
Jake Macdonald b113403994 use switch cases where it makes sense in the macro code
Change-Id: I4f896e10dad0af10b420948dd769833cf8d0df22
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/306981
Commit-Queue: Bob Nystrom <rnystrom@google.com>
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Auto-Submit: Jake Macdonald <jakemac@google.com>
2023-06-01 23:05:07 +00:00
Jake Macdonald 310baf2737 mark all public interfaces as abstract interface classes
make Code a sealed type, and all subtypes base classes

Change-Id: I328b6a25446dc89e88ae2f1c7e137b969f1b86ce
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/306682
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Jake Macdonald <jakemac@google.com>
2023-06-01 19:30:41 +00:00
Paul Berry 709c0e4ccd Flow analysis: combine ExpressionInfo, ReferenceWithType, and EqualityInfo.
Previously, flow analysis used three classes to keep track of
information about expressions that have been visited:

- ExpressionInfo, to keep track of information about expressions whose
  truth or falsity has an effect on flow analysis (such as `== null`
  checks, `is` checks, and combinations thereof those using `&&` and
  `||`), as well as identifying the literal expression `Null`.

- ReferenceWithType, to keep track of information about expressions
  that represent something that can be promoted (references to
  variables and fields), as well as the static type of the expression.

- EqualityInfo, which wrapped ExpressionInfo and ReferenceWithType,
  and also redundantly stored the static type of the expression.

These have now been combined into a single class hierarchy with a base
class called `ExpressionInfo`. This makes the code easier to reason
about, because it is no longer necessary to think about which of the
three above classes is needed in a given situation. Also, it helps
prepare for a follow-up CL in which I plan to refactor how flow
analysis gathers this information; the refactor will be easier with
just a single class hierarchy of information to be gathered.

This required a modest expansion of the API to flow analysis to
include more static types, since previously, static types weren't
needed by the ExpressionInfo class.

Change-Id: Id3de8b19049f8d920ebe85ab58c624ae3e55f226
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/304211
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2023-06-01 15:53:18 +00:00
Paul Berry 29d0311344 Flow analysis: clean up type parameters.
The `Expression` type parameter of `FlowAnalysis` is always a subtype
of `Node` in practice; this change updates the bounds on
`FlowAnalysis`, `FlowAnalysisDebug`, `_FlowAnalysisImpl`, and
`_LegacyTypePromotion` to reflect that.

Also, this change updates the redirecting factory constructor
`FlowAnalysis.legacy` so that it properly passes all the type
parameters over to `_LegacyTypePromotion`. There's no functional
change here, because type inference infers the correct parameters in
practice, but I prefer not to rely on that for correctness.

Change-Id: Ieacbe11dbb859557f27b5e2937b29381e8e934b1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/306315
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2023-05-31 17:24:48 +00:00
Paul Berry 12c01c41e2 Flow analysis: fix parameter type of ifStatement_thenBegin.
For a while during the development of flow analysis for patterns, I
was using `ifStatement_thenBegin` for both ordinary if-statements and
if-case statements, distinguishing the two by having the caller pass a
`null` value for `condition` in the latter case. Later I reworked the
API, adding `ifCaseStatement_begin`,
`ifCaseStatement_afterExpression`, and `ifCaseStatement_thenBegin` to
handle if-case statements. But I forgot to restore the old signature
for `ifStatement_thenBegin`.

This change restores the old signature, in which the `condition`
argument is non-nullable. There should be no functional change, since
all callers were passing non-null values already.

Change-Id: I8c275f0a5be453c7de6052262a8a87eaac8d75ee
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/306300
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2023-05-30 20:23:59 +00:00
Daco Harkes e1ae1b48ae [vm/ffi] dartdev CLI native-assets
This CL introduces native assets suport for `dart run` and introduces
`dart build` which is similar to `dart compile` but outputs a folder
instead to that native assets can be bundled with an executable.

Change-Id: Ib6cfb95539f0adee46c99e531e440928c3f72f2b
Cq-Include-Trybots: luci.dart.try:pkg-linux-debug-try,pkg-linux-release-try,pkg-mac-release-arm64-try,pkg-mac-release-try,pkg-win-release-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/267340
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
2023-05-30 09:10:28 +00:00
Paul Berry e213846ba0 Patterns parsing: fix record-typed variable patterns before certain tokens.
Previously, if a record-typed variable pattern lacked a `var` or
`final` keyword, and was followed by one of the tokens `||`, `&&`,
`as`, `?`, `!`, `when`, or `=>`, the parser would fail to recognize
it. This happened because the call to `computeVariablePatternType`
wasn't passing `true` for the optional parameter `required`; that in
turn placed `computeType` in a mode where it believed it was parsing a
potentially ambiguous construct in a top-level declaration, and hence
it would only accept the record type if the variable name was followed
by something that looked like part of a correct declaration (e.g. a
comma).

The fix is to pass `true` for the optional parameter `required` of
`computeVariablePatternType`. This places `computeType` in a mode
where it accepts the record type regardless of what follows it. This
is correct behavior since at the point where a variable pattern is
being parsed, ambiguities have already been taken care of and the
construct being parsed is most definitely a variable pattern.

Fixes #52521.

Change-Id: If20772ad914827a29df45c27eefb382ec1f470d2
Bug: https://github.com/dart-lang/sdk/issues/52521
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/305848
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2023-05-26 13:51:31 +00:00
Jens Johansen 284296f862 [parser] Support nullable record types in patterns
Not fixed for nullable record types in
https://dart-review.googlesource.com/c/sdk/+/280106.

Fixes: https://dartbug.com/52439
Closes: https://dartbug.com/52462

Change-Id: I52f42406f2e1c6b7c874a9828ef7f1de397b3c83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/304642
Reviewed-by: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
2023-05-25 10:28:05 +00:00
Paul Berry 54372b3308 Flow analysis: simplify API for accessing field properties.
Instead of having separate API methods `propertyGet` (for accessing
the properties of an explicit target) and `thisOrSuperPropertyGet`
(for accessing the properties of `this` or `super`), switch to a
single `propertyGet` method. Make the `target` parameter of
`propertyGet` a sealed class (`PropertyTarget`) with three subtypes
representing the three possible kinds of targets:
- `ExpressionPropertyTarget` for an explicit target expression,
- `SuperPropertyTarget` is the target is `super`, and
- `ThisPropertyTarget` if the target is `this`.

Also adjust the API for `promotedPropertyType` to use the new
`PropertyTarget` class for its `target` parameter, rather than a
nullable `target` expression and boolean `isSuperAccess` parameter.

Change-Id: I90535f6d6741776548bc4d60359fd4c40c0fab90
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/304763
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2023-05-24 17:50:57 +00:00
Paul Berry d5415d624e Update _fe_analyzer_shared to require Dart SDK version 3.0.
Change-Id: Ifc267c3d610de25c524c1294e43218a973086ce9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/291141
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Jake Macdonald <jakemac@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2023-05-24 14:30:47 +00:00
Srujan Gaddam 7f8611c9a6 [dart:js_interop] Disallow external operators using static interop
We've disallowed operators for interop methods before, but haven't
applied that to extension and inline methods. We currently support []
and []= using static interop, but that may or may not change later.

Change-Id: I0e52c29f1e47c1354182d2bd5cafbac30e314d11
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/301723
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
2023-05-22 21:50:51 +00:00
Srujan Gaddam 383520d6ed [dart:js_interop] Apply param errors to inline classes
Object literal constructors can't have positional parameters and
inline class members can't have named parameters. Adds tests and
rewords existing errors relating to parameters.

Change-Id: I9a25118b26b6b51857c2a455432ac84d96573e14
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/292241
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
2023-05-22 21:50:51 +00:00
Paul Berry 70e7adff19 Field promotion: distinguish between this. and super. accesses.
When promoting fields, in order to avoid unsoundness, we need to
distinguish between field accesses performed through `super` and field
accesses performed through `this`. Otherwise, a user could do
something like this:

    class B {
      final int? _i;
      B(this.i);
    }
    class C extends B {
      final int? _i;
      C(this._i, int? superI) : super(superI);
      int f() {
        if (super._i != null) {
          return this._i; // UNSOUND: `this._i` could be `null`
        }
      }
    }

To avoid this problem, flow analysis now uses separate promotion keys
for `super` and `this`, so that promoting a variable through `this`
leaves it unpromoted when accessed via `super`, and vice versa.

Note that in principle the implementations could inspect the enclosing
class, and only distinguish `this.` and `super.` accesses in the case
where it contains a declaration matching the field name. But doing so
would carry a performance and implementation complexity cost, and
would confer very little real-world benefit (since in practice users
don't mix `this.` and `super.` accesses and expect them to refer to
the same field).

Fixes #50138.

Bug: https://github.com/dart-lang/sdk/issues/50138
Change-Id: Ia0fd79b5ed7649d23a28efcbffb59b4c9ad63f70
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/304364
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2023-05-19 18:29:49 +00:00
Zach Anderson 1b9198c679 Revert "[dart:js_interop] Disallow ffi and JS interop in the same library"
This reverts commit 1c5d23e8a2.

Reason for revert: https://github.com/flutter/flutter/issues/127027

Original change's description:
> [dart:js_interop] Disallow ffi and JS interop in the same library
>
> dart2wasm can use both dart:ffi and JS interop libraries. To avoid
> confusion around external members, this disallows JS interop from
> being used in the same library as dart:ffi.
>
> Change-Id: I53e0426306be99c43b2bbfc14d65075128f0d5c5
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/301200
> Reviewed-by: Johnni Winther <johnniwinther@google.com>
> Reviewed-by: Joshua Litt <joshualitt@google.com>
> Commit-Queue: Srujan Gaddam <srujzs@google.com>

Change-Id: I1fd872e6d0cd679ec9c1842557745647385ec3af
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/304100
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Zach Anderson <zra@google.com>
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
2023-05-17 16:15:36 +00:00
Konstantin Shcheglov bd0e77c4fc Issue 52409. Reading a Never typed getter makes the flow unreachable.
Bug: https://github.com/dart-lang/sdk/issues/52409
Change-Id: I675ed8f8cfa0d2e5327c2c6bc0fb1bda7bde038c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/303840
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
2023-05-17 03:28:07 +00:00
Srujan Gaddam 1c5d23e8a2 [dart:js_interop] Disallow ffi and JS interop in the same library
dart2wasm can use both dart:ffi and JS interop libraries. To avoid
confusion around external members, this disallows JS interop from
being used in the same library as dart:ffi.

Change-Id: I53e0426306be99c43b2bbfc14d65075128f0d5c5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/301200
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
2023-05-16 22:50:46 +00:00