Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Unified Diff: pkg/compiler/lib/src/kernel/element_map_impl.dart

Issue 2884273002: Support mixins when loading from .dill (Closed)
Patch Set: Updated cf. comments Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/kernel/element_map.dart ('k') | pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/kernel/element_map_impl.dart
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 7d7d048ba0bba10b2a85558c1bf3b6cea018c619..6348d9aea9e5538545e99229e0a3cf6c32b0e1fe 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -5,6 +5,8 @@
library dart2js.kernel.element_map;
import 'package:kernel/ast.dart' as ir;
+import 'package:kernel/clone.dart';
+import 'package:kernel/type_algebra.dart';
import '../common.dart';
import '../common/names.dart' show Identifiers;
@@ -619,7 +621,27 @@ class KernelToElementMapImpl extends KernelToElementMapMixin {
}
@override
- FunctionEntity getConstructor(ir.Member node) => _getConstructor(node);
+ ConstructorEntity getConstructor(ir.Member node) => _getConstructor(node);
+
+ @override
+ ConstructorEntity getSuperConstructor(
+ ir.Constructor sourceNode, ir.Member targetNode) {
+ KConstructor source = getConstructor(sourceNode);
+ KClass sourceClass = source.enclosingClass;
+ KConstructor target = getConstructor(targetNode);
+ KClass targetClass = target.enclosingClass;
+ KClass superClass = _getSuperType(sourceClass)?.element;
+ if (superClass == targetClass) {
+ return target;
+ }
+ _KClassEnv env = _classEnvs[superClass.classIndex];
+ ir.Member member = env.lookupConstructor(target.name);
+ if (member != null) {
+ return getConstructor(member);
+ }
+ throw new SpannableAssertionFailure(
+ source, "Super constructor for $source not found.");
+ }
ConstantConstructor _getConstructorConstant(KConstructor constructor) {
_ConstructorData data = _memberList[constructor.memberIndex];
@@ -786,7 +808,54 @@ class _KClassEnv {
_KClassEnv(this.cls)
// TODO(johnniwinther): Change this to use a property on [cls] when such
// is added to kernel.
- : isUnnamedMixinApplication = cls.name.contains('+');
+ : isUnnamedMixinApplication =
+ cls.name.contains('+') || cls.name.contains('&');
+
+ /// Copied from 'package:kernel/transformations/mixin_full_resolution.dart'.
+ ir.Constructor _buildForwardingConstructor(
+ CloneVisitor cloner, ir.Constructor superclassConstructor) {
+ var superFunction = superclassConstructor.function;
+
+ // We keep types and default values for the parameters but always mark the
+ // parameters as final (since we just forward them to the super
+ // constructor).
+ ir.VariableDeclaration cloneVariable(ir.VariableDeclaration variable) {
+ ir.VariableDeclaration clone = cloner.clone(variable);
+ clone.isFinal = true;
+ return clone;
+ }
+
+ // Build a [FunctionNode] which has the same parameters as the one in the
+ // superclass constructor.
+ var positionalParameters =
+ superFunction.positionalParameters.map(cloneVariable).toList();
+ var namedParameters =
+ superFunction.namedParameters.map(cloneVariable).toList();
+ var function = new ir.FunctionNode(new ir.EmptyStatement(),
+ positionalParameters: positionalParameters,
+ namedParameters: namedParameters,
+ requiredParameterCount: superFunction.requiredParameterCount,
+ returnType: const ir.VoidType());
+
+ // Build a [SuperInitializer] which takes all positional/named parameters
+ // and forward them to the super class constructor.
+ var positionalArguments = <ir.Expression>[];
+ for (var variable in positionalParameters) {
+ positionalArguments.add(new ir.VariableGet(variable));
+ }
+ var namedArguments = <ir.NamedExpression>[];
+ for (var variable in namedParameters) {
+ namedArguments.add(
+ new ir.NamedExpression(variable.name, new ir.VariableGet(variable)));
+ }
+ var superInitializer = new ir.SuperInitializer(superclassConstructor,
+ new ir.Arguments(positionalArguments, named: namedArguments));
+
+ // Assemble the constructor.
+ return new ir.Constructor(function,
+ name: superclassConstructor.name,
+ initializers: <ir.Initializer>[superInitializer]);
+ }
void _ensureMaps() {
if (_memberMap == null) {
@@ -826,6 +895,25 @@ class _KClassEnv {
addMembers(cls.mixedInClass, includeStatic: false);
}
addMembers(cls, includeStatic: true);
+
+ if (isUnnamedMixinApplication && _constructorMap.isEmpty) {
+ // Unnamed mixin applications have no constructors when read from .dill.
+ // For each generative constructor in the superclass we make a
+ // corresponding forwarding constructor in the subclass.
+ //
+ // This code is copied from
+ // 'package:kernel/transformations/mixin_full_resolution.dart'
+ var superclassSubstitution = getSubstitutionMap(cls.supertype);
+ var superclassCloner =
+ new CloneVisitor(typeSubstitution: superclassSubstitution);
+ for (var superclassConstructor in cls.superclass.constructors) {
+ var forwardingConstructor = _buildForwardingConstructor(
+ superclassCloner, superclassConstructor);
+ cls.addMember(forwardingConstructor);
+ _constructorMap[forwardingConstructor.name.name] =
+ forwardingConstructor;
+ }
+ }
}
}
« no previous file with comments | « pkg/compiler/lib/src/kernel/element_map.dart ('k') | pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698