OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library engine.resolver.error_verifier; | 5 library engine.resolver.error_verifier; |
6 | 6 |
7 import "dart:math" as math; | 7 import "dart:math" as math; |
8 import 'dart:collection'; | 8 import 'dart:collection'; |
9 | 9 |
10 import 'ast.dart'; | 10 import 'ast.dart'; |
(...skipping 1775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1786 if (returnExpression == null) { | 1786 if (returnExpression == null) { |
1787 return false; | 1787 return false; |
1788 } | 1788 } |
1789 _errorReporter.reportErrorForNode( | 1789 _errorReporter.reportErrorForNode( |
1790 CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, | 1790 CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, |
1791 returnExpression); | 1791 returnExpression); |
1792 return true; | 1792 return true; |
1793 } | 1793 } |
1794 // RETURN_WITHOUT_VALUE | 1794 // RETURN_WITHOUT_VALUE |
1795 if (returnExpression == null) { | 1795 if (returnExpression == null) { |
1796 if (VoidTypeImpl.instance.isAssignableTo(expectedReturnType)) { | 1796 if (_computeReturnTypeForMethod( |
| 1797 null).isAssignableTo(expectedReturnType)) { |
1797 return false; | 1798 return false; |
1798 } | 1799 } |
1799 _hasReturnWithoutValue = true; | 1800 _hasReturnWithoutValue = true; |
1800 _errorReporter.reportErrorForNode( | 1801 _errorReporter.reportErrorForNode( |
1801 StaticWarningCode.RETURN_WITHOUT_VALUE, | 1802 StaticWarningCode.RETURN_WITHOUT_VALUE, |
1802 node); | 1803 node); |
1803 return true; | 1804 return true; |
1804 } else if (_inGenerator) { | 1805 } else if (_inGenerator) { |
1805 // RETURN_IN_GENERATOR | 1806 // RETURN_IN_GENERATOR |
1806 _errorReporter.reportErrorForNode( | 1807 _errorReporter.reportErrorForNode( |
(...skipping 3357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5164 * @param returnExpression the returned expression to evaluate | 5165 * @param returnExpression the returned expression to evaluate |
5165 * @param expectedReturnType the expressed return type by the enclosing method
or function | 5166 * @param expectedReturnType the expressed return type by the enclosing method
or function |
5166 * @return `true` if and only if an error code is generated on the passed node | 5167 * @return `true` if and only if an error code is generated on the passed node |
5167 * See [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]. | 5168 * See [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]. |
5168 */ | 5169 */ |
5169 bool _checkForReturnOfInvalidType(Expression returnExpression, | 5170 bool _checkForReturnOfInvalidType(Expression returnExpression, |
5170 DartType expectedReturnType) { | 5171 DartType expectedReturnType) { |
5171 if (_enclosingFunction == null) { | 5172 if (_enclosingFunction == null) { |
5172 return false; | 5173 return false; |
5173 } | 5174 } |
5174 DartType staticReturnType = getStaticType(returnExpression); | 5175 DartType staticReturnType = _computeReturnTypeForMethod(returnExpression); |
5175 if (expectedReturnType.isVoid) { | 5176 if (expectedReturnType.isVoid) { |
5176 if (staticReturnType.isVoid || | 5177 if (staticReturnType.isVoid || |
5177 staticReturnType.isDynamic || | 5178 staticReturnType.isDynamic || |
5178 staticReturnType.isBottom) { | 5179 staticReturnType.isBottom) { |
5179 return false; | 5180 return false; |
5180 } | 5181 } |
5181 _errorReporter.reportTypeErrorForNode( | 5182 _errorReporter.reportTypeErrorForNode( |
5182 StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, | 5183 StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, |
5183 returnExpression, | 5184 returnExpression, |
5184 [staticReturnType, expectedReturnType, _enclosingFunction.displayName]
); | 5185 [staticReturnType, expectedReturnType, _enclosingFunction.displayName]
); |
5185 return true; | 5186 return true; |
5186 } | 5187 } |
5187 if (_enclosingFunction.isAsynchronous && !_enclosingFunction.isGenerator) { | |
5188 // TODO(brianwilkerson) Figure out how to get the type "Future" so that we | |
5189 // can build the type we need to test against. | |
5190 // InterfaceType impliedType = "Future<" + flatten(staticReturnType)
+ ">" | |
5191 // if (impliedType.isAssignableTo(expectedReturnType)) { | |
5192 // return false; | |
5193 // } | |
5194 // errorReporter.reportTypeErrorForNode( | |
5195 // StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, | |
5196 // returnExpression, | |
5197 // impliedType, | |
5198 // expectedReturnType.getDisplayName(), | |
5199 // enclosingFunction.getDisplayName()); | |
5200 // return true; | |
5201 return false; | |
5202 } | |
5203 if (staticReturnType.isAssignableTo(expectedReturnType)) { | 5188 if (staticReturnType.isAssignableTo(expectedReturnType)) { |
5204 return false; | 5189 return false; |
5205 } | 5190 } |
5206 _errorReporter.reportTypeErrorForNode( | 5191 _errorReporter.reportTypeErrorForNode( |
5207 StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, | 5192 StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, |
5208 returnExpression, | 5193 returnExpression, |
5209 [staticReturnType, expectedReturnType, _enclosingFunction.displayName]); | 5194 [staticReturnType, expectedReturnType, _enclosingFunction.displayName]); |
5210 return true; | 5195 return true; |
5211 // TODO(brianwilkerson) Define a hint corresponding to the warning and | 5196 // TODO(brianwilkerson) Define a hint corresponding to the warning and |
5212 // report it if appropriate. | 5197 // report it if appropriate. |
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5782 _errorReporter.reportErrorForNode( | 5767 _errorReporter.reportErrorForNode( |
5783 CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, | 5768 CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, |
5784 interfaceNode, | 5769 interfaceNode, |
5785 [superType.displayName]); | 5770 [superType.displayName]); |
5786 } | 5771 } |
5787 } | 5772 } |
5788 // done | 5773 // done |
5789 return hasProblem; | 5774 return hasProblem; |
5790 } | 5775 } |
5791 | 5776 |
| 5777 DartType _computeReturnTypeForMethod(Expression returnExpression) { |
| 5778 // TODO(paulberry): do the right thing for generators. |
| 5779 if (returnExpression == null) { |
| 5780 if (_enclosingFunction.isAsynchronous) { |
| 5781 return _typeProvider.futureType.substitute4( |
| 5782 <DartType>[_typeProvider.nullType]); |
| 5783 } else { |
| 5784 return VoidTypeImpl.instance; |
| 5785 } |
| 5786 } |
| 5787 DartType staticReturnType = getStaticType(returnExpression); |
| 5788 if (staticReturnType != null && |
| 5789 _enclosingFunction.isAsynchronous && |
| 5790 staticReturnType.element != _typeProvider.futureType.element) { |
| 5791 return _typeProvider.futureType.substitute4(<DartType>[staticReturnType]); |
| 5792 } |
| 5793 return staticReturnType; |
| 5794 } |
| 5795 |
5792 /** | 5796 /** |
5793 * Return the error code that should be used when the given class references i
tself directly. | 5797 * Return the error code that should be used when the given class references i
tself directly. |
5794 * | 5798 * |
5795 * @param classElt the class that references itself | 5799 * @param classElt the class that references itself |
5796 * @return the error code that should be used | 5800 * @return the error code that should be used |
5797 */ | 5801 */ |
5798 ErrorCode _getBaseCaseErrorCode(ClassElement classElt) { | 5802 ErrorCode _getBaseCaseErrorCode(ClassElement classElt) { |
5799 InterfaceType supertype = classElt.supertype; | 5803 InterfaceType supertype = classElt.supertype; |
5800 if (supertype != null && _enclosingClass == supertype.element) { | 5804 if (supertype != null && _enclosingClass == supertype.element) { |
5801 return | 5805 return |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6225 toCheck.add(type.element); | 6229 toCheck.add(type.element); |
6226 // type arguments | 6230 // type arguments |
6227 if (type is InterfaceType) { | 6231 if (type is InterfaceType) { |
6228 InterfaceType interfaceType = type; | 6232 InterfaceType interfaceType = type; |
6229 for (DartType typeArgument in interfaceType.typeArguments) { | 6233 for (DartType typeArgument in interfaceType.typeArguments) { |
6230 _addTypeToCheck(typeArgument); | 6234 _addTypeToCheck(typeArgument); |
6231 } | 6235 } |
6232 } | 6236 } |
6233 } | 6237 } |
6234 } | 6238 } |
OLD | NEW |