| 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 |