GCC Code Coverage Report


Directory: ./
File: src/sema/sema.cpp
Date: 2023-04-27 00:55:30
Exec Total Coverage
Lines: 648 709 91.4%
Functions: 135 162 83.3%
Branches: 555 701 79.2%

Line Branch Exec Source
1 #include "sema/sema.h"
2 #include "ast/magic.h"
3 #include "ast/values/object.h"
4 #include "builtin/operators.h"
5 #include "dependencies/fmt.h"
6 #include "parser/format_spec.h"
7 #include "utilities/guard.h"
8 #include "utilities/strings.h"
9
10 namespace lython {
11 Arrow* get_arrow(
12 SemanticAnalyser* self, ExprNode* fun, ExprNode* type, int depth, int& offset, ClassDef*& cls);
13
14 bool SemanticAnalyser::add_name(ExprNode* expr, ExprNode* value, ExprNode* type) {
15 73 auto* name = cast<Name>(expr);
16
17
1/2
✓ Branch 0 taken 73 times.
✗ Branch 1 not taken.
73 if (name != nullptr) {
18 73 name->ctx = ExprContext::Store;
19 73 bindings.add(name->id, value, type);
20 73 return true;
21 }
22
23 return false;
24 }
25
26 bool SemanticAnalyser::typecheck(
27 ExprNode* lhs, TypeExpr* lhs_t, ExprNode* rhs, TypeExpr* rhs_t, CodeLocation const& loc) {
28
29
3/4
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 37 times.
✓ Branch 2 taken 452 times.
✗ Branch 3 not taken.
489 if (lhs_t != nullptr && rhs_t != nullptr) {
30
1/1
✓ Branch 1 taken 452 times.
452 lython::log(lython::LogLevel::Debug,
31 loc,
32 "lhs_t: {} kind {} rhs_t: {} kind:{}",
33 452 str(lhs_t),
34
1/1
✓ Branch 1 taken 452 times.
452 lhs_t->kind,
35 452 str(rhs_t),
36
1/1
✓ Branch 1 taken 452 times.
452 rhs_t->kind);
37 }
38
39 489 auto match = equal(lhs_t, rhs_t);
40
41
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 468 times.
489 if (!match) {
42 SEMA_ERROR(lhs, TypeError, lhs, lhs_t, rhs, rhs_t, loc);
43 }
44 489 return match;
45 }
46
47 bool SemanticAnalyser::is_type(TypeExpr* type, int depth, lython::CodeLocation const& loc) {
48 241 TypeExpr* value_t_t = exec(type, depth);
49
50 241 return typecheck(type, // int
51 value_t_t, // Type
52 nullptr, //
53 Type_t(), // Type
54 241 loc);
55 }
56
57 Tuple<ClassDef*, FunctionDef*>
58 SemanticAnalyser::find_method(TypeExpr* class_type, String const& methodname, int depth) {
59 ClassDef* cls = get_class(class_type, depth);
60
61 if (cls == nullptr) {
62 return std::make_tuple(nullptr, nullptr);
63 }
64
65 TypeExpr* op_type = nullptr;
66
67 return std::make_tuple(cls, cast<FunctionDef>(getattr(cls, methodname, op_type)));
68 }
69
70 // classname.__and__
71 String SemanticAnalyser::operator_function(TypeExpr* expr_t, StringRef op) {
72 22 auto* cls_ref = cast<Name>(expr_t);
73 22 ClassDef* expr_cls = cast<ClassDef>(load_name(cls_ref));
74
75
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 20 times.
22 if (expr_cls != nullptr) {
76
6/8
✓ Branch 1 taken 2 times.
✓ Branch 4 taken 2 times.
✓ Branch 8 taken 2 times.
✓ Branch 11 taken 2 times.
✓ Branch 15 taken 4 times.
✓ Branch 16 taken 2 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
8 return join(".", Array<String>{expr_cls->cls_namespace, String(StringView(op))});
77 }
78
79
1/1
✓ Branch 2 taken 20 times.
20 return "";
80 6 }
81
82 TypeExpr* SemanticAnalyser::boolop(BoolOp* n, int depth) {
83
2/2
✓ Branch 2 taken 10 times.
✓ Branch 5 taken 10 times.
10 auto* bool_type = make_ref(n, "bool");
84 10 bool and_implemented = false;
85 10 bool rand_implemented = false;
86 10 auto* return_t = bool_type;
87
88
1/1
✓ Branch 1 taken 10 times.
10 StringRef magic = operator_magic_name(n->op, false);
89
1/1
✓ Branch 1 taken 10 times.
10 StringRef rmagic = operator_magic_name(n->op, true);
90
91 // TODO: what about inheritance ?
92 10 ExprNode* lhs = n->values[0];
93
1/1
✓ Branch 1 taken 10 times.
10 TypeExpr* lhs_t = exec(lhs, depth);
94
2/2
✓ Branch 1 taken 10 times.
✓ Branch 4 taken 10 times.
10 String lhs_op = operator_function(lhs_t, magic);
95
96 10 ExprNode* rhs = nullptr;
97 10 TypeExpr* rhs_t = nullptr;
98 10 String rhs_op;
99
100
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 10 times.
22 for (int i = 1; i < n->values.size(); i++) {
101 12 rhs = n->values[i];
102
1/1
✓ Branch 1 taken 12 times.
12 rhs_t = exec(rhs, depth);
103
104
5/7
✓ Branch 1 taken 12 times.
✓ Branch 5 taken 12 times.
✓ Branch 8 taken 12 times.
✓ Branch 12 taken 36 times.
✓ Branch 13 taken 12 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
48 String signature = join("-", Array<String>{str(n->op), str(lhs_t), str(rhs_t)});
105
2/2
✓ Branch 1 taken 12 times.
✓ Branch 4 taken 12 times.
12 auto handler = get_native_bool_operation(signature);
106
107
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (handler) {
108 6 n->native_operator = handler;
109 } else {
110 // Not a native operator
111
2/2
✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
6 int lhs_op_varid = bindings.get_varid(lhs_op);
112
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if (lhs_op_varid > 0) {
113 // found the function we are calling
114 1 n->varid = lhs_op_varid;
115
116
1/1
✓ Branch 2 taken 1 times.
1 Arrow* operator_type = cast<Arrow>(bindings.get_type(lhs_op_varid));
117
118 assert(operator_type, "Bool operator needs to be Callable");
119 assert(operator_type->args.size() == 2, "Bool operator requires 2 arguments");
120
121 typecheck(lhs, lhs_t, nullptr, operator_type->args[0], LOC);
122 typecheck(rhs, rhs_t, nullptr, operator_type->args[1], LOC);
123 typecheck(nullptr, operator_type->returns, nullptr, make_ref(n, "bool"), LOC);
124 } else {
125
2/2
✓ Branch 1 taken 5 times.
✓ Branch 4 taken 5 times.
5 int rhs_op_varid = bindings.get_varid(rhs_op);
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (rhs_op_varid > 0) {
127 // found the function we are calling
128 n->varid = rhs_op_varid;
129
130 Arrow* operator_type = cast<Arrow>(bindings.get_type(rhs_op_varid));
131
132 assert(operator_type, "Bool operator needs to be Callable");
133 assert(operator_type->args.size() == 2, "Bool operator requires 2 arguments");
134
135 typecheck(lhs, lhs_t, nullptr, operator_type->args[1], LOC);
136 typecheck(rhs, rhs_t, nullptr, operator_type->args[0], LOC);
137 typecheck(nullptr, operator_type->returns, nullptr, make_ref(n, "bool"), LOC);
138 }
139
140
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 if (lhs_op_varid == -1 && rhs_op_varid == -1) {
141 SEMA_ERROR(n, UnsupportedOperand, str(n->op), lhs_t, rhs_t);
142 }
143 }
144 }
145
146 12 lhs_t = rhs_t;
147 12 lhs = rhs;
148
2/2
✓ Branch 1 taken 12 times.
✓ Branch 4 taken 12 times.
12 lhs_op = operator_function(lhs_t, magic);
149
150 /*
151 //
152 // TODO: we could create a builtin file that define
153 // bool as a class that has the __and__ attribute
154 // that would harmonize this code
155 //
156 // if not a bool we need to check for
157 // * __and__ inside the lhs
158 // * __rand__ inside the rhs
159 if (!equal(lhs_t, bool_type)) {
160
161 ClassDef* cls = nullptr;
162 FunctionDef* fun = nullptr;
163
164 std::tie(cls, fun) = find_method(lhs_t, magic);
165
166 if (fun == nullptr) {
167 SEMA_ERROR(UnsupportedOperand(str(n->op), lhs_t, rhs_t));
168 return nullptr;
169 }
170
171 // This is a standard call now
172 auto arrow_expr = exec(fun, depth);
173 auto arrow = cast<Arrow>(arrow_expr);
174
175 // Generate the Call Arrow
176 auto got = n->new_object<Arrow>();
177 got->args.push_back(make_ref(got, str(cls->name))); // lhs_t
178 got->args.push_back(rhs_t);
179 got->returns = arrow->returns;
180
181 typecheck(n, got, nullptr, arrow, LOC);
182 lhs_t = arrow->returns;
183 }
184 */
185 12 }
186
187 10 return return_t;
188 22 }
189 TypeExpr* SemanticAnalyser::namedexpr(NamedExpr* n, int depth) {
190 2 auto* value_t = exec(n->value, depth);
191 2 add_name(n->target, n->value, value_t);
192 2 return value_t;
193 }
194
195 TypeExpr* SemanticAnalyser::resolve_variable(ExprNode* node) {
196
197 37 Name* name = cast<Name>(node);
198
199
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 20 times.
37 if (name != nullptr) {
200 assert(name->varid >= 0, "Type need to be resolved");
201 17 return static_cast<TypeExpr*>(bindings.get_value(name->varid));
202 }
203
204 20 return nullptr;
205 }
206
207 TypeExpr* SemanticAnalyser::compare(Compare* n, int depth) {
208
209
1/1
✓ Branch 1 taken 35 times.
35 auto* prev_t = exec(n->left, depth);
210 35 auto* prev = n->left;
211
212
2/2
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 35 times.
80 for (int i = 0; i < n->ops.size(); i++) {
213 45 auto op = n->ops[i];
214 45 auto* cmp = n->comparators[i];
215
1/1
✓ Branch 1 taken 45 times.
45 auto* cmp_t = exec(cmp, depth);
216
217 // Check if we have a native function to handle this
218
5/7
✓ Branch 1 taken 45 times.
✓ Branch 5 taken 45 times.
✓ Branch 8 taken 45 times.
✓ Branch 12 taken 135 times.
✓ Branch 13 taken 45 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
180 String signature = join(String("-"), Array<String>{str(op), str(prev_t), str(cmp_t)});
219
220 // TODO: get return type
221
2/2
✓ Branch 1 taken 45 times.
✓ Branch 4 taken 45 times.
45 auto handler = get_native_cmp_operation(signature);
222
1/1
✓ Branch 1 taken 45 times.
45 n->native_operator.push_back(handler);
223
224
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 23 times.
45 if (!handler) {
225 SEMA_ERROR(n, UnsupportedOperand, str(op), prev_t, cmp_t);
226 }
227 //
228 // prev <op> cmp
229
230 // TODO: typecheck op
231 // op: (prev_t -> cmp_t -> bool)
232
233 // --
234 45 prev = cmp;
235 45 prev_t = cmp_t;
236 45 }
237
238
2/2
✓ Branch 2 taken 35 times.
✓ Branch 5 taken 35 times.
35 return make_ref(n, "bool");
239 45 }
240
241 TypeExpr* SemanticAnalyser::binop(BinOp* n, int depth) {
242
243
1/1
✓ Branch 1 taken 37 times.
37 auto* lhs_t = exec(n->left, depth);
244
1/1
✓ Branch 1 taken 37 times.
37 auto* rhs_t = exec(n->right, depth);
245
246 typecheck(n->left, lhs_t, n->right, rhs_t, LOC);
247
248
1/1
✓ Branch 1 taken 37 times.
37 TypeExpr* type = resolve_variable(lhs_t);
249
1/1
✓ Branch 1 taken 37 times.
37 BuiltinType* blt = cast<BuiltinType>(type);
250
251 // Builtin type, all the operations are known
252
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 20 times.
37 if (blt) {
253
6/9
✓ Branch 1 taken 17 times.
✓ Branch 5 taken 17 times.
✓ Branch 8 taken 17 times.
✓ Branch 12 taken 51 times.
✓ Branch 13 taken 17 times.
✓ Branch 15 taken 17 times.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
68 String signature = join(String("-"), Array<String>{str(n->op), str(lhs_t), str(rhs_t)});
254
255 kwdebug("signature: {}", signature);
256
2/2
✓ Branch 1 taken 17 times.
✓ Branch 4 taken 17 times.
17 n->native_operator = get_native_binary_operation(signature);
257
258 // FIXME: get return type
259 17 return lhs_t;
260 17 } else {
261 // TODO: Not a builtin type, so it is user defined
262 // need to check for a magic method that overload the right operator
263
264 // Get the return value of the custom operator
265 20 return lhs_t;
266 }
267
268 // TODO: check that op is defined for those types
269 // use the op return type here
270 return lhs_t;
271 17 }
272 TypeExpr* SemanticAnalyser::unaryop(UnaryOp* n, int depth) {
273
1/1
✓ Branch 1 taken 11 times.
11 auto* expr_t = exec(n->operand, depth);
274
275
5/7
✓ Branch 1 taken 11 times.
✓ Branch 5 taken 11 times.
✓ Branch 8 taken 11 times.
✓ Branch 12 taken 22 times.
✓ Branch 13 taken 11 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
33 String signature = join("-", Array<String>{str(n->op), str(expr_t)});
276
277
2/2
✓ Branch 1 taken 11 times.
✓ Branch 4 taken 11 times.
11 UnaryOp::NativeUnaryOp handler = get_native_unary_operation(signature);
278
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7 times.
11 if (!handler) {
279 SEMA_ERROR(n, UnsupportedOperand, str(n->op), expr_t, nullptr);
280 }
281
282 // assert(handler != nullptr, "Unary operation require native handler");
283 11 n->native_operator = handler;
284
285 // TODO: fetch native operator
286 // TODO: check that op is defined for this type
287 // use the op return type here
288 11 return expr_t;
289 22 }
290 TypeExpr* SemanticAnalyser::lambda(Lambda* n, int depth) {
291 2 Scope scope(bindings);
292
1/1
✓ Branch 1 taken 2 times.
2 auto* funtype = n->new_object<Arrow>();
293
1/1
✓ Branch 1 taken 2 times.
2 add_arguments(n->args, funtype, nullptr, depth);
294
1/1
✓ Branch 1 taken 2 times.
2 auto* type = exec(n->body, depth);
295 2 funtype->returns = type;
296 2 return funtype;
297 2 }
298 TypeExpr* SemanticAnalyser::ifexp(IfExp* n, int depth) {
299 3 auto* test_t = exec(n->test, depth);
300
301 typecheck(n->test, test_t, nullptr, make_ref(n, "bool"), LOC);
302 3 auto* body_t = exec(n->body, depth);
303 3 auto* orelse_t = exec(n->orelse, depth);
304
305 typecheck(nullptr, body_t, nullptr, orelse_t, LOC);
306 3 return body_t;
307 }
308 TypeExpr* SemanticAnalyser::dictexpr(DictExpr* n, int depth) {
309 5 TypeExpr* key_t = nullptr;
310 5 TypeExpr* val_t = nullptr;
311
312
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 5 times.
15 for (int i = 0; i < n->keys.size(); i++) {
313 10 auto* key_type = exec(n->keys[i], depth);
314 10 auto* val_type = exec(n->values[i], depth);
315
316
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
10 if (key_t != nullptr && val_t != nullptr) {
317 typecheck(n->keys[i], key_type, nullptr, key_t, LOC);
318 typecheck(n->values[i], val_type, nullptr, val_t, LOC);
319 3 } else {
320 7 key_t = key_type;
321 7 val_t = val_type;
322 }
323 }
324
325 5 DictType* type = n->new_object<DictType>();
326 5 type->key = key_t;
327 5 type->value = val_t;
328 5 return type;
329 }
330 TypeExpr* SemanticAnalyser::setexpr(SetExpr* n, int depth) {
331 5 TypeExpr* val_t = nullptr;
332
333
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 5 times.
15 for (int i = 0; i < n->elts.size(); i++) {
334 10 auto* val_type = exec(n->elts[i], depth);
335
336
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7 times.
10 if (val_t != nullptr) {
337 typecheck(n->elts[i], val_type, nullptr, val_t, LOC);
338 } else {
339 7 val_t = val_type;
340 }
341 }
342
343 5 SetType* type = n->new_object<SetType>();
344 5 type->value = val_t;
345 5 return type;
346 }
347 TypeExpr* SemanticAnalyser::listcomp(ListComp* n, int depth) {
348 2 Scope scope(bindings);
349
2/2
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
4 for (auto& gen: n->generators) {
350
1/1
✓ Branch 1 taken 2 times.
2 exec(gen.target, depth);
351
1/1
✓ Branch 1 taken 2 times.
2 exec(gen.iter, depth);
352
353
2/2
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
4 for (auto* if_: gen.ifs) {
354
1/1
✓ Branch 1 taken 2 times.
2 exec(if_, depth);
355 }
356 }
357
358
1/1
✓ Branch 1 taken 2 times.
2 auto* val_type = exec(n->elt, depth);
359
360
1/1
✓ Branch 1 taken 2 times.
2 auto* type = n->new_object<ArrayType>();
361 2 type->value = val_type;
362 2 return type;
363 2 }
364 TypeExpr* SemanticAnalyser::generateexpr(GeneratorExp* n, int depth) {
365 2 Scope scope(bindings);
366
2/2
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
4 for (auto& gen: n->generators) {
367
1/1
✓ Branch 1 taken 2 times.
2 exec(gen.target, depth);
368
1/1
✓ Branch 1 taken 2 times.
2 exec(gen.iter, depth);
369
370
2/2
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
4 for (auto* if_: gen.ifs) {
371
1/1
✓ Branch 1 taken 2 times.
2 exec(if_, depth);
372 }
373 }
374
375
1/1
✓ Branch 1 taken 2 times.
2 auto* val_type = exec(n->elt, depth);
376
1/1
✓ Branch 1 taken 2 times.
2 auto* type = n->new_object<ArrayType>();
377 2 type->value = val_type;
378 2 return type;
379 2 }
380 TypeExpr* SemanticAnalyser::setcomp(SetComp* n, int depth) {
381 2 Scope scope(bindings);
382
2/2
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
4 for (auto& gen: n->generators) {
383
1/1
✓ Branch 1 taken 2 times.
2 exec(gen.target, depth);
384
1/1
✓ Branch 1 taken 2 times.
2 exec(gen.iter, depth);
385
386
2/2
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
4 for (auto* if_: gen.ifs) {
387
1/1
✓ Branch 1 taken 2 times.
2 exec(if_, depth);
388 }
389 }
390
391
1/1
✓ Branch 1 taken 2 times.
2 auto* val_type = exec(n->elt, depth);
392
393
1/1
✓ Branch 1 taken 2 times.
2 auto* type = n->new_object<ArrayType>();
394 2 type->value = val_type;
395 2 return type;
396 2 }
397
398 TypeExpr* SemanticAnalyser::dictcomp(DictComp* n, int depth) {
399 2 Scope scope(bindings);
400
2/2
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
4 for (auto& gen: n->generators) {
401
1/1
✓ Branch 1 taken 2 times.
2 exec(gen.target, depth);
402
1/1
✓ Branch 1 taken 2 times.
2 exec(gen.iter, depth);
403
404
2/2
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
4 for (auto* if_: gen.ifs) {
405
1/1
✓ Branch 1 taken 2 times.
2 exec(if_, depth);
406 }
407 }
408
409
1/1
✓ Branch 1 taken 2 times.
2 auto* key_type = exec(n->key, depth);
410
1/1
✓ Branch 1 taken 2 times.
2 auto* val_type = exec(n->value, depth);
411
412
1/1
✓ Branch 1 taken 2 times.
2 auto* type = n->new_object<DictType>();
413 2 type->key = key_type;
414 2 type->value = val_type;
415 2 return type;
416 2 }
417 TypeExpr* SemanticAnalyser::await(Await* n, int depth) { return exec(n->value, depth); }
418 TypeExpr* SemanticAnalyser::yield(Yield* n, int depth) {
419 6 get_context().yield = true;
420
421
1/1
✓ Branch 1 taken 6 times.
6 auto r = exec<TypeExpr*>(n->value, depth);
422
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 4 times.
6 if (r.has_value()) {
423 2 return r.value();
424 }
425 4 return nullptr;
426 6 }
427 TypeExpr* SemanticAnalyser::yieldfrom(YieldFrom* n, int depth) { return exec(n->value, depth); }
428
429 // def fun(a: int, b:int) -> float:
430 // pass
431 //
432 // Arrow1: (int, int) -> float
433 //
434 // Arrow2: (typeof(arg1), typeof(arg2)) -> ..
435 //
436 // <fun>(arg1 arg2 ...)
437 //
438
439 Node* SemanticAnalyser::load_name(Name_t* n) {
440
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 38 times.
45 if (n == nullptr) {
441 7 return nullptr;
442 }
443
444 38 Node* result = nullptr;
445 38 int varid = 0;
446
447
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38 times.
38 if (n->dynamic) {
448 // Local variables | Arguments
449 assert(n->offset != -1, "Reference should have a reverse lookup offset");
450 varid = int(bindings.bindings.size()) - n->offset;
451 result = bindings.get_value(varid);
452 } else {
453 // Global variables
454 38 result = bindings.get_value(n->varid);
455 }
456
457 38 return result;
458 }
459
460 ClassDef* SemanticAnalyser::get_class(ExprNode* classref, int depth) {
461 29 auto* cls_name = cast<Name>(classref);
462
463
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 23 times.
29 if (!cls_name) {
464 6 return nullptr;
465 }
466
467 23 cls_name->ctx = ExprContext::Load;
468 // assert(cls_name->ctx == ExprContext::Load, "Reference to the class should be loaded");
469 23 auto* cls = cast<ClassDef>(load_name(cls_name));
470
471 23 return cls;
472 }
473
474 Arrow*
475 SemanticAnalyser::get_arrow(ExprNode* fun, ExprNode* type, int depth, int& offset, ClassDef*& cls) {
476
477
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 79 times.
91 if (type == nullptr) {
478 12 return nullptr;
479 }
480
481
2/3
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
79 switch (type->kind) {
482 71 case NodeKind::Arrow: {
483 71 offset = 0;
484 71 return cast<Arrow>(type);
485 }
486 8 case NodeKind::BuiltinType: {
487
3/4
✓ Branch 1 taken 8 times.
✓ Branch 4 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 8 times.
8 if (!equal(type, Type_t())) {
488 return nullptr;
489 }
490
491 // Fetch the class type inside the binding
492
1/1
✓ Branch 1 taken 8 times.
8 cls = get_class(fun, depth);
493
494
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (cls == nullptr) {
495 kwwarn("Could not resolve class");
496 return nullptr;
497 }
498 8 TypeExpr* arrow = nullptr;
499
500 // The methods were added to the context outside of the class itself
501 // here we need to resolve the method which is inside the context
502
503 // NOTE: we should call __new__ here implictly
504 //
505
506
3/3
✓ Branch 2 taken 8 times.
✓ Branch 6 taken 8 times.
✓ Branch 9 taken 8 times.
8 String ctor_name = String(cls->name) + String(".__init__");
507
2/2
✓ Branch 1 taken 8 times.
✓ Branch 4 taken 8 times.
8 int ctorvarid = bindings.get_varid(ctor_name);
508 8 Node* ctor = bindings.get_value(ctorvarid);
509
510 // Now we can switch the function being called from being the class
511 // to being the constructor of the class
512 assert(fun->kind == NodeKind::Name, "Expect a reference to the class");
513
514 // --update the ref to point to the constructor if we found it--
515 // We should not do that, we need the class definition to know
516 // the size of the object
517 /*
518 Name* fun_ref = cast<Name>(fun);
519 if (fun_ref != nullptr && ctorvarid != -1) {
520 fun_ref->varid = ctorvarid;
521 fun_ref->size = int(bindings.bindings.size()) - fun_ref->varid;
522 fun_ref->dynamic = bindings.is_dynamic(fun_ref->varid);
523 } else {
524 kwwarn("Constructor was not found");
525 }
526 */
527
528
1/1
✓ Branch 1 taken 8 times.
8 FunctionDef* init = cast<FunctionDef>(ctor);
529 // auto init = getattr(cls, "__init__", arrow);
530 8 offset = 1;
531
532
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (init == nullptr) {
533 kwdebug("Use default ctor");
534
1/1
✓ Branch 1 taken 4 times.
4 auto* cls_ref = make_ref(fun, cls->name);
535
1/1
✓ Branch 1 taken 4 times.
4 Arrow* arrow = fun->new_object<Arrow>();
536
1/1
✓ Branch 1 taken 4 times.
4 arrow->add_arg_type(cls_ref);
537 4 arrow->returns = cls_ref;
538 4 return arrow;
539 } else {
540 // ctor should already have been sema'ed
541
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (init->type != nullptr) {
542 4 return init->type;
543 }
544
545 // if not then we are doing it right now and this is a circle
546 SEMA_ERROR(fun, RecursiveDefinition, "", fun, cls);
547 return nullptr;
548 }
549 8 }
550 default: break;
551 }
552 return nullptr;
553 }
554
555 TypeExpr* SemanticAnalyser::call(Call* n, int depth) {
556 // Get the type of the function
557
1/1
✓ Branch 1 taken 91 times.
91 auto* type = exec(n->func, depth);
558
559 91 int offset = 0;
560 91 ClassDef* cls = nullptr;
561
1/1
✓ Branch 1 taken 91 times.
91 auto* arrow = get_arrow(n->func, type, depth, offset, cls);
562
563
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 79 times.
91 if (arrow == nullptr) {
564 SEMA_ERROR(n, TypeError, fmt::format("{} is not callable", str(n->func)));
565 }
566
567 // Sort kwargs to make them positional
568 // Get Arguments and generate an arrow from it
569
570 // Create the matching Arrow type for this call
571
1/1
✓ Branch 1 taken 91 times.
91 Arrow* got = n->new_object<Arrow>();
572
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 12 times.
91 if (arrow != nullptr) {
573
1/1
✓ Branch 2 taken 79 times.
79 got->args.reserve(arrow->arg_count());
574 }
575
576 // Method, insert the self argument since it is implicit
577
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 83 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
91 if (offset == 1 && cls) {
578
3/3
✓ Branch 1 taken 8 times.
✓ Branch 4 taken 8 times.
✓ Branch 7 taken 8 times.
8 got->add_arg_type(make_ref(got, str(cls->name)));
579 }
580
581
2/2
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 91 times.
142 for (auto& arg: n->args) {
582
2/2
✓ Branch 1 taken 51 times.
✓ Branch 4 taken 51 times.
51 got->add_arg_type(exec(arg, depth));
583 }
584
585 91 Dict<StringRef, ExprNode*> kwargs;
586
2/2
✓ Branch 4 taken 7 times.
✓ Branch 5 taken 91 times.
98 for (auto& kw: n->keywords) {
587
2/2
✓ Branch 1 taken 7 times.
✓ Branch 4 taken 7 times.
7 kwargs[kw.arg] = exec(kw.value, depth);
588 }
589
590
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 12 times.
91 if (arrow != nullptr) {
591
2/2
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 79 times.
111 for (int i = int(got->arg_count()); i < arrow->names.size(); i++) {
592
1/1
✓ Branch 2 taken 32 times.
32 auto name = arrow->names[i];
593
594
1/1
✓ Branch 1 taken 32 times.
32 auto item = kwargs.find(name);
595
2/2
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 2 times.
32 if (item == kwargs.end()) {
596
1/1
✓ Branch 1 taken 30 times.
30 auto value = got->defaults[name];
597
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (value) {
598 SEMA_ERROR(n, TypeError, fmt::format("Arguement {} is not set", name));
599 }
600 // Got default use the expected type
601
1/1
✓ Branch 2 taken 30 times.
30 got->add_arg_type(arrow->args[i]);
602 30 continue;
603 30 }
604
605
1/1
✓ Branch 2 taken 2 times.
2 got->add_arg_type(item->second);
606 32 }
607 }
608
609 // FIXME: we do not know the returns so we just use the one we have
610
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 12 times.
91 if (arrow != nullptr) {
611 79 if (got->arg_count() != arrow->arg_count()) {
612 // we do not really that check
613 // SEMA_ERROR(TypeError(" missing {} required positional arguments"));
614 //
615 }
616
617 79 got->returns = arrow->returns;
618 typecheck(n, got, n->func, arrow, LOC);
619 }
620
621
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 12 times.
91 if (arrow != nullptr) {
622 79 return arrow->returns;
623 }
624 12 return nullptr;
625 91 }
626 TypeExpr* SemanticAnalyser::joinedstr(JoinedStr* n, int depth) {
627
2/2
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 3 times.
10 for (auto* value: n->values) {
628
1/1
✓ Branch 1 taken 7 times.
7 exec(value, depth);
629 }
630
2/2
✓ Branch 2 taken 3 times.
✓ Branch 5 taken 3 times.
3 return make_ref(n, "str");
631 }
632 TypeExpr* SemanticAnalyser::formattedvalue(FormattedValue* n, int depth) {
633 3 TypeExpr* vtype = exec(n->value, depth);
634
635 // Objects are able to define their own format specifiers to replace the standard ones
636 // [[fill]align][sign][#][0][minimumwidth][.precision][type]
637 // < + # 0 [0-9]* .[0-9]* b e
638 // > - c E
639 // = ' ' d f
640 // ^ o F
641 // x g
642 // X G
643 // n n
644 // None %
645 //
646 // Conversion flag
647 // !r {0!s:20}
648 // !s {0!r:20}
649 //
650 // class object:
651 // def __format__(self, format_spec):
652 // return format(str(self), format_spec)
653 //
654 // https://peps.python.org/pep-3101/
655
656 // Here checking the type of the format spec is probably not the priority
657 // but validating the format spec
658 // the sinple case is if there is a single format_spec
659
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
3 if (n->format_spec->values.size() == 1) {
660 1 Constant* cst = cast<Constant>(n->format_spec->values[0]);
661
662
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (cst != nullptr) {
663
1/1
✓ Branch 2 taken 1 times.
1 String strspec = cst->value.get<String>();
664
1/1
✓ Branch 1 taken 1 times.
1 FormatSpecifier spec = FormatSpecifier::parse(strspec);
665
666 // FIXME: this should a SEMA error
667
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!spec.valid) {
668 kwdebug("Format spec is not valid; parsed {} unparsed string: `{}`", //
669 spec.__repr__(), //
670 spec.unparsed //
671 );
672 }
673
674
1/1
✓ Branch 1 taken 1 times.
1 if (spec.is_float()) {
675 // TODO
676 // check that vtype is double or float
677 }
678
679
1/1
✓ Branch 1 taken 1 times.
1 if (spec.is_integer()) {
680 // TODO
681 // check that vtype is an integer
682 }
683 1 }
684 }
685
686 // I think if there is more that means the spec is dynamic
687 // then we are limited in our ability to validate it
688 // we probably can extract the type it if it is defined the rest
689 // will remain undefined
690
2/2
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 3 times.
8 for (auto* value: n->format_spec->values) {
691
1/1
✓ Branch 1 taken 5 times.
5 Constant* cst = cast<Constant>(value);
692
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
5 if (cst != nullptr) {
693 // Partial format spec
694 } else {
695 // Can we use the type here to guess which
696 // part of the format spec this will fill out ?
697
1/1
✓ Branch 1 taken 2 times.
2 TypeExpr* etype = exec(value, depth);
698 }
699 }
700
701 3 return nullptr;
702 }
703 TypeExpr* SemanticAnalyser::constant(Constant* n, int depth) {
704
5/13
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 163 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 27 times.
✓ Branch 11 taken 20 times.
✓ Branch 12 taken 20 times.
✓ Branch 13 taken 2 times.
232 switch (n->value.type()) {
705 case ConstantValue::Ti8: return make_ref(n, "i8");
706 case ConstantValue::Ti16: return make_ref(n, "i16");
707
2/2
✓ Branch 2 taken 163 times.
✓ Branch 5 taken 163 times.
163 case ConstantValue::Ti32: return make_ref(n, "i32");
708 case ConstantValue::Ti64: return make_ref(n, "i64");
709
710 case ConstantValue::Tu8: return make_ref(n, "u8");
711 case ConstantValue::Tu16: return make_ref(n, "u16");
712 case ConstantValue::Tu32: return make_ref(n, "u32");
713 case ConstantValue::Tu64: return make_ref(n, "u64");
714
715 case ConstantValue::Tf32: return make_ref(n, "f32");
716
2/2
✓ Branch 2 taken 27 times.
✓ Branch 5 taken 27 times.
27 case ConstantValue::Tf64: return make_ref(n, "f64");
717
2/2
✓ Branch 2 taken 20 times.
✓ Branch 5 taken 20 times.
20 case ConstantValue::TString: return make_ref(n, "str");
718
2/2
✓ Branch 2 taken 20 times.
✓ Branch 5 taken 20 times.
20 case ConstantValue::TBool: return make_ref(n, "bool");
719 2 default: return nullptr;
720 }
721
722 return nullptr;
723 }
724
725 // This is only called when loading
726 TypeExpr* SemanticAnalyser::attribute(Attribute* n, int depth) {
727 // <value>.<name>
728 10 auto* type_t = exec(n->value, depth);
729 10 auto* class_t = get_class(type_t, depth);
730
731
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 4 times.
10 if (class_t == nullptr) {
732 // class was not found, this is probably because the lookup
733 // of the value failed, it should have produced a precise error
734 // so we do not have to
735 // SEMA_ERROR(NameError(n->value, str(n->value)));
736 6 return nullptr;
737 }
738
739
1/1
✓ Branch 1 taken 4 times.
4 n->attrid = class_t->get_attribute(n->attr);
740
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (n->attrid == -1) {
741 SEMA_ERROR(n, AttributeError, class_t, n->attr);
742 1 return nullptr;
743 }
744
745 3 ClassDef::Attr& attr = class_t->attributes[n->attrid];
746
747 if (attr.type != nullptr && is_type(attr.type, depth, LOC)) {
748 3 return attr.type;
749 }
750 return nullptr;
751 }
752
753 TypeExpr* SemanticAnalyser::attribute_assign(Attribute* n, int depth, TypeExpr* expected) {
754 // self: Ref[class_t]
755 11 auto* type_t = exec(n->value, depth);
756 11 auto* class_t = get_class(type_t, depth);
757
758
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (class_t == nullptr) {
759 SEMA_ERROR(n, NameError, n->value, str(n->value));
760 return nullptr;
761 }
762
763
1/1
✓ Branch 1 taken 11 times.
11 n->attrid = class_t->get_attribute(n->attr);
764
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 10 times.
11 if (n->attrid == -1) {
765 SEMA_ERROR(n, AttributeError, class_t, n->attr);
766 1 return nullptr;
767 }
768
769 // Update attribute type when we are in an assignment
770 10 ClassDef::Attr& attr = class_t->attributes[n->attrid];
771
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
10 if (n->attrid > 0 && attr.type == nullptr) {
772 attr.type = expected;
773 }
774
775 if (attr.type != nullptr && is_type(attr.type, depth, LOC)) {
776 10 return attr.type;
777 }
778 return nullptr;
779 }
780
781 TypeExpr* SemanticAnalyser::subscript(Subscript* n, int depth) {
782 5 auto* class_t = exec(n->value, depth);
783 5 exec(n->slice, depth);
784 // check that __getitem__ is defined in class_t
785 5 return nullptr;
786 }
787 TypeExpr* SemanticAnalyser::starred(Starred* n, int depth) {
788 // value should be of an expandable type
789 2 auto* value_t = exec(n->value, depth);
790 2 return nullptr;
791 }
792 TypeExpr* SemanticAnalyser::name(Name* n, int depth) {
793
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 706 times.
742 if (n->ctx == ExprContext::Store) {
794
1/1
✓ Branch 1 taken 36 times.
36 auto id = bindings.add(n->id, n, nullptr);
795 36 n->varid = id;
796 36 n->size = int(bindings.bindings.size());
797
798 kwdebug("Storing value for {} ({})", n->id, n->varid);
799 } else {
800 // Both delete & Load requires the variable to be defined first
801
2/2
✓ Branch 1 taken 706 times.
✓ Branch 4 taken 706 times.
706 n->varid = bindings.get_varid(n->id);
802 706 n->size = int(bindings.bindings.size());
803 706 n->offset = int(bindings.bindings.size()) - n->varid;
804 706 n->dynamic = bindings.is_dynamic(n->varid);
805
806
2/2
✓ Branch 0 taken 239 times.
✓ Branch 1 taken 467 times.
706 if (n->varid == -1) {
807 kwdebug("Value {} not found", n->id);
808 SEMA_ERROR(n, NameError, n, n->id);
809 }
810 }
811
812 // assert(n->varid != -1, "Should have been founds");
813
814 742 auto* t = bindings.get_type(n->varid);
815
2/2
✓ Branch 0 taken 327 times.
✓ Branch 1 taken 415 times.
742 if (t == nullptr) {
816 kwdebug("Value {} does not have a type", n->id);
817 } else {
818 kwdebug("Loading value {}: {} of type {}", n->id, n->varid, str(t));
819 }
820 742 return t;
821 }
822
823 TypeExpr* SemanticAnalyser::comment(Comment* n, int depth) { return nullptr; }
824
825 TypeExpr* SemanticAnalyser::listexpr(ListExpr* n, int depth) {
826 5 TypeExpr* val_t = nullptr;
827
828
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 5 times.
17 for (int i = 0; i < n->elts.size(); i++) {
829 12 auto* val_type = exec(n->elts[i], depth);
830
831
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 6 times.
12 if (val_type == nullptr) {
832 // FIXME Could not find tyep for n->elts[i]
833 } else if (val_t == nullptr && is_type(val_type, depth, LOC)) {
834 3 val_t = val_type;
835
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 } else if (val_t != nullptr) {
836 typecheck(n->elts[i], val_type, nullptr, val_t, LOC);
837 }
838 }
839
840 5 ArrayType* type = n->new_object<ArrayType>();
841 5 type->value = val_t;
842 5 return type;
843 }
844 TypeExpr* SemanticAnalyser::tupleexpr(TupleExpr* n, int depth) {
845 17 TupleType* type = n->new_object<TupleType>();
846 17 type->types.reserve(n->elts.size());
847
848
2/2
✓ Branch 1 taken 44 times.
✓ Branch 2 taken 17 times.
61 for (int i = 0; i < n->elts.size(); i++) {
849
1/1
✓ Branch 2 taken 44 times.
44 TypeExpr* val_t = exec(n->elts[i], depth);
850
851
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 21 times.
44 if (val_t == nullptr) {
852 // FIXME Could not find tyep for n->elts[i]
853
854 } else if (!is_type(val_t, depth, LOC)) {
855 val_t = nullptr;
856 }
857
858
1/1
✓ Branch 1 taken 44 times.
44 type->types.push_back(val_t);
859 }
860
861 17 return type;
862 }
863 TypeExpr* SemanticAnalyser::slice(Slice* n, int depth) {
864
1/1
✓ Branch 1 taken 4 times.
4 exec<TypeExpr*>(n->lower, depth);
865
1/1
✓ Branch 1 taken 4 times.
4 exec<TypeExpr*>(n->upper, depth);
866
1/1
✓ Branch 1 taken 4 times.
4 exec<TypeExpr*>(n->step, depth);
867 4 return nullptr;
868 }
869
870 // name : annotation = value
871 // void SemanticAnalyser::add_argument(
872 // Identifier const& name, TypeExpr* annotation, ExprNode* value, Arrow* arrow, int depth) {
873
874 // TypeExpr* value_t = exec(value, depth);
875
876 // }
877
878 void SemanticAnalyser::add_arguments(Arguments& args, Arrow* arrow, ClassDef* def, int depth) {
879 135 TypeExpr* class_t = nullptr;
880
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 121 times.
135 if (def != nullptr) {
881
2/2
✓ Branch 1 taken 14 times.
✓ Branch 4 taken 14 times.
14 class_t = make_ref(arrow, str(def->name));
882 }
883
884 auto resolve_argument = [&](TypeExpr* annotation, ExprNode* value) -> TypeExpr* {
885 111 TypeExpr* value_t = nullptr;
886 111 bool value_t_valid = false;
887 111 bool ann_valid = false;
888
889
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 102 times.
111 if (value != nullptr) {
890 9 value_t = exec(value, depth); // Infer the type of the value
891
892
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 if (value_t == nullptr) {
893 // FXIME: Could not find type for value
894 } else {
895 value_t_valid = is_type(value_t, depth, LOC);
896 }
897 }
898
899
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 27 times.
111 if (annotation != nullptr) {
900 ann_valid = is_type(annotation, depth, LOC);
901 }
902
903
4/4
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 74 times.
111 if (ann_valid && value_t_valid) {
904 typecheck(nullptr, annotation, value, value_t, LOC);
905 }
906
907
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 32 times.
111 if (ann_valid) {
908 79 return annotation;
909 }
910
911
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if (value_t_valid) {
912 return value_t;
913 }
914
915 32 return nullptr;
916 135 };
917
918
2/2
✓ Branch 1 taken 109 times.
✓ Branch 2 taken 135 times.
244 for (int i = 0, n = int(args.args.size()); i < n; i++) {
919
1/1
✓ Branch 2 taken 109 times.
109 Arg arg = args.args[i];
920
921 109 ExprNode* value = nullptr;
922
2/2
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 25 times.
109 ExprNode* annotation = arg.annotation.has_value() ? arg.annotation.value() : nullptr;
923
924 109 int d = int(args.defaults.size()) - (n - i);
925
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 102 times.
109 if (d >= 0) {
926 7 value = args.defaults[d];
927
1/1
✓ Branch 1 taken 7 times.
7 arrow->defaults[arg.arg] = true;
928 }
929
930
1/1
✓ Branch 1 taken 109 times.
109 TypeExpr* type = resolve_argument(annotation, value);
931
932 // if it is a method populate the type of self
933 // TODO: fix for staticmethod & class methods
934
4/4
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 82 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 13 times.
109 if (class_t != nullptr && i == 0) {
935 kwdebug("Insert class type");
936 14 type = class_t;
937 }
938
939 // we could populate the default value here
940 // but we would not want sema to think this is a constant
941
1/1
✓ Branch 1 taken 109 times.
109 bindings.add(arg.arg, nullptr, type);
942
943
1/2
✓ Branch 0 taken 109 times.
✗ Branch 1 not taken.
109 if (arrow != nullptr) {
944
1/1
✓ Branch 1 taken 109 times.
109 arrow->names.push_back(arg.arg);
945
946
2/3
✓ Branch 1 taken 109 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 109 times.
109 if (!arrow->add_arg_type(type)) {
947 SEMA_ERROR(
948 arrow, TypeError, fmt::format("Cannot have a function type refer to itself"));
949 }
950 }
951 109 }
952
953
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 135 times.
137 for (int i = 0, n = int(args.kwonlyargs.size()); i < n; i++) {
954
1/1
✓ Branch 2 taken 2 times.
2 auto arg = args.kwonlyargs[i];
955
956 2 ExprNode* value = nullptr;
957
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 ExprNode* annotation = arg.annotation.has_value() ? arg.annotation.value() : nullptr;
958
959 2 int d = int(args.kw_defaults.size()) - (n - i);
960
961
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (d >= 0) {
962 2 value = args.kw_defaults[d];
963
1/1
✓ Branch 1 taken 2 times.
2 arrow->defaults[arg.arg] = true;
964 }
965
966
1/1
✓ Branch 1 taken 2 times.
2 TypeExpr* type = resolve_argument(annotation, value);
967
968
1/1
✓ Branch 1 taken 2 times.
2 bindings.add(arg.arg, nullptr, type);
969
970
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (arrow != nullptr) {
971
1/1
✓ Branch 1 taken 2 times.
2 arrow->names.push_back(arg.arg);
972
2/3
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
2 if (!arrow->add_arg_type(type)) {
973 SEMA_ERROR(
974 arrow, TypeError, fmt::format("Cannot have a function type refer to itself"));
975 }
976 }
977 2 }
978 135 }
979
980 Arrow* SemanticAnalyser::functiondef_arrow(FunctionDef* n, StmtNode* class_t, int depth) {
981 127 Arrow* type = n->new_object<Arrow>();
982
983 {
984
1/1
✓ Branch 1 taken 127 times.
127 PopGuard ctx(semactx, SemaContext{false, true});
985
986
2/2
✓ Branch 1 taken 55 times.
✓ Branch 2 taken 72 times.
127 if (n->returns.has_value()) {
987 55 auto* return_t = n->returns.value();
988
989 if (is_type(return_t, depth, LOC)) {
990 55 type->returns = n->returns.value();
991 }
992 }
993
994 // The arguments will be rolled back
995
996
2/2
✓ Branch 1 taken 127 times.
✓ Branch 4 taken 127 times.
127 add_arguments(n->args, type, cast<ClassDef>(class_t), depth);
997 // --
998 127 }
999
1000 127 return type;
1001 }
1002
1003 String SemanticAnalyser::generate_function_name(FunctionDef* n) {
1004 // Generate the function name
1005
1/1
✓ Branch 2 taken 127 times.
127 String funname = String(n->name);
1006
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 119 times.
127 if (namespaces.size() > 0) {
1007
3/4
✓ Branch 2 taken 8 times.
✓ Branch 5 taken 8 times.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
8 String cls_namespace = join(".", namespaces);
1008
1/1
✓ Branch 1 taken 8 times.
8 funname = fmtstr("{}.{}", cls_namespace, funname);
1009 8 }
1010
1011 127 return funname;
1012 }
1013
1014 Array<TypeExpr*> SemanticAnalyser::exec_body(Array<StmtNode*>& body, int depth) {
1015
1016 127 Array<TypeExpr*> types;
1017
2/2
✓ Branch 5 taken 162 times.
✓ Branch 6 taken 127 times.
289 for (auto* stmt: body) {
1018
1/1
✓ Branch 1 taken 162 times.
162 TypeExpr* tp = exec(stmt, depth);
1019
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 25 times.
162 if (tp != nullptr) {
1020
1/1
✓ Branch 1 taken 137 times.
137 types.push_back(tp);
1021 }
1022 }
1023 127 return types;
1024 }
1025
1026 TypeExpr* SemanticAnalyser::functiondef(FunctionDef* n, int depth) {
1027 // if sema was already done on the function
1028
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 127 times.
127 if (n->type) {
1029 kwinfo("Send cached type {}", str(n->type));
1030 return n->type;
1031 }
1032
1033
1/1
✓ Branch 1 taken 127 times.
127 String funname = generate_function_name(n);
1034
1035
2/2
✓ Branch 1 taken 127 times.
✓ Branch 4 taken 127 times.
127 PopGuard _(namespaces, str(n->name));
1036
1/1
✓ Branch 1 taken 127 times.
127 PopGuard nested_stmt(nested, (StmtNode*)n);
1037 127 StmtNode* lst = nested_stmt.last(1, nullptr);
1038
1039 // Insert the function into the global context
1040 // the arrow type is not created right away to prevent
1041 // circular typing
1042
2/2
✓ Branch 1 taken 127 times.
✓ Branch 4 taken 127 times.
127 auto id = bindings.add(funname, n, nullptr);
1043
1044 // Enter function context
1045 127 Scope scope(bindings);
1046
1047 // Create the function type from the arguments
1048 // this will also add the arguments to the context
1049
1/1
✓ Branch 1 taken 127 times.
127 Arrow* fun_type = functiondef_arrow(n, lst, depth);
1050 127 TypeExpr* return_t = fun_type->returns;
1051
1052 // Update the function type at the very end
1053 127 bindings.set_type(id, fun_type);
1054
1055 // Infer return type from the body
1056
1/1
✓ Branch 2 taken 127 times.
127 PopGuard ctx(semactx, SemaContext());
1057
1/1
✓ Branch 1 taken 127 times.
127 auto return_effective = exec_body(n->body, depth);
1058
1059
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 72 times.
127 if (return_t != nullptr) {
1060 // Annotated type takes precedence
1061
1/1
✓ Branch 2 taken 55 times.
55 typecheck(nullptr, // lhs
1062 return_t, // lhs_t
1063 nullptr, // rhs
1064 oneof(return_effective), // rhs_t
1065 LOC);
1066 }
1067
1068 // do decorator last since we need to know our function signature to
1069 // typecheck them
1070
2/2
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 127 times.
133 for (auto decorator: n->decorator_list) {
1071
1/1
✓ Branch 1 taken 6 times.
6 auto* deco_t = exec(decorator.expr, depth);
1072 // TODO check the signature here
1073 }
1074
1075 127 n->type = fun_type;
1076 127 n->generator = get_context().yield;
1077 127 return fun_type;
1078 127 }
1079
1080 void SemanticAnalyser::record_attributes(ClassDef* n,
1081 Array<StmtNode*> const& body,
1082 Array<StmtNode*>& methods,
1083 FunctionDef** ctor,
1084 int depth) {
1085
1086
2/2
✓ Branch 5 taken 23 times.
✓ Branch 6 taken 17 times.
40 for (auto& stmt: n->body) {
1087 23 Scope scope(bindings);
1088
1089 // Assignment
1090 23 ExprNode* target = nullptr;
1091 23 TypeExpr* target_t = nullptr;
1092
1093 23 ExprNode* value = nullptr;
1094 23 TypeExpr* value_t = nullptr;
1095
1096
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 8 times.
23 switch (stmt->kind) {
1097 8 case NodeKind::FunctionDef: {
1098 // Look for special functions
1099
1/1
✓ Branch 1 taken 8 times.
8 auto* fun = cast<FunctionDef>(stmt);
1100
2/2
✓ Branch 1 taken 8 times.
✓ Branch 4 taken 8 times.
8 n->insert_method(fun->name, fun);
1101
1102
3/3
✓ Branch 1 taken 8 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 2 times.
8 if (str(fun->name) == "__init__") {
1103 kwinfo("Found ctor");
1104 6 ctor[0] = fun;
1105 } else {
1106
1/1
✓ Branch 1 taken 2 times.
2 methods.push_back(stmt);
1107 }
1108 8 continue;
1109 8 }
1110 2 case NodeKind::Assign: {
1111
1/1
✓ Branch 1 taken 2 times.
2 auto* assn = cast<Assign>(stmt);
1112 2 target = assn->targets[0];
1113 2 value = assn->value;
1114 2 break;
1115 }
1116 5 case NodeKind::AnnAssign: {
1117
1/1
✓ Branch 1 taken 5 times.
5 auto* ann = cast<AnnAssign>(stmt);
1118 5 target = ann->target;
1119 5 value = ann->value.fold(nullptr);
1120 target_t = is_type(ann->annotation, depth, LOC) ? ann->annotation : nullptr;
1121 5 break;
1122 }
1123 default: kwdebug("Unhandled statement {}", str(stmt->kind)); continue;
1124 8 }
1125
1126
1/1
✓ Branch 1 taken 7 times.
7 auto* name = cast<Name>(target);
1127
1128 // Not a variable, move on
1129
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (name == nullptr) {
1130 continue;
1131 }
1132
1133 // try to deduce type fo the value
1134
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if (value != nullptr) {
1135
1/1
✓ Branch 1 taken 7 times.
7 value_t = exec(value, depth);
1136
1137 if (!is_type(value_t, depth, LOC)) {
1138 value_t = nullptr;
1139 }
1140 }
1141
1142 // if both types are available do a type check
1143
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
7 if (target_t != nullptr && value_t != nullptr) {
1144 typecheck(target, target_t, value, value_t, LOC);
1145 }
1146
1147 // insert attribute using the annotation first
1148
4/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
✓ Branch 3 taken 7 times.
✓ Branch 6 taken 7 times.
7 n->insert_attribute(name->id, stmt, target_t != nullptr ? target_t : value_t);
1149 23 }
1150 17 }
1151
1152 void SemanticAnalyser::record_ctor_attributes(ClassDef* n, FunctionDef* ctor, int depth) {
1153
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (ctor->args.args.empty()) {
1154 kwerror("__init__ without self");
1155 return;
1156 }
1157
1158 kwinfo("Looking for attributes inside the ctor");
1159
1/1
✓ Branch 2 taken 6 times.
6 auto self = ctor->args.args[0].arg;
1160
1161 // we need the arguments in the scope so we can look them up
1162
1/1
✓ Branch 1 taken 6 times.
6 Arrow arrow;
1163
1164 6 Scope _(bindings);
1165
1/1
✓ Branch 1 taken 6 times.
6 add_arguments(ctor->args, &arrow, n, depth);
1166
1167
2/2
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 6 times.
14 for (auto* stmt: ctor->body) {
1168 8 ExprNode* attr_expr = nullptr;
1169 8 ExprNode* value = nullptr;
1170 8 TypeExpr* type = nullptr;
1171
1172
1/3
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
8 switch (stmt->kind) {
1173 8 case NodeKind::Assign: {
1174
1/1
✓ Branch 1 taken 8 times.
8 auto* assn = cast<Assign>(stmt);
1175 8 attr_expr = assn->targets[0];
1176 8 value = assn->value;
1177 8 break;
1178 }
1179 case NodeKind::AnnAssign: {
1180 auto* ann = cast<AnnAssign>(stmt);
1181 attr_expr = ann->target;
1182 value = ann->value.has_value() ? ann->value.value() : nullptr;
1183 type = ann->annotation;
1184 break;
1185 }
1186 default: break;
1187 }
1188
1189 // if stmt is a comment
1190
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (attr_expr == nullptr) {
1191 continue;
1192 }
1193
1194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (attr_expr->kind != NodeKind::Attribute) {
1195 continue;
1196 }
1197
1198
1/1
✓ Branch 1 taken 8 times.
8 auto* attr = cast<Attribute>(attr_expr);
1199
1/1
✓ Branch 1 taken 8 times.
8 auto* name = cast<Name>(attr->value);
1200
1201
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (name == nullptr) {
1202 continue;
1203 }
1204
1205
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if (name->id != self) {
1206 continue;
1207 }
1208
1209 //
1210 // TODO: think about this, sema will reexecute that
1211 // the type should be added else where because we are inside a function
1212 // and we are processing only a subset of statements
1213 //
1214 // TODO: maybe we should nto rely on `sema->exec(ctor, depth)`
1215 //
1216 // Try to guess the attribute type
1217
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 if (type == nullptr && value != nullptr) {
1218
1/1
✓ Branch 1 taken 8 times.
8 type = exec(value, depth);
1219
1220 if (!is_type(type, depth, LOC)) {
1221 type = nullptr;
1222 }
1223 }
1224
1225
2/2
✓ Branch 1 taken 8 times.
✓ Branch 4 taken 8 times.
8 n->insert_attribute(attr->attr, stmt, type);
1226 }
1227 6 }
1228
1229 TypeExpr* SemanticAnalyser::classdef(ClassDef* n, int depth) {
1230
1/1
✓ Branch 1 taken 17 times.
17 PopGuard _(nested, n);
1231
2/2
✓ Branch 1 taken 17 times.
✓ Branch 4 taken 17 times.
17 PopGuard _n(namespaces, str(n->name));
1232
1233 // a class is a new type
1234 // the type of a class is type
1235
2/2
✓ Branch 1 taken 17 times.
✓ Branch 4 taken 17 times.
17 int id = bindings.add(n->name, n, Type_t());
1236
2/2
✓ Branch 1 taken 17 times.
✓ Branch 4 taken 17 times.
17 Name* class_t = make_ref(n, str(n->name), id);
1237
1238 // TODO: go through bases and add their elements
1239
2/2
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 17 times.
19 for (auto* base: n->bases) {
1240
1/1
✓ Branch 1 taken 2 times.
2 exec(base, depth);
1241 }
1242
1243 //
1244
2/2
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 17 times.
19 for (auto& kw: n->keywords) {
1245
1/1
✓ Branch 1 taken 2 times.
2 exec(kw.value, depth);
1246 }
1247
1248 17 Array<StmtNode*> methods;
1249 17 FunctionDef* ctor = nullptr;
1250
1251 // we insert methods as regular functions
1252 // this makes the structure flat and makes lookup O(1)
1253 // instead of possible O(n) if the method is netested n times
1254
1255
2/2
✓ Branch 2 taken 17 times.
✓ Branch 5 taken 17 times.
17 String cls_namespace = join(".", namespaces);
1256
1/1
✓ Branch 1 taken 17 times.
17 n->cls_namespace = cls_namespace;
1257
1258 // Do a first pass to look for special methods such as __init__
1259 // the attributes here are also static
1260
1/1
✓ Branch 1 taken 17 times.
17 record_attributes(n, n->body, methods, &ctor, depth);
1261 // -----------------------------
1262
1263 // get __init__ and do a pass to insert its attribute to the class
1264
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 11 times.
17 if (ctor != nullptr) {
1265 // Traverse body to look for our attributes
1266
1/1
✓ Branch 1 taken 6 times.
6 record_ctor_attributes(n, ctor, depth);
1267
1268 // add the constructor to the context
1269
2/2
✓ Branch 1 taken 6 times.
✓ Branch 4 taken 6 times.
6 auto* ctor_t = cast<Arrow>(exec(ctor, depth));
1270
1271 // Fix ctor type
1272
3/6
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
6 if (ctor_t != nullptr && ctor_t->arg_count() > 0) {
1273
1/1
✓ Branch 1 taken 6 times.
6 ctor_t->set_arg_type(0, class_t);
1274 6 ctor_t->returns = class_t;
1275 }
1276 }
1277 // -----------------------------
1278
1279 // Process the remaining methods;
1280
2/2
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 17 times.
19 for (auto& stmt: methods) {
1281
1282 // fun_t is the arrow that is saved in the context
1283 // populate self type
1284
1/1
✓ Branch 1 taken 2 times.
2 auto* fun = cast<FunctionDef>(stmt);
1285
2/2
✓ Branch 1 taken 2 times.
✓ Branch 4 taken 2 times.
2 auto* fun_t = cast<Arrow>(exec(stmt, depth));
1286
1287
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
2 if (fun_t != nullptr && fun_t->arg_count() > 0) {
1288
1/1
✓ Branch 1 taken 2 times.
2 fun_t->set_arg_type(0, class_t);
1289 }
1290 }
1291
1292 // ----
1293
1294
2/2
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 17 times.
21 for (auto deco: n->decorator_list) {
1295
1/1
✓ Branch 1 taken 4 times.
4 auto* deco_t = exec(deco.expr, depth);
1296 // TODO: check signature here
1297 }
1298
1299
1/1
✓ Branch 1 taken 17 times.
34 return Type_t();
1300 17 }
1301
1302 TypeExpr* SemanticAnalyser::invalidstmt(InvalidStatement_t* n, int depth) {
1303 // ignore it, parser already showed this error
1304 1 return None_t();
1305 }
1306 TypeExpr* SemanticAnalyser::returnstmt(Return* n, int depth) {
1307
1/1
✓ Branch 1 taken 114 times.
114 auto v = exec<TypeExpr*>(n->value, depth);
1308
2/2
✓ Branch 1 taken 89 times.
✓ Branch 2 taken 25 times.
114 if (v.has_value()) {
1309 89 return v.value();
1310 }
1311
1/1
✓ Branch 1 taken 25 times.
25 return None_t();
1312 114 }
1313 TypeExpr* SemanticAnalyser::deletestmt(Delete* n, int depth) {
1314
2/2
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 2 times.
6 for (auto* target: n->targets) {
1315
1/1
✓ Branch 1 taken 4 times.
4 exec(target, depth);
1316 }
1317 2 return nullptr;
1318 }
1319 TypeExpr* SemanticAnalyser::assign(Assign* n, int depth) {
1320 68 auto* type = exec(n->value, depth);
1321
1322 // TODO: check if the assigned name already exist or not
1323 //
1324
1/2
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
68 if (n->targets.size() == 1) {
1325 68 auto* target = n->targets[0];
1326
1327
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 16 times.
68 if (target->kind == NodeKind::Name) {
1328 52 add_name(target, n->value, type);
1329
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 5 times.
16 } else if (target->kind == NodeKind::Attribute) {
1330 // Deduce the type of the attribute from the value
1331 11 auto* target_t = attribute_assign(cast<Attribute>(n->targets[0]), depth, type);
1332
1333 typecheck(target, target_t, n->value, type, LOC);
1334 } else {
1335 kwerror("Assignment to an unsupported expression {}", str(target->kind));
1336 }
1337
1338 } else {
1339 auto* types = cast<TupleType>(type);
1340 if (types == nullptr) {
1341 // TODO: unexpected type
1342 return type;
1343 }
1344
1345 if (types->types.size() != n->targets.size()) {
1346 // TODO: Add type mismatch
1347 return type;
1348 }
1349
1350 for (auto i = 0; i < types->types.size(); i++) {
1351 auto* target = n->targets[0];
1352 auto* name = cast<Name>(target);
1353 auto* type = types->types[0];
1354
1355 add_name(n->targets[0], n->value, type);
1356 }
1357 }
1358
1359 68 return type;
1360 }
1361 TypeExpr* SemanticAnalyser::augassign(AugAssign* n, int depth) {
1362
1/1
✓ Branch 1 taken 14 times.
14 auto* expected_type = exec(n->target, depth);
1363
1/1
✓ Branch 1 taken 14 times.
14 auto* type = exec(n->value, depth);
1364
1365
5/7
✓ Branch 1 taken 14 times.
✓ Branch 5 taken 14 times.
✓ Branch 8 taken 14 times.
✓ Branch 12 taken 42 times.
✓ Branch 13 taken 14 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
56 String signature = join("-", Array<String>{str(n->op), str(expected_type), str(type)});
1366
1367
2/2
✓ Branch 1 taken 14 times.
✓ Branch 4 taken 14 times.
14 auto handler = get_native_binary_operation(signature);
1368 14 n->native_operator = handler;
1369
1370
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 10 times.
14 if (handler == nullptr) {
1371 SEMA_ERROR(n, UnsupportedOperand, str(n->op), expected_type, type);
1372 }
1373
1374 typecheck(n->value, type, n->target, expected_type, LOC);
1375 14 return type;
1376 28 }
1377
1378 //! Annotation takes priority over the deduced type
1379 //! this enbles users to use annotation to debug
1380 TypeExpr* SemanticAnalyser::annassign(AnnAssign* n, int depth) {
1381 19 TypeExpr* constraint = n->annotation;
1382 bool ann_valid = is_type(n->annotation, depth, LOC);
1383
1384 19 ExprNode* value = n->value.fold(nullptr);
1385
1/1
✓ Branch 1 taken 19 times.
19 TypeExpr* value_t = exec<TypeExpr*>(n->value, depth).fold(nullptr);
1386
1387
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if (value != nullptr) {
1388
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if (value_t == nullptr) {
1389 // FIXME could not find type for value
1390 } else if (!is_type(value_t, depth, LOC)) {
1391 value_t = nullptr;
1392 }
1393 }
1394
1395
2/4
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19 times.
✗ Branch 3 not taken.
19 if (constraint != nullptr && value_t != nullptr) {
1396 // if we were able to deduce a type from the expression
1397 // make sure it matches the annotation constraint
1398 19 typecheck(n->target, // a
1399 constraint, // int
1400 value, // 1
1401 value_t, // int
1402 LOC);
1403 }
1404
1405
3/4
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 15 times.
19 if (value_t != nullptr && !ann_valid) {
1406 4 constraint = value_t;
1407 kwinfo("Could fix annotation here was {} should be {}", str(n->annotation), str(value_t));
1408
1409 // FIX annotation
1410 if (false) {
1411 n->annotation = value_t;
1412 }
1413 }
1414
1415
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 if (n->target->kind == NodeKind::Name) {
1416
1/1
✓ Branch 1 taken 19 times.
19 add_name(n->target, value, constraint);
1417 } else if (n->target->kind == NodeKind::Attribute) {
1418 // if it is an attribute make sure to update its type
1419 auto* attr_t = attribute_assign(cast<Attribute>(n->target), depth, constraint);
1420
1421 // if attr has no type it will be added
1422 // if attr has a type then we need to check that the assignment type
1423 // matches
1424 typecheck(n->target, attr_t, nullptr, constraint, LOC);
1425 }
1426
1427 19 return constraint;
1428 }
1429 TypeExpr* SemanticAnalyser::forstmt(For* n, int depth) {
1430
1/1
✓ Branch 1 taken 4 times.
4 auto* iter_t = exec(n->iter, depth);
1431
1432 // TODO: use iter_t to set target types
1433
1/1
✓ Branch 1 taken 4 times.
4 exec(n->target, depth);
1434
1435 // TODO: check consistency of return types
1436
1/1
✓ Branch 1 taken 4 times.
4 auto return_t1 = exec<TypeExpr*>(n->body, depth);
1437
1/1
✓ Branch 1 taken 4 times.
4 auto return_t2 = exec<TypeExpr*>(n->orelse, depth);
1438
1439
1/1
✓ Branch 1 taken 4 times.
8 return oneof(return_t1);
1440 4 }
1441 TypeExpr* SemanticAnalyser::whilestmt(While* n, int depth) {
1442
1/1
✓ Branch 1 taken 7 times.
7 exec(n->test, depth);
1443
1/1
✓ Branch 1 taken 7 times.
7 exec<TypeExpr*>(n->body, depth);
1444
1/1
✓ Branch 1 taken 7 times.
7 auto types = exec<TypeExpr*>(n->orelse, depth);
1445
1/1
✓ Branch 1 taken 7 times.
14 return oneof(types);
1446 7 }
1447 TypeExpr* SemanticAnalyser::ifstmt(If* n, int depth) {
1448
1/1
✓ Branch 1 taken 8 times.
8 exec(n->test, depth);
1449
1/1
✓ Branch 1 taken 8 times.
8 auto types = exec<TypeExpr*>(n->body, depth);
1450
1451
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 8 times.
10 for (int i = 0; i < n->tests.size(); i++) {
1452
1/1
✓ Branch 2 taken 2 times.
2 exec(n->tests[i], depth);
1453
1/1
✓ Branch 2 taken 2 times.
2 exec<TypeExpr*>(n->bodies[i], depth);
1454 }
1455
1456
1/1
✓ Branch 1 taken 8 times.
16 return oneof(types);
1457 8 }
1458 TypeExpr* SemanticAnalyser::with(With* n, int depth) {
1459
2/2
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 4 times.
12 for (auto& item: n->items) {
1460
1/1
✓ Branch 1 taken 8 times.
8 auto* type = exec(item.context_expr, depth);
1461
1462
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 if (item.optional_vars.has_value()) {
1463 8 auto* expr = item.optional_vars.value();
1464
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (expr->kind == NodeKind::Name) {
1465
1/1
✓ Branch 1 taken 8 times.
8 auto* name = cast<Name>(expr);
1466
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 if (name != nullptr) {
1467
1/1
✓ Branch 1 taken 8 times.
8 name->varid = bindings.add(name->id, expr, type);
1468 }
1469 } else {
1470 // FIXME: is this even possible ?
1471 exec(item.optional_vars.value(), depth);
1472 }
1473 }
1474 }
1475
1476
1/1
✓ Branch 1 taken 4 times.
4 auto types = exec<TypeExpr*>(n->body, depth);
1477
1/1
✓ Branch 1 taken 4 times.
8 return oneof(types);
1478 4 }
1479 TypeExpr* SemanticAnalyser::raise(Raise* n, int depth) {
1480 // TODO:
1481
1/1
✓ Branch 1 taken 4 times.
4 exec<TypeExpr*>(n->exc, depth);
1482
1/1
✓ Branch 1 taken 4 times.
4 exec<TypeExpr*>(n->cause, depth);
1483 4 return nullptr;
1484 }
1485 TypeExpr* SemanticAnalyser::trystmt(Try* n, int depth) {
1486
1487 2 Array<TypeExpr*> return_t1;
1488 2 Array<TypeExpr*> return_t2;
1489 2 Array<TypeExpr*> return_t3;
1490 2 Array<TypeExpr*> return_t4;
1491
1492
1/1
✓ Branch 1 taken 2 times.
2 return_t1 = exec<TypeExpr*>(n->body, depth);
1493
1494
2/2
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
4 for (ExceptHandler& handler: n->handlers) {
1495 2 Scope _(bindings);
1496
1497 2 TypeExpr* exception_type = nullptr;
1498
1499
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (handler.type.has_value()) {
1500 2 exception_type = handler.type.value();
1501
1502
1/1
✓ Branch 1 taken 2 times.
2 TypeExpr* type = exec(exception_type, depth);
1503 typecheck(exception_type, type, nullptr, make_ref(n, "Type"), LOC);
1504 }
1505
1506
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (handler.name.has_value()) {
1507
1/1
✓ Branch 2 taken 2 times.
2 bindings.add(handler.name.value(), nullptr, exception_type);
1508 }
1509
1510
1/1
✓ Branch 1 taken 2 times.
2 return_t2 = exec<TypeExpr*>(handler.body, depth);
1511 2 }
1512
1513
1/1
✓ Branch 1 taken 2 times.
2 return_t3 = exec<TypeExpr*>(n->orelse, depth);
1514
1/1
✓ Branch 1 taken 2 times.
2 return_t4 = exec<TypeExpr*>(n->orelse, depth);
1515
1516 // TODO:
1517
1/1
✓ Branch 1 taken 2 times.
4 return oneof(return_t1);
1518 2 }
1519 TypeExpr* SemanticAnalyser::assertstmt(Assert* n, int depth) {
1520 // TODO:
1521 // we need to build the AssertionError exception
1522 8 exec(n->test, depth);
1523
1/1
✓ Branch 1 taken 8 times.
8 exec<TypeExpr*>(n->msg, depth + 1);
1524 8 return nullptr;
1525 }
1526
1527 // This means the binding lookup for variable should stop before the global scope :/
1528 TypeExpr* SemanticAnalyser::global(Global* n, int depth) {
1529
2/2
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
2 for (auto& name: n->names) {
1530
2/2
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
1 auto varid = bindings.get_varid(name);
1531
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (varid == -1) {
1532 SEMA_ERROR(n, NameError, n, name);
1533 }
1534 }
1535 1 return nullptr;
1536 }
1537 TypeExpr* SemanticAnalyser::nonlocal(Nonlocal* n, int depth) {
1538
2/2
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
2 for (auto& name: n->names) {
1539
2/2
✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
1 auto varid = bindings.get_varid(name);
1540
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (varid == -1) {
1541 SEMA_ERROR(n, NameError, n, name);
1542 }
1543 }
1544 1 return nullptr;
1545 }
1546 TypeExpr* SemanticAnalyser::exprstmt(Expr* n, int depth) { return exec(n->value, depth); }
1547 TypeExpr* SemanticAnalyser::pass(Pass* n, int depth) { return None_t(); }
1548 TypeExpr* SemanticAnalyser::breakstmt(Break* n, int depth) {
1549 // check that we are inside a loop
1550 2 return nullptr;
1551 }
1552 TypeExpr* SemanticAnalyser::continuestmt(Continue* n, int depth) {
1553 // check that we are inside a loop
1554 2 return nullptr;
1555 }
1556 TypeExpr* SemanticAnalyser::match(Match* n, int depth) {
1557
1/1
✓ Branch 1 taken 6 times.
6 exec(n->subject, depth);
1558
1559 6 Array<TypeExpr*> types;
1560
2/2
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 6 times.
24 for (auto& b: n->cases) {
1561
1/1
✓ Branch 1 taken 18 times.
18 exec(b.pattern, depth + 1);
1562
1/1
✓ Branch 1 taken 18 times.
18 exec<TypeExpr*>(b.guard, depth + 1);
1563
1/1
✓ Branch 1 taken 18 times.
18 types = exec<TypeExpr*>(b.body, depth + 1);
1564 }
1565
1566
1/1
✓ Branch 1 taken 6 times.
12 return oneof(types);
1567 6 }
1568 TypeExpr* SemanticAnalyser::inlinestmt(Inline* n, int depth) {
1569
1/1
✓ Branch 1 taken 2 times.
2 auto types = exec<TypeExpr*>(n->body, depth);
1570
1/1
✓ Branch 1 taken 2 times.
4 return oneof(types);
1571 2 }
1572
1573 TypeExpr* SemanticAnalyser::matchvalue(MatchValue* n, int depth) {
1574 18 exec(n->value, depth);
1575 18 return nullptr;
1576 }
1577 TypeExpr* SemanticAnalyser::matchsingleton(MatchSingleton* n, int depth) { return nullptr; }
1578 TypeExpr* SemanticAnalyser::matchsequence(MatchSequence* n, int depth) {
1579
2/2
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 6 times.
14 for (auto* elt: n->patterns) {
1580
1/1
✓ Branch 1 taken 8 times.
8 exec(elt, depth);
1581 }
1582 6 return nullptr;
1583 }
1584 TypeExpr* SemanticAnalyser::matchmapping(MatchMapping* n, int depth) {
1585
2/2
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 4 times.
6 for (auto* pat: n->patterns) {
1586
1/1
✓ Branch 1 taken 2 times.
2 exec(pat, depth);
1587 }
1588 4 return nullptr;
1589 }
1590 TypeExpr* SemanticAnalyser::matchclass(MatchClass* n, int depth) {
1591 2 exec(n->cls, depth);
1592
2/2
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 2 times.
6 for (auto* pat: n->patterns) {
1593
1/1
✓ Branch 1 taken 4 times.
4 exec(pat, depth);
1594 }
1595
2/2
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
4 for (auto* pat: n->kwd_patterns) {
1596
1/1
✓ Branch 1 taken 2 times.
2 exec(pat, depth);
1597 }
1598 2 return nullptr;
1599 }
1600 TypeExpr* SemanticAnalyser::matchstar(MatchStar* n, int depth) {
1601 // TODO: need to get the type from the target
1602
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (n->name.has_value()) {
1603 2 bindings.add(n->name.value(), n, nullptr);
1604 }
1605 2 return nullptr;
1606 }
1607 TypeExpr* SemanticAnalyser::matchas(MatchAs* n, int depth) {
1608 // TODO: need to get the type from the target
1609
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 if (n->name.has_value()) {
1610 2 bindings.add(n->name.value(), n, nullptr);
1611 }
1612
1/1
✓ Branch 1 taken 2 times.
2 exec<TypeExpr*>(n->pattern, depth);
1613 2 return nullptr;
1614 }
1615 TypeExpr* SemanticAnalyser::matchor(MatchOr* n, int depth) {
1616
2/2
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 2 times.
6 for (auto* pat: n->patterns) {
1617
1/1
✓ Branch 1 taken 4 times.
4 exec(pat, depth);
1618 }
1619 2 return nullptr;
1620 }
1621
1622 TypeExpr* SemanticAnalyser::dicttype(DictType* n, int depth) { return Type_t(); }
1623 TypeExpr* SemanticAnalyser::arraytype(ArrayType* n, int depth) { return Type_t(); }
1624 TypeExpr* SemanticAnalyser::arrow(Arrow* n, int depth) { return Type_t(); }
1625 TypeExpr* SemanticAnalyser::builtintype(BuiltinType* n, int depth) { return Type_t(); }
1626 TypeExpr* SemanticAnalyser::tupletype(TupleType* n, int depth) { return Type_t(); }
1627 TypeExpr* SemanticAnalyser::settype(SetType* n, int depth) { return Type_t(); }
1628 TypeExpr* SemanticAnalyser::classtype(ClassType* n, int depth) { return Type_t(); }
1629
1630 TypeExpr* SemanticAnalyser::module(Module* stmt, int depth) {
1631 // TODO: Add a forward pass that simply add functions & variables
1632 // to the context so the SEMA can look everything up
1633
1/1
✓ Branch 1 taken 234 times.
234 exec<TypeExpr*>(stmt->body, depth);
1634 234 return nullptr;
1635 };
1636
1637 TypeExpr* SemanticAnalyser::interactive(Interactive* n, int depth) { return nullptr; }
1638 TypeExpr* SemanticAnalyser::functiontype(FunctionType* n, int depth) { return Type_t(); }
1639 TypeExpr* SemanticAnalyser::expression(Expression* n, int depth) { return exec(n->body, depth); }
1640
1641 bool SemanticAnalyser::has_errors() const { return !errors.empty(); }
1642 void SemanticAnalyser::show_diagnostic(std::ostream& out, class AbstractLexer* lexer) {
1643 170 SemaErrorPrinter printer(std::cout, lexer);
1644
1645
2/2
✓ Branch 5 taken 136 times.
✓ Branch 6 taken 170 times.
306 for (auto& diag: errors) {
1646
1/1
✓ Branch 1 taken 136 times.
136 std::cout << " ";
1647
1/1
✓ Branch 2 taken 136 times.
136 printer.print(*diag.get());
1648
1/1
✓ Branch 1 taken 136 times.
136 std::cout << "\n";
1649 }
1650 170 }
1651 } // namespace lython
1652