Line data Source code
1 : #include "../../../inc/visitors/validateTree/validateTree.h"
2 : #include "../../../inc/parsingAnalysis/ast/userTypes/ast_attrAccess.h"
3 : #include "../../../inc/parsingAnalysis/ast/userTypes/ast_constructorCall.h"
4 : #include "../../../inc/parsingAnalysis/ast/userTypes/ast_methodCall.h"
5 : #include "../../../inc/parsingAnalysis/ast/userTypes/ast_struct.h"
6 : #include "../../../inc/parsingAnalysis/ast/userTypes/ast_this.h"
7 : #include "../../../inc/parsingAnalysis/checkPosition.h"
8 :
9 : namespace nicole {
10 :
11 : // statement / body / null
12 : std::expected<bool, Error>
13 0 : ValidateTree::visit(const AST_STRUCT *node) const noexcept {
14 0 : if (!node) {
15 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid AST_STRUCT");
16 0 : }
17 0 : if (CheckPosition::itsBodyAncestorHasParent(node)) {
18 0 : return createError(ERROR_TYPE::VALIDATE_TREE,
19 0 : "a struct declaration must be outside of any scope");
20 0 : }
21 0 : const auto constructor{node->constructor()->accept(*this)};
22 0 : if (!constructor) {
23 0 : return createError(constructor.error());
24 0 : }
25 0 : const auto destructor{node->destructor()->accept(*this)};
26 0 : if (!destructor) {
27 0 : return createError(destructor.error());
28 0 : }
29 0 : for (const auto &chain : node->methods()) {
30 0 : const auto result{chain->accept(*this)};
31 0 : if (!result) {
32 0 : return createError(result.error());
33 0 : }
34 0 : }
35 0 : return true;
36 0 : }
37 :
38 : // chained childs
39 : std::expected<bool, Error>
40 0 : ValidateTree::visit(const AST_ATTR_ACCESS *node) const noexcept {
41 0 : if (!node) {
42 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid AST_ATTR_ACCESS");
43 0 : }
44 0 : if (!CheckPosition::hasAnyAncestorOf(
45 0 : node, {AST_TYPE::ATTR_ACCESS, AST_TYPE::METHOD_CALL, AST_TYPE::INDEX,
46 0 : AST_TYPE::CONSTRUCTOR_CALL, AST_TYPE::VAR_CALL})) {
47 0 : return createError(ERROR_TYPE::VALIDATE_TREE,
48 0 : "invalid hierarchy for attr access");
49 0 : }
50 0 : return true;
51 0 : }
52 :
53 : // chained childs
54 : std::expected<bool, Error>
55 0 : ValidateTree::visit(const AST_METHOD_CALL *node) const noexcept {
56 0 : if (!node) {
57 0 : return createError(ERROR_TYPE::NULL_NODE, "Invalid AST_METHOD_CALL");
58 0 : }
59 0 : if (!CheckPosition::hasAnyAncestorOf(
60 0 : node, {AST_TYPE::ATTR_ACCESS, AST_TYPE::METHOD_CALL, AST_TYPE::INDEX,
61 0 : AST_TYPE::CONSTRUCTOR_CALL, AST_TYPE::VAR_CALL})) {
62 0 : return createError(ERROR_TYPE::VALIDATE_TREE,
63 0 : "invalid hierarchy for Method call");
64 0 : }
65 0 : for (const auto &chain : node->parameters()) {
66 0 : const auto result{chain->accept(*this)};
67 0 : if (!result) {
68 0 : return createError(result.error());
69 0 : }
70 0 : }
71 0 : return true;
72 0 : }
73 :
74 : std::expected<bool, Error>
75 0 : ValidateTree::visit(const AST_METHOD_DECL *node) const noexcept {
76 0 : if (!node) {
77 0 : return createError(ERROR_TYPE::NULL_NODE, "Invalid AST_METHOD_DECL");
78 0 : }
79 0 : if (!CheckPosition::hasEveryAncestorInOrder(node, {AST_TYPE::STRUCT_DECL})) {
80 0 : return createError(ERROR_TYPE::VALIDATE_TREE,
81 0 : "invalid hierarchy for Method decl");
82 0 : }
83 0 : const auto result{node->body()->accept(*this)};
84 0 : if (!result) {
85 0 : return createError(result.error());
86 0 : }
87 0 : return true;
88 0 : }
89 :
90 : std::expected<bool, Error>
91 0 : ValidateTree::visit(const AST_CONSTRUCTOR_DECL *node) const noexcept {
92 0 : if (!node) {
93 0 : return createError(ERROR_TYPE::NULL_NODE, "Invalid AST_CONSTRUCTOR_DECL");
94 0 : }
95 0 : if (!CheckPosition::hasEveryAncestorInOrder(node, {AST_TYPE::STRUCT_DECL})) {
96 0 : return createError(ERROR_TYPE::VALIDATE_TREE,
97 0 : "invalid hierarchy for constructor decl");
98 0 : }
99 0 : if (node->super()) {
100 0 : const auto result{node->super()->accept(*this)};
101 0 : if (!result) {
102 0 : return createError(result.error());
103 0 : }
104 0 : }
105 0 : const auto result{node->body()->accept(*this)};
106 0 : if (!result) {
107 0 : return createError(result.error());
108 0 : }
109 0 : return true;
110 0 : }
111 :
112 : std::expected<bool, Error>
113 0 : ValidateTree::visit(const AST_SUPER *node) const noexcept {
114 0 : if (!node) {
115 0 : return createError(ERROR_TYPE::NULL_NODE, "Invalid AST_SUPER");
116 0 : }
117 0 : if (!CheckPosition::hasEveryAncestorInOrder(node,
118 0 : {AST_TYPE::DESTRUCTOR_DECL})) {
119 0 : return createError(ERROR_TYPE::VALIDATE_TREE,
120 0 : "invalid hierarchy for destructor decl");
121 0 : }
122 0 : for (const auto &chain : node->arguments()) {
123 0 : const auto result{chain->accept(*this)};
124 0 : if (!result) {
125 0 : return createError(result.error());
126 0 : }
127 0 : }
128 0 : return true;
129 0 : }
130 :
131 : std::expected<bool, Error>
132 0 : ValidateTree::visit(const AST_DESTRUCTOR_DECL *node) const noexcept {
133 0 : if (!node) {
134 0 : return createError(ERROR_TYPE::NULL_NODE, "Invalid AST_DESTRUCTOR_DECL");
135 0 : }
136 0 : if (!CheckPosition::hasEveryAncestorInOrder(node, {AST_TYPE::STRUCT_DECL})) {
137 0 : return createError(ERROR_TYPE::VALIDATE_TREE,
138 0 : "invalid hierarchy for destructor decl");
139 0 : }
140 0 : const auto result{node->body()->accept(*this)};
141 0 : if (!result) {
142 0 : return createError(result.error());
143 0 : }
144 0 : return true;
145 0 : }
146 :
147 : // func decl / struct
148 : std::expected<bool, Error>
149 0 : ValidateTree::visit(const AST_THIS *node) const noexcept {
150 0 : if (!node) {
151 0 : return createError(ERROR_TYPE::NULL_NODE, "invalid AST_THIS");
152 0 : }
153 0 : if (!CheckPosition::hasAnyAncestorOf(node, {AST_TYPE::STRUCT_DECL})) {
154 0 : return createError(ERROR_TYPE::VALIDATE_TREE,
155 0 : "a this call can only appear in methods");
156 0 : }
157 0 : return true;
158 0 : }
159 :
160 : // chained
161 : std::expected<bool, Error>
162 0 : ValidateTree::visit(const AST_CONSTRUCTOR_CALL *node) const noexcept {
163 0 : if (!node) {
164 0 : return createError(ERROR_TYPE::NULL_NODE, "Invalid AST_CONSTRUCTOR_CALL");
165 0 : }
166 0 : if (node->father()->type() != AST_TYPE::CHAIN) {
167 0 : return createError(ERROR_TYPE::VALIDATE_TREE,
168 0 : "invalid hierachy AST_VAR_CALL");
169 0 : }
170 0 : for (const auto &chain : node->parameters()) {
171 0 : const auto result{chain->accept(*this)};
172 0 : if (!result) {
173 0 : return createError(result.error());
174 0 : }
175 0 : }
176 0 : return true;
177 0 : }
178 :
179 : }
|