| 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 operator[](Node node); | 8 Element operator[](Node node); |
| 9 Selector getSelector(Send send); | 9 Selector getSelector(Send send); |
| 10 DartType getType(Node node); | 10 DartType getType(Node node); |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 metadata.ensureResolved(compiler); | 488 metadata.ensureResolved(compiler); |
| 489 } | 489 } |
| 490 } | 490 } |
| 491 | 491 |
| 492 void checkMembers(ClassElement cls) { | 492 void checkMembers(ClassElement cls) { |
| 493 assert(invariant(cls, cls.isDeclaration)); | 493 assert(invariant(cls, cls.isDeclaration)); |
| 494 if (cls.isObject(compiler)) return; | 494 if (cls.isObject(compiler)) return; |
| 495 // TODO(johnniwinther): Should this be done on the implementation element as | 495 // TODO(johnniwinther): Should this be done on the implementation element as |
| 496 // well? | 496 // well? |
| 497 cls.forEachMember((holder, member) { | 497 cls.forEachMember((holder, member) { |
| 498 // Perform various checks as side effect of "computing" the type. | 498 compiler.withCurrentElement(member, () { |
| 499 member.computeType(compiler); | 499 // Perform various checks as side effect of "computing" the type. |
| 500 member.computeType(compiler); |
| 500 | 501 |
| 501 // Check modifiers. | 502 // Check modifiers. |
| 502 if (member.isFunction() && member.modifiers.isFinal()) { | 503 if (member.isFunction() && member.modifiers.isFinal()) { |
| 503 compiler.reportMessage( | |
| 504 compiler.spanFromElement(member), | |
| 505 MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER.error(), | |
| 506 Diagnostic.ERROR); | |
| 507 } | |
| 508 if (member.isConstructor()) { | |
| 509 final mismatchedFlagsBits = | |
| 510 member.modifiers.flags & | |
| 511 (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT); | |
| 512 if (mismatchedFlagsBits != 0) { | |
| 513 final mismatchedFlags = | |
| 514 new Modifiers.withFlags(null, mismatchedFlagsBits); | |
| 515 compiler.reportMessage( | 504 compiler.reportMessage( |
| 516 compiler.spanFromElement(member), | 505 compiler.spanFromElement(member), |
| 517 MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS.error([mismatchedFlags]), | 506 MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER.error(), |
| 518 Diagnostic.ERROR); | 507 Diagnostic.ERROR); |
| 519 } | 508 } |
| 520 checkConstructorNameHack(holder, member); | 509 if (member.isConstructor()) { |
| 521 } | 510 final mismatchedFlagsBits = |
| 522 checkAbstractField(member); | 511 member.modifiers.flags & |
| 523 checkValidOverride(member, cls.lookupSuperMember(member.name)); | 512 (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT); |
| 513 if (mismatchedFlagsBits != 0) { |
| 514 final mismatchedFlags = |
| 515 new Modifiers.withFlags(null, mismatchedFlagsBits); |
| 516 compiler.reportMessage( |
| 517 compiler.spanFromElement(member), |
| 518 MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS.error( |
| 519 [mismatchedFlags]), |
| 520 Diagnostic.ERROR); |
| 521 } |
| 522 checkConstructorNameHack(holder, member); |
| 523 } |
| 524 checkAbstractField(member); |
| 525 checkValidOverride(member, cls.lookupSuperMember(member.name)); |
| 526 checkUserDefinableOperator(member); |
| 527 }); |
| 524 }); | 528 }); |
| 525 } | 529 } |
| 526 | 530 |
| 527 // TODO(ahe): Remove this method. It is only needed while we store | 531 // TODO(ahe): Remove this method. It is only needed while we store |
| 528 // constructor names as ClassName$id. Once we start storing | 532 // constructor names as ClassName$id. Once we start storing |
| 529 // constructors as just id, this will be caught by the general | 533 // constructors as just id, this will be caught by the general |
| 530 // mechanism for duplicate members. | 534 // mechanism for duplicate members. |
| 531 /// Check that a constructor name does not conflict with a member. | 535 /// Check that a constructor name does not conflict with a member. |
| 532 void checkConstructorNameHack(ClassElement holder, FunctionElement member) { | 536 void checkConstructorNameHack(ClassElement holder, FunctionElement member) { |
| 533 // If the name of the constructor is the same as the name of the | 537 // If the name of the constructor is the same as the name of the |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 compiler.spanFromElement(field.getter), | 586 compiler.spanFromElement(field.getter), |
| 583 MessageKind.GETTER_MISMATCH.error([mismatchedFlags]), | 587 MessageKind.GETTER_MISMATCH.error([mismatchedFlags]), |
| 584 Diagnostic.ERROR); | 588 Diagnostic.ERROR); |
| 585 compiler.reportMessage( | 589 compiler.reportMessage( |
| 586 compiler.spanFromElement(field.setter), | 590 compiler.spanFromElement(field.setter), |
| 587 MessageKind.SETTER_MISMATCH.error([mismatchedFlags]), | 591 MessageKind.SETTER_MISMATCH.error([mismatchedFlags]), |
| 588 Diagnostic.ERROR); | 592 Diagnostic.ERROR); |
| 589 } | 593 } |
| 590 } | 594 } |
| 591 | 595 |
| 596 void checkUserDefinableOperator(Element member) { |
| 597 FunctionElement function = member.asFunctionElement(); |
| 598 if (function == null) return; |
| 599 String value = member.name.stringValue; |
| 600 if (value == null) return; |
| 601 if (!(isUserDefinableOperator(value) || identical(value, 'unary-'))) return; |
| 602 |
| 603 int requiredParameterCount; |
| 604 MessageKind messageKind; |
| 605 FunctionSignature signature = function.computeSignature(compiler); |
| 606 if (identical(value, 'unary-')) { |
| 607 messageKind = MessageKind.MINUS_OPERATOR_BAD_ARITY; |
| 608 requiredParameterCount = 0; |
| 609 } else if (isMinusOperator(value)) { |
| 610 messageKind = MessageKind.MINUS_OPERATOR_BAD_ARITY; |
| 611 requiredParameterCount = 1; |
| 612 } else if (isUnaryOperator(value)) { |
| 613 messageKind = MessageKind.UNARY_OPERATOR_BAD_ARITY; |
| 614 requiredParameterCount = 0; |
| 615 } else if (isBinaryOperator(value)) { |
| 616 messageKind = MessageKind.BINARY_OPERATOR_BAD_ARITY; |
| 617 requiredParameterCount = 1; |
| 618 } else if (isTernaryOperator(value)) { |
| 619 messageKind = MessageKind.TERNARY_OPERATOR_BAD_ARITY; |
| 620 requiredParameterCount = 2; |
| 621 } else { |
| 622 compiler.internalErrorOnElement(function, |
| 623 'Unexpected user defined operator $value'); |
| 624 } |
| 625 checkArity(function, requiredParameterCount, messageKind); |
| 626 } |
| 627 |
| 628 void checkArity(FunctionElement function, |
| 629 int requiredParameterCount, MessageKind messageKind) { |
| 630 FunctionExpression node = function.parseNode(compiler); |
| 631 FunctionSignature signature = function.computeSignature(compiler); |
| 632 if (signature.requiredParameterCount != requiredParameterCount) { |
| 633 Node errorNode = node; |
| 634 if (node.parameters != null) { |
| 635 if (signature.requiredParameterCount < requiredParameterCount) { |
| 636 errorNode = node.parameters; |
| 637 } else { |
| 638 errorNode = node.parameters.nodes.skip(requiredParameterCount).head; |
| 639 } |
| 640 } |
| 641 compiler.reportMessage( |
| 642 compiler.spanFromNode(errorNode), |
| 643 messageKind.error([function.name]), |
| 644 Diagnostic.ERROR); |
| 645 } |
| 646 if (signature.optionalParameterCount != 0) { |
| 647 Node errorNode = |
| 648 node.parameters.nodes.skip(signature.requiredParameterCount).head; |
| 649 if (signature.optionalParametersAreNamed) { |
| 650 compiler.reportMessage( |
| 651 compiler.spanFromNode(errorNode), |
| 652 MessageKind.OPERATOR_NAMED_PARAMETERS.error([function.name]), |
| 653 Diagnostic.ERROR); |
| 654 } else { |
| 655 compiler.reportMessage( |
| 656 compiler.spanFromNode(errorNode), |
| 657 MessageKind.OPERATOR_OPTIONAL_PARAMETERS.error([function.name]), |
| 658 Diagnostic.ERROR); |
| 659 } |
| 660 } |
| 661 } |
| 662 |
| 592 reportErrorWithContext(Element errorneousElement, | 663 reportErrorWithContext(Element errorneousElement, |
| 593 MessageKind errorMessage, | 664 MessageKind errorMessage, |
| 594 Element contextElement, | 665 Element contextElement, |
| 595 MessageKind contextMessage) { | 666 MessageKind contextMessage) { |
| 596 compiler.reportMessage( | 667 compiler.reportMessage( |
| 597 compiler.spanFromElement(errorneousElement), | 668 compiler.spanFromElement(errorneousElement), |
| 598 errorMessage.error([contextElement.name, | 669 errorMessage.error([contextElement.name, |
| 599 contextElement.getEnclosingClass().name]), | 670 contextElement.getEnclosingClass().name]), |
| 600 Diagnostic.ERROR); | 671 Diagnostic.ERROR); |
| 601 compiler.reportMessage( | 672 compiler.reportMessage( |
| (...skipping 2716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3318 return e; | 3389 return e; |
| 3319 } | 3390 } |
| 3320 | 3391 |
| 3321 /// Assumed to be called by [resolveRedirectingFactory]. | 3392 /// Assumed to be called by [resolveRedirectingFactory]. |
| 3322 Element visitReturn(Return node) { | 3393 Element visitReturn(Return node) { |
| 3323 Node expression = node.expression; | 3394 Node expression = node.expression; |
| 3324 return finishConstructorReference(visit(expression), | 3395 return finishConstructorReference(visit(expression), |
| 3325 expression, expression); | 3396 expression, expression); |
| 3326 } | 3397 } |
| 3327 } | 3398 } |
| OLD | NEW |