[ddc] Add getter to accompany setter from mixin

When a mixin introduces a forwarding stub setter in the class
hierarchy there also needs to be the accompanying getter in the same
class if a getter is present further up the class hierarchy. This
is because the setter is represented as a property with only a setter
and the lack of a getter will not cause a lookup further up the
prototype chain.

Fixes: https://github.com/dart-lang/sdk/issues/46867
Change-Id: I8e41eb9d2569f0819200a82367ab7c723a1011cd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/209854
Commit-Queue: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Mark Zhou <markzipan@google.com>
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 57a1c38a..4f3d3c5 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -1127,13 +1127,29 @@
       var mixinName =
           getLocalClassName(superclass) + '_' + getLocalClassName(mixinClass);
       var mixinId = _emitTemporaryId(mixinName + '\$');
-      // Collect all forwarding stubs from anonymous mixins classes. These will
-      // contain covariant parameter checks that need to be applied.
-      var forwardingMethodStubs = [
+      // Collect all forwarding stub setters from anonymous mixins classes.
+      // These will contain covariant parameter checks that need to be applied.
+      var savedClassProperties = _classProperties;
+      _classProperties =
+          ClassPropertyModel.build(_types, _extensionTypes, _virtualFields, m);
+
+      var forwardingSetters = {
         for (var procedure in m.procedures)
           if (procedure.isForwardingStub && !procedure.isAbstract)
-            _emitMethodDeclaration(procedure)
-      ];
+            procedure.name.text: procedure
+      };
+
+      var forwardingMethodStubs = <js_ast.Method>[];
+      for (var s in forwardingSetters.values) {
+        forwardingMethodStubs.add(_emitMethodDeclaration(s));
+        // If there are getters matching the setters somewhere above in the
+        // class hierarchy we must also generate a forwarding getter due to the
+        // representation used in the compiled JavaScript.
+        var getterWrapper = _emitSuperAccessorWrapper(s, {}, forwardingSetters);
+        if (getterWrapper != null) forwardingMethodStubs.add(getterWrapper);
+      }
+
+      _classProperties = savedClassProperties;
 
       // Bind the mixin class to a name to workaround a V8 bug with es6 classes
       // and anonymous function names.