Line data Source code
1 : #include "../../../inc/parsingAnalysis/ast/userTypes/ast_attrAccess.h"
2 : #include "../../../inc/parsingAnalysis/ast/userTypes/ast_constructorCall.h"
3 : #include "../../../inc/parsingAnalysis/ast/userTypes/ast_methodCall.h"
4 : #include "../../../inc/parsingAnalysis/ast/userTypes/ast_struct.h"
5 : #include "../../../inc/parsingAnalysis/ast/userTypes/ast_this.h"
6 : #include "../../../inc/visitors/fillSemanticInfo/fillSemanticInfo.h"
7 : #include <cstddef>
8 : #include <memory>
9 : #include <variant>
10 : #include <vector>
11 :
12 : namespace nicole {
13 :
14 : std::expected<std::monostate, Error>
15 0 : FillSemanticInfo::visit(const AST_STRUCT *node) const noexcept {
16 0 : if (!node) {
17 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid AST_STRUCT");
18 0 : }
19 :
20 0 : analyzingInsideClass = true;
21 :
22 0 : currentStructGenericList_ = node->generics();
23 :
24 0 : if (hasDuplicatedGenerics(currentStructGenericList_)) {
25 0 : return createError(ERROR_TYPE::TYPE, "has duplicated generics");
26 0 : }
27 :
28 0 : std::shared_ptr<UserType> father{nullptr};
29 0 : if (node->fatherType()) {
30 0 : const auto instanceType =
31 0 : std::dynamic_pointer_cast<GenericInstanceType>(node->fatherType());
32 0 : if (instanceType) {
33 0 : if (typeTable_->isGenericType(instanceType, currentStructGenericList_)) {
34 0 : return createError(ERROR_TYPE::TYPE,
35 0 : instanceType->toString() +
36 0 : " is a generic so you cannot extend from it");
37 0 : }
38 0 : auto fatherExpected = typeTable_->getType(instanceType->name());
39 0 : if (!fatherExpected) {
40 0 : return createError(fatherExpected.error());
41 0 : }
42 0 : father = std::dynamic_pointer_cast<UserType>(fatherExpected.value());
43 0 : if (!father) {
44 0 : return createError(ERROR_TYPE::TYPE,
45 0 : "The father type is not a UserType");
46 0 : }
47 0 : } else {
48 0 : const auto userType =
49 0 : std::dynamic_pointer_cast<UserType>(node->fatherType());
50 0 : if (!userType) {
51 0 : return createError(
52 0 : ERROR_TYPE::TYPE,
53 0 : "father type can only be a user type or generic instance");
54 0 : }
55 0 : if (typeTable_->isGenericType(userType, currentStructGenericList_)) {
56 0 : return createError(ERROR_TYPE::TYPE,
57 0 : userType->toString() +
58 0 : " is a generic so you cannot extend from it");
59 0 : }
60 0 : auto fatherExpected = typeTable_->getType(userType->name());
61 0 : if (!fatherExpected) {
62 0 : return createError(fatherExpected.error());
63 0 : }
64 0 : father = std::dynamic_pointer_cast<UserType>(fatherExpected.value());
65 0 : if (!father) {
66 0 : return createError(ERROR_TYPE::TYPE,
67 0 : "The father type is not a UserType");
68 0 : }
69 0 : }
70 0 : }
71 0 : node->setFatherType(father);
72 0 : currentUserType_ =
73 0 : std::make_shared<UserType>(node->id(), father, node->generics());
74 :
75 0 : const auto insertType{typeTable_->insert(currentUserType_)};
76 0 : if (!insertType) {
77 0 : return createError(insertType.error());
78 0 : }
79 :
80 0 : pushScope();
81 :
82 0 : size_t pos{0};
83 0 : std::vector<std::pair<std::string, std::shared_ptr<nicole::Type>>> attributes;
84 0 : for (const auto &attr : node->attributes()) {
85 0 : auto attrType = attr.second;
86 0 : if (auto maskedEnum = typeTable_->isCompundEnumType(attrType))
87 0 : attrType = *maskedEnum;
88 :
89 0 : if (auto maskedGeneric =
90 0 : typeTable_->isCompundGenericType(attrType, currentGenericList_))
91 0 : attrType = *maskedGeneric;
92 0 : attributes.push_back({attr.first, attrType});
93 0 : const auto insertResult =
94 0 : currentUserType_->insertAttr(Attribute{attr.first, attrType, pos});
95 0 : if (!insertResult)
96 0 : return createError(insertResult.error());
97 0 : ++pos;
98 0 : }
99 0 : node->setAttributes(Attributes{attributes});
100 :
101 0 : for (const auto &method : node->methods()) {
102 0 : const auto result{method->accept(*this)};
103 0 : if (!result) {
104 0 : return createError(result.error());
105 0 : }
106 0 : }
107 :
108 0 : const auto constructor{node->constructor()->accept(*this)};
109 0 : if (!constructor) {
110 0 : return createError(constructor.error());
111 0 : }
112 :
113 0 : const auto destructor{node->destructor()->accept(*this)};
114 0 : if (!destructor) {
115 0 : return createError(destructor.error());
116 0 : }
117 :
118 0 : popScope();
119 :
120 0 : analyzingInsideClass = false;
121 0 : currentStructGenericList_.clear();
122 0 : currentGenericList_.clear();
123 :
124 0 : return {};
125 0 : }
126 :
127 : std::expected<std::monostate, Error>
128 0 : FillSemanticInfo::visit(const AST_ATTR_ACCESS *node) const noexcept {
129 0 : if (!node) {
130 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid AST_ATTR_ACCESS");
131 0 : }
132 0 : return {};
133 0 : }
134 :
135 : std::expected<std::monostate, Error>
136 0 : FillSemanticInfo::visit(const AST_METHOD_CALL *node) const noexcept {
137 0 : if (!node) {
138 0 : return createError(ERROR_TYPE::NULL_NODE, "Invalid AST_METHOD_CALL");
139 0 : }
140 0 : for (std::size_t i = 0; i < node->replaceOfGenerics().size(); ++i) {
141 0 : auto replacement = node->replaceOfGenerics()[i];
142 0 : if (!typeTable_->isPossibleType(replacement) &&
143 0 : !typeTable_->isGenericType(replacement, currentGenericList_)) {
144 0 : return createError(ERROR_TYPE::TYPE,
145 0 : replacement->toString() +
146 0 : " is not a possible type or generic");
147 0 : }
148 :
149 0 : if (auto maskedEnum = typeTable_->isCompundEnumType(replacement)) {
150 0 : replacement = *maskedEnum;
151 0 : auto setRes = node->setGenericReplacement(i, replacement);
152 0 : if (!setRes)
153 0 : return createError(setRes.error());
154 0 : }
155 :
156 0 : if (auto maskedGeneric = typeTable_->isCompundGenericType(
157 0 : replacement, currentGenericList_)) {
158 0 : replacement = *maskedGeneric;
159 0 : auto setRes = node->setGenericReplacement(i, replacement);
160 0 : if (!setRes)
161 0 : return createError(setRes.error());
162 0 : }
163 0 : }
164 :
165 0 : for (const auto &expr : node->parameters()) {
166 0 : const auto result = expr->accept(*this);
167 0 : if (!result)
168 0 : return createError(result.error());
169 0 : }
170 0 : return {};
171 0 : }
172 :
173 : std::expected<std::monostate, Error>
174 0 : FillSemanticInfo::visit(const AST_METHOD_DECL *node) const noexcept {
175 0 : if (!node)
176 0 : return createError(ERROR_TYPE::NULL_NODE, "Invalid AST_METHOD_DECL");
177 :
178 0 : currentGenericList_ = node->generics();
179 0 : auto mergedGenerics =
180 0 : mergeGenericLists(currentStructGenericList_, currentGenericList_);
181 0 : if (!mergedGenerics)
182 0 : return createError(mergedGenerics.error());
183 0 : currentGenericList_ = *mergedGenerics;
184 0 : node->setGenerics(currentGenericList_);
185 :
186 0 : pushScope();
187 0 : node->body()->setScope(currentScope_);
188 :
189 0 : std::vector<std::pair<std::string, std::shared_ptr<Type>>> updatedParams;
190 0 : for (const auto ¶m : node->parameters()) {
191 0 : if (currentUserType_->hasAttribute(param.first))
192 0 : return createError(ERROR_TYPE::ATTR, "Variable " + param.first +
193 0 : " is shadowing an attribute");
194 :
195 0 : if (!typeTable_->isPossibleType(param.second) &&
196 0 : !typeTable_->isGenericType(param.second, currentGenericList_))
197 0 : return createError(ERROR_TYPE::TYPE,
198 0 : param.second->toString() +
199 0 : " is not a possible type or generic");
200 :
201 0 : auto newType = param.second;
202 0 : if (auto maskedEnum = typeTable_->isCompundEnumType(newType))
203 0 : newType = *maskedEnum;
204 0 : if (auto maskedGeneric =
205 0 : typeTable_->isCompundGenericType(newType, currentGenericList_))
206 0 : newType = *maskedGeneric;
207 :
208 0 : updatedParams.push_back({param.first, newType});
209 :
210 0 : if (auto insertVar =
211 0 : currentScope_->insert(Variable{param.first, newType, nullptr});
212 0 : !insertVar)
213 0 : return createError(insertVar.error());
214 0 : }
215 0 : Parameters params{updatedParams};
216 0 : node->setParameters(params);
217 :
218 0 : if (!typeTable_->isPossibleType(node->returnType()) &&
219 0 : !typeTable_->isGenericType(node->returnType(), currentGenericList_))
220 0 : return createError(ERROR_TYPE::TYPE,
221 0 : node->returnType()->toString() +
222 0 : " is not a possible type or generic");
223 :
224 0 : auto retType = node->returnType();
225 0 : if (auto maskedReturn = typeTable_->isCompundEnumType(retType))
226 0 : retType = *maskedReturn;
227 0 : if (auto maskedGenericReturn =
228 0 : typeTable_->isCompundGenericType(retType, currentGenericList_))
229 0 : retType = *maskedGenericReturn;
230 0 : node->setReturnType(retType);
231 :
232 0 : Method newMethod{node->id(), currentGenericList_, params,
233 0 : retType, node->body(), node->isVirtual()};
234 :
235 0 : const auto combinedMethods = currentUserType_->getMethods(node->id());
236 0 : if (combinedMethods) {
237 0 : for (const auto &existingMethod : *combinedMethods) {
238 0 : if (areAmbiguousMethods(existingMethod, newMethod)) {
239 0 : if (!existingMethod.isInherited() ||
240 0 : (existingMethod.isInherited() && !existingMethod.isVirtual()))
241 0 : return createError(ERROR_TYPE::METHOD,
242 0 : "Ambiguous method declaration for: " + node->id());
243 0 : }
244 0 : }
245 0 : }
246 :
247 0 : currentUserType_->insertMethod(newMethod);
248 : // std::cout << "~~~~~~~~~~~~~~~~~~~~~~"<< currentUserType_->getMethods("toString")->size() << "\n";
249 :
250 0 : const auto bodyResult = node->body()->accept(*this);
251 0 : if (!bodyResult)
252 0 : return createError(bodyResult.error());
253 :
254 0 : popScope();
255 0 : currentGenericList_.clear();
256 0 : return {};
257 0 : }
258 :
259 : std::expected<std::monostate, Error>
260 0 : FillSemanticInfo::visit(const AST_CONSTRUCTOR_DECL *node) const noexcept {
261 0 : if (!node)
262 0 : return createError(ERROR_TYPE::NULL_NODE, "Invalid AST_CONSTRUCTOR_DECL");
263 :
264 0 : currentGenericList_ = node->generics();
265 0 : auto mergedGenerics =
266 0 : mergeGenericLists(currentStructGenericList_, currentGenericList_);
267 0 : if (!mergedGenerics)
268 0 : return createError(mergedGenerics.error());
269 0 : currentGenericList_ = *mergedGenerics;
270 0 : node->setGenerics(currentGenericList_);
271 :
272 0 : pushScope();
273 0 : node->body()->setScope(currentScope_);
274 :
275 0 : std::vector<std::pair<std::string, std::shared_ptr<nicole::Type>>>
276 0 : updatedParams;
277 0 : for (const auto ¶m : node->parameters()) {
278 0 : if (currentUserType_->hasAttribute(param.first))
279 0 : return createError(ERROR_TYPE::ATTR, "Variable " + param.first +
280 0 : " is shadowing an attribute");
281 :
282 0 : if (!typeTable_->isPossibleType(param.second) &&
283 0 : !typeTable_->isGenericType(param.second, currentGenericList_))
284 0 : return createError(ERROR_TYPE::TYPE,
285 0 : param.second->toString() +
286 0 : " is not a possible type or generic");
287 :
288 0 : auto newType = param.second;
289 0 : if (auto masked = typeTable_->isCompundEnumType(newType))
290 0 : newType = *masked;
291 0 : if (auto maskedGeneric =
292 0 : typeTable_->isCompundGenericType(newType, currentGenericList_))
293 0 : newType = *maskedGeneric;
294 :
295 0 : updatedParams.push_back({param.first, newType});
296 0 : if (auto insertResult =
297 0 : currentScope_->insert(Variable{param.first, newType, nullptr});
298 0 : !insertResult)
299 0 : return createError(insertResult.error());
300 0 : }
301 0 : Parameters params{updatedParams};
302 0 : node->setParameters(params);
303 :
304 0 : currentUserType_->setConstructor(std::make_shared<Constructor>(
305 0 : node->id(), node->generics(), params, node->returnType(), node->body()));
306 :
307 0 : if (node->super()) {
308 0 : if (auto superResult = node->super()->accept(*this); !superResult)
309 0 : return createError(superResult.error());
310 0 : }
311 :
312 0 : if (!typeTable_->isPossibleType(node->returnType()) &&
313 0 : !typeTable_->isGenericType(node->returnType(), currentGenericList_))
314 0 : return createError(ERROR_TYPE::TYPE,
315 0 : node->returnType()->toString() +
316 0 : " is not a possible type or generic");
317 :
318 0 : auto retType = node->returnType();
319 0 : if (auto masked = typeTable_->isCompundEnumType(retType))
320 0 : retType = *masked;
321 0 : if (auto maskedGeneric =
322 0 : typeTable_->isCompundGenericType(retType, currentGenericList_))
323 0 : retType = *maskedGeneric;
324 0 : node->setReturnType(retType);
325 :
326 0 : if (auto bodyResult = node->body()->accept(*this); !bodyResult)
327 0 : return createError(bodyResult.error());
328 :
329 0 : popScope();
330 0 : currentGenericList_.clear();
331 0 : return {};
332 0 : }
333 :
334 : std::expected<std::monostate, Error>
335 0 : FillSemanticInfo::visit(const AST_SUPER *node) const noexcept {
336 0 : if (!node) {
337 0 : return createError(ERROR_TYPE::NULL_NODE, "Invalid AST_SUPER");
338 0 : }
339 :
340 0 : const auto &reps = node->replacements();
341 0 : for (std::size_t i = 0; i < reps.size(); ++i) {
342 0 : auto replacement = reps[i];
343 :
344 0 : if (!typeTable_->isPossibleType(replacement) &&
345 0 : !typeTable_->isGenericType(replacement, currentGenericList_)) {
346 0 : return createError(ERROR_TYPE::TYPE,
347 0 : replacement->toString() +
348 0 : " is not a possible type or generic");
349 0 : }
350 :
351 0 : if (auto maskedEnum = typeTable_->isCompundEnumType(replacement)) {
352 0 : replacement = *maskedEnum;
353 0 : auto res = node->setGenericReplacement(i, replacement);
354 0 : if (!res) {
355 0 : return createError(res.error());
356 0 : }
357 0 : }
358 :
359 0 : if (auto maskedGeneric = typeTable_->isCompundGenericType(
360 0 : replacement, currentGenericList_)) {
361 0 : replacement = *maskedGeneric;
362 0 : auto res = node->setGenericReplacement(i, replacement);
363 0 : if (!res) {
364 0 : return createError(res.error());
365 0 : }
366 0 : }
367 0 : }
368 :
369 0 : for (const auto &arg : node->arguments()) {
370 0 : const auto result{arg->accept(*this)};
371 0 : if (!result) {
372 0 : return createError(result.error());
373 0 : }
374 0 : }
375 :
376 0 : return {};
377 0 : }
378 :
379 : std::expected<std::monostate, Error>
380 0 : FillSemanticInfo::visit(const AST_DESTRUCTOR_DECL *node) const noexcept {
381 0 : if (!node) {
382 0 : return createError(ERROR_TYPE::NULL_NODE, "Invalid AST_DESTRUCTOR_DECL");
383 0 : }
384 :
385 0 : currentUserType_->setDestructor(
386 0 : std::make_shared<Destructor>(node->id(), node->body()));
387 :
388 0 : pushScope();
389 0 : node->body()->setScope(currentScope_);
390 :
391 0 : const auto body{node->body()->accept(*this)};
392 0 : if (!body) {
393 0 : return createError(body.error());
394 0 : }
395 :
396 0 : popScope();
397 :
398 0 : return {};
399 0 : }
400 :
401 : std::expected<std::monostate, Error>
402 0 : FillSemanticInfo::visit(const AST_THIS *node) const noexcept {
403 0 : if (!node) {
404 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid AST_THIS");
405 0 : }
406 0 : if (analyzingInsideClass) {
407 0 : node->setUserType(currentUserType_);
408 0 : }
409 0 : return {};
410 0 : }
411 :
412 : std::expected<std::monostate, Error>
413 0 : FillSemanticInfo::visit(const AST_CONSTRUCTOR_CALL *node) const noexcept {
414 0 : if (!node) {
415 0 : return createError(ERROR_TYPE::NULL_NODE, "Invalid AST_CONSTRUCTOR_CALL");
416 0 : }
417 0 : if (typeTable_->isGenericType(
418 0 : std::make_shared<UserType>(node->id(), nullptr,
419 0 : std::vector<GenericParameter>{}),
420 0 : currentGenericList_)) {
421 0 : return {};
422 0 : }
423 0 : auto type{typeTable_->getType(node->id())};
424 0 : if (!type) {
425 0 : return createError(ERROR_TYPE::TYPE,
426 0 : "no type with id: " + node->id() + " exists");
427 0 : }
428 0 : if (const auto enumType{std::dynamic_pointer_cast<EnumType>(*type)}) {
429 0 : if (node->replaceOfGenerics().size()) {
430 0 : return createError(
431 0 : ERROR_TYPE::TYPE,
432 0 : "a enum cannot use generics replacements in it's constructor");
433 0 : }
434 0 : return {};
435 0 : }
436 :
437 0 : const auto isUserType{std::dynamic_pointer_cast<UserType>(*type)};
438 0 : if (node->replaceOfGenerics().size() != isUserType->genericParams().size()) {
439 0 : return createError(ERROR_TYPE::TYPE, "invalid replacements of list size");
440 0 : }
441 :
442 0 : for (const auto &replacement : node->replaceOfGenerics()) {
443 0 : if (!typeTable_->isPossibleType(replacement) and
444 0 : !typeTable_->isGenericType(replacement, currentGenericList_)) {
445 0 : return createError(ERROR_TYPE::TYPE,
446 0 : replacement->toString() +
447 0 : " is not a posibble type or generic");
448 0 : }
449 0 : }
450 :
451 0 : for (const auto &expr : node->parameters()) {
452 0 : const auto resul{expr->accept(*this)};
453 0 : if (!resul) {
454 0 : return createError(resul.error());
455 0 : }
456 0 : }
457 0 : return {};
458 0 : }
459 :
460 : } // namespace nicole
|