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); |
+ } |
} |
} |
} |