Skip to content

[NFC] Refactor name parsing into parseDeclNameRef() #28801

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 31 additions & 26 deletions include/swift/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -1412,38 +1412,43 @@ class Parser {
/// \param loc The location of the label (empty if it doesn't exist)
void parseOptionalArgumentLabel(Identifier &name, SourceLoc &loc);

/// Parse an unqualified-decl-base-name.
enum class DeclNameFlag : uint8_t {
/// If passed, operator basenames are allowed.
AllowOperators = 1 << 0,

/// If passed, names that coincide with keywords are allowed. Used after a
/// dot to enable things like '.init' and '.default'.
AllowKeywords = 1 << 1,

/// If passed, 'deinit' and 'subscript' should be parsed as special names,
/// not ordinary identifiers.
AllowKeywordsUsingSpecialNames = AllowKeywords | 1 << 2,

/// If passed, compound names with argument lists are allowed, unless they
/// have empty argument lists.
AllowCompoundNames = 1 << 4,

/// If passed, compound names with empty argument lists are allowed.
AllowZeroArgCompoundNames = AllowCompoundNames | 1 << 5,
};
using DeclNameOptions = OptionSet<DeclNameFlag>;

friend DeclNameOptions operator|(DeclNameFlag flag1, DeclNameFlag flag2) {
return DeclNameOptions(flag1) | flag2;
}

/// Without \c DeclNameFlag::AllowCompoundNames, parse an
/// unqualified-decl-base-name.
///
/// unqualified-decl-name:
/// identifier
/// unqualified-decl-base-name: identifier
///
/// \param afterDot Whether this identifier is coming after a period, which
/// enables '.init' and '.default' like expressions.
/// \param loc Will be populated with the location of the name.
/// \param diag The diagnostic to emit if this is not a name.
/// \param allowOperators Whether to allow operator basenames too.
DeclNameRef parseUnqualifiedDeclBaseName(bool afterDot, DeclNameLoc &loc,
const Diagnostic &diag,
bool allowOperators=false,
bool allowDeinitAndSubscript=false);

/// Parse an unqualified-decl-name.
/// With \c DeclNameFlag::AllowCompoundNames, parse an unqualified-base-name.
///
/// unqualified-decl-name:
/// unqualified-decl-base-name
/// unqualified-decl-base-name '(' ((identifier | '_') ':') + ')'
///
/// \param afterDot Whether this identifier is coming after a period, which
/// enables '.init' and '.default' like expressions.
/// \param loc Will be populated with the location of the name.
/// \param diag The diagnostic to emit if this is not a name.
/// \param allowOperators Whether to allow operator basenames too.
/// \param allowZeroArgCompoundNames Whether to allow empty argument lists.
DeclNameRef parseUnqualifiedDeclName(bool afterDot, DeclNameLoc &loc,
const Diagnostic &diag,
bool allowOperators=false,
bool allowZeroArgCompoundNames=false,
bool allowDeinitAndSubscript=false);
DeclNameRef parseDeclNameRef(DeclNameLoc &loc, const Diagnostic &diag,
DeclNameOptions flags);

Expr *parseExprIdentifier();
Expr *parseExprEditorPlaceholder(Token PlaceholderTok,
Expand Down
41 changes: 19 additions & 22 deletions lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -768,11 +768,10 @@ Parser::parseImplementsAttribute(SourceLoc AtLoc, SourceLoc Loc) {
}

if (!Status.shouldStopParsing()) {
MemberName =
parseUnqualifiedDeclName(/*afterDot=*/false, MemberNameLoc,
diag::attr_implements_expected_member_name,
/*allowOperators=*/true,
/*allowZeroArgCompoundNames=*/true);
MemberName = parseDeclNameRef(MemberNameLoc,
diag::attr_implements_expected_member_name,
DeclNameFlag::AllowZeroArgCompoundNames |
DeclNameFlag::AllowOperators);
if (!MemberName) {
Status.setIsParseError();
}
Expand Down Expand Up @@ -1022,10 +1021,8 @@ bool Parser::parseDifferentiableAttributeArguments(
SyntaxContext, SyntaxKind::FunctionDeclName);
Diagnostic funcDiag(diag::attr_differentiable_expected_function_name.ID,
{ label });
result.Name =
parseUnqualifiedDeclName(/*afterDot=*/false, result.Loc,
funcDiag, /*allowOperators=*/true,
/*allowZeroArgCompoundNames=*/true);
result.Name = parseDeclNameRef(result.Loc, funcDiag,
DeclNameFlag::AllowZeroArgCompoundNames | DeclNameFlag::AllowOperators);
// If no trailing comma or 'where' clause, terminate parsing arguments.
if (Tok.isNot(tok::comma, tok::kw_where))
terminateParsingArgs = true;
Expand Down Expand Up @@ -1129,10 +1126,11 @@ ParserResult<DerivativeAttr> Parser::parseDerivativeAttribute(SourceLoc atLoc,
SyntaxKind::FunctionDeclName);
// NOTE: Use `afterDot = true` and `allowDeinitAndSubscript = true` to
// enable, e.g. `@derivative(of: init)` and `@derivative(of: subscript)`.
original.Name = parseUnqualifiedDeclName(
/*afterDot*/ true, original.Loc,
diag::attr_derivative_expected_original_name, /*allowOperators*/ true,
/*allowZeroArgCompoundNames*/ true, /*allowDeinitAndSubscript*/ true);
original.Name = parseDeclNameRef(original.Loc,
diag::attr_derivative_expected_original_name,
DeclNameFlag::AllowZeroArgCompoundNames |
DeclNameFlag::AllowKeywordsUsingSpecialNames |
DeclNameFlag::AllowOperators);
}
if (consumeIfTrailingComma())
return makeParserError();
Expand Down Expand Up @@ -2060,10 +2058,11 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
SyntaxKind::DeclName);

DeclNameLoc loc;
replacedFunction = parseUnqualifiedDeclName(
true, loc, diag::attr_dynamic_replacement_expected_function,
/*allowOperators*/ true, /*allowZeroArgCompoundNames*/ true,
/*allowDeinitAndSubscript*/ true);
replacedFunction = parseDeclNameRef(loc,
diag::attr_dynamic_replacement_expected_function,
DeclNameFlag::AllowZeroArgCompoundNames |
DeclNameFlag::AllowKeywordsUsingSpecialNames |
DeclNameFlag::AllowOperators);
}
}

Expand Down Expand Up @@ -2572,11 +2571,9 @@ bool Parser::parseConventionAttributeInternal(
return true;
}

DeclNameLoc unusedWitnessMethodProtocolLoc;
convention.WitnessMethodProtocol = parseUnqualifiedDeclBaseName(
/*afterDot=*/false, unusedWitnessMethodProtocolLoc,
diag::convention_attribute_witness_method_expected_protocol
);
DeclNameLoc unusedLoc;
convention.WitnessMethodProtocol = parseDeclNameRef(unusedLoc,
diag::convention_attribute_witness_method_expected_protocol, {});
}

// Parse the ')'. We can't use parseMatchingToken if we're in
Expand Down
Loading