[fasta] Clone missing default values of formals in forwarding stubs

Fixes #31027.

For additional details see http://dartbug.com/33820.

Bug: http://dartbug.com/31027
Change-Id: I8eb3fb0c5d1bb6cdfc4115e3efaa5255cbd68e5b
Reviewed-on: https://dart-review.googlesource.com/64540
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
diff --git a/pkg/front_end/lib/src/fasta/builder/library_builder.dart b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
index dcd6413..5b43657 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -126,7 +126,7 @@
 
   int finishDeferredLoadTearoffs() => 0;
 
-  int finishNoSuchMethodForwarders() => 0;
+  int finishForwarders() => 0;
 
   int finishNativeMethods() => 0;
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
index e30260e..3ac31ab 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
@@ -432,8 +432,8 @@
     cloned.parent = cls;
 
     KernelLibraryBuilder library = this.library;
-    library.noSuchMethodForwardersOrigins.add(cloned);
-    library.noSuchMethodForwardersOrigins.add(procedure);
+    library.forwardersOrigins.add(cloned);
+    library.forwardersOrigins.add(procedure);
   }
 
   void addNoSuchMethodForwarderGetterForField(Member noSuchMethod,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
index 009fd3a..7821f30 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
@@ -129,11 +129,11 @@
   final List<KernelTypeVariableBuilder> boundlessTypeVariables =
       <KernelTypeVariableBuilder>[];
 
-  // A list of alternating noSuchMethod forwarders and the abstract procedures
-  // they were generated for.  Note that it may not include a forwarder-origin
-  // pair in cases when the former does not need to be updated after the body of
-  // the latter was built.
-  final List<Procedure> noSuchMethodForwardersOrigins = <Procedure>[];
+  // A list of alternating forwarders and the procedures they were generated
+  // for.  Note that it may not include a forwarder-origin pair in cases when
+  // the former does not need to be updated after the body of the latter was
+  // built.
+  final List<Procedure> forwardersOrigins = <Procedure>[];
 
   /// Exports that can't be serialized.
   ///
@@ -1012,12 +1012,12 @@
     return total;
   }
 
