Index: pkg/compiler/lib/src/ssa/builder_kernel.dart |
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart |
index 4dabdefd8bebe4ce7f2035f5e583f95dcf80f901..39e65e0fae69399ed4c599905c201986ba65c0c1 100644 |
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart |
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart |
@@ -308,34 +308,35 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder { |
/// Collects field initializers all the way up the inheritance chain. |
void _buildInitializers( |
ir.Constructor constructor, Map<ir.Field, HInstruction> fieldValues) { |
- var foundSuperCall = false; |
+ var foundSuperOrRedirectCall = false; |
for (var initializer in constructor.initializers) { |
- if (initializer is ir.SuperInitializer) { |
- foundSuperCall = true; |
- var superConstructor = initializer.target; |
+ if (initializer is ir.SuperInitializer || |
+ initializer is ir.RedirectingInitializer) { |
+ foundSuperOrRedirectCall = true; |
+ var superOrRedirectConstructor = initializer.target; |
var arguments = _normalizeAndBuildArguments( |
- superConstructor.function, initializer.arguments); |
- _buildInlinedSuperInitializers( |
- superConstructor, arguments, fieldValues); |
+ superOrRedirectConstructor.function, initializer.arguments); |
+ _buildInlinedInitializers( |
+ superOrRedirectConstructor, arguments, fieldValues); |
} else if (initializer is ir.FieldInitializer) { |
initializer.value.accept(this); |
fieldValues[initializer.field] = pop(); |
} |
} |
- // TODO(het): does kernel always set the super initializer at the end? |
- // If there was no super-call initializer, then call the default constructor |
- // in the superclass. |
- if (!foundSuperCall) { |
+ // Kernel always set the super initializer at the end, so if there was no |
+ // super-call initializer, then the default constructor is called in the |
+ // superclass. |
+ if (!foundSuperOrRedirectCall) { |
if (constructor.enclosingClass != astAdapter.objectClass) { |
var superclass = constructor.enclosingClass.superclass; |
var defaultConstructor = superclass.constructors |
- .firstWhere((c) => c.name == '', orElse: () => null); |
+ .firstWhere((c) => c.name.name == '', orElse: () => null); |
if (defaultConstructor == null) { |
compiler.reporter.internalError( |
NO_LOCATION_SPANNABLE, 'Could not find default constructor.'); |
} |
- _buildInlinedSuperInitializers( |
+ _buildInlinedInitializers( |
defaultConstructor, <HInstruction>[], fieldValues); |
} |
} |
@@ -387,7 +388,7 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder { |
/// Inlines the given super [constructor]'s initializers by collecting it's |
/// field values and building its constructor initializers. We visit super |
/// constructors all the way up to the [Object] constructor. |
- void _buildInlinedSuperInitializers(ir.Constructor constructor, |
+ void _buildInlinedInitializers(ir.Constructor constructor, |
List<HInstruction> arguments, Map<ir.Field, HInstruction> fieldValues) { |
// TODO(het): Handle RTI if class needs it |
fieldValues.addAll(_collectFieldValues(constructor.enclosingClass)); |
@@ -1198,7 +1199,8 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder { |
// If runtime type information is needed and the map literal has no type |
// parameters, 'constructor' is a static function that forwards the call to |
// the factory constructor without type parameters. |
- assert(constructor.kind == ir.ProcedureKind.Factory); |
+ assert(constructor.kind == ir.ProcedureKind.Method |
+ || constructor.kind == ir.ProcedureKind.Factory); |
// The instruction type will always be a subtype of the mapLiteralClass, but |
// type inference might discover a more specific type, or find nothing (in |