[ddc] Fix named args in redirecting constructors

Change-Id: Iaed36c3cab43672338a5b1750aad25951428052c
Fixes: https://github.com/dart-lang/sdk/issues/47831
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/221887
Reviewed-by: Mark Zhou <markzipan@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index ec112bc..a25692d 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -1612,14 +1612,12 @@
     var fn = node.function;
     var body = _emitArgumentInitializers(fn, node.name.text);
 
-    // Redirecting constructors: these are not allowed to have initializers,
-    // and the redirecting ctor invocation runs before field initializers.
-    var redirectCall = node.initializers
-            .firstWhere((i) => i is RedirectingInitializer, orElse: () => null)
-        as RedirectingInitializer;
-
-    if (redirectCall != null) {
-      body.add(_emitRedirectingConstructor(redirectCall, className));
+    // Redirecting constructors are not allowed to have conventional
+    // initializers but can have variable declarations in the form of
+    // initializers to support named arguments appearing anywhere in the
+    // arguments list.
+    if (node.initializers.any((i) => i is RedirectingInitializer)) {
+      body.add(_emitRedirectingConstructor(node.initializers, className));
       return body;
     }
 
@@ -1652,15 +1650,23 @@
   }
 
   js_ast.Statement _emitRedirectingConstructor(
-      RedirectingInitializer node, js_ast.Expression className) {
-    var ctor = node.target;
-    // We can't dispatch to the constructor with `this.new` as that might hit a
-    // derived class constructor with the same name.
-    return js.statement('#.#.call(this, #);', [
-      className,
-      _constructorName(ctor.name.text),
-      _emitArgumentList(node.arguments, types: false)
-    ]);
+      List<Initializer> initializers, js_ast.Expression className) {
+    var jsInitializers = <js_ast.Statement>[
+      for (var init in initializers)
+        if (init is LocalInitializer)
+          // Temporary locals are created when named arguments don't appear at
+          // the end of the arguments list.
+          visitVariableDeclaration(init.variable)
+        else if (init is RedirectingInitializer)
+          // We can't dispatch to the constructor with `this.new` as that might
+          // hit a derived class constructor with the same name.
+          js.statement('#.#.call(this, #);', [
+            className,
+            _constructorName(init.target.name.text),
+            _emitArgumentList(init.arguments, types: false)
+          ])
+    ];
+    return js_ast.Block(jsInitializers);
   }
 
   js_ast.Statement _emitSuperConstructorCallIfNeeded(