Skip to content

Commit 0c4e64c

Browse files
author
John Messerly
committed
fixes #25477, downward inference of generic methods
* we now push the context return type down when inferring * we also take this into account in our initial downards inference for arguments * adds a common AST interface for FunctionExpressionInvocation and MethodInvocation, so we can handle these more uniformly [email protected], [email protected] Review URL: https://codereview.chromium.org/1720433002 .
1 parent 9001fa7 commit 0c4e64c

File tree

8 files changed

+253
-208
lines changed

8 files changed

+253
-208
lines changed

pkg/analyzer/lib/dart/ast/ast.dart

Lines changed: 59 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ abstract class AstNode {
536536
* (either AST nodes or tokens) that make up the contents of this node,
537537
* including doc comments but excluding other comments.
538538
*/
539-
Iterable /*<AstNode | Token>*/ get childEntities;
539+
Iterable/*<AstNode | Token>*/ get childEntities;
540540

541541
/**
542542
* Return the offset of the character immediately following the last character
@@ -591,7 +591,7 @@ abstract class AstNode {
591591
* Use the given [visitor] to visit this node. Return the value returned by
592592
* the visitor as a result of visiting this node.
593593
*/
594-
dynamic /* =E */ accept /*<E>*/ (AstVisitor /*<E>*/ visitor);
594+
dynamic /* =E */ accept/*<E>*/(AstVisitor/*<E>*/ visitor);
595595

596596
/**
597597
* Return the most immediate ancestor of this node for which the [predicate]
@@ -3994,7 +3994,7 @@ abstract class FunctionExpression extends Expression {
39943994
*
39953995
* Clients may not extend, implement or mix-in this class.
39963996
*/
3997-
abstract class FunctionExpressionInvocation extends Expression {
3997+
abstract class FunctionExpressionInvocation extends InvocationExpression {
39983998
/**
39993999
* Initialize a newly created function expression invocation.
40004000
*/
@@ -4003,11 +4003,6 @@ abstract class FunctionExpressionInvocation extends Expression {
40034003
TypeArgumentList typeArguments,
40044004
ArgumentList argumentList) = FunctionExpressionInvocationImpl;
40054005

4006-
/**
4007-
* Return the list of arguments to the method.
4008-
*/
4009-
ArgumentList get argumentList;
4010-
40114006
/**
40124007
* Set the list of arguments to the method to the given [argumentList].
40134008
*/
@@ -4093,12 +4088,6 @@ abstract class FunctionExpressionInvocation extends Expression {
40934088
*/
40944089
void set staticInvokeType(DartType type);
40954090

4096-
/**
4097-
* Return the type arguments to be applied to the method being invoked, or
4098-
* `null` if no type arguments were provided.
4099-
*/
4100-
TypeArgumentList get typeArguments;
4101-
41024091
/**
41034092
* Set the type arguments to be applied to the method being invoked to the
41044093
* given [typeArguments].
@@ -4977,6 +4966,61 @@ abstract class InterpolationString extends InterpolationElement {
49774966
void set value(String value);
49784967
}
49794968

4969+
/**
4970+
* The invocation of a function or method; either a
4971+
* [FunctionExpressionInvocation] or a [MethodInvocation].
4972+
*
4973+
* Clients may not extend, implement or mix-in this class.
4974+
*/
4975+
abstract class InvocationExpression extends Expression {
4976+
/**
4977+
* Return the function type of the invocation based on the propagated type
4978+
* information, or `null` if the AST structure has not been resolved, or if
4979+
* the invoke could not be resolved.
4980+
*
4981+
* This will usually be a [FunctionType], but it can also be an
4982+
* [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
4983+
* interface type that implements `Function`.
4984+
*/
4985+
DartType propagatedInvokeType;
4986+
4987+
/**
4988+
* Return the function type of the invocation based on the static type
4989+
* information, or `null` if the AST structure has not been resolved, or if
4990+
* the invoke could not be resolved.
4991+
*
4992+
* This will usually be a [FunctionType], but it can also be an
4993+
* [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
4994+
* interface type that implements `Function`.
4995+
*/
4996+
DartType staticInvokeType;
4997+
4998+
/**
4999+
* Return the list of arguments to the method.
5000+
*/
5001+
ArgumentList get argumentList;
5002+
5003+
/**
5004+
* The expression that identifies the function or method being invoked.
5005+
* For example:
5006+
*
5007+
* (o.m)<TArgs>(args); // target will be `o.m`
5008+
* o.m<TArgs>(args); // target will be `m`
5009+
*
5010+
* In either case, the [function.staticType] will be the
5011+
* [staticInvokeType] before applying type arguments `TArgs`. Similarly,
5012+
* [function.propagatedType] will be the [propagatedInvokeType]
5013+
* before applying type arguments `TArgs`.
5014+
*/
5015+
Expression get function;
5016+
5017+
/**
5018+
* Return the type arguments to be applied to the method being invoked, or
5019+
* `null` if no type arguments were provided.
5020+
*/
5021+
TypeArgumentList get typeArguments;
5022+
}
5023+
49805024
/**
49815025
* An is expression.
49825026
*
@@ -5519,7 +5563,7 @@ abstract class MethodDeclaration extends ClassMember {
55195563
*
55205564
* Clients may not extend, implement or mix-in this class.
55215565
*/
5522-
abstract class MethodInvocation extends Expression {
5566+
abstract class MethodInvocation extends InvocationExpression {
55235567
/**
55245568
* Initialize a newly created method invocation. The [target] and [operator]
55255569
* can be `null` if there is no target.
@@ -5531,11 +5575,6 @@ abstract class MethodInvocation extends Expression {
55315575
TypeArgumentList typeArguments,
55325576
ArgumentList argumentList) = MethodInvocationImpl;
55335577

5534-
/**
5535-
* Return the list of arguments to the method.
5536-
*/
5537-
ArgumentList get argumentList;
5538-
55395578
/**
55405579
* Set the list of arguments to the method to the given [argumentList].
55415580
*/
@@ -5630,12 +5669,6 @@ abstract class MethodInvocation extends Expression {
56305669
*/
56315670
void set target(Expression expression);
56325671

5633-
/**
5634-
* Return the type arguments to be applied to the method being invoked, or
5635-
* `null` if no type arguments were provided.
5636-
*/
5637-
TypeArgumentList get typeArguments;
5638-
56395672
/**
56405673
* Set the type arguments to be applied to the method being invoked to the
56415674
* given [typeArguments].

pkg/analyzer/lib/src/dart/ast/ast.dart

Lines changed: 59 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -5054,69 +5054,34 @@ class FunctionExpressionImpl extends ExpressionImpl
50545054
* > functionExpressionInvocation ::=
50555055
* > [Expression] [TypeArgumentList]? [ArgumentList]
50565056
*/
5057-
class FunctionExpressionInvocationImpl extends ExpressionImpl
5057+
class FunctionExpressionInvocationImpl extends InvocationExpressionImpl
50585058
implements FunctionExpressionInvocation {
50595059
/**
50605060
* The expression producing the function being invoked.
50615061
*/
50625062
Expression _function;
50635063

5064-
/**
5065-
* The type arguments to be applied to the method being invoked, or `null` if
5066-
* no type arguments were provided.
5067-
*/
5068-
TypeArgumentList _typeArguments;
5069-
5070-
/**
5071-
* The list of arguments to the function.
5072-
*/
5073-
ArgumentList _argumentList;
5074-
50755064
/**
50765065
* The element associated with the function being invoked based on static type
50775066
* information, or `null` if the AST structure has not been resolved or the
50785067
* function could not be resolved.
50795068
*/
50805069
ExecutableElement staticElement;
50815070

5082-
/**
5083-
* The function type of the method invocation, or `null` if the AST
5084-
* structure has not been resolved, or if the invoke could not be resolved.
5085-
*
5086-
* This will usually be a [FunctionType], but it can also be an
5087-
* [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
5088-
* interface type that implements `Function`.
5089-
*/
5090-
DartType staticInvokeType;
5091-
50925071
/**
50935072
* The element associated with the function being invoked based on propagated
50945073
* type information, or `null` if the AST structure has not been resolved or
50955074
* the function could not be resolved.
50965075
*/
50975076
ExecutableElement propagatedElement;
50985077

5099-
/**
5100-
* Like [staticInvokeType], but reflects propagated type information.
5101-
*/
5102-
DartType propagatedInvokeType;
5103-
51045078
/**
51055079
* Initialize a newly created function expression invocation.
51065080
*/
51075081
FunctionExpressionInvocationImpl(Expression function,
5108-
TypeArgumentList typeArguments, ArgumentList argumentList) {
5082+
TypeArgumentList typeArguments, ArgumentList argumentList)
5083+
: super(typeArguments, argumentList) {
51095084
_function = _becomeParentOf(function);
5110-
_typeArguments = _becomeParentOf(typeArguments);
5111-
_argumentList = _becomeParentOf(argumentList);
5112-
}
5113-
5114-
@override
5115-
ArgumentList get argumentList => _argumentList;
5116-
5117-
@override
5118-
void set argumentList(ArgumentList argumentList) {
5119-
_argumentList = _becomeParentOf(argumentList);
51205085
}
51215086

51225087
@override
@@ -5149,14 +5114,6 @@ class FunctionExpressionInvocationImpl extends ExpressionImpl
51495114
@override
51505115
int get precedence => 15;
51515116

5152-
@override
5153-
TypeArgumentList get typeArguments => _typeArguments;
5154-
5155-
@override
5156-
void set typeArguments(TypeArgumentList typeArguments) {
5157-
_typeArguments = _becomeParentOf(typeArguments);
5158-
}
5159-
51605117
@override
51615118
accept(AstVisitor visitor) => visitor.visitFunctionExpressionInvocation(this);
51625119

@@ -6166,6 +6123,55 @@ class InterpolationStringImpl extends InterpolationElementImpl
61666123
void visitChildren(AstVisitor visitor) {}
61676124
}
61686125

6126+
/**
6127+
* Common base class for [FunctionExpressionInvocationImpl] and
6128+
* [MethodInvocationImpl].
6129+
*/
6130+
abstract class InvocationExpressionImpl extends ExpressionImpl
6131+
implements InvocationExpression {
6132+
/**
6133+
* The type arguments to be applied to the method being invoked, or `null` if
6134+
* no type arguments were provided.
6135+
*/
6136+
TypeArgumentList _typeArguments;
6137+
6138+
/**
6139+
* The list of arguments to the function.
6140+
*/
6141+
ArgumentList _argumentList;
6142+
6143+
@override
6144+
DartType propagatedInvokeType;
6145+
6146+
@override
6147+
DartType staticInvokeType;
6148+
6149+
/**
6150+
* Initialize a newly created invocation.
6151+
*/
6152+
InvocationExpressionImpl(
6153+
TypeArgumentList typeArguments, ArgumentList argumentList) {
6154+
_typeArguments = _becomeParentOf(typeArguments);
6155+
_argumentList = _becomeParentOf(argumentList);
6156+
}
6157+
6158+
@override
6159+
ArgumentList get argumentList => _argumentList;
6160+
6161+
@override
6162+
void set argumentList(ArgumentList argumentList) {
6163+
_argumentList = _becomeParentOf(argumentList);
6164+
}
6165+
6166+
@override
6167+
TypeArgumentList get typeArguments => _typeArguments;
6168+
6169+
@override
6170+
void set typeArguments(TypeArgumentList typeArguments) {
6171+
_typeArguments = _becomeParentOf(typeArguments);
6172+
}
6173+
}
6174+
61696175
/**
61706176
* An is expression.
61716177
*
@@ -6959,7 +6965,8 @@ class MethodDeclarationImpl extends ClassMemberImpl
69596965
* > methodInvocation ::=
69606966
* > ([Expression] '.')? [SimpleIdentifier] [TypeArgumentList]? [ArgumentList]
69616967
*/
6962-
class MethodInvocationImpl extends ExpressionImpl implements MethodInvocation {
6968+
class MethodInvocationImpl extends InvocationExpressionImpl
6969+
implements MethodInvocation {
69636970
/**
69646971
* The expression producing the object on which the method is defined, or
69656972
* `null` if there is no target (that is, the target is implicitly `this`).
@@ -6979,32 +6986,6 @@ class MethodInvocationImpl extends ExpressionImpl implements MethodInvocation {
69796986
*/
69806987
SimpleIdentifier _methodName;
69816988

6982-
/**
6983-
* The type arguments to be applied to the method being invoked, or `null` if
6984-
* no type arguments were provided.
6985-
*/
6986-
TypeArgumentList _typeArguments;
6987-
6988-
/**
6989-
* The list of arguments to the method.
6990-
*/
6991-
ArgumentList _argumentList;
6992-
6993-
/**
6994-
* The function type of the method invocation, or `null` if the AST
6995-
* structure has not been resolved, or if the invoke could not be resolved.
6996-
*
6997-
* This will usually be a [FunctionType], but it can also be an
6998-
* [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
6999-
* interface type that implements `Function`.
7000-
*/
7001-
DartType staticInvokeType;
7002-
7003-
/**
7004-
* Like [staticInvokeType], but reflects propagated type information.
7005-
*/
7006-
DartType propagatedInvokeType;
7007-
70086989
/**
70096990
* Initialize a newly created method invocation. The [target] and [operator]
70106991
* can be `null` if there is no target.
@@ -7014,19 +6995,10 @@ class MethodInvocationImpl extends ExpressionImpl implements MethodInvocation {
70146995
this.operator,
70156996
SimpleIdentifier methodName,
70166997
TypeArgumentList typeArguments,
7017-
ArgumentList argumentList) {
6998+
ArgumentList argumentList)
6999+
: super(typeArguments, argumentList) {
70187000
_target = _becomeParentOf(target);
70197001
_methodName = _becomeParentOf(methodName);
7020-
_typeArguments = _becomeParentOf(typeArguments);
7021-
_argumentList = _becomeParentOf(argumentList);
7022-
}
7023-
7024-
@override
7025-
ArgumentList get argumentList => _argumentList;
7026-
7027-
@override
7028-
void set argumentList(ArgumentList argumentList) {
7029-
_argumentList = _becomeParentOf(argumentList);
70307002
}
70317003

70327004
@override
@@ -7049,6 +7021,9 @@ class MethodInvocationImpl extends ExpressionImpl implements MethodInvocation {
70497021
@override
70507022
Token get endToken => _argumentList.endToken;
70517023

7024+
@override
7025+
Expression get function => methodName;
7026+
70527027
@override
70537028
bool get isCascaded =>
70547029
operator != null && operator.type == TokenType.PERIOD_PERIOD;
@@ -7087,14 +7062,6 @@ class MethodInvocationImpl extends ExpressionImpl implements MethodInvocation {
70877062
_target = _becomeParentOf(expression);
70887063
}
70897064

7090-
@override
7091-
TypeArgumentList get typeArguments => _typeArguments;
7092-
7093-
@override
7094-
void set typeArguments(TypeArgumentList typeArguments) {
7095-
_typeArguments = _becomeParentOf(typeArguments);
7096-
}
7097-
70987065
@override
70997066
accept(AstVisitor visitor) => visitor.visitMethodInvocation(this);
71007067

0 commit comments

Comments
 (0)