Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Unified Diff: sdk/lib/_internal/compiler/implementation/elements/modelx.dart

Issue 14168003: Implement implicit constructors in mixin applications. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Remove debug code and rebase Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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) {

Powered by Google App Engine
This is Rietveld 408576698