blob: b1f659d33efee56c0377ec3d5f02f89c3aaf9d8f [file] [log] [blame]
/**
* Provides a visitor for statements that allows rewriting the currently visited node.
*
* Copyright: Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
* Authors: $(LINK2 https://www.digitalmars.com, Walter Bright)
* License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/statement_rewrite_walker.d, _statement_rewrite_walker.d)
* Documentation: https://dlang.org/phobos/dmd_statement_rewrite_walker.html
* Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/statement_rewrite_walker.d
*/
module dmd.statement_rewrite_walker;
import core.stdc.stdio;
import dmd.statement;
import dmd.visitor;
/** A visitor to walk entire statements and provides ability to replace any sub-statements.
*/
extern (C++) class StatementRewriteWalker : SemanticTimePermissiveVisitor
{
alias visit = SemanticTimePermissiveVisitor.visit;
/* Point the currently visited statement.
* By using replaceCurrent() method, you can replace AST during walking.
*/
Statement* ps;
public:
final void visitStmt(ref Statement s)
{
ps = &s;
s.accept(this);
}
final void replaceCurrent(Statement s)
{
*ps = s;
}
override void visit(PeelStatement s)
{
if (s.s)
visitStmt(s.s);
}
override void visit(CompoundStatement s)
{
if (s.statements && s.statements.dim)
{
for (size_t i = 0; i < s.statements.dim; i++)
{
if ((*s.statements)[i])
visitStmt((*s.statements)[i]);
}
}
}
override void visit(CompoundDeclarationStatement s)
{
visit(cast(CompoundStatement)s);
}
override void visit(UnrolledLoopStatement s)
{
if (s.statements && s.statements.dim)
{
for (size_t i = 0; i < s.statements.dim; i++)
{
if ((*s.statements)[i])
visitStmt((*s.statements)[i]);
}
}
}
override void visit(ScopeStatement s)
{
if (s.statement)
visitStmt(s.statement);
}
override void visit(WhileStatement s)
{
if (s._body)
visitStmt(s._body);
}
override void visit(DoStatement s)
{
if (s._body)
visitStmt(s._body);
}
override void visit(ForStatement s)
{
if (s._init)
visitStmt(s._init);
if (s._body)
visitStmt(s._body);
}
override void visit(ForeachStatement s)
{
if (s._body)
visitStmt(s._body);
}
override void visit(ForeachRangeStatement s)
{
if (s._body)
visitStmt(s._body);
}
override void visit(IfStatement s)
{
if (s.ifbody)
visitStmt(s.ifbody);
if (s.elsebody)
visitStmt(s.elsebody);
}
override void visit(SwitchStatement s)
{
if (s._body)
visitStmt(s._body);
}
override void visit(CaseStatement s)
{
if (s.statement)
visitStmt(s.statement);
}
override void visit(CaseRangeStatement s)
{
if (s.statement)
visitStmt(s.statement);
}
override void visit(DefaultStatement s)
{
if (s.statement)
visitStmt(s.statement);
}
override void visit(SynchronizedStatement s)
{
if (s._body)
visitStmt(s._body);
}
override void visit(WithStatement s)
{
if (s._body)
visitStmt(s._body);
}
override void visit(TryCatchStatement s)
{
if (s._body)
visitStmt(s._body);
if (s.catches && s.catches.dim)
{
for (size_t i = 0; i < s.catches.dim; i++)
{
Catch c = (*s.catches)[i];
if (c && c.handler)
visitStmt(c.handler);
}
}
}
override void visit(TryFinallyStatement s)
{
if (s._body)
visitStmt(s._body);
if (s.finalbody)
visitStmt(s.finalbody);
}
override void visit(DebugStatement s)
{
if (s.statement)
visitStmt(s.statement);
}
override void visit(LabelStatement s)
{
if (s.statement)
visitStmt(s.statement);
}
}