| /** | |
| * 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); | |
| } | |
| } |