Consolidated CHANGELOG entry for 2.3.0.

I added an intro to the UI as code stuff and then merged all of the
changes from the previous dev releases.

Change-Id: I0726268adcf5838a24dfee1cacd13e730b004090
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99736
Commit-Queue: Bob Nystrom <rnystrom@google.com>
Reviewed-by: Vijay Menon <vsm@google.com>
Reviewed-by: Alexander Thomas <athom@google.com>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 650397d..4b5979a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,36 +1,207 @@
-## 2.2.1-dev.XX.0
-(Add new changes here, and they will be copied to the change section for the
-  next dev version)
+## 2.3.0
+
+The focus in this release is on the new "UI-as-code" language features which
+make collections more expressive and declarative.
 
 ### Language
 
+Flutter is growing rapidly, which means many Dart users are building UI in code
+out of big deeply-nested expressions. Our goal with 2.3.0 was to [make that kind
+of code easier to write and maintain][ui-as-code]. Collection literals are a
+large component, so we focused on three features to make collections more
+powerful. We'll use list literals in the examples below, but these features also
+work in map and set literals.
+
+[ui-as-code]: https://medium.com/dartlang/making-dart-a-better-language-for-ui-f1ccaf9f546c
+
+#### Spread
+
+Placing `...` before an expression inside a collection literal unpacks the
+result of the expression and inserts its elements directly inside the new
+collection. Where before you had to write something like this:
+
+```dart
+CupertinoPageScaffold(
+  child: ListView(children: [
+    Tab2Header()
+  ]..addAll(buildTab2Conversation())
+    ..add(buildFooter())),
+);
+```
+
+Now you can write this:
+
+```dart
+CupertinoPageScaffold(
+  child: ListView(children: [
+    Tab2Header(),
+    ...buildTab2Conversation(),
+    buildFooter()
+  ]),
+);
+```
+
+If you the expression might evaluate to null and you want to treat that as
+equivalent to zero elements, you can use the null-aware spread `?...`.
+
+#### Collection if
+
+Sometimes you might want to include one or more elements in a collection only
+under certain conditions. If you're lucky, you can use a `?:` operator to
+selectively swap out a single element, but if you want to exchange more than one
+or omit elements, you are forced to write imperative code like this:
+
+```dart
+Widget build(BuildContext context) {
+  var children = [
+    IconButton(icon: Icon(Icons.menu)),
+    Expanded(child: title)
+  ];
+
+  if (isAndroid) {
+    children.add(IconButton(icon: Icon(Icons.search)));
+  }
+
+  return Row(children: children);
+}
+```
+
+We now allow `if` inside collection literals to conditionally omit or (with
+`else`) swap out an element:
+
+```dart
+Widget build(BuildContext context) {
+  return Row(
+    children: [
+      IconButton(icon: Icon(Icons.menu)),
+      Expanded(child: title),
+      if (isAndroid)
+        IconButton(icon: Icon(Icons.search)),
+    ],
+  );
+}
+```
+
+Unlike the existing `?:` operator, a collection `if` can be composed with
+spreads to conditionally include or omit multiple items:
+
+```dart
+Widget build(BuildContext context) {
+  return Row(
+    children: [
+      IconButton(icon: Icon(Icons.menu)),
+      if (isAndroid) ...[
+        Expanded(child: title),
+        IconButton(icon: Icon(Icons.search)),
+      ]
+    ],
+  );
+}
+```
+
+#### Collection for
+
+In many cases, the higher-order methods on Iterable give you a declarative way
+to modify a collection in the context of a single expression. But some
+operations, especially involving both transforming and filtering, can be
+cumbersome to express in a functional style.
+
+To solve this problem, you can use `for` inside a collection literal. Each
+iteration of the loop produces an element which is then inserted in the
+resulting collection. Consider the following code:
+
+```dart
+var command = [
+  engineDartPath,
+  frontendServer,
+  ...fileSystemRoots.map((root) => "--filesystem-root=$root"),
+  ...entryPoints
+      .where((entryPoint) => fileExists("lib/$entryPoint.json"))
+      .map((entryPoint) => "lib/$entryPoint"),
+  mainPath
+];
+```
+
+With a collection `for`, the code becomes simpler:
+
+```dart
+var command = [
+  engineDartPath,
+  frontendServer,
+  for (var root in fileSystemRoots) "--filesystem-root=$root",
+  for (var entryPoint in entryPoints)
+    if (fileExists("lib/$entryPoint.json")) "lib/$entryPoint",
+  mainPath
+];
+```
+
+As you can see, all three of these features can be freely composed. For full
+details of the changes, see [the official proposal][ui-as-code proposal].
+
+[ui-as-code proposal]: https://github.com/dart-lang/language/blob/master/accepted/future-releases/unified-collections/feature-specification.md
+
+**Note: These features are not currently supported in *const* collection
+literals. In a future release, we intend to relax this restriction and allow
+spread and collection `if` inside const collections.**
+
 ### Core library changes
 
