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

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

Issue 1863803002: Validation of `@required` params (#26182). (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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 800 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 bool wasInConstInstanceCreation = _isInConstInstanceCreation; 811 bool wasInConstInstanceCreation = _isInConstInstanceCreation;
812 _isInConstInstanceCreation = node.isConst; 812 _isInConstInstanceCreation = node.isConst;
813 try { 813 try {
814 ConstructorName constructorName = node.constructorName; 814 ConstructorName constructorName = node.constructorName;
815 TypeName typeName = constructorName.type; 815 TypeName typeName = constructorName.type;
816 DartType type = typeName.type; 816 DartType type = typeName.type;
817 if (type is InterfaceType) { 817 if (type is InterfaceType) {
818 InterfaceType interfaceType = type; 818 InterfaceType interfaceType = type;
819 _checkForConstOrNewWithAbstractClass(node, typeName, interfaceType); 819 _checkForConstOrNewWithAbstractClass(node, typeName, interfaceType);
820 _checkForConstOrNewWithEnum(node, typeName, interfaceType); 820 _checkForConstOrNewWithEnum(node, typeName, interfaceType);
821 _checkForMissingRequiredParam(
822 node.staticElement?.type, node.argumentList, node.constructorName);
821 if (_isInConstInstanceCreation) { 823 if (_isInConstInstanceCreation) {
822 _checkForConstWithNonConst(node); 824 _checkForConstWithNonConst(node);
823 _checkForConstWithUndefinedConstructor( 825 _checkForConstWithUndefinedConstructor(
824 node, constructorName, typeName); 826 node, constructorName, typeName);
825 _checkForConstWithTypeParameters(typeName); 827 _checkForConstWithTypeParameters(typeName);
826 _checkForConstDeferredClass(node, constructorName, typeName); 828 _checkForConstDeferredClass(node, constructorName, typeName);
827 } else { 829 } else {
828 _checkForNewWithUndefinedConstructor(node, constructorName, typeName); 830 _checkForNewWithUndefinedConstructor(node, constructorName, typeName);
829 } 831 }
830 } 832 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 Object visitMethodInvocation(MethodInvocation node) { 924 Object visitMethodInvocation(MethodInvocation node) {
923 Expression target = node.realTarget; 925 Expression target = node.realTarget;
924 SimpleIdentifier methodName = node.methodName; 926 SimpleIdentifier methodName = node.methodName;
925 if (target != null) { 927 if (target != null) {
926 ClassElement typeReference = ElementResolver.getTypeReference(target); 928 ClassElement typeReference = ElementResolver.getTypeReference(target);
927 _checkForStaticAccessToInstanceMember(typeReference, methodName); 929 _checkForStaticAccessToInstanceMember(typeReference, methodName);
928 _checkForInstanceAccessToStaticMember(typeReference, methodName); 930 _checkForInstanceAccessToStaticMember(typeReference, methodName);
929 } else { 931 } else {
930 _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName); 932 _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName);
931 } 933 }
934 _checkForMissingRequiredParam(
935 node.staticInvokeType, node.argumentList, methodName);
932 return super.visitMethodInvocation(node); 936 return super.visitMethodInvocation(node);
933 } 937 }
934 938
935 @override 939 @override
936 Object visitNativeClause(NativeClause node) { 940 Object visitNativeClause(NativeClause node) {
937 // TODO(brianwilkerson) Figure out the right rule for when 'native' is 941 // TODO(brianwilkerson) Figure out the right rule for when 'native' is
938 // allowed. 942 // allowed.
939 if (!_isInSystemLibrary) { 943 if (!_isInSystemLibrary) {
940 _errorReporter.reportErrorForNode( 944 _errorReporter.reportErrorForNode(
941 ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE, node); 945 ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE, node);
(...skipping 2776 matching lines...) Expand 10 before | Expand all | Expand 10 after
3718 if (!executableElement.isStatic) { 3722 if (!executableElement.isStatic) {
3719 return; 3723 return;
3720 } 3724 }
3721 3725
3722 _errorReporter.reportErrorForNode( 3726 _errorReporter.reportErrorForNode(
3723 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, 3727 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
3724 name, 3728 name,
3725 [name.name]); 3729 [name.name]);
3726 } 3730 }
3727 3731
3732 void _checkForMissingRequiredParam(
3733 DartType type, ArgumentList argumentList, AstNode node) {
3734 if (type is FunctionType) {
3735 List<ParameterElement> parameters = type.parameters;
3736 for (ParameterElement param in parameters) {
3737 if (param.parameterKind == ParameterKind.NAMED) {
3738 ElementAnnotationImpl annotation = _getRequiredAnnotation(param);
3739 if (annotation != null) {
3740 String paramName = param.name;
3741 if (!_containsNamedExpression(argumentList, paramName)) {
3742 String reason = '';
3743 DartObject constantValue = annotation.constantValue;
3744 reason ??= constantValue.getField('reason')?.toStringValue();
Brian Wilkerson 2016/04/05 23:27:35 reason will never be null at this point, so I thin
pquitslund 2016/04/06 00:04:13 Right. Thanks for catching that.
3745 // Append a `.` if needed.
3746 if (reason != null &&
3747 reason.isNotEmpty &&
3748 !reason.endsWith('.')) {
3749 reason += '.';
3750 }
3751
3752 _errorReporter.reportErrorForNode(
3753 HintCode.MISSING_REQUIRED_PARAM, node, [paramName, reason]);
3754 }
3755 }
3756 }
3757 }
3758 }
3759 }
3760
3761 ElementAnnotationImpl _getRequiredAnnotation(ParameterElement param) => param
3762 .metadata
3763 .firstWhere((ElementAnnotation e) => e.isRequired, orElse: () => null);
3764
3765 bool _containsNamedExpression(ArgumentList args, String name) {
3766 for (Expression expression in args.arguments) {
3767 if (expression is NamedExpression) {
3768 if (expression.name.label.name == name) {
3769 return true;
3770 }
3771 }
3772 }
3773 return false;
3774 }
3775
3728 /** 3776 /**
3729 * Check whether the given [executableElement] collides with the name of a 3777 * Check whether the given [executableElement] collides with the name of a
3730 * static method in one of its superclasses, and reports the appropriate 3778 * static method in one of its superclasses, and reports the appropriate
3731 * warning if it does. The [errorNameTarget] is the node to report problems 3779 * warning if it does. The [errorNameTarget] is the node to report problems
3732 * on. 3780 * on.
3733 * 3781 *
3734 * See [StaticTypeWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ST ATIC]. 3782 * See [StaticTypeWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ST ATIC].
3735 */ 3783 */
3736 bool _checkForInstanceMethodNameCollidesWithSuperclassStatic( 3784 bool _checkForInstanceMethodNameCollidesWithSuperclassStatic(
3737 ExecutableElement executableElement, SimpleIdentifier errorNameTarget) { 3785 ExecutableElement executableElement, SimpleIdentifier errorNameTarget) {
(...skipping 2324 matching lines...) Expand 10 before | Expand all | Expand 10 after
6062 class _InvocationCollector extends RecursiveAstVisitor { 6110 class _InvocationCollector extends RecursiveAstVisitor {
6063 final List<String> superCalls = <String>[]; 6111 final List<String> superCalls = <String>[];
6064 6112
6065 @override 6113 @override
6066 visitMethodInvocation(MethodInvocation node) { 6114 visitMethodInvocation(MethodInvocation node) {
6067 if (node.target is SuperExpression) { 6115 if (node.target is SuperExpression) {
6068 superCalls.add(node.methodName.name); 6116 superCalls.add(node.methodName.name);
6069 } 6117 }
6070 } 6118 }
6071 } 6119 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/error.dart ('k') | pkg/analyzer/test/generated/hint_code_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698