Currently _emitArgumentList handles arguments for Dart
members, JS interop members, and object literal constructors.
It requires an Arguments node, which we end up synthesizing,
which messes with parent pointers erroneously. We also have
to separate out the arguments and do additional checks later
to detect whether the arguments passed correspond to an
object literal constructor.
Instead, we should create the resulting expression directly
in a helper method. A map is passed so that the names of
arguments can be easily changed when we handle @JS renaming
on object literal constructors. Lastly, we need to avoid
wrapping the values with assertInterop in the case where the
constructor is from a dart:js_interop interface. That library
only statically allows Functions to be passed if they're
externalized, in which case we shouldn't tell users to wrap
the Function with allowInterop (which doesn't exist anyways in
dart:js_interop).
Change-Id: If6fdc706e80837ab2b698cca704ffd9f08aed28a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/446184
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
Note: Const locals are still off for VM aot and dart2js for the entry
points I've found in an attempt to retain the old behaviour there.
It might be better if those targets could remove such locals in a
whole-world analysis instead.
* Keep const locals by default (except as noted above). Update the
verifier to accept that. For the platforms this has increased the
size by at most 6584 bytes. With this the VM will pass in any const
locals as it does normal locals, but as the variable is never
captured it will never pass a const local defined in a method when
inside a local function in that method.
* Change the dart scope calculation(s) to return the found variables
instead of just the types of the found variables.
* When the incremental compilers expression compilation - via the dart
scope calculation - finds a const local that it wasn't told about, it
will pass it on as an extra variable that it knows about, allowing
for evaluating const locals in the case not covered by the first
bullet.
With luck this can in future CLs be extended to know about other
variables that we're not told about, allowing to give a message saying
something like
"yes, we know what 'foo' is, but you can't currently use it" as wanted
in for instance https://github.com/dart-lang/sdk/issues/60316 and
https://github.com/dart-lang/sdk/issues/53996.
Tested: Existing tests for existing functionality; new tests for the new
Change-Id: I1ec24350273e6f81574bb2888f6bf46e3b8b1b47
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/445461
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
The analyzer already has an enum with the same name, but a slightly
different declaration. (The analyzer's enum declares only severities
of `error`, `warning`, and `info`, whereas the CFE's enum also
declares severities of `context`, `ignored`, and `internalProblem`).
I'm currently embarking on an arc of work that I hope will eventually
culminate in unifying the analyzer and CFE diagnostic message
representations (and their severities) into a single set of
classes. Until that unification is complete, both representations will
have to co-exist in the `_fe_analyzer_shared` package. To reduce
confusion during that time period, I would like the classes to have
distinct names.
Since the analyzer's `Severity` enum is exposed through the analyzer
public API, analyzer clients may depend on the name. So it makes sense
to rename the CFE's `Severity` enum.
Tested: standard trybots
Change-Id: I95622950f49b1754267e441e4636e046045629bb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/442102
Reviewed-by: Liam Appelbe <liama@google.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
The analyzer already has a class with the same name, but a slightly
different purpose. (The analyzer's class represents a single message
associated with a source location, whereas the CFE's class represents
a message along with related context messages).
I'm currently embarking on an arc of work that I hope will eventually
culminate in unifying the analyzer and CFE diagnostic message
representations into a single set of classes. Until that unification
is complete, both representations will have to co-exist in the
`_fe_analyzer_shared` package. To reduce confusion during that time
period, I would like the classes to have distinct names.
Since the analyzer's `DiagnosticMessage` class is exposed through the
analyzer public API, analyzer clients may depend on the name. So it
makes sense to rename the CFE's `DiagnosticMessage` class.
Tested: standard trybots
Change-Id: I6b6948fe9da18c7b6688333fa12ffeea8e81436f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/441831
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This type argument was never used. Removing it should make it easier
to make changes to the front end error message logic (and associated
code generator), which I intend to do as part of a long term plan to
make the analyzer and front end error reporting systems more
consistent, and eventually merge them.
Change-Id: I994cd2a74c5fd77df192f6a1f2dde46ba8a31883
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/442723
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Moves helpers from local functions and instance methods in the compiler
to static extensions on kernel nodes. These can be shared between the
old and new compilers.
Change-Id: Ifc2b5fe8945753823d7671171673c6c7add1e8cd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/439806
Reviewed-by: Mark Zhou <markzipan@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
* Avoids retrieving the instance type in more cases. In static class
methods (including constructor tear offs)
`dart_rti.instanceType(this)` was being used as the base of the
environment binding. In these cases the result was the reified type
of the JavaScript function. This worked as long as the base type of
the binding is ignored, but it was not intuitive and had to fall
through all the other cases before settling on that result.
* Avoids parsing a recipe for the `dynamic` every time when we already
can have it available in our type table.
Compiled code examples:
Building the type `A<R, S>` from function type parameters `R` and `S`:
Now:
`T.dynamic()[_bind](R)[_bind](S)[_eval]("A<1,2>")`
Previously:
`dart_rti.instanceType(this)[_bind](R)[_bind](S)[_eval]("A<1,2>")`
Building the type `B<R>` from function type parameters `R`:
Now:
`R[_eval]("B<0>")`
Previously:
`dart_rti.instanceType(this)[_bind](R)[_eval]("B<N+1>")`
where N is the number of type arguments of the enclosing class.
``
Change-Id: I213666edd7c6427f0d42d958541e53a798e8877c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/439460
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Update the last known good component after a recompile reject back to
the expected state before the recompile.
Adds tests for expression compilation after recompile accept and
recompile reject cases with `--target=dartdevc`. Similar to existing
tests for the VM.
Removes calls to `_generator.accept()` and
`component.computeCanonicalNames()` from `compileExpressionToJs()`.
These were added very early in the prototype implementation and it is no
longer clear why they would be needed.
Added some additional test cases for expression compilation involving
import resolution because the change that originally added the
`component.computeCanonicalNames()` call implies it was needed for that
reason. See: https://dart-review.googlesource.com/c/sdk/+/138010
TEST=pkg/frontend_server/test/frontend_server_test.dart,pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
Change-Id: I9c04bd46e56b33dc654d00fb330de29c3c643a5b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/434522
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
The name has always been annoying because it did not add strong typing. And now there aren't variants of the VM platform to distinguish.
Leave a copy at the old name to not immediately break illegal uses.
TEST=ci
Cq-Include-Trybots: luci.dart.try:flutter-analyze-try,flutter-frontend-try,flutter-linux-try
Change-Id: Ie76fa7f16940aa1ba8d582eb5197f0ae55dc8938
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/429828
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Under the hood, there is no difference between
`isSubtypeWhenUsingNullabilities` and
`isSubtypeWhenIgnoringNullabilities` by now. This CL makes the
corresponding renames and removals in the CFE and its clients.
TEST=existing
Change-Id: I22060c29834179c30ba62562aa254146b1d7530d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/433480
Reviewed-by: Ömer Ağacan <omersa@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Refactors the hot reload test suite to support non-FE server based hot reload. Similar to DartPad it uses a DDC process running in '--persistent_worker' mode and sends bazel requests for each reload.
I call this "stateless" mode because the compilation process itself is not maintaining any state. The necessary metadata is passed from one compilation to the other via a delta dill. This differs from the "stateful" mode where the FE server persists a kernel AST in memory from one compilation to the next.
Disregarding the browsers there are effectively 3 run modes now:
- web stateful
- web stateless (new)
- vm stateful
One key difference between the "stateless" and "stateful" modes is the output format of the JS files. In stateful mode DDC emits a file per library being re-compiled. In stateless mode DDC is emitting a single file with all the libraries.
DartPad's workflow is slightly simpler than what's seen in the stateless mode here. It only supports editing a single library so we skip processing any metadata. To simulate this I've added the special 'main_only' which passes a single library for each reload generation. I've verified that this would fail if not for the change recently made to ddc_module_loader.js.
Change-Id: If05da6dbeded4dd20e9e6d9dfaed52151541a19b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/434340
Commit-Queue: Nate Biggs <natebiggs@google.com>
Reviewed-by: Mark Zhou <markzipan@google.com>
Reviewed-by: Kevin Moore <kevmoo@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
The current conditions make it so that every library transitively reachable from a reload target (and therefore included in the DDC output) must be known in the client when `dartDevEmbedder.hotReload` is called.
While this is the case for pages running with DWDS, it's an unnecessary constraint. Some users may only care about reloading a specific subset of known libraries. As is the case in dart-pad when we only need to reload the main library as we know this is the only code that can have changed.
Any new libraries must also registered and initialized as this is new code not yet in the page. This would happen if a new import was added to the code.
Change-Id: I164f59a6931fd809867716c164cb467880806f8c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/432440
Commit-Queue: Nate Biggs <natebiggs@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
When wildcard method arguments should be removed from the scope before
attempting to evaluate an expression. Otherwise their names are invalid
and cause a Dart compile time error.
Add tests for all forms of wildcards in expression evaluation.
Change-Id: I21a7676a1495383926552a1039789f7d29256a67
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/431951
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
The `_as` methods for primitive types are designed to be called from
both the `_as` selector and directly from generated code.
For the primitive types that are known at compile time and cannot change
via linking or hot reload, we can generate direct calls.
Adapted from https://dart-review.googlesource.com/c/sdk/+/420380
In addition to the base change:
* Remove `int` cast helpers from DDC only code in favor of the
versions from dart:_rti.
* Moves existing optimizations from `visitAsExpression` to `_emitCast`
to apply them consistently.
Change-Id: I13d24e3756400f2358556812728db17bc73f544a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/427040
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Stephen Adams <sra@google.com>
These packages can be specified with the `non-hot-reloadable-package` flag and will be compiled without their members being properly hot reloadable. In exchange, we can perform additional optimizations (such as avoiding levels of indirection/checks in anticipation of their being updated).
This additionally overhauls our memory compiler to use the incremental compiler for proper state-passing hot reload testing + adds tests for this functionality.
Change-Id: Ief65896410f32655f064bd15728703629faa4051
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/428343
Reviewed-by: Nate Biggs <natebiggs@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
`needsCapture` will ensure that any variables used within an async scope get included in the 'asyncScope' object that's created for that scope.
The variables used to lower Dart late variables in particular get emitted separately. But they can still be used across async scopes so they need the special capture logic as well.
Bug: https://github.com/dart-lang/sdk/issues/60748
Change-Id: I2486fce41f88f186fd799029c2cc59635f7ad8f5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/429780
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
when they have been rewritten to include hot reload checks. Appears to
fix the issue detected in the dwds test failure.
Issue: https://github.com/dart-lang/webdev/issues/2617.
The new mapping ensures breakpoints applied to the call site in the Dart
source are the call site instead of the the generation check.
Allows the tooling to set a breakpoint on the static method call site,
and then when paused, a step-into will action will advance the program
into the static method.
In the future we will need to reevaluate how we generate code where a
single branch of execution in Dart source produces multiple branches in
JavaScript. I believe right now the tooling will not support creating
breakpoints in both branches even when they both have a mapping to the
same Dart source location.
Change-Id: I1ea0548768d8213dc7eefc332814d3bda7c81535
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/427567
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Moves the remaining special case logic out of `_emitMethodCall()`
simplifying the reasoning about where so hot reload soundness checks
can be added.
The original change exposed a latent soundness bug that allowed for
some dynamic getter invocations to be performed without runtime checks.
This reland adds adds a note about the newly enforced runtime checks to
the CHANGELOG.
Change-Id: I387438b8615e60f73dfc5e3b883b8c6d5a9993da
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/425942
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Mark Zhou <markzipan@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
Previously, code in a closure was compiled with the assumption that
invocations known to be statically sound didn't need any runtime checks
to guaranty soundness.
Now, if the code is retained from an earlier compile and executed after
a hot reload, any assumptions regarding soundness may be invalid.
This change transforms what was an invocation expression into a larger
expression that performs additional checks (similar to a dynamic call).
All checks are skipped if the compile generation matches the current hot
reload generation at runtime.
The soundness checks are handled by a new runtime helper method
`hotReloadCorrectnessChecks`. Any argument expressions are hoisted into
let variables to preserve their evaluation order and to ensure they are
only evaluated once. The helper checks for the existence of the
invocation target, the shape of the method signature, and runtime type
of the passed arguments. Mismatches result in an invocation of
`NoSuchMethod`. Any returned value is cast to the expected static type
of the original invocation.
Change-Id: If925f1a9b475d5ac581b2526403ab7c95753ffef
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/421640
Reviewed-by: Jens Johansen <jensj@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
Reviewed-by: Mark Zhou <markzipan@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
It is possible with the way the library manager is written
today that during a hot restart, a previously defined library
may be initialized. Because the manager uses the same map
to store the initializers for the non-hot restart case and
the hot restart case, we may end up using a newer version of
code in an older generation. Instead, this CL adds a pending
map that stores the hot restart initializers so that we can
later add them to the general map of initializers right before
we call main during a hot restart and during synchronous code.
This should avoid that race condition.
Change-Id: Ib40cbe5bec400035276ebd6fca12efed7077a2b8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/425190
Commit-Queue: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
These tests are currently run with the ES6 module format.
This expands and refactors the test suite to also test the
DDC library bundle module format. Refactoring is mostly
limited to better naming and structuring of parameters.
Change-Id: If2a813af1a503e18d74dd4eec57eac4ecc8a3f35
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/424880
Reviewed-by: Nicholas Shahan <nshahan@google.com>
- Sets the name field in the emitted LibraryBundle node to
to the provided module name. We tried to avoid providing a
module name as the notion doesn't map cleanly to library
bundles, but we need to respect the provided module name.
- Emits a call to set the source map for a given library
bundle url. We don't need the full trackLibraries call so we
don't use it.
- Adds a check to avoid redefining libraries outside of a hot
reload or a hot restart. This was handled in the same code
where we emitted trackLibraries calls in the old compiler
for dynamic modules, but we want this for all code, regardless
of whether dynamic modules is enabled. So, add this check in
the library manager instead.
Change-Id: Ic4e86dbfca2b3eefa99cce44fae0973164ab77a5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/423620
Reviewed-by: Nicholas Shahan <nshahan@google.com>