comparison src/dil/ast/NodeCopier.d @ 806:bcb74c9b895c

Moved out files in the trunk folder to the root.
author Aziz K?ksal <aziz.koeksal@gmail.com>
date Sun, 09 Mar 2008 00:12:19 +0100
parents trunk/src/dil/ast/NodeCopier.d@9e6c6bb73e5f
children
comparison
equal deleted inserted replaced
805:a3fab8b74a7d 806:bcb74c9b895c
1 /++
2 Author: Aziz Köksal
3 License: GPL3
4 +/
5 module dil.ast.NodeCopier;
6
7 import common;
8
9 /// Mixed into the body of a class that inherits from Node.
10 const string copyMethod = `
11 override typeof(this) copy()
12 {
13 mixin copyNode!(typeof(this));
14 return copyNode(this);
15 }`;
16
17 /// A helper function that generates code for copying subnodes.
18 string doCopy_(string obj, string[] members)
19 {
20 char[] result;
21 foreach (member; members)
22 {
23 if (member.length > 2 && member[$-2..$] == "[]") // Array copy.
24 {
25 member = member[0..$-2];
26 // obj.member = obj.member.dup;
27 // foreach (ref m_; obj.member)
28 // m_ = m_.copy();
29 result ~= obj~"."~member~" = "~obj~"."~member~".dup;"
30 "foreach (ref m_; "~obj~"."~member~")"
31 "m_ = m_.copy();";
32 }
33 else if (member[$-1] == '?') // Optional member copy.
34 {
35 member = member[0..$-1];
36 // obj.member && (obj.member = obj.member.copy());
37 result ~= obj~"."~member~" && ("~obj~"."~member~" = "~obj~"."~member~".copy());";
38 }
39 else // Non-optional member copy.
40 // obj.member = obj.member.copy();
41 result ~= obj~"."~member~" = "~obj~"."~member~".copy();";
42 }
43 return result;
44 }
45
46 string doCopy(string[] members)
47 {
48 return doCopy_("x", members);
49 }
50
51 string doCopy(string member)
52 {
53 return doCopy_("x", [member]);
54 }
55
56 // pragma(msg, doCopy("decls?"));
57
58 /// Returns a deep copy of node.
59 T copyNode(T)(T node)
60 {
61 assert(node !is null);
62
63 // Firstly do a shallow copy.
64 T x = cast(T)cast(void*)node.dup;
65
66 // Now copy the subnodes.
67 static if (is(Declaration) && is(T : Declaration))
68 {
69 alias T D;
70 static if (is(D == CompoundDeclaration))
71 mixin(doCopy("decls[]"));
72 //EmptyDeclaration,
73 //IllegalDeclaration,
74 //ModuleDeclaration have no subnodes.
75 static if (is(D == AliasDeclaration) ||
76 is(D == TypedefDeclaration))
77 mixin(doCopy("decl"));
78 static if (is(D == EnumDeclaration))
79 mixin(doCopy(["baseType?", "members[]"]));
80 static if (is(D == EnumMemberDeclaration))
81 mixin(doCopy("value"));
82 static if (is(D == ClassDeclaration) || is( D == InterfaceDeclaration))
83 mixin(doCopy(["bases[]", "decls"]));
84 static if (is(D == StructDeclaration) || is(D == UnionDeclaration))
85 mixin(doCopy("decls"));
86 static if (is(D == ConstructorDeclaration))
87 mixin(doCopy(["params", "funcBody"]));
88 static if (is(D == StaticConstructorDeclaration) ||
89 is(D == DestructorDeclaration) ||
90 is(D == StaticDestructorDeclaration) ||
91 is(D == InvariantDeclaration) ||
92 is(D == UnittestDeclaration))
93 mixin(doCopy("funcBody"));
94 static if (is(D == FunctionDeclaration))
95 mixin(doCopy(["returnType", "params", "funcBody"]));
96 static if (is(D == VariablesDeclaration))
97 {
98 mixin(doCopy("typeNode?"));
99 x.inits = x.inits.dup;
100 foreach(ref init; x.inits)
101 init && (init = init.copy());
102 }
103 static if (is(D == DebugDeclaration) || is(D == VersionDeclaration))
104 mixin(doCopy(["decls?","elseDecls?"]));
105 static if (is(D == StaticIfDeclaration))
106 mixin(doCopy(["condition","ifDecls", "elseDecls?"]));
107 static if (is(D == StaticAssertDeclaration))
108 mixin(doCopy(["condition","message?"]));
109 static if (is(D == TemplateDeclaration))
110 mixin(doCopy(["tparams","decls"]));
111 static if (is(D == NewDeclaration) || is(D == DeleteDeclaration))
112 mixin(doCopy(["params","funcBody"]));
113 static if (is(D == ProtectionDeclaration) ||
114 is(D == StorageClassDeclaration) ||
115 is(D == LinkageDeclaration) ||
116 is(D == AlignDeclaration))
117 mixin(doCopy("decls"));
118 static if (is(D == PragmaDeclaration))
119 mixin(doCopy(["args[]","decls"]));
120 static if (is(D == MixinDeclaration))
121 mixin(doCopy(["templateExpr?","argument?"]));
122 }
123 else
124 static if (is(Expression) && is(T : Expression))
125 {
126 alias T E;
127 static if (is(E == IllegalExpression))
128 {}
129 else
130 static if (is(E == CondExpression))
131 mixin(doCopy(["condition", "lhs", "rhs"]));
132 else
133 static if (is(E : BinaryExpression))
134 mixin(doCopy(["lhs", "rhs"]));
135 else
136 static if (is(E : UnaryExpression))
137 {
138 static if (is(E == CastExpression))
139 mixin(doCopy("type"));
140 mixin(doCopy("e")); // Copy member in base class UnaryExpression.
141 static if (is(E == IndexExpression))
142 mixin(doCopy("args[]"));
143 static if (is(E == SliceExpression))
144 mixin(doCopy(["left?", "right?"]));
145 static if (is(E == AsmPostBracketExpression))
146 mixin(doCopy("e2"));
147 }
148 else
149 {
150 static if (is(E == NewExpression))
151 mixin(doCopy(["newArgs[]", "type", "ctorArgs[]"]));
152 static if (is(E == NewAnonClassExpression))
153 mixin(doCopy(["newArgs[]", "bases[]", "ctorArgs[]", "decls"]));
154 static if (is(E == AsmBracketExpression))
155 mixin(doCopy("e"));
156 static if (is(E == TemplateInstanceExpression))
157 mixin(doCopy("targs?"));
158 static if (is(E == ArrayLiteralExpression))
159 mixin(doCopy("values[]"));
160 static if (is(E == AArrayLiteralExpression))
161 mixin(doCopy(["keys[]", "values[]"]));
162 static if (is(E == AssertExpression))
163 mixin(doCopy(["expr", "msg?"]));
164 static if (is(E == MixinExpression) ||
165 is(E == ImportExpression))
166 mixin(doCopy("expr"));
167 static if (is(E == TypeofExpression) ||
168 is(E == TypeDotIdExpression) ||
169 is(E == TypeidExpression))
170 mixin(doCopy("type"));
171 static if (is(E == IsExpression))
172 mixin(doCopy(["type", "specType?", "tparams?"]));
173 static if (is(E == FunctionLiteralExpression))
174 mixin(doCopy(["returnType?", "params?", "funcBody"]));
175 static if (is(E == ParenExpression))
176 mixin(doCopy("next"));
177 static if (is(E == TraitsExpression))
178 mixin(doCopy("targs"));
179 // VoidInitializer has no subnodes.
180 static if (is(E == ArrayInitExpression))
181 {
182 mixin(doCopy("values[]"));
183 x.keys = x.keys.dup;
184 foreach(ref key; x.keys)
185 key && (key = key.copy());
186 }
187 static if (is(E == StructInitExpression))
188 mixin(doCopy("values[]"));
189 static if (is(E == StringExpression))
190 x.str = x.str.dup;
191 }
192 }
193 else
194 static if (is(Statement) && is(T : Statement))
195 {
196 alias T S;
197 static if (is(S == CompoundStatement))
198 mixin(doCopy("stmnts[]"));
199 //IllegalStatement,
200 //EmptyStatement have no subnodes.
201 static if (is(S == FuncBodyStatement))
202 mixin(doCopy(["funcBody?", "inBody?", "outBody?"]));
203 static if (is(S == ScopeStatement) || is(S == LabeledStatement))
204 mixin(doCopy("s"));
205 static if (is(S == ExpressionStatement))
206 mixin(doCopy("e"));
207 static if (is(S == DeclarationStatement))
208 mixin(doCopy("decl"));
209 static if (is(S == IfStatement))
210 {
211 if (x.variable)
212 mixin(doCopy("variable"));
213 else
214 mixin(doCopy("condition"));
215 mixin(doCopy(["ifBody", "elseBody?"]));
216 }
217 static if (is(S == WhileStatement))
218 mixin(doCopy(["condition", "whileBody"]));
219 static if (is(S == DoWhileStatement))
220 mixin(doCopy(["doBody", "condition"]));
221 static if (is(S == ForStatement))
222 mixin(doCopy(["init?", "condition?", "increment?", "forBody"]));
223 static if (is(S == ForeachStatement))
224 mixin(doCopy(["params", "aggregate", "forBody"]));
225 static if (is(S == ForeachRangeStatement))
226 mixin(doCopy(["params", "lower", "upper", "forBody"]));
227 static if (is(S == SwitchStatement))
228 mixin(doCopy(["condition", "switchBody"]));
229 static if (is(S == CaseStatement))
230 mixin(doCopy(["values[]", "caseBody"]));
231 static if (is(S == DefaultStatement))
232 mixin(doCopy("defaultBody"));
233 //ContinueStatement,
234 //BreakStatement have no subnodes.
235 static if (is(S == ReturnStatement))
236 mixin(doCopy("e?"));
237 static if (is(S == GotoStatement))
238 mixin(doCopy("caseExpr?"));
239 static if (is(S == WithStatement))
240 mixin(doCopy(["e", "withBody"]));
241 static if (is(S == SynchronizedStatement))
242 mixin(doCopy(["e?", "syncBody"]));
243 static if (is(S == TryStatement))
244 mixin(doCopy(["tryBody", "catchBodies[]", "finallyBody?"]));
245 static if (is(S == CatchStatement))
246 mixin(doCopy(["param?", "catchBody"]));
247 static if (is(S == FinallyStatement))
248 mixin(doCopy("finallyBody"));
249 static if (is(S == ScopeGuardStatement))
250 mixin(doCopy("scopeBody"));
251 static if (is(S == ThrowStatement))
252 mixin(doCopy("e"));
253 static if (is(S == VolatileStatement))
254 mixin(doCopy("volatileBody?"));
255 static if (is(S == AsmBlockStatement))
256 mixin(doCopy("statements"));
257 static if (is(S == AsmStatement))
258 mixin(doCopy("operands[]"));
259 //AsmAlignStatement,
260 //IllegalAsmStatement have no subnodes.
261 static if (is(S == PragmaStatement))
262 mixin(doCopy(["args[]", "pragmaBody"]));
263 static if (is(S == MixinStatement))
264 mixin(doCopy("templateExpr"));
265 static if (is(S == StaticIfStatement))
266 mixin(doCopy(["condition", "ifBody", "elseBody?"]));
267 static if (is(S == StaticAssertStatement))
268 mixin(doCopy(["condition", "message?"]));
269 static if (is(S == DebugStatement) || is(S == VersionStatement))
270 mixin(doCopy(["mainBody", "elseBody?"]));
271 }
272 else
273 static if (is(TypeNode) && is(T : TypeNode))
274 {
275 //IllegalType,
276 //IntegralType,
277 //ModuleScopeType,
278 //IdentifierType have no subnodes.
279 static if (is(T == QualifiedType))
280 mixin(doCopy(["lhs", "rhs"]));
281 static if (is(T == TypeofType))
282 mixin(doCopy("e"));
283 static if (is(T == TemplateInstanceType))
284 mixin(doCopy("targs?"));
285 static if (is(T == PointerType))
286 mixin(doCopy("next"));
287 static if (is(T == ArrayType))
288 mixin(doCopy(["next", "assocType?", "e1?", "e2?"]));
289 static if (is(T == FunctionType) || is(T == DelegateType))
290 mixin(doCopy(["returnType", "params"]));
291 static if (is(T == CFuncPointerType))
292 mixin(doCopy(["next", "params?"]));
293 static if (is(T == BaseClassType) ||
294 is(T == ConstType) ||
295 is(T == InvariantType))
296 mixin(doCopy("next"));
297 }
298 else
299 static if (is(Parameter) && is(T == Parameter))
300 {
301 mixin(doCopy(["type?", "defValue?"]));
302 }
303 else
304 static if (is(Parameter) && is(T == Parameters) ||
305 is(TemplateParameter) && is(T == TemplateParameters) ||
306 is(TemplateArguments) && is(T == TemplateArguments))
307 {
308 mixin(doCopy("children[]"));
309 }
310 else
311 static if (is(TemplateParameter) && is(T : TemplateParameter))
312 {
313 static if (is(N == TemplateAliasParameter) ||
314 is(N == TemplateTypeParameter) ||
315 is(N == TemplateThisParameter))
316 mixin(doCopy(["specType", "defType"]));
317 static if (is(N == TemplateValueParameter))
318 mixin(doCopy(["valueType", "specValue?", "defValue?"]));
319 //TemplateTupleParameter has no subnodes.
320 }
321 else
322 static assert(0, "copying of "~typeof(x).stringof~" is not handled");
323 return x;
324 }