Skip to content

Commit 908f194

Browse files
authored
Merge pull request #7582 from bitjammer/sr-3989-syntax-fallthrough-stmt
[Syntax] Implement fallthrough-statement
2 parents c5bd8ab + 0d8a82d commit 908f194

File tree

5 files changed

+131
-9
lines changed

5 files changed

+131
-9
lines changed

include/swift/Syntax/StmtSyntax.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class StmtSyntaxData : public SyntaxData {
4848
/// | compiler-control-statement ';'?
4949
class StmtSyntax : public Syntax {
5050
protected:
51-
StmtSyntax(RC<SyntaxData> Root, StmtSyntaxData *Data);
51+
StmtSyntax(const RC<SyntaxData> Root, const StmtSyntaxData *Data);
5252
public:
5353
static bool classof(const Syntax *S) {
5454
return S->isStmt();
@@ -189,7 +189,7 @@ class FallthroughStmtSyntaxData final : public StmtSyntaxData {
189189

190190
public:
191191
static bool classof(const SyntaxData *SD) {
192-
return SD->getKind() == SyntaxKind::StmtList;
192+
return SD->getKind() == SyntaxKind::FallthroughStmt;
193193
}
194194
};
195195

@@ -198,20 +198,34 @@ class FallthroughStmtSyntaxData final : public StmtSyntaxData {
198198

199199
class FallthroughStmtSyntax : public StmtSyntax {
200200
friend struct SyntaxFactory;
201+
friend class SyntaxData;
202+
friend class FallthroughStmtSyntaxData;
203+
204+
using DataType = FallthroughStmtSyntaxData;
201205

202206
enum class Cursor : CursorIndex {
203207
FallthroughKeyword,
204208
};
205209

206210
FallthroughStmtSyntax(const RC<SyntaxData> Root,
207-
FallthroughStmtSyntaxData *Data);
211+
const FallthroughStmtSyntaxData *Data);
208212

209213
static FallthroughStmtSyntax make(RC<RawSyntax> Raw,
210214
const SyntaxData *Parent = nullptr,
211215
CursorIndex IndexInParent = 0);
212216
static FallthroughStmtSyntax makeBlank();
213217

214218
public:
219+
220+
/// Get the 'fallthrough' keyword associated comprising this
221+
/// fallthrough statement.
222+
RC<TokenSyntax> getFallthroughKeyword() const;
223+
224+
/// Return a new FallthroughtStmtSyntax with the given fallthrough
225+
/// keyword.
226+
FallthroughStmtSyntax
227+
withFallthroughKeyword(RC<TokenSyntax> NewFallthroughKeyword) const;
228+
215229
static bool classof(const Syntax *S) {
216230
return S->getKind() == SyntaxKind::FallthroughStmt;
217231
}

include/swift/Syntax/SyntaxFactory.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ struct SyntaxFactory {
108108

109109
#pragma mark - Tokens
110110

111+
/// Make a 'fallthrough' keyword with the specified leading and
112+
/// trailing trivia.
113+
static RC<TokenSyntax> makeFallthroughKeyword(const Trivia &LeadingTrivia,
114+
const Trivia &TrailingTrivia);
115+
111116
/// Make an at-sign '@' token with the specified leading and
112117
/// trailing trivia.
113118
static RC<TokenSyntax> makeAtSignToken(const Trivia &LeadingTrivia,

lib/Syntax/StmtSyntax.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,21 @@
1616
using namespace swift;
1717
using namespace swift::syntax;
1818

19-
StmtSyntax::StmtSyntax(RC<SyntaxData> Root, StmtSyntaxData *Data)
19+
StmtSyntax::StmtSyntax(const RC<SyntaxData> Root, const StmtSyntaxData *Data)
2020
: Syntax(Root, Data) {}
2121

2222
#pragma mark fallthrough-statement Data
2323

2424
FallthroughStmtSyntaxData::FallthroughStmtSyntaxData(RC<RawSyntax> Raw,
2525
const SyntaxData *Parent,
2626
CursorIndex IndexInParent)
27-
: StmtSyntaxData(Raw, Parent, IndexInParent) {}
27+
: StmtSyntaxData(Raw, Parent, IndexInParent) {
28+
assert(Raw->Kind == SyntaxKind::FallthroughStmt);
29+
assert(Raw->Layout.size() == 1);
30+
syntax_assert_child_token_text(Raw,
31+
FallthroughStmtSyntax::Cursor::FallthroughKeyword,
32+
tok::kw_fallthrough, "fallthrough");
33+
}
2834

2935
RC<FallthroughStmtSyntaxData>
3036
FallthroughStmtSyntaxData::make(RC<RawSyntax> Raw,
@@ -45,8 +51,9 @@ RC<FallthroughStmtSyntaxData> FallthroughStmtSyntaxData::makeBlank() {
4551

4652
#pragma mark fallthrough-statement API
4753

48-
FallthroughStmtSyntax::FallthroughStmtSyntax(const RC<SyntaxData> Root,
49-
FallthroughStmtSyntaxData *Data)
54+
FallthroughStmtSyntax::
55+
FallthroughStmtSyntax(const RC<SyntaxData> Root,
56+
const FallthroughStmtSyntaxData *Data)
5057
: StmtSyntax(Root, Data) {}
5158

5259
FallthroughStmtSyntax
@@ -62,6 +69,19 @@ FallthroughStmtSyntax::make(RC<RawSyntax> Raw, const SyntaxData *Parent,
6269
};
6370
}
6471

72+
RC<TokenSyntax> FallthroughStmtSyntax::getFallthroughKeyword() const {
73+
return cast<TokenSyntax>(getRaw()->getChild(Cursor::FallthroughKeyword));
74+
}
75+
76+
FallthroughStmtSyntax FallthroughStmtSyntax::
77+
withFallthroughKeyword(RC<TokenSyntax> NewFallthroughKeyword) const {
78+
syntax_assert_token_is(NewFallthroughKeyword, tok::kw_fallthrough,
79+
"fallthrough");
80+
return Data->replaceChild<FallthroughStmtSyntax>(NewFallthroughKeyword,
81+
Cursor::FallthroughKeyword);
82+
}
83+
84+
6585
CodeBlockStmtSyntaxData::CodeBlockStmtSyntaxData(RC<RawSyntax> Raw)
6686
: StmtSyntaxData(Raw) {
6787
assert(Raw->Kind == SyntaxKind::CodeBlockStmt);

lib/Syntax/SyntaxFactory.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,16 @@ FallthroughStmtSyntax SyntaxFactory::makeBlankFallthroughStmt() {
250250
#pragma mark - Tokens
251251

252252
RC<TokenSyntax>
253-
SyntaxFactory::makeAtSignToken(const swift::syntax::Trivia &LeadingTrivia,
254-
const swift::syntax::Trivia &TrailingTrivia) {
253+
SyntaxFactory::makeFallthroughKeyword(const Trivia &LeadingTrivia,
254+
const Trivia &TrailingTrivia) {
255+
return TokenSyntax::make(tok::kw_fallthrough, "fallthrough",
256+
SourcePresence::Present,
257+
LeadingTrivia, TrailingTrivia);
258+
}
259+
260+
RC<TokenSyntax>
261+
SyntaxFactory::makeAtSignToken(const Trivia &LeadingTrivia,
262+
const Trivia &TrailingTrivia) {
255263
return TokenSyntax::make(tok::at_sign, "@", SourcePresence::Present,
256264
LeadingTrivia, TrailingTrivia);
257265
}

unittests/Syntax/StmtSyntaxTests.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#include "swift/Syntax/SyntaxFactory.h"
2+
#include "swift/Syntax/StmtSyntax.h"
3+
#include "llvm/ADT/SmallString.h"
4+
#include "gtest/gtest.h"
5+
6+
using namespace swift;
7+
using namespace swift::syntax;
8+
9+
#pragma mark - fallthrough-statement
10+
11+
TEST(StmtSyntaxTests, FallthroughStmtGetAPIs) {
12+
llvm::SmallString<48> Scratch;
13+
llvm::raw_svector_ostream OS(Scratch);
14+
15+
auto FallthroughKW = SyntaxFactory::makeFallthroughKeyword({}, {});
16+
17+
auto Fallthrough = SyntaxFactory::makeBlankFallthroughStmt()
18+
.withFallthroughKeyword(FallthroughKW);
19+
20+
/// This should be directly shared through reference-counting.
21+
ASSERT_EQ(FallthroughKW, Fallthrough.getFallthroughKeyword());
22+
}
23+
24+
TEST(StmtSyntaxTests, FallthroughStmtWithAPIs) {
25+
llvm::SmallString<48> Scratch;
26+
llvm::raw_svector_ostream OS(Scratch);
27+
28+
auto FallthroughKW = SyntaxFactory::makeFallthroughKeyword({}, {});
29+
30+
SyntaxFactory::makeBlankFallthroughStmt()
31+
.withFallthroughKeyword(FallthroughKW)
32+
.print(OS);
33+
34+
ASSERT_EQ(OS.str().str(), "fallthrough");
35+
}
36+
37+
TEST(StmtSyntaxTests, FallthroughStmtMakeAPIs) {
38+
auto FallthroughKW = SyntaxFactory::makeFallthroughKeyword({}, {});
39+
40+
{
41+
llvm::SmallString<48> Scratch;
42+
llvm::raw_svector_ostream OS(Scratch);
43+
44+
SyntaxFactory::makeFallthroughStmt(FallthroughKW).print(OS);
45+
ASSERT_EQ(OS.str().str(), "fallthrough");
46+
}
47+
48+
{
49+
llvm::SmallString<48> Scratch;
50+
llvm::raw_svector_ostream OS(Scratch);
51+
52+
FallthroughKW = FallthroughKW->withLeadingTrivia(Trivia::spaces(2));
53+
54+
SyntaxFactory::makeFallthroughStmt(FallthroughKW).print(OS);
55+
ASSERT_EQ(OS.str().str(), " fallthrough");
56+
}
57+
58+
{
59+
llvm::SmallString<48> Scratch;
60+
llvm::raw_svector_ostream OS(Scratch);
61+
62+
FallthroughKW = FallthroughKW->withTrailingTrivia(Trivia::spaces(2));
63+
64+
SyntaxFactory::makeFallthroughStmt(FallthroughKW).print(OS);
65+
ASSERT_EQ(OS.str().str(), " fallthrough ");
66+
}
67+
68+
{
69+
llvm::SmallString<1> Scratch;
70+
llvm::raw_svector_ostream OS(Scratch);
71+
72+
SyntaxFactory::makeBlankFallthroughStmt().print(OS);
73+
ASSERT_EQ(OS.str().str(), "");
74+
}
75+
}

0 commit comments

Comments
 (0)