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 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 void _checkReturnOrYield(Expression expression, AstNode node, | 713 void _checkReturnOrYield(Expression expression, AstNode node, |
714 {bool yieldStar: false}) { | 714 {bool yieldStar: false}) { |
715 FunctionBody body = node.getAncestor((n) => n is FunctionBody); | 715 FunctionBody body = node.getAncestor((n) => n is FunctionBody); |
716 var type = _getExpectedReturnType(body, yieldStar: yieldStar); | 716 var type = _getExpectedReturnType(body, yieldStar: yieldStar); |
717 if (type == null) { | 717 if (type == null) { |
718 // We have a type mismatch: the async/async*/sync* modifier does | 718 // We have a type mismatch: the async/async*/sync* modifier does |
719 // not match the return or yield type. We should have already gotten an | 719 // not match the return or yield type. We should have already gotten an |
720 // analyzer error in this case. | 720 // analyzer error in this case. |
721 return; | 721 return; |
722 } | 722 } |
723 InterfaceType futureType = typeProvider.futureType; | |
724 DartType actualType = expression?.staticType; | |
725 if (body.isAsynchronous && | |
726 !body.isGenerator && | |
727 actualType is InterfaceType && | |
728 actualType.element == futureType.element) { | |
729 type = futureType.instantiate([type]); | |
730 } | |
731 // TODO(vsm): Enforce void or dynamic (to void?) when expression is null. | 723 // TODO(vsm): Enforce void or dynamic (to void?) when expression is null. |
732 if (expression != null) checkAssignment(expression, type); | 724 if (expression != null) checkAssignment(expression, type); |
733 } | 725 } |
734 | 726 |
735 void _checkRuntimeTypeCheck(AstNode node, TypeName typeName) { | 727 void _checkRuntimeTypeCheck(AstNode node, TypeName typeName) { |
736 var type = getType(typeName); | 728 var type = getType(typeName); |
737 if (!rules.isGroundType(type)) { | 729 if (!rules.isGroundType(type)) { |
738 _recordMessage(node, StrongModeCode.NON_GROUND_TYPE_CHECK_INFO, [type]); | 730 _recordMessage(node, StrongModeCode.NON_GROUND_TYPE_CHECK_INFO, [type]); |
739 } | 731 } |
740 } | 732 } |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 } | 843 } |
852 | 844 |
853 var type = functionType.returnType; | 845 var type = functionType.returnType; |
854 | 846 |
855 InterfaceType expectedType = null; | 847 InterfaceType expectedType = null; |
856 if (body.isAsynchronous) { | 848 if (body.isAsynchronous) { |
857 if (body.isGenerator) { | 849 if (body.isGenerator) { |
858 // Stream<T> -> T | 850 // Stream<T> -> T |
859 expectedType = typeProvider.streamType; | 851 expectedType = typeProvider.streamType; |
860 } else { | 852 } else { |
861 // Future<T> -> T | 853 // Don't validate return type of async methods. |
862 // TODO(vsm): Revisit with issue #228. | 854 // They're handled by the runtime implementation. |
863 expectedType = typeProvider.futureType; | 855 return null; |
864 } | 856 } |
865 } else { | 857 } else { |
866 if (body.isGenerator) { | 858 if (body.isGenerator) { |
867 // Iterable<T> -> T | 859 // Iterable<T> -> T |
868 expectedType = typeProvider.iterableType; | 860 expectedType = typeProvider.iterableType; |
869 } else { | 861 } else { |
870 // T -> T | 862 // T -> T |
871 return type; | 863 return type; |
872 } | 864 } |
873 } | 865 } |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1375 var visited = new Set<InterfaceType>(); | 1367 var visited = new Set<InterfaceType>(); |
1376 do { | 1368 do { |
1377 visited.add(current); | 1369 visited.add(current); |
1378 current.mixins.reversed.forEach( | 1370 current.mixins.reversed.forEach( |
1379 (m) => _checkIndividualOverridesFromClass(node, m, seen, true)); | 1371 (m) => _checkIndividualOverridesFromClass(node, m, seen, true)); |
1380 _checkIndividualOverridesFromClass(node, current.superclass, seen, true); | 1372 _checkIndividualOverridesFromClass(node, current.superclass, seen, true); |
1381 current = current.superclass; | 1373 current = current.superclass; |
1382 } while (!current.isObject && !visited.contains(current)); | 1374 } while (!current.isObject && !visited.contains(current)); |
1383 } | 1375 } |
1384 } | 1376 } |
OLD | NEW |