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

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

Powered by Google App Engine
This is Rietveld 408576698