Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| index ae787bed30938ecd494655ab1a7b62fc540611b1..2da813066a7933582a19dbf39d89f88b043ddf76 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| @@ -2492,10 +2492,6 @@ class ResolverVisitor extends MappingVisitor<Element> { |
| enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); |
| } |
| Element redirectionTarget = resolveRedirectingFactory(node); |
| - var type = mapping.getType(node.expression); |
| - if (type is InterfaceType && !type.isRaw) { |
| - unimplemented(node.expression, 'type arguments on redirecting factory'); |
| - } |
| useElement(node.expression, redirectionTarget); |
| FunctionElement constructor = enclosingElement; |
| if (constructor.modifiers.isConst() && |
| @@ -2503,7 +2499,30 @@ class ResolverVisitor extends MappingVisitor<Element> { |
| error(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); |
| } |
| constructor.defaultImplementation = redirectionTarget; |
| - if (Elements.isUnresolved(redirectionTarget)) return; |
| + if (Elements.isUnresolved(redirectionTarget) || |
| + !redirectionTarget.isConstructor()) { |
| + compiler.backend.registerThrowNoSuchMethod(mapping); |
|
ngeoffray
2013/05/30 08:23:14
Do you really need to make it explicit in both cas
karlklose
2013/05/30 11:44:23
The test is not necessary, I removed it.
|
| + return; |
| + } |
| + |
| + // Compute the signature of the target method taking into account the |
| + // type arguments that are specified in the redirection, and store it on |
| + // the return node. |
| + ClassElement targetClass = redirectionTarget.getEnclosingClass(); |
| + InterfaceType type = mapping.getType(node.expression) |
| + .subst(currentClass.typeVariables, targetClass.typeVariables); |
| + mapping.setType(node, type); |
| + |
| + // Check that the target constructor is type compatible with the |
| + // redirecting constructor. |
| + FunctionType targetType = redirectionTarget.computeType(compiler) |
| + .subst(type.typeArguments, targetClass.typeVariables); |
| + FunctionType constructorType = constructor.computeType(compiler); |
| + if (!compiler.types.isSubtype(targetType, constructorType)) { |
| + compiler.backend.registerThrowNoSuchMethod(mapping); |
|
ngeoffray
2013/05/30 08:23:14
I think you can remove the registering here.
karlklose
2013/05/30 11:44:23
I have added logic to test whether we need this.
|
| + warning(node, MessageKind.INVALID_ARGUMENTS, |
| + {'methodName': redirectionTarget.name}); |
| + } |
| // TODO(ahe): Check that this doesn't lead to a cycle. For now, |
| // just make sure that the redirection target isn't itself a |
| @@ -2513,7 +2532,7 @@ class ResolverVisitor extends MappingVisitor<Element> { |
| FunctionExpression function = targetImplementation.parseNode(compiler); |
| if (function.body != null && function.body.asReturn() != null |
| && function.body.asReturn().isRedirectingFactoryBody) { |
| - unimplemented(node.expression, 'redirecing to redirecting factory'); |
| + unimplemented(node.expression, 'redirecting to redirecting factory'); |
| } |
| } |
| world.registerStaticUse(redirectionTarget); |