Skip to content

Commit fe047b9

Browse files
committed
Parser: Tweak parseTypeIdentifier to better suit its only remaining client
1 parent 9898fca commit fe047b9

File tree

3 files changed

+31
-68
lines changed

3 files changed

+31
-68
lines changed

include/swift/Parse/Parser.h

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,22 +1296,25 @@ class Parser {
12961296
SourceLoc &LAngleLoc,
12971297
SourceLoc &RAngleLoc);
12981298

1299-
/// Parses a type identifier (e.g. 'Foo' or 'Foo.Bar.Baz').
1299+
/// Parses and returns the base type for a qualified declaration name,
1300+
/// positioning the parser at the '.' before the final declaration name. This
1301+
/// position is important for parsing final declaration names like '.init' via
1302+
/// `parseUnqualifiedDeclName`. For example, 'Foo.Bar.f' parses as 'Foo.Bar'
1303+
/// and the parser is positioned at '.f'. If there is no base type qualifier
1304+
/// (e.g. when parsing just 'f'), returns an empty parser error.
13001305
///
1301-
/// When `isParsingQualifiedDeclBaseType` is true:
1302-
/// - Parses and returns the base type for a qualified declaration name,
1303-
/// positioning the parser at the '.' before the final declaration name.
1304-
// This position is important for parsing final declaration names like
1305-
// '.init' via `parseUnqualifiedDeclName`.
1306-
/// - For example, 'Foo.Bar.f' parses as 'Foo.Bar' and the parser is
1307-
/// positioned at '.f'.
1308-
/// - If there is no base type qualifier (e.g. when parsing just 'f'), returns
1309-
/// an empty parser error.
1310-
ParserResult<TypeRepr> parseTypeIdentifier(
1311-
bool isParsingQualifiedDeclBaseType = false);
1306+
/// \verbatim
1307+
/// qualified-decl-name-base-type:
1308+
/// identifier generic-args? ('.' identifier generic-args?)*
1309+
/// \endverbatim
1310+
ParserResult<TypeRepr> parseQualifiedDeclNameBaseType();
13121311

13131312
/// Parse an identifier type, e.g 'Foo' or 'Bar<Int>'.
1314-
ParserResult<IdentTypeRepr> parseSimpleTypeIdentifier();
1313+
///
1314+
/// \verbatim
1315+
/// type-identifier: identifier generic-args?
1316+
/// \endverbatim
1317+
ParserResult<IdentTypeRepr> parseTypeIdentifier();
13151318

