Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/elements/modelx.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart |
| index 915a55d075d024ec9a6bfc4e24cf5461bc5d89bf..560e78c81a996c4dfeaacc0e5b605f6e82acea70 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart |
| @@ -1288,6 +1288,44 @@ class SynthesizedConstructorElementX extends FunctionElementX { |
| Token position() => enclosingElement.position(); |
| } |
| +/** |
| + * A synthetic constructor that directly forwards to a constructor in the super |
| + * class of a mixin application. |
| + * |
| + * In a mixin application `Base with M`, any constructor defined in `Base` is |
| + * available as if they were a constructor defined in the mixin application with |
| + * the same formal parameters that calls the constructor in the super class via |
| + * a `super` initializer (see Ch. 9.1 in the language specification). |
| + */ |
| +class ForwardingConstructorElementX extends FunctionElementX |
| + implements ForwardingConstructorElement { |
| + final FunctionElement superConstructor; |
| + |
| + ForwardingConstructorElementX(SourceString name, |
| + FunctionElement superConstructor, |
| + Element enclosing) |
| + : super(name, superConstructor.kind, superConstructor.modifiers, enclosing), |
| + this.superConstructor = superConstructor; |
| + |
| + parseNode(compiler) { throw 'parseNode in synthetic constructor forward.'; } |
|
ahe
2013/04/15 13:36:46
compiler.internalErrorOnElement
karlklose
2013/04/25 11:25:53
Removed.
|
| + |
| + get declaration => this; |
| + |
| + get implementation => this; |
| + |
| + get defaultImplementation => this; |
| + |
| + FunctionSignature computeSignature(compiler) { |
| + return superConstructor.computeSignature(compiler); |
| + } |
| + |
| + Token position() => superConstructor.position(); |
|
ahe
2013/04/15 13:36:46
I'm not sure this is a good position. Wouldn't th
karlklose
2013/04/25 11:25:53
Removed.
|
| + |
| + get redirectionTarget => superConstructor.redirectionTarget; |
| + |
| + bool get isSynthesized => true; |
| +} |
| + |
| class VoidElementX extends ElementX { |
| VoidElementX(Element enclosing) |
| : super(const SourceString('void'), ElementKind.VOID, enclosing); |
| @@ -1837,7 +1875,8 @@ class MixinApplicationElementX extends BaseClassElementX |
| final Node node; |
| final Modifiers modifiers; |
| - FunctionElement constructor; |
| + Link<FunctionElement> constructors = new Link<FunctionElement>(); |
| + |
| ClassElement mixin; |
| // TODO(kasperl): The analyzer complains when I don't have these two |
| @@ -1850,15 +1889,19 @@ class MixinApplicationElementX extends BaseClassElementX |
| : super(name, enclosing, id, STATE_NOT_STARTED); |
| bool get isMixinApplication => true; |
| - bool get hasConstructor => constructor != null; |
| - bool get hasLocalScopeMembers => false; |
| + bool get hasConstructor => !constructors.isEmpty; |
| + bool get hasLocalScopeMembers => constructors.isEmpty; |
| Token position() => node.getBeginToken(); |
| Node parseNode(DiagnosticListener listener) => node; |
| Element localLookup(SourceString name) { |
| - if (this.name == name) return constructor; |
| + for (Link<Element> link = constructors; |
| + !link.isEmpty; |
| + link = link.tail) { |
| + if (link.head.name == name) return link.head; |
| + } |
| if (mixin == null) return null; |
| Element mixedInElement = mixin.localLookup(name); |
| if (mixedInElement == null) return null; |
| @@ -1876,12 +1919,16 @@ class MixinApplicationElementX extends BaseClassElementX |
| } |
| void addToScope(Element element, DiagnosticListener listener) { |
| - throw new UnsupportedError("cannot add to scope of $this"); |
| + if (!element.isConstructor()) { |
| + listener.cancel('can only add constructors to mixin application scope,' |
|
ahe
2013/04/15 13:36:46
Please emit a proper error instead of calling canc
karlklose
2013/04/25 11:25:53
Done.
|
| + ' but got $element', element: this); |
| + } |
| + constructors = constructors.prepend(element); |
| } |
| void setDefaultConstructor(FunctionElement constructor, Compiler compiler) { |
| assert(!hasConstructor); |
| - this.constructor = constructor; |
| + addToScope(constructor, compiler); |
| } |
| Link<DartType> computeTypeParameters(Compiler compiler) { |