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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
155 DartType expectedType = _elementType(element); | 155 DartType expectedType = _elementType(element); |
156 if (expectedType == null) expectedType = DynamicTypeImpl.instance; | 156 if (expectedType == null) expectedType = DynamicTypeImpl.instance; |
157 checkArgument(arg, expectedType); | 157 checkArgument(arg, expectedType); |
158 } | 158 } |
159 } | 159 } |
160 | 160 |
161 void checkAssignment(Expression expr, DartType type) { | 161 void checkAssignment(Expression expr, DartType type) { |
162 if (expr is ParenthesizedExpression) { | 162 if (expr is ParenthesizedExpression) { |
163 checkAssignment(expr.expression, type); | 163 checkAssignment(expr.expression, type); |
164 } else { | 164 } else { |
165 _checkDowncast(expr, type); | 165 if (_checkNonNullAssignment(expr, type)) { |
166 _checkNonNullAssignment(expr, type); | 166 _checkDowncast(expr, type); |
167 } | |
167 } | 168 } |
168 } | 169 } |
169 | 170 |
170 /// Analyzer checks boolean conversions, but we need to check too, because | 171 /// Analyzer checks boolean conversions, but we need to check too, because |
171 /// it uses the default assignability rules that allow `dynamic` and `Object` | 172 /// it uses the default assignability rules that allow `dynamic` and `Object` |
172 /// to be assigned to bool with no message. | 173 /// to be assigned to bool with no message. |
173 void checkBoolean(Expression expr) => | 174 void checkBoolean(Expression expr) => |
174 checkAssignment(expr, typeProvider.boolType); | 175 checkAssignment(expr, typeProvider.boolType); |
175 | 176 |
176 void checkFunctionApplication( | 177 void checkFunctionApplication( |
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
832 return; | 833 return; |
833 } | 834 } |
834 if (declElement.enclosingElement is ExecutableElement) { | 835 if (declElement.enclosingElement is ExecutableElement) { |
835 // Variable declaration is inside a function or method, so it's safe. | 836 // Variable declaration is inside a function or method, so it's safe. |
836 return; | 837 return; |
837 } | 838 } |
838 _recordMessage(node, StrongModeCode.UNSAFE_BLOCK_CLOSURE_INFERENCE, | 839 _recordMessage(node, StrongModeCode.UNSAFE_BLOCK_CLOSURE_INFERENCE, |
839 [declElement.name]); | 840 [declElement.name]); |
840 } | 841 } |
841 | 842 |
842 void _checkNonNullAssignment(Expression expression, DartType type) { | 843 /// Checks if the assignment is valid with respect to non-nullable types. |
844 /// Returns `false` if a nullable expression is assigned to a variable of | |
845 /// non-nullable type and `true` otherwise. | |
846 bool _checkNonNullAssignment(Expression expression, DartType type) { | |
843 var exprType = expression.staticType; | 847 var exprType = expression.staticType; |
844 if (rules.isNonNullableType(type) && !rules.isNonNullableType(exprType)) { | 848 if (rules.isNonNullableType(type) && !rules.isNonNullableType(exprType)) { |
Leaf
2016/08/03 23:45:07
I'd suggest a helper "isNullableType", to avoid do
stanm
2016/08/04 00:31:15
Good idea, thanks!
| |
845 _recordMessage(expression, StaticTypeWarningCode.INVALID_ASSIGNMENT, | 849 _recordMessage(expression, StaticTypeWarningCode.INVALID_ASSIGNMENT, |
846 [exprType, type]); | 850 [exprType, type]); |
851 return false; | |
847 } | 852 } |
853 return true; | |
848 } | 854 } |
849 | 855 |
850 void _checkReturnOrYield(Expression expression, AstNode node, | 856 void _checkReturnOrYield(Expression expression, AstNode node, |
851 {bool yieldStar: false}) { | 857 {bool yieldStar: false}) { |
852 FunctionBody body = node.getAncestor((n) => n is FunctionBody); | 858 FunctionBody body = node.getAncestor((n) => n is FunctionBody); |
853 var type = _getExpectedReturnType(body, yieldStar: yieldStar); | 859 var type = _getExpectedReturnType(body, yieldStar: yieldStar); |
854 if (type == null) { | 860 if (type == null) { |
855 // We have a type mismatch: the async/async*/sync* modifier does | 861 // We have a type mismatch: the async/async*/sync* modifier does |
856 // not match the return or yield type. We should have already gotten an | 862 // not match the return or yield type. We should have already gotten an |
857 // analyzer error in this case. | 863 // analyzer error in this case. |
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1489 var visited = new Set<InterfaceType>(); | 1495 var visited = new Set<InterfaceType>(); |
1490 do { | 1496 do { |
1491 visited.add(current); | 1497 visited.add(current); |
1492 current.mixins.reversed.forEach( | 1498 current.mixins.reversed.forEach( |
1493 (m) => _checkIndividualOverridesFromClass(node, m, seen, true)); | 1499 (m) => _checkIndividualOverridesFromClass(node, m, seen, true)); |
1494 _checkIndividualOverridesFromClass(node, current.superclass, seen, true); | 1500 _checkIndividualOverridesFromClass(node, current.superclass, seen, true); |
1495 current = current.superclass; | 1501 current = current.superclass; |
1496 } while (!current.isObject && !visited.contains(current)); | 1502 } while (!current.isObject && !visited.contains(current)); |
1497 } | 1503 } |
1498 } | 1504 } |
OLD | NEW |