Add support for representing nullable function-typed parameters
Change-Id: Ia667236d5d60bb5c1aca7fc0747702f244182a19
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/104621
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 2e5f1ae..a34b97c 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -2810,7 +2810,8 @@
/// A function-typed formal parameter.
///
/// functionSignature ::=
-/// [TypeAnnotation]? [SimpleIdentifier] [TypeParameterList]? [FormalParameterList]
+/// [TypeAnnotation]? [SimpleIdentifier] [TypeParameterList]?
+/// [FormalParameterList] '?'?
///
/// Clients may not extend, implement or mix-in this class.
abstract class FunctionTypedFormalParameter implements NormalFormalParameter {
@@ -2821,6 +2822,11 @@
/// [parameters].
void set parameters(FormalParameterList parameters);
+ /// Return the question mark indicating that the function type is nullable, or
+ /// `null` if there is no question mark. Having a nullable function type means
+ /// that the parameter can be null.
+ Token get question;
+
/// Return the return type of the function, or `null` if the function does not
/// have a return type.
TypeAnnotation get returnType;
diff --git a/pkg/analyzer/lib/dart/ast/ast_factory.dart b/pkg/analyzer/lib/dart/ast/ast_factory.dart
index bf624d8..2796e1a 100644
--- a/pkg/analyzer/lib/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/dart/ast/ast_factory.dart
@@ -549,7 +549,8 @@
TypeAnnotation returnType,
@required SimpleIdentifier identifier,
TypeParameterList typeParameters,
- @required FormalParameterList parameters});
+ @required FormalParameterList parameters,
+ Token question});
/// Initialize a newly created generic function type.
GenericFunctionType genericFunctionType(
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 8a28fb8..8a79218 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -5186,6 +5186,9 @@
/// The parameters of the function-typed parameter.
FormalParameterListImpl _parameters;
+ @override
+ Token question;
+
/// Initialize a newly created formal parameter. Either or both of the
/// [comment] and [metadata] can be `null` if the parameter does not have the
/// corresponding attribute. The [returnType] can be `null` if no return type
@@ -5198,7 +5201,8 @@
TypeAnnotationImpl returnType,
SimpleIdentifierImpl identifier,
TypeParameterListImpl typeParameters,
- FormalParameterListImpl parameters)
+ FormalParameterListImpl parameters,
+ this.question)
: super(
comment, metadata, covariantKeyword, requiredKeyword, identifier) {
_returnType = _becomeParentOf(returnType);
diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
index ded10fd..1cd13f3 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
@@ -588,7 +588,7 @@
TypeParameterList typeParameters,
FormalParameterList parameters) =>
new FunctionTypedFormalParameterImpl(comment, metadata, null, null,
- returnType, identifier, typeParameters, parameters);
+ returnType, identifier, typeParameters, parameters, null);
@override
FunctionTypedFormalParameter functionTypedFormalParameter2(
@@ -599,9 +599,18 @@
TypeAnnotation returnType,
@required SimpleIdentifier identifier,
TypeParameterList typeParameters,
- @required FormalParameterList parameters}) =>
- new FunctionTypedFormalParameterImpl(comment, metadata, covariantKeyword,
- requiredKeyword, returnType, identifier, typeParameters, parameters);
+ @required FormalParameterList parameters,
+ Token question}) =>
+ new FunctionTypedFormalParameterImpl(
+ comment,
+ metadata,
+ covariantKeyword,
+ requiredKeyword,
+ returnType,
+ identifier,
+ typeParameters,
+ parameters,
+ question);
@override
GenericFunctionType genericFunctionType(
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 1a26ff2..807d3c6 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -600,7 +600,8 @@
returnType: cloneNode(node.returnType),
identifier: cloneNode(node.identifier),
typeParameters: cloneNode(node.typeParameters),
- parameters: cloneNode(node.parameters));
+ parameters: cloneNode(node.parameters),
+ question: cloneToken(node.question));
@override
AstNode visitGenericFunctionType(GenericFunctionType node) =>
@@ -3009,7 +3010,8 @@
returnType: _cloneNode(node.returnType),
identifier: _cloneNode(node.identifier),
typeParameters: _cloneNode(node.typeParameters),
- parameters: _cloneNode(node.parameters));
+ parameters: _cloneNode(node.parameters),
+ question: _mapToken(node.question));
@override
AstNode visitGenericFunctionType(GenericFunctionType node) =>
@@ -7406,6 +7408,9 @@
_visitNode(node.identifier);
_visitNode(node.typeParameters);
_visitNode(node.parameters);
+ if (node.question != null) {
+ _writer.print('?');
+ }
}
@override
@@ -8705,6 +8710,9 @@
safelyVisitNode(node.identifier);
safelyVisitNode(node.typeParameters);
safelyVisitNode(node.parameters);
+ if (node.question != null) {
+ sink.write('?');
+ }
}
@override
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index bcdc6f3..00cf65e 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -2393,6 +2393,16 @@
"f()", AstTestFactory.functionTypedFormalParameter(null, "f"));
}
+ void test_visitFunctionTypedFormalParameter_nullable() {
+ _assertSource(
+ "T f()?",
+ astFactory.functionTypedFormalParameter2(
+ returnType: AstTestFactory.typeName4("T"),
+ identifier: AstTestFactory.identifier3('f'),
+ parameters: AstTestFactory.formalParameterList([]),
+ question: TokenFactory.tokenFromType(TokenType.QUESTION)));
+ }
+
void test_visitFunctionTypedFormalParameter_type() {
_assertSource(
"T f()",
@@ -5149,6 +5159,16 @@
"f()", AstTestFactory.functionTypedFormalParameter(null, "f"));
}
+ void test_visitFunctionTypedFormalParameter_nullable() {
+ _assertSource(
+ "T f()?",
+ astFactory.functionTypedFormalParameter2(
+ returnType: AstTestFactory.typeName4("T"),
+ identifier: AstTestFactory.identifier3('f'),
+ parameters: AstTestFactory.formalParameterList([]),
+ question: TokenFactory.tokenFromType(TokenType.QUESTION)));
+ }
+
void test_visitFunctionTypedFormalParameter_type() {
_assertSource(
"T f()",