| Index: pkg/analyzer/lib/src/task/strong_mode.dart
|
| diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
|
| index ea4e0b349010cacd68764464160adda7a6a8c636..93de3ddc149720040ab4d85b7ea7ae86b558f031 100644
|
| --- a/pkg/analyzer/lib/src/task/strong_mode.dart
|
| +++ b/pkg/analyzer/lib/src/task/strong_mode.dart
|
| @@ -121,8 +121,9 @@ class InstanceMemberInferrer {
|
| DartType parameterType = null;
|
| int length = overriddenTypes.length;
|
| for (int i = 0; i < length; i++) {
|
| - DartType type = _getTypeOfCorrespondingParameter(
|
| + ParameterElement matchingParam = _getCorrespondingParameter(
|
| parameter, index, overriddenTypes[i].parameters);
|
| + var type = matchingParam?.type ?? typeProvider.dynamicType;
|
| if (parameterType == null) {
|
| parameterType = type;
|
| } else if (parameterType != type) {
|
| @@ -156,45 +157,38 @@ class InstanceMemberInferrer {
|
| }
|
|
|
| /**
|
| - * Given a method, return the type of the parameter in the method that
|
| - * corresponds to the given [parameter]. If the parameter is positional, then
|
| + * Given a method, return the parameter in the method that corresponds to the
|
| + * given [parameter]. If the parameter is positional, then
|
| * it appears at the given [index] in its enclosing element's list of
|
| * parameters.
|
| */
|
| - DartType _getTypeOfCorrespondingParameter(ParameterElement parameter,
|
| + ParameterElement _getCorrespondingParameter(ParameterElement parameter,
|
| int index, List<ParameterElement> methodParameters) {
|
| //
|
| // Find the corresponding parameter.
|
| //
|
| - ParameterElement matchingParameter = null;
|
| if (parameter.parameterKind == ParameterKind.NAMED) {
|
| //
|
| // If we're looking for a named parameter, only a named parameter with
|
| // the same name will be matched.
|
| //
|
| - matchingParameter = methodParameters.lastWhere(
|
| + return methodParameters.lastWhere(
|
| (ParameterElement methodParameter) =>
|
| methodParameter.parameterKind == ParameterKind.NAMED &&
|
| methodParameter.name == parameter.name,
|
| orElse: () => null);
|
| - } else {
|
| - //
|
| - // If we're looking for a positional parameter we ignore the difference
|
| - // between required and optional parameters.
|
| - //
|
| - if (index < methodParameters.length) {
|
| - matchingParameter = methodParameters[index];
|
| - if (matchingParameter.parameterKind == ParameterKind.NAMED) {
|
| - matchingParameter = null;
|
| - }
|
| - }
|
| }
|
| //
|
| - // Then return the type of the parameter.
|
| + // If we're looking for a positional parameter we ignore the difference
|
| + // between required and optional parameters.
|
| //
|
| - return matchingParameter == null
|
| - ? typeProvider.dynamicType
|
| - : matchingParameter.type;
|
| + if (index < methodParameters.length) {
|
| + var matchingParameter = methodParameters[index];
|
| + if (matchingParameter.parameterKind != ParameterKind.NAMED) {
|
| + return matchingParameter;
|
| + }
|
| + }
|
| + return null;
|
| }
|
|
|
| /**
|
| @@ -311,10 +305,18 @@ class InstanceMemberInferrer {
|
| int length = parameters.length;
|
| for (int i = 0; i < length; ++i) {
|
| ParameterElement parameter = parameters[i];
|
| - if (parameter is ParameterElementImpl && parameter.hasImplicitType) {
|
| - parameter.type = _computeParameterType(parameter, i, overriddenTypes);
|
| - if (element is PropertyAccessorElement) {
|
| - _updateSyntheticVariableType(element);
|
| + if (parameter is ParameterElementImpl) {
|
| + // If a parameter is covariant, any parameters that override it are too.
|
| + parameter.inheritsCovariant = overriddenTypes.any((f) {
|
| + var param = _getCorrespondingParameter(parameter, i, f.parameters);
|
| + return param != null && param.isCovariant;
|
| + });
|
| +
|
| + if (parameter.hasImplicitType) {
|
| + parameter.type = _computeParameterType(parameter, i, overriddenTypes);
|
| + if (element is PropertyAccessorElement) {
|
| + _updateSyntheticVariableType(element);
|
| + }
|
| }
|
| }
|
| }
|
|
|