Non-breaking AST changes to support constructor tearoffs.

Change-Id: Ic82dd28135ccaa2d5b42898642a1d6e1e0868cb0
Bug: https://github.com/dart-lang/sdk/issues/46020
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/199680
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Paul Berry 2021-05-15 14:16:09 +00:00 committed by commit-bot@chromium.org
parent 11bbea8797
commit 81c45e4455
4 changed files with 241 additions and 0 deletions

View file

@ -1762,6 +1762,19 @@ abstract class ConstructorName implements AstNode, ConstructorReferenceNode {
set type(TypeName type);
}
/// An expression representing a reference to a constructor, e.g. the expression
/// `List.filled` in `var x = List.filled;`.
///
/// Objects of this type are not produced directly by the parser (because the
/// parser cannot tell whether an identifier refers to a type); they are
/// produced at resolution time.
///
/// Clients may not extend, implement or mix-in this class.
abstract class ConstructorReference implements Expression {
/// The constructor being referenced.
ConstructorName get constructorName;
}
/// An AST node that makes reference to a constructor.
///
/// Clients may not extend, implement or mix-in this class.
@ -3000,6 +3013,36 @@ abstract class FunctionExpressionInvocation
set typeArguments(TypeArgumentList? typeArguments);
}
/// An expression representing a reference to a function, possibly with type
/// arguments applied to it, e.g. the expression `print` in `var x = print;`.
///
/// Clients may not extend, implement or mix-in this class.
abstract class FunctionReference implements Expression {
/// The function being referenced.
///
/// In error-free code, this will be either a SimpleIdentifier (indicating a
/// function that is in scope), a PrefixedIdentifier (indicating a either
/// function imported via prefix or a static method in a class), or a
/// PropertyAccess (indicating a static method in a class imported via
/// prefix). In code with errors, this could be other kinds of expressions
/// (e.g. `(...)<int>` parses as a FunctionReference whose referent is a
/// ParenthesizedExpression.
Expression get function;
/// The type arguments being applied to the function, or `null` if there are
/// no type arguments.
TypeArgumentList? get typeArguments;
/// The actual type arguments being applied to the function, either explicitly
/// specified in [typeArguments], or inferred.
///
/// If the AST has been resolved, never returns `null`, returns an empty list
/// if the function does not have type parameters.
///
/// Returns `null` if the AST structure has not been resolved.
List<DartType>? get typeArgumentTypes;
}
/// A function type alias.
///
/// functionTypeAlias ::=
@ -5525,6 +5568,23 @@ abstract class TypedLiteral implements Literal {
set typeArguments(TypeArgumentList? typeArguments);
}
/// An expression representing a type, e.g. the expression `int` in
/// `var x = int;`.
///
/// Objects of this type are not produced directly by the parser (because the
/// parser cannot tell whether an identifier refers to a type); they are
/// produced at resolution time.
///
/// The `.staticType` getter returns the type of the expression (which will
/// always be the type `Type`). To see the type represented by the type literal
/// use `.typeName.type`.
///
/// Clients may not extend, implement or mix-in this class.
abstract class TypeLiteral implements Expression {
/// The type represented by this literal.
TypeName get typeName;
}
/// The name of a type, which can optionally include type arguments.
///
/// typeName ::=

View file

