commit | e9e761644d9954faa740901e1eb6b6e71a9003f6 | [log] [tgz] |
---|---|---|
author | Paul Berry <paulberry@google.com> | Tue Oct 01 16:08:52 2024 +0000 |
committer | Commit Queue <dart-scoped@luci-project-accounts.iam.gserviceaccount.com> | Tue Oct 01 16:08:52 2024 +0000 |
tree | 08d7eb89062cb4a57540950f9a76f6768e201818 | |
parent | c4a77dce652b074efd21785ab5b35e822e3cf4c7 [diff] |
[analyzer][cfe] Share constraint generation for non-generic function types This change combines function-handling logic from the analyzer's `TypeConstraintGatherer._functionType0` and the CFE's `TypeConstraintGatherer._isNullabilityAwareSubtypeMatch` methods into `TypeConstraintGenerator.performSubtypeConstraintGenerationForFunctionTypes`, which is in `_fe_analyzer_shared`. The CFE and the analyzer have some pretty significant differences in how they represent function types: - In the analyzer, all function parameters are in a single `parameters` list; each element of this list (of type `ParameterElement`) can be queried to find out if it is named or unnamed, and if it is required or optional. A convention enforced partially by the `FunctionType` constructor is that the `parameters` list stores reqired unnamed parameters first, then either optional unnamed parameters or named parameters; named parameters are sorted by name. The analyzer provides additional getters `namedParameterTypes`, `normalParameterNames`, `normalParameterTypes`, `optionalParameterNames`, and `optionalParameterTypes`, which provide other views of this information (for example, `namedParameterTypes` contains just the named parameters, as a map from name to `ParameterElement`). - In the CFE, unnamed and named parameters are in two separate lists (`positionalParameters`, of type `List<DartType>`, and `namedParameters`, of type `List<NamedType>`); in `positionalParameters`, required parameters come before optional ones. A single integer (`requiredParameterCount`) indicates how many elements of `positionalParameters` are required, and by convention, `namedParameters` is sorted by name. In order to share logic between these representations, I had to come up with a common API that these two representations could be easily adapted to. The analyzer's representation proved to be easier to adapt, so I based the common API mostly on the CFE's representation, but with some name changes for clarity. The shared API is: - `positionalParameterTypes` gets a list of positional parameter types - `requiredPositionalParameterCount` tells how many entries in `positionalParameterTypes` are required. - `returnType` gets the function type's return type. - `sortedNamedParameters` gets a list of information about named parameters. The list elements are sorted by name, and each element of this list is of type `FunctionParameterStructure` (a common interface implemented both by the analyzer's `ParameterElement` and the CFE's `NamedType`). - `typeFormals` gets a list of the function type's formal type parameters. To minimize the performance impact of adapting the analyzer to this API, the analyzer computes `positionalParameterTypes`, `requiredPositionalParameterCount`, and `sortedNamedParameters` at the time a `FunctionType` is constructed. Hopefully this should not be too much of a performance hit, since doing so does not take too much more effort than checking that the named parameters are sorted (which the `FunctionType` constructor was already doing). This is based on previous work by Chloe Stefantsova in https://dart-review.googlesource.com/c/sdk/+/386480. Change-Id: Iefe18d72771146399d81747ceab9c929516b0523 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/386322 Commit-Queue: Paul Berry <paulberry@google.com> Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Chloe Stefantsova <cstefantsova@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.