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 19754002: Rewrite how we handle synthesized constructors in the compiler. This was motivated by issue https:/… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 compiler.enqueuer.resolution.registerStaticUse(
344 element.targetConstructor);
345 return new TreeElementMapping(element);
346 }
342 if (element.isPatched) { 347 if (element.isPatched) {
343 checkMatchingPatchSignatures(element, element.patch); 348 checkMatchingPatchSignatures(element, element.patch);
344 element = element.patch; 349 element = element.patch;
345 } 350 }
346 return compiler.withCurrentElement(element, () { 351 return compiler.withCurrentElement(element, () {
347 FunctionExpression tree = element.parseNode(compiler); 352 FunctionExpression tree = element.parseNode(compiler);
348 if (tree.modifiers.isExternal()) { 353 if (tree.modifiers.isExternal()) {
349 error(tree, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION); 354 error(tree, MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION);
350 return; 355 return;
351 } 356 }
(...skipping 2176 matching lines...) Expand 10 before | Expand all | Expand 10 after
2528 if (!targetSignature.isCompatibleWith(constructorSignature)) { 2533 if (!targetSignature.isCompatibleWith(constructorSignature)) {
2529 compiler.backend.registerThrowNoSuchMethod(mapping); 2534 compiler.backend.registerThrowNoSuchMethod(mapping);
2530 } 2535 }
2531 2536
2532 // TODO(ahe): Check that this doesn't lead to a cycle. For now, 2537 // TODO(ahe): Check that this doesn't lead to a cycle. For now,
2533 // just make sure that the redirection target isn't itself a 2538 // just make sure that the redirection target isn't itself a
2534 // redirecting factory. 2539 // redirecting factory.
2535 { // This entire block is temporary code per the above TODO. 2540 { // This entire block is temporary code per the above TODO.
2536 FunctionElement targetImplementation = redirectionTarget.implementation; 2541 FunctionElement targetImplementation = redirectionTarget.implementation;
2537 FunctionExpression function = targetImplementation.parseNode(compiler); 2542 FunctionExpression function = targetImplementation.parseNode(compiler);
2538 if (function.body != null && function.body.asReturn() != null 2543 if (function != null
ahe 2013/07/18 09:59:32 I think if function is null, there is a big chance
2544 && function.body != null
2545 && function.body.asReturn() != null
2539 && function.body.asReturn().isRedirectingFactoryBody) { 2546 && function.body.asReturn().isRedirectingFactoryBody) {
2540 unimplemented(node.expression, 'redirecting to redirecting factory'); 2547 unimplemented(node.expression, 'redirecting to redirecting factory');
2541 } 2548 }
2542 } 2549 }
2543 world.registerStaticUse(redirectionTarget); 2550 world.registerStaticUse(redirectionTarget);
2544 world.registerInstantiatedClass( 2551 world.registerInstantiatedClass(
2545 redirectionTarget.enclosingElement.declaration, mapping); 2552 redirectionTarget.enclosingElement.declaration, mapping);
2546 if (isSymbolConstructor) { 2553 if (isSymbolConstructor) {
2547 // Make sure that collection_dev.Symbol.validated is registered. 2554 // Make sure that collection_dev.Symbol.validated is registered.
2548 assert(invariant(node, compiler.symbolValidatedConstructor != null)); 2555 assert(invariant(node, compiler.symbolValidatedConstructor != null));
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after
3265 superElement.ensureResolved(compiler); 3272 superElement.ensureResolved(compiler);
3266 } 3273 }
3267 element.supertype = superElement.computeType(compiler); 3274 element.supertype = superElement.computeType(compiler);
3268 } 3275 }
3269 } 3276 }
3270 3277
3271 assert(element.interfaces == null); 3278 assert(element.interfaces == null);
3272 element.interfaces = resolveInterfaces(node.interfaces, node.superclass); 3279 element.interfaces = resolveInterfaces(node.interfaces, node.superclass);
3273 calculateAllSupertypes(element); 3280 calculateAllSupertypes(element);
3274 3281
3275 element.addDefaultConstructorIfNeeded(compiler); 3282 if (!element.hasConstructor) {
3283 Element superMember =
3284 element.superclass.localLookup(const SourceString(''));
3285 if (superMember == null || !superMember.isGenerativeConstructor()) {
3286 ResolutionWarning warning = new ResolutionWarning(
3287 MessageKind.CANNOT_FIND_CONSTRUCTOR,
3288 {'constructorName': const SourceString('')});
3289 compiler.reportError(node, warning);
ahe 2013/07/18 14:32:56 Please use: compiler.reportErrorCode(node, Messag
ngeoffray 2013/07/18 15:25:14 Done.
3290 superMember = new ErroneousElementX(
ahe 2013/07/18 14:32:56 I'm not sure why you include the error message in
ngeoffray 2013/07/18 15:25:14 As discussed, if the erroneous element is later us
3291 warning.message.kind, warning.message.arguments,
3292 const SourceString(''), element);
3293 compiler.backend.registerThrowNoSuchMethod(mapping);
3294 }
3295 FunctionElement constructor =
3296 new SynthesizedConstructorElementX.forDefault(superMember, element);
3297 element.setDefaultConstructor(constructor, compiler);
3298 }
3276 return element.computeType(compiler); 3299 return element.computeType(compiler);
3277 } 3300 }
3278 3301
3279 DartType visitNamedMixinApplication(NamedMixinApplication node) { 3302 DartType visitNamedMixinApplication(NamedMixinApplication node) {
3280 compiler.ensure(element != null); 3303 compiler.ensure(element != null);
3281 compiler.ensure(element.resolutionState == STATE_STARTED); 3304 compiler.ensure(element.resolutionState == STATE_STARTED);
3282 3305
3283 InterfaceType type = element.computeType(compiler); 3306 InterfaceType type = element.computeType(compiler);
3284 scope = new TypeDeclarationScope(scope, element); 3307 scope = new TypeDeclarationScope(scope, element);
3285 resolveTypeVariableBounds(node.typeParameters); 3308 resolveTypeVariableBounds(node.typeParameters);
(...skipping 23 matching lines...) Expand all
3309 mixinApplication.resolutionState = STATE_DONE; 3332 mixinApplication.resolutionState = STATE_DONE;
3310 mixinApplication.supertypeLoadState = STATE_DONE; 3333 mixinApplication.supertypeLoadState = STATE_DONE;
3311 return mixinApplication.computeType(compiler); 3334 return mixinApplication.computeType(compiler);
3312 } 3335 }
3313 3336
3314 bool isDefaultConstructor(FunctionElement constructor) { 3337 bool isDefaultConstructor(FunctionElement constructor) {
3315 return constructor.name == const SourceString('') && 3338 return constructor.name == const SourceString('') &&
3316 constructor.computeSignature(compiler).parameterCount == 0; 3339 constructor.computeSignature(compiler).parameterCount == 0;
3317 } 3340 }
3318 3341
3319 FunctionElement createForwardingConstructor(FunctionElement constructor, 3342 FunctionElement createForwardingConstructor(FunctionElement target,
3320 ClassElement target) { 3343 ClassElement enclosing) {
3321 return new SynthesizedConstructorElementX.forwarding(constructor.name, 3344 return new SynthesizedConstructorElementX(target.name,
3322 constructor, 3345 target,
3323 target); 3346 enclosing);
3324 } 3347 }
3325 3348
3326 void doApplyMixinTo(MixinApplicationElement mixinApplication, 3349 void doApplyMixinTo(MixinApplicationElement mixinApplication,
3327 DartType supertype, 3350 DartType supertype,
3328 DartType mixinType) { 3351 DartType mixinType) {
3329 Node node = mixinApplication.parseNode(compiler); 3352 Node node = mixinApplication.parseNode(compiler);
3330 3353
3331 if (mixinApplication.supertype != null) { 3354 if (mixinApplication.supertype != null) {
3332 // [supertype] is not null if there was a cycle. 3355 // [supertype] is not null if there was a cycle.
3333 assert(invariant(node, compiler.compilationFailed)); 3356 assert(invariant(node, compiler.compilationFailed));
(...skipping 18 matching lines...) Expand all
3352 assert(mixinApplication.interfaces == null); 3375 assert(mixinApplication.interfaces == null);
3353 mixinApplication.interfaces = interfaces; 3376 mixinApplication.interfaces = interfaces;
3354 3377
3355 assert(mixinApplication.mixin == null); 3378 assert(mixinApplication.mixin == null);
3356 mixinApplication.mixin = resolveMixinFor(mixinApplication, mixinType); 3379 mixinApplication.mixin = resolveMixinFor(mixinApplication, mixinType);
3357 3380
3358 // Create forwarding constructors for constructor defined in the superclass 3381 // Create forwarding constructors for constructor defined in the superclass
3359 // because they are now hidden by the mixin application. 3382 // because they are now hidden by the mixin application.
3360 ClassElement superclass = supertype.element; 3383 ClassElement superclass = supertype.element;
3361 superclass.forEachLocalMember((Element member) { 3384 superclass.forEachLocalMember((Element member) {
3362 if (!member.isConstructor()) return; 3385 if (!member.isGenerativeConstructor()) return;
3363 if (member.isSynthesized && !member.isForwardingConstructor) return;
3364 if (isDefaultConstructor(member)) return;
3365 assert(invariant(node, !member.isFactoryConstructor(),
3366 message: 'mixins cannot have factory constructors'));
3367 // Skip forwarding constructors and use their target.
3368 FunctionElement constructor =
3369 member.isForwardingConstructor ? member.targetConstructor : member;
3370 assert(invariant(node, !constructor.isForwardingConstructor));
3371 FunctionElement forwarder = 3386 FunctionElement forwarder =
3372 createForwardingConstructor(constructor, mixinApplication); 3387 createForwardingConstructor(member, mixinApplication);
3373 mixinApplication.addConstructor(forwarder); 3388 mixinApplication.addConstructor(forwarder);
3374 }); 3389 });
3375 mixinApplication.addDefaultConstructorIfNeeded(compiler);
3376 calculateAllSupertypes(mixinApplication); 3390 calculateAllSupertypes(mixinApplication);
3377 } 3391 }
3378 3392
3379 ClassElement resolveMixinFor(MixinApplicationElement mixinApplication, 3393 ClassElement resolveMixinFor(MixinApplicationElement mixinApplication,
3380 DartType mixinType) { 3394 DartType mixinType) {
3381 ClassElement mixin = mixinType.element; 3395 ClassElement mixin = mixinType.element;
3382 mixin.ensureResolved(compiler); 3396 mixin.ensureResolved(compiler);
3383 3397
3384 // Check for cycles in the mixin chain. 3398 // Check for cycles in the mixin chain.
3385 ClassElement previous = mixinApplication; // For better error messages. 3399 ClassElement previous = mixinApplication; // For better error messages.
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after
4020 return e; 4034 return e;
4021 } 4035 }
4022 4036
4023 /// Assumed to be called by [resolveRedirectingFactory]. 4037 /// Assumed to be called by [resolveRedirectingFactory].
4024 Element visitReturn(Return node) { 4038 Element visitReturn(Return node) {
4025 Node expression = node.expression; 4039 Node expression = node.expression;
4026 return finishConstructorReference(visit(expression), 4040 return finishConstructorReference(visit(expression),
4027 expression, expression); 4041 expression, expression);
4028 } 4042 }
4029 } 4043 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698