1 /** 2 * Provides a visitor for statements that allows rewriting the currently visited node. 3 * 4 * Copyright: Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved 5 * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright) 6 * License: $(LINK2 http://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: visitStmt(ref Statement s)32 final void visitStmt(ref Statement s) 33 { 34 ps = &s; 35 s.accept(this); 36 } 37 replaceCurrent(Statement s)38 final void replaceCurrent(Statement s) 39 { 40 *ps = s; 41 } 42 visit(PeelStatement s)43 override void visit(PeelStatement s) 44 { 45 if (s.s) 46 visitStmt(s.s); 47 } 48 visit(CompoundStatement s)49 override void visit(CompoundStatement s) 50 { 51 if (s.statements && s.statements.dim) 52 { 53 for (size_t i = 0; i < s.statements.dim; i++) 54 { 55 if ((*s.statements)[i]) 56 visitStmt((*s.statements)[i]); 57 } 58 } 59 } 60 visit(CompoundDeclarationStatement s)61 override void visit(CompoundDeclarationStatement s) 62 { 63 visit(cast(CompoundStatement)s); 64 } 65 visit(UnrolledLoopStatement s)66 override void visit(UnrolledLoopStatement s) 67 { 68 if (s.statements && s.statements.dim) 69 { 70 for (size_t i = 0; i < s.statements.dim; i++) 71 { 72 if ((*s.statements)[i]) 73 visitStmt((*s.statements)[i]); 74 } 75 } 76 } 77 visit(ScopeStatement s)78 override void visit(ScopeStatement s) 79 { 80 if (s.statement) 81 visitStmt(s.statement); 82 } 83 visit(WhileStatement s)84 override void visit(WhileStatement s) 85 { 86 if (s._body) 87 visitStmt(s._body); 88 } 89 visit(DoStatement s)90 override void visit(DoStatement s) 91 { 92 if (s._body) 93 visitStmt(s._body); 94 } 95 visit(ForStatement s)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 visit(ForeachStatement s)104 override void visit(ForeachStatement s) 105 { 106 if (s._body) 107 visitStmt(s._body); 108 } 109 visit(ForeachRangeStatement s)110 override void visit(ForeachRangeStatement s) 111 { 112 if (s._body) 113 visitStmt(s._body); 114 } 115 visit(IfStatement s)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 visit(SwitchStatement s)124 override void visit(SwitchStatement s) 125 { 126 if (s._body) 127 visitStmt(s._body); 128 } 129 visit(CaseStatement s)130 override void visit(CaseStatement s) 131 { 132 if (s.statement) 133 visitStmt(s.statement); 134 } 135 visit(CaseRangeStatement s)136 override void visit(CaseRangeStatement s) 137 { 138 if (s.statement) 139 visitStmt(s.statement); 140 } 141 visit(DefaultStatement s)142 override void visit(DefaultStatement s) 143 { 144 if (s.statement) 145 visitStmt(s.statement); 146 } 147 visit(SynchronizedStatement s)148 override void visit(SynchronizedStatement s) 149 { 150 if (s._body) 151 visitStmt(s._body); 152 } 153 visit(WithStatement s)154 override void visit(WithStatement s) 155 { 156 if (s._body) 157 visitStmt(s._body); 158 } 159 visit(TryCatchStatement s)160 override void visit(TryCatchStatement s) 161 { 162 if (s._body) 163 visitStmt(s._body); 164 if (s.catches && s.catches.dim) 165 { 166 for (size_t i = 0; i < s.catches.dim; i++) 167 { 168 Catch c = (*s.catches)[i]; 169 if (c && c.handler) 170 visitStmt(c.handler); 171 } 172 } 173 } 174 visit(TryFinallyStatement s)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 visit(DebugStatement s)183 override void visit(DebugStatement s) 184 { 185 if (s.statement) 186 visitStmt(s.statement); 187 } 188 visit(LabelStatement s)189 override void visit(LabelStatement s) 190 { 191 if (s.statement) 192 visitStmt(s.statement); 193 } 194 } 195