Skip to content

Commit 0988e54

Browse files
committed
[Parser] Factor parsing of accessors into its own function
1 parent 559ae7f commit 0988e54

File tree

2 files changed

+71
-46
lines changed

2 files changed

+71
-46
lines changed

include/swift/Parse/Parser.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,14 @@ class Parser {
11891189
bool HasLetOrVarKeyword = true);
11901190

11911191
struct ParsedAccessors;
1192+
1193+
bool parseAccessorAfterIntroducer(
1194+
SourceLoc Loc, AccessorKind Kind, ParsedAccessors &accessors,
1195+
bool &hasEffectfulGet, ParameterList *Indices, bool &parsingLimitedSyntax,
1196+
DeclAttributes &Attributes, ParseDeclOptions Flags,
1197+
AbstractStorageDecl *storage, SourceLoc StaticLoc, ParserStatus &Status
1198+
);
1199+
11921200
ParserStatus parseGetSet(ParseDeclOptions Flags, ParameterList *Indices,
11931201
TypeRepr *ResultType, ParsedAccessors &accessors,
11941202
AbstractStorageDecl *storage, SourceLoc StaticLoc);

lib/Parse/ParseDecl.cpp

Lines changed: 63 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6571,6 +6571,64 @@ ParserStatus Parser::parseGetEffectSpecifier(ParsedAccessors &accessors,
65716571
return Status;
65726572
}
65736573

6574+
bool Parser::parseAccessorAfterIntroducer(
6575+
SourceLoc Loc, AccessorKind Kind, ParsedAccessors &accessors,
6576+
bool &hasEffectfulGet, ParameterList *Indices, bool &parsingLimitedSyntax,
6577+
DeclAttributes &Attributes, ParseDeclOptions Flags,
6578+
AbstractStorageDecl *storage, SourceLoc StaticLoc, ParserStatus &Status
6579+
) {
6580+
auto *ValueNamePattern = parseOptionalAccessorArgument(Loc, *this, Kind);
6581+
6582+
// Next, parse effects specifiers. While it's only valid to have them
6583+
// on 'get' accessors, we also emit diagnostics if they show up on others.
6584+
SourceLoc asyncLoc;
6585+
SourceLoc throwsLoc;
6586+
Status |= parseGetEffectSpecifier(accessors, asyncLoc, throwsLoc,
6587+
hasEffectfulGet, Kind, Loc);
6588+
6589+
// Set up a function declaration.
6590+
auto accessor =
6591+
createAccessorFunc(Loc, ValueNamePattern, Indices, StaticLoc, Flags,
6592+
Kind, storage, this, Loc, asyncLoc, throwsLoc);
6593+
accessor->getAttrs() = Attributes;
6594+
6595+
// Collect this accessor and detect conflicts.
6596+
if (auto existingAccessor = accessors.add(accessor)) {
6597+
diagnoseRedundantAccessors(*this, Loc, Kind,
6598+
/*subscript*/Indices != nullptr,
6599+
existingAccessor);
6600+
}
6601+
6602+
// There should be no body in the limited syntax; diagnose unexpected
6603+
// accessor implementations.
6604+
if (parsingLimitedSyntax) {
6605+
if (Tok.is(tok::l_brace))
6606+
diagnose(Tok, diag::unexpected_getset_implementation_in_protocol,
6607+
getAccessorNameForDiagnostic(Kind, /*article*/ false));
6608+
return false;
6609+
}
6610+
6611+
// It's okay not to have a body if there's an external asm name.
6612+
if (!Tok.is(tok::l_brace)) {
6613+
// Accessors don't need bodies in module interfaces
6614+
if (SF.Kind == SourceFileKind::Interface)
6615+
return false;
6616+
6617+
// _silgen_name'd accessors don't need bodies.
6618+
if (!Attributes.hasAttribute<SILGenNameAttr>()) {
6619+
diagnose(Tok, diag::expected_lbrace_accessor,
6620+
getAccessorNameForDiagnostic(accessor, /*article*/ false));
6621+
Status |= makeParserError();
6622+
return true;
6623+
}
6624+
6625+
return false;
6626+
}
6627+
6628+
parseAbstractFunctionBody(accessor);
6629+
return false;
6630+
}
6631+
65746632
ParserStatus Parser::parseGetSet(ParseDeclOptions Flags, ParameterList *Indices,
65756633
TypeRepr *ResultType,
65766634
ParsedAccessors &accessors,
@@ -6703,53 +6761,12 @@ ParserStatus Parser::parseGetSet(ParseDeclOptions Flags, ParameterList *Indices,
67036761
if (parsingLimitedSyntax && Tok.is(tok::l_paren)) {
67046762
diagnose(Loc, diag::protocol_setter_name);
67056763
}
6706-
auto *ValueNamePattern = parseOptionalAccessorArgument(Loc, *this, Kind);
67076764

6708-
// Next, parse effects specifiers. While it's only valid to have them
6709-
// on 'get' accessors, we also emit diagnostics if they show up on others.
6710-
SourceLoc asyncLoc;
6711-
SourceLoc throwsLoc;
6712-
Status |= parseGetEffectSpecifier(accessors, asyncLoc, throwsLoc,
6713-
hasEffectfulGet, Kind, Loc);
6714-
6715-
// Set up a function declaration.
6716-
auto accessor =
6717-
createAccessorFunc(Loc, ValueNamePattern, Indices, StaticLoc, Flags,
6718-
Kind, storage, this, Loc, asyncLoc, throwsLoc);
6719-
accessor->getAttrs() = Attributes;
6720-
6721-
// Collect this accessor and detect conflicts.
6722-
if (auto existingAccessor = accessors.add(accessor)) {
6723-
diagnoseRedundantAccessors(*this, Loc, Kind,
6724-
/*subscript*/Indices != nullptr,
6725-
existingAccessor);
6726-
}
6727-
6728-
// There should be no body in the limited syntax; diagnose unexpected
6729-
// accessor implementations.
6730-
if (parsingLimitedSyntax) {
6731-
if (Tok.is(tok::l_brace))
6732-
diagnose(Tok, diag::unexpected_getset_implementation_in_protocol,
6733-
getAccessorNameForDiagnostic(Kind, /*article*/ false));
6734-
continue;
6735-
}
6736-
6737-
// It's okay not to have a body if there's an external asm name.
6738-
if (!Tok.is(tok::l_brace)) {
6739-
// Accessors don't need bodies in module interfaces
6740-
if (SF.Kind == SourceFileKind::Interface)
6741-
continue;
6742-
// _silgen_name'd accessors don't need bodies.
6743-
if (!Attributes.hasAttribute<SILGenNameAttr>()) {
6744-
diagnose(Tok, diag::expected_lbrace_accessor,
6745-
getAccessorNameForDiagnostic(accessor, /*article*/ false));
6746-
Status |= makeParserError();
6747-
break;
6748-
}
6749-
continue;
6750-
}
6751-
6752-
parseAbstractFunctionBody(accessor);
6765+
if (parseAccessorAfterIntroducer(
6766+
Loc, Kind, accessors, hasEffectfulGet, Indices, parsingLimitedSyntax,
6767+
Attributes, Flags, storage, StaticLoc, Status
6768+
))
6769+
break;
67536770
}
67546771
backtrack->cancelBacktrack();
67556772
backtrack.reset();

0 commit comments

Comments
 (0)