1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // This file contains the implementations of the Accept methods for the AST
6 // nodes.  Generally, all they do is invoke the appropriate TreeVisitor method
7 // for each field of the node.
8 
9 #include "banjo/raw_ast.h"
10 #include "banjo/tree_visitor.h"
11 
12 namespace banjo {
13 namespace raw {
14 
SourceElementMark(TreeVisitor & tv,const SourceElement & element)15 SourceElementMark::SourceElementMark(TreeVisitor& tv,
16                                      const SourceElement& element)
17     : tv_(tv), element_(element) {
18     tv_.OnSourceElementStart(element_);
19 }
20 
~SourceElementMark()21 SourceElementMark::~SourceElementMark() {
22     tv_.OnSourceElementEnd(element_);
23 }
24 
Accept(TreeVisitor & visitor)25 void CompoundIdentifier::Accept(TreeVisitor& visitor) {
26     SourceElementMark sem(visitor, *this);
27     for (auto i = components.begin(); i != components.end(); ++i) {
28         visitor.OnIdentifier(*i);
29     }
30 }
31 
Accept(TreeVisitor & visitor)32 void StringLiteral::Accept(TreeVisitor& visitor) {
33     SourceElementMark sem(visitor, *this);
34 }
35 
Accept(TreeVisitor & visitor)36 void NumericLiteral::Accept(TreeVisitor& visitor) {
37     SourceElementMark sem(visitor, *this);
38 }
39 
Accept(TreeVisitor & visitor)40 void TrueLiteral::Accept(TreeVisitor& visitor) {
41     SourceElementMark sem(visitor, *this);
42 }
43 
Accept(TreeVisitor & visitor)44 void FalseLiteral::Accept(TreeVisitor& visitor) {
45     SourceElementMark sem(visitor, *this);
46 }
47 
Accept(TreeVisitor & visitor)48 void IdentifierConstant::Accept(TreeVisitor& visitor) {
49     SourceElementMark sem(visitor, *this);
50     visitor.OnCompoundIdentifier(identifier);
51 }
52 
Accept(TreeVisitor & visitor)53 void LiteralConstant::Accept(TreeVisitor& visitor) {
54     SourceElementMark sem(visitor, *this);
55     visitor.OnLiteral(literal);
56 }
57 
Accept(TreeVisitor & visitor)58 void Attribute::Accept(TreeVisitor& visitor) {
59     SourceElementMark sem(visitor, *this);
60 }
61 
Accept(TreeVisitor & visitor)62 void AttributeList::Accept(TreeVisitor& visitor) {
63     SourceElementMark sem(visitor, *this);
64     for (auto i = attributes_->attributes_.begin(); i != attributes_->attributes_.end(); ++i) {
65         visitor.OnAttribute(*i);
66     }
67 }
68 
Accept(TreeVisitor & visitor)69 void ArrayType::Accept(TreeVisitor& visitor) {
70     SourceElementMark sem(visitor, *this);
71     visitor.OnType(element_type);
72     visitor.OnConstant(element_count);
73 }
74 
Accept(TreeVisitor & visitor)75 void VectorType::Accept(TreeVisitor& visitor) {
76     SourceElementMark sem(visitor, *this);
77     visitor.OnType(element_type);
78     if (maybe_element_count != nullptr) {
79         visitor.OnConstant(maybe_element_count);
80     }
81     visitor.OnNullability(nullability);
82 }
83 
Accept(TreeVisitor & visitor)84 void StringType::Accept(TreeVisitor& visitor) {
85     SourceElementMark sem(visitor, *this);
86     if (maybe_element_count != nullptr) {
87         visitor.OnConstant(maybe_element_count);
88     }
89 
90     visitor.OnNullability(nullability);
91 }
92 
Accept(TreeVisitor & visitor)93 void HandleType::Accept(TreeVisitor& visitor) {
94     SourceElementMark sem(visitor, *this);
95     visitor.OnHandleSubtype(subtype);
96     visitor.OnNullability(nullability);
97 }
98 
Accept(TreeVisitor & visitor)99 void RequestHandleType::Accept(TreeVisitor& visitor) {
100     SourceElementMark sem(visitor, *this);
101     visitor.OnCompoundIdentifier(identifier);
102     visitor.OnNullability(nullability);
103 }
104 
Accept(TreeVisitor & visitor)105 void PrimitiveType::Accept(TreeVisitor& visitor) {
106     SourceElementMark sem(visitor, *this);
107     visitor.OnPrimitiveSubtype(subtype);
108 }
109 
Accept(TreeVisitor & visitor)110 void IdentifierType::Accept(TreeVisitor& visitor) {
111     SourceElementMark sem(visitor, *this);
112     visitor.OnCompoundIdentifier(identifier);
113     visitor.OnNullability(nullability);
114 }
115 
Accept(TreeVisitor & visitor)116 void Using::Accept(TreeVisitor& visitor) {
117     SourceElementMark sem(visitor, *this);
118     visitor.OnCompoundIdentifier(using_path);
119     if (maybe_alias != nullptr) {
120         visitor.OnIdentifier(maybe_alias);
121     }
122     if (maybe_primitive != nullptr) {
123         visitor.OnPrimitiveType(maybe_primitive);
124     }
125 }
126 
Accept(TreeVisitor & visitor)127 void ConstDeclaration::Accept(TreeVisitor& visitor) {
128     SourceElementMark sem(visitor, *this);
129     if (attributes != nullptr) {
130         visitor.OnAttributeList(attributes);
131     }
132     visitor.OnType(type);
133     visitor.OnIdentifier(identifier);
134     visitor.OnConstant(constant);
135 }
136 
Accept(TreeVisitor & visitor)137 void EnumMember::Accept(TreeVisitor& visitor) {
138     SourceElementMark sem(visitor, *this);
139     if (attributes != nullptr) {
140         visitor.OnAttributeList(attributes);
141     }
142     visitor.OnIdentifier(identifier);
143     visitor.OnConstant(value);
144 }
145 
Accept(TreeVisitor & visitor)146 void EnumDeclaration::Accept(TreeVisitor& visitor) {
147     SourceElementMark sem(visitor, *this);
148     if (attributes != nullptr) {
149         visitor.OnAttributeList(attributes);
150     }
151     visitor.OnIdentifier(identifier);
152     if (maybe_subtype != nullptr) {
153         visitor.OnPrimitiveType(maybe_subtype);
154     }
155     for (auto member = members.begin(); member != members.end(); ++member) {
156         visitor.OnEnumMember(*member);
157     }
158 }
159 
Accept(TreeVisitor & visitor)160 void Parameter::Accept(TreeVisitor& visitor) {
161     SourceElementMark sem(visitor, *this);
162     visitor.OnType(type);
163     visitor.OnIdentifier(identifier);
164 }
165 
Accept(TreeVisitor & visitor)166 void ParameterList::Accept(TreeVisitor& visitor) {
167     SourceElementMark sem(visitor, *this);
168     for (auto parameter = parameter_list.begin(); parameter != parameter_list.end(); ++parameter) {
169         visitor.OnParameter(*parameter);
170     }
171 }
172 
Accept(TreeVisitor & visitor)173 void InterfaceMethod::Accept(TreeVisitor& visitor) {
174     SourceElementMark sem(visitor, *this);
175     if (attributes != nullptr) {
176         visitor.OnAttributeList(attributes);
177     }
178     visitor.OnIdentifier(identifier);
179     if (maybe_request != nullptr) {
180         visitor.OnParameterList(maybe_request);
181     }
182     if (maybe_response != nullptr) {
183         visitor.OnParameterList(maybe_response);
184     }
185 }
186 
Accept(TreeVisitor & visitor)187 void InterfaceDeclaration::Accept(TreeVisitor& visitor) {
188     SourceElementMark sem(visitor, *this);
189     if (attributes != nullptr) {
190         visitor.OnAttributeList(attributes);
191     }
192     visitor.OnIdentifier(identifier);
193     for (auto superinterface = superinterfaces.begin();
194          superinterface != superinterfaces.end();
195          ++superinterface) {
196         visitor.OnCompoundIdentifier(*superinterface);
197     }
198     for (auto method = methods.begin();
199          method != methods.end();
200          ++method) {
201         visitor.OnInterfaceMethod(*method);
202     }
203 }
204 
Accept(TreeVisitor & visitor)205 void StructMember::Accept(TreeVisitor& visitor) {
206     SourceElementMark sem(visitor, *this);
207     if (attributes != nullptr) {
208         visitor.OnAttributeList(attributes);
209     }
210     visitor.OnType(type);
211     visitor.OnIdentifier(identifier);
212     if (maybe_default_value != nullptr) {
213         visitor.OnConstant(maybe_default_value);
214     }
215 }
216 
Accept(TreeVisitor & visitor)217 void StructDeclaration::Accept(TreeVisitor& visitor) {
218     SourceElementMark sem(visitor, *this);
219     if (attributes != nullptr) {
220         visitor.OnAttributeList(attributes);
221     }
222     visitor.OnIdentifier(identifier);
223     for (auto member = members.begin();
224          member != members.end();
225          ++member) {
226         visitor.OnStructMember(*member);
227     }
228 }
229 
Accept(TreeVisitor & visitor)230 void UnionMember::Accept(TreeVisitor& visitor) {
231     SourceElementMark sem(visitor, *this);
232     if (attributes != nullptr) {
233         visitor.OnAttributeList(attributes);
234     }
235     visitor.OnType(type);
236     visitor.OnIdentifier(identifier);
237 }
238 
Accept(TreeVisitor & visitor)239 void UnionDeclaration::Accept(TreeVisitor& visitor) {
240     SourceElementMark sem(visitor, *this);
241     if (attributes != nullptr) {
242         visitor.OnAttributeList(attributes);
243     }
244     visitor.OnIdentifier(identifier);
245     for (auto member = members.begin();
246          member != members.end();
247          ++member) {
248         visitor.OnUnionMember(*member);
249     }
250 }
251 
Accept(TreeVisitor & visitor)252 void File::Accept(TreeVisitor& visitor) {
253     SourceElementMark sem(visitor, *this);
254     visitor.OnCompoundIdentifier(library_name);
255     for (auto i = using_list.begin();
256          i != using_list.end();
257          ++i) {
258         visitor.OnUsing(*i);
259     }
260     for (auto i = const_declaration_list.begin();
261          i != const_declaration_list.end();
262          ++i) {
263         visitor.OnConstDeclaration(*i);
264     }
265     for (auto i = enum_declaration_list.begin();
266          i != enum_declaration_list.end();
267          ++i) {
268         visitor.OnEnumDeclaration(*i);
269     }
270     for (auto i = interface_declaration_list.begin();
271          i != interface_declaration_list.end();
272          ++i) {
273         visitor.OnInterfaceDeclaration(*i);
274     }
275     for (auto i = struct_declaration_list.begin();
276          i != struct_declaration_list.end();
277          ++i) {
278         visitor.OnStructDeclaration(*i);
279     }
280     for (auto i = union_declaration_list.begin();
281          i != union_declaration_list.end();
282          ++i) {
283         visitor.OnUnionDeclaration(*i);
284     }
285 }
286 
287 } // namespace raw
288 } // namespace banjo
289