+#### `dart:isolate`
+
+*   Added `debugName` property to `Isolate`.
+*   Added `debugName` optional parameter to `Isolate.spawn` and
+    `Isolate.spawnUri`.
+
+#### `dart:core`
+
+*   RegExp patterns can now use lookbehind assertions.
+*   RegExp patterns can now use named capture groups and named backreferences.
+    Currently, named group matches can only be retrieved in Dart either by the
+    implicit index of the named group or by downcasting the returned Match
+    object to the type RegExpMatch. The RegExpMatch interface contains methods
+    for retrieving the available group names and retrieving a match by group
+    name.
+
 ### Dart VM
 
-* The VM service now requires an authentication code by default. This behavior
-  can be disabled by providing the `--disable-service-auth-codes` flag.
+*   The VM service now requires an authentication code by default. This behavior
+    can be disabled by providing the `--disable-service-auth-codes` flag.
 
-### Tool Changes
+*   Support for deprecated flags '-c' and '--checked' has been removed.
 
-#### Linter
+### Dart for the Web
 
-The Linter was updated to `0.1.86` which includes the following changes:
+#### dart2js
 
-* new lint: `prefer_inlined_adds`
-* new lint: `prefer_for_elements_to_map_fromIterable`
-* new lint: `prefer_if_elements_to_conditional_expressions`
-* new lint: `diagnostic_describe_all_properties`
+A binary format was added to dump-info. The old JSON format is still available
+and provided by default, but we are starting to deprecate it. The new binary
+format is more compact and cheaper to generate. On some large apps we tested, it
+was 4x faster to serialize and used 6x less memory.
 
-#### Other Tools
+To use the binary format today, use `--dump-info=binary`, instead of
+`--dump-info`.
 
-## 2.2.1-dev.3.1
+What to expect next?
 
-* Cherry-pick 245576a096a2da54ef21d664d37d1f50f6f8dbb7 to dev
-* Cherry-pick a47b4ad2b8683cc8a82aa0ff89da2db7a3be27a3 to dev
-* Cherry-pick 9a2b222cba94126591b5d985a42d40c704a73c90 to dev
+*   The [visualizer tool][visualizer] will not be updated to support the new
+    binary format, but you can find several command-line tools at
+    `package:dart2js_info` that provide similar features to those in the
+    visualizer.
 
-### Tool Changes
+*   The command-line tools in `package:dart2js_info` also work with the old JSON
+    format, so you can start using them even before you enable the new format.
+
+*   In a future release `--dump-info` will default to `--dump-info=binary`. At
+    that point, there will be an option to fallback to the JSON format, but the
+    visualizer tool will be deprecated.
+
+*   A release after that, the JSON format will no longer be available from
+    dart2js, but may be available from a command-line tool in
+    `package:dart2js_info`.
+
+[visualizer]: https://dart-lang.github.io/dump-info-visualizer/
+
+### Tools
 
 #### dartfmt
 
@@ -39,103 +210,25 @@
 *   Properly format trailing commas in assertions.
 *   Improve indentation of adjacent strings in argument lists.
 
-## 2.2.1-dev.3.0
-
-### Dart VM
-
-* Support for deprecated flags '-c' and '--checked' has been removed
-
-### Core library changes
-
-#### `dart:isolate`
-
-* Added `debugName` property to `Isolate`.
-* Added `debugName` optional parameter to `Isolate.spawn` and
-  `Isolate.spawnUri`.
-
-### Tool Changes
-
-#### dartfmt
-
-* Tweak set literal formatting to follow other collection literals.
-* Add support for "UI as code" features.
-
 #### Linter
 
