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 c8598e882fd953a7eeabfdb198c55aab390ddcd4..1dec5fd7e92cddff2e65c3fd8dedfd2259acb3dc 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| @@ -306,7 +306,7 @@ class ResolverTask extends CompilerTask { |
| visitor.useElement(tree, element); |
| visitor.setupFunction(tree, element); |
| - if (isConstructor) { |
| + if (isConstructor && element is! ForwardingConstructorElement) { |
|
ahe
2013/04/15 13:36:46
Can you call a method instead?
|
| // Even if there is no initializer list we still have to do the |
| // resolution in case there is an implicit super constructor call. |
| InitializerResolver resolver = new InitializerResolver(visitor); |
| @@ -315,6 +315,8 @@ class ResolverTask extends CompilerTask { |
| if (redirection != null) { |
| resolveRedirectingConstructor(resolver, tree, element, redirection); |
| } |
| + } else if (element is ForwardingConstructorElement) { |
|
ahe
2013/04/15 13:36:46
Can you call a method instead?
|
| + // Initializers will be cehcked on the original constructor. |
| } else if (tree.initializers != null) { |
| error(tree, MessageKind.FUNCTION_WITH_INITIALIZER); |
| } |
| @@ -2500,7 +2502,11 @@ class ResolverVisitor extends CommonResolverVisitor<Element> { |
| compiler.backend.registerThrowNoSuchMethod(mapping); |
| } |
| compiler.withCurrentElement(constructor, () { |
| - FunctionExpression tree = constructor.parseNode(compiler); |
| + FunctionElement target = constructor; |
| + if (constructor is ForwardingConstructorElement) { |
|
ahe
2013/04/15 13:36:46
Can you call a method instead.
|
| + target = constructor.superConstructor; |
| + } |
| + FunctionExpression tree = target.parseNode(compiler); |
|
ahe
2013/04/15 13:36:46
What happens if your superclass is itself a mixin
|
| compiler.resolver.resolveConstructorImplementation(constructor, tree); |
| }); |
| @@ -3186,6 +3192,33 @@ class ClassResolverVisitor extends TypeDefinitionVisitor { |
| assert(mixinApplication.mixin == null); |
| mixinApplication.mixin = resolveMixinFor(mixinApplication, mixinType); |
| + |
| + // Create forwarding constructors for constructor defined in the super class |
|
ahe
2013/04/15 13:36:46
superclass is one word.
|
| + // because they are now hidden by the mixin application. |
| + ClassElement superclass = supertype.element; |
| + bool constructorsAdded = false; |
|
ahe
2013/04/15 13:36:46
Where is this used?
|
| + superclass.forEachLocalMember((Element member) { |
| + if (!member.isConstructor() || member.isSynthesized) return; |
| + assert(!member.isFactoryConstructor()); |
|
ahe
2013/04/15 13:36:46
Please use assert(invariant(...))
|
| + FunctionElement constructor = member; |
| + SourceString constructorName; |
| + if (constructor.name == superclass.name) { |
| + if (constructor.computeSignature(compiler).parameterCount == 0) { |
| + return; |
| + } |
| + constructorName = mixinApplication.name; |
| + } else { |
| + SourceString selector = |
| + Elements.deconstructConstructorName(constructor.name, superclass); |
| + constructorName = |
| + Elements.constructConstructorName(mixinApplication.name, selector); |
| + } |
| + Element forwarder = |
| + new ForwardingConstructorElementX(constructorName, constructor, |
| + mixinApplication); |
| + mixinApplication.addToScope(forwarder, compiler); |
| + constructorsAdded = true; |
| + }); |
| mixinApplication.addDefaultConstructorIfNeeded(compiler); |
| calculateAllSupertypes(mixinApplication); |
| } |