Use formal parameters location to access function expression types.
There is still an issue with using type parameters inside function
expression bodies. https://github.com/dart-lang/sdk/issues/33722
R=brianwilkerson@google.com, paulberry@google.com
Change-Id: I9c1a4f8b6d6545a22de1b67953a7d833bf96df03
Reviewed-on: https://dart-review.googlesource.com/63365
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/fasta/resolution_applier.dart b/pkg/analyzer/lib/src/fasta/resolution_applier.dart
index 39bf30a..2ba57bf 100644
--- a/pkg/analyzer/lib/src/fasta/resolution_applier.dart
+++ b/pkg/analyzer/lib/src/fasta/resolution_applier.dart
@@ -313,7 +313,7 @@
parameterList.accept(this);
node.body.accept(this);
- _storeFunctionType(_get(node).inferredType, element);
+ _storeFunctionType(_get(node.parameters).inferredType, element);
// Associate the elements with the nodes.
if (element != null) {
diff --git a/pkg/analyzer/test/generated/hint_code_kernel_test.dart b/pkg/analyzer/test/generated/hint_code_kernel_test.dart
index 14b0e84..6d58259 100644
--- a/pkg/analyzer/test/generated/hint_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_kernel_test.dart
@@ -274,20 +274,6 @@
return super.test_strongMode_downCastCompositeWarn();
}
- @override
- @failingTest
- test_strongMode_topLevelInstanceGetter_implicitlyTyped_invoke() {
- return super
- .test_strongMode_topLevelInstanceGetter_implicitlyTyped_invoke();
- }
-
- @override
- @failingTest
- test_strongMode_topLevelInstanceGetter_implicitlyTyped_invoke_explicit_type_params() {
- return super
- .test_strongMode_topLevelInstanceGetter_implicitlyTyped_invoke_explicit_type_params();
- }
-
@failingTest
@override
test_undefinedOperator_binaryExpression() async {
diff --git a/pkg/analyzer/test/src/context/mock_sdk.dart b/pkg/analyzer/test/src/context/mock_sdk.dart
index e49e2fb..ed684ec 100644
--- a/pkg/analyzer/test/src/context/mock_sdk.dart
+++ b/pkg/analyzer/test/src/context/mock_sdk.dart
@@ -285,7 +285,7 @@
}
class List<E> implements Iterable<E> {
- List();
+ List([int length]);
factory List.from(Iterable elements, {bool growable: true}) => null;
void add(E value) {}
void addAll(Iterable<E> iterable) {}
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart
index 4121a0b..e1153f2 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart
@@ -29,6 +29,24 @@
@override
@failingTest
@potentialAnalyzerProblem
+ test_closure_generic() async {
+ // Bad state: Not found T in main() → dynamic
+ // https://github.com/dart-lang/sdk/issues/33722
+ await super.test_closure_generic();
+ }
+
+ @override
+ @failingTest
+ @potentialAnalyzerProblem
+ test_local_function_generic() async {
+ // Bad state: Not found T in main() → void
+ // https://github.com/dart-lang/sdk/issues/33722
+ await super.test_local_function_generic();
+ }
+
+ @override
+ @failingTest
+ @potentialAnalyzerProblem
test_unresolved_assignment_left_identifier_compound() async {
await super.test_unresolved_assignment_left_identifier_compound();
}
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 76bb3ff..6007a37 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -1750,6 +1750,38 @@
}
}
+ test_closure_generic() async {
+ addTestFile(r'''
+main() {
+ foo(<T>() => new List<T>(4));
+}
+
+void foo(List<T> Function<T>() createList) {}
+''');
+ await resolveTestFile();
+
+ var closure = findNode.functionExpression('<T>() =>');
+ assertType(closure, '<T>() → List<T>');
+
+ FunctionElementImpl closureElement = closure.element;
+ expect(closureElement.enclosingElement, findElement.function('main'));
+ expect(closureElement.returnType.toString(), 'List<T>');
+ expect(closureElement.parameters, isEmpty);
+
+ var typeParameters = closureElement.typeParameters;
+ expect(typeParameters, hasLength(1));
+
+ TypeParameterElement tElement = typeParameters[0];
+ expect(tElement.name, 'T');
+ expect(tElement.nameOffset, 16);
+
+ var creation = findNode.instanceCreation('new List');
+ assertType(creation, 'List<T>');
+
+ var tRef = findNode.simple('T>(4)');
+ assertElement(tRef, tElement);
+ }
+
test_closure_inField() async {
addTestFile(r'''
class C {
@@ -3074,7 +3106,10 @@
test_local_function_generic() async {
addTestFile(r'''
void main() {
- T f<T, U>(T a, U b) {}
+ T f<T, U>(T a, U b) {
+ a;
+ b;
+ }
var v = f(1, '2');
}
''');
@@ -3118,23 +3153,31 @@
expect(fExpression.element, same(fElement));
{
- List<ParameterElement> elements = fElement.parameters;
- expect(elements, hasLength(2));
+ List<ParameterElement> parameters = fElement.parameters;
+ expect(parameters, hasLength(2));
List<FormalParameter> nodes = fExpression.parameters.parameters;
expect(nodes, hasLength(2));
- _assertSimpleParameter(nodes[0], elements[0],
+ _assertSimpleParameter(nodes[0], parameters[0],
name: 'a',
offset: 28,
kind: ParameterKind.REQUIRED,
type: tElement.type);
- _assertSimpleParameter(nodes[1], elements[1],
+ _assertSimpleParameter(nodes[1], parameters[1],
name: 'b',
offset: 33,
kind: ParameterKind.REQUIRED,
type: uElement.type);
+
+ var aRef = findNode.simple('a;');
+ assertElement(aRef, parameters[0]);
+ assertType(aRef, 'T');
+
+ var bRef = findNode.simple('b;');
+ assertElement(bRef, parameters[1]);
+ assertType(bRef, 'U');
}
VariableDeclarationStatement vStatement = mainStatements[1];
@@ -7315,6 +7358,15 @@
fail('Not found class field: $name');
}
+ FunctionElement function(String name) {
+ for (var function in unitElement.functions) {
+ if (function.name == name) {
+ return function;
+ }
+ }
+ fail('Not found top-level function: $name');
+ }
+
PropertyAccessorElement getter(String name) {
for (var class_ in unitElement.types) {
for (var accessor in class_.accessors) {
@@ -7385,6 +7437,18 @@
return _node(search).getAncestor((n) => n is CascadeExpression);
}
+ FunctionExpression functionExpression(String search) {
+ return _node(search).getAncestor((n) => n is FunctionExpression);
+ }
+
+ InstanceCreationExpression instanceCreation(String search) {
+ return _node(search).getAncestor((n) => n is InstanceCreationExpression);
+ }
+
+ MethodInvocation methodInvocation(String search) {
+ return _node(search).getAncestor((n) => n is MethodInvocation);
+ }
+
SimpleIdentifier simple(String search) {
return _node(search);
}
@@ -7396,6 +7460,6 @@
fail('The pattern |$search| is not unique in:\n$content');
}
expect(index, greaterThanOrEqualTo(0));
- return new NodeLocator(index).searchWithin(result.unit);
+ return new NodeLocator2(index).searchWithin(result.unit);
}
}