-  int finishNoSuchMethodForwarders() {
+  int finishForwarders() {
     int count = 0;
     CloneVisitor cloner = new CloneVisitor();
-    for (int i = 0; i < noSuchMethodForwardersOrigins.length; i += 2) {
-      Procedure forwarder = noSuchMethodForwardersOrigins[i];
-      Procedure origin = noSuchMethodForwardersOrigins[i + 1];
+    for (int i = 0; i < forwardersOrigins.length; i += 2) {
+      Procedure forwarder = forwardersOrigins[i];
+      Procedure origin = forwardersOrigins[i + 1];
 
       int positionalCount = origin.function.positionalParameters.length;
       if (forwarder.function.positionalParameters.length != positionalCount) {
@@ -1057,7 +1057,7 @@
 
       ++count;
     }
-    noSuchMethodForwardersOrigins.clear();
+    forwardersOrigins.clear();
     return count;
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index 892648e..677ff35 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -469,8 +469,9 @@
   /// annotations, and creates forwarding stubs as needed.
   void finalizeCovariance(InterfaceResolver interfaceResolver) {
     interfaceResolver.finalizeCovariance(
-        this, _inferenceInfo.gettersAndMethods);
-    interfaceResolver.finalizeCovariance(this, _inferenceInfo.setters);
+        this, _inferenceInfo.gettersAndMethods, _inferenceInfo.builder.library);
+    interfaceResolver.finalizeCovariance(
+        this, _inferenceInfo.setters, _inferenceInfo.builder.library);
     interfaceResolver.recordInstrumentation(this);
   }
 
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 3304efc..aab29be 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -387,10 +387,10 @@
     int count = 0;
     builders.forEach((Uri uri, LibraryBuilder library) {
       if (library.loader == this) {
-        count += library.finishNoSuchMethodForwarders();
+        count += library.finishForwarders();
       }
     });
-    ticker.logMs("Finished noSuchMethod forwarders for $count procedures");
+    ticker.logMs("Finished forwarders for $count procedures");
   }
 
   void resolveConstructors() {
diff --git a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
index bf2284c..ddcd9cf 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
@@ -43,6 +43,8 @@
 
 import '../builder/builder.dart' show LibraryBuilder;
 
+import '../kernel/kernel_library_builder.dart' show KernelLibraryBuilder;
+
 import '../kernel/kernel_shadow_ast.dart'
     show
         ShadowClass,
@@ -292,8 +294,7 @@
     IncludesTypeParametersCovariantly needsCheckVisitor =
         enclosingClass.typeParameters.isEmpty
             ? null
-            : ShadowClass
-                    .getClassInferenceInfo(enclosingClass)
+            : ShadowClass.getClassInferenceInfo(enclosingClass)
                     .needsCheckVisitor ??=
                 new IncludesTypeParametersCovariantly(
                     enclosingClass.typeParameters);
@@ -774,8 +775,8 @@
     }
     var positionalParameters = method.function.positionalParameters;
     for (int i = 0; i < positionalParameters.length; ++i) {
-      if (VariableDeclarationJudgment
-          .isImplicitlyTyped(positionalParameters[i])) {
+      if (VariableDeclarationJudgment.isImplicitlyTyped(
+          positionalParameters[i])) {
         // Note that if the parameter is not present in the overridden method,
         // getPositionalParameterType treats it as dynamic.  This is consistent
         // with the behavior called for in the informal top level type inference
@@ -917,6 +918,11 @@
         var forwardingNode = new ForwardingNode(
             this, null, class_, name, kind, candidates, start, end);
         getters[getterIndex++] = forwardingNode.finalize();
+        if (library is KernelLibraryBuilder &&
+            forwardingNode.finalize() != forwardingNode.resolve()) {
+          library.forwardersOrigins.add(forwardingNode.finalize());
+          library.forwardersOrigins.add(forwardingNode.resolve());
+        }
         return;
       }
 
@@ -1029,12 +1035,18 @@
     setters.length = setterIndex;
   }
 
-  void finalizeCovariance(Class class_, List<Member> apiMembers) {
+  void finalizeCovariance(
+      Class class_, List<Member> apiMembers, LibraryBuilder library) {
     for (int i = 0; i < apiMembers.length; i++) {
       var member = apiMembers[i];
       Member resolution;
       if (member is ForwardingNode) {
         apiMembers[i] = resolution = member.finalize();
+        if (library is KernelLibraryBuilder &&
+            member.finalize() != member.resolve()) {
+          library.forwardersOrigins.add(member.finalize());
+          library.forwardersOrigins.add(member.resolve());
+        }
       } else {
         resolution = member;
       }
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.strong.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.strong.expect
index 3234a21..36ff607b 100644
--- a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.strong.expect
@@ -30,9 +30,9 @@
   synthetic constructor •() → void
     : super self::B::•()
     ;
-  forwarding-stub method f([generic-covariant-impl core::num x]) → void
+  forwarding-stub method f([generic-covariant-impl core::num x = 10]) → void
     return super.{self::B::f}(x);
-  forwarding-stub method g({generic-covariant-impl core::num x}) → void
+  forwarding-stub method g({generic-covariant-impl core::num x = 20}) → void
     return super.{self::B::g}(x: x);
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.strong.transformed.expect
index 3234a21..36ff607b 100644
--- a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.strong.transformed.expect
@@ -30,9 +30,9 @@
   synthetic constructor •() → void
     : super self::B::•()
     ;
-  forwarding-stub method f([generic-covariant-impl core::num x]) → void
+  forwarding-stub method f([generic-covariant-impl core::num x = 10]) → void
     return super.{self::B::f}(x);
-  forwarding-stub method g({generic-covariant-impl core::num x}) → void
+  forwarding-stub method g({generic-covariant-impl core::num x = 20}) → void
     return super.{self::B::g}(x: x);
 }
 static method main() → dynamic {
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 4c3a11f..b5d4f7b 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -201,7 +201,6 @@
 regress/issue_31299: TypeCheckError
 regress/issue_33452: RuntimeError # Test has an intentional error
 
-runtime_checks/forwarding_stub_with_default_values: RuntimeError # Bug 31027
 runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast: RuntimeError
 runtime_checks_new/mixin_forwarding_stub_field: TypeCheckError
 runtime_checks_new/mixin_forwarding_stub_getter: TypeCheckError