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 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
814 | 814 |
815 @override | 815 @override |
816 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { | 816 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
817 Expression functionExpression = node.function; | 817 Expression functionExpression = node.function; |
818 DartType expressionType = functionExpression.staticType; | 818 DartType expressionType = functionExpression.staticType; |
819 if (!_isFunctionType(expressionType)) { | 819 if (!_isFunctionType(expressionType)) { |
820 _errorReporter.reportErrorForNode( | 820 _errorReporter.reportErrorForNode( |
821 StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, | 821 StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, |
822 functionExpression); | 822 functionExpression); |
823 } else if (expressionType is FunctionType) { | 823 } else if (expressionType is FunctionType) { |
824 _checkTypeArguments(expressionType.element, node.typeArguments); | 824 _checkTypeArguments(node); |
825 } | 825 } |
826 _checkForImplicitDynamicInvoke(node); | 826 _checkForImplicitDynamicInvoke(node); |
827 return super.visitFunctionExpressionInvocation(node); | 827 return super.visitFunctionExpressionInvocation(node); |
828 } | 828 } |
829 | 829 |
830 @override | 830 @override |
831 Object visitFunctionTypeAlias(FunctionTypeAlias node) { | 831 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
832 _checkForBuiltInIdentifierAsName( | 832 _checkForBuiltInIdentifierAsName( |
833 node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME); | 833 node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME); |
834 _checkForDefaultValueInFunctionTypeAlias(node); | 834 _checkForDefaultValueInFunctionTypeAlias(node); |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1025 Object visitMethodInvocation(MethodInvocation node) { | 1025 Object visitMethodInvocation(MethodInvocation node) { |
1026 Expression target = node.realTarget; | 1026 Expression target = node.realTarget; |
1027 SimpleIdentifier methodName = node.methodName; | 1027 SimpleIdentifier methodName = node.methodName; |
1028 if (target != null) { | 1028 if (target != null) { |
1029 ClassElement typeReference = ElementResolver.getTypeReference(target); | 1029 ClassElement typeReference = ElementResolver.getTypeReference(target); |
1030 _checkForStaticAccessToInstanceMember(typeReference, methodName); | 1030 _checkForStaticAccessToInstanceMember(typeReference, methodName); |
1031 _checkForInstanceAccessToStaticMember(typeReference, methodName); | 1031 _checkForInstanceAccessToStaticMember(typeReference, methodName); |
1032 } else { | 1032 } else { |
1033 _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName); | 1033 _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName); |
1034 } | 1034 } |
1035 _checkTypeArguments( | 1035 _checkTypeArguments(node); |
1036 node.methodName.staticElement, node.typeArguments, target?.staticType); | |
1037 _checkForImplicitDynamicInvoke(node); | 1036 _checkForImplicitDynamicInvoke(node); |
1038 return super.visitMethodInvocation(node); | 1037 return super.visitMethodInvocation(node); |
1039 } | 1038 } |
1040 | 1039 |
1041 @override | 1040 @override |
1042 Object visitNativeClause(NativeClause node) { | 1041 Object visitNativeClause(NativeClause node) { |
1043 // TODO(brianwilkerson) Figure out the right rule for when 'native' is | 1042 // TODO(brianwilkerson) Figure out the right rule for when 'native' is |
1044 // allowed. | 1043 // allowed. |
1045 if (!_isInSystemLibrary) { | 1044 if (!_isInSystemLibrary) { |
1046 _errorReporter.reportErrorForNode( | 1045 _errorReporter.reportErrorForNode( |
(...skipping 5102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6149 } | 6148 } |
6150 } | 6149 } |
6151 } | 6150 } |
6152 | 6151 |
6153 /** | 6152 /** |
6154 * Verify that the given [typeArguments] are all within their bounds, as | 6153 * Verify that the given [typeArguments] are all within their bounds, as |
6155 * defined by the given [element]. | 6154 * defined by the given [element]. |
6156 * | 6155 * |
6157 * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]. | 6156 * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]. |
6158 */ | 6157 */ |
6159 void _checkTypeArguments(Element element, TypeArgumentList typeArguments, | 6158 void _checkTypeArguments(InvocationExpression node) { |
Jennifer Messerly
2017/01/24 03:09:16
rewrote this to simplify
in general -- when we st
| |
6160 [DartType targetType]) { | 6159 NodeList<TypeAnnotation> typeArgumentList = node.typeArguments?.arguments; |
6161 if (element == null || typeArguments == null) { | 6160 if (typeArgumentList == null) { |
6162 return; | 6161 return; |
6163 } | 6162 } |
6164 void reportError(TypeAnnotation argument, DartType argumentType, | |
6165 DartType parameterType) { | |
6166 _errorReporter.reportTypeErrorForNode( | |
6167 StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, | |
6168 argument, | |
6169 [argumentType, parameterType]); | |
6170 } | |
6171 | 6163 |
6172 if (element is FunctionTypedElement) { | 6164 var genericType = node.function.staticType; |
6173 _checkTypeArgumentsAgainstBounds( | 6165 var instantiatedType = node.staticInvokeType; |
6174 element.typeParameters, typeArguments, targetType, reportError); | 6166 if (genericType is FunctionType && instantiatedType is FunctionType) { |
6175 } else if (element is ClassElement) { | 6167 var fnTypeParams = |
6176 _checkTypeArgumentsAgainstBounds( | 6168 TypeParameterTypeImpl.getTypes(genericType.typeFormals); |
6177 element.typeParameters, typeArguments, targetType, reportError); | 6169 var typeArgs = typeArgumentList.map((t) => t.type).toList(); |
6178 } else if (element is ParameterElement || element is LocalVariableElement) { | |
6179 // TODO(brianwilkerson) Implement this case | |
6180 } else { | |
6181 print('Unhandled element type: ${element.runtimeType}'); | |
6182 } | |
6183 } | |
6184 | 6170 |
6185 void _checkTypeArgumentsAgainstBounds( | 6171 for (int i = 0, len = math.min(typeArgs.length, fnTypeParams.length); |
6186 List<TypeParameterElement> typeParameters, | 6172 i < len; |
6187 TypeArgumentList typeArgumentList, | 6173 i++) { |
6188 DartType targetType, | 6174 // Check the `extends` clause for the type parameter, if any. |
6189 void reportError(TypeAnnotation argument, DartType argumentType, | 6175 // |
6190 DartType parameterType)) { | 6176 // Also substitute to handle cases like this: |
6191 NodeList<TypeAnnotation> typeArguments = typeArgumentList.arguments; | 6177 // |
6192 int argumentsLength = typeArguments.length; | 6178 // <TFrom, TTo extends TFrom> |
6193 int maxIndex = math.min(typeParameters.length, argumentsLength); | 6179 // <TFrom, TTo extends Iterable<TFrom>> |
6194 | 6180 // <T extends Clonable<T>> |
6195 bool shouldSubstitute = | 6181 // |
6196 argumentsLength != 0 && argumentsLength == typeParameters.length; | 6182 DartType argType = typeArgs[i]; |
6197 List<DartType> argumentTypes = shouldSubstitute | 6183 DartType bound = |
6198 ? typeArguments.map((TypeAnnotation type) => type.type).toList() | 6184 fnTypeParams[i].bound.substitute2(typeArgs, fnTypeParams); |
6199 : null; | 6185 if (!_typeSystem.isSubtypeOf(argType, bound)) { |
6200 List<DartType> parameterTypes = shouldSubstitute | 6186 _errorReporter.reportTypeErrorForNode( |
6201 ? typeParameters | 6187 StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, |
6202 .map((TypeParameterElement element) => element.type) | 6188 typeArgumentList[i], |
6203 .toList() | 6189 [argType, bound]); |
6204 : null; | |
6205 List<DartType> targetTypeParameterTypes = null; | |
6206 for (int i = 0; i < maxIndex; i++) { | |
6207 TypeAnnotation argument = typeArguments[i]; | |
6208 DartType argType = argument.type; | |
6209 DartType boundType = typeParameters[i].bound; | |
6210 if (argType != null && boundType != null) { | |
6211 if (targetType is ParameterizedType) { | |
6212 if (targetTypeParameterTypes == null) { | |
6213 targetTypeParameterTypes = targetType.typeParameters | |
6214 .map((TypeParameterElement element) => element.type) | |
6215 .toList(); | |
6216 } | |
6217 boundType = boundType.substitute2( | |
6218 targetType.typeArguments, targetTypeParameterTypes); | |
6219 } | |
6220 if (shouldSubstitute) { | |
6221 boundType = boundType.substitute2(argumentTypes, parameterTypes); | |
6222 } | |
6223 if (!_typeSystem.isSubtypeOf(argType, boundType)) { | |
6224 reportError(argument, argType, boundType); | |
6225 } | 6190 } |
6226 } | 6191 } |
6227 } | 6192 } |
6228 } | 6193 } |
6229 | 6194 |
6230 void _checkUseOfCovariantInParameters(FormalParameterList node) { | 6195 void _checkUseOfCovariantInParameters(FormalParameterList node) { |
6231 AstNode parent = node.parent; | 6196 AstNode parent = node.parent; |
6232 if (parent is MethodDeclaration && !parent.isStatic) { | 6197 if (parent is MethodDeclaration && !parent.isStatic) { |
6233 return; | 6198 return; |
6234 } | 6199 } |
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7094 class _InvocationCollector extends RecursiveAstVisitor { | 7059 class _InvocationCollector extends RecursiveAstVisitor { |
7095 final List<String> superCalls = <String>[]; | 7060 final List<String> superCalls = <String>[]; |
7096 | 7061 |
7097 @override | 7062 @override |
7098 visitMethodInvocation(MethodInvocation node) { | 7063 visitMethodInvocation(MethodInvocation node) { |
7099 if (node.target is SuperExpression) { | 7064 if (node.target is SuperExpression) { |
7100 superCalls.add(node.methodName.name); | 7065 superCalls.add(node.methodName.name); |
7101 } | 7066 } |
7102 } | 7067 } |
7103 } | 7068 } |
OLD | NEW |