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

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

Issue 10834327: Produce error when duplicate field initializers are found (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: == -> ===, improved test, removed unnecessary "defensive" null checks 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 | tests/co19/co19-leg.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 // Check for duplicate initializers. 460 checkForDuplicateInitializers(name, init);
453 if (initialized.containsKey(name)) {
454 error(init, MessageKind.DUPLICATE_INITIALIZER, [name]);
455 warning(initialized[name], MessageKind.ALREADY_INITIALIZED, [name]);
456 }
457 initialized[name] = init;
458 // Resolve initializing value. 461 // Resolve initializing value.
459 visitor.visitInStaticContext(init.arguments.head); 462 visitor.visitInStaticContext(init.arguments.head);
460 } 463 }
461 464
462 Element resolveSuperOrThisForSend(FunctionElement constructor, 465 Element resolveSuperOrThisForSend(FunctionElement constructor,
463 FunctionExpression functionNode, 466 FunctionExpression functionNode,
464 Send call) { 467 Send call) {
465 // Resolve the selector and the arguments. 468 // Resolve the selector and the arguments.
466 ResolverTask resolver = visitor.compiler.resolver; 469 ResolverTask resolver = visitor.compiler.resolver;
467 visitor.inStaticContext(() { 470 visitor.inStaticContext(() {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 } 548 }
546 return null; 549 return null;
547 } 550 }
548 551
549 /** 552 /**
550 * Resolve all initializers of this constructor. In the case of a redirecting 553 * Resolve all initializers of this constructor. In the case of a redirecting
551 * constructor, the resolved constructor's function element is returned. 554 * constructor, the resolved constructor's function element is returned.
552 */ 555 */
553 FunctionElement resolveInitializers(FunctionElement constructor, 556 FunctionElement resolveInitializers(FunctionElement constructor,
554 FunctionExpression functionNode) { 557 FunctionExpression functionNode) {
558 // Keep track of all "this.param" parameters specified for constructor so
559 // that we can ensure that fields are initialized only once.
560 FunctionSignature functionParameters =
561 constructor.computeSignature(visitor.compiler);
562 functionParameters.forEachParameter((Element element) {
563 if (element.kind === ElementKind.FIELD_PARAMETER) {
564 checkForDuplicateInitializers(element.name,
565 element.parseNode(visitor.compiler));
566 }
567 });
568
555 if (functionNode.initializers === null) { 569 if (functionNode.initializers === null) {
556 initializers = const EmptyLink<Node>(); 570 initializers = const EmptyLink<Node>();
557 } else { 571 } else {
558 initializers = functionNode.initializers.nodes; 572 initializers = functionNode.initializers.nodes;
559 } 573 }
560 FunctionElement result; 574 FunctionElement result;
561 bool resolvedSuper = false; 575 bool resolvedSuper = false;
562 for (Link<Node> link = initializers; 576 for (Link<Node> link = initializers;
563 !link.isEmpty(); 577 !link.isEmpty();
564 link = link.tail) { 578 link = link.tail) {
(...skipping 1893 matching lines...) Expand 10 before | Expand all | Expand 10 after
2458 TopScope(LibraryElement library) : super(null, library); 2472 TopScope(LibraryElement library) : super(null, library);
2459 Element lookup(SourceString name) { 2473 Element lookup(SourceString name) {
2460 return library.find(name); 2474 return library.find(name);
2461 } 2475 }
2462 2476
2463 Element add(Element newElement) { 2477 Element add(Element newElement) {
2464 throw "Cannot add an element in the top scope"; 2478 throw "Cannot add an element in the top scope";
2465 } 2479 }
2466 String toString() => '$element'; 2480 String toString() => '$element';
2467 } 2481 }
OLDNEW
« no previous file with comments | « no previous file | tests/co19/co19-leg.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698