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

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: 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 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 2228 matching lines...) Expand 10 before | Expand all | Expand 10 after
2558 resolveSelector(node.send); 2560 resolveSelector(node.send);
2559 resolveArguments(node.send.argumentsNode); 2561 resolveArguments(node.send.argumentsNode);
2560 useElement(node.send, constructor); 2562 useElement(node.send, constructor);
2561 if (Elements.isUnresolved(constructor)) return constructor; 2563 if (Elements.isUnresolved(constructor)) return constructor;
2562 Selector callSelector = mapping.getSelector(node.send); 2564 Selector callSelector = mapping.getSelector(node.send);
2563 if (!callSelector.applies(constructor, compiler)) { 2565 if (!callSelector.applies(constructor, compiler)) {
2564 warnArgumentMismatch(node.send, constructor); 2566 warnArgumentMismatch(node.send, constructor);
2565 compiler.backend.registerThrowNoSuchMethod(mapping); 2567 compiler.backend.registerThrowNoSuchMethod(mapping);
2566 } 2568 }
2567 compiler.withCurrentElement(constructor, () { 2569 compiler.withCurrentElement(constructor, () {
2568 FunctionExpression tree = constructor.parseNode(compiler); 2570 FunctionElement target = constructor;
2571 if (constructor.isForwardingConstructor) {
2572 target = constructor.targetConstructor;
2573 }
2574 FunctionExpression tree = target.parseNode(compiler);
2569 compiler.resolver.resolveConstructorImplementation(constructor, tree); 2575 compiler.resolver.resolveConstructorImplementation(constructor, tree);
2570 }); 2576 });
2571 2577
2572 if (constructor.defaultImplementation != constructor) { 2578 if (constructor.defaultImplementation != constructor) {
2573 // Support for deprecated interface support. 2579 // Support for deprecated interface support.
2574 // TODO(ngeoffray): Remove once we remove such support. 2580 // TODO(ngeoffray): Remove once we remove such support.
2575 world.registerStaticUse(constructor.declaration); 2581 world.registerStaticUse(constructor.declaration);
2576 world.registerInstantiatedClass( 2582 world.registerInstantiatedClass(
2577 constructor.getEnclosingClass().declaration, mapping); 2583 constructor.getEnclosingClass().declaration, mapping);
2578 constructor = constructor.defaultImplementation; 2584 constructor = constructor.defaultImplementation;
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after
3262 mixinApplication.supertypeLoadState = STATE_DONE; 3268 mixinApplication.supertypeLoadState = STATE_DONE;
3263 return mixinApplication.computeType(compiler); 3269 return mixinApplication.computeType(compiler);
3264 } 3270 }
3265 3271
3266 void doApplyMixinTo(MixinApplicationElement mixinApplication, 3272 void doApplyMixinTo(MixinApplicationElement mixinApplication,
3267 DartType supertype, 3273 DartType supertype,
3268 DartType mixinType) { 3274 DartType mixinType) {
3269 assert(mixinApplication.supertype == null); 3275 assert(mixinApplication.supertype == null);
3270 mixinApplication.supertype = supertype; 3276 mixinApplication.supertype = supertype;
3271 3277
3278 Node node = mixinApplication.parseNode(compiler);
3272 // Named mixin application may have an 'implements' clause. 3279 // Named mixin application may have an 'implements' clause.
3273 NamedMixinApplication namedMixinApplication = 3280 NamedMixinApplication namedMixinApplication =
3274 mixinApplication.parseNode(compiler).asNamedMixinApplication(); 3281 node.asNamedMixinApplication();
3275 Link<DartType> interfaces = (namedMixinApplication != null) 3282 Link<DartType> interfaces = (namedMixinApplication != null)
3276 ? resolveInterfaces(namedMixinApplication.interfaces, 3283 ? resolveInterfaces(namedMixinApplication.interfaces,
3277 namedMixinApplication.superclass) 3284 namedMixinApplication.superclass)
3278 : const Link<DartType>(); 3285 : const Link<DartType>();
3279 3286
3280 // The class that is the result of a mixin application implements 3287 // The class that is the result of a mixin application implements
3281 // the interface of the class that was mixed in so always prepend 3288 // the interface of the class that was mixed in so always prepend
3282 // that to the interface list. 3289 // that to the interface list.
3283 interfaces = interfaces.prepend(mixinType); 3290 interfaces = interfaces.prepend(mixinType);
3284 assert(mixinApplication.interfaces == null); 3291 assert(mixinApplication.interfaces == null);
3285 mixinApplication.interfaces = interfaces; 3292 mixinApplication.interfaces = interfaces;
3286 3293
3287 assert(mixinApplication.mixin == null); 3294 assert(mixinApplication.mixin == null);
3288 mixinApplication.mixin = resolveMixinFor(mixinApplication, mixinType); 3295 mixinApplication.mixin = resolveMixinFor(mixinApplication, mixinType);
3296
3297 // Create forwarding constructors for constructor defined in the superclass
3298 // because they are now hidden by the mixin application.
3299 ClassElement superclass = supertype.element;
3300 superclass.forEachLocalMember((Element member) {
3301 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.
3302 assert(invariant(node, !member.isFactoryConstructor(),
3303 message: 'mixins cannot have factory constructors'));
3304 FunctionElement constructor = member;
3305 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
3306 if (constructor.name == superclass.name) {
3307 if (constructor.computeSignature(compiler).parameterCount == 0) {
3308 return;
3309 }
3310 constructorName = mixinApplication.name;
3311 } else {
3312 SourceString selector =
3313 Elements.deconstructConstructorName(constructor.name, superclass);
3314 constructorName =
3315 Elements.constructConstructorName(mixinApplication.name, selector);
3316 }
3317 Element forwarder =
3318 new SynthesizedConstructorElementX.forwarding(constructorName,
3319 constructor, mixinApplication);
3320 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.
3321 });
3289 mixinApplication.addDefaultConstructorIfNeeded(compiler); 3322 mixinApplication.addDefaultConstructorIfNeeded(compiler);
3290 calculateAllSupertypes(mixinApplication); 3323 calculateAllSupertypes(mixinApplication);
3291 } 3324 }
3292 3325
3293 ClassElement resolveMixinFor(MixinApplicationElement mixinApplication, 3326 ClassElement resolveMixinFor(MixinApplicationElement mixinApplication,
3294 DartType mixinType) { 3327 DartType mixinType) {
3295 ClassElement mixin = mixinType.element; 3328 ClassElement mixin = mixinType.element;
3296 mixin.ensureResolved(compiler); 3329 mixin.ensureResolved(compiler);
3297 3330
3298 // Check for cycles in the mixin chain. 3331 // Check for cycles in the mixin chain.
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
3977 return e; 4010 return e;
3978 } 4011 }
3979 4012
3980 /// Assumed to be called by [resolveRedirectingFactory]. 4013 /// Assumed to be called by [resolveRedirectingFactory].
3981 Element visitReturn(Return node) { 4014 Element visitReturn(Return node) {
3982 Node expression = node.expression; 4015 Node expression = node.expression;
3983 return finishConstructorReference(visit(expression), 4016 return finishConstructorReference(visit(expression),
3984 expression, expression); 4017 expression, expression);
3985 } 4018 }
3986 } 4019 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698