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 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
839 TypeArgumentList typeArguments = node.typeArguments; | 839 TypeArgumentList typeArguments = node.typeArguments; |
840 if (typeArguments != null) { | 840 if (typeArguments != null) { |
841 if (node.constKeyword != null) { | 841 if (node.constKeyword != null) { |
842 NodeList<TypeName> arguments = typeArguments.arguments; | 842 NodeList<TypeName> arguments = typeArguments.arguments; |
843 if (arguments.length != 0) { | 843 if (arguments.length != 0) { |
844 _checkForInvalidTypeArgumentInConstTypedLiteral(arguments, | 844 _checkForInvalidTypeArgumentInConstTypedLiteral(arguments, |
845 CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST); | 845 CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST); |
846 } | 846 } |
847 } | 847 } |
848 _checkForExpectedOneListTypeArgument(node, typeArguments); | 848 _checkForExpectedOneListTypeArgument(node, typeArguments); |
849 _checkForListElementTypeNotAssignable(node, typeArguments); | |
850 } | 849 } |
| 850 |
| 851 _checkForListElementTypeNotAssignable(node); |
851 return super.visitListLiteral(node); | 852 return super.visitListLiteral(node); |
852 } | 853 } |
853 | 854 |
854 @override | 855 @override |
855 Object visitMapLiteral(MapLiteral node) { | 856 Object visitMapLiteral(MapLiteral node) { |
856 TypeArgumentList typeArguments = node.typeArguments; | 857 TypeArgumentList typeArguments = node.typeArguments; |
857 if (typeArguments != null) { | 858 if (typeArguments != null) { |
858 NodeList<TypeName> arguments = typeArguments.arguments; | 859 NodeList<TypeName> arguments = typeArguments.arguments; |
859 if (arguments.length != 0) { | 860 if (arguments.length != 0) { |
860 if (node.constKeyword != null) { | 861 if (node.constKeyword != null) { |
861 _checkForInvalidTypeArgumentInConstTypedLiteral(arguments, | 862 _checkForInvalidTypeArgumentInConstTypedLiteral(arguments, |
862 CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP); | 863 CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP); |
863 } | 864 } |
864 } | 865 } |
865 _checkExpectedTwoMapTypeArguments(typeArguments); | 866 _checkExpectedTwoMapTypeArguments(typeArguments); |
866 _checkForMapTypeNotAssignable(node, typeArguments); | |
867 } | 867 } |
| 868 |
| 869 _checkForMapTypeNotAssignable(node); |
868 _checkForNonConstMapAsExpressionStatement(node); | 870 _checkForNonConstMapAsExpressionStatement(node); |
869 return super.visitMapLiteral(node); | 871 return super.visitMapLiteral(node); |
870 } | 872 } |
871 | 873 |
872 @override | 874 @override |
873 Object visitMethodDeclaration(MethodDeclaration node) { | 875 Object visitMethodDeclaration(MethodDeclaration node) { |
874 ExecutableElement previousFunction = _enclosingFunction; | 876 ExecutableElement previousFunction = _enclosingFunction; |
875 try { | 877 try { |
876 _isInStaticMethod = node.isStatic; | 878 _isInStaticMethod = node.isStatic; |
877 _enclosingFunction = node.element; | 879 _enclosingFunction = node.element; |
(...skipping 3153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4031 for (TypeName typeName in arguments) { | 4033 for (TypeName typeName in arguments) { |
4032 if (typeName.type is TypeParameterType) { | 4034 if (typeName.type is TypeParameterType) { |
4033 _errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name]); | 4035 _errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name]); |
4034 foundError = true; | 4036 foundError = true; |
4035 } | 4037 } |
4036 } | 4038 } |
4037 return foundError; | 4039 return foundError; |
4038 } | 4040 } |
4039 | 4041 |
4040 /** | 4042 /** |
4041 * Verify that the elements given list [literal] are subtypes of the specified | 4043 * Verify that the elements given list [literal] are subtypes of the list's |
4042 * element type. The [typeArguments] are the type arguments. | 4044 * static type. |
4043 * | 4045 * |
4044 * See [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], and | 4046 * See [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], and |
4045 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]. | 4047 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]. |
4046 */ | 4048 */ |
4047 bool _checkForListElementTypeNotAssignable( | 4049 void _checkForListElementTypeNotAssignable(ListLiteral literal) { |
4048 ListLiteral literal, TypeArgumentList typeArguments) { | 4050 // Determine the list's element type. We base this on the static type and |
4049 NodeList<TypeName> typeNames = typeArguments.arguments; | 4051 // not the literal's type arguments because in strong mode, the type |
4050 if (typeNames.length < 1) { | 4052 // arguments may be inferred. |
4051 return false; | 4053 DartType listType = literal.staticType; |
4052 } | 4054 assert(listType is InterfaceTypeImpl); |
4053 DartType listElementType = typeNames[0].type; | 4055 |
| 4056 List<DartType> typeArguments = |
| 4057 (listType as InterfaceTypeImpl).typeArguments; |
| 4058 assert(typeArguments.length == 1); |
| 4059 |
| 4060 DartType listElementType = typeArguments[0]; |
| 4061 |
4054 // Check every list element. | 4062 // Check every list element. |
4055 bool hasProblems = false; | |
4056 for (Expression element in literal.elements) { | 4063 for (Expression element in literal.elements) { |
4057 if (literal.constKeyword != null) { | 4064 if (literal.constKeyword != null) { |
4058 // TODO(paulberry): this error should be based on the actual type of the | 4065 // TODO(paulberry): this error should be based on the actual type of the |
4059 // list element, not the static type. See dartbug.com/21119. | 4066 // list element, not the static type. See dartbug.com/21119. |
4060 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( | 4067 _checkForArgumentTypeNotAssignableWithExpectedTypes( |
4061 element, | 4068 element, |
4062 listElementType, | 4069 listElementType, |
4063 CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) { | 4070 CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE); |
4064 hasProblems = true; | |
4065 } | |
4066 } | 4071 } |
4067 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( | 4072 _checkForArgumentTypeNotAssignableWithExpectedTypes(element, |
4068 element, | 4073 listElementType, StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE); |
4069 listElementType, | |
4070 StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) { | |
4071 hasProblems = true; | |
4072 } | |
4073 } | 4074 } |
4074 return hasProblems; | |
4075 } | 4075 } |
4076 | 4076 |
4077 /** | 4077 /** |
4078 * Verify that the key/value of entries of the given map [literal] are | 4078 * Verify that the key/value of entries of the given map [literal] are |
4079 * subtypes of the key/value types specified in the type arguments. The | 4079 * subtypes of the map's static type. |
4080 * [typeArguments] are the type arguments. | |
4081 * | 4080 * |
4082 * See [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], | 4081 * See [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], |
4083 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], | 4082 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], |
4084 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and | 4083 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and |
4085 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. | 4084 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. |
4086 */ | 4085 */ |
4087 bool _checkForMapTypeNotAssignable( | 4086 void _checkForMapTypeNotAssignable(MapLiteral literal) { |
4088 MapLiteral literal, TypeArgumentList typeArguments) { | 4087 // Determine the map's key and value types. We base this on the static type |
4089 // Prepare maps key/value types. | 4088 // and not the literal's type arguments because in strong mode, the type |
4090 NodeList<TypeName> typeNames = typeArguments.arguments; | 4089 // arguments may be inferred. |
4091 if (typeNames.length < 2) { | 4090 DartType mapType = literal.staticType; |
4092 return false; | 4091 assert(mapType is InterfaceTypeImpl); |
4093 } | 4092 |
4094 DartType keyType = typeNames[0].type; | 4093 List<DartType> typeArguments = |
4095 DartType valueType = typeNames[1].type; | 4094 (mapType as InterfaceTypeImpl).typeArguments; |
4096 // Check every map entry. | 4095 assert(typeArguments.length == 2); |
4097 bool hasProblems = false; | 4096 DartType keyType = typeArguments[0]; |
| 4097 DartType valueType = typeArguments[1]; |
| 4098 |
4098 NodeList<MapLiteralEntry> entries = literal.entries; | 4099 NodeList<MapLiteralEntry> entries = literal.entries; |
4099 for (MapLiteralEntry entry in entries) { | 4100 for (MapLiteralEntry entry in entries) { |
4100 Expression key = entry.key; | 4101 Expression key = entry.key; |
4101 Expression value = entry.value; | 4102 Expression value = entry.value; |
4102 if (literal.constKeyword != null) { | 4103 if (literal.constKeyword != null) { |
4103 // TODO(paulberry): this error should be based on the actual type of the | 4104 // TODO(paulberry): this error should be based on the actual type of the |
4104 // list element, not the static type. See dartbug.com/21119. | 4105 // list element, not the static type. See dartbug.com/21119. |
4105 if (_checkForArgumentTypeNotAssignableWithExpectedTypes(key, keyType, | 4106 _checkForArgumentTypeNotAssignableWithExpectedTypes(key, keyType, |
4106 CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE)) { | 4107 CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE); |
4107 hasProblems = true; | 4108 _checkForArgumentTypeNotAssignableWithExpectedTypes( |
4108 } | |
4109 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( | |
4110 value, | 4109 value, |
4111 valueType, | 4110 valueType, |
4112 CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) { | 4111 CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE); |
4113 hasProblems = true; | |
4114 } | |
4115 } | 4112 } |
4116 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( | 4113 _checkForArgumentTypeNotAssignableWithExpectedTypes( |
4117 key, keyType, StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE)) { | 4114 key, keyType, StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE); |
4118 hasProblems = true; | 4115 _checkForArgumentTypeNotAssignableWithExpectedTypes( |
4119 } | 4116 value, valueType, StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE); |
4120 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( | |
4121 value, valueType, StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) { | |
4122 hasProblems = true; | |
4123 } | |
4124 } | 4117 } |
4125 return hasProblems; | |
4126 } | 4118 } |
4127 | 4119 |
4128 /** | 4120 /** |
4129 * Verify that the [_enclosingClass] does not define members with the same nam
e | 4121 * Verify that the [_enclosingClass] does not define members with the same nam
e |
4130 * as the enclosing class. | 4122 * as the enclosing class. |
4131 * | 4123 * |
4132 * See [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]. | 4124 * See [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]. |
4133 */ | 4125 */ |
4134 bool _checkForMemberWithClassName() { | 4126 bool _checkForMemberWithClassName() { |
4135 if (_enclosingClass == null) { | 4127 if (_enclosingClass == null) { |
(...skipping 1551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5687 SimpleIdentifier variable = node.identifier != null | 5679 SimpleIdentifier variable = node.identifier != null |
5688 ? node.identifier | 5680 ? node.identifier |
5689 : node.loopVariable.identifier; | 5681 : node.loopVariable.identifier; |
5690 DartType variableType = getStaticType(variable); | 5682 DartType variableType = getStaticType(variable); |
5691 | 5683 |
5692 DartType loopType = node.awaitKeyword != null | 5684 DartType loopType = node.awaitKeyword != null |
5693 ? _typeProvider.streamType | 5685 ? _typeProvider.streamType |
5694 : _typeProvider.iterableType; | 5686 : _typeProvider.iterableType; |
5695 | 5687 |
5696 // Use an explicit string instead of [loopType] to remove the "<E>". | 5688 // Use an explicit string instead of [loopType] to remove the "<E>". |
5697 String loopTypeName = node.awaitKeyword != null | 5689 String loopTypeName = node.awaitKeyword != null ? "Stream" : "Iterable"; |
5698 ? "Stream" | |
5699 : "Iterable"; | |
5700 | 5690 |
5701 // The object being iterated has to implement Iterable<T> for some T that | 5691 // The object being iterated has to implement Iterable<T> for some T that |
5702 // is assignable to the variable's type. | 5692 // is assignable to the variable's type. |
5703 // TODO(rnystrom): Move this into mostSpecificTypeArgument()? | 5693 // TODO(rnystrom): Move this into mostSpecificTypeArgument()? |
5704 iterableType = iterableType.resolveToBound(_typeProvider.objectType); | 5694 iterableType = iterableType.resolveToBound(_typeProvider.objectType); |
5705 DartType bestIterableType = _typeSystem.mostSpecificTypeArgument( | 5695 DartType bestIterableType = |
5706 iterableType, loopType); | 5696 _typeSystem.mostSpecificTypeArgument(iterableType, loopType); |
5707 if (bestIterableType == null) { | 5697 if (bestIterableType == null) { |
5708 _errorReporter.reportTypeErrorForNode( | 5698 _errorReporter.reportTypeErrorForNode( |
5709 StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE, | 5699 StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE, |
5710 node, | 5700 node.iterable, |
5711 [iterableType, loopTypeName]); | 5701 [iterableType, loopTypeName]); |
5712 } else if (!_typeSystem.isAssignableTo(bestIterableType, variableType)) { | 5702 } else if (!_typeSystem.isAssignableTo(bestIterableType, variableType)) { |
5713 _errorReporter.reportTypeErrorForNode( | 5703 _errorReporter.reportTypeErrorForNode( |
5714 StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE, | 5704 StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE, |
5715 node, | 5705 node.iterable, |
5716 [iterableType, loopTypeName, variableType]); | 5706 [iterableType, loopTypeName, variableType]); |
5717 } | 5707 } |
5718 } | 5708 } |
5719 | 5709 |
5720 /** | 5710 /** |
5721 * Check for a type mis-match between the yielded type and the declared | 5711 * Check for a type mis-match between the yielded type and the declared |
5722 * return type of a generator function. | 5712 * return type of a generator function. |
5723 * | 5713 * |
5724 * This method should only be called in generator functions. | 5714 * This method should only be called in generator functions. |
5725 */ | 5715 */ |
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6324 class _InvocationCollector extends RecursiveAstVisitor { | 6314 class _InvocationCollector extends RecursiveAstVisitor { |
6325 final List<String> superCalls = <String>[]; | 6315 final List<String> superCalls = <String>[]; |
6326 | 6316 |
6327 @override | 6317 @override |
6328 visitMethodInvocation(MethodInvocation node) { | 6318 visitMethodInvocation(MethodInvocation node) { |
6329 if (node.target is SuperExpression) { | 6319 if (node.target is SuperExpression) { |
6330 superCalls.add(node.methodName.name); | 6320 superCalls.add(node.methodName.name); |
6331 } | 6321 } |
6332 } | 6322 } |
6333 } | 6323 } |
OLD | NEW |