@@ -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
@@ -1762,107 +1764,113 @@ class BuilderClosureRewriter
1762
1764
solution (solution), dc(dc), builderTransform(builderTransform),
1763
1765
rewriteTarget(rewriteTarget) { }
1764
1766
1765
- NullablePtr<Stmt>
1766
- visitBraceStmt (BraceStmt *braceStmt, ResultBuilderTarget target,
1767
- Optional<ResultBuilderTarget> innerTarget = None ) {
1768
- std::vector<ASTNode> newElements;
1769
-
1770
- // If there is an "inner" target corresponding to this brace, declare
1771
- // it's temporary variable if needed.
1772
- if (innerTarget) {
1773
- declareTemporaryVariable (innerTarget-> captured . first , newElements );
1767
+ // / Visit the element of a brace statement, returning \c false if the element
1768
+ // / was rewritten successfully, or \c true if there was an error.
1769
+ bool visitBraceElement (ASTNode node, std::vector<ASTNode> &newElements ) {
1770
+ // Implicit returns in single-expression function bodies are treated
1771
+ // as the expression.
1772
+ if ( auto returnStmt =
1773
+ dyn_cast_or_null<ReturnStmt>(node. dyn_cast <Stmt *>())) {
1774
+ assert (returnStmt-> isImplicit ());
1775
+ node = returnStmt-> getResult ( );
1774
1776
}
1775
1777
1776
- for (auto node : braceStmt->getElements ()) {
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 ();
1783
- }
1778
+ if (auto expr = node.dyn_cast <Expr *>()) {
1779
+ // Skip error expressions.
1780
+ if (isa<ErrorExpr>(expr))
1781
+ return false ;
1784
1782
1785
- if (auto expr = node.dyn_cast <Expr *>()) {
1786
- // Skip error expressions.
1787
- if (isa<ErrorExpr>(expr))
1788
- continue ;
1783
+ // Each expression turns into a 'let' that captures the value of
1784
+ // the expression.
1785
+ auto recorded = takeCapturedExpr (expr);
1789
1786
1790
- // Each expression turns into a 'let' that captures the value of
1791
- // the expression.
1792
- auto recorded = takeCapturedExpr (expr);
1787
+ // Rewrite the expression
1788
+ Expr *finalExpr = rewriteExpr (recorded.generatedExpr );
1793
1789
1794
- // Rewrite the expression
1795
- Expr *finalExpr = rewriteExpr (recorded.generatedExpr );
1790
+ // Form a new pattern binding to bind the temporary variable to the
1791
+ // transformed expression.
1792
+ declareTemporaryVariable (recorded.temporaryVar , newElements, finalExpr);
1793
+ return false ;
1794
+ }
1796
1795
1797
- // Form a new pattern binding to bind the temporary variable to the
1798
- // transformed expression.
1799
- declareTemporaryVariable (recorded.temporaryVar , newElements, finalExpr);
1800
- continue ;
1796
+ if (auto stmt = node.dyn_cast <Stmt *>()) {
1797
+ // "throw" statements produce no value. Transform them directly.
1798
+ if (auto throwStmt = dyn_cast<ThrowStmt>(stmt)) {
1799
+ if (auto newStmt = visitThrowStmt (throwStmt)) {
1800
+ newElements.push_back (newStmt.get ());
1801
+ }
1802
+ return false ;
1801
1803
}
1802
1804
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
- continue ;
1810
- }
1805
+ // Each statement turns into a (potential) temporary variable
1806
+ // binding followed by the statement itself.
1807
+ auto captured = takeCapturedStmt (stmt);
1811
1808
1812
- // Each statement turns into a (potential) temporary variable
1813
- // binding followed by the statement itself.
1814
- auto captured = takeCapturedStmt (stmt);
1809
+ declareTemporaryVariable (captured.first , newElements);
1815
1810
1816
- declareTemporaryVariable (captured.first , newElements);
1811
+ auto finalStmt =
1812
+ visit (stmt, ResultBuilderTarget{ResultBuilderTarget::TemporaryVar,
1813
+ std::move (captured)});
1817
1814
1818
- auto finalStmt = visit (
1819
- stmt,
1820
- ResultBuilderTarget{ResultBuilderTarget::TemporaryVar,
1821
- std::move (captured)}) ;
1815
+ // Re-write of statements that envolve type-checking
1816
+ // could fail, such a failure terminates the walk.
1817
+ if (!finalStmt)
1818
+ return true ;
1822
1819
1823
- // Re-write of statements that envolve type-checking
1824
- // could fail, such a failure terminates the walk.
1825
- if (!finalStmt)
1826
- return nullptr ;
1820
+ newElements.push_back (finalStmt.get ());
1821
+ return false ;
1822
+ }
1827
1823
1828
- newElements.push_back (finalStmt.get ());
1829
- continue ;
1830
- }
1824
+ auto decl = node.get <Decl *>();
1831
1825
1832
- auto decl = node.get <Decl *>();
1826
+ // Skip #if declarations.
1827
+ if (isa<IfConfigDecl>(decl)) {
1828
+ newElements.push_back (decl);
1829
+ return false ;
1830
+ }
1833
1831
1834
- // Skip #if declarations.
1835
- if (isa<IfConfigDecl>(decl)) {
1836
- newElements.push_back (decl);
1837
- continue ;
1838
- }
1832
+ // Diagnose #warning / #error during application.
1833
+ if (auto poundDiag = dyn_cast<PoundDiagnosticDecl>(decl)) {
1834
+ TypeChecker::typeCheckDecl (poundDiag);
1835
+ newElements.push_back (decl);
1836
+ return false ;
1837
+ }
1839
1838
1840
- // Diagnose #warning / #error during application.
1841
- if (auto poundDiag = dyn_cast<PoundDiagnosticDecl>(decl)) {
1842
- TypeChecker::typeCheckDecl (poundDiag);
1843
- newElements.push_back (decl);
1844
- continue ;
1845
- }
1839
+ // Skip variable declarations; they're always part of a pattern
1840
+ // binding.
1841
+ if (isa<VarDecl>(decl)) {
1842
+ TypeChecker::typeCheckDecl (decl);
1843
+ newElements.push_back (decl);
1844
+ return false ;
1845
+ }
1846
1846
1847
- // Skip variable declarations; they're always part of a pattern
1848
- // binding.
1849
- if (isa<VarDecl>(decl)) {
1850
- TypeChecker::typeCheckDecl (decl);
1851
- newElements.push_back (decl);
1852
- continue ;
1853
- }
1847
+ // Handle pattern bindings.
1848
+ if (auto patternBinding = dyn_cast<PatternBindingDecl>(decl)) {
1849
+ auto resultTarget =
1850
+ rewriteTarget (SolutionApplicationTarget{patternBinding});
1851
+ assert (resultTarget.has_value () &&
1852
+ " Could not rewrite pattern binding entries!" );
1853
+ TypeChecker::typeCheckDecl (resultTarget->getAsPatternBinding ());
1854
+ newElements.push_back (resultTarget->getAsPatternBinding ());
1855
+ return false ;
1856
+ }
1854
1857
1855
- // Handle pattern bindings.
1856
- if (auto patternBinding = dyn_cast<PatternBindingDecl>(decl)) {
1857
- auto resultTarget = 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
- continue ;
1863
- }
1858
+ llvm_unreachable (" Cannot yet handle declarations" );
1859
+ }
1864
1860
1865
- llvm_unreachable (" Cannot yet handle declarations" );
1861
+ NullablePtr<Stmt>
1862
+ visitBraceStmt (BraceStmt *braceStmt, ResultBuilderTarget target,
1863
+ Optional<ResultBuilderTarget> innerTarget = None) {
1864
+ std::vector<ASTNode> newElements;
1865
+
1866
+ // If there is an "inner" target corresponding to this brace, declare
1867
+ // it's temporary variable if needed.
1868
+ if (innerTarget)
1869
+ declareTemporaryVariable (innerTarget->captured .first , newElements);
1870
+
1871
+ for (auto node : braceStmt->getElements ()) {
1872
+ if (visitBraceElement (node, newElements))
1873
+ return nullptr ;
1866
1874
}
1867
1875
1868
1876
// If there is an "inner" target corresponding to this brace, initialize
0 commit comments