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

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

Issue 1586813002: fix #25425, more inference of generic methods (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 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
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 &&

Powered by Google App Engine
This is Rietveld 408576698