| 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 |