| 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 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 void visitYieldStatement(YieldStatement node) { | 562 void visitYieldStatement(YieldStatement node) { |
| 563 _checkReturnOrYield(node.expression, node, yieldStar: node.star != null); | 563 _checkReturnOrYield(node.expression, node, yieldStar: node.star != null); |
| 564 node.visitChildren(this); | 564 node.visitChildren(this); |
| 565 } | 565 } |
| 566 | 566 |
| 567 StaticInfo _checkAssignment(Expression expr, DartType toT) { | 567 StaticInfo _checkAssignment(Expression expr, DartType toT) { |
| 568 final fromT = expr.staticType ?? DynamicTypeImpl.instance; | 568 final fromT = expr.staticType ?? DynamicTypeImpl.instance; |
| 569 final Coercion c = _coerceTo(fromT, toT); | 569 final Coercion c = _coerceTo(fromT, toT); |
| 570 if (c is Identity) return null; | 570 if (c is Identity) return null; |
| 571 if (c is CoercionError) return new StaticTypeError(rules, expr, toT); | 571 if (c is CoercionError) return new StaticTypeError(rules, expr, toT); |
| 572 var reason = null; | 572 if (c is Cast) return DownCast.create(rules, expr, c); |
| 573 | |
| 574 var errors = <String>[]; | |
| 575 | |
| 576 var ok = _inferExpression(expr, toT, errors); | |
| 577 if (ok) return InferredType.create(rules, expr, toT); | |
| 578 reason = (errors.isNotEmpty) ? errors.first : null; | |
| 579 | |
| 580 if (c is Cast) return DownCast.create(rules, expr, c, reason: reason); | |
| 581 assert(false); | 573 assert(false); |
| 582 return null; | 574 return null; |
| 583 } | 575 } |
| 584 | 576 |
| 585 void _checkCompoundAssignment(AssignmentExpression expr) { | 577 void _checkCompoundAssignment(AssignmentExpression expr) { |
| 586 var op = expr.operator.type; | 578 var op = expr.operator.type; |
| 587 assert(op.isAssignmentOperator && op != TokenType.EQ); | 579 assert(op.isAssignmentOperator && op != TokenType.EQ); |
| 588 var methodElement = expr.staticElement; | 580 var methodElement = expr.staticElement; |
| 589 if (methodElement == null) { | 581 if (methodElement == null) { |
| 590 // Dynamic invocation | 582 // Dynamic invocation |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 793 t = parent.staticInvokeType; | 785 t = parent.staticInvokeType; |
| 794 } | 786 } |
| 795 } | 787 } |
| 796 if (t is InterfaceType) { | 788 if (t is InterfaceType) { |
| 797 return rules.getCallMethodType(t); | 789 return rules.getCallMethodType(t); |
| 798 } | 790 } |
| 799 if (t is FunctionType) return t; | 791 if (t is FunctionType) return t; |
| 800 return null; | 792 return null; |
| 801 } | 793 } |
| 802 | 794 |
| 803 /// Checks if we can perform downwards inference on [e] tp get type [t]. | |
| 804 /// If it is not possible, this will add a message to [errors]. | |
| 805 bool _inferExpression(Expression e, DartType t, List<String> errors) { | |
| 806 DartType staticType = e.staticType ?? DynamicTypeImpl.instance; | |
| 807 if (rules.isSubtypeOf(staticType, t)) { | |
| 808 return true; | |
| 809 } | |
| 810 errors.add("$e cannot be typed as $t"); | |
| 811 return false; | |
| 812 } | |
| 813 | |
| 814 /// Returns `true` if the expression is a dynamic function call or method | 795 /// Returns `true` if the expression is a dynamic function call or method |
| 815 /// invocation. | 796 /// invocation. |
| 816 bool _isDynamicCall(Expression call) { | 797 bool _isDynamicCall(Expression call) { |
| 817 var ft = _getTypeAsCaller(call); | 798 var ft = _getTypeAsCaller(call); |
| 818 // TODO(leafp): This will currently return true if t is Function | 799 // TODO(leafp): This will currently return true if t is Function |
| 819 // This is probably the most correct thing to do for now, since | 800 // This is probably the most correct thing to do for now, since |
| 820 // this code is also used by the back end. Maybe revisit at some | 801 // this code is also used by the back end. Maybe revisit at some |
| 821 // point? | 802 // point? |
| 822 if (ft == null) return true; | 803 if (ft == null) return true; |
| 823 // Dynamic as the parameter type is treated as bottom. A function with | 804 // Dynamic as the parameter type is treated as bottom. A function with |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1238 } while (!current.isObject && !visited.contains(current)); | 1219 } while (!current.isObject && !visited.contains(current)); |
| 1239 } | 1220 } |
| 1240 | 1221 |
| 1241 void _recordMessage(StaticInfo info) { | 1222 void _recordMessage(StaticInfo info) { |
| 1242 if (info == null) return; | 1223 if (info == null) return; |
| 1243 var error = info.toAnalysisError(); | 1224 var error = info.toAnalysisError(); |
| 1244 if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) _failure = true; | 1225 if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) _failure = true; |
| 1245 _reporter.onError(error); | 1226 _reporter.onError(error); |
| 1246 } | 1227 } |
| 1247 } | 1228 } |
| OLD | NEW |