1 /** 2 * Provides a visitor for statements that allows rewriting the currently visited node. 3 * 4 * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved 5 * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) 6 * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 7 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/statement_rewrite_walker.d, _statement_rewrite_walker.d) 8 * Documentation: https://dlang.org/phobos/dmd_statement_rewrite_walker.html 9 * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/statement_rewrite_walker.d 10 */ 11 12 module dmd.statement_rewrite_walker; 13 14 import core.stdc.stdio; 15 16 import dmd.statement; 17 import dmd.visitor; 18 19 20 /** A visitor to walk entire statements and provides ability to replace any sub-statements. 21 */ 22 extern (C++) class StatementRewriteWalker : SemanticTimePermissiveVisitor 23 { 24 alias visit = SemanticTimePermissiveVisitor.visit; 25 26 /* Point the currently visited statement. 27 * By using replaceCurrent() method, you can replace AST during walking. 28 */ 29 Statement* ps; 30 31 public: 32 final void visitStmt(ref Statement s) 33 { 34 ps = &s; 35 s.accept(this); 36 } 37 38 final void replaceCurrent(Statement s) 39 { 40 *ps = s; 41 } 42 43 override void visit(PeelStatement s) 44 { 45 if (s.s) 46 visitStmt(s.s); 47 } 48 49 override void visit(CompoundStatement s) 50 { 51 if (s.statements && s.statements.length) 52 { 53 for (size_t i = 0; i < s.statements.length; i++) 54 { 55 if ((*s.statements)[i]) 56 visitStmt((*s.statements)[i]); 57 } 58 } 59 } 60 61 override void visit(CompoundDeclarationStatement s) 62 { 63 visit(cast(CompoundStatement)s); 64 } 65 66 override void visit(UnrolledLoopStatement s) 67 { 68 if (s.statements && s.statements.length) 69 { 70 for (size_t i = 0; i < s.statements.length; i++) 71 { 72 if ((*s.statements)[i]) 73 visitStmt((*s.statements)[i]); 74 } 75 } 76 } 77 78 override void visit(ScopeStatement s) 79 { 80 if (s.statement) 81 visitStmt(s.statement); 82 } 83 84 override void visit(WhileStatement s) 85 { 86 if (s._body) 87 visitStmt(s._body); 88 } 89 90 override void visit(DoStatement s) 91 { 92 if (s._body) 93 visitStmt(s._body); 94 } 95 96 override void visit(ForStatement s) 97 { 98 if (s._init) 99 visitStmt(s._init); 100 if (s._body) 101 visitStmt(s._body); 102 } 103 104 override void visit(ForeachStatement s) 105 { 106 if (s._body) 107 visitStmt(s._body); 108 } 109 110 override void visit(ForeachRangeStatement s) 111 { 112 if (s._body) 113 visitStmt(s._body); 114 } 115 116 override void visit(IfStatement s) 117 { 118 if (s.ifbody) 119 visitStmt(s.ifbody); 120 if (s.elsebody) 121 visitStmt(s.elsebody); 122 } 123 124 override void visit(SwitchStatement s) 125 { 126 if (s._body) 127 visitStmt(s._body); 128 } 129 130 override void visit(CaseStatement s) 131 { 132 if (s.statement) 133 visitStmt(s.statement); 134 } 135 136 override void visit(CaseRangeStatement s) 137 { 138 if (s.statement) 139 visitStmt(s.statement); 140 } 141 142 override void visit(DefaultStatement s) 143 { 144 if (s.statement) 145 visitStmt(s.statement); 146 } 147 148 override void visit(SynchronizedStatement s) 149 { 150 if (s._body) 151 visitStmt(s._body); 152 } 153 154 override void visit(WithStatement s) 155 { 156 if (s._body) 157 visitStmt(s._body); 158 } 159 160 override void visit(TryCatchStatement s) 161 { 162 if (s._body) 163 visitStmt(s._body); 164 if (s.catches && s.catches.length) 165 { 166 for (size_t i = 0; i < s.catches.length; i++) 167 { 168 Catch c = (*s.catches)[i]; 169 if (c && c.handler) 170 visitStmt(c.handler); 171 } 172 } 173 } 174 175 override void visit(TryFinallyStatement s) 176 { 177 if (s._body) 178 visitStmt(s._body); 179 if (s.finalbody) 180 visitStmt(s.finalbody); 181 } 182 183 override void visit(DebugStatement s) 184 { 185 if (s.statement) 186 visitStmt(s.statement); 187 } 188 189 override void visit(LabelStatement s) 190 { 191 if (s.statement) 192 visitStmt(s.statement); 193 } 194 }