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

Side by Side 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, 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of resolution; 5 part of resolution;
6 6
7 abstract class TreeElements { 7 abstract class TreeElements {
8 Element get currentElement; 8 Element get currentElement;
9 Set<Node> get superUses; 9 Set<Node> get superUses;
10 10
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 if (isConstructor) { 301 if (isConstructor) {
302 if (tree.returnType != null) { 302 if (tree.returnType != null) {
303 error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE); 303 error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE);
304 } 304 }
305 resolveConstructorImplementation(element, tree); 305 resolveConstructorImplementation(element, tree);
306 } 306 }
307 ResolverVisitor visitor = visitorFor(element); 307 ResolverVisitor visitor = visitorFor(element);
308 visitor.useElement(tree, element); 308 visitor.useElement(tree, element);
309 visitor.setupFunction(tree, element); 309 visitor.setupFunction(tree, element);
310 310
311 if (isConstructor) { 311 if (isConstructor && !element.isForwardingConstructor) {
312 // Even if there is no initializer list we still have to do the 312 // Even if there is no initializer list we still have to do the
313 // resolution in case there is an implicit super constructor call. 313 // resolution in case there is an implicit super constructor call.
314 InitializerResolver resolver = new InitializerResolver(visitor); 314 InitializerResolver resolver = new InitializerResolver(visitor);
315 FunctionElement redirection = 315 FunctionElement redirection =
316 resolver.resolveInitializers(element, tree); 316 resolver.resolveInitializers(element, tree);
317 if (redirection != null) { 317 if (redirection != null) {
318 resolveRedirectingConstructor(resolver, tree, element, redirection); 318 resolveRedirectingConstructor(resolver, tree, element, redirection);
319 } 319 }
320 } else if (element.isForwardingConstructor) {
321 // Initializers will be checked on the original constructor.
320 } else if (tree.initializers != null) { 322 } else if (tree.initializers != null) {
321 error(tree, MessageKind.FUNCTION_WITH_INITIALIZER); 323 error(tree, MessageKind.FUNCTION_WITH_INITIALIZER);
322 } 324 }
323 visitBody(visitor, tree.body); 325 visitBody(visitor, tree.body);
324 326
325 // Get the resolution tree and check that the resolved 327 // Get the resolution tree and check that the resolved
326 // function doesn't use 'super' if it is mixed into another 328 // function doesn't use 'super' if it is mixed into another
327 // class. This is the part of the 'super' mixin check that 329 // class. This is the part of the 'super' mixin check that
328 // happens when a function is resolved after the mixin 330 // happens when a function is resolved after the mixin
329 // application has been performed. 331 // application has been performed.
(...skipping 2238 matching lines...) Expand 10 before | Expand all | Expand 10 after
2568 resolveSelector(node.send, constructor); 2570 resolveSelector(node.send, constructor);
2569 resolveArguments(node.send.argumentsNode); 2571 resolveArguments(node.send.argumentsNode);
2570 useElement(node.send, constructor); 2572 useElement(node.send, constructor);
2571 if (Elements.isUnresolved(constructor)) return constructor; 2573 if (Elements.isUnresolved(constructor)) return constructor;
2572 Selector callSelector = mapping.getSelector(node.send); 2574 Selector callSelector = mapping.getSelector(node.send);
2573 if (!callSelector.applies(constructor, compiler)) { 2575 if (!callSelector.applies(constructor, compiler)) {
2574 warnArgumentMismatch(node.send, constructor); 2576 warnArgumentMismatch(node.send, constructor);
2575 compiler.backend.registerThrowNoSuchMethod(mapping); 2577 compiler.backend.registerThrowNoSuchMethod(mapping);
2576 } 2578 }
2577 compiler.withCurrentElement(constructor, () { 2579 compiler.withCurrentElement(constructor, () {
2578 FunctionExpression tree = constructor.parseNode(compiler); 2580 FunctionElement target = constructor;
2581 if (constructor.isForwardingConstructor) {
2582 target = constructor.targetConstructor;
2583 }
2584 FunctionExpression tree = target.parseNode(compiler);
2579 compiler.resolver.resolveConstructorImplementation(constructor, tree); 2585 compiler.resolver.resolveConstructorImplementation(constructor, tree);
2580 }); 2586 });
2581 2587
2582 if (constructor.defaultImplementation != constructor) { 2588 if (constructor.defaultImplementation != constructor) {
2583 // Support for deprecated interface support. 2589 // Support for deprecated interface support.
2584 // TODO(ngeoffray): Remove once we remove such support. 2590 // TODO(ngeoffray): Remove once we remove such support.
2585 world.registerStaticUse(constructor.declaration); 2591 world.registerStaticUse(constructor.declaration);
2586 world.registerInstantiatedClass( 2592 world.registerInstantiatedClass(
2587 constructor.getEnclosingClass().declaration, mapping); 2593 constructor.getEnclosingClass().declaration, mapping);
2588 constructor = constructor.defaultImplementation; 2594 constructor = constructor.defaultImplementation;
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after
3272 element.getCompilationUnit(), 3278 element.getCompilationUnit(),
3273 compiler.getNextFreeClassId(), 3279 compiler.getNextFreeClassId(),
3274 element.parseNode(compiler), 3280 element.parseNode(compiler),
3275 Modifiers.EMPTY); // TODO(kasperl): Should this be abstract? 3281 Modifiers.EMPTY); // TODO(kasperl): Should this be abstract?
3276 doApplyMixinTo(mixinApplication, supertype, mixinType); 3282 doApplyMixinTo(mixinApplication, supertype, mixinType);
3277 mixinApplication.resolutionState = STATE_DONE; 3283 mixinApplication.resolutionState = STATE_DONE;
3278 mixinApplication.supertypeLoadState = STATE_DONE; 3284 mixinApplication.supertypeLoadState = STATE_DONE;
3279 return mixinApplication.computeType(compiler); 3285 return mixinApplication.computeType(compiler);
3280 } 3286 }
3281 3287
3288 bool isDefaultConstructor(FunctionElement constructor) {
3289 return constructor.name == constructor.getEnclosingClass().name &&
3290 constructor.computeSignature(compiler).parameterCount == 0;
3291 }
3292
3293 FunctionElement createForwardingConstructor(FunctionElement constructor,
3294 ClassElement target) {
3295 ClassElement cls = constructor.getEnclosingClass();
3296 SourceString constructorName;
3297 if (constructor.name == cls.name) {
3298 constructorName = target.name;
3299 } else {
3300 SourceString selector =
3301 Elements.deconstructConstructorName(constructor.name, cls);
3302 constructorName =
3303 Elements.constructConstructorName(target.name, selector);
3304 }
3305 return new SynthesizedConstructorElementX.forwarding(constructorName,
3306 constructor,
3307 target);
3308 }
3309
3282 void doApplyMixinTo(MixinApplicationElement mixinApplication, 3310 void doApplyMixinTo(MixinApplicationElement mixinApplication,
3283 DartType supertype, 3311 DartType supertype,
3284 DartType mixinType) { 3312 DartType mixinType) {
3285 assert(mixinApplication.supertype == null); 3313 assert(mixinApplication.supertype == null);
3286 mixinApplication.supertype = supertype; 3314 mixinApplication.supertype = supertype;
3287 3315
3316 Node node = mixinApplication.parseNode(compiler);
3288 // Named mixin application may have an 'implements' clause. 3317 // Named mixin application may have an 'implements' clause.
3289 NamedMixinApplication namedMixinApplication = 3318 NamedMixinApplication namedMixinApplication =
3290 mixinApplication.parseNode(compiler).asNamedMixinApplication(); 3319 node.asNamedMixinApplication();
3291 Link<DartType> interfaces = (namedMixinApplication != null) 3320 Link<DartType> interfaces = (namedMixinApplication != null)
3292 ? resolveInterfaces(namedMixinApplication.interfaces, 3321 ? resolveInterfaces(namedMixinApplication.interfaces,
3293 namedMixinApplication.superclass) 3322 namedMixinApplication.superclass)
3294 : const Link<DartType>(); 3323 : const Link<DartType>();
3295 3324
3296 // The class that is the result of a mixin application implements 3325 // The class that is the result of a mixin application implements
3297 // the interface of the class that was mixed in so always prepend 3326 // the interface of the class that was mixed in so always prepend
3298 // that to the interface list. 3327 // that to the interface list.
3299 interfaces = interfaces.prepend(mixinType); 3328 interfaces = interfaces.prepend(mixinType);
3300 assert(mixinApplication.interfaces == null); 3329 assert(mixinApplication.interfaces == null);
3301 mixinApplication.interfaces = interfaces; 3330 mixinApplication.interfaces = interfaces;
3302 3331
3303 assert(mixinApplication.mixin == null); 3332 assert(mixinApplication.mixin == null);
3304 mixinApplication.mixin = resolveMixinFor(mixinApplication, mixinType); 3333 mixinApplication.mixin = resolveMixinFor(mixinApplication, mixinType);
3334
3335 // Create forwarding constructors for constructor defined in the superclass
3336 // because they are now hidden by the mixin application.
3337 ClassElement superclass = supertype.element;
3338 superclass.forEachLocalMember((Element member) {
3339 if (!member.isConstructor()) return;
3340 if (member.isSynthesized && !member.isForwardingConstructor) return;
3341 if (isDefaultConstructor(member)) return;
3342 assert(invariant(node, !member.isFactoryConstructor(),
3343 message: 'mixins cannot have factory constructors'));
3344 // Skip forwarding constructors and use their target.
3345 FunctionElement constructor =
3346 member.isForwardingConstructor ? member.targetConstructor : member;
3347 assert(invariant(node, !constructor.isForwardingConstructor));
3348 FunctionElement forwarder =
3349 createForwardingConstructor(constructor, mixinApplication);
3350 mixinApplication.addConstructor(forwarder);
3351 });
3305 mixinApplication.addDefaultConstructorIfNeeded(compiler); 3352 mixinApplication.addDefaultConstructorIfNeeded(compiler);
3306 calculateAllSupertypes(mixinApplication); 3353 calculateAllSupertypes(mixinApplication);
3307 } 3354 }
3308 3355
3309 ClassElement resolveMixinFor(MixinApplicationElement mixinApplication, 3356 ClassElement resolveMixinFor(MixinApplicationElement mixinApplication,
3310 DartType mixinType) { 3357 DartType mixinType) {
3311 ClassElement mixin = mixinType.element; 3358 ClassElement mixin = mixinType.element;
3312 mixin.ensureResolved(compiler); 3359 mixin.ensureResolved(compiler);
3313 3360
3314 // Check for cycles in the mixin chain. 3361 // Check for cycles in the mixin chain.
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after
4001 return e; 4048 return e;
4002 } 4049 }
4003 4050
4004 /// Assumed to be called by [resolveRedirectingFactory]. 4051 /// Assumed to be called by [resolveRedirectingFactory].
4005 Element visitReturn(Return node) { 4052 Element visitReturn(Return node) {
4006 Node expression = node.expression; 4053 Node expression = node.expression;
4007 return finishConstructorReference(visit(expression), 4054 return finishConstructorReference(visit(expression),
4008 expression, expression); 4055 expression, expression);
4009 } 4056 }
4010 } 4057 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698