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 |