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 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 assert(invariant(element, element.isDeclaration)); | 332 assert(invariant(element, element.isDeclaration)); |
333 return compiler.withCurrentElement(element, () { | 333 return compiler.withCurrentElement(element, () { |
334 bool isConstructor = | 334 bool isConstructor = |
335 identical(element.kind, ElementKind.GENERATIVE_CONSTRUCTOR); | 335 identical(element.kind, ElementKind.GENERATIVE_CONSTRUCTOR); |
336 TreeElements elements = | 336 TreeElements elements = |
337 compiler.enqueuer.resolution.getCachedElements(element); | 337 compiler.enqueuer.resolution.getCachedElements(element); |
338 if (elements != null) { | 338 if (elements != null) { |
339 assert(isConstructor); | 339 assert(isConstructor); |
340 return elements; | 340 return elements; |
341 } | 341 } |
| 342 if (element.isSynthesized) { |
| 343 Element target = element.targetConstructor; |
| 344 if (!target.isErroneous()) { |
| 345 compiler.enqueuer.resolution.registerStaticUse( |
| 346 element.targetConstructor); |
| 347 } |
| 348 return new TreeElementMapping(element); |
| 349 } |
342 if (element.isPatched) { | 350 if (element.isPatched) { |
343 checkMatchingPatchSignatures(element, element.patch); | 351 checkMatchingPatchSignatures(element, element.patch); |
344 element = element.patch; | 352 element = element.patch; |
345 } | 353 } |
346 return compiler.withCurrentElement(element, () { | 354 return compiler.withCurrentElement(element, () { |
347 FunctionExpression tree = element.parseNode(compiler); | 355 FunctionExpression tree = element.parseNode(compiler); |
348 if (tree.modifiers.isExternal()) { | 356 if (tree.modifiers.isExternal()) { |
349 error(tree, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION); | 357 error(tree, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION); |
350 return; | 358 return; |
351 } | 359 } |
(...skipping 2177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2529 if (!targetSignature.isCompatibleWith(constructorSignature)) { | 2537 if (!targetSignature.isCompatibleWith(constructorSignature)) { |
2530 compiler.backend.registerThrowNoSuchMethod(mapping); | 2538 compiler.backend.registerThrowNoSuchMethod(mapping); |
2531 } | 2539 } |
2532 | 2540 |
2533 // TODO(ahe): Check that this doesn't lead to a cycle. For now, | 2541 // TODO(ahe): Check that this doesn't lead to a cycle. For now, |
2534 // just make sure that the redirection target isn't itself a | 2542 // just make sure that the redirection target isn't itself a |
2535 // redirecting factory. | 2543 // redirecting factory. |
2536 { // This entire block is temporary code per the above TODO. | 2544 { // This entire block is temporary code per the above TODO. |
2537 FunctionElement targetImplementation = redirectionTarget.implementation; | 2545 FunctionElement targetImplementation = redirectionTarget.implementation; |
2538 FunctionExpression function = targetImplementation.parseNode(compiler); | 2546 FunctionExpression function = targetImplementation.parseNode(compiler); |
2539 if (function.body != null && function.body.asReturn() != null | 2547 if (function != null |
| 2548 && function.body != null |
| 2549 && function.body.asReturn() != null |
2540 && function.body.asReturn().isRedirectingFactoryBody) { | 2550 && function.body.asReturn().isRedirectingFactoryBody) { |
2541 unimplemented(node.expression, 'redirecting to redirecting factory'); | 2551 unimplemented(node.expression, 'redirecting to redirecting factory'); |
2542 } | 2552 } |
2543 } | 2553 } |
2544 world.registerStaticUse(redirectionTarget); | 2554 world.registerStaticUse(redirectionTarget); |
2545 world.registerInstantiatedClass( | 2555 world.registerInstantiatedClass( |
2546 redirectionTarget.enclosingElement.declaration, mapping); | 2556 redirectionTarget.enclosingElement.declaration, mapping); |
2547 if (isSymbolConstructor) { | 2557 if (isSymbolConstructor) { |
2548 // Make sure that collection_dev.Symbol.validated is registered. | 2558 // Make sure that collection_dev.Symbol.validated is registered. |
2549 assert(invariant(node, compiler.symbolValidatedConstructor != null)); | 2559 assert(invariant(node, compiler.symbolValidatedConstructor != null)); |
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3266 superElement.ensureResolved(compiler); | 3276 superElement.ensureResolved(compiler); |
3267 } | 3277 } |
3268 element.supertype = superElement.computeType(compiler); | 3278 element.supertype = superElement.computeType(compiler); |
3269 } | 3279 } |
3270 } | 3280 } |
3271 | 3281 |
3272 assert(element.interfaces == null); | 3282 assert(element.interfaces == null); |
3273 element.interfaces = resolveInterfaces(node.interfaces, node.superclass); | 3283 element.interfaces = resolveInterfaces(node.interfaces, node.superclass); |
3274 calculateAllSupertypes(element); | 3284 calculateAllSupertypes(element); |
3275 | 3285 |
3276 element.addDefaultConstructorIfNeeded(compiler); | 3286 if (!element.hasConstructor) { |
| 3287 Element superMember = |
| 3288 element.superclass.localLookup(const SourceString('')); |
| 3289 if (superMember == null || !superMember.isGenerativeConstructor()) { |
| 3290 MessageKind kind = MessageKind.CANNOT_FIND_CONSTRUCTOR; |
| 3291 Map arguments = {'constructorName': const SourceString('')}; |
| 3292 compiler.reportErrorCode(node, kind, arguments); |
| 3293 superMember = new ErroneousElementX( |
| 3294 kind, arguments, const SourceString(''), element); |
| 3295 compiler.backend.registerThrowNoSuchMethod(mapping); |
| 3296 } |
| 3297 FunctionElement constructor = |
| 3298 new SynthesizedConstructorElementX.forDefault(superMember, element); |
| 3299 element.setDefaultConstructor(constructor, compiler); |
| 3300 } |
3277 return element.computeType(compiler); | 3301 return element.computeType(compiler); |
3278 } | 3302 } |
3279 | 3303 |
3280 DartType visitNamedMixinApplication(NamedMixinApplication node) { | 3304 DartType visitNamedMixinApplication(NamedMixinApplication node) { |
3281 compiler.ensure(element != null); | 3305 compiler.ensure(element != null); |
3282 compiler.ensure(element.resolutionState == STATE_STARTED); | 3306 compiler.ensure(element.resolutionState == STATE_STARTED); |
3283 | 3307 |
3284 InterfaceType type = element.computeType(compiler); | 3308 InterfaceType type = element.computeType(compiler); |
3285 scope = new TypeDeclarationScope(scope, element); | 3309 scope = new TypeDeclarationScope(scope, element); |
3286 resolveTypeVariableBounds(node.typeParameters); | 3310 resolveTypeVariableBounds(node.typeParameters); |
(...skipping 23 matching lines...) Expand all Loading... |
3310 mixinApplication.resolutionState = STATE_DONE; | 3334 mixinApplication.resolutionState = STATE_DONE; |
3311 mixinApplication.supertypeLoadState = STATE_DONE; | 3335 mixinApplication.supertypeLoadState = STATE_DONE; |
3312 return mixinApplication.computeType(compiler); | 3336 return mixinApplication.computeType(compiler); |
3313 } | 3337 } |
3314 | 3338 |
3315 bool isDefaultConstructor(FunctionElement constructor) { | 3339 bool isDefaultConstructor(FunctionElement constructor) { |
3316 return constructor.name == const SourceString('') && | 3340 return constructor.name == const SourceString('') && |
3317 constructor.computeSignature(compiler).parameterCount == 0; | 3341 constructor.computeSignature(compiler).parameterCount == 0; |
3318 } | 3342 } |
3319 | 3343 |
3320 FunctionElement createForwardingConstructor(FunctionElement constructor, | 3344 FunctionElement createForwardingConstructor(FunctionElement target, |
3321 ClassElement target) { | 3345 ClassElement enclosing) { |
3322 return new SynthesizedConstructorElementX.forwarding(constructor.name, | 3346 return new SynthesizedConstructorElementX(target.name, |
3323 constructor, | 3347 target, |
3324 target); | 3348 enclosing); |
3325 } | 3349 } |
3326 | 3350 |
3327 void doApplyMixinTo(MixinApplicationElement mixinApplication, | 3351 void doApplyMixinTo(MixinApplicationElement mixinApplication, |
3328 DartType supertype, | 3352 DartType supertype, |
3329 DartType mixinType) { | 3353 DartType mixinType) { |
3330 Node node = mixinApplication.parseNode(compiler); | 3354 Node node = mixinApplication.parseNode(compiler); |
3331 | 3355 |
3332 if (mixinApplication.supertype != null) { | 3356 if (mixinApplication.supertype != null) { |
3333 // [supertype] is not null if there was a cycle. | 3357 // [supertype] is not null if there was a cycle. |
3334 assert(invariant(node, compiler.compilationFailed)); | 3358 assert(invariant(node, compiler.compilationFailed)); |
(...skipping 18 matching lines...) Expand all Loading... |
3353 assert(mixinApplication.interfaces == null); | 3377 assert(mixinApplication.interfaces == null); |
3354 mixinApplication.interfaces = interfaces; | 3378 mixinApplication.interfaces = interfaces; |
3355 | 3379 |
3356 assert(mixinApplication.mixin == null); | 3380 assert(mixinApplication.mixin == null); |
3357 mixinApplication.mixin = resolveMixinFor(mixinApplication, mixinType); | 3381 mixinApplication.mixin = resolveMixinFor(mixinApplication, mixinType); |
3358 | 3382 |
3359 // Create forwarding constructors for constructor defined in the superclass | 3383 // Create forwarding constructors for constructor defined in the superclass |
3360 // because they are now hidden by the mixin application. | 3384 // because they are now hidden by the mixin application. |
3361 ClassElement superclass = supertype.element; | 3385 ClassElement superclass = supertype.element; |
3362 superclass.forEachLocalMember((Element member) { | 3386 superclass.forEachLocalMember((Element member) { |
3363 if (!member.isConstructor()) return; | 3387 if (!member.isGenerativeConstructor()) return; |
3364 if (member.isSynthesized && !member.isForwardingConstructor) return; | |
3365 if (isDefaultConstructor(member)) return; | |
3366 assert(invariant(node, !member.isFactoryConstructor(), | |
3367 message: 'mixins cannot have factory constructors')); | |
3368 // Skip forwarding constructors and use their target. | |
3369 FunctionElement constructor = | |
3370 member.isForwardingConstructor ? member.targetConstructor : member; | |
3371 assert(invariant(node, !constructor.isForwardingConstructor)); | |
3372 FunctionElement forwarder = | 3388 FunctionElement forwarder = |
3373 createForwardingConstructor(constructor, mixinApplication); | 3389 createForwardingConstructor(member, mixinApplication); |
3374 mixinApplication.addConstructor(forwarder); | 3390 mixinApplication.addConstructor(forwarder); |
3375 }); | 3391 }); |
3376 mixinApplication.addDefaultConstructorIfNeeded(compiler); | |
3377 calculateAllSupertypes(mixinApplication); | 3392 calculateAllSupertypes(mixinApplication); |
3378 } | 3393 } |
3379 | 3394 |
3380 ClassElement resolveMixinFor(MixinApplicationElement mixinApplication, | 3395 ClassElement resolveMixinFor(MixinApplicationElement mixinApplication, |
3381 DartType mixinType) { | 3396 DartType mixinType) { |
3382 ClassElement mixin = mixinType.element; | 3397 ClassElement mixin = mixinType.element; |
3383 mixin.ensureResolved(compiler); | 3398 mixin.ensureResolved(compiler); |
3384 | 3399 |
3385 // Check for cycles in the mixin chain. | 3400 // Check for cycles in the mixin chain. |
3386 ClassElement previous = mixinApplication; // For better error messages. | 3401 ClassElement previous = mixinApplication; // For better error messages. |
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4055 return e; | 4070 return e; |
4056 } | 4071 } |
4057 | 4072 |
4058 /// Assumed to be called by [resolveRedirectingFactory]. | 4073 /// Assumed to be called by [resolveRedirectingFactory]. |
4059 Element visitReturn(Return node) { | 4074 Element visitReturn(Return node) { |
4060 Node expression = node.expression; | 4075 Node expression = node.expression; |
4061 return finishConstructorReference(visit(expression), | 4076 return finishConstructorReference(visit(expression), |
4062 expression, expression); | 4077 expression, expression); |
4063 } | 4078 } |
4064 } | 4079 } |
OLD | NEW |