Skip to content

Commit 53d7406

Browse files
committed
[NFC] Add tok::colon_colon to parser
1 parent 9a98834 commit 53d7406

File tree

6 files changed

+51
-15
lines changed

6 files changed

+51
-15
lines changed

include/swift/AST/TokenKinds.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ PUNCTUATOR(period_prefix, ".")
203203
PUNCTUATOR(comma, ",")
204204
PUNCTUATOR(ellipsis, "...")
205205
PUNCTUATOR(colon, ":")
206+
PUNCTUATOR(colon_colon, "::")
206207
PUNCTUATOR(semi, ";")
207208
PUNCTUATOR(equal, "=")
208209
PUNCTUATOR(at_sign, "@")

include/swift/Parse/Parser.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,17 @@ class Parser {
763763
consumeStartingCharacterOfCurrentToken(tok Kind = tok::oper_binary_unspaced,
764764
size_t Len = 1);
765765

766+
/// If the next token is \c tok::colon, consume it; if the next token is
767+
/// \c tok::colon_colon, split it into two \c tok::colons and consume the
768+
/// first; otherwise, do nothing and return false.
769+
bool consumeIfColonSplittingDoubles() {
770+
if (!Tok.isAny(tok::colon, tok::colon_colon))
771+
return false;
772+
773+
consumeStartingCharacterOfCurrentToken(tok::colon);
774+
return true;
775+
}
776+
766777
//===--------------------------------------------------------------------===//
767778
// Primitive Parsing
768779

lib/Parse/Lexer.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2762,9 +2762,15 @@ void Lexer::lexImpl() {
27622762

27632763
case ',': return formToken(tok::comma, TokStart);
27642764
case ';': return formToken(tok::semi, TokStart);
2765-
case ':': return formToken(tok::colon, TokStart);
27662765
case '\\': return formToken(tok::backslash, TokStart);
27672766

2767+
case ':':
2768+
if (CurPtr[0] == ':') {
2769+
CurPtr++;
2770+
return formToken(tok::colon_colon, TokStart);
2771+
}
2772+
return formToken(tok::colon, TokStart);
2773+
27682774
case '#': {
27692775
// Try lex a raw string literal.
27702776
auto *Diags = getTokenDiags();

lib/Parse/ParseDecl.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1808,11 +1808,10 @@ void Parser::parseObjCSelector(SmallVector<Identifier, 4> &Names,
18081808
IsNullarySelector = true;
18091809
while (true) {
18101810
// Empty selector piece.
1811-
if (Tok.is(tok::colon)) {
1811+
if (consumeIfColonSplittingDoubles()) {
18121812
Names.push_back(Identifier());
1813-
NameLocs.push_back(Tok.getLoc());
1813+
NameLocs.push_back(PreviousLoc);
18141814
IsNullarySelector = false;
1815-
consumeToken();
18161815
continue;
18171816
}
18181817

@@ -1823,8 +1822,7 @@ void Parser::parseObjCSelector(SmallVector<Identifier, 4> &Names,
18231822
consumeToken();
18241823

18251824
// If we have a colon, consume it.
1826-
if (Tok.is(tok::colon)) {
1827-
consumeToken();
1825+
if (consumeIfColonSplittingDoubles()) {
18281826
IsNullarySelector = false;
18291827
continue;
18301828
}

lib/Parse/ParseExpr.cpp

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2142,14 +2142,29 @@ ParserResult<Expr> Parser::parseExprStringLiteral() {
21422142
AppendingExpr));
21432143
}
21442144

2145+
/// Equivalent to \c Tok.is(tok::colon), but pretends that \c tok::colon_colon
2146+
/// doesn't exist if \c EnableExperimentalModuleSelector is disabled.
2147+
static bool isColon(Parser &P, Token Tok, tok altColon = tok::NUM_TOKENS) {
2148+
// FIXME: Introducing tok::colon_colon broke diag::empty_arg_label_underscore.
2149+
// We only care about tok::colon_colon when module selectors are turned on, so
2150+
// when they are turned off, this function works around the bug by treating
2151+
// tok::colon_colon as a synonym for tok::colon. However, the bug still exists
2152+
// when Feature::ModuleSelector is enabled. We will need to address this
2153+
// before the feature can be released.
2154+
2155+
if (P.Context.LangOpts.hasFeature(Feature::ModuleSelector))
2156+
return Tok.isAny(tok::colon, altColon);
2157+
2158+
return Tok.isAny(tok::colon, tok::colon_colon, altColon);
2159+
}
2160+
21452161
void Parser::parseOptionalArgumentLabel(Identifier &name, SourceLoc &loc,
21462162
bool isAttr) {
21472163
/// A token that has the same meaning as colon, but is deprecated, if one exists for this call.
21482164
auto altColon = isAttr ? tok::equal : tok::NUM_TOKENS;
21492165

21502166
// Check to see if there is an argument label.
2151-
if (Tok.canBeArgumentLabel() && peekToken().isAny(tok::colon, altColon)) {
2152-
// Label found, including colon.
2167+
if (Tok.canBeArgumentLabel() && isColon(*this, peekToken(), altColon)) {
21532168
auto text = Tok.getText();
21542169

21552170
// If this was an escaped identifier that need not have been escaped, say
@@ -2168,7 +2183,7 @@ void Parser::parseOptionalArgumentLabel(Identifier &name, SourceLoc &loc,
21682183
}
21692184

21702185
loc = consumeArgumentLabel(name, /*diagnoseDollarPrefix=*/false);
2171-
} else if (Tok.isAny(tok::colon, altColon)) {
2186+
} else if (isColon(*this, Tok, altColon)) {
21722187
// Found only the colon.
21732188
diagnose(Tok, diag::expected_label_before_colon)
21742189
.fixItInsert(Tok.getLoc(), "<#label#>");
@@ -2178,7 +2193,12 @@ void Parser::parseOptionalArgumentLabel(Identifier &name, SourceLoc &loc,
21782193
}
21792194

21802195
// If we get here, we ought to be on the colon.
2181-
assert(Tok.isAny(tok::colon, altColon));
2196+
ASSERT(Tok.isAny(tok::colon, tok::colon_colon, altColon));
2197+
2198+
if (Tok.is(tok::colon_colon)) {
2199+
consumeIfColonSplittingDoubles();
2200+
return;
2201+
}
21822202

21832203
if (Tok.is(altColon))
21842204
diagnose(Tok, diag::replace_equal_with_colon_for_value)
@@ -2208,7 +2228,7 @@ static bool tryParseArgLabelList(Parser &P, Parser::DeclNameOptions flags,
22082228
flags.contains(Parser::DeclNameFlag::AllowZeroArgCompoundNames) &&
22092229
next.is(tok::r_paren);
22102230
// An argument label.
2211-
bool nextIsArgLabel = next.canBeArgumentLabel() || next.is(tok::colon);
2231+
bool nextIsArgLabel = next.canBeArgumentLabel() || isColon(P, next);
22122232
// An editor placeholder.
22132233
bool nextIsPlaceholder = next.isEditorPlaceholder();
22142234

@@ -2221,11 +2241,11 @@ static bool tryParseArgLabelList(Parser &P, Parser::DeclNameOptions flags,
22212241
lparenLoc = P.consumeToken(tok::l_paren);
22222242
while (P.Tok.isNot(tok::r_paren)) {
22232243
// If we see a ':', the user forgot the '_';
2224-
if (P.Tok.is(tok::colon)) {
2225-
P.diagnose(P.Tok, diag::empty_arg_label_underscore)
2226-
.fixItInsert(P.Tok.getLoc(), "_");
2244+
if (P.consumeIfColonSplittingDoubles()) {
2245+
P.diagnose(P.PreviousLoc, diag::empty_arg_label_underscore)
2246+
.fixItInsert(P.PreviousLoc, "_");
22272247
argumentLabels.push_back(Identifier());
2228-
argumentLabelLocs.push_back(P.consumeToken(tok::colon));
2248+
argumentLabelLocs.push_back(P.PreviousLoc);
22292249
}
22302250

22312251
Identifier argName;

0 commit comments

Comments
 (0)