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 fdda79a83b6a617b25e2b48f3238eafa459ba8a8..bed47607204941145fe8123cd67ddafe05297ccc 100644 |
| --- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart |
| +++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart |
| @@ -495,6 +495,9 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
| */ |
| @override |
| Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { |
| + if (_strongMode) { |
| + _inferFunctionInvocationGeneric(node); |
| + } |
| DartType staticType = _computeInvokeReturnType(node.staticInvokeType); |
| _recordStaticType(node, staticType); |
| DartType functionPropagatedType = node.propagatedInvokeType; |
| @@ -713,12 +716,12 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
| Object visitMethodInvocation(MethodInvocation node) { |
| SimpleIdentifier methodNameNode = node.methodName; |
| Element staticMethodElement = methodNameNode.staticElement; |
| + if (_strongMode) { |
| + _inferMethodInvocation(node); |
|
Jennifer Messerly
2016/01/13 22:32:46
moved up so we don't need to overwrite the return
|
| + } |
| // Record types of the variable invoked as a function. |
| if (staticMethodElement is VariableElement) { |
| - VariableElement variable = staticMethodElement; |
| - DartType staticType = variable.type; |
|
Jennifer Messerly
2016/01/13 22:32:46
This code is no longer needed, as ElementResolver
|
| - _recordStaticType(methodNameNode, staticType); |
| - DartType propagatedType = _overrideManager.getType(variable); |
| + DartType propagatedType = _overrideManager.getType(staticMethodElement); |
| _resolver.recordPropagatedTypeIfBetter(methodNameNode, propagatedType); |
| } |
| // Record static return type of the static element. |
| @@ -731,9 +734,6 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
| // Check for special cases. |
| bool needPropagatedType = true; |
| String methodName = methodNameNode.name; |
| - if (_strongMode) { |
| - _inferMethodInvocation(node); |
| - } |
| if (methodName == "then") { |
| Expression target = node.realTarget; |
| if (target != null) { |
| @@ -1802,20 +1802,53 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
| * type variables, using the actual types of the arguments. |
| */ |
| bool _inferMethodInvocationGeneric(MethodInvocation node) { |
| - Element element = node.methodName.staticElement; |
| - DartType invokeType = node.staticInvokeType; |
| + DartType instantiatedType = node.staticInvokeType; |
| + DartType originalType = node.methodName.staticType; |
| + // TODO(jmesserly): support generic `call` methods. |
| + // Perhaps we should always record a FunctionType in staticInvokeType |
| + // and the methodName's staticType. |
| + if (instantiatedType is FunctionType && originalType is FunctionType) { |
| + FunctionType inferred = _inferGenericInvoke(instantiatedType, |
| + originalType, node.typeArguments, node.argumentList); |
| + if (inferred != null) { |
| + node.staticInvokeType = inferred; |
| + node.staticType = inferred.returnType; |
|
Jennifer Messerly
2016/01/13 22:32:46
oops, I'll remove this line. It is no longer neede
|
| + return true; |
| + } |
| + } |
| + return false; |
| + } |
| + /** |
| + * Similar to [_inferMethodInvocationGeneric] but for function expression |
| + * invocations. |
| + */ |
| + // TODO(jmesserly): if we had a common AST interface between these two nodes, |
|
Jennifer Messerly
2016/01/13 22:32:46
this method is virtually identical to the one abov
|
| + // we could remove this duplicated code. |
| + bool _inferFunctionInvocationGeneric(FunctionExpressionInvocation node) { |
| + DartType instantiatedType = node.staticInvokeType; |
| + DartType originalType = node.function.staticType; |
| + if (instantiatedType is FunctionType && originalType is FunctionType) { |
| + FunctionType inferred = _inferGenericInvoke(instantiatedType, |
| + originalType, node.typeArguments, node.argumentList); |
| + if (inferred != null) { |
| + node.staticInvokeType = inferred; |
| + return true; |
| + } |
| + } |
| + return false; |
| + } |
| + |
| + FunctionType _inferGenericInvoke(FunctionType invokeType, FunctionType fnType, |
| + TypeArgumentList typeArguments, ArgumentList argumentList) { |
| TypeSystem ts = _typeSystem; |
| - if (node.typeArguments == null && |
| - element is ExecutableElement && |
| - ts is StrongTypeSystemImpl) { |
| - FunctionType fnType = element.type; |
| + if (typeArguments == null && ts is StrongTypeSystemImpl) { |
| if (fnType.typeFormals.isNotEmpty && |
| ts.instantiateToBounds(fnType) == invokeType) { |
| // Get the parameters that correspond to the uninstantiated generic. |
| List<ParameterElement> rawParameters = |
| ResolverVisitor.resolveArgumentsToParameters( |
| - node.argumentList, fnType.parameters, null); |
| + argumentList, fnType.parameters, null); |
| List<DartType> paramTypes = <DartType>[]; |
| List<DartType> argTypes = <DartType>[]; |
| @@ -1823,7 +1856,7 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
| ParameterElement parameter = rawParameters[i]; |
| if (parameter != null) { |
| paramTypes.add(parameter.type); |
| - argTypes.add(node.argumentList.arguments[i].staticType); |
| + argTypes.add(argumentList.arguments[i].staticType); |
| } |
| } |
| @@ -1834,15 +1867,13 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
| // Fix up the parameter elements based on inferred method. |
| List<ParameterElement> inferredParameters = |
| ResolverVisitor.resolveArgumentsToParameters( |
| - node.argumentList, inferred.parameters, null); |
| - node.argumentList.correspondingStaticParameters = inferredParameters; |
| - node.staticInvokeType = inferred; |
| - _recordStaticType(node, inferred.returnType); |
| - return true; |
| + argumentList, inferred.parameters, null); |
| + argumentList.correspondingStaticParameters = inferredParameters; |
| + return inferred; |
| } |
| } |
| } |
| - return false; |
| + return null; |
| } |
| /** |
| @@ -1892,7 +1923,7 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
| return false; |
| } |
| DartType inferredType = inferredElement.type; |
| - DartType nodeType = node.staticType; |
| + DartType nodeType = node.staticInvokeType; |
|
Jennifer Messerly
2016/01/13 22:32:46
the "_inferMethodInvocationObject" method didn't w
|
| if (nodeType != null && |
| nodeType.isDynamic && |
| inferredType is FunctionType && |