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

Unified Diff: pkg/analyzer/lib/src/generated/static_type_analyzer.dart

Issue 1442883003: generic method type parameter inference (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 1 month 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
Index: pkg/analyzer/lib/src/generated/static_type_analyzer.dart
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 3f8c0ef4759c1180902847a4a78f0f40afe8c8bc..6c786fa137a1561b4a61969e3f9e05768ce9187e 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -1694,12 +1694,35 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
* type for the result using an ad-hoc list of psuedo-generic methods.
Leaf 2015/11/20 02:09:43 comment is out of date?
Jennifer Messerly 2015/11/20 17:09:46 Done.
*/
bool _inferMethodInvocationGeneric(MethodInvocation node) {
- DartType inferredType = _matchGeneric(node);
- // TODO(vsm): If the inferred type is not a subtype,
- // should we use a GLB instead?
- if (inferredType != null &&
- _typeSystem.isSubtypeOf(inferredType, node.staticType)) {
- _recordStaticType(node, inferredType);
+ Element element = node.methodName.staticElement;
+ DartType fnType = node.methodName.staticType;
+ TypeSystem ts = _typeSystem;
+ if (element is ExecutableElement &&
+ fnType is FunctionTypeImpl &&
+ ts is StrongTypeSystemImpl) {
Brian Wilkerson 2015/11/19 00:10:17 Is this test here to determine whether we're runni
+ List<Expression> arguments = node.argumentList.arguments;
+ List<DartType> argTypes = arguments.map((e) => e.staticType).toList();
+ List<DartType> paramTypes =
+ arguments.map((e) => e.staticParameterElement.type).toList();
+
+ FunctionType inferred = ts.inferCallFromArguments(
+ _typeProvider, fnType, paramTypes, argTypes);
+ if (inferred != fnType) {
+ // TODO(jmesserly): inference should be happening earlier, which would
+ // allow these parameters to be correct from the get-go.
+
+ List<ParameterElement> inferredParameters = inferred.parameters;
+ List<ParameterElement> correspondingParams =
+ new List<ParameterElement>();
+ for (Expression arg in arguments) {
+ int i = element.parameters.indexOf(arg.staticParameterElement);
+ correspondingParams.add(inferredParameters[i]);
+ }
+ node.argumentList.correspondingStaticParameters = correspondingParams;
+
+ _recordStaticType(node.methodName, inferred);
+ _recordStaticType(node, inferred.returnType);
+ }
return true;
}
return false;
@@ -1863,91 +1886,6 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
}
/**
- * Return a more specialized type for a method invocation based on
- * an ad-hoc list of pseudo-generic methods.
- */
- DartType _matchGeneric(MethodInvocation node) {
- Element e = node.methodName.staticElement;
-
- if (e == null || e.name == null) {
- return null;
- }
-
- List<DartType> arguments =
- node.argumentList.arguments.map((arg) => arg.staticType).toList();
-
- bool matchInvocation(DartType t, int c) {
- return (node.realTarget != null) &&
- node.realTarget.staticType.isSubtypeOf(t) &&
- arguments.length == c;
- }
-
- switch (e.name) {
- case 'max':
- case 'min':
- if (e.library.source.uri.toString() == 'dart:math' &&
- arguments.length == 2) {
- DartType tx = arguments[0];
- DartType ty = arguments[1];
- if (tx == ty &&
- (tx == _typeProvider.intType || tx == _typeProvider.doubleType)) {
- return tx;
- }
- }
- return null;
- case 'wait':
- if (matchInvocation(_typeProvider.futureType, 1)) {
- DartType tx = arguments[0];
- // Iterable<Future<T>> -> Future<List<T>>
- DartType futureType =
- _findIteratedType(tx, _typeProvider.iterableType);
- if (futureType.element != _typeProvider.futureType.element) {
- return null;
- }
- List<DartType> typeArguments =
- (futureType as InterfaceType).typeArguments;
- if (typeArguments.length != 1) {
- return null;
- }
- DartType baseType = typeArguments[0];
- if (baseType.isDynamic) {
- return null;
- }
- return _typeProvider.futureType.substitute4([
- _typeProvider.listType.substitute4([baseType])
- ]);
- }
- return null;
- case 'map':
- if (matchInvocation(_typeProvider.iterableDynamicType, 1)) {
- DartType tx = arguments[0];
- return (tx is FunctionType)
- ? _typeProvider.iterableType.substitute4([tx.returnType])
- : null;
- }
- return null;
- case 'fold':
- if (matchInvocation(_typeProvider.iterableDynamicType, 2)) {
- DartType tx = arguments[0];
- DartType ty = arguments[1];
- // TODO(vsm): LUB?
- return (ty is FunctionType && tx == ty.returnType) ? tx : null;
- }
- return null;
- case 'then':
- if (matchInvocation(_typeProvider.futureDynamicType, 1)) {
- DartType tx = arguments[0];
- return (tx is FunctionType)
- ? _typeProvider.futureType.substitute4([tx.returnType])
- : null;
- }
- return null;
- default:
- return null;
- }
- }
-
- /**
* Record that the propagated type of the given node is the given type.
*
* @param expression the node whose type is to be recorded

Powered by Google App Engine
This is Rietveld 408576698