@@ -1520,15 +1520,13 @@ bool Parser::canParseType() {
15201520 switch (Tok.getKind ()) {
15211521 case tok::kw_Self:
15221522 case tok::kw_Any:
1523+ case tok::identifier:
15231524 case tok::code_complete:
15241525 if (!canParseTypeIdentifier ())
15251526 return false ;
15261527 break ;
1527- case tok::kw_protocol: // Deprecated composition syntax
1528- case tok::identifier:
1529- if (!canParseTypeIdentifierOrTypeComposition ())
1530- return false ;
1531- break ;
1528+ case tok::kw_protocol:
1529+ return canParseOldStyleProtocolComposition ();
15321530 case tok::l_paren: {
15331531 consumeToken ();
15341532 if (!canParseTypeTupleBody ())
@@ -1561,14 +1559,22 @@ bool Parser::canParseType() {
15611559 return false ;
15621560 }
15631561
1564- // '.Type', '.Protocol', '?', and '!' still leave us with type-simple.
1562+ // A member type, '.Type', '.Protocol', '?', and '!' still leave us with
1563+ // type-simple.
15651564 while (true ) {
1566- if ((Tok.is (tok::period) || Tok.is (tok::period_prefix)) &&
1567- (peekToken ().isContextualKeyword (" Type" )
1568- || peekToken ().isContextualKeyword (" Protocol" ))) {
1565+ if (Tok.isAny (tok::period_prefix, tok::period)) {
15691566 consumeToken ();
1570- consumeToken (tok::identifier);
1571- continue ;
1567+
1568+ if (Tok.isContextualKeyword (" Type" ) ||
1569+ Tok.isContextualKeyword (" Protocol" )) {
1570+ consumeToken ();
1571+ continue ;
1572+ }
1573+
1574+ if (canParseTypeIdentifier ())
1575+ continue ;
1576+
1577+ return false ;
15721578 }
15731579 if (isOptionalToken (Tok)) {
15741580 consumeOptionalToken ();
@@ -1581,6 +1587,13 @@ bool Parser::canParseType() {
15811587 break ;
15821588 }
15831589
1590+ while (Tok.isContextualPunctuator (" &" )) {
1591+ consumeToken ();
1592+ // FIXME: Should be 'canParseTypeSimple', but we don't have one.
1593+ if (!canParseType ())
1594+ return false ;
1595+ }
1596+
15841597 if (isAtFunctionTypeArrow ()) {
15851598 // Handle type-function if we have an '->' with optional
15861599 // 'async' and/or 'throws'.
@@ -1605,25 +1618,10 @@ bool Parser::canParseType() {
16051618 return true ;
16061619}
16071620
1608- bool Parser::canParseTypeIdentifierOrTypeComposition () {
1609- if (Tok.is (tok::kw_protocol))
1610- return canParseOldStyleProtocolComposition ();
1611-
1612- while (true ) {
1613- if (!canParseTypeIdentifier ())
1614- return false ;
1615-
1616- if (Tok.isContextualPunctuator (" &" )) {
1617- consumeToken ();
1618- continue ;
1619- } else {
1620- return true ;
1621- }
1622- }
1623- }
1624-
1625- bool Parser::canParseSimpleTypeIdentifier () {
1621+ bool Parser::canParseTypeIdentifier () {
16261622 // Parse an identifier.
1623+ //
1624+ // FIXME: We should expect e.g. 'X.var'. Almost any keyword is a valid member component.
16271625 if (!Tok.isAny (tok::identifier, tok::kw_Self, tok::kw_Any, tok::code_complete))
16281626 return false ;
16291627 consumeToken ();
@@ -1635,28 +1633,11 @@ bool Parser::canParseSimpleTypeIdentifier() {
16351633 return true ;
16361634}
16371635
1638- bool Parser::canParseTypeIdentifier () {
1639- while (true ) {
1640- if (!canParseSimpleTypeIdentifier ())
1641- return false ;
1642-
1643- // Treat 'Foo.<anything>' as an attempt to write a dotted type
1644- // unless <anything> is 'Type' or 'Protocol'.
1645- if ((Tok.is (tok::period) || Tok.is (tok::period_prefix)) &&
1646- !peekToken ().isContextualKeyword (" Type" ) &&
1647- !peekToken ().isContextualKeyword (" Protocol" )) {
1648- consumeToken ();
1649- } else {
1650- return true ;
1651- }
1652- }
1653- }
1654-
16551636bool Parser::canParseBaseTypeForQualifiedDeclName () {
16561637 BacktrackingScope backtrack (*this );
16571638
16581639 // Parse a simple type identifier.
1659- if (!canParseSimpleTypeIdentifier ())
1640+ if (!canParseTypeIdentifier ())
16601641 return false ;
16611642
16621643 // Qualified name base types must be followed by a period.
0 commit comments