1
2
3
4
5
6 #include <cmajor/binder/XmlAttributeProcessor.hpp>
7 #include <cmajor/binder/BoundCompileUnit.hpp>
8 #include <cmajor/binder/TypeResolver.hpp>
9 #include <cmajor/binder/StatementBinder.hpp>
10 #include <cmajor/binder/TypeBinder.hpp>
11 #include <cmajor/binder/BoundClass.hpp>
12 #include <cmajor/binder/BoundFunction.hpp>
13 #include <cmajor/symbols/Exception.hpp>
14 #include <cmajor/symbols/SymbolCreatorVisitor.hpp>
15 #include <sngcm/ast/TypeExpr.hpp>
16 #include <sngcm/ast/Expression.hpp>
17 #include <sngcm/ast/Literal.hpp>
18 #include <soulng/util/Unicode.hpp>
19
20 namespace cmajor { namespace binder {
21
22 using namespace soulng::unicode;
23 using namespace cmajor::symbols;
24
25 XmlAttributeProcessor::XmlAttributeProcessor() : AttributeProcessor(U"xml")
26 {
27 }
28
29 void XmlAttributeProcessor::TypeCheck(AttributeNode* attribute, Symbol* symbol)
30 {
31 switch (symbol->GetSymbolType())
32 {
33 case SymbolType::classTypeSymbol: case SymbolType::classTemplateSpecializationSymbol: case SymbolType::memberVariableSymbol:
34 {
35 if (attribute->Value() == U"true" || attribute->Value() == U"false")
36 {
37 return;
38 }
39 else
40 {
41 throw Exception("unknown attribute value '" + ToUtf8(attribute->Value()) + "' for attribute '" + ToUtf8(attribute->Name()) + "'", attribute->GetSpan(), attribute->ModuleId());
42 }
43 break;
44 }
45 }
46 AttributeProcessor::TypeCheck(attribute, symbol);
47 }
48
49 void XmlAttributeProcessor::GenerateSymbols(AttributeNode* attribute, Symbol* symbol, BoundCompileUnit& boundCompileUnit, ContainerScope* containerScope)
50 {
51 if (symbol->IsClassTypeSymbol())
52 {
53 ClassTypeSymbol* classTypeSymbol = static_cast<ClassTypeSymbol*>(symbol);
54 if (attribute->Value() == U"true")
55 {
56 GenerateToXmlSymbol(attribute, classTypeSymbol, boundCompileUnit, containerScope);
57 GenerateSystemDomElementConstructorSymbol(attribute, classTypeSymbol, boundCompileUnit, containerScope);
58 }
59 }
60 }
61
62 void XmlAttributeProcessor::GenerateImplementation(AttributeNode* attribute, Symbol* symbol, StatementBinder* statementBinder)
63 {
64 if (symbol->IsClassTypeSymbol())
65 {
66 ClassTypeSymbol* classTypeSymbol = static_cast<ClassTypeSymbol*>(symbol);
67 auto toXmlIt = toXmlMemberFunctionSymbolMap.find(symbol);
68 if (toXmlIt != toXmlMemberFunctionSymbolMap.cend())
69 {
70 MemberFunctionSymbol* toXmlMemberFunctionSymbol = toXmlIt->second;
71 GenerateToXmlMemberFunctionImplementation(attribute, classTypeSymbol, toXmlMemberFunctionSymbol, statementBinder);
72 }
73 else
74 {
75 throw Exception("internal error in XML attribute implementation: member function 'ToXml' symbol for symbol '" + ToUtf8(symbol->FullName()) + "' not found", attribute->GetSpan(), attribute->ModuleId());
76 }
77 auto contructorIt = constructorSymbolMap.find(symbol);
78 if (contructorIt != constructorSymbolMap.cend())
79 {
80 ConstructorSymbol* constructorSymbol = contructorIt->second;
81 GenerateSystemDomElementConstructorImplementation(attribute, classTypeSymbol, constructorSymbol, statementBinder);
82 }
83 else
84 {
85 throw Exception("internal error in XML attribute implementation: constructor symbol for symbol '" + ToUtf8(symbol->FullName()) + "' not found", attribute->GetSpan(), attribute->ModuleId());
86 }
87 }
88 }
89
90 void XmlAttributeProcessor::GenerateToXmlSymbol(AttributeNode* attribute, ClassTypeSymbol* classTypeSymbol, BoundCompileUnit& boundCompileUnit, ContainerScope* containerScope)
91 {
92 MemberFunctionSymbol* toXmlMemberFunctionSymbol = new MemberFunctionSymbol(attribute->GetSpan(), attribute->ModuleId(), U"ToXml");
93 toXmlMemberFunctionSymbol->SetModule(&boundCompileUnit.GetModule());
94 toXmlMemberFunctionSymbol->SetGroupName(U"ToXml");
95 if (classTypeSymbol->BaseClass())
96 {
97 toXmlMemberFunctionSymbol->SetOverride();
98 }
99 else if (classTypeSymbol->Destructor() && classTypeSymbol->Destructor()->IsVirtual())
100 {
101 toXmlMemberFunctionSymbol->SetVirtual();
102 }
103 GetRootModuleForCurrentThread()->GetSymbolTable().SetFunctionIdFor(toXmlMemberFunctionSymbol);
104 ParameterSymbol* thisParam = new ParameterSymbol(attribute->GetSpan(), attribute->ModuleId(), U"this");
105 thisParam->SetType(classTypeSymbol->AddPointer(attribute->GetSpan(), attribute->ModuleId()));
106 ParameterSymbol* fieldNameParam = new ParameterSymbol(attribute->GetSpan(), attribute->ModuleId(), U"fieldName");
107 IdentifierNode * stringIdNode(new IdentifierNode(attribute->GetSpan(), attribute->ModuleId(), U"System.string"));
108 Node * refNode(new LValueRefNode(attribute->GetSpan(), attribute->ModuleId(), stringIdNode));
109 std::unique_ptr<Node> constNode(new ConstNode(attribute->GetSpan(), attribute->ModuleId(), refNode));
110 TypeSymbol* stringType = ResolveType(constNode.get(), boundCompileUnit, containerScope);
111 fieldNameParam->SetType(stringType);
112 TemplateIdNode templateId(attribute->GetSpan(), attribute->ModuleId(), new IdentifierNode(attribute->GetSpan(), attribute->ModuleId(), U"System.UniquePtr"));
113 templateId.AddTemplateArgument(new IdentifierNode(attribute->GetSpan(), attribute->ModuleId(), U"System.Dom.Element"));
114 TypeSymbol* uniquePtrElementType = ResolveType(&templateId, boundCompileUnit, containerScope);
115 toXmlMemberFunctionSymbol->SetReturnType(uniquePtrElementType);
116 ParameterSymbol* returnParam = new ParameterSymbol(attribute->GetSpan(), attribute->ModuleId(), U"@return");
117 returnParam->SetParent(toXmlMemberFunctionSymbol);
118 returnParam->SetType(uniquePtrElementType->AddPointer(attribute->GetSpan(), attribute->ModuleId()));
119 toXmlMemberFunctionSymbol->SetReturnParam(returnParam);
120 toXmlMemberFunctionSymbol->SetAccess(SymbolAccess::public_);
121 toXmlMemberFunctionSymbol->AddMember(thisParam);
122 toXmlMemberFunctionSymbol->AddMember(fieldNameParam);
123 classTypeSymbol->AddMember(toXmlMemberFunctionSymbol);
124 toXmlMemberFunctionSymbol->ComputeName();
125 toXmlMemberFunctionSymbolMap[classTypeSymbol] = toXmlMemberFunctionSymbol;
126 }
127
128 void XmlAttributeProcessor::GenerateSystemDomElementConstructorSymbol(AttributeNode* attribute, ClassTypeSymbol* classTypeSymbol, BoundCompileUnit& boundCompileUnit, ContainerScope* containerScope)
129 {
130 ConstructorSymbol* constructorSymbol = new ConstructorSymbol(attribute->GetSpan(), attribute->ModuleId(), U"@constructor");
131 constructorSymbol->SetModule(&boundCompileUnit.GetModule());
132 constructorSymbol->SetGroupName(U"@constructor");
133 GetRootModuleForCurrentThread()->GetSymbolTable().SetFunctionIdFor(constructorSymbol);
134 ParameterSymbol* thisParam = new ParameterSymbol(attribute->GetSpan(), attribute->ModuleId(), U"this");
135 thisParam->SetType(classTypeSymbol->AddPointer(attribute->GetSpan(), attribute->ModuleId()));
136 ParameterSymbol* elementParam = new ParameterSymbol(attribute->GetSpan(), attribute->ModuleId(), U"@element");
137 std::unique_ptr<PointerNode> pointertNode(new PointerNode(attribute->GetSpan(), attribute->ModuleId(), new IdentifierNode(attribute->GetSpan(), attribute->ModuleId(), U"System.Dom.Element")));
138 TypeSymbol* elementType = ResolveType(pointertNode.get(), boundCompileUnit, containerScope);
139 elementParam->SetType(elementType);
140 constructorSymbol->SetAccess(SymbolAccess::public_);
141 constructorSymbol->AddMember(thisParam);
142 constructorSymbol->AddMember(elementParam);
143 classTypeSymbol->AddMember(constructorSymbol);
144 constructorSymbol->ComputeName();
145 constructorSymbolMap[classTypeSymbol] = constructorSymbol;
146 }
147
148 void XmlAttributeProcessor::GenerateToXmlMemberFunctionImplementation(AttributeNode* attribute, ClassTypeSymbol* classTypeSymbol, MemberFunctionSymbol* toXmlMemberFunctionSymbol,
149 StatementBinder* statementBinder)
150 {
151 try
152 {
153 FileScope* fileScope = new FileScope();
154 Symbol* systemDomElement = GetRootModuleForCurrentThread()->GetSymbolTable().GlobalNs().GetContainerScope()->Lookup(U"System.Dom.Element");
155 if (systemDomElement)
156 {
157 fileScope->AddContainerScope(systemDomElement->Ns()->GetContainerScope());
158 }
159 statementBinder->GetBoundCompileUnit().AddFileScope(fileScope);
160 std::unique_ptr<BoundFunction> boundFunction(new BoundFunction(&statementBinder->GetBoundCompileUnit(), toXmlMemberFunctionSymbol));
161 Span span = attribute->GetSpan();
162 boost::uuids::uuid moduleId = attribute->ModuleId();
163 CompoundStatementNode compoundStatementNode(span, moduleId);
164 compoundStatementNode.SetEndBraceSpan(span);
165
166 TemplateIdNode* uniquePtrSystemDomElement = new TemplateIdNode(span, moduleId, new IdentifierNode(span, moduleId, U"System.UniquePtr"));
167 uniquePtrSystemDomElement->AddTemplateArgument(new IdentifierNode(span, moduleId, U"System.Dom.Element"));
168 ConstructionStatementNode* constructSystemDomElementStatement = new ConstructionStatementNode(span, moduleId, uniquePtrSystemDomElement, new IdentifierNode(span, moduleId, U"@element"));
169 NewNode* newNode = new NewNode(span, moduleId, new IdentifierNode(span, moduleId, U"System.Dom.Element"));
170 InvokeNode* toUtf32Node = new InvokeNode(span, moduleId, new IdentifierNode(span, moduleId, U"System.ToUtf32"));
171 toUtf32Node->AddArgument(new IdentifierNode(span, moduleId, U"fieldName"));
172 newNode->AddArgument(toUtf32Node);
173 constructSystemDomElementStatement->AddArgument(newNode);
174 compoundStatementNode.AddStatement(constructSystemDomElementStatement);
175
176 if (classTypeSymbol->BaseClass())
177 {
178 ClassTypeSymbol* baseClassSymbol = classTypeSymbol->BaseClass();
179 AttributesNode* attributes = baseClassSymbol->GetAttributes();
180 if (attributes)
181 {
182 AttributeNode* xmlAttribute = attributes->GetAttribute(U"xml");
183 if (xmlAttribute)
184 {
185 if (xmlAttribute->Value() == U"true")
186 {
187 Span span = classTypeSymbol->BaseClass()->GetSpan();
188 boost::uuids::uuid moduleId = classTypeSymbol->SourceModuleId();
189 BaseNode* baseNode = new BaseNode(span, moduleId);
190 ArrowNode* arrowNode = new ArrowNode(span, moduleId, baseNode, new IdentifierNode(span, moduleId, U"ToXml"));
191 InvokeNode* toXmlInvokeNode = new InvokeNode(span, moduleId, arrowNode);
192 toXmlInvokeNode->AddArgument(new StringLiteralNode(span, moduleId, "base"));
193 DotNode* dotNode = new DotNode(span, moduleId, toXmlInvokeNode, new IdentifierNode(span, moduleId, U"Release"));
194 InvokeNode* dotInvokeNode = new InvokeNode(span, moduleId, dotNode);
195 TemplateIdNode* uniquePtrNode = new TemplateIdNode(span, moduleId, new IdentifierNode(span, moduleId, U"System.UniquePtr"));
196 uniquePtrNode->AddTemplateArgument(new IdentifierNode(span, moduleId, U"System.Dom.Node"));
197 InvokeNode* uniquePtrNodeInvokeNode = new InvokeNode(span, moduleId, uniquePtrNode);
198 uniquePtrNodeInvokeNode->AddArgument(dotInvokeNode);
199 ArrowNode* appendChildArrowNode = new ArrowNode(span, moduleId, new IdentifierNode(span, moduleId, U"@element"), new IdentifierNode(span, moduleId, U"AppendChild"));
200 InvokeNode* appendChildInvokeNode = new InvokeNode(span, moduleId, appendChildArrowNode);
201 appendChildInvokeNode->AddArgument(uniquePtrNodeInvokeNode);
202 ExpressionStatementNode* appendChildStatement = new ExpressionStatementNode(span, moduleId, appendChildInvokeNode);
203 compoundStatementNode.AddStatement(appendChildStatement);
204 }
205 }
206 }
207 }
208
209 for (MemberVariableSymbol* memberVariableSymbol : classTypeSymbol->MemberVariables())
210 {
211 AttributesNode* attributes = memberVariableSymbol->GetAttributes();
212 if (attributes)
213 {
214 AttributeNode* xmlAttribute = attributes->GetAttribute(U"xml");
215 if (xmlAttribute)
216 {
217 if (xmlAttribute->Value() == U"false")
218 {
219 continue;
220 }
221 }
222 }
223 InvokeNode* toXmlInvokeNode = new InvokeNode(memberVariableSymbol->GetSpan(), memberVariableSymbol->SourceModuleId(), new IdentifierNode(span, moduleId, U"ToXml"));
224 toXmlInvokeNode->AddArgument(new IdentifierNode(memberVariableSymbol->GetSpan(), memberVariableSymbol->SourceModuleId(), memberVariableSymbol->Name()));
225 toXmlInvokeNode->AddArgument(new StringLiteralNode(memberVariableSymbol->GetSpan(), memberVariableSymbol->SourceModuleId(), ToUtf8(memberVariableSymbol->Name())));
226 DotNode* dotNode = new DotNode(memberVariableSymbol->GetSpan(), memberVariableSymbol->SourceModuleId(), toXmlInvokeNode, new IdentifierNode(
227 memberVariableSymbol->GetSpan(), memberVariableSymbol->SourceModuleId(), U"Release"));
228 InvokeNode* dotInvokeNode = new InvokeNode(memberVariableSymbol->GetSpan(), memberVariableSymbol->SourceModuleId(), dotNode);
229 TemplateIdNode* uniquePtrNode = new TemplateIdNode(memberVariableSymbol->GetSpan(), memberVariableSymbol->SourceModuleId(),
230 new IdentifierNode(memberVariableSymbol->GetSpan(), memberVariableSymbol->SourceModuleId(), U"System.UniquePtr"));
231 uniquePtrNode->AddTemplateArgument(new IdentifierNode(memberVariableSymbol->GetSpan(), memberVariableSymbol->SourceModuleId(),
232 U"System.Dom.Node"));
233 InvokeNode* uniquePtrNodeInvokeNode = new InvokeNode(memberVariableSymbol->GetSpan(), memberVariableSymbol->SourceModuleId(), uniquePtrNode);
234 uniquePtrNodeInvokeNode->AddArgument(dotInvokeNode);
235 ArrowNode* appendChildArrowNode = new ArrowNode(span, moduleId, new IdentifierNode(span, moduleId, U"@element"), new IdentifierNode(span, moduleId, U"AppendChild"));
236 InvokeNode* appendChildInvokeNode = new InvokeNode(span, moduleId, appendChildArrowNode);
237 appendChildInvokeNode->AddArgument(uniquePtrNodeInvokeNode);
238 ExpressionStatementNode* appendChildStatement = new ExpressionStatementNode(memberVariableSymbol->GetSpan(), memberVariableSymbol->SourceModuleId(), appendChildInvokeNode);
239 compoundStatementNode.AddStatement(appendChildStatement);
240 }
241
242 TemplateIdNode* uniquePtrNode = new TemplateIdNode(span, moduleId, new IdentifierNode(span, moduleId, U"System.UniquePtr"));
243 uniquePtrNode->AddTemplateArgument(new IdentifierNode(span, moduleId, U"System.Dom.Element"));
244 InvokeNode* invokeReleaseUniquePtrNode = new InvokeNode(span, moduleId, uniquePtrNode);
245 invokeReleaseUniquePtrNode->AddArgument(new InvokeNode(span, moduleId, new DotNode(span, moduleId, new IdentifierNode(span, moduleId, U"@element"),
246 new IdentifierNode(span, moduleId, U"Release"))));
247 ReturnStatementNode* returnStatementNode = new ReturnStatementNode(span, moduleId, invokeReleaseUniquePtrNode);
248 compoundStatementNode.AddStatement(returnStatementNode);
249
250 SymbolTable& symbolTable = statementBinder->GetBoundCompileUnit().GetSymbolTable();
251 symbolTable.BeginContainer(toXmlMemberFunctionSymbol);
252 SymbolCreatorVisitor symbolCreatorVisitor(symbolTable);
253 compoundStatementNode.Accept(symbolCreatorVisitor);
254 symbolTable.EndContainer();
255 TypeBinder typeBinder(statementBinder->GetBoundCompileUnit());
256 ContainerScope* containerScope = statementBinder->GetContainerScope();
257 typeBinder.SetContainerScope(containerScope);
258 statementBinder->SetContainerScope(toXmlMemberFunctionSymbol->GetContainerScope());
259 typeBinder.SetCurrentFunctionSymbol(toXmlMemberFunctionSymbol);
260 compoundStatementNode.Accept(typeBinder);
261 BoundFunction* prevFunction = statementBinder->CurrentFunction();
262 statementBinder->SetCurrentFunction(boundFunction.get());
263 compoundStatementNode.Accept(*statementBinder);
264 statementBinder->SetContainerScope(containerScope);
265 BoundStatement* boundStatement = statementBinder->ReleaseStatement();
266 Assert(boundStatement->GetBoundNodeType() == BoundNodeType::boundCompoundStatement, "bound compound statement expected");
267 BoundCompoundStatement* compoundStatement = static_cast<BoundCompoundStatement*>(boundStatement);
268 boundFunction->SetBody(std::unique_ptr<BoundCompoundStatement>(compoundStatement));
269 statementBinder->CurrentClass()->AddMember(std::move(boundFunction));
270 statementBinder->SetCurrentFunction(prevFunction);
271 statementBinder->GetBoundCompileUnit().RemoveLastFileScope();
272 }
273 catch (const Exception& ex;)
274 {
275 std::vector<std::std::pair<Span, boost::uuids::uuid>>references;
276 references.push_back(std::make_pair(ex.Defined(), ex.DefinedModuleId()));
277 references.insert(references.end(), ex.References().begin(), ex.References().end());
278 throw Exception("error in XML attribute generation: could not create 'UniquePtr<System.Dom.Element> ToXml(const string& fieldName)' member function for class '" + ToUtf8(classTypeSymbol->FullName()) + "': " + ex.Message(),
279 classTypeSymbol->GetSpan(), classTypeSymbol->SourceModuleId(), references);
280 }
281 }
282
283 void XmlAttributeProcessor::GenerateSystemDomElementConstructorImplementation(AttributeNode* attribute, ClassTypeSymbol* classTypeSymbol, ConstructorSymbol* constructorSymbol, StatementBinder* statementBinder)
284 {
285 try
286 {
287 FileScope* fileScope = new FileScope();
288 statementBinder->GetBoundCompileUnit().AddFileScope(fileScope);
289 std::unique_ptr<BoundFunction> boundFunction(new BoundFunction(&statementBinder->GetBoundCompileUnit(), constructorSymbol));
290 Span span = attribute->GetSpan();
291 boost::uuids::uuid moduleId = attribute->ModuleId();
292 ConstructorNode constructorNode(span, moduleId);
293 CompoundStatementNode compoundStatementNode(span, moduleId);
294 compoundStatementNode.SetEndBraceSpan(span);
295
296 ClassTypeSymbol* baseClass = classTypeSymbol->BaseClass();
297 if (baseClass)
298 {
299 AttributesNode* attributes = baseClass->GetAttributes();
300 if (attributes)
301 {
302 AttributeNode* xmlAttribute = attributes->GetAttribute(U"xml");
303 if (xmlAttribute)
304 {
305 if (xmlAttribute->Value() == U"true")
306 {
307 Span span = baseClass->GetSpan();
308 boost::uuids::uuid moduleId = classTypeSymbol->SourceModuleId();
309 InvokeNode* invokeNode = new InvokeNode(span, moduleId, new IdentifierNode(span, moduleId, U"GetXmlFieldElement"));
310 invokeNode->AddArgument(new StringLiteralNode(span, moduleId, "base"));
311 invokeNode->AddArgument(new IdentifierNode(span, moduleId, U"@element"));
312 BaseInitializerNode* baseInitializer = new BaseInitializerNode(span, moduleId);
313 baseInitializer->AddArgument(invokeNode);
314 constructorNode.AddInitializer(baseInitializer);
315 }
316 }
317 }
318 }
319
320 for (MemberVariableSymbol* memberVariableSymbol : classTypeSymbol->MemberVariables())
321 {
322 AttributesNode* attributes = memberVariableSymbol->GetAttributes();
323 if (attributes)
324 {
325 AttributeNode* xmlAttribute = attributes->GetAttribute(U"xml");
326 if (xmlAttribute)
327 {
328 if (xmlAttribute->Value() == U"false")
329 {
330 continue;
331 }
332 }
333 }
334 InvokeNode* invokeNode = new InvokeNode(memberVariableSymbol->GetSpan(), memberVariableSymbol->SourceModuleId(), new IdentifierNode(span, moduleId, U"FromXml"));
335 invokeNode->AddArgument(new IdentifierNode(memberVariableSymbol->GetSpan(), memberVariableSymbol->SourceModuleId(), U"@element"));
336 invokeNode->AddArgument(new StringLiteralNode(memberVariableSymbol->GetSpan(), memberVariableSymbol->SourceModuleId(), ToUtf8(memberVariableSymbol->Name())));
337 invokeNode->AddArgument(new IdentifierNode(memberVariableSymbol->GetSpan(), memberVariableSymbol->SourceModuleId(), memberVariableSymbol->Name()));
338 ExpressionStatementNode* fromXmlStatement = new ExpressionStatementNode(memberVariableSymbol->GetSpan(), memberVariableSymbol->SourceModuleId(), invokeNode);
339 compoundStatementNode.AddStatement(fromXmlStatement);
340 }
341
342 SymbolTable& symbolTable = statementBinder->GetBoundCompileUnit().GetSymbolTable();
343 symbolTable.BeginContainer(constructorSymbol);
344 SymbolCreatorVisitor symbolCreatorVisitor(symbolTable);
345 compoundStatementNode.Accept(symbolCreatorVisitor);
346 symbolTable.EndContainer();
347 TypeBinder typeBinder(statementBinder->GetBoundCompileUnit());
348 ContainerScope* containerScope = statementBinder->GetContainerScope();
349 typeBinder.SetContainerScope(containerScope);
350 statementBinder->SetContainerScope(constructorSymbol->GetContainerScope());
351 typeBinder.SetCurrentFunctionSymbol(constructorSymbol);
352 compoundStatementNode.Accept(typeBinder);
353 BoundFunction* prevFunction = statementBinder->CurrentFunction();
354 statementBinder->SetCurrentFunction(boundFunction.get());
355 ConstructorSymbol* prevConstructorSymbol = statementBinder->CurrentConstructorSymbol();
356 ConstructorNode* prevConstructorNode = statementBinder->CurrentConstructorNode();
357 statementBinder->SetCurrentConstructor(constructorSymbol, &constructorNode);
358 compoundStatementNode.Accept(*statementBinder);
359 statementBinder->SetContainerScope(containerScope);
360 BoundStatement* boundStatement = statementBinder->ReleaseStatement();
361 Assert(boundStatement->GetBoundNodeType() == BoundNodeType::boundCompoundStatement, "bound compound statement expected");
362 BoundCompoundStatement* compoundStatement = static_cast<BoundCompoundStatement*>(boundStatement);
363 boundFunction->SetBody(std::unique_ptr<BoundCompoundStatement>(compoundStatement));
364 statementBinder->CurrentClass()->AddMember(std::move(boundFunction));
365 statementBinder->SetCurrentConstructor(prevConstructorSymbol, prevConstructorNode);
366 statementBinder->SetCurrentFunction(prevFunction);
367 statementBinder->GetBoundCompileUnit().RemoveLastFileScope();
368 }
369 catch (const Exception& ex;)
370 {
371 std::vector<std::std::pair<Span, boost::uuids::uuid>>references;
372 references.push_back(std::make_pair(ex.Defined(), ex.DefinedModuleId()));
373 references.insert(references.end(), ex.References().begin(), ex.References().end());
374 throw Exception("error in XML attribute generation: could not create constructor taking System.Dom.Element* for the class '" + ToUtf8(classTypeSymbol->FullName()) + "': " + ex.Message(),
375 classTypeSymbol->GetSpan(), classTypeSymbol->SourceModuleId(), references);
376 }
377 }
378 } }