| Index: pkg/front_end/lib/src/fasta/kernel/body_builder.dart
|
| diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
|
| index e6df46ae9530b10176aa55a139fa98ed7e5ab0b5..4c120d0fe5b60c9a6c8e6c196b3d584deabac4e3 100644
|
| --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
|
| +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
|
| @@ -15,6 +15,8 @@ import 'package:kernel/core_types.dart' show CoreTypes;
|
|
|
| import 'package:kernel/transformations/flags.dart' show TransformerFlag;
|
|
|
| +import 'package:kernel/type_algebra.dart' show Substitution;
|
| +
|
| import '../fasta_codes.dart' as fasta;
|
|
|
| import '../fasta_codes.dart' show LocatedMessage, Message;
|
| @@ -64,11 +66,7 @@ import '../type_inference/type_promotion.dart' show TypePromoter;
|
|
|
| import 'frontend_accessors.dart' show buildIsNull, makeBinary;
|
|
|
| -import 'redirecting_factory_body.dart'
|
| - show
|
| - RedirectingFactoryBody,
|
| - getRedirectingFactoryBody,
|
| - getRedirectionTarget;
|
| +import 'redirecting_factory_body.dart' show RedirectingFactoryBody;
|
|
|
| import 'utils.dart' show offsetForToken;
|
|
|
| @@ -2327,21 +2325,48 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
| }
|
| } else if (b.isFactory) {
|
| initialTarget = b.target;
|
| - target = getRedirectionTarget(initialTarget);
|
| - if (target == null) {
|
| - push(deprecated_buildCompileTimeError(
|
| - "Cyclic definition of factory '${name}'.",
|
| - nameToken.charOffset));
|
| - return;
|
| - }
|
| - RedirectingFactoryBody body = getRedirectingFactoryBody(target);
|
| + RedirectingFactoryBody body =
|
| + RedirectingFactoryBody.getRedirectingFactoryBody(initialTarget);
|
| if (body != null) {
|
| - // If the redirection target is itself a redirecting factory, it
|
| - // means that it is unresolved. So we set target to null so we
|
| - // can generate a no-such-method error below.
|
| - assert(body.isUnresolved);
|
| - target = null;
|
| - errorName = body.unresolvedName;
|
| + target = body.target;
|
| + if (target == null) {
|
| + push(deprecated_buildCompileTimeError(
|
| + "Cyclic definition of factory"
|
| + " '${debugName(type.name, name)}'.",
|
| + nameToken.charOffset));
|
| + return;
|
| + }
|
| + DartType targetType = body.returnType;
|
| + if (arguments.types.isNotEmpty) {
|
| + if (initialTarget.function.typeParameters.length !=
|
| + arguments.types.length) {
|
| + // TODO(ahe): Report a problem here, try to unify with
|
| + // [buildStaticInvocation].
|
| + arguments.types.clear();
|
| + } else {
|
| + Substitution substitution = Substitution.fromPairs(
|
| + initialTarget.function.typeParameters, arguments.types);
|
| + targetType = substitution.substituteType(targetType);
|
| + if (targetType is InterfaceType) {
|
| + arguments = new KernelArguments(arguments.positional,
|
| + types: targetType.typeArguments, named: arguments.named)
|
| + ..fileOffset = arguments.fileOffset;
|
| + } else {
|
| + arguments.types.clear();
|
| + }
|
| + }
|
| + }
|
| + body = RedirectingFactoryBody.getRedirectingFactoryBody(target);
|
| + if (body != null) {
|
| + // If the redirection target is itself a redirecting factory, it
|
| + // means that it is unresolved. So we set target to null so we
|
| + // can generate a no-such-method error below.
|
| + assert(body.isUnresolved);
|
| + target = null;
|
| + errorName = body.unresolvedName;
|
| + }
|
| + } else {
|
| + target = initialTarget;
|
| }
|
| }
|
| if (target is Constructor ||
|
|
|