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 analyzer.src.generated.error_verifier; | 5 library analyzer.src.generated.error_verifier; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 import "dart:math" as math; | 8 import "dart:math" as math; |
9 | 9 |
10 import 'package:analyzer/dart/ast/ast.dart'; | 10 import 'package:analyzer/dart/ast/ast.dart'; |
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
682 | 682 |
683 @override | 683 @override |
684 Object visitForStatement(ForStatement node) { | 684 Object visitForStatement(ForStatement node) { |
685 if (node.condition != null) { | 685 if (node.condition != null) { |
686 _checkForNonBoolCondition(node.condition); | 686 _checkForNonBoolCondition(node.condition); |
687 } | 687 } |
688 return super.visitForStatement(node); | 688 return super.visitForStatement(node); |
689 } | 689 } |
690 | 690 |
691 @override | 691 @override |
692 Object visitForEachStatement(ForEachStatement node) { | |
693 _checkForInIterable(node); | |
694 return super.visitForEachStatement(node); | |
695 } | |
696 | |
697 @override | |
692 Object visitFunctionDeclaration(FunctionDeclaration node) { | 698 Object visitFunctionDeclaration(FunctionDeclaration node) { |
693 ExecutableElement outerFunction = _enclosingFunction; | 699 ExecutableElement outerFunction = _enclosingFunction; |
694 try { | 700 try { |
695 SimpleIdentifier identifier = node.name; | 701 SimpleIdentifier identifier = node.name; |
696 String methodName = ""; | 702 String methodName = ""; |
697 if (identifier != null) { | 703 if (identifier != null) { |
698 methodName = identifier.name; | 704 methodName = identifier.name; |
699 } | 705 } |
700 _enclosingFunction = node.element; | 706 _enclosingFunction = node.element; |
701 TypeName returnType = node.returnType; | 707 TypeName returnType = node.returnType; |
(...skipping 4954 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5656 parameters[0].kind != ParameterKind.REQUIRED) { | 5662 parameters[0].kind != ParameterKind.REQUIRED) { |
5657 _errorReporter.reportErrorForNode( | 5663 _errorReporter.reportErrorForNode( |
5658 CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER, | 5664 CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER, |
5659 setterName); | 5665 setterName); |
5660 return true; | 5666 return true; |
5661 } | 5667 } |
5662 return false; | 5668 return false; |
5663 } | 5669 } |
5664 | 5670 |
5665 /** | 5671 /** |
5672 * Check for a type mis-match between the iterable expression and the | |
5673 * assigned variable in a for-in statement. | |
5674 */ | |
5675 void _checkForInIterable(ForEachStatement node) { | |
5676 // Ignore malformed for statements. | |
5677 if (node.identifier == null && node.loopVariable == null) { | |
5678 return; | |
5679 } | |
5680 | |
5681 DartType iterableType = getStaticType(node.iterable); | |
5682 if (iterableType.isDynamic) { | |
5683 return; | |
5684 } | |
5685 | |
5686 // The type of the loop variable. | |
5687 SimpleIdentifier variable = node.identifier != null | |
Jennifer Messerly
2016/03/08 19:14:11
probably not worth it, but this could be:
nod
| |
5688 ? node.identifier | |
5689 : node.loopVariable.identifier; | |
5690 DartType variableType = getStaticType(variable); | |
5691 | |
5692 DartType loopType = node.awaitKeyword != null | |
5693 ? _typeProvider.streamType | |
5694 : _typeProvider.iterableType; | |
5695 | |
5696 // Use an explicit string instead of [loopType] to remove the "<E>". | |
5697 String loopTypeName = node.awaitKeyword != null | |
Jennifer Messerly
2016/03/08 19:14:11
do you need this? Isn't this just: `loopType.name`
| |
5698 ? "Stream" | |
5699 : "Iterable"; | |
5700 | |
5701 // The object being iterated has to implement Iterable<T> for some T that | |
5702 // is assignable to the variable's type. | |
5703 // TODO(rnystrom): Move this into mostSpecificTypeArgument()? | |
Jennifer Messerly
2016/03/08 19:14:11
yeah, I think that makes sense.
| |
5704 iterableType = iterableType.resolveToBound(_typeProvider.objectType); | |
5705 DartType bestIterableType = _typeSystem.mostSpecificTypeArgument( | |
5706 iterableType, loopType); | |
5707 if (bestIterableType == null) { | |
5708 _errorReporter.reportTypeErrorForNode( | |
5709 StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE, | |
5710 node, | |
5711 [iterableType, loopTypeName]); | |
5712 } else if (!_typeSystem.isAssignableTo(bestIterableType, variableType)) { | |
5713 _errorReporter.reportTypeErrorForNode( | |
5714 StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE, | |
5715 node, | |
5716 [iterableType, loopTypeName, variableType]); | |
5717 } | |
5718 } | |
5719 | |
5720 /** | |
5666 * Check for a type mis-match between the yielded type and the declared | 5721 * Check for a type mis-match between the yielded type and the declared |
5667 * return type of a generator function. | 5722 * return type of a generator function. |
5668 * | 5723 * |
5669 * This method should only be called in generator functions. | 5724 * This method should only be called in generator functions. |
5670 */ | 5725 */ |
5671 bool _checkForYieldOfInvalidType( | 5726 void _checkForYieldOfInvalidType( |
Brian Wilkerson
2016/03/08 01:12:12
fyi: I don't know that it matters, but the origina
Bob Nystrom
2016/03/08 19:00:50
I'm not sure about the other methods, but this one
| |
5672 Expression yieldExpression, bool isYieldEach) { | 5727 Expression yieldExpression, bool isYieldEach) { |
5673 assert(_inGenerator); | 5728 assert(_inGenerator); |
5674 if (_enclosingFunction == null) { | 5729 if (_enclosingFunction == null) { |
5675 return false; | 5730 return; |
5676 } | 5731 } |
5677 DartType declaredReturnType = _enclosingFunction.returnType; | 5732 DartType declaredReturnType = _enclosingFunction.returnType; |
5678 DartType staticYieldedType = getStaticType(yieldExpression); | 5733 DartType staticYieldedType = getStaticType(yieldExpression); |
5679 DartType impliedReturnType; | 5734 DartType impliedReturnType; |
5680 if (isYieldEach) { | 5735 if (isYieldEach) { |
5681 impliedReturnType = staticYieldedType; | 5736 impliedReturnType = staticYieldedType; |
5682 } else if (_enclosingFunction.isAsynchronous) { | 5737 } else if (_enclosingFunction.isAsynchronous) { |
5683 impliedReturnType = | 5738 impliedReturnType = |
5684 _typeProvider.streamType.instantiate(<DartType>[staticYieldedType]); | 5739 _typeProvider.streamType.instantiate(<DartType>[staticYieldedType]); |
5685 } else { | 5740 } else { |
5686 impliedReturnType = | 5741 impliedReturnType = |
5687 _typeProvider.iterableType.instantiate(<DartType>[staticYieldedType]); | 5742 _typeProvider.iterableType.instantiate(<DartType>[staticYieldedType]); |
5688 } | 5743 } |
5689 if (!_typeSystem.isAssignableTo(impliedReturnType, declaredReturnType)) { | 5744 if (!_typeSystem.isAssignableTo(impliedReturnType, declaredReturnType)) { |
5690 _errorReporter.reportTypeErrorForNode( | 5745 _errorReporter.reportTypeErrorForNode( |
5691 StaticTypeWarningCode.YIELD_OF_INVALID_TYPE, | 5746 StaticTypeWarningCode.YIELD_OF_INVALID_TYPE, |
5692 yieldExpression, | 5747 yieldExpression, |
5693 [impliedReturnType, declaredReturnType]); | 5748 [impliedReturnType, declaredReturnType]); |
5694 return true; | 5749 return; |
5695 } | 5750 } |
5696 if (isYieldEach) { | 5751 if (isYieldEach) { |
5697 // Since the declared return type might have been "dynamic", we need to | 5752 // Since the declared return type might have been "dynamic", we need to |
5698 // also check that the implied return type is assignable to generic | 5753 // also check that the implied return type is assignable to generic |
5699 // Stream/Iterable. | 5754 // Stream/Iterable. |
5700 DartType requiredReturnType; | 5755 DartType requiredReturnType; |
5701 if (_enclosingFunction.isAsynchronous) { | 5756 if (_enclosingFunction.isAsynchronous) { |
5702 requiredReturnType = _typeProvider.streamDynamicType; | 5757 requiredReturnType = _typeProvider.streamDynamicType; |
5703 } else { | 5758 } else { |
5704 requiredReturnType = _typeProvider.iterableDynamicType; | 5759 requiredReturnType = _typeProvider.iterableDynamicType; |
5705 } | 5760 } |
5706 if (!_typeSystem.isAssignableTo(impliedReturnType, requiredReturnType)) { | 5761 if (!_typeSystem.isAssignableTo(impliedReturnType, requiredReturnType)) { |
5707 _errorReporter.reportTypeErrorForNode( | 5762 _errorReporter.reportTypeErrorForNode( |
5708 StaticTypeWarningCode.YIELD_OF_INVALID_TYPE, | 5763 StaticTypeWarningCode.YIELD_OF_INVALID_TYPE, |
5709 yieldExpression, | 5764 yieldExpression, |
5710 [impliedReturnType, requiredReturnType]); | 5765 [impliedReturnType, requiredReturnType]); |
5711 return true; | 5766 return; |
5712 } | 5767 } |
5713 } | 5768 } |
5714 return false; | |
5715 } | 5769 } |
5716 | 5770 |
5717 /** | 5771 /** |
5718 * Verify that if the given class [declaration] implements the class Function | 5772 * Verify that if the given class [declaration] implements the class Function |
5719 * that it has a concrete implementation of the call method. | 5773 * that it has a concrete implementation of the call method. |
5720 * | 5774 * |
5721 * See [StaticWarningCode.FUNCTION_WITHOUT_CALL]. | 5775 * See [StaticWarningCode.FUNCTION_WITHOUT_CALL]. |
5722 */ | 5776 */ |
5723 bool _checkImplementsFunctionWithoutCall(ClassDeclaration declaration) { | 5777 bool _checkImplementsFunctionWithoutCall(ClassDeclaration declaration) { |
5724 if (declaration.isAbstract) { | 5778 if (declaration.isAbstract) { |
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6270 class _InvocationCollector extends RecursiveAstVisitor { | 6324 class _InvocationCollector extends RecursiveAstVisitor { |
6271 final List<String> superCalls = <String>[]; | 6325 final List<String> superCalls = <String>[]; |
6272 | 6326 |
6273 @override | 6327 @override |
6274 visitMethodInvocation(MethodInvocation node) { | 6328 visitMethodInvocation(MethodInvocation node) { |
6275 if (node.target is SuperExpression) { | 6329 if (node.target is SuperExpression) { |
6276 superCalls.add(node.methodName.name); | 6330 superCalls.add(node.methodName.name); |
6277 } | 6331 } |
6278 } | 6332 } |
6279 } | 6333 } |
OLD | NEW |