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

Unified Diff: pkg/analyzer/lib/src/task/strong_mode.dart

Issue 1311433005: Integrate recent parameter override logic (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Address comments Created 5 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/analyzer/test/src/task/strong_mode_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 7958f7a4655fdcf4c372f810fb4ff164ef9d4906..fda0467196890f37256e54695ff78c5b10af7379 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -9,6 +9,7 @@ import 'dart:collection';
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
/**
* An object used to find static variables whose types should be inferred and
@@ -164,6 +165,32 @@ class InstanceMemberInferrer {
}
/**
+ * Compute the best type for the [parameter] at the given [index] that must be
+ * compatible with the types of the corresponding parameters of the given
+ * [overriddenMethods].
+ *
+ * At the moment, this method will only return a type other than 'dynamic' if
+ * the types of all of the parameters are the same. In the future we might
+ * want to be smarter about it, such as by returning the least upper bound of
+ * the parameter types.
+ */
+ DartType _computeParameterType(ParameterElement parameter, int index,
+ List<ExecutableElement> overriddenMethods) {
+ DartType parameterType = null;
+ int length = overriddenMethods.length;
+ for (int i = 0; i < length; i++) {
+ DartType type = _getTypeOfCorrespondingParameter(
+ parameter, index, overriddenMethods[i]);
+ if (parameterType == null) {
+ parameterType = type;
+ } else if (parameterType != type) {
+ return typeProvider.dynamicType;
+ }
+ }
+ return parameterType == null ? typeProvider.dynamicType : parameterType;
+ }
+
+ /**
* Compute the best return type for a method that must be compatible with the
* return types of each of the given [overriddenMethods].
*
@@ -209,6 +236,49 @@ 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
+ * it appears at the given [index] in it's enclosing element's list of
Leaf 2015/08/26 17:11:09 it's -> its.
Brian Wilkerson 2015/08/26 17:36:15 Done
+ * parameters.
+ */
+ DartType _getTypeOfCorrespondingParameter(
+ ParameterElement parameter, int index, ExecutableElement method) {
+ //
+ // Find the corresponding parameter.
+ //
+ List<ParameterElement> methodParameters = method.parameters;
+ 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(
+ (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.
+ //
+ return matchingParameter == null
+ ? typeProvider.dynamicType
+ : matchingParameter.type;
+ }
+
+ /**
* If the given [accessorElement] represents a non-synthetic instance getter
* for which no return type was provided, infer the return type of the getter.
*/
@@ -324,15 +394,43 @@ class InstanceMemberInferrer {
* for which no return type was provided, infer the return type of the method.
*/
void _inferMethod(MethodElement methodElement) {
- if (!methodElement.isSynthetic &&
- !methodElement.isStatic &&
- methodElement.hasImplicitReturnType &&
+ if (methodElement.isSynthetic || methodElement.isStatic) {
+ return;
+ }
+ List<ExecutableElement> overriddenMethods = null;
+ //
+ // Infer the return type.
+ //
+ if (methodElement.hasImplicitReturnType &&
_getReturnType(methodElement).isDynamic) {
- List<ExecutableElement> overriddenMethods = inheritanceManager
- .lookupOverrides(methodElement.enclosingElement, methodElement.name);
- if (overriddenMethods.isNotEmpty && _onlyMethods(overriddenMethods)) {
- MethodElementImpl element = methodElement as MethodElementImpl;
- _setReturnType(element, _computeReturnType(overriddenMethods));
+ overriddenMethods = inheritanceManager.lookupOverrides(
+ methodElement.enclosingElement, methodElement.name);
+ if (overriddenMethods.isEmpty || !_onlyMethods(overriddenMethods)) {
+ return;
+ }
+ MethodElementImpl element = methodElement as MethodElementImpl;
+ _setReturnType(element, _computeReturnType(overriddenMethods));
+ }
+ //
+ // Infer the parameter types.
+ //
+ List<ParameterElement> parameters = methodElement.parameters;
+ var length = parameters.length;
+ for (int i = 0; i < length; ++i) {
+ ParameterElement parameter = parameters[i];
+ if (parameter.hasImplicitType && parameter.type.isDynamic) {
+ overriddenMethods = overriddenMethods ??
vicb 2015/08/29 06:10:42 If the analyzer is supposed to work with SDK v1.11
Brian Wilkerson 2015/08/29 16:15:05 If only we had a tool that could tell us when we m
+ inheritanceManager.lookupOverrides(
+ methodElement.enclosingElement, methodElement.name);
+ if (overriddenMethods.isEmpty || !_onlyMethods(overriddenMethods)) {
+ return;
+ }
+ DartType type = _computeParameterType(parameter, i, overriddenMethods);
+ if (!type.isDynamic) {
+ if (parameter is ParameterElementImpl) {
+ parameter.type = type;
+ }
+ }
}
}
}
« no previous file with comments | « no previous file | pkg/analyzer/test/src/task/strong_mode_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698