@@ -1567,6 +1567,181 @@ class VoidType extends _SpecialSimpleType
15671567 Type withNullability (NullabilitySuffix suffix) => this ;
15681568}
15691569
1570+ /// Representation of a [FunctionType] that has been parsed but hasn't had
1571+ /// meaning assigned to its identifiers yet.
1572+ class _PreFunctionType extends _PreType {
1573+ final _PreType returnType;
1574+ final List <_PreType > positionalParameterTypes;
1575+ final int requiredPositionalParameterCount;
1576+ final List <_PreNamedFunctionParameter > namedParameters;
1577+
1578+ _PreFunctionType (
1579+ {required this .returnType,
1580+ required this .positionalParameterTypes,
1581+ required this .requiredPositionalParameterCount,
1582+ required this .namedParameters});
1583+
1584+ @override
1585+ Type materialize () => FunctionType (
1586+ returnType.materialize (),
1587+ [
1588+ for (var positionalParameterType in positionalParameterTypes)
1589+ positionalParameterType.materialize ()
1590+ ],
1591+ requiredPositionalParameterCount: requiredPositionalParameterCount,
1592+ namedParameters: [
1593+ for (var namedParameter in namedParameters)
1594+ NamedFunctionParameter (
1595+ isRequired: namedParameter.isRequired,
1596+ name: namedParameter.name,
1597+ type: namedParameter.type.materialize ())
1598+ ]);
1599+ }
1600+
1601+ /// Representation of a named function parameter in a [_PreFunctionType] .
1602+ class _PreNamedFunctionParameter {
1603+ final String name;
1604+ final _PreType type;
1605+ final bool isRequired;
1606+
1607+ _PreNamedFunctionParameter (
1608+ {required this .name, required this .type, required this .isRequired});
1609+ }
1610+
1611+ /// Representation of a named component of a [_PreRecordType] .
1612+ class _PreNamedType {
1613+ final String name;
1614+ final _PreType type;
1615+
1616+ _PreNamedType ({required this .name, required this .type});
1617+ }
1618+
1619+ /// Representation of a [PrimaryType] or [TypeParameterType] that has been
1620+ /// parsed but hasn't had meaning assigned to its identifiers yet.
1621+ class _PrePrimaryType extends _PreType {
1622+ final String typeName;
1623+ final List <_PreType > typeArgs;
1624+
1625+ _PrePrimaryType ({required this .typeName, required this .typeArgs});
1626+
1627+ @override
1628+ Type materialize () {
1629+ var nameInfo = TypeRegistry .lookup (typeName);
1630+ switch (nameInfo) {
1631+ case TypeParameter ():
1632+ if (typeArgs.isNotEmpty) {
1633+ throw ParseError ('Type parameter types do not accept type arguments' );
1634+ }
1635+ return TypeParameterType (nameInfo);
1636+ case InterfaceTypeName ():
1637+ return PrimaryType (nameInfo,
1638+ args: [for (var typeArg in typeArgs) typeArg.materialize ()]);
1639+ case SpecialTypeName ():
1640+ if (typeName == 'dynamic' ) {
1641+ if (typeArgs.isNotEmpty) {
1642+ throw ParseError ('`dynamic` does not accept type arguments' );
1643+ }
1644+ return DynamicType .instance;
1645+ } else if (typeName == 'error' ) {
1646+ if (typeArgs.isNotEmpty) {
1647+ throw ParseError ('`error` does not accept type arguments' );
1648+ }
1649+ return InvalidType .instance;
1650+ } else if (typeName == 'FutureOr' ) {
1651+ if (typeArgs.length != 1 ) {
1652+ throw ParseError ('`FutureOr` requires exactly one type argument' );
1653+ }
1654+ return FutureOrType (typeArgs.single.materialize ());
1655+ } else if (typeName == 'Never' ) {
1656+ if (typeArgs.isNotEmpty) {
1657+ throw ParseError ('`Never` does not accept type arguments' );
1658+ }
1659+ return NeverType .instance;
1660+ } else if (typeName == 'Null' ) {
1661+ if (typeArgs.isNotEmpty) {
1662+ throw ParseError ('`Null` does not accept type arguments' );
1663+ }
1664+ return NullType .instance;
1665+ } else if (typeName == 'void' ) {
1666+ if (typeArgs.isNotEmpty) {
1667+ throw ParseError ('`void` does not accept type arguments' );
1668+ }
1669+ return VoidType .instance;
1670+ } else {
1671+ throw UnimplementedError ('Unknown special type name: $typeName ' );
1672+ }
1673+ }
1674+ }
1675+ }
1676+
1677+ /// Representation of a promoted [TypeParameterType] that has been parsed but
1678+ /// hasn't had meaning assigned to its identifiers yet.
1679+ class _PrePromotedType extends _PreType {
1680+ final _PreType inner;
1681+ final _PreType promotion;
1682+
1683+ _PrePromotedType ({required this .inner, required this .promotion});
1684+
1685+ @override
1686+ Type materialize () {
1687+ var type = inner.materialize ();
1688+ if (type case TypeParameterType (promotion: null )) {
1689+ return TypeParameterType (type.typeParameter,
1690+ promotion: promotion.materialize ());
1691+ } else {
1692+ throw ParseError (
1693+ 'The type to the left of & must be an unpromoted type parameter' );
1694+ }
1695+ }
1696+ }
1697+
1698+ /// Representation of a [RecordType] that has been parsed but hasn't had
1699+ /// meaning assigned to its identifiers yet.
1700+ class _PreRecordType extends _PreType {
1701+ final List <_PreType > positionalTypes;
1702+ final List <_PreNamedType > namedTypes;
1703+
1704+ _PreRecordType ({required this .positionalTypes, required this .namedTypes});
1705+
1706+ @override
1707+ Type materialize () => RecordType (positionalTypes: [
1708+ for (var positionalType in positionalTypes) positionalType.materialize ()
1709+ ], namedTypes: [
1710+ for (var namedType in namedTypes)
1711+ NamedType (name: namedType.name, type: namedType.type.materialize ())
1712+ ]);
1713+ }
1714+
1715+ /// Representation of a [Type] that has been parsed but hasn't had meaning
1716+ /// assigned to its identifiers yet.
1717+ sealed class _PreType {
1718+ /// Translates `this` into a [Type] .
1719+ ///
1720+ /// The meaning of identifiers in `this` is determined by looking them up in
1721+ /// the [TypeRegistry] .
1722+ Type materialize ();
1723+ }
1724+
1725+ /// Representation of a [Type] with a nullability suffix that has been parsed
1726+ /// but hasn't had meaning assigned to its identifiers yet.
1727+ class _PreTypeWithNullability extends _PreType {
1728+ final _PreType inner;
1729+ final NullabilitySuffix nullabilitySuffix;
1730+
1731+ _PreTypeWithNullability (
1732+ {required this .inner, required this .nullabilitySuffix});
1733+
1734+ @override
1735+ Type materialize () => inner.materialize ().withNullability (nullabilitySuffix);
1736+ }
1737+
1738+ /// Representation of an [UnknownType] that has been parsed but hasn't had
1739+ /// meaning assigned to its identifiers yet.
1740+ class _PreUnknownType extends _PreType {
1741+ @override
1742+ Type materialize () => const UnknownType ();
1743+ }
1744+
15701745/// Shared implementation of the types `void` , `dynamic` , `null` , `Never` , and
15711746/// the invalid type.
15721747///
@@ -1628,10 +1803,10 @@ class _TypeParser {
16281803 'Error parsing type `$_typeStr ` at token $_currentToken : $message ' );
16291804 }
16301805
1631- List <NamedFunctionParameter > _parseNamedFunctionParameters () {
1806+ List <_PreNamedFunctionParameter > _parseNamedFunctionParameters () {
16321807 assert (_currentToken == '{' );
16331808 _next ();
1634- var namedParameters = < NamedFunctionParameter > [];
1809+ var namedParameters = < _PreNamedFunctionParameter > [];
16351810 while (true ) {
16361811 var isRequired = _currentToken == 'required' ;
16371812 if (isRequired) {
@@ -1642,7 +1817,7 @@ class _TypeParser {
16421817 if (_identifierRegexp.matchAsPrefix (name) == null ) {
16431818 _parseFailure ('Expected an identifier' );
16441819 }
1645- namedParameters.add (NamedFunctionParameter (
1820+ namedParameters.add (_PreNamedFunctionParameter (
16461821 name: name, type: type, isRequired: isRequired));
16471822 _next ();
16481823 if (_currentToken == ',' ) {
@@ -1659,7 +1834,8 @@ class _TypeParser {
16591834 return namedParameters;
16601835 }
16611836
1662- void _parseOptionalFunctionParameters (List <Type > positionalParameterTypes) {
1837+ void _parseOptionalFunctionParameters (
1838+ List <_PreType > positionalParameterTypes) {
16631839 assert (_currentToken == '[' );
16641840 _next ();
16651841 while (true ) {
@@ -1677,17 +1853,17 @@ class _TypeParser {
16771853 _next ();
16781854 }
16791855
1680- List <NamedType > _parseRecordTypeNamedFields () {
1856+ List <_PreNamedType > _parseRecordTypeNamedFields () {
16811857 assert (_currentToken == '{' );
16821858 _next ();
1683- var namedTypes = < NamedType > [];
1859+ var namedTypes = < _PreNamedType > [];
16841860 while (_currentToken != '}' ) {
16851861 var type = _parseType ();
16861862 var name = _currentToken;
16871863 if (_identifierRegexp.matchAsPrefix (name) == null ) {
16881864 _parseFailure ('Expected an identifier' );
16891865 }
1690- namedTypes.add (NamedType (name: name, type: type));
1866+ namedTypes.add (_PreNamedType (name: name, type: type));
16911867 _next ();
16921868 if (_currentToken == ',' ) {
16931869 _next ();
@@ -1706,8 +1882,8 @@ class _TypeParser {
17061882 return namedTypes;
17071883 }
17081884
1709- Type _parseRecordTypeRest (List <Type > positionalTypes) {
1710- List <NamedType >? namedTypes;
1885+ _PreRecordType _parseRecordTypeRest (List <_PreType > positionalTypes) {
1886+ List <_PreNamedType >? namedTypes;
17111887 while (_currentToken != ')' ) {
17121888 if (_currentToken == '{' ) {
17131889 namedTypes = _parseRecordTypeNamedFields ();
@@ -1727,34 +1903,31 @@ class _TypeParser {
17271903 _parseFailure ('Expected `)` or `,`' );
17281904 }
17291905 _next ();
1730- return RecordType (
1906+ return _PreRecordType (
17311907 positionalTypes: positionalTypes, namedTypes: namedTypes ?? const []);
17321908 }
17331909
1734- Type ? _parseSuffix (Type type) {
1910+ _PreType ? _parseSuffix (_PreType type) {
17351911 if (_currentToken == '?' ) {
17361912 _next ();
1737- return type.withNullability (NullabilitySuffix .question);
1913+ return _PreTypeWithNullability (
1914+ inner: type, nullabilitySuffix: NullabilitySuffix .question);
17381915 } else if (_currentToken == '*' ) {
17391916 _next ();
1740- return type.withNullability (NullabilitySuffix .star);
1917+ return _PreTypeWithNullability (
1918+ inner: type, nullabilitySuffix: NullabilitySuffix .star);
17411919 } else if (_currentToken == '&' ) {
1742- if (type case TypeParameterType (promotion: null )) {
1743- _next ();
1744- var promotion = _parseUnsuffixedType ();
1745- return TypeParameterType (type.typeParameter, promotion: promotion);
1746- } else {
1747- _parseFailure (
1748- 'The type to the left of & must be an unpromoted type parameter' );
1749- }
1920+ _next ();
1921+ var promotion = _parseUnsuffixedType ();
1922+ return _PrePromotedType (inner: type, promotion: promotion);
17501923 } else if (_currentToken == 'Function' ) {
17511924 _next ();
17521925 if (_currentToken != '(' ) {
17531926 _parseFailure ('Expected `(`' );
17541927 }
17551928 _next ();
1756- var positionalParameterTypes = < Type > [];
1757- List <NamedFunctionParameter >? namedFunctionParameters;
1929+ var positionalParameterTypes = < _PreType > [];
1930+ List <_PreNamedFunctionParameter >? namedFunctionParameters;
17581931 int ? requiredPositionalParameterCount;
17591932 if (_currentToken != ')' ) {
17601933 while (true ) {
@@ -1781,7 +1954,9 @@ class _TypeParser {
17811954 }
17821955 }
17831956 _next ();
1784- return FunctionType (type, positionalParameterTypes,
1957+ return _PreFunctionType (
1958+ returnType: type,
1959+ positionalParameterTypes: positionalParameterTypes,
17851960 requiredPositionalParameterCount: requiredPositionalParameterCount ??
17861961 positionalParameterTypes.length,
17871962 namedParameters: namedFunctionParameters ?? const []);
@@ -1790,7 +1965,7 @@ class _TypeParser {
17901965 }
17911966 }
17921967
1793- Type _parseType () {
1968+ _PreType _parseType () {
17941969 // We currently accept the following grammar for types:
17951970 // type := unsuffixedType nullability suffix*
17961971 // unsuffixedType := identifier typeArgs?
@@ -1825,10 +2000,10 @@ class _TypeParser {
18252000 return result;
18262001 }
18272002
1828- Type _parseUnsuffixedType () {
2003+ _PreType _parseUnsuffixedType () {
18292004 if (_currentToken == '_' ) {
18302005 _next ();
1831- return const UnknownType ();
2006+ return _PreUnknownType ();
18322007 }
18332008 if (_currentToken == '(' ) {
18342009 _next ();
@@ -1851,7 +2026,7 @@ class _TypeParser {
18512026 _parseFailure ('Expected an identifier, `_`, or `(`' );
18522027 }
18532028 _next ();
1854- List <Type > typeArgs;
2029+ List <_PreType > typeArgs;
18552030 if (_currentToken == '<' ) {
18562031 _next ();
18572032 typeArgs = [];
@@ -1867,50 +2042,7 @@ class _TypeParser {
18672042 } else {
18682043 typeArgs = const [];
18692044 }
1870- var nameInfo = TypeRegistry .lookup (typeName);
1871- switch (nameInfo) {
1872- case TypeParameter ():
1873- if (typeArgs.isNotEmpty) {
1874- throw ParseError ('Type parameter types do not accept type arguments' );
1875- }
1876- return TypeParameterType (nameInfo);
1877- case InterfaceTypeName ():
1878- return PrimaryType (nameInfo, args: typeArgs);
1879- case SpecialTypeName ():
1880- if (typeName == 'dynamic' ) {
1881- if (typeArgs.isNotEmpty) {
1882- throw ParseError ('`dynamic` does not accept type arguments' );
1883- }
1884- return DynamicType .instance;
1885- } else if (typeName == 'error' ) {
1886- if (typeArgs.isNotEmpty) {
1887- throw ParseError ('`error` does not accept type arguments' );
1888- }
1889- return InvalidType .instance;
1890- } else if (typeName == 'FutureOr' ) {
1891- if (typeArgs.length != 1 ) {
1892- throw ParseError ('`FutureOr` requires exactly one type argument' );
1893- }
1894- return FutureOrType (typeArgs.single);
1895- } else if (typeName == 'Never' ) {
1896- if (typeArgs.isNotEmpty) {
1897- throw ParseError ('`Never` does not accept type arguments' );
1898- }
1899- return NeverType .instance;
1900- } else if (typeName == 'Null' ) {
1901- if (typeArgs.isNotEmpty) {
1902- throw ParseError ('`Null` does not accept type arguments' );
1903- }
1904- return NullType .instance;
1905- } else if (typeName == 'void' ) {
1906- if (typeArgs.isNotEmpty) {
1907- throw ParseError ('`void` does not accept type arguments' );
1908- }
1909- return VoidType .instance;
1910- } else {
1911- throw UnimplementedError ('Unknown special type name: $typeName ' );
1912- }
1913- }
2045+ return _PrePrimaryType (typeName: typeName, typeArgs: typeArgs);
19142046 }
19152047
19162048 static Type parse (String typeStr) {
@@ -1920,7 +2052,7 @@ class _TypeParser {
19202052 throw ParseError ('Extra tokens after parsing type `$typeStr `: '
19212053 '${parser ._tokens .sublist (parser ._i , parser ._tokens .length - 1 )}' );
19222054 }
1923- return result;
2055+ return result. materialize () ;
19242056 }
19252057
19262058 static List <String > _tokenizeTypeStr (String typeStr) {
0 commit comments