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

Unified Diff: sdk/lib/_internal/compiler/implementation/resolution/members.dart

Issue 14168003: Implement implicit constructors in mixin applications. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. 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/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);
}

Powered by Google App Engine
This is Rietveld 408576698