Skip to content

Commit 7696ec5

Browse files
committed
Support for using generic function types in other AST structures.
[email protected] BUG= Review-Url: https://codereview.chromium.org/2814063003 .
1 parent dd150dd commit 7696ec5

File tree

2 files changed

+72
-8
lines changed

2 files changed

+72
-8
lines changed

pkg/analyzer/lib/src/generated/declaration_resolver.dart

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:analyzer/dart/ast/ast.dart';
88
import 'package:analyzer/dart/ast/token.dart';
99
import 'package:analyzer/dart/ast/visitor.dart';
1010
import 'package:analyzer/dart/element/element.dart';
11+
import 'package:analyzer/dart/element/type.dart';
1112
import 'package:analyzer/exception/exception.dart';
1213
import 'package:analyzer/src/dart/ast/ast.dart';
1314
import 'package:analyzer/src/dart/element/builder.dart';
@@ -225,6 +226,7 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
225226
elementName: functionName.name + '=');
226227
}
227228
}
229+
_setGenericFunctionType(node.returnType, element.returnType);
228230
node.functionExpression.element = element;
229231
_walker._elementHolder?.addFunction(element);
230232
_walk(new ElementWalker.forExecutable(element, _enclosingUnit), () {
@@ -278,6 +280,7 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
278280
@override
279281
Object visitGenericFunctionType(GenericFunctionType node) {
280282
GenericFunctionTypeElement element = node.type.element;
283+
_setGenericFunctionType(node.returnType, element.returnType);
281284
_walk(new ElementWalker.forGenericFunctionType(element), () {
282285
super.visitGenericFunctionType(node);
283286
});
@@ -288,8 +291,7 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
288291
Object visitGenericTypeAlias(GenericTypeAlias node) {
289292
GenericTypeAliasElementImpl element =
290293
_match(node.name, _walker.getTypedef());
291-
(node.functionType as GenericFunctionTypeImpl)?.type =
292-
element.function?.type;
294+
_setGenericFunctionType(node.functionType, element.function?.type);
293295
_walk(new ElementWalker.forGenericTypeAlias(element), () {
294296
super.visitGenericTypeAlias(node);
295297
});
@@ -357,6 +359,7 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
357359
elementName: nameOfMethod + '=');
358360
}
359361
}
362+
_setGenericFunctionType(node.returnType, element.returnType);
360363
_walk(new ElementWalker.forExecutable(element, _enclosingUnit), () {
361364
super.visitMethodDeclaration(node);
362365
});
@@ -393,10 +396,7 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
393396
ParameterElement element =
394397
_match(node.identifier, _walker.getParameter());
395398
(node as SimpleFormalParameterImpl).element = element;
396-
TypeAnnotation type = node.type;
397-
if (type is GenericFunctionTypeImpl) {
398-
type.type = element.type;
399-
}
399+
_setGenericFunctionType(node.type, element.type);
400400
_walk(new ElementWalker.forParameter(element), () {
401401
super.visitSimpleFormalParameter(node);
402402
});
@@ -463,10 +463,13 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
463463
if (_walker.elementBuilder != null) {
464464
return _walker.elementBuilder.visitVariableDeclarationList(node);
465465
} else {
466-
super.visitVariableDeclarationList(node);
466+
node.variables.accept(this);
467+
VariableElement firstVariable = node.variables[0].element;
468+
_setGenericFunctionType(node.type, firstVariable.type);
469+
node.type?.accept(this);
467470
if (node.parent is! FieldDeclaration &&
468471
node.parent is! TopLevelVariableDeclaration) {
469-
_resolveMetadata(node, node.metadata, node.variables[0].element);
472+
_resolveMetadata(node, node.metadata, firstVariable);
470473
}
471474
return null;
472475
}
@@ -537,6 +540,15 @@ class DeclarationResolver extends RecursiveAstVisitor<Object> {
537540
}
538541
}
539542

543+
/**
544+
* If the given [typeNode] is a [GenericFunctionType], set its [type].
545+
*/
546+
void _setGenericFunctionType(TypeAnnotation typeNode, DartType type) {
547+
if (typeNode is GenericFunctionTypeImpl) {
548+
typeNode.type = type;
549+
}
550+
}
551+
540552
/**
541553
* Recurses through the element model and AST, verifying that all elements are
542554
* matched.

pkg/analyzer/test/generated/declaration_resolver_test.dart

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,58 @@ void set zzz(_) {}
468468
expect(getterName.staticElement, same(setterElement));
469469
}
470470

471+
test_genericFunction_asFunctionReturnType() async {
472+
String code = r'''
473+
Function(int, String) f() => null;
474+
''';
475+
CompilationUnit unit = await resolveSource(code);
476+
// re-resolve
477+
_cloneResolveUnit(unit);
478+
// no other validations than built into DeclarationResolver
479+
}
480+
481+
test_genericFunction_asGenericFunctionReturnType() async {
482+
String code = r'''
483+
typedef F<T> = int Function(T t, S s) Function<S>(int);
484+
''';
485+
CompilationUnit unit = await resolveSource(code);
486+
// re-resolve
487+
_cloneResolveUnit(unit);
488+
// no other validations than built into DeclarationResolver
489+
}
490+
491+
test_genericFunction_asMethodReturnType() async {
492+
String code = r'''
493+
class C {
494+
Function(int, String) m() => null;
495+
}
496+
''';
497+
CompilationUnit unit = await resolveSource(code);
498+
// re-resolve
499+
_cloneResolveUnit(unit);
500+
// no other validations than built into DeclarationResolver
501+
}
502+
503+
test_genericFunction_asParameterReturnType() async {
504+
String code = r'''
505+
f(Function(int, String) p) => null;
506+
''';
507+
CompilationUnit unit = await resolveSource(code);
508+
// re-resolve
509+
_cloneResolveUnit(unit);
510+
// no other validations than built into DeclarationResolver
511+
}
512+
513+
test_genericFunction_asTopLevelVariableType() async {
514+
String code = r'''
515+
int Function(int, String) v;
516+
''';
517+
CompilationUnit unit = await resolveSource(code);
518+
// re-resolve
519+
_cloneResolveUnit(unit);
520+
// no other validations than built into DeclarationResolver
521+
}
522+
471523
test_invalid_functionDeclaration_getter_inFunction() async {
472524
String code = r'''
473525
var v = (() {

0 commit comments

Comments
 (0)