| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |