[flow analysis] Re-work handling of CFE null-aware guards. The CFE desugars null-aware expressions such as `a?.b` into equivalent `let` expressions involving a temporary guard variable (e.g., `let x = a in x == null ? null : x.b`). This desugaring happens in the body builder, prior to flow analysis. As a result, the expressions and variables passed to flow analysis are those of the desugared `let` expression rather than those of the code the user wrote. So a hack is needed to ensure that flow analysis produces the correct result; the hack involves promoting the temporary guard variable in the code path where it is not null. Prior to this change, the hack was done entirely in the CFE. Instead of making a single pair of calls to `FlowAnalysis.nullAwareAccess_rightBegin` and `FlowAnalysis.nullAwareAccess_end` for every null-aware expression, the CFE made two nested pairs of calls: one to promote the true target of the null-aware access, and the other to promote the temporary guard variable. This had the advantage of keeping the hack entirely in the CFE, but unfortunately it got in the way of fixing https://github.com/dart-lang/language/issues/4344, because it prevented flow analysis from properly recognizing field accesses inside null-aware expressions. This change adds an optional `guardVariable` parameter to `FlowAnalysis_nullAwareAccess_rightBegin`, and shifts the responsibility for promoting the temporary guard variable to the flow analysis engine itself. With this change, the CFE no longer needs to make two nested pairs of calls to `FlowAnalysis.nullAwareAccess_rightBegin` and `FlowAnalysis.nullAwareAccess_end`, and flow analysis now has the necessary information to recognize field accesses inside null-aware expressions. I will perform the actual fix for https://github.com/dart-lang/language/issues/4344 in a follow-up CL. Note that in the future, I would like to change the CFE so that it desugars null-aware accesses during type inference rather than during the body builder; this will allow the expressions and variables passed to flow analysis to be precisely those of the code the user wrote; that in turn will give us extra confidence that flow analysis produces the same results in the analyzer and the CFE. Change-Id: Ie63619a3ca0f011c1ae8e3c0c76b5bc7c1ab8419 Bug: https://github.com/dart-lang/language/issues/4344 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/427341 Reviewed-by: Johnni Winther <johnniwinther@google.com> Reviewed-by: Chloe Stefantsova <cstefantsova@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
Dart is:
Approachable: Develop with a strongly typed programming language that is consistent, concise, and offers modern language features like null safety and patterns.
Portable: Compile to ARM, x64, or RISC-V machine code for mobile, desktop, and backend. Compile to JavaScript or WebAssembly for the web.
Productive: Make changes iteratively: use hot reload to see the result instantly in your running app. Diagnose app issues using DevTools.
Dart's flexible compiler technology lets you run Dart code in different ways, depending on your target platform and goals:
Dart Native: For programs targeting devices (mobile, desktop, server, and more), Dart Native includes both a Dart VM with JIT (just-in-time) compilation and an AOT (ahead-of-time) compiler for producing machine code.
Dart Web: For programs targeting the web, Dart Web includes both a development time compiler (dartdevc) and a production time compiler (dart2js).
Dart is free and open source.
See LICENSE and PATENT_GRANT.
Visit dart.dev to learn more about the language, tools, and to find codelabs.
Browse pub.dev for more packages and libraries contributed by the community and the Dart team.
Our API reference documentation is published at api.dart.dev, based on the stable release. (We also publish docs from our beta and dev channels, as well as from the primary development branch).
If you want to build Dart yourself, here is a guide to getting the source, preparing your machine to build the SDK, and building.
There are more documents in our repo at docs.
The easiest way to contribute to Dart is to file issues.
You can also contribute patches, as described in Contributing.
Future plans for Dart are included in the combined Dart and Flutter roadmap on the Flutter wiki.