1
/**
2
 * Provides a depth-first statement visitor.
3
 *
4
 * Copyright:   Copyright (C) 1999-2020 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/sparse.d, _sparse.d)
8
 * Documentation:  https://dlang.org/phobos/dmd_sapply.html
9
 * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/sapply.d
10
 */
11

12
module dmd.sapply;
13

14
import dmd.statement;
15
import dmd.visitor;
16

17
/**************************************
18
 * A Statement tree walker that will visit each Statement s in the tree,
19
 * in depth-first evaluation order, and call fp(s,param) on it.
20
 * fp() signals whether the walking continues with its return value:
21
 * Returns:
22
 *      0       continue
23
 *      1       done
24
 * It's a bit slower than using virtual functions, but more encapsulated and less brittle.
25
 * Creating an iterator for this would be much more complex.
26
 */
27
extern (C++) final class PostorderStatementVisitor : StoppableVisitor
28
{
29
    alias visit = typeof(super).visit;
30
public:
31
    StoppableVisitor v;
32

33 1
    extern (D) this(StoppableVisitor v)
34
    {
35 1
        this.v = v;
36
    }
37

38
    bool doCond(Statement s)
39
    {
40 1
        if (!stop && s)
41 1
            s.accept(this);
42 1
        return stop;
43
    }
44

45
    bool applyTo(Statement s)
46
    {
47 1
        s.accept(v);
48 1
        stop = v.stop;
49 1
        return true;
50
    }
51

52
    override void visit(Statement s)
53
    {
54 1
        applyTo(s);
55
    }
56

57
    override void visit(PeelStatement s)
58
    {
59 0
        doCond(s.s) || applyTo(s);
60
    }
61

62
    override void visit(CompoundStatement s)
63
    {
64 1
        for (size_t i = 0; i < s.statements.dim; i++)
65 1
            if (doCond((*s.statements)[i]))
66 1
                return;
67 1
        applyTo(s);
68
    }
69

70
    override void visit(UnrolledLoopStatement s)
71
    {
72 1
        for (size_t i = 0; i < s.statements.dim; i++)
73 1
            if (doCond((*s.statements)[i]))
74 1
                return;
75 0
        applyTo(s);
76
    }
77

78
    override void visit(ScopeStatement s)
79
    {
80 1
        doCond(s.statement) || applyTo(s);
81
    }
82

83
    override void visit(WhileStatement s)
84
    {
85 0
        doCond(s._body) || applyTo(s);
86
    }
87

88
    override void visit(DoStatement s)
89
    {
90 1
        doCond(s._body) || applyTo(s);
91
    }
92

93
    override void visit(ForStatement s)
94
    {
95 1
        doCond(s._init) || doCond(s._body) || applyTo(s);
96
    }
97

98
    override void visit(ForeachStatement s)
99
    {
100 0
        doCond(s._body) || applyTo(s);
101
    }
102

103
    override void visit(ForeachRangeStatement s)
104
    {
105 0
        doCond(s._body) || applyTo(s);
106
    }
107

108
    override void visit(IfStatement s)
109
    {
110 1
        doCond(s.ifbody) || doCond(s.elsebody) || applyTo(s);
111
    }
112

113
    override void visit(PragmaStatement s)
114
    {
115 0
        doCond(s._body) || applyTo(s);
116
    }
117

118
    override void visit(SwitchStatement s)
119
    {
120 1
        doCond(s._body) || applyTo(s);
121
    }
122

123
    override void visit(CaseStatement s)
124
    {
125 1
        doCond(s.statement) || applyTo(s);
126
    }
127

128
    override void visit(DefaultStatement s)
129
    {
130 1
        doCond(s.statement) || applyTo(s);
131
    }
132

133
    override void visit(SynchronizedStatement s)
134
    {
135 0
        doCond(s._body) || applyTo(s);
136
    }
137

138
    override void visit(WithStatement s)
139
    {
140 1
        doCond(s._body) || applyTo(s);
141
    }
142

143
    override void visit(TryCatchStatement s)
144
    {
145 1
        if (doCond(s._body))
146 1
            return;
147 1
        for (size_t i = 0; i < s.catches.dim; i++)
148 1
            if (doCond((*s.catches)[i].handler))
149 1
                return;
150 1
        applyTo(s);
151
    }
152

153
    override void visit(TryFinallyStatement s)
154
    {
155 1
        doCond(s._body) || doCond(s.finalbody) || applyTo(s);
156
    }
157

158
    override void visit(ScopeGuardStatement s)
159
    {
160 0
        doCond(s.statement) || applyTo(s);
161
    }
162

163
    override void visit(DebugStatement s)
164
    {
165 0
        doCond(s.statement) || applyTo(s);
166
    }
167

168
    override void visit(LabelStatement s)
169
    {
170 1
        doCond(s.statement) || applyTo(s);
171
    }
172
}
173

174
bool walkPostorder(Statement s, StoppableVisitor v)
175
{
176 1
    scope PostorderStatementVisitor pv = new PostorderStatementVisitor(v);
177 1
    s.accept(pv);
178 1
    return v.stop;
179
}

Read our documentation on viewing source code .

Loading