[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.