Skip to content

Commit 4639f99

Browse files
ahoppenJan Svobodarintaro
committed
[syntax-parse] Parse all literals and magic identifiers using libSyntax
This commit re-applies changes that have been applied, reversed, re-applied and re-reversed. Credit for the original implementation goes to Jan Svoboda <[email protected]> for writing the original implementation and Rintaro Ishizaki <[email protected]> who review it and applied some fixes. Co-authored-by: Jan Svoboda <[email protected]> Co-authored-by: Rintaro Ishizaki <[email protected]>
1 parent a46aa28 commit 4639f99

File tree

3 files changed

+225
-69
lines changed

3 files changed

+225
-69
lines changed

include/swift/Parse/ASTGen.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,18 @@ class ASTGen {
3434
//===--------------------------------------------------------------------===//
3535
// MARK: - Expressions
3636
public:
37+
Expr *generate(const BooleanLiteralExprSyntax &Expr, const SourceLoc &Loc);
38+
Expr *generate(const FloatLiteralExprSyntax &Expr, const SourceLoc &Loc);
3739
Expr *generate(const IntegerLiteralExprSyntax &Expr, const SourceLoc &Loc);
40+
Expr *generate(const NilLiteralExprSyntax &Expr, const SourceLoc &Loc);
41+
Expr *generate(const PoundColumnExprSyntax &Expr, const SourceLoc &Loc);
42+
Expr *generate(const PoundDsohandleExprSyntax &Expr, const SourceLoc &Loc);
43+
Expr *generate(const PoundFileExprSyntax &Expr, const SourceLoc &Loc);
44+
Expr *generate(const PoundFileIDExprSyntax &Expr, const SourceLoc &Loc);
45+
Expr *generate(const PoundFilePathExprSyntax &Expr, const SourceLoc &Loc);
46+
Expr *generate(const PoundLineExprSyntax &Expr, const SourceLoc &Loc);
47+
Expr *generate(const PoundFunctionExprSyntax &Expr, const SourceLoc &Loc);
48+
Expr *generate(const UnknownExprSyntax &Expr, const SourceLoc &Loc);
3849

3950
private:
4051
/// Map magic literal tokens such as #file to their MagicIdentifierLiteralExpr

lib/Parse/ASTGenExpr.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,84 @@
1717
using namespace swift;
1818
using namespace swift::syntax;
1919

20+
Expr *ASTGen::generate(const BooleanLiteralExprSyntax &Expr, const SourceLoc &Loc) {
21+
TokenSyntax Literal = Expr.getBooleanLiteral();
22+
assert(Literal.getTokenKind() == tok::kw_true ||
23+
Literal.getTokenKind() == tok::kw_false);
24+
bool Value = Literal.getTokenKind() == tok::kw_true;
25+
SourceLoc LiteralLoc = advanceLocBegin(Loc, Literal);
26+
return new (Context) BooleanLiteralExpr(Value, LiteralLoc);
27+
}
28+
29+
Expr *ASTGen::generate(const FloatLiteralExprSyntax &Expr, const SourceLoc &Loc) {
30+
TokenSyntax Digits = Expr.getFloatingDigits();
31+
StringRef Text = copyAndStripUnderscores(Digits.getText());
32+
auto DigitsLoc = advanceLocBegin(Loc, Digits);
33+
return new (Context) FloatLiteralExpr(Text, DigitsLoc);
34+
}
35+
2036
Expr *ASTGen::generate(const IntegerLiteralExprSyntax &Expr, const SourceLoc &Loc) {
2137
TokenSyntax Digits = Expr.getDigits();
2238
StringRef Text = copyAndStripUnderscores(Digits.getText());
2339
auto DigitsLoc = advanceLocBegin(Loc, Digits);
2440
return new (Context) IntegerLiteralExpr(Text, DigitsLoc);
2541
}
2642

43+
Expr *ASTGen::generate(const NilLiteralExprSyntax &Expr, const SourceLoc &Loc) {
44+
TokenSyntax Nil = Expr.getNilKeyword();
45+
SourceLoc NilLoc = advanceLocBegin(Loc, Nil);
46+
return new (Context) NilLiteralExpr(NilLoc);
47+
}
48+
49+
Expr *ASTGen::generate(const PoundColumnExprSyntax &Expr, const SourceLoc &Loc) {
50+
return generateMagicIdentifierLiteralExpr(Expr.getPoundColumn(), Loc);
51+
}
52+
53+
Expr *ASTGen::generate(const PoundDsohandleExprSyntax &Expr, const SourceLoc &Loc) {
54+
return generateMagicIdentifierLiteralExpr(Expr.getPoundDsohandle(), Loc);
55+
}
56+
57+
Expr *ASTGen::generate(const PoundFileExprSyntax &Expr, const SourceLoc &Loc) {
58+
return generateMagicIdentifierLiteralExpr(Expr.getPoundFile(), Loc);
59+
}
60+
61+
Expr *ASTGen::generate(const PoundFileIDExprSyntax &Expr, const SourceLoc &Loc) {
62+
return generateMagicIdentifierLiteralExpr(Expr.getPoundFileID(), Loc);
63+
}
64+
65+
Expr *ASTGen::generate(const PoundFilePathExprSyntax &Expr, const SourceLoc &Loc) {
66+
return generateMagicIdentifierLiteralExpr(Expr.getPoundFilePath(), Loc);
67+
}
68+
69+
Expr *ASTGen::generate(const PoundFunctionExprSyntax &Expr, const SourceLoc &Loc) {
70+
return generateMagicIdentifierLiteralExpr(Expr.getPoundFunction(), Loc);
71+
}
72+
73+
Expr *ASTGen::generate(const PoundLineExprSyntax &Expr, const SourceLoc &Loc) {
74+
return generateMagicIdentifierLiteralExpr(Expr.getPoundLine(), Loc);
75+
}
76+
77+
Expr *ASTGen::generate(const UnknownExprSyntax &Expr, const SourceLoc &Loc) {
78+
if (Expr.getNumChildren() == 1 && Expr.getChild(0)->isToken()) {
79+
Syntax Token = *Expr.getChild(0);
80+
tok Kind = Token.getRaw()->getTokenKind();
81+
switch (Kind) {
82+
case tok::kw___FILE__:
83+
case tok::kw___LINE__:
84+
case tok::kw___COLUMN__:
85+
case tok::kw___FUNCTION__:
86+
case tok::kw___DSO_HANDLE__: {
87+
auto MagicKind = getMagicIdentifierLiteralKind(Kind);
88+
SourceLoc TokenLoc = advanceLocBegin(Loc, Token);
89+
return new (Context) MagicIdentifierLiteralExpr(MagicKind, TokenLoc);
90+
}
91+
default:
92+
return nullptr;
93+
}
94+
}
95+
return nullptr;
96+
}
97+
2798
//===----------------------------------------------------------------------===//
2899
// MARK: - Private
29100

lib/Parse/ParseExpr.cpp

Lines changed: 143 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,18 +1037,6 @@ getMagicIdentifierLiteralKind(tok Kind, const LangOptions &Opts) {
10371037
}
10381038
}
10391039

