mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[AST] Introduce explicit actions for ASTWalker
Replace the use of bool and pointer returns for `walkToXXXPre`/`walkToXXXPost`, and instead use explicit actions such as `Action::Continue(E)`, `Action::SkipChildren(E)`, and `Action::Stop()`. There are also conditional variants, e.g `Action::SkipChildrenIf`, `Action::VisitChildrenIf`, and `Action::StopIf`. There is still more work that can be done here, in particular: - SourceEntityWalker still needs to be migrated. - Some uses of `return false` in pre-visitation methods can likely now be replaced by `Action::Stop`. - We still use bool and pointer returns internally within the ASTWalker traversal, which could likely be improved. But I'm leaving those as future work for now as this patch is already large enough.
This commit is contained in:
@@ -657,37 +657,38 @@ static void extendDepthMap(
|
||||
// should actually do this, as it doesn't reflect the true expression depth,
|
||||
// but it's needed to preserve compatibility with the behavior from when
|
||||
// TupleExpr and ParenExpr were used to represent argument lists.
|
||||
std::pair<bool, ArgumentList *>
|
||||
PreWalkResult<ArgumentList *>
|
||||
walkToArgumentListPre(ArgumentList *ArgList) override {
|
||||
++Depth;
|
||||
return {true, ArgList};
|
||||
return Action::Continue(ArgList);
|
||||
}
|
||||
ArgumentList *walkToArgumentListPost(ArgumentList *ArgList) override {
|
||||
PostWalkResult<ArgumentList *>
|
||||
walkToArgumentListPost(ArgumentList *ArgList) override {
|
||||
--Depth;
|
||||
return ArgList;
|
||||
return Action::Continue(ArgList);
|
||||
}
|
||||
|
||||
std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
|
||||
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
|
||||
DepthMap[E] = {Depth, Parent.getAsExpr()};
|
||||
++Depth;
|
||||
|
||||
if (auto CE = dyn_cast<ClosureExpr>(E))
|
||||
Closures.push_back(CE);
|
||||
|
||||
return { true, E };
|
||||
return Action::Continue(E);
|
||||
}
|
||||
|
||||
Expr *walkToExprPost(Expr *E) override {
|
||||
PostWalkResult<Expr *> walkToExprPost(Expr *E) override {
|
||||
if (auto CE = dyn_cast<ClosureExpr>(E)) {
|
||||
assert(Closures.back() == CE);
|
||||
Closures.pop_back();
|
||||
}
|
||||
|
||||
--Depth;
|
||||
return E;
|
||||
return Action::Continue(E);
|
||||
}
|
||||
|
||||
std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override {
|
||||
PreWalkResult<Stmt *> walkToStmtPre(Stmt *S) override {
|
||||
if (auto RS = dyn_cast<ReturnStmt>(S)) {
|
||||
// For return statements, treat the parent of the return expression
|
||||
// as the closure itself.
|
||||
@@ -695,11 +696,11 @@ static void extendDepthMap(
|
||||
llvm::SaveAndRestore<ParentTy> SavedParent(Parent, Closures.back());
|
||||
auto E = RS->getResult();
|
||||
E->walk(*this);
|
||||
return { false, S };
|
||||
return Action::SkipChildren(S);
|
||||
}
|
||||
}
|
||||
|
||||
return { true, S };
|
||||
return Action::Continue(S);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2856,31 +2857,28 @@ FunctionType::ExtInfo ClosureEffectsRequest::evaluate(
|
||||
DeclContext *DC;
|
||||
bool FoundThrow = false;
|
||||
|
||||
std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
|
||||
PreWalkResult<Expr *> walkToExprPre(Expr *expr) override {
|
||||
// If we've found a 'try', record it and terminate the traversal.
|
||||
if (isa<TryExpr>(expr)) {
|
||||
FoundThrow = true;
|
||||
return { false, nullptr };
|
||||
return Action::Stop();
|
||||
}
|
||||
|
||||
// Don't walk into a 'try!' or 'try?'.
|
||||
if (isa<ForceTryExpr>(expr) || isa<OptionalTryExpr>(expr)) {
|
||||
return { false, expr };
|
||||
return Action::SkipChildren(expr);
|
||||
}
|
||||
|
||||
// Do not recurse into other closures.
|
||||
if (isa<ClosureExpr>(expr))
|
||||
return { false, expr };
|
||||
return Action::SkipChildren(expr);
|
||||
|
||||
return { true, expr };
|
||||
return Action::Continue(expr);
|
||||
}
|
||||
|
||||
bool walkToDeclPre(Decl *decl) override {
|
||||
PreWalkAction walkToDeclPre(Decl *decl) override {
|
||||
// Do not walk into function or type declarations.
|
||||
if (!isa<PatternBindingDecl>(decl))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return Action::VisitChildrenIf(isa<PatternBindingDecl>(decl));
|
||||
}
|
||||
|
||||
bool isSyntacticallyExhaustive(DoCatchStmt *stmt) {
|
||||
@@ -2966,11 +2964,11 @@ FunctionType::ExtInfo ClosureEffectsRequest::evaluate(
|
||||
return LabelItem.isSyntacticallyExhaustive();
|
||||
}
|
||||
|
||||
std::pair<bool, Stmt *> walkToStmtPre(Stmt *stmt) override {
|
||||
PreWalkResult<Stmt *> walkToStmtPre(Stmt *stmt) override {
|
||||
// If we've found a 'throw', record it and terminate the traversal.
|
||||
if (isa<ThrowStmt>(stmt)) {
|
||||
FoundThrow = true;
|
||||
return { false, nullptr };
|
||||
return Action::Stop();
|
||||
}
|
||||
|
||||
// Handle do/catch differently.
|
||||
@@ -2979,27 +2977,27 @@ FunctionType::ExtInfo ClosureEffectsRequest::evaluate(
|
||||
// if the catch isn't syntactically exhaustive.
|
||||
if (!isSyntacticallyExhaustive(doCatch)) {
|
||||
if (!doCatch->getBody()->walk(*this))
|
||||
return { false, nullptr };
|
||||
return Action::Stop();
|
||||
}
|
||||
|
||||
// Walk into all the catch clauses.
|
||||
for (auto catchClause : doCatch->getCatches()) {
|
||||
if (!catchClause->walk(*this))
|
||||
return { false, nullptr };
|
||||
return Action::Stop();
|
||||
}
|
||||
|
||||
// We've already walked all the children we care about.
|
||||
return { false, stmt };
|
||||
return Action::SkipChildren(stmt);
|
||||
}
|
||||
|
||||
if (auto forEach = dyn_cast<ForEachStmt>(stmt)) {
|
||||
if (forEach->getTryLoc().isValid()) {
|
||||
FoundThrow = true;
|
||||
return { false, nullptr };
|
||||
return Action::Stop();
|
||||
}
|
||||
}
|
||||
|
||||
return { true, stmt };
|
||||
return Action::Continue(stmt);
|
||||
}
|
||||
|
||||
public:
|
||||
@@ -4834,10 +4832,10 @@ static void extendPreorderIndexMap(
|
||||
explicit RecordingTraversal(llvm::DenseMap<Expr *, unsigned> &indexMap)
|
||||
: IndexMap(indexMap) { }
|
||||
|
||||
std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
|
||||
PreWalkResult<Expr *> walkToExprPre(Expr *E) override {
|
||||
IndexMap[E] = Index;
|
||||
++Index;
|
||||
return { true, E };
|
||||
return Action::Continue(E);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user