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 f7c72a7a8cc0478c7b904a3827769ff2a16f3818..11e317ae551957ea3dfbefe28fa0bc019d65b6f0 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,45 @@ 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)}'.", |
Johnni Winther
2017/08/30 12:18:46
Long line.
ahe
2017/08/30 15:07:22
Done.
|
+ nameToken.charOffset)); |
+ return; |
+ } |
+ DartType targetType = body.returnType; |
+ if (arguments.types.isNotEmpty) { |
+ if (initialTarget.function.typeParameters.length != |
+ arguments.types.length) { |
+ arguments.types.clear(); |
Johnni Winther
2017/08/30 12:18:46
Has the type argument mismatch been reported?
ahe
2017/08/30 15:07:22
No. I've added a TODO for that. I would like this
ahe
2017/08/30 15:13:09
And filed this bug: https://github.com/dart-lang/s
|
+ } 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 || |