Allow annotating top-level or static fields with `@Native` to create
fields backed by native memory.
By using the `_addressOf` operator implemented in the VM, these fields
can be implemented in the CFE by replacing them with accessors looking
up the pointer and then using existing methods to load and store the
value.
Closes https://github.com/dart-lang/sdk/issues/50551
TEST=tests/ffi/native_assets/asset_*_test.dart
TEST=pkg/analyzer/test/src/diagnostics/ffi_native_test.dart
CoreLibraryReviewExempt: VM & dart2wasm only feature
Change-Id: I61dccc88076723d6a6ba02d7fd848b18e4caf780
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/338020
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Lasse Nielsen <lrn@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
This updates the handling of method/setter conflict between declared
and inherited members in extension types. Declared member now precludes
the conflicting members from being inherited, thus avoid the compile
time error.
Closes#53720
Change-Id: Ie185fa5f378d3bca64ebf77480e2fcefa767bc30
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/341560
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
A quirk of analyzer and CFE implementations is that they resolve
property gets such as `foo.bar` to specific field or getter
declarations that may be not be directly defined on the target type;
for example if `foo` has type `B`, and `B` extends `A`, and `A`
contains a field called `bar`, then `foo.bar` is considered to refer
to `A.bar`, for example:
class A {
int? bar;
}
class B extends A {}
f(B foo) {
print(foo.bar); // Resolved to `A.bar`.
}
This is in contrast with the language specification, which makes a
clean distinction between class _declarations_ and the _interfaces_
implied by those declarations. While a class declaration can contain
(among other things) both getters and fields, which might be concrete
or abstract, an interface doesn't distinguish between getters and
fields, and is inherently abstract.
The advantage of the analyzer/CFE approach is that it allows more
intuitive error messages and "go to definition" behavior, which
benefits users. But it has some ill-defined corner cases involving
complex class hierarchies, because not every property access can be
resolved to a unique declaration (sometimes a getter is multiply
inherited from multiple interfaces, for example). The language spec
approach has the advantage of being well-defined and consistent even
in situations involving complex class hierarchies.
When I initially implemented field promotion, I took advantage of this
quirk of the analyzer and CFE implementations, so that I could make
property gets that refer to field declarations promotable, while
keeping property gets that refer to abstract getter declarations
non-promotable. This caused unpredictable behaviors in the ill-defined
corner cases. It also meant that in certain rare cases, a property
access might not be promoted even when it would be sound to do so
(e.g. a property access might refer to a private abstract getter
declaration, but the only concrete _implementation_ of that abstract
getter was a final field).
This CL changes the rule for promotability so that any get of a
private property is considered promotable, provided that the
containing library doesn't contain any concrete getters, non-final
fields, or external fields with the same name. It no longer matters
whether the private property refers to a field or a getter. This rule
is simpler than the old rule, restores the spec's clean distinction
between class declarations and interfaces, and allows more promotions
without sacrificing soundness.
For additional details please see the breaking change announcement at
https://github.com/dart-lang/sdk/issues/54056, as well as the original
change proposal at https://github.com/dart-lang/language/issues/3328.
Fixes https://github.com/dart-lang/sdk/issues/54056.
Fixes https://github.com/dart-lang/language/issues/3328.
Change-Id: I38ffcb9ecce8bccb93b1b2586a1222a0fb1005a7
Bug: https://github.com/dart-lang/sdk/issues/54056
Bug: https://github.com/dart-lang/language/issues/3328
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/337609
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Lasse Nielsen <lrn@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This moves pattern variable assignments of fully matched expressions into the case body. This will help backends (dart2js in particular) to reason about the code flow.
Closes#54115
Change-Id: I598a384a829f16e91ab2d6a309499cf20b9cc121
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/339122
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
This changes the pattern matching lowering to avoid using late final variables (or lowerings thereof) and instead inline the initializer where used. This avoids generating closures that are hard for backends to reason about and optimize.
Closes#52805Closes#53804
Change-Id: Ia887446dd4d4475d05cf852c812bfe4b851de261
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/338860
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
General approach: Find all scopes for an offset,
then pick "the right one".
This still leaves a few offsets where we can't pick 1 scope in the
(non-outline) dills in the out directory though.
More thorough testing will follow.
TEST=ci
Change-Id: I66448498e07aa03f720733bcaf167bbfa30bca2f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/338840
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Includes a cleanup of the errors reported for duplicate instance field.
Previously, in addition to reporting the duplicate, we would report that
the field cannot be used because it is a duplicate and that the
duplicate field hasn't been initialized.
Closes#53467Closes#53320
Change-Id: Ifd94223500809f3be36a1345d9d0c409778eed8a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/336885
Reviewed-by: Paul Berry <paulberry@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
This language feature allows the user to declare a static type using
`extension type` syntax, for example:
extension type IdNumber(int i) {
operator <(IdNumber other) => i < other.i;
bool isValid(Some parameters) => ...;
}
This behaves similarly to a "wrapper" class:
class IdNumber {
final int i;
IdNumber(this.i);
operator <(IdNumber other) => i < other.i;
bool isValid(Some parameters) => ...;
}
However, at runtime, no wrapper objects are created; instead, an
instance of the extension type is represented directly by its
"representation type" (`int` in the above example), and methods like
`isValid` are resolved statically. This gives developers an
abstraction mechanism with the advantage of zero runtime performance
cost, since no extra heap space is required, and no extra instructions
are needed to convert between an extension type and its underlying
representation.
The disadvantage of using extension types as an abstraction mechanism
is that since no wrapper objects are created at runtime, the
abstraction can be bypassed using `dynamic`, runtime casts, or by
"laundering" the object through contravariant generic methods like
`List.add` (which are runtime checked in Dart). For example:
main() {
var id = IdNumber(1);
var list1 = <int>[];
List<Object> list2 = list1;
list2.add(id); // OK at compile time because `IdNumber` is a
// subtype of `Object`. OK at runtime because
// at runtime, `IdNumber` and `int` are
// indistinguishable.
int i = list1[0];
print(i);
}
Extension types are expected to be particularly useful for
low-overhead decoding of external data formats (such as JSON), and for
inter-operation with other languages (such as Javascript).
For additional information see the feature specification:
https://github.com/dart-lang/language/blob/main/accepted/future-releases/extension-types/feature-specification.md
Change-Id: I900a3a25dcfc38bfa9c9f9b5b9fa20f362883653
Tested: Standard trybots
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/335062
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Currently, if a not-enabled-by-default experimental flag is on we allow
formatting to fail.
This means that when the flag is flipped there's a risk of failures as
formatter crashes are now not allowed anymore.
The failures for flipping the extension types / inline-class feature
has caused crashes and was fixed before (twice!) in
https://dart-review.googlesource.com/c/sdk/+/336001https://dart-review.googlesource.com/c/sdk/+/335448
But naturally a new test was added after
(https://dart-review.googlesource.com/c/sdk/+/336022) and we had a new
failure on the flag-flip CL.
This CL instead pretends like the inline-class flag is already flipped,
in that the formatter is not allowed to crash because of it.
That should make any new tests added before the flag is flipped that
would otherwise cause a failure upon flag flip, fail, forcing the
update of the status file.
The status file is furtermore updated.
Change-Id: Ifbc3d271a614e5dd747b35b252034087ad155a92
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/337321
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
Before (or, currently) we force the `ExperimentalFlag.inlineClass`
experimental flag to be on and it's experimental and we thus basically
always allow the formatter to fail.
With the flag being flipped this allowing it to fail goes away.
This CL fixes some of it by passing flags to the formatter as well, and
"fixes" the rest by putting in status entries.
Change-Id: I059efa0473dc0746bd72b45071c69915d4472b07
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/336001
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>