13161319
/// Parse a dotted type, e.g. 'Foo<X>.Y.Z', 'P.Type', '[X].Y'.
13171320
ParserResult<TypeRepr> parseTypeDotted(ParserResult<TypeRepr> Base);
@@ -1575,10 +1578,6 @@ class Parser {
15751578
bool canParseTypedPattern();
15761579

15771580
/// Returns true if a qualified declaration name base type can be parsed.
1578-
///
1579-
/// \verbatim
1580-
/// qualified-decl-name-base-type: simple-type-identifier '.'
1581-
/// \endverbatim
15821581
bool canParseBaseTypeForQualifiedDeclName();
15831582

15841583
/// Returns true if the current token is '->' or effects specifiers followed

lib/Parse/ParseDecl.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,7 +1423,7 @@ static Optional<AccessorKind> isAccessorLabel(const Token &token) {
14231423
return None;
14241424
}
14251425

1426-
/// Helper function that parses 'type-identifier' for `parseQualifiedDeclName`.
1426+
/// Helper function that parses a base type for `parseQualifiedDeclName`.
14271427
/// Returns true on error. Sets `baseType` to the parsed base type if present,
14281428
/// or to `nullptr` if not. A missing base type is not considered an error.
14291429
static bool parseBaseTypeForQualifiedDeclName(Parser &P, TypeRepr *&baseType) {
@@ -1434,15 +1434,15 @@ static bool parseBaseTypeForQualifiedDeclName(Parser &P, TypeRepr *&baseType) {
14341434
if (!P.canParseBaseTypeForQualifiedDeclName())
14351435
return false;
14361436

1437-
auto result = P.parseTypeIdentifier(/*isParsingQualifiedDeclName*/ true);
1437+
auto result = P.parseQualifiedDeclNameBaseType();
14381438
// If base type should be parseable but the actual base type result is null,
14391439
// return true (error).
14401440
if (result.isNull())
14411441
return true;
14421442

14431443
// Consume the leading period before the final declaration name component.
1444-
// `parseTypeIdentifier(/*isParsingQualifiedDeclName*/ true)` leaves the
1445-
// leading period unparsed to avoid syntax verification errors.
1444+
// `parseQualifiedDeclNameBaseType` leaves the leading period unparsed to
1445+
// avoid syntax verification errors.
14461446
assert(P.startsWithSymbol(P.Tok, '.') && "false");
14471447

14481448
// Check if this is a reference to a property or subscript accessor.
@@ -1478,9 +1478,7 @@ static bool parseBaseTypeForQualifiedDeclName(Parser &P, TypeRepr *&baseType) {
14781478
///
14791479
/// \verbatim
14801480
/// qualified-decl-name:
1481-
/// type-identifier? unqualified-decl-name
1482-
/// type-identifier:
1483-
/// identifier generic-args? ('.' identifier generic-args?)*
1481+
/// qualified-decl-name-base-type? unqualified-decl-name
14841482
/// \endverbatim
14851483
///
14861484
// TODO(TF-1066): Use module qualified name syntax/parsing instead of custom

lib/Parse/ParseType.cpp

Lines changed: 10 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ ParserResult<TypeRepr> Parser::parseTypeSimple(
204204
status, PackTypeRepr::create(Context, keywordLoc,
205205
SourceRange(lbLoc, rbLoc), elements));
206206
} else {
207-
ty = parseSimpleTypeIdentifier();
207+
ty = parseTypeIdentifier();
208208
if (auto *ITR = cast_or_null<IdentTypeRepr>(ty.getPtrOrNull())) {
209209
if (Tok.is(tok::code_complete) && !Tok.isAtStartOfLine()) {
210210
if (IDECallbacks)
@@ -716,16 +716,8 @@ ParserStatus Parser::parseGenericArguments(SmallVectorImpl<TypeRepr *> &Args,
716716
return makeParserSuccess();
717717
}
718718

719-
/// parseTypeIdentifier
720-
///
721-
/// type-identifier:
722-
/// identifier generic-args? ('.' identifier generic-args?)*
723-
///
724-
ParserResult<TypeRepr>
725-
Parser::parseTypeIdentifier(bool isParsingQualifiedDeclBaseType) {
726-
// If parsing a qualified declaration name, return error if base type cannot
727-
// be parsed.
728-
if (isParsingQualifiedDeclBaseType && !canParseBaseTypeForQualifiedDeclName())
719+
ParserResult<TypeRepr> Parser::parseQualifiedDeclNameBaseType() {
720+
if (!canParseBaseTypeForQualifiedDeclName())
729721
return makeParserError();
730722

731723
if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_Self)) {
@@ -750,38 +742,11 @@ Parser::parseTypeIdentifier(bool isParsingQualifiedDeclBaseType) {
750742
return nullptr;
751743
}
752744

753-
// In SIL files (not just when parsing SIL types), accept the
754-
// Pack{} syntax for spelling variadic type packs.
755-
if (SIL && Tok.isContextualKeyword("Pack") &&
756-
peekToken().is(tok::l_brace)) {
757-
TokReceiver->registerTokenKindChange(Tok.getLoc(), tok::contextual_keyword);
758-
SourceLoc keywordLoc = consumeToken(tok::identifier);
759-
SourceLoc lbLoc = consumeToken(tok::l_brace);
760-
SourceLoc rbLoc;
761-
SmallVector<TypeRepr*, 8> elements;
762-
auto status = parseList(tok::r_brace, lbLoc, rbLoc,
763-
/*AllowSepAfterLast=*/false,
764-
diag::expected_rbrace_pack_type_list,
765-
[&] () -> ParserStatus {
766-
auto element = parseType(diag::expected_type);
767-
if (element.hasCodeCompletion())
768-
return makeParserCodeCompletionStatus();
769-
if (element.isNull())
770-
return makeParserError();
771-
elements.push_back(element.get());
772-
return makeParserSuccess();
773-
});
774-
775-
return makeParserResult(status,
776-
PackTypeRepr::create(Context, keywordLoc, SourceRange(lbLoc, rbLoc),
777-
elements));
778-
}
779-
780745
ParserStatus Status;
781746
SmallVector<IdentTypeRepr *, 4> ComponentsR;
782747
SourceLoc EndLoc;
783748
while (true) {
784-
auto IdentResult = parseSimpleTypeIdentifier();
749+
auto IdentResult = parseTypeIdentifier();
785750
if (IdentResult.isParseErrorOrHasCompletion())
786751
return IdentResult;
787752

@@ -797,9 +762,10 @@ Parser::parseTypeIdentifier(bool isParsingQualifiedDeclBaseType) {
797762
if (peekToken().isContextualKeyword("Type") ||
798763
peekToken().isContextualKeyword("Protocol"))
799764
break;
800-
// If parsing a qualified declaration name, break before parsing the
801-
// period before the final declaration name component.
802-
if (isParsingQualifiedDeclBaseType) {
765+
766+
// Break before parsing the period before the final declaration
767+
// name component.
768+
{
803769
// If qualified name base type cannot be parsed from the current
804770
// point (i.e. the next type identifier is not followed by a '.'),
805771
// then the next identifier is the final declaration name component.
@@ -839,7 +805,7 @@ Parser::parseTypeIdentifier(bool isParsingQualifiedDeclBaseType) {
839805
return makeParserResult(Status, DeclRefTR);
840806
}
841807

842-
ParserResult<IdentTypeRepr> Parser::parseSimpleTypeIdentifier() {
808+
ParserResult<IdentTypeRepr> Parser::parseTypeIdentifier() {
843809
// FIXME: We should parse e.g. 'X.var'. Almost any keyword is a valid member
844810
// component.
845811
DeclNameLoc Loc;
@@ -901,7 +867,7 @@ ParserResult<TypeRepr> Parser::parseTypeDotted(ParserResult<TypeRepr> Base) {
901867
continue;
902868
}
903869

904-
auto IdentResult = parseSimpleTypeIdentifier();
870+
auto IdentResult = parseTypeIdentifier();
905871
if (IdentResult.isParseErrorOrHasCompletion())
906872
return IdentResult | ParserStatus(Base);
907873

0 commit comments

Comments
 (0)