Version 2.15.0-26.0.dev

Merge commit '19d12d18d66ea8e6208a920dd0e257cf8d4a0f64' into 'dev'
diff --git a/pkg/analyzer/tool/macro/generate.dart b/pkg/analyzer/tool/macro/generate.dart
new file mode 100644
index 0000000..2cc9a41
--- /dev/null
+++ b/pkg/analyzer/tool/macro/generate.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io' as io;
+
+import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/util/file_paths.dart' as file_paths;
+
+void main(List<String> arguments) async {
+  if (arguments.length != 1) {
+    _printUsage();
+    io.exit(1);
+  }
+
+  var resourceProvider = PhysicalResourceProvider.INSTANCE;
+  var pathContext = resourceProvider.pathContext;
+
+  // The directory must exist.
+  var packagePath = arguments[0];
+  var packageFolder = resourceProvider.getFolder(packagePath);
+  if (!packageFolder.exists) {
+    print('Error: $packagePath does not exist.');
+    io.exit(1);
+  }
+
+  // The directory must be a Pub package.
+  var pubspecYamlFile = packageFolder.getChildAssumingFile(
+    file_paths.pubspecYaml,
+  );
+  if (!pubspecYamlFile.exists) {
+    print('Error: ${pubspecYamlFile.path} does not exist.');
+    io.exit(1);
+  }
+
+  var collection = AnalysisContextCollection(
+    includedPaths: [packagePath],
+  );
+  for (var analysisContext in collection.contexts) {
+    var analyzedPaths = analysisContext.contextRoot.analyzedFiles();
+    for (var path in analyzedPaths) {
+      if (file_paths.isDart(pathContext, path)) {
+        var session = analysisContext.currentSession;
+        var unitElementResult = await session.getUnitElement(path);
+        if (unitElementResult is UnitElementResult) {
+          var unitElement =
+              unitElementResult.element as CompilationUnitElementImpl;
+          // If has macro-generated content, write it.
+          var macroGeneratedContent = unitElement.macroGeneratedContent;
+          if (macroGeneratedContent != null) {
+            var relativePath = pathContext.relative(path, from: packagePath);
+            var combinedPath = pathContext.join(
+                packagePath, '.dart_tool', 'analyzer', 'macro', relativePath);
+            resourceProvider.getFile(combinedPath)
+              ..parent2.create()
+              ..writeAsStringSync(macroGeneratedContent);
+          }
+        }
+      }
+    }
+  }
+}
+
+void _printUsage() {
+  print('''
+Usage: dart generate.dart path-to-pub-package
+Write combined code of files that have macro-generated declarations.
+''');
+}
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 262b847..7a3c80d 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -1913,28 +1913,24 @@
   /// ```dart
   /// /// Starts listening to [input] and duplicates all non-error events.
   /// StreamSubscription<int> _onListen(Stream<int> input, bool cancelOnError) {
-  ///   late StreamSubscription<String> subscription;
-  ///   // Create controller that forwards pause, resume and cancel events.
-  ///   var controller = new StreamController<String>(
-  ///       onPause: () {
-  ///         subscription.pause();
-  ///       },
-  ///       onResume: () {
-  ///         subscription.resume();
-  ///       },
-  ///       onCancel: () => subscription.cancel(),
-  ///       sync: true); // "sync" is correct here, since events are forwarded.
-  ///
-  ///   // Listen to the provided stream.
-  ///   subscription = input.listen((data) {
-  ///     // Duplicate the data.
-  ///     controller.add(data);
-  ///     controller.add(data);
-  ///   },
-  ///       onError: controller.addError,
-  ///       onDone: controller.close,
-  ///       cancelOnError: cancelOnError);
-  ///
+  ///   // Create the result controller.
+  ///   // Using `sync` is correct here, since only async events are forwarded.
+  ///   var controller = StreamController<int>(sync: true);
+  ///   controller.onListen = () {
+  ///     var subscription = input.listen((data) {
+  ///       // Duplicate the data.
+  ///       controller.add(data);
+  ///       controller.add(data);
+  ///     },
+  ///         onError: controller.addError,
+  ///         onDone: controller.close,
+  ///         cancelOnError: cancelOnError);
+  ///     // Controller forwards pause, resume and cancel events.
+  ///     controller
+  ///       ..onPause = subscription.pause
+  ///       ..onResume = subscription.resume
+  ///       ..onCancel = subscription.cancel;
+  ///   };
   ///   // Return a new [StreamSubscription] by listening to the controller's
   ///   // stream.
   ///   return controller.stream.listen(null);
diff --git a/tools/VERSION b/tools/VERSION
index 70ba861..595c654 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 15
 PATCH 0
-PRERELEASE 25
+PRERELEASE 26
 PRERELEASE_PATCH 0
\ No newline at end of file