Adapt ResolutionApplier.visitFormalParameterList to handle function-typed formal parameters.
Fixes #33845.
Change-Id: I6de918d644e9a22b1a9f9cd384b972047078a472
Reviewed-on: https://dart-review.googlesource.com/65162
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 015946f..d326fcd 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -1220,7 +1220,7 @@
}
@override
- void endFunctionTypedFormalParameter() {
+ void endFunctionTypedFormalParameter(Token nameToken) {
debugEvent("FunctionTypedFormalParameter");
FormalParameterList formalParameters = pop();
diff --git a/pkg/analyzer/lib/src/fasta/resolution_applier.dart b/pkg/analyzer/lib/src/fasta/resolution_applier.dart
index 2125919..7c73f73 100644
--- a/pkg/analyzer/lib/src/fasta/resolution_applier.dart
+++ b/pkg/analyzer/lib/src/fasta/resolution_applier.dart
@@ -258,9 +258,19 @@
}
if (normalParameter is SimpleFormalParameter) {
normalParameter.type?.accept(this);
+ } else if (normalParameter is FieldFormalParameter) {
+ normalParameter.type?.accept(this);
+ } else if (normalParameter is FunctionTypedFormalParameter) {
+ normalParameter.returnType?.accept(this);
+ normalParameter.typeParameters?.accept(this);
+ normalParameter.parameters?.accept(this);
+ var data = _get(normalParameter.identifier);
+ normalParameter.identifier.staticType = data.inferredType;
} else {
- // TODO(paulberry): handle function typed formal parameters
- // (dartbug.com/33845)
+ // Now that DefaultFormalParameter has been handled, all parameters
+ // should be SimpleFormalParameter, FieldFormalParameter, or
+ // FunctionTypedFormalParameter.
+ throw new UnimplementedError('${normalParameter.runtimeType}');
}
}
}
diff --git a/pkg/analyzer/lib/src/fasta/resolution_storer.dart b/pkg/analyzer/lib/src/fasta/resolution_storer.dart
index 72fdf19..218029f 100644
--- a/pkg/analyzer/lib/src/fasta/resolution_storer.dart
+++ b/pkg/analyzer/lib/src/fasta/resolution_storer.dart
@@ -291,6 +291,11 @@
ExpressionJudgment judgment, int location, DartType inferredType) =>
genericExpression("functionExpression", location, inferredType);
+ @override
+ void functionTypedFormalParameter(int location, DartType type) {
+ _store(location, inferredType: type);
+ }
+
void genericExpression(
String expressionType, int location, DartType inferredType) {
_store(location, inferredType: inferredType);
@@ -615,9 +620,10 @@
isTypeReference: true);
}
- void typeVariableDeclaration(
+ void typeVariableDeclaration(int location,
covariant TypeVariableBinder binder, TypeParameter typeParameter) {
_storeTypeVariableDeclaration(binder.fileOffset, typeParameter);
+ _store(location, declaration: binder.fileOffset);
}
void variableAssign(
diff --git a/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart b/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
index 73bce7e..6f40a3c 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
@@ -185,13 +185,6 @@
@override
@failingTest
- test_forEach_genericFunctionType() {
- // Bad state: Not found T in main() → dynamic
- return super.test_forEach_genericFunctionType();
- }
-
- @override
- @failingTest
@FastaProblem('https://github.com/dart-lang/sdk/issues/33799')
test_functionTypeAlias_scope_signature() async {
// Caused by Bad state: Found 1 annotation nodes and 0 element annotations
diff --git a/pkg/analyzer/test/generated/parser_fasta_listener.dart b/pkg/analyzer/test/generated/parser_fasta_listener.dart
index 9697a3c..daa3ac4 100644
--- a/pkg/analyzer/test/generated/parser_fasta_listener.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_listener.dart
@@ -795,9 +795,9 @@
}
@override
- void endFunctionTypedFormalParameter() {
+ void endFunctionTypedFormalParameter(Token nameToken) {
end('FunctionTypedFormalParameter');
- super.endFunctionTypedFormalParameter();
+ super.endFunctionTypedFormalParameter(nameToken);
}
@override
diff --git a/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart b/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
index e8408a0..92bc27e 100644
--- a/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
@@ -1410,6 +1410,13 @@
@override
@failingTest
+ test_typeAnnotationDeferredClass_fieldFormalParameter() {
+ // Bad state: No data for A at 73 in /lib2.dart
+ return super.test_typeAnnotationDeferredClass_fieldFormalParameter();
+ }
+
+ @override
+ @failingTest
@potentialAnalyzerProblem
test_typeAnnotationDeferredClass_functionDeclaration_returnType() async {
return super
@@ -1418,6 +1425,14 @@
@override
@failingTest
+ test_typeAnnotationDeferredClass_functionTypedFormalParameter_returnType() {
+ // Bad state: No data for A at 52 in /lib2.dart
+ return super
+ .test_typeAnnotationDeferredClass_functionTypedFormalParameter_returnType();
+ }
+
+ @override
+ @failingTest
test_typeAnnotationDeferredClass_isExpression() {
// Bad state: No data for A at 77 in /lib2.dart
return super.test_typeAnnotationDeferredClass_isExpression();
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart
index e62131b..ab5a476 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart
@@ -156,6 +156,13 @@
await super.test_getResult_doesNotExist();
}
+ @override
+ @failingTest
+ test_getResult_functionTypeFormalParameter_withTypeParameter() {
+ // Failed assertion: 'element != null': is not true.
+ return super.test_getResult_functionTypeFormalParameter_withTypeParameter();
+ }
+
@failingTest
@potentialAnalyzerProblem
@override
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 fdfdd7c..8f9e062 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -3967,6 +3967,32 @@
}
}
+ test_local_function_with_function_typed_parameter() async {
+ addTestFile('''
+class C {}
+class D {}
+class E {}
+void f() {
+ void g(C callback<T extends E>(D d)) {}
+}
+''');
+ await resolveTestFile();
+ var callback = findNode.simple('callback');
+ assertType(callback, '<T extends E>(D) → C');
+ var cReference = findNode.simple('C callback');
+ var cElement = findElement.class_('C');
+ assertType(cReference, 'C');
+ assertElement(cReference, cElement);
+ var dReference = findNode.simple('D d');
+ var dElement = findElement.class_('D');
+ assertType(dReference, 'D');
+ assertElement(dReference, dElement);
+ var eReference = findNode.simple('E>');
+ var eElement = findElement.class_('E');
+ assertType(eReference, 'E');
+ assertElement(eReference, eElement);
+ }
+
test_local_parameter() async {
String content = r'''
void main(int p) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 3838ba4..6f75480 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -2439,7 +2439,7 @@
}
@override
- void endFunctionTypedFormalParameter() {
+ void endFunctionTypedFormalParameter(Token nameToken) {
debugEvent("FunctionTypedFormalParameter");
if (inCatchClause || functionNestingLevel != 0) {
exitLocalScope();
@@ -2448,6 +2448,7 @@
DartType returnType = pop();
List<TypeParameter> typeVariables = typeVariableBuildersToKernel(pop());
FunctionType type = formals.toFunctionType(returnType, typeVariables);
+ _typeInferrer.functionTypedFormalParameter(nameToken.offset, type);
exitLocalScope();
push(type);
functionNestingLevel--;
@@ -3811,7 +3812,6 @@
variable.binder = _typeInferrer.binderForTypeVariable(
variable, variable.charOffset, variable.name);
}
- storeTypeUse(offsetForToken(token), variable.target);
if (annotations != null) {
_typeInferrer.inferMetadata(this, factory, annotations);
for (Expression annotation in annotations) {
@@ -3893,7 +3893,8 @@
int i = 0;
for (KernelTypeVariableBuilder builder in typeVariableBuilders) {
var typeParameter = builder.target;
- _typeInferrer.typeVariableDeclaration(builder.binder, typeParameter);
+ _typeInferrer.typeVariableDeclaration(
+ builder.charOffset, builder.binder, typeParameter);
typeParameters[i++] = typeParameter;
}
return typeParameters;
diff --git a/pkg/front_end/lib/src/fasta/kernel/factory.dart b/pkg/front_end/lib/src/fasta/kernel/factory.dart
index 885c394..5ede5ca 100644
--- a/pkg/front_end/lib/src/fasta/kernel/factory.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/factory.dart
@@ -204,6 +204,8 @@
Expression functionExpression(
ExpressionJudgment judgment, int fileOffset, DartType inferredType);
+ Object functionTypedFormalParameter(int fileOffset, DartType type);
+
Expression ifNull(
ExpressionJudgment judgment,
int fileOffset,
@@ -444,7 +446,7 @@
DartType type);
Object typeVariableDeclaration(
- covariant Object binder, TypeParameter typeParameter);
+ int fileOffset, covariant Object binder, TypeParameter typeParameter);
Expression variableAssign(
ExpressionJudgment judgment,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_factory.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_factory.dart
index f474c5e..31c1598 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_factory.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_factory.dart
@@ -303,6 +303,9 @@
}
@override
+ void functionTypedFormalParameter(int fileOffset, DartType type) {}
+
+ @override
Expression ifNull(
ExpressionJudgment judgment,
int fileOffset,
@@ -662,7 +665,7 @@
DartType type) {}
@override
- TypeParameter typeVariableDeclaration(
+ TypeParameter typeVariableDeclaration(int fileOffset,
covariant KernelTypeVariableBuilder binder, TypeParameter typeParameter) {
return typeParameter;
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/toplevel_inference_factory.dart b/pkg/front_end/lib/src/fasta/kernel/toplevel_inference_factory.dart
index 6aad140..60e7542 100644
--- a/pkg/front_end/lib/src/fasta/kernel/toplevel_inference_factory.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/toplevel_inference_factory.dart
@@ -241,6 +241,9 @@
ExpressionJudgment judgment, int fileOffset, DartType inferredType) {}
@override
+ void functionTypedFormalParameter(int fileOffset, DartType type) {}
+
+ @override
void ifNull(ExpressionJudgment judgment, int fileOffset, void leftOperand,
Token operator, void rightOperand, DartType inferredType) {}
@@ -506,7 +509,7 @@
@override
void typeVariableDeclaration(
- covariant void binder, TypeParameter typeParameter) {}
+ int fileOffset, covariant void binder, TypeParameter typeParameter) {}
@override
void variableAssign(
diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
index 3af09ee..467e833 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -641,8 +641,8 @@
}
@override
- void endFunctionTypedFormalParameter() {
- listener?.endFunctionTypedFormalParameter();
+ void endFunctionTypedFormalParameter(Token nameToken) {
+ listener?.endFunctionTypedFormalParameter(nameToken);
}
@override
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index c69cf17..1f6dd5c 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -996,7 +996,7 @@
/// - type variables
/// - return type
/// - formal parameters
- void endFunctionTypedFormalParameter() {
+ void endFunctionTypedFormalParameter(Token nameToken) {
logEvent("FunctionTypedFormalParameter");
}
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 861b15c..0c820a7 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -1350,7 +1350,7 @@
token = typeInfo.parseType(beforeType, this);
endInlineFunctionType = parseFormalParametersRequiredOpt(
endInlineFunctionType, MemberKind.FunctionTypedParameter);
- listener.endFunctionTypedFormalParameter();
+ listener.endFunctionTypedFormalParameter(beforeInlineFunctionType);
// Generalized function types don't allow inline function types.
// The following isn't allowed:
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 8f8c5c1..597ecd0 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -1016,7 +1016,7 @@
}
@override
- void endFunctionTypedFormalParameter() {
+ void endFunctionTypedFormalParameter(Token nameToken) {
debugEvent("FunctionTypedFormalParameter");
List<FormalParameterBuilder> formals = pop();
int formalsOffset = pop();
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart
index 4b2a6db..17332eb 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart
@@ -216,6 +216,8 @@
void functionExpression(
ExpressionJudgment judgment, Location location, DartType inferredType);
+ void functionTypedFormalParameter(Location location, DartType type);
+
void ifNull(ExpressionJudgment judgment, Location location, void leftOperand,
Token operator, void rightOperand, DartType inferredType);
@@ -451,7 +453,7 @@
DartType type);
void typeVariableDeclaration(
- covariant Object binder, TypeParameter typeParameter);
+ Location location, covariant Object binder, TypeParameter typeParameter);
void variableAssign(
ExpressionJudgment judgment,
@@ -686,6 +688,8 @@
void functionExpression(
ExpressionJudgment judgment, location, DartType inferredType) {}
+ void functionTypedFormalParameter(int location, DartType type) {}
+
@override
void ifNull(ExpressionJudgment judgment, location, void leftOperand,
Token operator, void rightOperand, DartType inferredType) {}
@@ -938,7 +942,7 @@
@override
void typeVariableDeclaration(
- covariant void binder, TypeParameter typeParameter) {}
+ location, covariant void binder, TypeParameter typeParameter) {}
@override
void variableAssign(
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index e03c017..afe2bbe 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -342,6 +342,8 @@
Object binderForTypeVariable(
KernelTypeVariableBuilder builder, int fileOffset, String name);
+ void functionTypedFormalParameter(int offset, DartType type);
+
/// Performs full type inference on the given field initializer.
void inferFieldInitializer<Expression, Statement, Initializer, Type>(
InferenceHelper helper,
@@ -390,7 +392,8 @@
void storeTypeUse(int offset, Node node);
- void typeVariableDeclaration(Object binder, TypeParameter typeParameter);
+ void typeVariableDeclaration(
+ int offset, Object binder, TypeParameter typeParameter);
void voidType(int offset, Token token, DartType type);
}
@@ -415,6 +418,8 @@
void binderForTypeVariable(
KernelTypeVariableBuilder builder, int fileOffset, String name) {}
+ void functionTypedFormalParameter(int offset, DartType type) {}
+
@override
void inferFieldInitializer<Expression, Statement, Initializer, Type>(
InferenceHelper helper,
@@ -465,7 +470,8 @@
void storeTypeUse(int offset, Node node) {}
@override
- void typeVariableDeclaration(Object binder, TypeParameter typeParameter) {}
+ void typeVariableDeclaration(
+ int offset, Object binder, TypeParameter typeParameter) {}
@override
void voidType(int offset, Token token, DartType type) {}
@@ -541,6 +547,10 @@
return listener.binderForTypeVariable(builder, fileOffset, name);
}
+ void functionTypedFormalParameter(int offset, DartType type) {
+ listener.functionTypedFormalParameter(offset, type);
+ }
+
bool isAssignable(DartType expectedType, DartType actualType) {
return typeSchemaEnvironment.isSubtypeOf(expectedType, actualType) ||
typeSchemaEnvironment.isSubtypeOf(actualType, expectedType);
@@ -1758,8 +1768,9 @@
}
@override
- void typeVariableDeclaration(Object binder, TypeParameter typeParameter) {
- return listener.typeVariableDeclaration(binder, typeParameter);
+ void typeVariableDeclaration(
+ int offset, Object binder, TypeParameter typeParameter) {
+ return listener.typeVariableDeclaration(offset, binder, typeParameter);
}
@override