Skip to content

Commit 439d99c

Browse files
authored
Merge pull request #28801 from brentdax/im-not-qualified-for-this
[NFC] Refactor name parsing into `parseDeclNameRef()`
2 parents a46ea4b + bed2ce4 commit 439d99c

File tree

4 files changed

+168
-155
lines changed

4 files changed

+168
-155
lines changed

include/swift/Parse/Parser.h

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,38 +1412,43 @@ class Parser {
14121412
/// \param loc The location of the label (empty if it doesn't exist)
14131413
void parseOptionalArgumentLabel(Identifier &name, SourceLoc &loc);
14141414

1415-
/// Parse an unqualified-decl-base-name.
1415+
enum class DeclNameFlag : uint8_t {
1416+
/// If passed, operator basenames are allowed.
1417+
AllowOperators = 1 << 0,
1418+
1419+
/// If passed, names that coincide with keywords are allowed. Used after a
1420+
/// dot to enable things like '.init' and '.default'.
1421+
AllowKeywords = 1 << 1,
1422+
1423+
/// If passed, 'deinit' and 'subscript' should be parsed as special names,
1424+
/// not ordinary identifiers.
1425+
AllowKeywordsUsingSpecialNames = AllowKeywords | 1 << 2,
1426+
1427+
/// If passed, compound names with argument lists are allowed, unless they
1428+
/// have empty argument lists.
1429+
AllowCompoundNames = 1 << 4,
1430+
1431+
/// If passed, compound names with empty argument lists are allowed.
1432+
AllowZeroArgCompoundNames = AllowCompoundNames | 1 << 5,
1433+
};
1434+
using DeclNameOptions = OptionSet<DeclNameFlag>;
1435+
1436+
friend DeclNameOptions operator|(DeclNameFlag flag1, DeclNameFlag flag2) {
1437+
return DeclNameOptions(flag1) | flag2;
1438+
}
1439+
1440+
/// Without \c DeclNameFlag::AllowCompoundNames, parse an
1441+
/// unqualified-decl-base-name.
14161442
///
1417-
/// unqualified-decl-name:
1418-
/// identifier
1443+
/// unqualified-decl-base-name: identifier
14191444
///
1420-
/// \param afterDot Whether this identifier is coming after a period, which
1421-
/// enables '.init' and '.default' like expressions.
1422-
/// \param loc Will be populated with the location of the name.
1423-
/// \param diag The diagnostic to emit if this is not a name.
1424-
/// \param allowOperators Whether to allow operator basenames too.
1425-
DeclNameRef parseUnqualifiedDeclBaseName(bool afterDot, DeclNameLoc &loc,
1426-
const Diagnostic &diag,
1427-
bool allowOperators=false,
1428-
bool allowDeinitAndSubscript=false);
1429-
1430-
/// Parse an unqualified-decl-name.
1445+
/// With \c DeclNameFlag::AllowCompoundNames, parse an unqualified-base-name.
14311446
///
14321447
/// unqualified-decl-name:
14331448
/// unqualified-decl-base-name
14341449
/// unqualified-decl-base-name '(' ((identifier | '_') ':') + ')'
1435-
///
1436-
/// \param afterDot Whether this identifier is coming after a period, which
1437-
/// enables '.init' and '.default' like expressions.
1438-
/// \param loc Will be populated with the location of the name.
1439-
/// \param diag The diagnostic to emit if this is not a name.
1440-
/// \param allowOperators Whether to allow operator basenames too.
1441-
/// \param allowZeroArgCompoundNames Whether to allow empty argument lists.
1442-
DeclNameRef parseUnqualifiedDeclName(bool afterDot, DeclNameLoc &loc,
1443-
const Diagnostic &diag,
1444-
bool allowOperators=false,
1445-
bool allowZeroArgCompoundNames=false,
1446-
bool allowDeinitAndSubscript=false);
1450+
DeclNameRef parseDeclNameRef(DeclNameLoc &loc, const Diagnostic &diag,
1451+
DeclNameOptions flags);
14471452

14481453
Expr *parseExprIdentifier();
14491454
Expr *parseExprEditorPlaceholder(Token PlaceholderTok,

lib/Parse/ParseDecl.cpp

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -768,11 +768,10 @@ Parser::parseImplementsAttribute(SourceLoc AtLoc, SourceLoc Loc) {
768768
}
769769

770770
if (!Status.shouldStopParsing()) {
771-
MemberName =
772-
parseUnqualifiedDeclName(/*afterDot=*/false, MemberNameLoc,
773-
diag::attr_implements_expected_member_name,
774-
/*allowOperators=*/true,
775-
/*allowZeroArgCompoundNames=*/true);
771+
MemberName = parseDeclNameRef(MemberNameLoc,
772+
diag::attr_implements_expected_member_name,
773+
DeclNameFlag::AllowZeroArgCompoundNames |
774+
DeclNameFlag::AllowOperators);
776775
if (!MemberName) {
777776
Status.setIsParseError();
778777
}
@@ -1022,10 +1021,8 @@ bool Parser::parseDifferentiableAttributeArguments(
10221021
SyntaxContext, SyntaxKind::FunctionDeclName);
10231022
Diagnostic funcDiag(diag::attr_differentiable_expected_function_name.ID,
10241023
{ label });
1025-
result.Name =
1026-
parseUnqualifiedDeclName(/*afterDot=*/false, result.Loc,
1027-
funcDiag, /*allowOperators=*/true,
1028-
/*allowZeroArgCompoundNames=*/true);
1024+
result.Name = parseDeclNameRef(result.Loc, funcDiag,
1025+
DeclNameFlag::AllowZeroArgCompoundNames | DeclNameFlag::AllowOperators);
10291026
// If no trailing comma or 'where' clause, terminate parsing arguments.
10301027
if (Tok.isNot(tok::comma, tok::kw_where))
10311028
terminateParsingArgs = true;
@@ -1129,10 +1126,11 @@ ParserResult<DerivativeAttr> Parser::parseDerivativeAttribute(SourceLoc atLoc,
11291126
SyntaxKind::FunctionDeclName);
11301127
// NOTE: Use `afterDot = true` and `allowDeinitAndSubscript = true` to
11311128
// enable, e.g. `@derivative(of: init)` and `@derivative(of: subscript)`.
1132-
original.Name = parseUnqualifiedDeclName(
1133-
/*afterDot*/ true, original.Loc,
1134-
diag::attr_derivative_expected_original_name, /*allowOperators*/ true,
1135-
/*allowZeroArgCompoundNames*/ true, /*allowDeinitAndSubscript*/ true);
1129+
original.Name = parseDeclNameRef(original.Loc,
1130+
diag::attr_derivative_expected_original_name,
1131+
DeclNameFlag::AllowZeroArgCompoundNames |
1132+
DeclNameFlag::AllowKeywordsUsingSpecialNames |
1133+
DeclNameFlag::AllowOperators);
11361134
}
11371135
if (consumeIfTrailingComma())
11381136
return makeParserError();
@@ -2060,10 +2058,11 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
20602058
SyntaxKind::DeclName);
20612059

20622060
DeclNameLoc loc;
2063-
replacedFunction = parseUnqualifiedDeclName(
2064-
true, loc, diag::attr_dynamic_replacement_expected_function,
2065-
/*allowOperators*/ true, /*allowZeroArgCompoundNames*/ true,
2066-
/*allowDeinitAndSubscript*/ true);
2061+
replacedFunction = parseDeclNameRef(loc,
2062+
diag::attr_dynamic_replacement_expected_function,
2063+
DeclNameFlag::AllowZeroArgCompoundNames |
2064+
DeclNameFlag::AllowKeywordsUsingSpecialNames |
2065+
DeclNameFlag::AllowOperators);
20672066
}
20682067
}
20692068

@@ -2572,11 +2571,9 @@ bool Parser::parseConventionAttributeInternal(
25722571
return true;
25732572
}
25742573

2575-
DeclNameLoc unusedWitnessMethodProtocolLoc;
2576-
convention.WitnessMethodProtocol = parseUnqualifiedDeclBaseName(
2577-
/*afterDot=*/false, unusedWitnessMethodProtocolLoc,
2578-
diag::convention_attribute_witness_method_expected_protocol
2579-
);
2574+
DeclNameLoc unusedLoc;
2575+
convention.WitnessMethodProtocol = parseDeclNameRef(unusedLoc,
2576+
diag::convention_attribute_witness_method_expected_protocol, {});
25802577
}
25812578

25822579
// Parse the ')'. We can't use parseMatchingToken if we're in

0 commit comments

Comments
 (0)