OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library dev_compiler.src.checker.checker; | 5 library dev_compiler.src.checker.checker; |
6 | 6 |
7 import 'package:analyzer/analyzer.dart'; | 7 import 'package:analyzer/analyzer.dart'; |
8 import 'package:analyzer/src/generated/ast.dart'; | 8 import 'package:analyzer/src/generated/ast.dart'; |
9 import 'package:analyzer/src/generated/element.dart'; | 9 import 'package:analyzer/src/generated/element.dart'; |
10 import 'package:analyzer/src/generated/scanner.dart' show Token, TokenType; | 10 import 'package:analyzer/src/generated/scanner.dart' show Token, TokenType; |
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 // potentially too conservative. Instead, at runtime, we must fail hard | 698 // potentially too conservative. Instead, at runtime, we must fail hard |
699 // if the Dart as and the DDC as would return different values. | 699 // if the Dart as and the DDC as would return different values. |
700 node.visitChildren(this); | 700 node.visitChildren(this); |
701 } | 701 } |
702 | 702 |
703 visitIsExpression(IsExpression node) { | 703 visitIsExpression(IsExpression node) { |
704 _checkRuntimeTypeCheck(node, node.type); | 704 _checkRuntimeTypeCheck(node, node.type); |
705 node.visitChildren(this); | 705 node.visitChildren(this); |
706 } | 706 } |
707 | 707 |
| 708 visitBinaryExpression(BinaryExpression node) { |
| 709 var op = node.operator; |
| 710 if (op.isUserDefinableOperator) { |
| 711 if (_rules.isDynamicTarget(node.leftOperand)) { |
| 712 // Dynamic invocation |
| 713 // TODO(vsm): Move this logic to the resolver? |
| 714 if (op.type != TokenType.EQ_EQ && op.type != TokenType.BANG_EQ) { |
| 715 _recordDynamicInvoke(node); |
| 716 } |
| 717 } else { |
| 718 var element = node.staticElement; |
| 719 // Method invocation. |
| 720 if (element is MethodElement) { |
| 721 var type = element.type as FunctionType; |
| 722 assert(type.normalParameterTypes.length == 1); |
| 723 node.rightOperand = |
| 724 checkArgument(node.rightOperand, type.normalParameterTypes[0]); |
| 725 } else { |
| 726 // TODO(vsm): Assert that the analyzer found an error here? |
| 727 } |
| 728 } |
| 729 } else { |
| 730 // Non-method operator. |
| 731 switch (op.type) { |
| 732 case TokenType.AMPERSAND_AMPERSAND: |
| 733 case TokenType.BAR_BAR: |
| 734 var boolType = _rules.provider.boolType; |
| 735 node.leftOperand = checkArgument(node.leftOperand, boolType); |
| 736 node.rightOperand = checkArgument(node.rightOperand, boolType); |
| 737 break; |
| 738 case TokenType.BANG_EQ: |
| 739 break; |
| 740 default: |
| 741 assert(false); |
| 742 } |
| 743 } |
| 744 node.visitChildren(this); |
| 745 } |
| 746 |
708 DartType getType(TypeName name) { | 747 DartType getType(TypeName name) { |
709 return (name == null) ? _rules.provider.dynamicType : name.type; | 748 return (name == null) ? _rules.provider.dynamicType : name.type; |
710 } | 749 } |
711 | 750 |
712 Expression checkAssignment(Expression expr, DartType type) { | 751 Expression checkAssignment(Expression expr, DartType type) { |
713 final staticInfo = _rules.checkAssignment(expr, type, _constantContext); | 752 if (expr is ParenthesizedExpression) { |
714 _recordMessage(staticInfo); | 753 expr.expression = checkAssignment(expr.expression, type); |
715 if (staticInfo is Conversion) expr = staticInfo; | 754 } else { |
| 755 final staticInfo = _rules.checkAssignment(expr, type, _constantContext); |
| 756 _recordMessage(staticInfo); |
| 757 if (staticInfo is Conversion) expr = staticInfo; |
| 758 } |
716 return expr; | 759 return expr; |
717 } | 760 } |
718 | 761 |
719 DartType _specializedBinaryReturnType( | 762 DartType _specializedBinaryReturnType( |
720 TokenType op, DartType t1, DartType t2, DartType normalReturnType) { | 763 TokenType op, DartType t1, DartType t2, DartType normalReturnType) { |
721 // This special cases binary return types as per 16.26 and 16.27 of the | 764 // This special cases binary return types as per 16.26 and 16.27 of the |
722 // Dart language spec. | 765 // Dart language spec. |
723 switch (op) { | 766 switch (op) { |
724 case TokenType.PLUS: | 767 case TokenType.PLUS: |
725 case TokenType.MINUS: | 768 case TokenType.MINUS: |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
797 void _recordDynamicInvoke(AstNode node) { | 840 void _recordDynamicInvoke(AstNode node) { |
798 _reporter.log(new DynamicInvoke(_rules, node)); | 841 _reporter.log(new DynamicInvoke(_rules, node)); |
799 } | 842 } |
800 | 843 |
801 void _recordMessage(StaticInfo info) { | 844 void _recordMessage(StaticInfo info) { |
802 if (info == null) return; | 845 if (info == null) return; |
803 if (info.level >= logger.Level.SEVERE) _failure = true; | 846 if (info.level >= logger.Level.SEVERE) _failure = true; |
804 _reporter.log(info); | 847 _reporter.log(info); |
805 } | 848 } |
806 } | 849 } |
OLD | NEW |