Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(285)

Side by Side Diff: pkg/analyzer/lib/src/generated/error_verifier.dart

Issue 2653873002: fix #28141, fix super generic method bounds check (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698