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

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: 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..61b8dd3a7524625a928683dcec408cf10b9d631e 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,79 @@ 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) {
+ //
+ // Return the type of the corresponding parameter in the method with the
+ // given [methodIndex].
+ //
+ DartType getOverriddenType(int methodIndex) {
+ //
+ // Find the corresponding parameter.
+ //
+ List<ParameterElement> overriddenParameters =
+ overriddenMethods[methodIndex].parameters;
+ ParameterElement overriddenParameter = 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.
+ //
+ for (int i = overriddenParameters.length - 1; i >= 0; i--) {
Leaf 2015/08/25 23:06:37 I think using overridenParameter = overridenPar
Brian Wilkerson 2015/08/26 15:25:37 Done
+ overriddenParameter = overriddenParameters[index];
Leaf 2015/08/25 23:06:37 I think this should be i instead of index?
Brian Wilkerson 2015/08/26 15:25:37 Subsumed by previous change.
+ if (overriddenParameter.parameterKind == ParameterKind.NAMED &&
+ overriddenParameter.name == parameter.name) {
+ break;
+ }
+ overriddenParameter = null;
+ }
+ } else {
+ //
+ // If we're looking for a positional parameter we ignore the difference
+ // between required and optional parameters.
+ //
+ if (index < overriddenParameters.length) {
+ overriddenParameter = overriddenParameters[index];
+ if (overriddenParameter.parameterKind == ParameterKind.NAMED) {
+ overriddenParameter = null;
+ }
+ }
+ }
+ //
+ // Then get the type of the parameter.
+ //
+ if (overriddenParameter == null) {
+ return typeProvider.dynamicType;
+ }
+ DartType type = overriddenParameter.type;
+ if (type is TypeParameterType) {
Leaf 2015/08/25 23:06:37 Hmm, is this to address the possibility that the o
Brian Wilkerson 2015/08/26 15:25:37 Yes, but we do have the instantiated type, so this
+ return typeProvider.dynamicType;
+ }
+ return type;
+ }
+ DartType parameterType = null;
+ int length = overriddenMethods.length;
+ for (int i = 0; i < length; i++) {
+ DartType type = getOverriddenType(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].
*
@@ -324,15 +398,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 ??
+ 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