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

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: Fix an assert. 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 4b42981b6129ddaf54bc0bac898f69db9987f2aa..156066f97739f72c0694acfe4a2c775636f94275 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);
}
@@ -2575,7 +2577,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);
});
@@ -3279,15 +3285,38 @@ class ClassResolverVisitor extends TypeDefinitionVisitor {
return mixinApplication.computeType(compiler);
}
+ bool isDefaultConstructor(FunctionElement constructor) {
+ return constructor.name == constructor.getEnclosingClass().name &&
+ constructor.computeSignature(compiler).parameterCount == 0;
+ }
+
+ FunctionElement createForwardingConstructor(FunctionElement constructor,
+ ClassElement target) {
+ ClassElement cls = constructor.getEnclosingClass();
+ SourceString constructorName;
+ if (constructor.name == cls.name) {
+ constructorName = target.name;
+ } else {
+ SourceString selector =
+ Elements.deconstructConstructorName(constructor.name, cls);
+ constructorName =
+ Elements.constructConstructorName(target.name, selector);
+ }
+ return new SynthesizedConstructorElementX.forwarding(constructorName,
+ constructor,
+ target);
+ }
+
void doApplyMixinTo(MixinApplicationElement mixinApplication,
DartType supertype,
DartType mixinType) {
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)
@@ -3302,6 +3331,24 @@ 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()) return;
+ if (member.isSynthesized && !member.isForwardingConstructor) return;
+ if (isDefaultConstructor(member)) return;
+ assert(invariant(node, !member.isFactoryConstructor(),
+ message: 'mixins cannot have factory constructors'));
+ // Skip forwarding constructors and use their target.
+ FunctionElement constructor =
+ member.isForwardingConstructor ? member.targetConstructor : member;
+ assert(invariant(node, !constructor.isForwardingConstructor));
+ FunctionElement forwarder =
+ createForwardingConstructor(constructor, mixinApplication);
+ mixinApplication.addConstructor(forwarder);
+ });
mixinApplication.addDefaultConstructorIfNeeded(compiler);
calculateAllSupertypes(mixinApplication);
}

Powered by Google App Engine
This is Rietveld 408576698