diff --git a/pkg/analyzer/lib/dart/analysis/features.dart b/pkg/analyzer/lib/dart/analysis/features.dart index e08660886a8..5390ffa99fb 100644 --- a/pkg/analyzer/lib/dart/analysis/features.dart +++ b/pkg/analyzer/lib/dart/analysis/features.dart @@ -32,6 +32,10 @@ abstract class Feature { /// Feature information for the triple-shift operator. static final triple_shift = ExperimentalFeatures.triple_shift; + /// Feature information for non-function type aliases. + static final nonfunction_type_aliases = + ExperimentalFeatures.nonfunction_type_aliases; + /// Feature information for variance. static final variance = ExperimentalFeatures.variance; diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart index 7ee7034323a..9f49d07d573 100644 --- a/pkg/analyzer/lib/dart/ast/ast.dart +++ b/pkg/analyzer/lib/dart/ast/ast.dart @@ -2933,12 +2933,18 @@ abstract class GenericTypeAlias implements TypeAlias { set equals(Token token); /// Return the type of function being defined by the alias. + /// + /// When the non-function type aliases feature is enabled and the denoted + /// type is not a [GenericFunctionType], return `null`. GenericFunctionType get functionType; /// Set the type of function being defined by the alias to the given /// [functionType]. set functionType(GenericFunctionType functionType); + /// Return the type being defined by the alias. + TypeAnnotation get type; + /// Return the type parameters for the function type, or `null` if the /// function type does not have any type parameters. TypeParameterList get typeParameters; diff --git a/pkg/analyzer/lib/dart/ast/ast_factory.dart b/pkg/analyzer/lib/dart/ast/ast_factory.dart index 65b253eb312..4dcba210935 100644 --- a/pkg/analyzer/lib/dart/ast/ast_factory.dart +++ b/pkg/analyzer/lib/dart/ast/ast_factory.dart @@ -511,7 +511,7 @@ abstract class AstFactory { SimpleIdentifier name, TypeParameterList typeParameters, Token equals, - GenericFunctionType functionType, + TypeAnnotation type, Token semicolon); /// Returns a newly created import show combinator. diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart index 428ee8a81b3..bd5e0680c4e 100644 --- a/pkg/analyzer/lib/src/dart/ast/ast.dart +++ b/pkg/analyzer/lib/src/dart/ast/ast.dart @@ -5363,6 +5363,9 @@ class GenericFunctionTypeImpl extends TypeAnnotationImpl /// metadata 'typedef' [SimpleIdentifier] [TypeParameterList]? = /// [FunctionType] ';' class GenericTypeAliasImpl extends TypeAliasImpl implements GenericTypeAlias { + /// The type being defined by the alias. + TypeAnnotationImpl _type; + /// The type parameters for the function type, or `null` if the function /// type does not have any type parameters. TypeParameterListImpl _typeParameters; @@ -5370,9 +5373,6 @@ class GenericTypeAliasImpl extends TypeAliasImpl implements GenericTypeAlias { @override Token equals; - /// The type of function being defined by the alias. - GenericFunctionTypeImpl _functionType; - /// Returns a newly created generic type alias. Either or both of the /// [comment] and [metadata] can be `null` if the variable list does not have /// the corresponding attribute. The [typeParameters] can be `null` if there @@ -5384,11 +5384,11 @@ class GenericTypeAliasImpl extends TypeAliasImpl implements GenericTypeAlias { SimpleIdentifierImpl name, TypeParameterListImpl typeParameters, this.equals, - GenericFunctionTypeImpl functionType, + TypeAnnotationImpl type, Token semicolon) : super(comment, metadata, typedefToken, name, semicolon) { _typeParameters = _becomeParentOf(typeParameters); - _functionType = _becomeParentOf(functionType); + _type = _becomeParentOf(type); } @override @@ -5398,19 +5398,30 @@ class GenericTypeAliasImpl extends TypeAliasImpl implements GenericTypeAlias { ..add(name) ..add(_typeParameters) ..add(equals) - ..add(_functionType); + ..add(_type); @override Element get declaredElement => name.staticElement; + /// The type of function being defined by the alias. + /// + /// If the non-function type aliases feature is enabled, a type alias may have + /// a [_type] which is not a [GenericFunctionTypeImpl]. In that case `null` + /// is returned. @override - GenericFunctionType get functionType => _functionType; + GenericFunctionType get functionType { + var t = _type; + return t is GenericFunctionTypeImpl ? t : null; + } @override set functionType(GenericFunctionType functionType) { - _functionType = _becomeParentOf(functionType as GenericFunctionTypeImpl); + _type = _becomeParentOf(functionType as TypeAnnotationImpl); } + @override + TypeAnnotation get type => _type; + @override TypeParameterList get typeParameters => _typeParameters; @@ -5429,7 +5440,7 @@ class GenericTypeAliasImpl extends TypeAliasImpl implements GenericTypeAlias { super.visitChildren(visitor); name?.accept(visitor); _typeParameters?.accept(visitor); - _functionType?.accept(visitor); + _type?.accept(visitor); } } diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart index 8e1fd6ade77..f1a91b6875f 100644 --- a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart +++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart @@ -575,10 +575,10 @@ class AstFactoryImpl extends AstFactory { SimpleIdentifier name, TypeParameterList typeParameters, Token equals, - GenericFunctionType functionType, + TypeAnnotation type, Token semicolon) => GenericTypeAliasImpl(comment, metadata, typedefKeyword, name, - typeParameters, equals, functionType, semicolon); + typeParameters, equals, type, semicolon); @override HideCombinator hideCombinator( diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart index ccfec8180af..5204bac487a 100644 --- a/pkg/analyzer/lib/src/fasta/ast_builder.dart +++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart @@ -128,6 +128,9 @@ class AstBuilder extends StackListener { /// `true` if triple-shift behavior is enabled final bool enableTripleShift; + /// `true` if nonfunction-type-aliases behavior is enabled + final bool enableNonFunctionTypeAliases; + /// `true` if variance behavior is enabled final bool enableVariance; @@ -143,6 +146,8 @@ class AstBuilder extends StackListener { enableControlFlowCollections = _featureSet.isEnabled(Feature.control_flow_collections), enableTripleShift = _featureSet.isEnabled(Feature.triple_shift), + enableNonFunctionTypeAliases = + _featureSet.isEnabled(Feature.nonfunction_type_aliases), enableVariance = _featureSet.isEnabled(Feature.variance), uri = uri ?? fileUri; @@ -1532,10 +1537,8 @@ class AstBuilder extends StackListener { SimpleIdentifier name = pop(); List metadata = pop(); Comment comment = _findComment(metadata, typedefKeyword); - if (type is! GenericFunctionType) { - // This error is also reported in the OutlineBuilder. + if (type is! GenericFunctionType && !enableNonFunctionTypeAliases) { handleRecoverableError(messageTypedefNotFunction, equals, equals); - type = null; } declarations.add(ast.genericTypeAlias( comment, @@ -1544,7 +1547,7 @@ class AstBuilder extends StackListener { name, templateParameters, equals, - type as GenericFunctionType, + type, semicolon)); } } @@ -3042,8 +3045,11 @@ class AstBuilder extends StackListener { // Determine if this is a set or map based on type args and content final typeArgCount = typeArguments?.arguments?.length; - bool isSet = - typeArgCount == 1 ? true : typeArgCount != null ? false : null; + bool isSet = typeArgCount == 1 + ? true + : typeArgCount != null + ? false + : null; isSet ??= hasSetEntry; // Build the set or map