@@ -364,68 +364,70 @@ class BuilderClosureVisitor
364
364
}
365
365
}
366
366
367
- VarDecl *visitBraceStmt (BraceStmt *braceStmt) {
368
- SmallVector<Expr *, 4 > expressions;
367
+ void visitBraceElement (ASTNode node, SmallVectorImpl<Expr *> &expressions) {
369
368
auto addChild = [&](VarDecl *childVar) {
370
369
if (!childVar)
371
370
return ;
372
371
373
372
expressions.push_back (builder.buildVarRef (childVar, childVar->getLoc ()));
374
373
};
375
374
376
- for (auto node : braceStmt->getElements ()) {
377
- // Implicit returns in single-expression function bodies are treated
378
- // as the expression.
379
- if (auto returnStmt =
380
- dyn_cast_or_null<ReturnStmt>(node.dyn_cast <Stmt *>())) {
381
- assert (returnStmt->isImplicit ());
382
- node = returnStmt->getResult ();
383
- }
384
-
385
- if (auto stmt = node.dyn_cast <Stmt *>()) {
386
- addChild (visit (stmt));
387
- continue ;
388
- }
375
+ // Implicit returns in single-expression function bodies are treated
376
+ // as the expression.
377
+ if (auto returnStmt =
378
+ dyn_cast_or_null<ReturnStmt>(node.dyn_cast <Stmt *>())) {
379
+ assert (returnStmt->isImplicit ());
380
+ node = returnStmt->getResult ();
381
+ }
389
382
390
- if (auto decl = node.dyn_cast <Decl *>()) {
391
- // Just ignore #if; the chosen children should appear in the
392
- // surrounding context. This isn't good for source tools but it
393
- // at least works.
394
- if (isa<IfConfigDecl>(decl))
395
- continue ;
383
+ if (auto stmt = node.dyn_cast <Stmt *>()) {
384
+ addChild (visit (stmt));
385
+ return ;
386
+ }
396
387
397
- // Skip #warning/#error; we'll handle them when applying the builder.
398
- if (isa<PoundDiagnosticDecl>(decl)) {
399
- continue ;
400
- }
388
+ if (auto decl = node.dyn_cast <Decl *>()) {
389
+ // Just ignore #if; the chosen children should appear in the
390
+ // surrounding context. This isn't good for source tools but it
391
+ // at least works.
392
+ if (isa<IfConfigDecl>(decl))
393
+ return ;
401
394
402
- // Pattern bindings are okay so long as all of the entries are
403
- // initialized.
404
- if (auto patternBinding = dyn_cast<PatternBindingDecl>(decl)) {
405
- visitPatternBindingDecl (patternBinding);
406
- continue ;
407
- }
395
+ // Skip #warning/#error; we'll handle them when applying the builder.
396
+ if (isa<PoundDiagnosticDecl>(decl))
397
+ return ;
408
398
409
- // Ignore variable declarations, because they're always handled within
410
- // their enclosing pattern bindings.
411
- if (isa<VarDecl>(decl))
412
- continue ;
399
+ // Pattern bindings are okay so long as all of the entries are
400
+ // initialized.
401
+ if (auto patternBinding = dyn_cast<PatternBindingDecl>(decl)) {
402
+ visitPatternBindingDecl (patternBinding);
403
+ return ;
404
+ }
413
405
414
- if (!unhandledNode)
415
- unhandledNode = decl;
406
+ // Ignore variable declarations, because they're always handled within
407
+ // their enclosing pattern bindings.
408
+ if (isa<VarDecl>(decl))
409
+ return ;
416
410
417
- continue ;
418
- }
411
+ if (!unhandledNode)
412
+ unhandledNode = decl;
419
413
420
- auto expr = node.get <Expr *>();
421
- if (cs && builder.supports (ctx.Id_buildExpression )) {
422
- expr = buildCallIfWanted (expr->getLoc (), ctx.Id_buildExpression ,
423
- { expr }, { Identifier () });
424
- }
414
+ return ;
415
+ }
425
416
426
- addChild (captureExpr (expr, /* oneWay=*/ true , node.get <Expr *>()));
417
+ auto expr = node.get <Expr *>();
418
+ if (cs && builder.supports (ctx.Id_buildExpression )) {
419
+ expr = buildCallIfWanted (expr->getLoc (), ctx.Id_buildExpression ,
420
+ {expr}, {Identifier ()});
427
421
}
428
422
423
+ addChild (captureExpr (expr, /* oneWay=*/ true , node.get <Expr *>()));
424
+ }
425
+
426
+ VarDecl *visitBraceStmt (BraceStmt *braceStmt) {
427
+ SmallVector<Expr *, 4 > expressions;
428
+ for (auto node : braceStmt->getElements ())
429
+ visitBraceElement (node, expressions);
430
+
429
431
if (!cs || hadError)
430
432
return nullptr ;
431
433
@@ -1769,107 +1771,113 @@ class BuilderClosureRewriter
1769
1771
solution (solution), dc(dc), builderTransform(builderTransform),
1770
1772
rewriteTarget(rewriteTarget) { }
1771
1773
1772
- NullablePtr<Stmt>
1773
- visitBraceStmt (BraceStmt *braceStmt, ResultBuilderTarget target,
1774
- Optional<ResultBuilderTarget> innerTarget = None ) {
1775
- std::vector<ASTNode> newElements;
1776
-
1777
- // If there is an "inner" target corresponding to this brace, declare
1778
- // it's temporary variable if needed.
1779
- if (innerTarget) {
1780
- declareTemporaryVariable (innerTarget-> captured . first , newElements );
1774
+ // / Visit the element of a brace statement, returning \c false if the element
1775
+ // / was rewritten successfully, or \c true if there was an error.
1776
+ bool visitBraceElement (ASTNode node, std::vector<ASTNode> &newElements ) {
1777
+ // Implicit returns in single-expression function bodies are treated
1778
+ // as the expression.
1779
+ if ( auto returnStmt =
1780
+ dyn_cast_or_null<ReturnStmt>(node. dyn_cast <Stmt *>())) {
1781
+ assert (returnStmt-> isImplicit ());
1782
+ node = returnStmt-> getResult ( );
1781
1783
}
1782
1784
1783
- for (auto node : braceStmt->getElements ()) {
1784
- // Implicit returns in single-expression function bodies are treated
1785
- // as the expression.
1786
- if (auto returnStmt =
1787
- dyn_cast_or_null<ReturnStmt>(node.dyn_cast <Stmt *>())) {
1788
- assert (returnStmt->isImplicit ());
1789
- node = returnStmt->getResult ();
1790
- }
1785
+ if (auto expr = node.dyn_cast <Expr *>()) {
1786
+ // Skip error expressions.
1787
+ if (isa<ErrorExpr>(expr))
1788
+ return false ;
1791
1789
1792
- if (auto expr = node.dyn_cast <Expr *>()) {
1793
- // Skip error expressions.
1794
- if (isa<ErrorExpr>(expr))
1795
- continue ;
1790
+ // Each expression turns into a 'let' that captures the value of
1791
+ // the expression.
1792
+ auto recorded = takeCapturedExpr (expr);
1796
1793
1797
- // Each expression turns into a 'let' that captures the value of
1798
- // the expression.
1799
- auto recorded = takeCapturedExpr (expr);
1794
+ // Rewrite the expression
1795
+ Expr *finalExpr = rewriteExpr (recorded.generatedExpr );
1800
1796
1801
- // Rewrite the expression
1802
- Expr *finalExpr = rewriteExpr (recorded.generatedExpr );
1797
+ // Form a new pattern binding to bind the temporary variable to the
1798
+ // transformed expression.
1799
+ declareTemporaryVariable (recorded.temporaryVar , newElements, finalExpr);
1800
+ return false ;
1801
+ }
1803
1802
1804
- // Form a new pattern binding to bind the temporary variable to the
1805
- // transformed expression.
1806
- declareTemporaryVariable (recorded.temporaryVar , newElements, finalExpr);
1807
- continue ;
1803
+ if (auto stmt = node.dyn_cast <Stmt *>()) {
1804
+ // "throw" statements produce no value. Transform them directly.
1805
+ if (auto throwStmt = dyn_cast<ThrowStmt>(stmt)) {
1806
+ if (auto newStmt = visitThrowStmt (throwStmt)) {
1807
+ newElements.push_back (newStmt.get ());
1808
+ }
1809
+ return false ;
1808
1810
}
1809
1811
1810
- if (auto stmt = node.dyn_cast <Stmt *>()) {
1811
- // "throw" statements produce no value. Transform them directly.
1812
- if (auto throwStmt = dyn_cast<ThrowStmt>(stmt)) {
1813
- if (auto newStmt = visitThrowStmt (throwStmt)) {
1814
- newElements.push_back (newStmt.get ());
1815
- }
1816
- continue ;
1817
- }
1812
+ // Each statement turns into a (potential) temporary variable
1813
+ // binding followed by the statement itself.
1814
+ auto captured = takeCapturedStmt (stmt);
1818
1815
1819
- // Each statement turns into a (potential) temporary variable
1820
- // binding followed by the statement itself.
1821
- auto captured = takeCapturedStmt (stmt);
1816
+ declareTemporaryVariable (captured.first , newElements);
1822
1817
1823
- declareTemporaryVariable (captured.first , newElements);
1818
+ auto finalStmt =
1819
+ visit (stmt, ResultBuilderTarget{ResultBuilderTarget::TemporaryVar,
1820
+ std::move (captured)});
1824
1821
1825
- auto finalStmt = visit (
1826
- stmt,
1827
- ResultBuilderTarget{ResultBuilderTarget::TemporaryVar,
1828
- std::move (captured)}) ;
1822
+ // Re-write of statements that envolve type-checking
1823
+ // could fail, such a failure terminates the walk.
1824
+ if (!finalStmt)
1825
+ return true ;
1829
1826
1830
- // Re-write of statements that envolve type-checking
1831
- // could fail, such a failure terminates the walk.
1832
- if (!finalStmt)
1833
- return nullptr ;
1827
+ newElements.push_back (finalStmt.get ());
1828
+ return false ;
1829
+ }
1834
1830
1835
- newElements.push_back (finalStmt.get ());
1836
- continue ;
1837
- }
1831
+ auto decl = node.get <Decl *>();
1838
1832
1839
- auto decl = node.get <Decl *>();
1833
+ // Skip #if declarations.
1834
+ if (isa<IfConfigDecl>(decl)) {
1835
+ newElements.push_back (decl);
1836
+ return false ;
1837
+ }
1840
1838
1841
- // Skip #if declarations.
1842
- if (isa<IfConfigDecl>(decl)) {
1843
- newElements.push_back (decl);
1844
- continue ;
1845
- }
1839
+ // Diagnose #warning / #error during application.
1840
+ if (auto poundDiag = dyn_cast<PoundDiagnosticDecl>(decl)) {
1841
+ TypeChecker::typeCheckDecl (poundDiag);
1842
+ newElements.push_back (decl);
1843
+ return false ;
1844
+ }
1846
1845
1847
- // Diagnose #warning / #error during application.
1848
- if (auto poundDiag = dyn_cast<PoundDiagnosticDecl>(decl)) {
1849
- TypeChecker::typeCheckDecl (poundDiag);
1850
- newElements.push_back (decl);
1851
- continue ;
1852
- }
1846
+ // Skip variable declarations; they're always part of a pattern
1847
+ // binding.
1848
+ if (isa<VarDecl>(decl)) {
1849
+ TypeChecker::typeCheckDecl (decl);
1850
+ newElements.push_back (decl);
1851
+ return false ;
1852
+ }
1853
1853
1854
- // Skip variable declarations; they're always part of a pattern
1855
- // binding.
1856
- if (isa<VarDecl>(decl)) {
1857
- TypeChecker::typeCheckDecl (decl);
1858
- newElements.push_back (decl);
1859
- continue ;
1860
- }
1854
+ // Handle pattern bindings.
1855
+ if (auto patternBinding = dyn_cast<PatternBindingDecl>(decl)) {
1856
+ auto resultTarget =
1857
+ rewriteTarget (SolutionApplicationTarget{patternBinding});
1858
+ assert (resultTarget.has_value () &&
1859
+ " Could not rewrite pattern binding entries!" );
1860
+ TypeChecker::typeCheckDecl (resultTarget->getAsPatternBinding ());
1861
+ newElements.push_back (resultTarget->getAsPatternBinding ());
1862
+ return false ;
1863
+ }
1861
1864
1862
- // Handle pattern bindings.
1863
- if (auto patternBinding = dyn_cast<PatternBindingDecl>(decl)) {
1864
- auto resultTarget = rewriteTarget (SolutionApplicationTarget{patternBinding});
1865
- assert (resultTarget.has_value ()
1866
- && " Could not rewrite pattern binding entries!" );
1867
- TypeChecker::typeCheckDecl (resultTarget->getAsPatternBinding ());
1868
- newElements.push_back (resultTarget->getAsPatternBinding ());
1869
- continue ;
1870
- }
1865
+ llvm_unreachable (" Cannot yet handle declarations" );
1866
+ }
1871
1867
1872
- llvm_unreachable (" Cannot yet handle declarations" );
1868
+ NullablePtr<Stmt>
1869
+ visitBraceStmt (BraceStmt *braceStmt, ResultBuilderTarget target,
1870
+ Optional<ResultBuilderTarget> innerTarget = None) {
1871
+ std::vector<ASTNode> newElements;
1872
+
1873
+ // If there is an "inner" target corresponding to this brace, declare
1874
+ // it's temporary variable if needed.
1875
+ if (innerTarget)
1876
+ declareTemporaryVariable (innerTarget->captured .first , newElements);
1877
+
1878
+ for (auto node : braceStmt->getElements ()) {
1879
+ if (visitBraceElement (node, newElements))
1880
+ return nullptr ;
1873
1881
}
1874
1882
1875
1883
// If there is an "inner" target corresponding to this brace, initialize
0 commit comments