Chromium Code Reviews| 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 |