| Index: pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
|
| 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 b01bc3c9bbcc1b866272a1ad809df2a3b99f74dc..fb6a5a4ef7f37dcdca362dcacc87031029d4a77b 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
|
| @@ -7,9 +7,14 @@ library fasta.kernel_class_builder;
|
| import 'package:kernel/ast.dart' show
|
| Class,
|
| DartType,
|
| + Expression,
|
| ExpressionStatement,
|
| + Field,
|
| InterfaceType,
|
| + ListLiteral,
|
| Member,
|
| + Name,
|
| + StaticGet,
|
| StringLiteral,
|
| Supertype,
|
| Throw;
|
| @@ -24,6 +29,7 @@ import 'kernel_builder.dart' show
|
| Builder,
|
| ClassBuilder,
|
| ConstructorReferenceBuilder,
|
| + KernelLibraryBuilder,
|
| KernelProcedureBuilder,
|
| KernelTypeBuilder,
|
| LibraryBuilder,
|
| @@ -94,10 +100,13 @@ abstract class KernelClassBuilder
|
| }
|
| }
|
|
|
| - int resolveConstructors(LibraryBuilder library) {
|
| + int resolveConstructors(KernelLibraryBuilder library) {
|
| int count = super.resolveConstructors(library);
|
| if (count != 0) {
|
| - members.forEach((String name, Builder builder) {
|
| + // Copy keys to avoid concurrent modification error.
|
| + List<String> names = members.keys.toList();
|
| + for (String name in names) {
|
| + Builder builder = members[name];
|
| if (builder is KernelProcedureBuilder && builder.isFactory) {
|
| // Compute the immediate redirection target, not the effective.
|
| ConstructorReferenceBuilder redirectionTarget =
|
| @@ -105,6 +114,7 @@ abstract class KernelClassBuilder
|
| if (redirectionTarget != null) {
|
| assert(builder.actualBody == null);
|
| Builder targetBuilder = redirectionTarget.target;
|
| + addRedirectingConstructor(builder, library);
|
| if (targetBuilder is ProcedureBuilder) {
|
| Member target = targetBuilder.target;
|
| builder.body = new RedirectingFactoryBody(target);
|
| @@ -121,8 +131,38 @@ abstract class KernelClassBuilder
|
| }
|
| }
|
| }
|
| - });
|
| + }
|
| }
|
| return count;
|
| }
|
| +
|
| + void addRedirectingConstructor(KernelProcedureBuilder constructor,
|
| + KernelLibraryBuilder library) {
|
| + // Add a new synthetic field to this class for representing factory
|
| + // constructors. This is used to support resolving such constructors in
|
| + // source code.
|
| + //
|
| + // The synthetic field looks like this:
|
| + //
|
| + // final _redirecting# = [c1, ..., cn];
|
| + //
|
| + // Where each c1 ... cn are an instance of [StaticGet] whose target is
|
| + // [constructor.target].
|
| + //
|
| + // TODO(ahe): Generate the correct factory body instead.
|
| + DillMemberBuilder constructorsField =
|
| + members.putIfAbsent("_redirecting#", () {
|
| + ListLiteral literal = new ListLiteral(<Expression>[]);
|
| + Name name = new Name("_redirecting#", library.library);
|
| + Field field = new Field(name, isStatic: true,
|
| + initializer: literal, fileUri: cls.fileUri)
|
| + ..fileOffset = cls.fileOffset;
|
| + cls.addMember(field);
|
| + return new DillMemberBuilder(field, this);
|
| + });
|
| + Field field = constructorsField.target;
|
| + ListLiteral literal = field.initializer;
|
| + literal.expressions.add(
|
| + new StaticGet(constructor.target)..parent = literal);
|
| + }
|
| }
|
|
|