2 * A depth-first visitor for expressions.
4 * Copyright: Copyright (C) 1999-2024 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/apply.d, _apply.d)
8 * Documentation: https://dlang.org/phobos/dmd_apply.html
9 * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/apply.d
12 module dmd
.postordervisitor
;
14 import dmd
.arraytypes
;
16 import dmd
.expression
;
17 import dmd
.root
.array
;
20 bool walkPostorder(Expression e
, StoppableVisitor v
)
22 scope PostorderExpressionVisitor pv
= new PostorderExpressionVisitor(v
);
27 /**************************************
28 * An Expression tree walker that will visit each Expression e in the tree,
29 * in depth-first evaluation order, and call fp(e,param) on it.
30 * fp() signals whether the walking continues with its return value:
34 * It's a bit slower than using virtual functions, but more encapsulated and less brittle.
35 * Creating an iterator for this would be much more complex.
37 private extern (C
++) final class PostorderExpressionVisitor
: StoppableVisitor
39 alias visit
= typeof(super).visit
;
43 extern (D
) this(StoppableVisitor v
) scope @safe
48 bool doCond(Expression e
)
55 extern(D
) bool doCond(Expression
[] e
)
57 for (size_t i
= 0; i
< e
.length
&& !stop
; i
++)
62 bool applyTo(Expression e
)
69 override void visit(Expression e
)
74 override void visit(NewExp e
)
76 //printf("NewExp::apply(): %s\n", toChars());
77 doCond(e
.thisexp
) ||
doCond(e
.arguments
.peekSlice()) ||
applyTo(e
);
80 override void visit(NewAnonClassExp e
)
82 //printf("NewAnonClassExp::apply(): %s\n", toChars());
83 doCond(e
.thisexp
) ||
doCond(e
.arguments
.peekSlice()) ||
applyTo(e
);
86 override void visit(TypeidExp e
)
88 doCond(isExpression(e
.obj
)) ||
applyTo(e
);
91 override void visit(UnaExp e
)
93 doCond(e
.e1
) ||
applyTo(e
);
96 override void visit(BinExp e
)
98 doCond(e
.e1
) ||
doCond(e
.e2
) ||
applyTo(e
);
101 override void visit(AssertExp e
)
103 //printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
104 doCond(e
.e1
) ||
doCond(e
.msg
) ||
applyTo(e
);
107 override void visit(CallExp e
)
109 //printf("CallExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
110 doCond(e
.e1
) ||
doCond(e
.arguments
.peekSlice()) ||
applyTo(e
);
113 override void visit(ArrayExp e
)
115 //printf("ArrayExp::apply(apply_fp_t fp, void *param): %s\n", toChars());
116 doCond(e
.e1
) ||
doCond(e
.arguments
.peekSlice()) ||
applyTo(e
);
119 override void visit(SliceExp e
)
121 doCond(e
.e1
) ||
doCond(e
.lwr
) ||
doCond(e
.upr
) ||
applyTo(e
);
124 override void visit(ArrayLiteralExp e
)
126 doCond(e
.basis
) ||
doCond(e
.elements
.peekSlice()) ||
applyTo(e
);
129 override void visit(AssocArrayLiteralExp e
)
131 doCond(e
.keys
.peekSlice()) ||
doCond(e
.values
.peekSlice()) ||
applyTo(e
);
134 override void visit(StructLiteralExp e
)
136 if (e
.stageflags
& stageApply
)
138 const old
= e
.stageflags
;
139 e
.stageflags |
= stageApply
;
140 doCond(e
.elements
.peekSlice()) ||
applyTo(e
);
144 override void visit(TupleExp e
)
146 doCond(e
.e0
) ||
doCond(e
.exps
.peekSlice()) ||
applyTo(e
);
149 override void visit(CondExp e
)
151 doCond(e
.econd
) ||
doCond(e
.e1
) ||
doCond(e
.e2
) ||
applyTo(e
);