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 ffd407fcd4a2d50ceea67133be87e2a38c3416a5..97a972b6a66d04e073a8e5360b2307f05179318e 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart |
| @@ -308,7 +308,7 @@ class ResolverTask extends CompilerTask { |
| visitor.useElement(tree, element); |
| visitor.setupFunction(tree, element); |
| - if (isConstructor) { |
| + if (isConstructor && !element.isForwardingConstructor) { |
| // 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); |
| @@ -317,6 +317,8 @@ class ResolverTask extends CompilerTask { |
| if (redirection != null) { |
| resolveRedirectingConstructor(resolver, tree, element, redirection); |
| } |
| + } else if (element.isForwardingConstructor) { |
| + // Initializers will be checked on the original constructor. |
| } else if (tree.initializers != null) { |
| error(tree, MessageKind.FUNCTION_WITH_INITIALIZER); |
| } |
| @@ -2565,7 +2567,11 @@ class ResolverVisitor extends MappingVisitor<Element> { |
| compiler.backend.registerThrowNoSuchMethod(mapping); |
| } |
| compiler.withCurrentElement(constructor, () { |
| - FunctionExpression tree = constructor.parseNode(compiler); |
| + FunctionElement target = constructor; |
| + if (constructor.isForwardingConstructor) { |
| + target = constructor.targetConstructor; |
| + } |
| + FunctionExpression tree = target.parseNode(compiler); |
| compiler.resolver.resolveConstructorImplementation(constructor, tree); |
| }); |
| @@ -3269,9 +3275,10 @@ class ClassResolverVisitor extends TypeDefinitionVisitor { |
| assert(mixinApplication.supertype == null); |
| mixinApplication.supertype = supertype; |
| + Node node = mixinApplication.parseNode(compiler); |
| // Named mixin application may have an 'implements' clause. |
| NamedMixinApplication namedMixinApplication = |
| - mixinApplication.parseNode(compiler).asNamedMixinApplication(); |
| + node.asNamedMixinApplication(); |
| Link<DartType> interfaces = (namedMixinApplication != null) |
| ? resolveInterfaces(namedMixinApplication.interfaces, |
| namedMixinApplication.superclass) |
| @@ -3286,6 +3293,32 @@ class ClassResolverVisitor extends TypeDefinitionVisitor { |
| assert(mixinApplication.mixin == null); |
| mixinApplication.mixin = resolveMixinFor(mixinApplication, mixinType); |
| + |
| + // Create forwarding constructors for constructor defined in the superclass |
| + // because they are now hidden by the mixin application. |
| + ClassElement superclass = supertype.element; |
| + superclass.forEachLocalMember((Element member) { |
| + if (!member.isConstructor() || member.isSynthesized) return; |
|
kasperl
2013/04/25 12:13:12
Does this work if the superclass itself is a mixin
karlklose
2013/05/03 09:35:45
I change it to work with these.
|
| + assert(invariant(node, !member.isFactoryConstructor(), |
| + message: 'mixins cannot have factory constructors')); |
| + FunctionElement constructor = member; |
| + SourceString constructorName; |
|
kasperl
2013/04/25 12:13:12
Add a helper for computing the constructor name? .
karlklose
2013/05/03 09:35:45
I created a method to create the forwarding constr
|
| + 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 SynthesizedConstructorElementX.forwarding(constructorName, |
| + constructor, mixinApplication); |
| + mixinApplication.addToScope(forwarder, compiler); |
|
kasperl
2013/04/25 12:13:12
I'd rather have a method for adding a new construc
karlklose
2013/05/03 09:35:45
Done.
|
| + }); |
| mixinApplication.addDefaultConstructorIfNeeded(compiler); |
| calculateAllSupertypes(mixinApplication); |
| } |