@@ -1222,45 +1222,61 @@ ConstraintSystem::matchResultBuilder(AnyFunctionRef fn, Type builderType,
1222
1222
return getTypeMatchSuccess ();
1223
1223
}
1224
1224
1225
- namespace {
1226
- class ReturnStmtFinder : public ASTWalker {
1227
- std::vector<ReturnStmt *> ReturnStmts;
1225
+ // / Walks the given brace statement and calls the given function reference on
1226
+ // / every occurrence of an explicit `return` statement.
1227
+ // /
1228
+ // / \param callback A function reference that takes a `return` statement and
1229
+ // / returns a boolean value indicating whether to abort the walk.
1230
+ // /
1231
+ // / \returns `true` if the walk was aborted, `false` otherwise.
1232
+ static bool walkExplicitReturnStmts (const BraceStmt *BS,
1233
+ function_ref<bool (ReturnStmt *)> callback) {
1234
+ class Walker : public ASTWalker {
1235
+ function_ref<bool (ReturnStmt *)> callback;
1236
+
1237
+ public:
1238
+ Walker (decltype (Walker::callback) callback) : callback(callback) {}
1239
+
1240
+ MacroWalking getMacroWalkingBehavior () const override {
1241
+ return MacroWalking::Arguments;
1242
+ }
1228
1243
1229
- public:
1230
- static std::vector<ReturnStmt *> find (const BraceStmt *BS) {
1231
- ReturnStmtFinder finder;
1232
- const_cast <BraceStmt *>(BS)->walk (finder);
1233
- return std::move (finder.ReturnStmts );
1234
- }
1244
+ PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
1245
+ return Action::SkipNode (E);
1246
+ }
1235
1247
1236
- MacroWalking getMacroWalkingBehavior () const override {
1237
- return MacroWalking::Arguments;
1238
- }
1248
+ PreWalkResult<Stmt *> walkToStmtPre (Stmt *S) override {
1249
+ if (S->isImplicit ()) {
1250
+ return Action::SkipNode (S);
1251
+ }
1239
1252
1240
- PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
1241
- return Action::SkipNode (E);
1242
- }
1253
+ auto *returnStmt = dyn_cast<ReturnStmt>(S);
1254
+ if (!returnStmt) {
1255
+ return Action::Continue (S);
1256
+ }
1243
1257
1244
- PreWalkResult<Stmt *> walkToStmtPre (Stmt *S) override {
1245
- // If we see a return statement, note it..
1246
- auto *returnStmt = dyn_cast<ReturnStmt>(S);
1247
- if (!returnStmt || returnStmt->isImplicit ())
1248
- return Action::Continue (S);
1258
+ if (callback (returnStmt)) {
1259
+ return Action::Stop ();
1260
+ }
1249
1261
1250
- ReturnStmts. push_back (returnStmt);
1251
- return Action::SkipNode (S);
1252
- }
1262
+ // Skip children & post walk and continue.
1263
+ return Action::SkipNode (S);
1264
+ }
1253
1265
1254
- // / Ignore patterns.
1255
- PreWalkResult<Pattern *> walkToPatternPre (Pattern *pat) override {
1256
- return Action::SkipNode (pat);
1257
- }
1258
- };
1259
- } // end anonymous namespace
1266
+ // / Ignore patterns.
1267
+ PreWalkResult<Pattern *> walkToPatternPre (Pattern *pat) override {
1268
+ return Action::SkipNode (pat);
1269
+ }
1270
+ };
1271
+
1272
+ Walker walker (callback);
1273
+
1274
+ return const_cast <BraceStmt *>(BS)->walk (walker) == nullptr ;
1275
+ }
1260
1276
1261
1277
bool BraceHasExplicitReturnStmtRequest::evaluate (Evaluator &evaluator,
1262
1278
const BraceStmt *BS) const {
1263
- return ! ReturnStmtFinder::find (BS). empty ( );
1279
+ return walkExplicitReturnStmts (BS, [](ReturnStmt *) { return true ; } );
1264
1280
}
1265
1281
1266
1282
std::vector<ReturnStmt *> TypeChecker::findReturnStatements (AnyFunctionRef fn) {
@@ -1269,7 +1285,14 @@ std::vector<ReturnStmt *> TypeChecker::findReturnStatements(AnyFunctionRef fn) {
1269
1285
return std::vector<ReturnStmt *>();
1270
1286
}
1271
1287
1272
- return ReturnStmtFinder::find (fn.getBody ());
1288
+ std::vector<ReturnStmt *> results;
1289
+
1290
+ walkExplicitReturnStmts (fn.getBody (), [&results](ReturnStmt *RS) {
1291
+ results.push_back (RS);
1292
+ return false ;
1293
+ });
1294
+
1295
+ return results;
1273
1296
}
1274
1297
1275
1298
ResultBuilderOpSupport TypeChecker::checkBuilderOpSupport (
0 commit comments