Skip to content

Commit

Permalink
fix generic function expressions, part of #25175
Browse files Browse the repository at this point in the history
  • Loading branch information
John Messerly committed Jan 13, 2016
1 parent 666964b commit 351ccc5
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 21 deletions.
34 changes: 17 additions & 17 deletions pkg/analyzer/lib/src/dart/element/type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -216,22 +216,8 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
* Private constructor.
*/
FunctionTypeImpl._(TypeParameterizedElement element, String name,
this.prunedTypedefs, List<DartType> typeArguments, this._isInstantiated)
: super(element, name) {
if (typeArguments == null) {
// TODO(jmesserly): reuse TypeParameterTypeImpl.getTypes once we can
// make it generic, which will allow it to return List<DartType> instead
// of List<TypeParameterType>.
if (typeParameters.isEmpty) {
typeArguments = DartType.EMPTY_LIST;
} else {
typeArguments = new List<DartType>.from(
typeParameters.map((t) => t.type),
growable: false);
}
}
_typeArguments = typeArguments;
}
this.prunedTypedefs, this._typeArguments, this._isInstantiated)
: super(element, name);

/**
* Return the base parameter elements of this function element.
Expand Down Expand Up @@ -493,7 +479,21 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
/**
* A list containing the actual types of the type arguments.
*/
List<DartType> get typeArguments => _typeArguments;
List<DartType> get typeArguments {
if (_typeArguments == null) {
// TODO(jmesserly): reuse TypeParameterTypeImpl.getTypes once we can
// make it generic, which will allow it to return List<DartType> instead
// of List<TypeParameterType>.
if (typeParameters.isEmpty) {
_typeArguments = DartType.EMPTY_LIST;
} else {
_typeArguments = new List<DartType>.from(
typeParameters.map((t) => t.type),
growable: false);
}
}
return _typeArguments;
}

@override
List<TypeParameterElement> get typeParameters {
Expand Down
4 changes: 0 additions & 4 deletions pkg/analyzer/lib/src/generated/resolver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3100,10 +3100,6 @@ class ElementBuilder extends RecursiveAstVisitor<Object> {
if (_functionTypesToFix != null) {
_functionTypesToFix.add(element);
} else {
// TODO(jmesserly): for local functions inside of top-level generic
// functions, this is probably not right. The function type should be set
// after the enclosingElement is set, otherwise we won't be able to
// substitute those type parameters later.
element.type = new FunctionTypeImpl(element);
}
element.hasImplicitReturnType = true;
Expand Down
6 changes: 6 additions & 0 deletions pkg/analyzer/test/generated/resolver_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13043,6 +13043,8 @@ var topG = topF;
void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
var c = new C<int>();
/*=T*/ lf/*<T>*/(/*=T*/ e) => null;

var lambdaCall = (/*<E>*/(/*=E*/ e) => e)/*<int>*/(3);
var methodCall = (c.f)/*<int>*/(3);
var staticCall = (C.g)/*<int>*/(3);
var staticFieldCall = (C.h)/*<int>*/(3);
Expand All @@ -13059,6 +13061,7 @@ void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
expect(_findIdentifier('localCall').staticType.toString(), "int");
expect(_findIdentifier('paramCall').staticType.toString(), "int");
expect(_findIdentifier('lambdaCall').staticType.toString(), "int");
}

void fail_genericMethod_functionExpressionInvocation_inferred() {
Expand All @@ -13074,6 +13077,8 @@ var topG = topF;
void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
var c = new C<int>();
/*=T*/ lf/*<T>*/(/*=T*/ e) => null;

var lambdaCall = (/*<E>*/(/*=E*/ e) => e)(3);
var methodCall = (c.f)(3);
var staticCall = (C.g)(3);
var staticFieldCall = (C.h)(3);
Expand All @@ -13090,6 +13095,7 @@ void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
expect(_findIdentifier('localCall').staticType.toString(), "int");
expect(_findIdentifier('paramCall').staticType.toString(), "int");
expect(_findIdentifier('lambdaCall').staticType.toString(), "int");
}

void fail_genericMethod_functionInvocation_inferred() {
Expand Down

0 comments on commit 351ccc5

Please sign in to comment.