Call sites targeting a procedure annotated with `external-effect` will
not produce any code, including the argument which will not be
evaluated.
However, the single parameter will be treated as 'live' for the purposes
of any global analysis the backends do. This is useful for things like
protobuf shaking where a user may want to retain certain protobuf
messages without actually emitting the code that retains those messages.
Today this functionality is available internally in the vm and wasm SDK
libraries. dart2js has similar functionality represented via the
opaqueTrue and opaqueFalse booleans (which will cause conditional
branches to get shaken after analysis). This will replace dart2js's
opaque(True/False).
This also adds validation to the frontend to ensure a method annotated
with 'external-effect' is well-formed.
Change-Id: If1c4096673e655c58fe7638840a16125003e7809
Tested: Backend tests for codegen were added. A frontend test was added for the validation. A language test was added to confirm the behavior.
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/476020
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
To support checking for dynamically-callable targets in dart dynamic
modules, we need to use a bit in the Function header in AOT. Currently
all 32 bits of `kind_tags_` are in use. To make space for that new bit,
we need to evict one of the current properties that is not needed by AOT.
Among them, `IsRedirectingFactory` made the top of the list. It has only
one use in non-AOT logic.
TEST=existing
Bug: b/448095881
Change-Id: I3112d8865523696ed8e906a6c59f53c23db3090a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/498281
Auto-Submit: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
The 2nd argument of _simpleInstanceOf call is always a
Constant (type). However, a Redefinition can be inserted in the middle.
So, instead of ArgumentAt(1)->AsConstant()->value() it is
more safe to use ArgumentValueAt(1)->BoundConstant() as
BindsToConstant/BoundConstant unwraps Redefinition(s) via
OriginalDefinition().
TEST=runtime/tests/vm/dart/regress_63211_test.dart
Fixes https://github.com/dart-lang/sdk/issues/63211
Change-Id: Ie4a473ebe2deee8562e6634a792f02b0dcefc918
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/497761
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This CL adjusts the CFE handling of errors such that error_test.dart
succeeds: It changes the placement of the error about "wrong parameter
type" such that it is reported on the type annotation and not on the
parameter's name. Next, it adds some extra checks such that it is
enforced that the parameter of an anonymous method must be positional
and mandatory.
Change-Id: I56851d94c9fd975e117c17f671d684f155a28847
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/498021
Commit-Queue: Erik Ernst <eernst@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
It is a compile-time error for `super` to be used in any way when in the
body of a parameterless anonymous method. This CL adds these error
messages to the analyzer.
It introduces a new `SuperContext` in order to maintain proper knowledge
about the situation when it is detected, but it uses a rather generic
error message (just saying that the context is wrong) following the
rationale that this is sufficient for occurrences of `super` in static
members, constructors, top-level declarations, and more.
Change-Id: I4552be0983e4d64a6e59fd03521cbe4f5c784f15
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/498040
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Erik Ernst <eernst@google.com>
In order to perform runtime checks on dynamic calls, the JIT runtime
needs to also have access to some pragmas introduced by the annotator.
Primarily we need the `dynamically-callable` and
`implicit-dynamically-callable` pragmas.
For now, this CL allows us to mimic the behavior in JIT by using the
annotator also when doing non-aot kernel compiles. This is not enough to
support JIT in the general case: it doesn't support compiling from
source with the front-end-server or incremental builds. To support those
we will likely need a modular approach (like only annotating explicit
dynamically-callable during kernel compiles and inferring
implicit-dynamically-callable in the VM instead).
Note: this CL doesn't introduce new logic, it mainly moves the existing
logic to also run when building kernel snapshots for JIT.
TEST=existing, in the future additional coverage will be added when
performing runtime checks.
Change-Id: I9b97dd9f029f1d538ee23c0dff73b01dec0d776b
Bug: b/506246406
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/497622
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Sigmund Cherem <sigmund@google.com>
An attempt to capture some of the conclusions from recent discussions.
Please let me know if this doesn't sound reasonable or if there are
pieces I've missed (such as other exceptions to the general rule).
Change-Id: I2520a768de116be5d9a86f9cb4494dcad7d88f5c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/497780
Reviewed-by: Keerti Parthasarathy <keertip@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
dart2wasm imports strings as globals for which JavaScript engines would
provide the respective values. The standalone target needs to support
all WebAssembly runtimes, so it can't rely on this mechanism.
Instead, this imports functions to convert a WebAssembly arrays of char
codes or ASCII bytes into a string. For now, these functions have to
return JS strings since the rest of the SDK relies on that. In the
future, embedders would be able to return any string implementation as
an externref.
Because calling host functions is invalid in constant contexts, string
constants can't be regular globals. For now, this uses the default
non-eager constant implementation with one initialization function per
string constant. Eventually, we should probably initialize these
strings in a WASM start function instead.
TEST=pkg/dart2wasm/test/standalone_test.dart
Change-Id: I93b7c3846fbe99daa8ffa31e452f62672b61ce4b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/495020
Reviewed-by: Nate Biggs <natebiggs@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
I changed the parsing of const dot shorthands to parse the entire selector chain in `parsePrecedenceExpression` rather than parsing them in `parseConstExpression`. We were originally parsing the initial expression before the `.` and only flagging that as a dot shorthand which prevented any chaining on const constructors. Const expressions with chained methods/property accesses were not being flagged as a dot shorthand so we weren’t saving the context type properly which led to producing the “unknown context type” error.
Before:
```
class C {
const new someConstCtor();
C method() => this;
}
C c = const .someConstCtor.method();
// (const .someConstCtor) is parsed and handled as a const constructor
// (const .someConstCtor) is handled as a dot shorthand, context is
// saved on only this AST and not the outer chain.
// Then we parse the rest of the selector chain (.method())
//
// Error: No context type for (const .someConstCtor.method())
```
After:
```
class C {
const new someConstCtor();
C method() => this;
}
C c = const .someConstCtor.method();
// (const .someConstCtor) is parsed and handled as a const constructor.
// Then we parse the rest of the selector chain (.method())
// (const .someConstCtor.method()) is handled as a dot shorthand, context is saved for this outer node.
//
// OK. No error because we are able to retrieve the type for the
// entire dot shorthand chain.
```
Fixes: https://github.com/dart-lang/sdk/issues/63119
Change-Id: I3308d8eb7ce101466be257aba6b5448921bff136
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/495560
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
This reverts commit e7dbd6ba48.
Reason for revert: Broke flutter_analyze
Original change's description:
> [dart:js_interop] Make JSFunction and JSExportedDartFunction generic
>
> Fixes https://github.com/dart-lang/sdk/issues/54557
>
> The generic type in JSExportedDartFunction corresponds to the
> static type of the function it wrapped, whereas for JSFunction,
> it's purely a descriptor of the JS function.
>
> When calling JSExportedDartFunction, a cast is now introduced
> to cast it to T.
>
> When calling isA, the type in JSExportedDartFunction is passed
> along to check that the value that is wrapped is that function
> type. Because the T in JSFunction is descriptive, e.g.
> isA<JSFunction<int Function()>>() does no such check.
>
> ____
>
> Also cleans up:
>
> - isA<JSTypedArray>() logic to use intrinsic functions
> - some expectation files to be consistent for both dart2js and ddc.
>
> CoreLibraryReviewExempt: Backend-specific library with needed reviews.
> Change-Id: I1a55c4386e416fa4ccabe06ac5051f41c2e2e95a
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/496820
> Reviewed-by: Lasse Nielsen <lrn@google.com>
> Commit-Queue: Srujan Gaddam <srujzs@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Change-Id: I98447c8c95906feb7f8f1a57859a24fc8e4966d6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/498080
Commit-Queue: Alexander Aprelev <aam@google.com>
Auto-Submit: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Replace manual type construction utilities in type system tests with a
unified string-based type parser. This simplifies test code, improves
readability, and enables more expressive type scenarios.
Key changes:
- Introduce TypeSpecParser and TypeParsingScope to parse types,
function types, records, and type parameters from strings.
- Add parseType() and related helpers to AbstractTypeSystemTest,
replacing ElementsTypesMixin usage.
- Remove ElementsTypesMixin and migrate all tests to use parsed
types instead of manually constructed TypeImpl instances.
- Extend _SpecParser to support:
- Promoted type parameter bounds (`T & int`)
- Parenthesized vs record types disambiguation
- Additional built-in types (InvalidType, UnknownInferredType)
- Variance in generic function types
- Covariant parameters
- Refactor scope construction to use _Scope.forLibraries, reducing
duplicated interface/type alias collection logic.
- Add standalone materialization flow for type parameters to support
parsing in isolation.
Impact:
- Tests become more declarative and closer to Dart syntax.
- Eliminates boilerplate and reduces risk of inconsistencies in
manual type construction.
- Enables testing of newer type system features (promotion,
variance, complex function types) via concise string specs.
Change-Id: I85dd0aa88a37142356f14419d0d35350e38b9c8b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/497680
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Change 64060a8ddf accidentally lost `?? []` for non-optional fields when parsing JSON. This change restores that (in `generate_dart_common.dart`), along with some minor tweaks to get the codegen to work on Windows.
For reasons I don't understand, the generated files were formatted differently to how the formatter formats them on my machine today, which unfortunately makes the diff larger than the intended change.
Change-Id: Ibadaa3ec4c6af4e636c1e5ffd2c7e792bc1e8a14
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/497600
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
To infer the type arguments of a redirecting factory redirection,
intermediate positional and named arguments are created for the RHS of
the redirection as if for an invocation. The references to the
positional and named parameters in those arguments should be wrapped
into `InternalPositionalParameter` and `InternalNamedParameter`, since
the inference expects internal nodes and otherwise crashes.
Part of https://github.com/dart-lang/sdk/issues/61571
Change-Id: I469f5f2a67aca15df0d4449c8f5a55216e204e22
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/493400
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
`ConstantVisitor.visitAdjacentStrings` previously delegated to
`_concatenateNodes`, which folds the list pairwise and materializes
a new `DartObjectImpl` / `StringState` at every step. For an
`AdjacentStrings` with `n` string pieces of total length `L`, this
is roughly O(L^2) work and garbage.
This is pathological on generated code: parser generators and other
codegen tools commonly emit a single large string constant as a long
sequence of adjacent string literals (e.g. encoded transition tables
for a table-driven parser). In those files, constant evaluation of
a single top-level `const` dominates analyzer runtime.
Fast-path `visitAdjacentStrings`: when every element evaluates to a
plain `StringState`, append into one `StringBuffer` and return a
single final `DartObjectImpl`. Fall back to the existing
`_concatenateNodes` path only when an element is not a plain string
(diagnostic, unknown, etc.).
Wall-clock time to resolve a library containing one `const table =`
of N adjacent 16-char string pieces, on an Apple M-series laptop
with a recent main-channel SDK:
pieces total_chars baseline_ms patched_ms speedup
1024 16384 218 222 ~1x
4096 65536 180 189 ~1x
16384 262144 245 166 ~1.5x
65536 1048576 9229 246 ~37x
At larger sizes the baseline grows quadratically while the patched
path stays linear; n=262144 took multiple minutes on the baseline
and roughly half a second after the patch.
TEST=pkg/analyzer/test/src/dart/constant/evaluation_test.dart:test_visitAdjacentInterpolation_simple
Bug: https://github.com/dart-lang/sdk/issues/63222
Change-Id: Ibffe4124d025fceb5991ea88b4af9a03f36525b4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/497001
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Fixes https://github.com/dart-lang/sdk/issues/54557
The generic type in JSExportedDartFunction corresponds to the
static type of the function it wrapped, whereas for JSFunction,
it's purely a descriptor of the JS function.
When calling JSExportedDartFunction, a cast is now introduced
to cast it to T.
When calling isA, the type in JSExportedDartFunction is passed
along to check that the value that is wrapped is that function
type. Because the T in JSFunction is descriptive, e.g.
isA<JSFunction<int Function()>>() does no such check.
____
Also cleans up:
- isA<JSTypedArray>() logic to use intrinsic functions
- some expectation files to be consistent for both dart2js and ddc.
CoreLibraryReviewExempt: Backend-specific library with needed reviews.
Change-Id: I1a55c4386e416fa4ccabe06ac5051f41c2e2e95a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/496820
Reviewed-by: Lasse Nielsen <lrn@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This change extends the dynamic-modules-validator in the CFE to
accept an allowlist of dynamic call selectors.
Calls to selectors in such allowlist are accepted and shouldn't
report validation errors, even if the dynamic interface contains no
exposed members with that selector name. The goal is to eventually
use this allowlist to enable dynamic calls within dynamic modules,
where the target of the call is defined in bytecode.
At this time, we only support public selector names in the allow
list.
TEST=pkg/front_end/testcases/general/dynamic_modules/main.dart
BUG=b/448095881
Change-Id: I94850781f235f8b3fd3cbd9b167302f79f5020b8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/496782
Commit-Queue: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
This CL migrates the `dwds` and `dwds_test_common` packages into the Dart SDK
repository.
Key Changes:
- Monorepo Compliance: Updated the pubspecs to align with the SDK pub workspace setup.
- Excluded `pkg/dwds_test_common/fixtures/` from `package_deps.dart`.
- Updated pkg to status to skip `dwds/test/integration/*` & `dwds_test_common/fixtures/*` until DWDS migration is complete.
- Remove package `build_daemon` from DWDS' `pubspec.yaml` as it's not approved for SDK env.
- Added `@skip_package_deps_validation` to the following files to ignore import checks for package:build_daemon: `server.dart`, `utilities.dart`, `context.dart`.
- Created `pkg/dwds/lib/src/utilities/test_path_utils.dart` to fix path resolution failures in tests (ie. `build_script_test.dart` and `ensure_version_test.dart`).
Testing:
- All tests passing locally.
- CI try bots are green.
Design Doc: http://goto.google.com/migrating-webdev and http://goto.google.com/migrating-dwds
Fixes https://github.com/dart-lang/sdk/issues/62100
Fixes https://github.com/dart-lang/sdk/issues/62101
Fixes https://github.com/dart-lang/sdk/issues/62102
Fixes https://github.com/dart-lang/sdk/issues/62103
Cq-Include-Trybots: luci.dart.try:pkg-win-release-try,pkg-win-release-arm64-try,pkg-mac-release-try,pkg-mac-release-arm64-try,pkg-linux-release-try,pkg-linux-release-arm64-try,pkg-linux-debug-try
Change-Id: I6130be8b7e0b42fbbf81b26a4950a2c4282e3a48
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/494660
Commit-Queue: Jessy Yameogo <yjessy@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
I could not get the Dart script to successfully run from GN, and I
also could not find examples of the same. Everything is Python, so
Python it is.
Change-Id: I767aaf42d1584ae331d028ef073a534e5d36b77b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/496402
Reviewed-by: Ivan Inozemtsev <iinozemtsev@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
This CL adds several CFE coverage tests and removes all 'Not run.'
coverage comments added in CL 494440 except one in
`AnonymousMethodExpression.toTextInternal` (I assume this is only
invoked in debugging code) and one immediately before `throw
UnimplementedError...`.
Change-Id: I578be895d59d6487aa981ea5a44519a1cce7b78b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/497200
Commit-Queue: Erik Ernst <eernst@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This is a re-land of 152cc24, which has been reverted in 3f9ae7. Unlike
the original change, this doesn't alter the `dart:_wasm` library.
We can revisit an API split to remove `js_interop` APIs there once the
standalone target has progressed further.
Original change's description:
> [dart2wasm] Split patch files by whether they use JS interop
>
> The eventual goal of the `dart2wasm_standalone` platform is to not rely
> on a JavaScript environment, which requires rewriting everything that
> currently relies on `js_interop` or `JS()` helpers.
>
> Since most of the patches are still written in Dart and we don't want
> to duplicate that code for the standalone target, this splits patch
> files by whether they rely on JS-interop or not. The main entrypoint
> for each patch (e.g. `lib/_internal/wasm/lib/core_patch.dart`) no
> longer relies on JS-interop and can safely be used in the standalone
> target. Part files that previously needed to use JS-interop have been
> moved into separate patches now, which allows us to migrate them
> incrementally.
>
> In some cases, it was easier to add new patch files:
>
> - Similar to the split between `boxed_int` and the `toString` helper
> patch, we now have the same for `boxed_double`.
> - The functionality to copy from JS typed data wrappers into Dart typed
> lists wouldn't work with standalone, so I've moved it into a separate
> method we can patch to be a noop.
> - `dart:_wasm` exposes APIs to convert between `JSAny` and `externref`.
> This is part of a public API, but I had to move those declarations
> into a patch file because they wouldn't work with standalone.
> Arguably, a separate library (`dart:_wasm_js_interop`?) would be
> cleaner but it might be fine as long as `dart:_wasm` is experimental?
>
> For now, new patch files relying on JS interop are also applied to the
> standalone target. They are marked with a comment indicating that they
> need to be migrated though.
Cq-Include-Trybots: luci.dart.try:flutter-analyze-try
Change-Id: I98a628f96cba7e0f0af7e86e058cda43c2c73898
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/495302
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>