| 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 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be | 5 // TODO(jmesserly): this was ported from package:dev_compiler, and needs to be |
| 6 // refactored to fit into analyzer. | 6 // refactored to fit into analyzer. |
| 7 library analyzer.src.task.strong.checker; | 7 library analyzer.src.task.strong.checker; |
| 8 | 8 |
| 9 import 'package:analyzer/analyzer.dart'; | 9 import 'package:analyzer/analyzer.dart'; |
| 10 import 'package:analyzer/dart/ast/ast.dart'; | 10 import 'package:analyzer/dart/ast/ast.dart'; |
| (...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 var functionType = methodElement.type; | 615 var functionType = methodElement.type; |
| 616 var paramTypes = functionType.normalParameterTypes; | 616 var paramTypes = functionType.normalParameterTypes; |
| 617 assert(paramTypes.length == 1); | 617 assert(paramTypes.length == 1); |
| 618 assert(functionType.namedParameterTypes.isEmpty); | 618 assert(functionType.namedParameterTypes.isEmpty); |
| 619 assert(functionType.optionalParameterTypes.isEmpty); | 619 assert(functionType.optionalParameterTypes.isEmpty); |
| 620 | 620 |
| 621 // Check the LHS type. | 621 // Check the LHS type. |
| 622 var staticInfo; | 622 var staticInfo; |
| 623 var rhsType = _getStaticType(expr.rightHandSide); | 623 var rhsType = _getStaticType(expr.rightHandSide); |
| 624 var lhsType = _getStaticType(expr.leftHandSide); | 624 var lhsType = _getStaticType(expr.leftHandSide); |
| 625 var returnType = _specializedBinaryReturnType( | 625 var returnType = rules.refineBinaryExpressionType( |
| 626 op, lhsType, rhsType, functionType.returnType); | 626 typeProvider, lhsType, op, rhsType, functionType.returnType); |
| 627 | 627 |
| 628 if (!rules.isSubtypeOf(returnType, lhsType)) { | 628 if (!rules.isSubtypeOf(returnType, lhsType)) { |
| 629 final numType = typeProvider.numType; | 629 final numType = typeProvider.numType; |
| 630 // Try to fix up the numerical case if possible. | 630 // Try to fix up the numerical case if possible. |
| 631 if (rules.isSubtypeOf(lhsType, numType) && | 631 if (rules.isSubtypeOf(lhsType, numType) && |
| 632 rules.isSubtypeOf(lhsType, rhsType)) { | 632 rules.isSubtypeOf(lhsType, rhsType)) { |
| 633 // This is also slightly different from spec, but allows us to keep | 633 // This is also slightly different from spec, but allows us to keep |
| 634 // compound operators in the int += num and num += dynamic cases. | 634 // compound operators in the int += num and num += dynamic cases. |
| 635 staticInfo = | 635 staticInfo = |
| 636 DownCast.create(rules, expr.rightHandSide, rhsType, lhsType); | 636 DownCast.create(rules, expr.rightHandSide, rhsType, lhsType); |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 | 914 |
| 915 if (info is CoercionInfo) { | 915 if (info is CoercionInfo) { |
| 916 // TODO(jmesserly): if we're run again on the same AST, we'll produce the | 916 // TODO(jmesserly): if we're run again on the same AST, we'll produce the |
| 917 // same annotations. This should be harmless. This might go away once | 917 // same annotations. This should be harmless. This might go away once |
| 918 // CodeChecker is integrated better with analyzer, as it will know that | 918 // CodeChecker is integrated better with analyzer, as it will know that |
| 919 // checking has already been performed. | 919 // checking has already been performed. |
| 920 // assert(CoercionInfo.get(info.node) == null); | 920 // assert(CoercionInfo.get(info.node) == null); |
| 921 CoercionInfo.set(info.node, info); | 921 CoercionInfo.set(info.node, info); |
| 922 } | 922 } |
| 923 } | 923 } |
| 924 | |
| 925 DartType _specializedBinaryReturnType( | |
| 926 TokenType op, DartType t1, DartType t2, DartType normalReturnType) { | |
| 927 // This special cases binary return types as per 16.26 and 16.27 of the | |
| 928 // Dart language spec. | |
| 929 switch (op) { | |
| 930 case TokenType.PLUS: | |
| 931 case TokenType.MINUS: | |
| 932 case TokenType.STAR: | |
| 933 case TokenType.TILDE_SLASH: | |
| 934 case TokenType.PERCENT: | |
| 935 case TokenType.PLUS_EQ: | |
| 936 case TokenType.MINUS_EQ: | |
| 937 case TokenType.STAR_EQ: | |
| 938 case TokenType.TILDE_SLASH_EQ: | |
| 939 case TokenType.PERCENT_EQ: | |
| 940 if (t1 == typeProvider.intType && t2 == typeProvider.intType) return t1; | |
| 941 if (t1 == typeProvider.doubleType && t2 == typeProvider.doubleType) | |
| 942 return t1; | |
| 943 // This particular combo is not spelled out in the spec, but all | |
| 944 // implementations and analyzer seem to follow this. | |
| 945 if (t1 == typeProvider.doubleType && t2 == typeProvider.intType) | |
| 946 return t1; | |
| 947 } | |
| 948 return normalReturnType; | |
| 949 } | |
| 950 } | 924 } |
| 951 | 925 |
| 952 /// Checks for overriding declarations of fields and methods. This is used to | 926 /// Checks for overriding declarations of fields and methods. This is used to |
| 953 /// check overrides between classes and superclasses, interfaces, and mixin | 927 /// check overrides between classes and superclasses, interfaces, and mixin |
| 954 /// applications. | 928 /// applications. |
| 955 class _OverrideChecker { | 929 class _OverrideChecker { |
| 956 bool _failure = false; | 930 bool _failure = false; |
| 957 final StrongTypeSystemImpl rules; | 931 final StrongTypeSystemImpl rules; |
| 958 final TypeProvider _typeProvider; | 932 final TypeProvider _typeProvider; |
| 959 final AnalysisErrorListener _reporter; | 933 final AnalysisErrorListener _reporter; |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1292 } while (!current.isObject && !visited.contains(current)); | 1266 } while (!current.isObject && !visited.contains(current)); |
| 1293 } | 1267 } |
| 1294 | 1268 |
| 1295 void _recordMessage(StaticInfo info) { | 1269 void _recordMessage(StaticInfo info) { |
| 1296 if (info == null) return; | 1270 if (info == null) return; |
| 1297 var error = info.toAnalysisError(); | 1271 var error = info.toAnalysisError(); |
| 1298 if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) _failure = true; | 1272 if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) _failure = true; |
| 1299 _reporter.onError(error); | 1273 _reporter.onError(error); |
| 1300 } | 1274 } |
| 1301 } | 1275 } |
| OLD | NEW |