@ -232,6 +232,10 @@ abstract class AstFactory {
ConstructorName constructorName(
TypeName type, Token? period, SimpleIdentifier? name);
/// Returns a newly created constructor reference.
ConstructorReference constructorReference(
{required ConstructorName constructorName});
/// Returns a newly created continue statement. The [label] can be `null` if
/// there is no label associated with the statement.
ContinueStatement continueStatement(
@ -470,6 +474,11 @@ abstract class AstFactory {
FunctionExpressionInvocation functionExpressionInvocation(Expression function,
TypeArgumentList? typeArguments, ArgumentList argumentList);
/// Returns a newly created function reference. The [typeArguments] can be
/// `null` if there are no type arguments being applied to the function.
FunctionReference functionReference(
{required Expression function, TypeArgumentList? typeArguments});
/// Returns a newly created function type alias. Either or both of the
/// [comment] and [metadata] can be `null` if the function does not have the
/// corresponding attribute. The [returnType] can be `null` if no return type
@ -866,6 +875,9 @@ abstract class AstFactory {
TypeArgumentList typeArgumentList(
Token leftBracket, List<TypeAnnotation> arguments, Token rightBracket);
/// Returns a newly created type literal.
TypeLiteral typeLiteral({required TypeName typeName});
/// Returns a newly created type name. The [typeArguments] can be `null` if
/// there are no type arguments. The [question] can be `null` if there is no
/// question mark.

View file

@ -2680,6 +2680,52 @@ class ConstructorNameImpl extends AstNodeImpl implements ConstructorName {
}
}
/// An expression representing a reference to a constructor, e.g. the expression
/// `List.filled` in `var x = List.filled;`.
///
/// Objects of this type are not produced directly by the parser (because the
/// parser cannot tell whether an identifier refers to a type); they are
/// produced at resolution time.
class ConstructorReferenceImpl extends ExpressionImpl
implements ConstructorReference {
ConstructorNameImpl _constructorName;
ConstructorReferenceImpl(this._constructorName) {
_becomeParentOf(_constructorName);
}
@override
Token get beginToken => constructorName.beginToken;
@override
Iterable<SyntacticEntity> get childEntities =>
ChildEntities()..add(constructorName);
@override
ConstructorNameImpl get constructorName => _constructorName;
set constructorName(ConstructorNameImpl value) {
_constructorName = _becomeParentOf(value);
}
@override
Token get endToken => constructorName.endToken;
@override
Precedence get precedence => Precedence.postfix;
@override
E? accept<E>(AstVisitor<E> visitor) {
throw UnimplementedError(
'Visitor support for ConstructorReference is not yet implemented');
}
@override
void visitChildren(AstVisitor visitor) {
constructorName.accept(visitor);
}
}
/// A continue statement.
///
/// continueStatement ::=
@ -4972,6 +5018,64 @@ class FunctionExpressionInvocationImpl extends InvocationExpressionImpl
bool _extendsNullShorting(Expression child) => identical(child, _function);
}
/// An expression representing a reference to a function, possibly with type
/// arguments applied to it, e.g. the expression `print` in `var x = print;`.
class FunctionReferenceImpl extends ExpressionImpl
implements FunctionReference {
ExpressionImpl _function;
TypeArgumentListImpl? _typeArguments;
@override
List<DartType>? typeArgumentTypes;
FunctionReferenceImpl(this._function, {TypeArgumentListImpl? typeArguments})
: _typeArguments = typeArguments {
_becomeParentOf(_function);
_becomeParentOf(_typeArguments);
}
@override
Token get beginToken => function.beginToken;
@override
Iterable<SyntacticEntity> get childEntities =>
ChildEntities()..add(function)..add(typeArguments);
@override
Token get endToken => typeArguments?.endToken ?? function.endToken;
@override
ExpressionImpl get function => _function;
set function(ExpressionImpl value) {
_function = _becomeParentOf(value);
}
@override
Precedence get precedence =>
typeArguments == null ? function.precedence : Precedence.postfix;
@override
TypeArgumentListImpl? get typeArguments => _typeArguments;
set typeArguments(TypeArgumentListImpl? value) {
_typeArguments = _becomeParentOf(value);
}
@override
E? accept<E>(AstVisitor<E> visitor) {
throw UnimplementedError(
'Visitor support for FunctionReference is not yet implemented');
}
@override
void visitChildren(AstVisitor visitor) {
function.accept(visitor);
typeArguments?.accept(visitor);
}
}
/// A function type alias.
///
/// functionTypeAlias ::=
@ -9963,6 +10067,56 @@ abstract class TypedLiteralImpl extends LiteralImpl implements TypedLiteral {
}
}
/// An expression representing a type, e.g. the expression `int` in
/// `var x = int;`.
///
/// Objects of this type are not produced directly by the parser (because the
/// parser cannot tell whether an identifier refers to a type); they are
/// produced at resolution time.
///
/// The `.staticType` getter returns the type of the expression (which will
/// always be the type `Type`). To see the type represented by the type literal
/// use `.typeName.type`.
class TypeLiteralImpl extends ExpressionImpl implements TypeLiteral {
TypeNameImpl _typeName;
TypeLiteralImpl(this._typeName) {
_becomeParentOf(_typeName);
}
@override
Token get beginToken => typeName.beginToken;
@override
Iterable<SyntacticEntity> get childEntities => ChildEntities()..add(typeName);
@override
Token get endToken => typeName.endToken;
@override
Precedence get precedence => typeName.typeArguments == null
? typeName.name.precedence
: Precedence.postfix;
@override
TypeNameImpl get typeName => _typeName;
set typeName(TypeNameImpl value) {
_typeName = _becomeParentOf(value);
}
@override
E? accept<E>(AstVisitor<E> visitor) {
throw UnimplementedError(
'Visitor support for TypeLiteral is not yet implemented');
}
@override
void visitChildren(AstVisitor visitor) {
typeName.accept(visitor);
}
}
/// The name of a type, which can optionally include type arguments.
///
/// typeName ::=

View file

@ -300,6 +300,11 @@ class AstFactoryImpl extends AstFactory {
ConstructorNameImpl(
type as TypeNameImpl, period, name as SimpleIdentifierImpl?);
@override
ConstructorReferenceImpl constructorReference(
{required ConstructorName constructorName}) =>
ConstructorReferenceImpl(constructorName as ConstructorNameImpl);
@override
ContinueStatementImpl continueStatement(
Token continueKeyword, SimpleIdentifier? label, Token semicolon) =>
@ -629,6 +634,12 @@ class AstFactoryImpl extends AstFactory {
typeArguments as TypeArgumentListImpl?,
argumentList as ArgumentListImpl);
@override
FunctionReferenceImpl functionReference(
{required Expression function, TypeArgumentList? typeArguments}) =>
FunctionReferenceImpl(function as ExpressionImpl,
typeArguments: typeArguments as TypeArgumentListImpl);
@override
FunctionTypeAliasImpl functionTypeAlias(
Comment? comment,
@ -1185,6 +1196,10 @@ class AstFactoryImpl extends AstFactory {
List<TypeAnnotation> arguments, Token rightBracket) =>
TypeArgumentListImpl(leftBracket, arguments, rightBracket);
@override
TypeLiteralImpl typeLiteral({required TypeName typeName}) =>
TypeLiteralImpl(typeName as TypeNameImpl);
@override
TypeNameImpl typeName(Identifier name, TypeArgumentList? typeArguments,
{Token? question}) =>