-The Linter was updated to `0.1.83` which includes the following changes:
+The Linter was updated to `0.1.86`, which includes the following changes:
 
-* updated `file_names` to skip prefixed-extension Dart files (e.g., `.css.dart`, `.g.dart`)
-* miscellaneous rule documentation fixes
-* fixed NPE in `avoid_shadowing_type_parameters`
-* added linter version numbering for use in analyzer summaries
-* fixed type utilities to handle inheritance cycles
-* fixed `unnecessary_parenthesis` false positives
-
-## 2.2.1-dev.2.0
-
-## 2.2.1-dev.1.1
-
-* Cherry-pick 567d552de8ff93d704111467e7f3bf3b896ab684 to dev
-* Cherry-pick 4ca57befd707a0309e384472a566c084eef0e56e to dev
-
-## 2.2.1-dev.1.0
-
-* Support for deprecated flags '-c' and '--checked' has been removed
-* RegExp patterns can now use lookbehind assertions.
-* RegExp patterns can now use named capture groups and named backreferences.
-  Currently, named group matches can only be retrieved in Dart either by
-  the implicit index of the named group or by downcasting the returned Match
-  object to the type RegExpMatch. The RegExpMatch interface contains methods
-  for retrieving the available group names and retrieving a match by group name.
-
-### Tool Changes
+*   Added the following lints: `prefer_inlined_adds`,
+    `prefer_for_elements_to_map_fromIterable`,
+    `prefer_if_elements_to_conditional_expressions`,
+    `diagnostic_describe_all_properties`.
+*   Updated `file_names` to skip prefixed-extension Dart files (`.css.dart`,
+  `.g.dart`, etc.).
+*   Fixed false positives in `unnecessary_parenthesis`.
 
 #### Pub client
 
-* Added a CHANGELOG validator that complains if you `pub publish` without mentioning the current
-  version.
-* Removed validation of library names when doing `pub publish`.
-* Added support for `pub global activate`ing package from a custom pub URL.
-* Added subcommand: `pub logout`. Logs you out of the current session.
-* Fix: Use default server for `pub uploader` command.
-
-#### dart2js
-
-*  `--dump-info=binary`
-
-   A binary format was added to dump-info. The old JSON format is still
-   available and provided by default, but we are starting to deprecate it.
-
-   The new binary format is more compact and cheaper to generate.  On some large
-   apps we tested, it was 4x faster to serialize and used 6x less memory.
-
-   To use it today, use `--dump-info=binary`, instead of `--dump-info`.
-
-   What to expect next?
-   * The [visualizer tool][visualizer] will not be updated to support this new
-     format, but you can find several command-line tools at
-     `package:dart2js_info` that provide similar features to those in the
-     visualizer.
-
-   * The command-line tools in `package:dart2js_info` also work with the old
-     JSON format, so you can start using it even before you enable the new
-     format.
-
-   * In a future release `--dump-info` will default to `--dump-info=binary`. At
-     that point, there will be an option to fallback to the JSON format, but the
-     visualizer tool will be deprecated.
-
-   * A release after that, the JSON format will no longer be available from
-     dart2js, but may be availabe from a command-line tool in
-     `package:dart2js_info`.
-
-[visualizer]: https://dart-lang.github.io/dump-info-visualizer/
-
-## 2.2.1-dev.0.0
-
-* Cherry-pick 6f8415245d4dd298730facf83e03de69fc29bbd3 to dev
-* Cherry-pick e7d263b05f7f66d15f778df60ee60625e9a3c5f4 to dev
-* Cherry-pick dc8a56bc0ece296915c7016e0a8241c7068eca18 to dev
+*   Added a CHANGELOG validator that complains if you `pub publish` without
+    mentioning the current version.
+*   Removed validation of library names when doing `pub publish`.
+*   Added support for `pub global activate`ing package from a custom pub URL.
+*   Added subcommand: `pub logout`. Logs you out of the current session.
 
 ## 2.2.0 - 2019-02-26