Chromium Code Reviews| 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 |