| 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 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 } | 636 } |
| 637 } | 637 } |
| 638 | 638 |
| 639 void checkUserDefinableOperator(Element member) { | 639 void checkUserDefinableOperator(Element member) { |
| 640 FunctionElement function = member.asFunctionElement(); | 640 FunctionElement function = member.asFunctionElement(); |
| 641 if (function == null) return; | 641 if (function == null) return; |
| 642 String value = member.name.stringValue; | 642 String value = member.name.stringValue; |
| 643 if (value == null) return; | 643 if (value == null) return; |
| 644 if (!(isUserDefinableOperator(value) || identical(value, 'unary-'))) return; | 644 if (!(isUserDefinableOperator(value) || identical(value, 'unary-'))) return; |
| 645 | 645 |
| 646 bool isMinus = false; |
| 646 int requiredParameterCount; | 647 int requiredParameterCount; |
| 647 MessageKind messageKind; | 648 MessageKind messageKind; |
| 648 FunctionSignature signature = function.computeSignature(compiler); | 649 FunctionSignature signature = function.computeSignature(compiler); |
| 649 if (identical(value, 'unary-')) { | 650 if (identical(value, 'unary-')) { |
| 651 isMinus = true; |
| 650 messageKind = MessageKind.MINUS_OPERATOR_BAD_ARITY; | 652 messageKind = MessageKind.MINUS_OPERATOR_BAD_ARITY; |
| 651 requiredParameterCount = 0; | 653 requiredParameterCount = 0; |
| 652 } else if (isMinusOperator(value)) { | 654 } else if (isMinusOperator(value)) { |
| 655 isMinus = true; |
| 653 messageKind = MessageKind.MINUS_OPERATOR_BAD_ARITY; | 656 messageKind = MessageKind.MINUS_OPERATOR_BAD_ARITY; |
| 654 requiredParameterCount = 1; | 657 requiredParameterCount = 1; |
| 655 } else if (isUnaryOperator(value)) { | 658 } else if (isUnaryOperator(value)) { |
| 656 messageKind = MessageKind.UNARY_OPERATOR_BAD_ARITY; | 659 messageKind = MessageKind.UNARY_OPERATOR_BAD_ARITY; |
| 657 requiredParameterCount = 0; | 660 requiredParameterCount = 0; |
| 658 } else if (isBinaryOperator(value)) { | 661 } else if (isBinaryOperator(value)) { |
| 659 messageKind = MessageKind.BINARY_OPERATOR_BAD_ARITY; | 662 messageKind = MessageKind.BINARY_OPERATOR_BAD_ARITY; |
| 660 requiredParameterCount = 1; | 663 requiredParameterCount = 1; |
| 661 } else if (isTernaryOperator(value)) { | 664 } else if (isTernaryOperator(value)) { |
| 662 messageKind = MessageKind.TERNARY_OPERATOR_BAD_ARITY; | 665 messageKind = MessageKind.TERNARY_OPERATOR_BAD_ARITY; |
| 663 requiredParameterCount = 2; | 666 requiredParameterCount = 2; |
| 664 } else { | 667 } else { |
| 665 compiler.internalErrorOnElement(function, | 668 compiler.internalErrorOnElement(function, |
| 666 'Unexpected user defined operator $value'); | 669 'Unexpected user defined operator $value'); |
| 667 } | 670 } |
| 668 checkArity(function, requiredParameterCount, messageKind); | 671 checkArity(function, requiredParameterCount, messageKind, isMinus); |
| 669 } | 672 } |
| 670 | 673 |
| 671 void checkArity(FunctionElement function, | 674 void checkArity(FunctionElement function, |
| 672 int requiredParameterCount, MessageKind messageKind) { | 675 int requiredParameterCount, MessageKind messageKind, |
| 676 bool isMinus) { |
| 673 FunctionExpression node = function.parseNode(compiler); | 677 FunctionExpression node = function.parseNode(compiler); |
| 674 FunctionSignature signature = function.computeSignature(compiler); | 678 FunctionSignature signature = function.computeSignature(compiler); |
| 675 if (signature.requiredParameterCount != requiredParameterCount) { | 679 if (signature.requiredParameterCount != requiredParameterCount) { |
| 676 Node errorNode = node; | 680 Node errorNode = node; |
| 677 if (node.parameters != null) { | 681 if (node.parameters != null) { |
| 678 if (signature.requiredParameterCount < requiredParameterCount) { | 682 if (isMinus || |
| 683 signature.requiredParameterCount < requiredParameterCount) { |
| 684 // If there are too few parameters, point to the whole parameter list. |
| 685 // For instance |
| 686 // |
| 687 // int operator +() {} |
| 688 // ^^ |
| 689 // |
| 690 // int operator []=(value) {} |
| 691 // ^^^^^^^ |
| 692 // |
| 693 // For operator -, always point the whole parameter list, like |
| 694 // |
| 695 // int operator -(a, b) {} |
| 696 // ^^^^^^ |
| 697 // |
| 698 // instead of |
| 699 // |
| 700 // int operator -(a, b) {} |
| 701 // ^ |
| 702 // |
| 703 // since the correction might not be to remove 'b' but instead to |
| 704 // remove 'a, b'. |
| 679 errorNode = node.parameters; | 705 errorNode = node.parameters; |
| 680 } else { | 706 } else { |
| 681 errorNode = node.parameters.nodes.skip(requiredParameterCount).head; | 707 errorNode = node.parameters.nodes.skip(requiredParameterCount).head; |
| 682 } | 708 } |
| 683 } | 709 } |
| 684 compiler.reportMessage( | 710 compiler.reportMessage( |
| 685 compiler.spanFromSpannable(errorNode), | 711 compiler.spanFromSpannable(errorNode), |
| 686 messageKind.error([function.name]), | 712 messageKind.error([function.name]), |
| 687 Diagnostic.ERROR); | 713 Diagnostic.ERROR); |
| 688 } | 714 } |
| (...skipping 2849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3538 return e; | 3564 return e; |
| 3539 } | 3565 } |
| 3540 | 3566 |
| 3541 /// Assumed to be called by [resolveRedirectingFactory]. | 3567 /// Assumed to be called by [resolveRedirectingFactory]. |
| 3542 Element visitReturn(Return node) { | 3568 Element visitReturn(Return node) { |
| 3543 Node expression = node.expression; | 3569 Node expression = node.expression; |
| 3544 return finishConstructorReference(visit(expression), | 3570 return finishConstructorReference(visit(expression), |
| 3545 expression, expression); | 3571 expression, expression); |
| 3546 } | 3572 } |
| 3547 } | 3573 } |
| OLD | NEW |