| 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 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1044 | 1044 |
| 1045 /// Records an implicit cast for the [expr] from [from] to [to]. | 1045 /// Records an implicit cast for the [expr] from [from] to [to]. |
| 1046 /// | 1046 /// |
| 1047 /// This will emit the appropriate error/warning/hint message as well as mark | 1047 /// This will emit the appropriate error/warning/hint message as well as mark |
| 1048 /// the AST node. | 1048 /// the AST node. |
| 1049 void _recordImplicitCast(Expression expr, DartType to, | 1049 void _recordImplicitCast(Expression expr, DartType to, |
| 1050 {DartType from, bool opAssign: false}) { | 1050 {DartType from, bool opAssign: false}) { |
| 1051 assert(rules.isSubtypeOf(to, from)); | 1051 assert(rules.isSubtypeOf(to, from)); |
| 1052 | 1052 |
| 1053 // Inference "casts": | 1053 // Inference "casts": |
| 1054 if (expr is Literal || expr is FunctionExpression) { | 1054 if (expr is Literal) { |
| 1055 // fromT should be an exact type - this will almost certainly fail at | 1055 // fromT should be an exact type - this will almost certainly fail at |
| 1056 // runtime. | 1056 // runtime. |
| 1057 _recordMessage(expr, StrongModeCode.STATIC_TYPE_ERROR, [expr, from, to]); | 1057 if (expr is ListLiteral) { |
| 1058 _recordMessage( |
| 1059 expr, StrongModeCode.INVALID_CAST_LITERAL_LIST, [from, to]); |
| 1060 } else if (expr is MapLiteral) { |
| 1061 _recordMessage( |
| 1062 expr, StrongModeCode.INVALID_CAST_LITERAL_MAP, [from, to]); |
| 1063 } else { |
| 1064 _recordMessage( |
| 1065 expr, StrongModeCode.INVALID_CAST_LITERAL, [expr, from, to]); |
| 1066 } |
| 1058 return; | 1067 return; |
| 1059 } | 1068 } |
| 1060 | 1069 |
| 1070 if (expr is FunctionExpression) { |
| 1071 _recordMessage( |
| 1072 expr, StrongModeCode.INVALID_CAST_FUNCTION_EXPR, [from, to]); |
| 1073 return; |
| 1074 } |
| 1075 |
| 1061 if (expr is InstanceCreationExpression) { | 1076 if (expr is InstanceCreationExpression) { |
| 1062 ConstructorElement e = expr.staticElement; | 1077 ConstructorElement e = expr.staticElement; |
| 1063 if (e == null || !e.isFactory) { | 1078 if (e == null || !e.isFactory) { |
| 1064 // fromT should be an exact type - this will almost certainly fail at | 1079 // fromT should be an exact type - this will almost certainly fail at |
| 1065 // runtime. | 1080 // runtime. |
| 1066 | 1081 _recordMessage(expr, StrongModeCode.INVALID_CAST_NEW_EXPR, [from, to]); |
| 1067 _recordMessage( | |
| 1068 expr, StrongModeCode.STATIC_TYPE_ERROR, [expr, from, to]); | |
| 1069 return; | 1082 return; |
| 1070 } | 1083 } |
| 1071 } | 1084 } |
| 1072 | 1085 |
| 1073 if (isKnownFunction(expr)) { | 1086 if (isKnownFunction(expr)) { |
| 1074 _recordMessage(expr, StrongModeCode.STATIC_TYPE_ERROR, [expr, from, to]); | 1087 Element e = _getKnownElement(expr); |
| 1088 _recordMessage( |
| 1089 expr, |
| 1090 e is MethodElement |
| 1091 ? StrongModeCode.INVALID_CAST_METHOD |
| 1092 : StrongModeCode.INVALID_CAST_FUNCTION, |
| 1093 [e.name, from, to]); |
| 1075 return; | 1094 return; |
| 1076 } | 1095 } |
| 1077 | 1096 |
| 1078 // Composite cast: these are more likely to fail. | 1097 // Composite cast: these are more likely to fail. |
| 1079 bool downCastComposite = false; | 1098 bool downCastComposite = false; |
| 1080 if (!rules.isGroundType(to)) { | 1099 if (!rules.isGroundType(to)) { |
| 1081 // This cast is (probably) due to our different treatment of dynamic. | 1100 // This cast is (probably) due to our different treatment of dynamic. |
| 1082 // It may be more likely to fail at runtime. | 1101 // It may be more likely to fail at runtime. |
| 1083 if (from is InterfaceType) { | 1102 if (from is InterfaceType) { |
| 1084 // For class types, we'd like to allow non-generic down casts, e.g., | 1103 // For class types, we'd like to allow non-generic down casts, e.g., |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1477 var visited = new Set<InterfaceType>(); | 1496 var visited = new Set<InterfaceType>(); |
| 1478 do { | 1497 do { |
| 1479 visited.add(current); | 1498 visited.add(current); |
| 1480 current.mixins.reversed.forEach( | 1499 current.mixins.reversed.forEach( |
| 1481 (m) => _checkIndividualOverridesFromClass(node, m, seen, true)); | 1500 (m) => _checkIndividualOverridesFromClass(node, m, seen, true)); |
| 1482 _checkIndividualOverridesFromClass(node, current.superclass, seen, true); | 1501 _checkIndividualOverridesFromClass(node, current.superclass, seen, true); |
| 1483 current = current.superclass; | 1502 current = current.superclass; |
| 1484 } while (!current.isObject && !visited.contains(current)); | 1503 } while (!current.isObject && !visited.contains(current)); |
| 1485 } | 1504 } |
| 1486 } | 1505 } |
| OLD | NEW |