Skip to content

Commit 561c379

Browse files
committed
refactor the parsing logic for "x.y" to detangle it a bit, NFC.
1 parent a0efe4f commit 561c379

File tree

1 file changed

+74
-75
lines changed

1 file changed

+74
-75
lines changed

lib/Parse/ParseExpr.cpp

Lines changed: 74 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,95 +1250,94 @@ ParserResult<Expr> Parser::parseExprPostfix(Diag<> ID, bool isExprBasic) {
12501250
// Check for a .foo suffix.
12511251
SourceLoc TokLoc = Tok.getLoc();
12521252
if (consumeIf(tok::period) || consumeIf(tok::period_prefix)) {
1253-
// Non-identifier cases.
1254-
if (Tok.isNot(tok::identifier) && Tok.isNot(tok::integer_literal) &&
1255-
Tok.isNot(tok::kw_init)) {
1256-
// A metatype expr.
1257-
if (Tok.is(tok::kw_dynamicType)) {
1258-
Result = makeParserResult(
1259-
new (Context) DynamicTypeExpr(Result.get(), consumeToken(),
1260-
Type()));
1261-
continue;
1262-
}
1253+
1254+
// Handle "x.42" - a tuple index.
1255+
if (Tok.is(tok::integer_literal)) {
1256+
DeclName name = Context.getIdentifier(Tok.getText());
1257+
SourceLoc nameLoc = consumeToken(tok::integer_literal);
12631258

1264-
// A '.self' expr.
1265-
if (Tok.is(tok::kw_self)) {
1266-
Result = makeParserResult(
1267-
new (Context) DotSelfExpr(Result.get(), TokLoc, consumeToken()));
1259+
// Don't allow '.<integer literal>' following a numeric literal
1260+
// expression.
1261+
if (Result.isNonNull() && isa<NumberLiteralExpr>(Result.get())) {
1262+
diagnose(nameLoc, diag::numeric_literal_numeric_member)
1263+
.highlight(Result.get()->getSourceRange());
12681264
continue;
12691265
}
12701266

1271-
// If we have '.<keyword><code_complete>', try to recover by creating
1272-
// an identifier with the same spelling as the keyword.
1273-
if (Tok.isKeyword() && peekToken().is(tok::code_complete)) {
1274-
Identifier Name = Context.getIdentifier(Tok.getText());
1275-
Result = makeParserResult(
1276-
new (Context) UnresolvedDotExpr(Result.get(), TokLoc,
1277-
Name, DeclNameLoc(Tok.getLoc()),
1278-
/*Implicit=*/false));
1279-
consumeToken();
1280-
}
1281-
1282-
if (Tok.is(tok::code_complete)) {
1283-
if (CodeCompletion && Result.isNonNull())
1284-
CodeCompletion->completeDotExpr(Result.get(), /*DotLoc=*/TokLoc);
1285-
// Eat the code completion token because we handled it.
1286-
consumeToken(tok::code_complete);
1287-
Result.setHasCodeCompletion();
1288-
return Result;
1289-
}
1290-
checkForInputIncomplete();
1291-
diagnose(Tok, diag::expected_member_name);
1292-
return nullptr;
1267+
Result = makeParserResult(
1268+
new (Context) UnresolvedDotExpr(Result.get(), TokLoc, name,
1269+
DeclNameLoc(nameLoc),
1270+
/*Implicit=*/false));
1271+
continue;
12931272
}
12941273

1295-
// Don't allow '.<integer literal>' following a numeric literal
1296-
// expression.
1297-
if (Tok.is(tok::integer_literal) && Result.isNonNull() &&
1298-
(isa<FloatLiteralExpr>(Result.get()) ||
1299-
isa<IntegerLiteralExpr>(Result.get()))) {
1300-
diagnose(Tok, diag::numeric_literal_numeric_member)
1301-
.highlight(Result.get()->getSourceRange());
1302-
consumeToken();
1274+
// Handle "x.dynamicType" - A metatype expr.
1275+
if (Tok.is(tok::kw_dynamicType)) {
1276+
Result = makeParserResult(
1277+
new (Context) DynamicTypeExpr(Result.get(), consumeToken(), Type()));
13031278
continue;
13041279
}
13051280

1306-
if (Result.isParseError())
1281+
// Handle "x.self" expr.
1282+
if (Tok.is(tok::kw_self)) {
1283+
Result = makeParserResult(
1284+
new (Context) DotSelfExpr(Result.get(), TokLoc, consumeToken()));
13071285
continue;
1308-
1309-
if (Tok.isAny(tok::identifier, tok::kw_init)) {
1310-
DeclNameLoc NameLoc;
1311-
DeclName Name = parseUnqualifiedDeclName(/*allowInit=*/true,
1312-
NameLoc,
1313-
diag::expected_member_name);
1314-
if (!Name) return nullptr;
1286+
}
13151287

1288+
// Handle "x.<tab>" for code completion.
1289+
if (Tok.is(tok::code_complete)) {
1290+
if (CodeCompletion && Result.isNonNull())
1291+
CodeCompletion->completeDotExpr(Result.get(), /*DotLoc=*/TokLoc);
1292+
// Eat the code completion token because we handled it.
1293+
consumeToken(tok::code_complete);
1294+
Result.setHasCodeCompletion();
1295+
return Result;
1296+
}
1297+
1298+
// If we have '.<keyword><code_complete>', try to recover by creating
1299+
// an identifier with the same spelling as the keyword.
1300+
if (Tok.isKeyword() && peekToken().is(tok::code_complete)) {
1301+
Identifier Name = Context.getIdentifier(Tok.getText());
13161302
Result = makeParserResult(
1317-
new (Context) UnresolvedDotExpr(Result.get(), TokLoc, Name,
1318-
NameLoc,
1319-
/*Implicit=*/false));
1320-
1321-
if (canParseAsGenericArgumentList()) {
1322-
SmallVector<TypeRepr*, 8> args;
1323-
SourceLoc LAngleLoc, RAngleLoc;
1324-
if (parseGenericArguments(args, LAngleLoc, RAngleLoc)) {
1325-
diagnose(LAngleLoc, diag::while_parsing_as_left_angle_bracket);
1326-
}
1303+
new (Context) UnresolvedDotExpr(Result.get(), TokLoc,
1304+
Name, DeclNameLoc(Tok.getLoc()),
1305+
/*Implicit=*/false));
1306+
consumeToken();
1307+
}
1308+
1309+
// Non-identifier cases.
1310+
if (Tok.isNot(tok::identifier, tok::kw_init)) {
1311+
checkForInputIncomplete();
1312+
diagnose(Tok, diag::expected_member_name);
1313+
return nullptr;
1314+
}
13271315

1328-
SmallVector<TypeLoc, 8> locArgs;
1329-
for (auto ty : args)
1330-
locArgs.push_back(ty);
1331-
Result = makeParserResult(new (Context) UnresolvedSpecializeExpr(
1332-
Result.get(), LAngleLoc, Context.AllocateCopy(locArgs),
1333-
RAngleLoc));
1316+
assert(Tok.isAny(tok::identifier, tok::kw_init));
1317+
DeclNameLoc NameLoc;
1318+
DeclName Name = parseUnqualifiedDeclName(/*allowInit=*/true,
1319+
NameLoc,
1320+
diag::expected_member_name);
1321+
if (!Name) return nullptr;
1322+
1323+
Result = makeParserResult(
1324+
new (Context) UnresolvedDotExpr(Result.get(), TokLoc, Name,
1325+
NameLoc,
1326+
/*Implicit=*/false));
1327+
1328+
if (canParseAsGenericArgumentList()) {
1329+
SmallVector<TypeRepr*, 8> args;
1330+
SourceLoc LAngleLoc, RAngleLoc;
1331+
if (parseGenericArguments(args, LAngleLoc, RAngleLoc)) {
1332+
diagnose(LAngleLoc, diag::while_parsing_as_left_angle_bracket);
13341333
}
1335-
} else {
1336-
DeclName name = Context.getIdentifier(Tok.getText());
1337-
SourceLoc nameLoc = consumeToken(tok::integer_literal);
1338-
Result = makeParserResult(
1339-
new (Context) UnresolvedDotExpr(Result.get(), TokLoc, name,
1340-
DeclNameLoc(nameLoc),
1341-
/*Implicit=*/false));
1334+
1335+
SmallVector<TypeLoc, 8> locArgs;
1336+
for (auto ty : args)
1337+
locArgs.push_back(ty);
1338+
Result = makeParserResult(new (Context) UnresolvedSpecializeExpr(
1339+
Result.get(), LAngleLoc, Context.AllocateCopy(locArgs),
1340+
RAngleLoc));
13421341
}
13431342

13441343
// If there is an expr-call-suffix, parse it and form a call.

0 commit comments

Comments
 (0)