Chromium Code Reviews| Index: pkg/analyzer/lib/src/generated/error_verifier.dart |
| diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart |
| index c77d13ade7f0aff6d6e2bf7dd01d774667d126a8..a319f7f678d76df60a8fa6628995ecd7339ad249 100644 |
| --- a/pkg/analyzer/lib/src/generated/error_verifier.dart |
| +++ b/pkg/analyzer/lib/src/generated/error_verifier.dart |
| @@ -818,6 +818,8 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> { |
| InterfaceType interfaceType = type; |
| _checkForConstOrNewWithAbstractClass(node, typeName, interfaceType); |
| _checkForConstOrNewWithEnum(node, typeName, interfaceType); |
| + _checkForMissingRequiredParam( |
| + node.staticElement?.type, node.argumentList, node.constructorName); |
| if (_isInConstInstanceCreation) { |
| _checkForConstWithNonConst(node); |
| _checkForConstWithUndefinedConstructor( |
| @@ -929,6 +931,8 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> { |
| } else { |
| _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName); |
| } |
| + _checkForMissingRequiredParam( |
| + node.staticInvokeType, node.argumentList, methodName); |
| return super.visitMethodInvocation(node); |
| } |
| @@ -3725,6 +3729,50 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> { |
| [name.name]); |
| } |
| + void _checkForMissingRequiredParam( |
| + DartType type, ArgumentList argumentList, AstNode node) { |
| + if (type is FunctionType) { |
| + List<ParameterElement> parameters = type.parameters; |
| + for (ParameterElement param in parameters) { |
| + if (param.parameterKind == ParameterKind.NAMED) { |
| + ElementAnnotationImpl annotation = _getRequiredAnnotation(param); |
| + if (annotation != null) { |
| + String paramName = param.name; |
| + if (!_containsNamedExpression(argumentList, paramName)) { |
| + String reason = ''; |
| + DartObject constantValue = annotation.constantValue; |
| + 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.
|
| + // Append a `.` if needed. |
| + if (reason != null && |
| + reason.isNotEmpty && |
| + !reason.endsWith('.')) { |
| + reason += '.'; |
| + } |
| + |
| + _errorReporter.reportErrorForNode( |
| + HintCode.MISSING_REQUIRED_PARAM, node, [paramName, reason]); |
| + } |
| + } |
| + } |
| + } |
| + } |
| + } |
| + |
| + ElementAnnotationImpl _getRequiredAnnotation(ParameterElement param) => param |
| + .metadata |
| + .firstWhere((ElementAnnotation e) => e.isRequired, orElse: () => null); |
| + |
| + bool _containsNamedExpression(ArgumentList args, String name) { |
| + for (Expression expression in args.arguments) { |
| + if (expression is NamedExpression) { |
| + if (expression.name.label.name == name) { |
| + return true; |
| + } |
| + } |
| + } |
| + return false; |
| + } |
| + |
| /** |
| * Check whether the given [executableElement] collides with the name of a |
| * static method in one of its superclasses, and reports the appropriate |