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

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

Issue 1977903002: Add support to the task model for the @required annotation (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Remove unused code Created 4 years, 7 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';
11 import 'package:analyzer/dart/ast/token.dart'; 11 import 'package:analyzer/dart/ast/token.dart';
12 import 'package:analyzer/dart/ast/visitor.dart'; 12 import 'package:analyzer/dart/ast/visitor.dart';
13 import 'package:analyzer/dart/element/element.dart'; 13 import 'package:analyzer/dart/element/element.dart';
14 import 'package:analyzer/dart/element/type.dart'; 14 import 'package:analyzer/dart/element/type.dart';
15 import 'package:analyzer/dart/element/visitor.dart'; 15 import 'package:analyzer/dart/element/visitor.dart';
16 import 'package:analyzer/src/dart/ast/utilities.dart'; 16 import 'package:analyzer/src/dart/ast/utilities.dart';
17 import 'package:analyzer/src/dart/element/element.dart'; 17 import 'package:analyzer/src/dart/element/element.dart';
18 import 'package:analyzer/src/dart/element/member.dart'; 18 import 'package:analyzer/src/dart/element/member.dart';
19 import 'package:analyzer/src/dart/element/type.dart'; 19 import 'package:analyzer/src/dart/element/type.dart';
20 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart'; 20 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
21 import 'package:analyzer/src/error/pending_error.dart';
21 import 'package:analyzer/src/generated/constant.dart'; 22 import 'package:analyzer/src/generated/constant.dart';
22 import 'package:analyzer/src/generated/element_resolver.dart'; 23 import 'package:analyzer/src/generated/element_resolver.dart';
23 import 'package:analyzer/src/generated/engine.dart'; 24 import 'package:analyzer/src/generated/engine.dart';
24 import 'package:analyzer/src/generated/error.dart'; 25 import 'package:analyzer/src/generated/error.dart';
25 import 'package:analyzer/src/generated/java_engine.dart'; 26 import 'package:analyzer/src/generated/java_engine.dart';
26 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode; 27 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
27 import 'package:analyzer/src/generated/resolver.dart'; 28 import 'package:analyzer/src/generated/resolver.dart';
28 import 'package:analyzer/src/generated/sdk.dart' show DartSdk, SdkLibrary; 29 import 'package:analyzer/src/generated/sdk.dart' show DartSdk, SdkLibrary;
30 import 'package:analyzer/src/generated/source.dart';
29 import 'package:analyzer/src/generated/utilities_dart.dart'; 31 import 'package:analyzer/src/generated/utilities_dart.dart';
32 import 'package:analyzer/src/task/dart.dart';
30 import 'package:analyzer/src/task/strong/info.dart' show StaticInfo; 33 import 'package:analyzer/src/task/strong/info.dart' show StaticInfo;
31 34
32 /** 35 /**
33 * A visitor used to traverse an AST structure looking for additional errors and 36 * A visitor used to traverse an AST structure looking for additional errors and
34 * warnings not covered by the parser and resolver. 37 * warnings not covered by the parser and resolver.
35 */ 38 */
36 class ErrorVerifier extends RecursiveAstVisitor<Object> { 39 class ErrorVerifier extends RecursiveAstVisitor<Object> {
37 /** 40 /**
38 * Static final string with value `"getter "` used in the construction of the 41 * Static final string with value `"getter "` used in the construction of the
39 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], and 42 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], and
(...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after
822 Object visitInstanceCreationExpression(InstanceCreationExpression node) { 825 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
823 bool wasInConstInstanceCreation = _isInConstInstanceCreation; 826 bool wasInConstInstanceCreation = _isInConstInstanceCreation;
824 _isInConstInstanceCreation = node.isConst; 827 _isInConstInstanceCreation = node.isConst;
825 try { 828 try {
826 ConstructorName constructorName = node.constructorName; 829 ConstructorName constructorName = node.constructorName;
827 TypeName typeName = constructorName.type; 830 TypeName typeName = constructorName.type;
828 DartType type = typeName.type; 831 DartType type = typeName.type;
829 if (type is InterfaceType) { 832 if (type is InterfaceType) {
830 _checkForConstOrNewWithAbstractClass(node, typeName, type); 833 _checkForConstOrNewWithAbstractClass(node, typeName, type);
831 _checkForConstOrNewWithEnum(node, typeName, type); 834 _checkForConstOrNewWithEnum(node, typeName, type);
832 _checkForMissingRequiredParam(
833 node.staticElement?.type, node.argumentList, node.constructorName);
834 if (_isInConstInstanceCreation) { 835 if (_isInConstInstanceCreation) {
835 _checkForConstWithNonConst(node); 836 _checkForConstWithNonConst(node);
836 _checkForConstWithUndefinedConstructor( 837 _checkForConstWithUndefinedConstructor(
837 node, constructorName, typeName); 838 node, constructorName, typeName);
838 _checkForConstWithTypeParameters(typeName); 839 _checkForConstWithTypeParameters(typeName);
839 _checkForConstDeferredClass(node, constructorName, typeName); 840 _checkForConstDeferredClass(node, constructorName, typeName);
840 } else { 841 } else {
841 _checkForNewWithUndefinedConstructor(node, constructorName, typeName); 842 _checkForNewWithUndefinedConstructor(node, constructorName, typeName);
842 } 843 }
843 } 844 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 Object visitMethodInvocation(MethodInvocation node) { 936 Object visitMethodInvocation(MethodInvocation node) {
936 Expression target = node.realTarget; 937 Expression target = node.realTarget;
937 SimpleIdentifier methodName = node.methodName; 938 SimpleIdentifier methodName = node.methodName;
938 if (target != null) { 939 if (target != null) {
939 ClassElement typeReference = ElementResolver.getTypeReference(target); 940 ClassElement typeReference = ElementResolver.getTypeReference(target);
940 _checkForStaticAccessToInstanceMember(typeReference, methodName); 941 _checkForStaticAccessToInstanceMember(typeReference, methodName);
941 _checkForInstanceAccessToStaticMember(typeReference, methodName); 942 _checkForInstanceAccessToStaticMember(typeReference, methodName);
942 } else { 943 } else {
943 _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName); 944 _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName);
944 } 945 }
945 _checkForMissingRequiredParam(
946 node.staticInvokeType, node.argumentList, methodName);
947 _checkTypeArguments( 946 _checkTypeArguments(
948 node.methodName.staticElement, node.typeArguments, target?.staticType); 947 node.methodName.staticElement, node.typeArguments, target?.staticType);
949 return super.visitMethodInvocation(node); 948 return super.visitMethodInvocation(node);
950 } 949 }
951 950
952 @override 951 @override
953 Object visitNativeClause(NativeClause node) { 952 Object visitNativeClause(NativeClause node) {
954 // TODO(brianwilkerson) Figure out the right rule for when 'native' is 953 // TODO(brianwilkerson) Figure out the right rule for when 'native' is
955 // allowed. 954 // allowed.
956 if (!_isInSystemLibrary) { 955 if (!_isInSystemLibrary) {
(...skipping 3282 matching lines...) Expand 10 before | Expand all | Expand 10 after
4239 void _checkForMissingJSLibAnnotation(Annotation node) { 4238 void _checkForMissingJSLibAnnotation(Annotation node) {
4240 if (node.elementAnnotation?.isJS ?? false) { 4239 if (node.elementAnnotation?.isJS ?? false) {
4241 Element element = ElementLocator.locate(node.parent); 4240 Element element = ElementLocator.locate(node.parent);
4242 if (element?.library?.isJS != true) { 4241 if (element?.library?.isJS != true) {
4243 _errorReporter.reportErrorForNode( 4242 _errorReporter.reportErrorForNode(
4244 HintCode.MISSING_JS_LIB_ANNOTATION, node, [element.name]); 4243 HintCode.MISSING_JS_LIB_ANNOTATION, node, [element.name]);
4245 } 4244 }
4246 } 4245 }
4247 } 4246 }
4248 4247
4249 void _checkForMissingRequiredParam(
4250 DartType type, ArgumentList argumentList, AstNode node) {
4251 if (type is FunctionType) {
4252 List<ParameterElement> parameters = type.parameters;
4253 for (ParameterElement param in parameters) {
4254 if (param.parameterKind == ParameterKind.NAMED) {
4255 ElementAnnotationImpl annotation = _getRequiredAnnotation(param);
4256 if (annotation != null) {
4257 String paramName = param.name;
4258 if (!_containsNamedExpression(argumentList, paramName)) {
4259 DartObject constantValue = annotation.constantValue;
4260 String reason =
4261 constantValue?.getField('reason')?.toStringValue();
4262 if (reason != null) {
4263 _errorReporter.reportErrorForNode(
4264 HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS,
4265 node,
4266 [paramName, reason]);
4267 } else {
4268 _errorReporter.reportErrorForNode(
4269 HintCode.MISSING_REQUIRED_PARAM, node, [paramName]);
4270 }
4271 }
4272 }
4273 }
4274 }
4275 }
4276 }
4277
4278 /** 4248 /**
4279 * Verify that the given function [body] does not contain return statements 4249 * Verify that the given function [body] does not contain return statements
4280 * that both have and do not have return values. 4250 * that both have and do not have return values.
4281 * 4251 *
4282 * See [StaticWarningCode.MIXED_RETURN_TYPES]. 4252 * See [StaticWarningCode.MIXED_RETURN_TYPES].
4283 */ 4253 */
4284 void _checkForMixedReturns(BlockFunctionBody body) { 4254 void _checkForMixedReturns(BlockFunctionBody body) {
4285 if (_hasReturnWithoutValue) { 4255 if (_hasReturnWithoutValue) {
4286 return; 4256 return;
4287 } 4257 }
(...skipping 1466 matching lines...) Expand 10 before | Expand all | Expand 10 after
5754 } 5724 }
5755 } 5725 }
5756 DartType staticReturnType = getStaticType(returnExpression); 5726 DartType staticReturnType = getStaticType(returnExpression);
5757 if (staticReturnType != null && _enclosingFunction.isAsynchronous) { 5727 if (staticReturnType != null && _enclosingFunction.isAsynchronous) {
5758 return _typeProvider.futureType.instantiate( 5728 return _typeProvider.futureType.instantiate(
5759 <DartType>[staticReturnType.flattenFutures(_typeSystem)]); 5729 <DartType>[staticReturnType.flattenFutures(_typeSystem)]);
5760 } 5730 }
5761 return staticReturnType; 5731 return staticReturnType;
5762 } 5732 }
5763 5733
5764 bool _containsNamedExpression(ArgumentList args, String name) {
5765 for (Expression expression in args.arguments) {
5766 if (expression is NamedExpression) {
5767 if (expression.name.label.name == name) {
5768 return true;
5769 }
5770 }
5771 }
5772 return false;
5773 }
5774
5775 bool _expressionIsAssignableAtType(Expression expression, 5734 bool _expressionIsAssignableAtType(Expression expression,
5776 DartType actualStaticType, DartType expectedStaticType) { 5735 DartType actualStaticType, DartType expectedStaticType) {
5777 bool concrete = 5736 bool concrete =
5778 _options.strongMode && StaticInfo.isKnownFunction(expression); 5737 _options.strongMode && StaticInfo.isKnownFunction(expression);
5779 if (concrete) { 5738 if (concrete) {
5780 actualStaticType = 5739 actualStaticType =
5781 _typeSystem.typeToConcreteType(_typeProvider, actualStaticType); 5740 _typeSystem.typeToConcreteType(_typeProvider, actualStaticType);
5782 // TODO(leafp): Move the Downcast functionality here. 5741 // TODO(leafp): Move the Downcast functionality here.
5783 // TODO(leafp): Support strict downcasts 5742 // TODO(leafp): Support strict downcasts
5784 } 5743 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
5858 } 5817 }
5859 5818
5860 ClassElement classElement = 5819 ClassElement classElement =
5861 member.getAncestor((element) => element is ClassElement); 5820 member.getAncestor((element) => element is ClassElement);
5862 if (classElement == null) { 5821 if (classElement == null) {
5863 return null; 5822 return null;
5864 } 5823 }
5865 return _inheritanceManager.lookupInheritance(classElement, member.name); 5824 return _inheritanceManager.lookupInheritance(classElement, member.name);
5866 } 5825 }
5867 5826
5868 ElementAnnotationImpl _getRequiredAnnotation(ParameterElement param) => param
5869 .metadata
5870 .firstWhere((ElementAnnotation e) => e.isRequired, orElse: () => null);
5871
5872 /** 5827 /**
5873 * Return the type of the first and only parameter of the given [setter]. 5828 * Return the type of the first and only parameter of the given [setter].
5874 */ 5829 */
5875 DartType _getSetterType(PropertyAccessorElement setter) { 5830 DartType _getSetterType(PropertyAccessorElement setter) {
5876 // Get the parameters for MethodDeclaration or FunctionDeclaration 5831 // Get the parameters for MethodDeclaration or FunctionDeclaration
5877 List<ParameterElement> setterParameters = setter.parameters; 5832 List<ParameterElement> setterParameters = setter.parameters;
5878 // If there are no setter parameters, return no type. 5833 // If there are no setter parameters, return no type.
5879 if (setterParameters.length == 0) { 5834 if (setterParameters.length == 0) {
5880 return null; 5835 return null;
5881 } 5836 }
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
6222 // type arguments 6177 // type arguments
6223 if (type is InterfaceType) { 6178 if (type is InterfaceType) {
6224 for (DartType typeArgument in type.typeArguments) { 6179 for (DartType typeArgument in type.typeArguments) {
6225 _addTypeToCheck(typeArgument); 6180 _addTypeToCheck(typeArgument);
6226 } 6181 }
6227 } 6182 }
6228 } 6183 }
6229 } 6184 }
6230 6185
6231 /** 6186 /**
6187 * A class used to compute a list of the constants whose value needs to be
6188 * computed before errors can be computed by the [VerifyUnitTask].
6189 */
6190 class RequiredConstantsComputer extends RecursiveAstVisitor {
6191 /**
6192 * The source with which any pending errors will be associated.
6193 */
6194 final Source source;
6195
6196 /**
6197 * A list of the pending errors that were computed.
6198 */
6199 final List<PendingError> pendingErrors = <PendingError>[];
6200
6201 /**
6202 * A list of the constants whose value needs to be computed before the pending
6203 * errors can be used to compute an analysis error.
6204 */
6205 final List<ConstantEvaluationTarget> requiredConstants =
6206 <ConstantEvaluationTarget>[];
6207
6208 /**
6209 * Initialize a newly created computer to compute required constants within
6210 * the given [source].
6211 */
6212 RequiredConstantsComputer(this.source);
6213
6214 @override
6215 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
6216 DartType type = node.constructorName.type.type;
6217 if (type is InterfaceType) {
6218 _checkForMissingRequiredParam(
6219 node.staticElement?.type, node.argumentList, node.constructorName);
6220 }
6221 return super.visitInstanceCreationExpression(node);
6222 }
6223
6224 @override
6225 Object visitMethodInvocation(MethodInvocation node) {
6226 _checkForMissingRequiredParam(
6227 node.staticInvokeType, node.argumentList, node.methodName);
6228 return super.visitMethodInvocation(node);
6229 }
6230
6231 void _checkForMissingRequiredParam(
6232 DartType type, ArgumentList argumentList, AstNode node) {
6233 if (type is FunctionType) {
6234 for (ParameterElement parameter in type.parameters) {
6235 if (parameter.parameterKind == ParameterKind.NAMED) {
6236 ElementAnnotationImpl annotation = _getRequiredAnnotation(parameter);
6237 if (annotation != null) {
6238 String parameterName = parameter.name;
6239 if (!_containsNamedExpression(argumentList, parameterName)) {
6240 requiredConstants.add(annotation);
6241 pendingErrors.add(new PendingMissingRequiredParameterError(
6242 source, parameterName, node, annotation));
6243 }
6244 }
6245 }
6246 }
6247 }
6248 }
6249
6250 bool _containsNamedExpression(ArgumentList args, String name) {
6251 NodeList<Expression> arguments = args.arguments;
6252 for (int i = arguments.length - 1; i >= 0; i--) {
6253 Expression expression = arguments[i];
6254 if (expression is NamedExpression) {
6255 if (expression.name.label.name == name) {
6256 return true;
6257 }
6258 }
6259 }
6260 return false;
6261 }
6262
6263 ElementAnnotationImpl _getRequiredAnnotation(ParameterElement param) => param
6264 .metadata
6265 .firstWhere((ElementAnnotation e) => e.isRequired, orElse: () => null);
6266 }
6267
6268 /**
6232 * Recursively visits an AST, looking for method invocations. 6269 * Recursively visits an AST, looking for method invocations.
6233 */ 6270 */
6234 class _InvocationCollector extends RecursiveAstVisitor { 6271 class _InvocationCollector extends RecursiveAstVisitor {
6235 final List<String> superCalls = <String>[]; 6272 final List<String> superCalls = <String>[];
6236 6273
6237 @override 6274 @override
6238 visitMethodInvocation(MethodInvocation node) { 6275 visitMethodInvocation(MethodInvocation node) {
6239 if (node.target is SuperExpression) { 6276 if (node.target is SuperExpression) {
6240 superCalls.add(node.methodName.name); 6277 superCalls.add(node.methodName.name);
6241 } 6278 }
6242 } 6279 }
6243 } 6280 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698