Skip to content

Commit 8a69f88

Browse files
authored
Merge pull request #27955 from AnthonyLatsis/bracestmt_cleanup
NFC: Solidify and tidy up the BraceStmt interface
2 parents a259eb5 + 6325915 commit 8a69f88

17 files changed

+47
-46
lines changed

include/swift/AST/Stmt.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,13 @@ class BraceStmt final : public Stmt,
173173

174174
SourceRange getSourceRange() const { return SourceRange(LBLoc, RBLoc); }
175175

176+
bool empty() const { return getNumElements() == 0; }
176177
unsigned getNumElements() const { return Bits.BraceStmt.NumElements; }
177178

178-
ASTNode getElement(unsigned i) const { return getElements()[i]; }
179-
void setElement(unsigned i, ASTNode node) { getElements()[i] = node; }
179+
ASTNode getFirstElement() const { return getElements().front(); }
180+
ASTNode getLastElement() const { return getElements().back(); }
181+
182+
void setFirstElement(ASTNode node) { getElements().front() = node; }
180183

181184
/// The elements contained within the BraceStmt.
182185
MutableArrayRef<ASTNode> getElements() {

lib/AST/ASTScopeCreation.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -640,8 +640,7 @@ class ScopeCreator final {
640640
// Can occur in illegal code
641641
if (auto *const s = n.dyn_cast<Stmt *>()) {
642642
if (auto *const bs = dyn_cast<BraceStmt>(s))
643-
ASTScopeAssert(bs->getNumElements() == 0,
644-
"Might mess up insertion point");
643+
ASTScopeAssert(bs->empty(), "Might mess up insertion point");
645644
}
646645
return !n.isDecl(DeclKind::Var);
647646
}

lib/AST/Decl.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ Expr *AbstractFunctionDecl::getSingleExpressionBody() const {
609609
assert(hasSingleExpressionBody() && "Not a single-expression body");
610610
auto braceStmt = getBody();
611611
assert(braceStmt != nullptr && "No body currently available.");
612-
auto body = getBody()->getElement(0);
612+
auto body = getBody()->getFirstElement();
613613
if (auto *stmt = body.dyn_cast<Stmt *>()) {
614614
if (auto *returnStmt = dyn_cast<ReturnStmt>(stmt)) {
615615
return returnStmt->getResult();
@@ -626,7 +626,7 @@ Expr *AbstractFunctionDecl::getSingleExpressionBody() const {
626626

627627
void AbstractFunctionDecl::setSingleExpressionBody(Expr *NewBody) {
628628
assert(hasSingleExpressionBody() && "Not a single-expression body");
629-
auto body = getBody()->getElement(0);
629+
auto body = getBody()->getFirstElement();
630630
if (auto *stmt = body.dyn_cast<Stmt *>()) {
631631
if (auto *returnStmt = dyn_cast<ReturnStmt>(stmt)) {
632632
returnStmt->setResult(NewBody);
@@ -642,7 +642,7 @@ void AbstractFunctionDecl::setSingleExpressionBody(Expr *NewBody) {
642642
return;
643643
}
644644
}
645-
getBody()->setElement(0, NewBody);
645+
getBody()->setFirstElement(NewBody);
646646
}
647647

648648
bool AbstractStorageDecl::isTransparent() const {

lib/AST/Expr.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1854,24 +1854,24 @@ FORWARD_SOURCE_LOCS_TO(ClosureExpr, Body.getPointer())
18541854

18551855
Expr *ClosureExpr::getSingleExpressionBody() const {
18561856
assert(hasSingleExpressionBody() && "Not a single-expression body");
1857-
auto body = getBody()->getElement(0);
1857+
auto body = getBody()->getFirstElement();
18581858
if (body.is<Stmt *>())
18591859
return cast<ReturnStmt>(body.get<Stmt *>())->getResult();
18601860
return body.get<Expr *>();
18611861
}
18621862

18631863
void ClosureExpr::setSingleExpressionBody(Expr *NewBody) {
18641864
assert(hasSingleExpressionBody() && "Not a single-expression body");
1865-
auto body = getBody()->getElement(0);
1865+
auto body = getBody()->getFirstElement();
18661866
if (body.is<Stmt *>()) {
18671867
cast<ReturnStmt>(body.get<Stmt *>())->setResult(NewBody);
18681868
return;
18691869
}
1870-
getBody()->setElement(0, NewBody);
1870+
getBody()->setFirstElement(NewBody);
18711871
}
18721872

18731873
bool ClosureExpr::hasEmptyBody() const {
1874-
return getBody()->getNumElements() == 0;
1874+
return getBody()->empty();
18751875
}
18761876

18771877
FORWARD_SOURCE_LOCS_TO(AutoClosureExpr, Body)
@@ -1883,7 +1883,7 @@ void AutoClosureExpr::setBody(Expr *E) {
18831883
}
18841884

18851885
Expr *AutoClosureExpr::getSingleExpressionBody() const {
1886-
return cast<ReturnStmt>(Body->getElement(0).get<Stmt *>())->getResult();
1886+
return cast<ReturnStmt>(Body->getFirstElement().get<Stmt *>())->getResult();
18871887
}
18881888

18891889
FORWARD_SOURCE_LOCS_TO(UnresolvedPatternExpr, subPattern)
@@ -2222,14 +2222,14 @@ TapExpr::TapExpr(Expr * SubExpr, BraceStmt *Body)
22222222
: Expr(ExprKind::Tap, /*Implicit=*/true),
22232223
SubExpr(SubExpr), Body(Body) {
22242224
if (Body) {
2225-
assert(Body->getNumElements() > 0 &&
2226-
Body->getElement(0).isDecl(DeclKind::Var) &&
2225+
assert(!Body->empty() &&
2226+
Body->getFirstElement().isDecl(DeclKind::Var) &&
22272227
"First element of Body should be a variable to init with the subExpr");
22282228
}
22292229
}
22302230

22312231
VarDecl * TapExpr::getVar() const {
2232-
return dyn_cast<VarDecl>(Body->getElement(0).dyn_cast<Decl *>());
2232+
return dyn_cast<VarDecl>(Body->getFirstElement().dyn_cast<Decl *>());
22332233
}
22342234

22352235
SourceLoc TapExpr::getEndLoc() const {

lib/IDE/ExprContextAnalysis.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,7 @@ class ExprContextAnalyzer {
756756
/// in order to avoid a base expression affecting the type. However, now that
757757
/// we've typechecked, we will take the context type into account.
758758
static bool isSingleExpressionBodyForCodeCompletion(BraceStmt *body) {
759-
return body->getNumElements() == 1 && body->getElements()[0].is<Expr *>();
759+
return body->getNumElements() == 1 && body->getFirstElement().is<Expr *>();
760760
}
761761

762762
public:

lib/IDE/IDERequests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ struct RangeResolver::Implementation {
486486
// Unbox the brace statement to find its type.
487487
if (auto BS = dyn_cast<BraceStmt>(N.get<Stmt*>())) {
488488
if (!BS->getElements().empty()) {
489-
return resolveNodeType(BS->getElements().back(),
489+
return resolveNodeType(BS->getLastElement(),
490490
RangeKind::SingleStatement);
491491
}
492492
}

lib/IDE/Refactoring.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,7 +1692,7 @@ findCollapseNestedIfTarget(ResolvedCursorInfo CursorInfo) {
16921692
return {};
16931693

16941694
IfStmt *InnerIf =
1695-
dyn_cast_or_null<IfStmt>(Body->getElement(0).dyn_cast<Stmt *>());
1695+
dyn_cast_or_null<IfStmt>(Body->getFirstElement().dyn_cast<Stmt *>());
16961696
if (!InnerIf)
16971697
return {};
16981698

@@ -2119,8 +2119,8 @@ bool RefactoringActionConvertIfLetExprToGuardExpr::performChange() {
21192119
auto Body = dyn_cast_or_null<BraceStmt>(If->getThenStmt());
21202120

21212121
// Get if-let then body.
2122-
auto firstElement = Body->getElements()[0];
2123-
auto lastElement = Body->getElements().back();
2122+
auto firstElement = Body->getFirstElement();
2123+
auto lastElement = Body->getLastElement();
21242124
SourceRange bodyRange = firstElement.getSourceRange();
21252125
bodyRange.widen(lastElement.getSourceRange());
21262126
auto BodyCharRange = Lexer::getCharSourceRangeFromSourceRange(SM, bodyRange);
@@ -2138,8 +2138,8 @@ bool RefactoringActionConvertIfLetExprToGuardExpr::performChange() {
21382138

21392139
// Get if-let else body.
21402140
if (auto *ElseBody = dyn_cast_or_null<BraceStmt>(If->getElseStmt())) {
2141-
auto firstElseElement = ElseBody->getElements()[0];
2142-
auto lastElseElement = ElseBody->getElements().back();
2141+
auto firstElseElement = ElseBody->getFirstElement();
2142+
auto lastElseElement = ElseBody->getLastElement();
21432143
SourceRange elseBodyRange = firstElseElement.getSourceRange();
21442144
elseBodyRange.widen(lastElseElement.getSourceRange());
21452145
auto ElseBodyCharRange = Lexer::getCharSourceRangeFromSourceRange(SM, elseBodyRange);
@@ -2225,9 +2225,9 @@ bool RefactoringActionConvertGuardExprToIfLetExpr::performChange() {
22252225
// Get guard body
22262226
auto Body = dyn_cast_or_null<BraceStmt>(Guard->getBody());
22272227

2228-
if (Body && Body->getElements().size() > 1) {
2229-
auto firstElement = Body->getElements()[0];
2230-
auto lastElement = Body->getElements().back();
2228+
if (Body && Body->getNumElements() > 1) {
2229+
auto firstElement = Body->getFirstElement();
2230+
auto lastElement = Body->getLastElement();
22312231
SourceRange bodyRange = firstElement.getSourceRange();
22322232
bodyRange.widen(lastElement.getSourceRange());
22332233
auto BodyCharRange = Lexer::getCharSourceRangeFromSourceRange(SM, bodyRange);

lib/IRGen/GenClass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1466,7 +1466,7 @@ namespace {
14661466
// If we have the destructor body, we know whether SILGen
14671467
// generated a -dealloc body.
14681468
if (auto braceStmt = destructor->getBody())
1469-
return braceStmt->getNumElements() != 0;
1469+
return !braceStmt->empty();
14701470

14711471
// We don't have a destructor body, so hunt for the SIL function
14721472
// for it.

lib/Parse/ParseDecl.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5580,7 +5580,7 @@ void Parser::parseAbstractFunctionBody(AbstractFunctionDecl *AFD) {
55805580
// may be incomplete and the type mismatch in return statement will just
55815581
// confuse the type checker.
55825582
if (!Body.hasCodeCompletion() && BS->getNumElements() == 1) {
5583-
auto Element = BS->getElement(0);
5583+
auto Element = BS->getFirstElement();
55845584
if (auto *stmt = Element.dyn_cast<Stmt *>()) {
55855585
if (isa<FuncDecl>(AFD)) {
55865586
if (auto *returnStmt = dyn_cast<ReturnStmt>(stmt)) {
@@ -5605,15 +5605,15 @@ void Parser::parseAbstractFunctionBody(AbstractFunctionDecl *AFD) {
56055605
}
56065606
if (auto F = dyn_cast<FuncDecl>(AFD)) {
56075607
auto RS = new (Context) ReturnStmt(SourceLoc(), E);
5608-
BS->setElement(0, RS);
5608+
BS->setFirstElement(RS);
56095609
AFD->setHasSingleExpressionBody();
56105610
AFD->setSingleExpressionBody(E);
56115611
} else if (auto *F = dyn_cast<ConstructorDecl>(AFD)) {
56125612
if (F->isFailable() && isa<NilLiteralExpr>(E)) {
56135613
// If it's a nil literal, just insert return. This is the only
56145614
// legal thing to return.
56155615
auto RS = new (Context) ReturnStmt(E->getStartLoc(), E);
5616-
BS->setElement(0, RS);
5616+
BS->setFirstElement(RS);
56175617
AFD->setHasSingleExpressionBody();
56185618
AFD->setSingleExpressionBody(E);
56195619
}

lib/SILGen/SILGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -982,7 +982,7 @@ void SILGenModule::emitObjCAllocatorDestructor(ClassDecl *cd,
982982

983983
// Emit the Objective-C -dealloc entry point if it has
984984
// something to do beyond messaging the superclass's -dealloc.
985-
if (dd->hasBody() && dd->getBody()->getNumElements() != 0)
985+
if (dd->hasBody() && !dd->getBody()->empty())
986986
emitObjCDestructorThunk(dd);
987987

988988
// Emit the ivar initializer, if needed.

lib/SILGen/SILGenPattern.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2319,7 +2319,7 @@ void PatternMatchEmission::emitCaseBody(CaseStmt *caseBlock) {
23192319
RegularLocation::getAutoGeneratedLocation(caseBlock->getEndLoc());
23202320
if (auto *braces = dyn_cast<BraceStmt>(caseBlock->getBody()))
23212321
if (braces->getNumElements() == 1 &&
2322-
dyn_cast_or_null<DoStmt>(braces->getElement(0).dyn_cast<Stmt *>()))
2322+
dyn_cast_or_null<DoStmt>(braces->getFirstElement().dyn_cast<Stmt *>()))
23232323
cleanupLoc = CleanupLocation(caseBlock);
23242324
SGF.emitBreakOutOf(cleanupLoc, PatternMatchStmt);
23252325
}

lib/SILOptimizer/Mandatory/DataflowDiagnostics.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,8 @@ static void diagnoseMissingReturn(const UnreachableInst *UI,
6060

6161
SILLocation L = UI->getLoc();
6262
assert(L && ResTy);
63-
auto numElements = BS->getNumElements();
64-
if (numElements > 0) {
65-
auto element = BS->getElement(numElements - 1);
63+
if (!BS->empty()) {
64+
auto element = BS->getLastElement();
6665
if (auto expr = element.dyn_cast<Expr *>()) {
6766
if (expr->getType()->isEqual(ResTy)) {
6867
Context.Diags.diagnose(

lib/Sema/CSApply.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5591,7 +5591,7 @@ ClosureExpr *ExprRewriter::coerceClosureExprToVoid(ClosureExpr *closureExpr) {
55915591

55925592
// A single-expression body contains a single return statement
55935593
// prior to this transformation.
5594-
auto member = closureExpr->getBody()->getElement(0);
5594+
auto member = closureExpr->getBody()->getFirstElement();
55955595

55965596
if (member.is<Stmt *>()) {
55975597
auto returnStmt = cast<ReturnStmt>(member.get<Stmt *>());
@@ -5643,7 +5643,7 @@ ClosureExpr *ExprRewriter::coerceClosureExprFromNever(ClosureExpr *closureExpr)
56435643

56445644
// A single-expression body contains a single return statement
56455645
// prior to this transformation.
5646-
auto member = closureExpr->getBody()->getElement(0);
5646+
auto member = closureExpr->getBody()->getFirstElement();
56475647

56485648
if (member.is<Stmt *>()) {
56495649
auto returnStmt = cast<ReturnStmt>(member.get<Stmt *>());

lib/Sema/CSDiagnostics.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2673,7 +2673,7 @@ void ContextualFailure::tryComputedPropertyFixIts(Expr *expr) const {
26732673

26742674
if (auto TLCD = dyn_cast<TopLevelCodeDecl>(getDC())) {
26752675
if (TLCD->getBody()->isImplicit()) {
2676-
if (auto decl = TLCD->getBody()->getElement(0).dyn_cast<Decl *>()) {
2676+
if (auto decl = TLCD->getBody()->getFirstElement().dyn_cast<Decl *>()) {
26772677
if (auto binding = dyn_cast<PatternBindingDecl>(decl)) {
26782678
PBD = binding;
26792679
}

lib/Sema/TypeCheckPattern.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ extractEnumElement(TypeChecker &TC, DeclContext *DC, SourceLoc UseLoc,
4646
if (!body || body->getNumElements() != 1)
4747
return nullptr;
4848

49-
auto *retStmtRaw = body->getElement(0).dyn_cast<Stmt *>();
49+
auto *retStmtRaw = body->getFirstElement().dyn_cast<Stmt *>();
5050
auto *retStmt = dyn_cast_or_null<ReturnStmt>(retStmtRaw);
5151
if (!retStmt)
5252
return nullptr;

lib/Sema/TypeCheckREPL.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ void TypeChecker::processREPLTopLevel(SourceFile &SF, TopLevelContext &TLC,
443443
if (!TLCD || TLCD->getBody()->getElements().empty())
444444
continue;
445445

446-
auto Entry = TLCD->getBody()->getElement(0);
446+
auto Entry = TLCD->getBody()->getFirstElement();
447447

448448
// Check to see if the TLCD has an expression that we have to transform.
449449
if (auto *E = Entry.dyn_cast<Expr*>())

lib/Sema/TypeCheckStmt.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,9 +1758,9 @@ Stmt *StmtChecker::visitBraceStmt(BraceStmt *BS) {
17581758
// BraceStmt does not start a TopLevelDecl).
17591759
if (IsBraceStmtFromTopLevelDecl) {
17601760
IsBraceStmtFromTopLevelDecl = false;
1761-
} else if (BS->getNumElements() > 0) {
1761+
} else if (!BS->empty()) {
17621762
if (auto stmt =
1763-
BS->getElement(BS->getNumElements() - 1).dyn_cast<Stmt *>()) {
1763+
BS->getLastElement().dyn_cast<Stmt *>()) {
17641764
if (auto deferStmt = dyn_cast<DeferStmt>(stmt)) {
17651765
TC.diagnose(deferStmt->getStartLoc(), diag::defer_stmt_at_block_end)
17661766
.fixItReplace(deferStmt->getStartLoc(), "do");
@@ -2084,12 +2084,12 @@ TypeCheckFunctionBodyUntilRequest::evaluate(Evaluator &evaluator,
20842084
if (resultTypeLoc.isNull() || resultTypeLoc.getType()->isVoid()) {
20852085
// The function returns void. We don't need an explicit return, no matter
20862086
// what the type of the expression is. Take the inserted return back out.
2087-
body->setElement(0, expr);
2087+
body->setFirstElement(expr);
20882088
}
20892089
}
20902090
} else if (isa<ConstructorDecl>(AFD) &&
2091-
(body->getNumElements() == 0 ||
2092-
!isKnownEndOfConstructor(body->getElements().back()))) {
2091+
(body->empty() ||
2092+
!isKnownEndOfConstructor(body->getLastElement()))) {
20932093
// For constructors, we make sure that the body ends with a "return" stmt,
20942094
// which we either implicitly synthesize, or the user can write. This
20952095
// simplifies SILGen.
@@ -2111,12 +2111,12 @@ TypeCheckFunctionBodyUntilRequest::evaluate(Evaluator &evaluator,
21112111
// that we have eagerly converted something like `{ fatalError() }`
21122112
// into `{ return fatalError() }` that has to be corrected here.
21132113
if (isa<FuncDecl>(AFD) && cast<FuncDecl>(AFD)->hasSingleExpressionBody()) {
2114-
if (auto *stmt = body->getElement(0).dyn_cast<Stmt *>()) {
2114+
if (auto *stmt = body->getFirstElement().dyn_cast<Stmt *>()) {
21152115
if (auto *retStmt = dyn_cast<ReturnStmt>(stmt)) {
21162116
if (retStmt->isImplicit() && retStmt->hasResult()) {
21172117
auto returnType = retStmt->getResult()->getType();
21182118
if (returnType && returnType->isUninhabited())
2119-
body->setElement(0, retStmt->getResult());
2119+
body->setFirstElement(retStmt->getResult());
21202120
}
21212121
}
21222122
}

0 commit comments

Comments
 (0)