LCOV - code coverage report
Current view: top level - src/visitors/fillSemanticInfo - fillSemanticUserTypes.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 370 0
Test Date: 2025-04-18 15:53:49 Functions: 0.0 % 9 0

            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 &param : 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 &param : 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
        

Generated by: LCOV version 2.0-1