1040-
/// Map magic literal kinds such as #file to their SyntaxKind.
1041-
static SyntaxKind
1042-
getMagicIdentifierSyntaxKind(MagicIdentifierLiteralExpr::Kind LiteralKind) {
1043-
switch (LiteralKind) {
1044-
#define MAGIC_IDENTIFIER(NAME, STRING, SYNTAX_KIND) \
1045-
case MagicIdentifierLiteralExpr::NAME: \
1046-
return SyntaxKind::SYNTAX_KIND;
1047-
#include "swift/AST/MagicIdentifierKinds.def"
1048-
}
1049-
llvm_unreachable("not a magic literal kind");
1050-
}
1051-
10521040
ParserResult<Expr>
10531041
Parser::parseExprPostfixSuffix(ParserResult<Expr> Result, bool isExprBasic,
10541042
bool periodHasKeyPathBehavior,
@@ -1413,28 +1401,45 @@ ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) {
14131401
switch (Tok.getKind()) {
14141402
case tok::integer_literal:
14151403
return parseExprAST<IntegerLiteralExprSyntax>();
1404+
case tok::floating_literal:
1405+
return parseExprAST<FloatLiteralExprSyntax>();
1406+
case tok::kw_nil:
1407+
return parseExprAST<NilLiteralExprSyntax>();
1408+
case tok::kw_true:
1409+
case tok::kw_false:
1410+
return parseExprAST<BooleanLiteralExprSyntax>();
1411+
// Cases for magic identifier tokens
1412+
case tok::pound_file:
1413+
#define MAGIC_IDENTIFIER_TOKEN(NAME, TOKEN) case tok::TOKEN:
1414+
#include "swift/AST/MagicIdentifierKinds.def"
1415+
{
1416+
auto Kind = getMagicIdentifierLiteralKind(Tok.getKind(), Context.LangOpts);
1417+
switch (Kind) {
1418+
case MagicIdentifierLiteralExpr::FileID:
1419+
return parseExprAST<PoundFileIDExprSyntax>();
1420+
case MagicIdentifierLiteralExpr::FilePath:
1421+
return parseExprAST<PoundFilePathExprSyntax>();
1422+
case MagicIdentifierLiteralExpr::FileIDSpelledAsFile:
1423+
return parseExprAST<PoundFileExprSyntax>();
1424+
case MagicIdentifierLiteralExpr::FilePathSpelledAsFile:
1425+
return parseExprAST<PoundFileExprSyntax>();
1426+
case MagicIdentifierLiteralExpr::Function:
1427+
return parseExprAST<PoundFunctionExprSyntax>();
1428+
case MagicIdentifierLiteralExpr::Line:
1429+
return parseExprAST<PoundLineExprSyntax>();
1430+
case MagicIdentifierLiteralExpr::Column:
1431+
return parseExprAST<PoundColumnExprSyntax>();
1432+
case MagicIdentifierLiteralExpr::DSOHandle:
1433+
return parseExprAST<PoundDsohandleExprSyntax>();
1434+
}
1435+
}
14161436
default:
14171437
break;
14181438
}
14191439

14201440
// Direct parsing of tokens to an AST
14211441
SyntaxParsingContext ExprContext(SyntaxContext, SyntaxContextKind::Expr);
14221442
switch (Tok.getKind()) {
1423-
case tok::integer_literal: {
1424-
StringRef Text = copyAndStripUnderscores(Tok.getText());
1425-
SourceLoc Loc = consumeToken(tok::integer_literal);
1426-
ExprContext.setCreateSyntax(SyntaxKind::IntegerLiteralExpr);
1427-
return makeParserResult(new (Context)
1428-
IntegerLiteralExpr(Text, Loc,
1429-
/*Implicit=*/false));
1430-
}
1431-
case tok::floating_literal: {
1432-
StringRef Text = copyAndStripUnderscores(Tok.getText());
1433-
SourceLoc Loc = consumeToken(tok::floating_literal);
1434-
ExprContext.setCreateSyntax(SyntaxKind::FloatLiteralExpr);
1435-
return makeParserResult(new (Context) FloatLiteralExpr(Text, Loc,
1436-
/*Implicit=*/false));
1437-
}
14381443
case tok::at_sign:
14391444
// Objective-C programmers habitually type @"foo", so recover gracefully
14401445
// with a fixit. If this isn't @"foo", just handle it like an unknown
@@ -1449,49 +1454,7 @@ ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) {
14491454

14501455
case tok::string_literal: // "foo"
14511456
return parseExprStringLiteral();
1452-
1453-
case tok::kw_nil:
1454-
ExprContext.setCreateSyntax(SyntaxKind::NilLiteralExpr);
1455-
return makeParserResult(new (Context)
1456-
NilLiteralExpr(consumeToken(tok::kw_nil)));
14571457

1458-
case tok::kw_true:
1459-
case tok::kw_false: {
1460-
ExprContext.setCreateSyntax(SyntaxKind::BooleanLiteralExpr);
1461-
bool isTrue = Tok.is(tok::kw_true);
1462-
return makeParserResult(new (Context)
1463-
BooleanLiteralExpr(isTrue, consumeToken()));
1464-
}
1465-
1466-
// Cases for deprecated magic identifier tokens
1467-
#define MAGIC_IDENTIFIER_DEPRECATED_TOKEN(NAME, TOKEN) case tok::TOKEN:
1468-
#include "swift/AST/MagicIdentifierKinds.def"
1469-
{
1470-
auto Kind = getMagicIdentifierLiteralKind(Tok.getKind(), Context.LangOpts);
1471-
auto replacement = MagicIdentifierLiteralExpr::getKindString(Kind);
1472-
1473-
diagnose(Tok.getLoc(), diag::snake_case_deprecated,
1474-
Tok.getText(), replacement)
1475-
.fixItReplace(Tok.getLoc(), replacement);
1476-
LLVM_FALLTHROUGH;
1477-
}
1478-
1479-
// Cases for non-deprecated magic identifier tokens
1480-
case tok::pound_file:
1481-
#define MAGIC_IDENTIFIER_DEPRECATED_TOKEN(NAME, TOKEN)
1482-
#define MAGIC_IDENTIFIER_TOKEN(NAME, TOKEN) case tok::TOKEN:
1483-
#include "swift/AST/MagicIdentifierKinds.def"
1484-
{
1485-
auto Kind = getMagicIdentifierLiteralKind(Tok.getKind(), Context.LangOpts);
1486-
SyntaxKind SKind = getMagicIdentifierSyntaxKind(Kind);
1487-
1488-
ExprContext.setCreateSyntax(SKind);
1489-
SourceLoc Loc = consumeToken();
1490-
1491-
return makeParserResult(new (Context) MagicIdentifierLiteralExpr(
1492-
Kind, Loc, /*implicit=*/false));
1493-
}
1494-
14951458
case tok::identifier: // foo
14961459
case tok::kw_self: // self
14971460

@@ -3731,9 +3694,120 @@ template <typename SyntaxNode> ParserResult<Expr> Parser::parseExprAST() {
37313694
return makeParserResult(ExprAST);
37323695
}
37333696

3697+
template <>
3698+
ParsedExprSyntax Parser::parseExprSyntax<BooleanLiteralExprSyntax>() {
3699+
auto Token = consumeTokenSyntax();
3700+
return ParsedSyntaxRecorder::makeBooleanLiteralExpr(std::move(Token),
3701+
*SyntaxContext);
3702+
}
3703+
3704+
template <> ParsedExprSyntax Parser::parseExprSyntax<FloatLiteralExprSyntax>() {
3705+
auto Token = consumeTokenSyntax(tok::floating_literal);
3706+
return ParsedSyntaxRecorder::makeFloatLiteralExpr(std::move(Token),
3707+
*SyntaxContext);
3708+
}
3709+
37343710
template <>
37353711
ParsedExprSyntax Parser::parseExprSyntax<IntegerLiteralExprSyntax>() {
37363712
auto Token = consumeTokenSyntax(tok::integer_literal);
37373713
return ParsedSyntaxRecorder::makeIntegerLiteralExpr(std::move(Token),
37383714
*SyntaxContext);
37393715
}
3716+
3717+
template <> ParsedExprSyntax Parser::parseExprSyntax<NilLiteralExprSyntax>() {
3718+
auto Token = consumeTokenSyntax(tok::kw_nil);
3719+
return ParsedSyntaxRecorder::makeNilLiteralExpr(std::move(Token),
3720+
*SyntaxContext);
3721+
}
3722+
3723+
template <> ParsedExprSyntax Parser::parseExprSyntax<PoundColumnExprSyntax>() {
3724+
if (Tok.getKind() == tok::kw___COLUMN__) {
3725+
StringRef fixit = "#column";
3726+
diagnose(Tok.getLoc(), diag::snake_case_deprecated, Tok.getText(), fixit)
3727+
.fixItReplace(Tok.getLoc(), fixit);
3728+
3729+
auto Token = consumeTokenSyntax(tok::kw___COLUMN__);
3730+
return ParsedSyntaxRecorder::makeUnknownExpr({Token}, *SyntaxContext);
3731+
}
3732+
3733+
auto Token = consumeTokenSyntax(tok::pound_column);
3734+
return ParsedSyntaxRecorder::makePoundColumnExpr(std::move(Token),
3735+
*SyntaxContext);
3736+
}
3737+
3738+
template <>
3739+
ParsedExprSyntax Parser::parseExprSyntax<PoundDsohandleExprSyntax>() {
3740+
if (Tok.getKind() == tok::kw___DSO_HANDLE__) {
3741+
StringRef fixit = "#dsohandle";
3742+
diagnose(Tok.getLoc(), diag::snake_case_deprecated, Tok.getText(), fixit)
3743+
.fixItReplace(Tok.getLoc(), fixit);
3744+
3745+
auto Token =
3746+
consumeTokenSyntax(tok::kw___DSO_HANDLE__);
3747+
return ParsedSyntaxRecorder::makeUnknownExpr({Token}, *SyntaxContext);
3748+
}
3749+
3750+
auto Token = consumeTokenSyntax(tok::pound_dsohandle);
3751+
return ParsedSyntaxRecorder::makePoundDsohandleExpr(std::move(Token),
3752+
*SyntaxContext);
3753+
}
3754+
3755+
template <> ParsedExprSyntax Parser::parseExprSyntax<PoundFileExprSyntax>() {
3756+
if (Tok.getKind() == tok::kw___FILE__) {
3757+
StringRef fixit = "#file";
3758+
diagnose(Tok.getLoc(), diag::snake_case_deprecated, Tok.getText(), fixit)
3759+
.fixItReplace(Tok.getLoc(), fixit);
3760+
3761+
auto Token = consumeTokenSyntax(tok::kw___FILE__);
3762+
return ParsedSyntaxRecorder::makeUnknownExpr({Token}, *SyntaxContext);
3763+
}
3764+
3765+
auto Token = consumeTokenSyntax(tok::pound_file);
3766+
return ParsedSyntaxRecorder::makePoundFileExpr(std::move(Token),
3767+
*SyntaxContext);
3768+
}
3769+
3770+
template <> ParsedExprSyntax Parser::parseExprSyntax<PoundFileIDExprSyntax>() {
3771+
auto Token = consumeTokenSyntax(tok::pound_fileID);
3772+
return ParsedSyntaxRecorder::makePoundFileIDExpr(std::move(Token),
3773+
*SyntaxContext);
3774+
}
3775+
3776+
template <>
3777+
ParsedExprSyntax Parser::parseExprSyntax<PoundFilePathExprSyntax>() {
3778+
auto Token = consumeTokenSyntax(tok::pound_filePath);
3779+
return ParsedSyntaxRecorder::makePoundFilePathExpr(std::move(Token),
3780+
*SyntaxContext);
3781+
}
3782+
3783+
template <> ParsedExprSyntax Parser::parseExprSyntax<PoundLineExprSyntax>() {
3784+
if (Tok.getKind() == tok::kw___LINE__) {
3785+
StringRef fixit = "#line";
3786+
diagnose(Tok.getLoc(), diag::snake_case_deprecated, Tok.getText(), fixit)
3787+
.fixItReplace(Tok.getLoc(), fixit);
3788+
3789+
auto Token = consumeTokenSyntax(tok::kw___LINE__);
3790+
return ParsedSyntaxRecorder::makeUnknownExpr({Token}, *SyntaxContext);
3791+
}
3792+
3793+
// FIXME: #line was renamed to #sourceLocation
3794+
auto Token = consumeTokenSyntax(tok::pound_line);
3795+
return ParsedSyntaxRecorder::makePoundLineExpr(std::move(Token),
3796+
*SyntaxContext);
3797+
}
3798+
3799+
template <>
3800+
ParsedExprSyntax Parser::parseExprSyntax<PoundFunctionExprSyntax>() {
3801+
if (Tok.getKind() == tok::kw___FUNCTION__) {
3802+
StringRef fixit = "#function";
3803+
diagnose(Tok.getLoc(), diag::snake_case_deprecated, Tok.getText(), fixit)
3804+
.fixItReplace(Tok.getLoc(), fixit);
3805+
3806+
auto Token = consumeTokenSyntax(tok::kw___FUNCTION__);
3807+
return ParsedSyntaxRecorder::makeUnknownExpr({Token}, *SyntaxContext);
3808+
}
3809+
3810+
auto Token = consumeTokenSyntax(tok::pound_function);
3811+
return ParsedSyntaxRecorder::makePoundFunctionExpr(std::move(Token),
3812+
*SyntaxContext);
3813+
}

0 commit comments

Comments
 (0)