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