This updates the exhaustive checking algorithm to produce a list of
witnesses instead of a single witness in case of a non-exhaustive error.
This is used to create a witness for each missing subtype when checking
"sealed static types", for instance enums and sealed classes.
The current error reporting isn't changed and only reports the first
witness. Use of the multiple witnesses in error messages and/or lints
must be done in the CFE and analyzer.
Change-Id: I950816f6a9eca16773f182d5d820929bdcb39684
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/357160
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
In discussion with the language team, we've decided to ship this
feature in Dart 3.4. This CL contains a minimal CHANGELOG entry for
the feature; I plan to expand on it once I'm finished with the feature
specification document.
Change-Id: Iac86ebed322feb8e478bf5a6780d50adb433ed7f
Tested: trybots
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/355900
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Nate Bosch <nbosch@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This removes the Declaration from RecordFieldDeclaration and renames it
to RecordField. The fields of a record type are not declarations but
are similar to FormalParameter of a FunctionTypeAnnotation; they contain
part of the information for the RecordTypeAnnotation but are not
identifiable on their own.
Change-Id: Iaa9d95d49f2152096b970c6e2d24c524327f933e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/355740
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jake Macdonald <jakemac@google.com>
This CL introduces a way to mark all instances of a class as deeply
immutable.
In order to statically verify that all instances of a deeply immutable
class are immutable, a deeply immutable classes must have the following
properties:
1. All instance fields must
1. have a deeply immutable type,
2. be final, and
3. be non-late.
2. The class must be `final` or `sealed`. This ensures no
non-deeply-immutable subtypes are added by external code.
3. All subtypes must be deeply immutable. This ensures 1.1 can be
trusted.
4. The super type must be deeply immutable (except for Object).
Note that instances of some classes in the VM are deeply immutable
while their class cannot be marked immutable.
* SendPort, Capability, RegExp, and StackTrace are not `final` and
can be implemented by external code.
* UnmodifiableTypedDataViews do not have a public type. (It was
recently deprecated.)
See runtime/docs/deeply_immutable.md for more details.
Use case:
This enables attaching a `Dart_FinalizableHandle` to a deeply immutable
object and the deeply immutable object with other isolates in the same
isolate group.
(Note that `NativeFinalizer`s live in an isolate, and not an isolate
group. So this should currently _not_ be used with `NativeFinalizer`s.
See https://github.com/dart-lang/sdk/issues/55062 for making a
`NativeFinalizer.shared(` that would live in an isolate group instead
of in an isolate.)
Implementation details:
Before this CL, the `ImmutableBit` in the object header was only ever
set to true for predefined class ids (and for const objects). After
this CL, the bit can also be set to true for non const instances of
user-defined classes. The object allocation and initialization code has
been changed to deal with this new case. The immutability of a class is
saved in the class state bits. On object allocation and initialization
the immutability bit is read from the class for non-predefined class
ids.
TEST=runtime/tests/vm/dart/isolates/fast_object_copy2_test.dart
TEST=runtime/vm/isolate_reload_test.cc
TEST=tests/lib/isolate/deeply_immutable_*
Bug: https://github.com/dart-lang/sdk/issues/55120
Bug: https://github.com/dart-lang/sdk/issues/54885
Change-Id: Ib97fe589cb4f81673cb928c93e3093838d82132d
Cq-Include-Trybots: luci.dart.try:vm-aot-android-release-arm64c-try,vm-aot-android-release-arm_x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-debug-x64c-try,vm-aot-mac-release-arm64-try,vm-aot-mac-release-x64-try,vm-aot-obfuscate-linux-release-x64-try,vm-aot-optimization-level-linux-release-x64-try,vm-appjit-linux-debug-x64-try,vm-asan-linux-release-x64-try,vm-checked-mac-release-arm64-try,vm-eager-optimization-linux-release-ia32-try,vm-eager-optimization-linux-release-x64-try,vm-ffi-android-debug-arm-try,vm-ffi-android-debug-arm64c-try,vm-ffi-qemu-linux-release-arm-try,vm-ffi-qemu-linux-release-riscv64-try,vm-fuchsia-release-x64-try,vm-kernel-linux-debug-x64-try,vm-kernel-precomp-linux-release-x64-try,vm-linux-debug-ia32-try,vm-linux-debug-x64-try,vm-linux-debug-x64c-try,vm-mac-debug-arm64-try,vm-mac-debug-x64-try,vm-msan-linux-release-x64-try,vm-reload-linux-debug-x64-try,vm-reload-rollback-linux-debug-x64-try,vm-ubsan-linux-release-x64-try
Cq-Include-Trybots: dart-internal/g3.dart-internal.try:g3-cbuild-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/354902
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
In the following expression types, the static type is computed using
the least upper bound ("LUB") of their subexpressions (adjusted as
appropriate to account for the null-shorting behaviors of `??` and
`??=`):
- Conditional expressions (`a ? b : c`)
- If-null expressions (`a ?? b`)
- If-null assignments (`a ??= b`)
- Switch expressions (`switch (s) { p0 => e0, ... }`)
This can lead to problems since the LUB computation sometimes produces
a greater bound than is strictly necessary (for example if there are
multiple candidate bounds at the same level of the class hierarchy,
the LUB algorithm will walk up the class hierarchy until it finds a
level at which there is a unique result). For a discussion of the kind
of problems that can arise, see
https://github.com/dart-lang/language/issues/1618.
This change improves the situation by changing the analysis of these
four expression types so that after computing a candidate static type
using LUB, if that static type does not satisfy the expression's
context, but the static types of all the subexpressions *do* satisfy
the expression's context, then the greatest closure of the context is
used as the static type instead of the LUB. This is the algorithm
proposed in
https://github.com/dart-lang/language/issues/1618#issuecomment-1507241494.
This is theoretically a breaking change (since it can change code that
demotes a local variable into code that doesn't, and then the demotion
or lack of demotion can have follow-on effects in later code). So it
is implemented behind the `inference-update-3` experiment
flag. However, in practice it is minimally breaking; a test over all
of google3 found no test failures from turning the feature on.
Since one of these expression types (switch expressions) is
implemented in `package:_fe_analyzer_shared`, but the other three are
implemented separately in the `package:analyzer` and
`package:front_end`, this change required modifications to all three
packages. I've included tests for the new functionality, following the
testing style of each package. I've also included a comprehensive set
of language tests that fully exercises the feature regardless of how
it's implemented.
Since `package:front_end` has many different implementations of `??=`
depending on the form of the left hand side, I've tried to be quite
comprehensive in the language tests, covering each type of assignable
expression that might appear to the left of `??=`.
Change-Id: I13a6168b6edf6eac1e52ecdb3532985af19dbcdf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/353440
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
Today, each boolean requires 1 byte. With this implementation all booleans on a class combined require between one and three bytes, depending on which ones are set.
This may or may not actually be worthwhile, please push back if you think it's not :). I can't tell much difference running real macros.
Change-Id: Ie9fac0497f0d4571c5f1314009ec9d7c474b073c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/352562
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Auto-Submit: Jake Macdonald <jakemac@google.com>
Reviewed-by: Morgan :) <davidmorgan@google.com>
E.g. running
```
out/ReleaseX64/dart pkg/_fe_analyzer_shared/test/macros/executor/executor_test.dart
```
(which is apparently the wrong executable) fails after 12 minutes (!)
with "TimeoutException after 0:12:00.000000: Test timed out after 12
minutes."
With this instead it runs in a few seconds because the stuff that makes
it wait forever throws instead.
Change-Id: Idd8be08438863511769b4cace1a492d613cadb03
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/352301
Reviewed-by: Jake Macdonald <jakemac@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
This adds support for generating the merged augmentation library in the
CFE. In order to get the right file offsets in the generated AST the
MacroExecutor.buildArgumentationLibrary function is extended to compute
a list of spans the describe what each segment of the generated source
code contains. These spans are used to compute the offset relation
between the intermediate augmentation libraries and the merged
augmentation libraries.
Change-Id: Ie5b9c23130da67ac874fb824b82827bfd6b88880
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/349864
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
Reviewed-by: Jake Macdonald <jakemac@google.com>
- Adds hasInitializer and hasConst to VariableDeclaration.
- Renames isStatic to hasStatic to be consistent with other members.
- Improves serialization tests by randomizing some values, which
should help to catch ordering errors in serialization.
Change-Id: I44199b1b058444510b9fa55afe0611187b90fc95
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/352540
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Morgan :) <davidmorgan@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Auto-Submit: Jake Macdonald <jakemac@google.com>
The only expected exceptions at this point are DiagnosticException and MacroException subtypes; everything else is a bug in the implementation.
Tweak the diagnostic to explain that it's due to a bug in the macro. Add the exception message and stack trace as a context message, and a fix hint to contact the author.
Add a language test.
R=jakemac@google.com
Change-Id: Ieaa6bedb3bc1646e4be61b384619152cc173b7e0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/351040
Auto-Submit: Morgan :) <davidmorgan@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Morgan :) <davidmorgan@google.com>
Reviewed-by: Jake Macdonald <jakemac@google.com>
Previous attempt to use AST and builder was removed.
Also, after talk with Brian, removed scopes, and replaced with more
course grained, but simpler collision detection. If there is a declaration with the same name as prefixed, the name stays prefixed. Similarly, if there is an unprefixed invocation.
Change-Id: If2b0ce530ac81482e5bfd066d6df43e1a5d34799
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/350683
Reviewed-by: Jake Macdonald <jakemac@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This prevents --pause-isolates-on-start and --pause-isolates-on-exit
from impacting isolates spawned from system isolates. This should be
revisited to determine if:
- Inheriting the system isolate property is actually what we want to do
in general
- Isolate.spawn* APIs should instead include a parameter to specify an
isolate as a system isolate
Fixes https://github.com/dart-lang/sdk/issues/54729
TEST=Manual testing
Change-Id: Ibacdea845db6344148c11bebf001e4cac3377a62
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/348460
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
I don't try to be even close to be correct here, but this is the base
on top of which I'd like to build the full implementation.
The idea is that we scan, and implement parser listener that builds
prefixed name in scopes. We fill scope with declarations as we find them. Using these scopes we can decide which import prefixes can be removed.
As usually for shared code, clients will implement abstract methods in the client specific way.
We might get a hierarchy of `Edit` objects, such as `RemoveImportPrefix` and `RemoveImportDirective` because at least in the analyzer we might need to apply some changes to the element models (metadata, constants).
Change-Id: I153259d87a09ab070f37192ae64ccd8da36e2d41
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/350260
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>