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

Side by Side Diff: dart/lib/compiler/implementation/resolver.dart

Issue 10860039: Produce error when duplicate field initializers are found (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased Created 8 years, 4 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
« no previous file with comments | « no previous file | dart/tests/co19/co19-dart2js.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 interface TreeElements { 5 interface TreeElements {
6 Element operator[](Node node); 6 Element operator[](Node node);
7 Selector getSelector(Send send); 7 Selector getSelector(Send send);
8 Type getType(TypeAnnotation annotation); 8 Type getType(TypeAnnotation annotation);
9 } 9 }
10 10
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 visitor.warning(node, kind, arguments); 422 visitor.warning(node, kind, arguments);
423 } 423 }
424 424
425 bool isFieldInitializer(SendSet node) { 425 bool isFieldInitializer(SendSet node) {
426 if (node.selector.asIdentifier() == null) return false; 426 if (node.selector.asIdentifier() == null) return false;
427 if (node.receiver == null) return true; 427 if (node.receiver == null) return true;
428 if (node.receiver.asIdentifier() == null) return false; 428 if (node.receiver.asIdentifier() == null) return false;
429 return node.receiver.asIdentifier().isThis(); 429 return node.receiver.asIdentifier().isThis();
430 } 430 }
431 431
432 void checkForDuplicateInitializers(SourceString name, Node init) {
433 if (initialized.containsKey(name)) {
434 error(init, MessageKind.DUPLICATE_INITIALIZER, [name]);
435 warning(initialized[name], MessageKind.ALREADY_INITIALIZED, [name]);
436 }
437 initialized[name] = init;
438 }
439
432 void resolveFieldInitializer(FunctionElement constructor, SendSet init) { 440 void resolveFieldInitializer(FunctionElement constructor, SendSet init) {
433 // init is of the form [this.]field = value. 441 // init is of the form [this.]field = value.
434 final Node selector = init.selector; 442 final Node selector = init.selector;
435 final SourceString name = selector.asIdentifier().source; 443 final SourceString name = selector.asIdentifier().source;
436 // Lookup target field. 444 // Lookup target field.
437 Element target; 445 Element target;
438 if (isFieldInitializer(init)) { 446 if (isFieldInitializer(init)) {
439 final ClassElement classElement = constructor.getEnclosingClass(); 447 final ClassElement classElement = constructor.getEnclosingClass();
440 target = classElement.lookupLocalMember(name); 448 target = classElement.lookupLocalMember(name);
441 if (target === null) { 449 if (target === null) {
442 error(selector, MessageKind.CANNOT_RESOLVE, [name]); 450 error(selector, MessageKind.CANNOT_RESOLVE, [name]);
443 } else if (target.kind != ElementKind.FIELD) { 451 } else if (target.kind != ElementKind.FIELD) {
444 error(selector, MessageKind.NOT_A_FIELD, [name]); 452 error(selector, MessageKind.NOT_A_FIELD, [name]);
445 } else if (!target.isInstanceMember()) { 453 } else if (!target.isInstanceMember()) {
446 error(selector, MessageKind.INIT_STATIC_FIELD, [name]); 454 error(selector, MessageKind.INIT_STATIC_FIELD, [name]);
447 } 455 }
448 } else { 456 } else {
449 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); 457 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER);
450 } 458 }
451 visitor.useElement(init, target); 459 visitor.useElement(init, target);
452 visitor.world.registerStaticUse(target); 460 visitor.world.registerStaticUse(target);
453 // Check for duplicate initializers. 461 checkForDuplicateInitializers(name, init);
454 if (initialized.containsKey(name)) {
455 error(init, MessageKind.DUPLICATE_INITIALIZER, [name]);
456 warning(initialized[name], MessageKind.ALREADY_INITIALIZED, [name]);
457 }
458 initialized[name] = init;
459 // Resolve initializing value. 462 // Resolve initializing value.
460 visitor.visitInStaticContext(init.arguments.head); 463 visitor.visitInStaticContext(init.arguments.head);
461 } 464 }
462 465
463 Element resolveSuperOrThisForSend(FunctionElement constructor, 466 Element resolveSuperOrThisForSend(FunctionElement constructor,
464 FunctionExpression functionNode, 467 FunctionExpression functionNode,
465 Send call) { 468 Send call) {
466 // Resolve the selector and the arguments. 469 // Resolve the selector and the arguments.
467 ResolverTask resolver = visitor.compiler.resolver; 470 ResolverTask resolver = visitor.compiler.resolver;
468 visitor.inStaticContext(() { 471 visitor.inStaticContext(() {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 } 550 }
548 return null; 551 return null;
549 } 552 }
550 553
551 /** 554 /**
552 * Resolve all initializers of this constructor. In the case of a redirecting 555 * Resolve all initializers of this constructor. In the case of a redirecting
553 * constructor, the resolved constructor's function element is returned. 556 * constructor, the resolved constructor's function element is returned.
554 */ 557 */
555 FunctionElement resolveInitializers(FunctionElement constructor, 558 FunctionElement resolveInitializers(FunctionElement constructor,
556 FunctionExpression functionNode) { 559 FunctionExpression functionNode) {
560 // Keep track of all "this.param" parameters specified for constructor so
561 // that we can ensure that fields are initialized only once.
562 FunctionSignature functionParameters =
563 constructor.computeSignature(visitor.compiler);
564 functionParameters.forEachParameter((Element element) {
565 if (element.kind === ElementKind.FIELD_PARAMETER) {
566 checkForDuplicateInitializers(element.name,
567 element.parseNode(visitor.compiler));
568 }
569 });
570
557 if (functionNode.initializers === null) { 571 if (functionNode.initializers === null) {
558 initializers = const EmptyLink<Node>(); 572 initializers = const EmptyLink<Node>();
559 } else { 573 } else {
560 initializers = functionNode.initializers.nodes; 574 initializers = functionNode.initializers.nodes;
561 } 575 }
562 FunctionElement result; 576 FunctionElement result;
563 bool resolvedSuper = false; 577 bool resolvedSuper = false;
564 for (Link<Node> link = initializers; 578 for (Link<Node> link = initializers;
565 !link.isEmpty(); 579 !link.isEmpty();
566 link = link.tail) { 580 link = link.tail) {
(...skipping 1905 matching lines...) Expand 10 before | Expand all | Expand 10 after
2472 TopScope(LibraryElement library) : super(null, library); 2486 TopScope(LibraryElement library) : super(null, library);
2473 Element lookup(SourceString name) { 2487 Element lookup(SourceString name) {
2474 return library.find(name); 2488 return library.find(name);
2475 } 2489 }
2476 2490
2477 Element add(Element newElement) { 2491 Element add(Element newElement) {
2478 throw "Cannot add an element in the top scope"; 2492 throw "Cannot add an element in the top scope";
2479 } 2493 }
2480 String toString() => '$element'; 2494 String toString() => '$element';
2481 } 2495 }
OLDNEW
« no previous file with comments | « no previous file | dart/tests/co19/co19-dart2js.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698