Line | Count | Source (jump to first uncovered line) |
1 | #include <Python.h> |
2 | |
3 | #include "pegen.h" |
4 | #include "string_parser.h" |
5 | |
6 | static PyObject * |
7 | _create_dummy_identifier(Parser *p) |
8 | { |
9 | return _PyPegen_new_identifier(p, ""); |
10 | } |
11 | |
12 | void * |
13 | _PyPegen_dummy_name(Parser *p, ...) |
14 | { |
15 | static void *cache = NULL; |
16 | |
17 | if (cache != NULL) { Branch (17:9): [True: 93.0k, False: 60]
|
18 | return cache; |
19 | } |
20 | |
21 | PyObject *id = _create_dummy_identifier(p); |
22 | if (!id) { Branch (22:9): [True: 0, False: 60]
|
23 | return NULL; |
24 | } |
25 | cache = _PyAST_Name(id, Load, 1, 0, 1, 0, p->arena); |
26 | return cache; |
27 | } |
28 | |
29 | /* Creates a single-element asdl_seq* that contains a */ |
30 | asdl_seq * |
31 | _PyPegen_singleton_seq(Parser *p, void *a) |
32 | { |
33 | assert(a != NULL); |
34 | asdl_seq *seq = (asdl_seq*)_Py_asdl_generic_seq_new(1, p->arena); |
35 | if (!seq) { Branch (35:9): [True: 0, False: 705k]
|
36 | return NULL; |
37 | } |
38 | asdl_seq_SET_UNTYPED(seq, 0, a); |
39 | return seq; |
40 | } |
41 | |
42 | /* Creates a copy of seq and prepends a to it */ |
43 | asdl_seq * |
44 | _PyPegen_seq_insert_in_front(Parser *p, void *a, asdl_seq *seq) |
45 | { |
46 | assert(a != NULL); |
47 | if (!seq) { Branch (47:9): [True: 50.6k, False: 210k]
|
48 | return _PyPegen_singleton_seq(p, a); |
49 | } |
50 | |
51 | asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(asdl_seq_LEN(seq) + 1, p->arena); |
52 | if (!new_seq) { Branch (52:9): [True: 0, False: 210k]
|
53 | return NULL; |
54 | } |
55 | |
56 | asdl_seq_SET_UNTYPED(new_seq, 0, a); |
57 | for (Py_ssize_t i = 1, l = asdl_seq_LEN210k (new_seq); i < l; i++957k ) { Branch (57:55): [True: 957k, False: 210k]
|
58 | asdl_seq_SET_UNTYPED(new_seq, i, asdl_seq_GET_UNTYPED(seq, i - 1)); |
59 | } |
60 | return new_seq; |
61 | } |
62 | |
63 | /* Creates a copy of seq and appends a to it */ |
64 | asdl_seq * |
65 | _PyPegen_seq_append_to_end(Parser *p, asdl_seq *seq, void *a) |
66 | { |
67 | assert(a != NULL); |
68 | if (!seq) { Branch (68:9): [True: 0, False: 7]
|
69 | return _PyPegen_singleton_seq(p, a); |
70 | } |
71 | |
72 | asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(asdl_seq_LEN(seq) + 1, p->arena); |
73 | if (!new_seq) { Branch (73:9): [True: 0, False: 7]
|
74 | return NULL; |
75 | } |
76 | |
77 | for (Py_ssize_t i = 0, l = 7 asdl_seq_LEN7 (new_seq); i + 1 < l; i++8 ) { Branch (77:55): [True: 8, False: 7]
|
78 | asdl_seq_SET_UNTYPED(new_seq, i, asdl_seq_GET_UNTYPED(seq, i)); |
79 | } |
80 | asdl_seq_SET_UNTYPED(new_seq, asdl_seq_LEN(new_seq) - 1, a); |
81 | return new_seq; |
82 | } |
83 | |
84 | static Py_ssize_t |
85 | _get_flattened_seq_size(asdl_seq *seqs) |
86 | { |
87 | Py_ssize_t size = 0; |
88 | for (Py_ssize_t i = 0, l = asdl_seq_LEN97.1k (seqs); i < l; i++442k ) { Branch (88:52): [True: 442k, False: 97.1k]
|
89 | asdl_seq *inner_seq = asdl_seq_GET_UNTYPED(seqs, i); |
90 | size += asdl_seq_LEN(inner_seq); |
91 | } |
92 | return size; |
93 | } |
94 | |
95 | /* Flattens an asdl_seq* of asdl_seq*s */ |
96 | asdl_seq * |
97 | _PyPegen_seq_flatten(Parser *p, asdl_seq *seqs) |
98 | { |
99 | Py_ssize_t flattened_seq_size = _get_flattened_seq_size(seqs); |
100 | assert(flattened_seq_size > 0); |
101 | |
102 | asdl_seq *flattened_seq = (asdl_seq*)_Py_asdl_generic_seq_new(flattened_seq_size, p->arena); |
103 | if (!flattened_seq) { Branch (103:9): [True: 0, False: 97.1k]
|
104 | return NULL; |
105 | } |
106 | |
107 | int flattened_seq_idx = 0; |
108 | for (Py_ssize_t i = 0, l = asdl_seq_LEN97.1k (seqs); i < l; i++442k ) { Branch (108:52): [True: 442k, False: 97.1k]
|
109 | asdl_seq *inner_seq = asdl_seq_GET_UNTYPED(seqs, i); |
110 | for (Py_ssize_t j = 0, li = asdl_seq_LEN442k (inner_seq); j < li; j++446k ) { Branch (110:62): [True: 446k, False: 442k]
|
111 | asdl_seq_SET_UNTYPED(flattened_seq, flattened_seq_idx++, asdl_seq_GET_UNTYPED(inner_seq, j)); |
112 | } |
113 | } |
114 | assert(flattened_seq_idx == flattened_seq_size); |
115 | |
116 | return flattened_seq; |
117 | } |
118 | |
119 | void * |
120 | _PyPegen_seq_last_item(asdl_seq *seq) |
121 | { |
122 | Py_ssize_t len = asdl_seq_LEN(seq); |
123 | return asdl_seq_GET_UNTYPED(seq, len - 1); |
124 | } |
125 | |
126 | void * |
127 | _PyPegen_seq_first_item(asdl_seq *seq) |
128 | { |
129 | return asdl_seq_GET_UNTYPED(seq, 0); |
130 | } |
131 | |
132 | /* Creates a new name of the form <first_name>.<second_name> */ |
133 | expr_ty |
134 | _PyPegen_join_names_with_dot(Parser *p, expr_ty first_name, expr_ty second_name) |
135 | { |
136 | assert(first_name != NULL && second_name != NULL); |
137 | PyObject *first_identifier = first_name->v.Name.id; |
138 | PyObject *second_identifier = second_name->v.Name.id; |
139 | |
140 | if (PyUnicode_READY(first_identifier) == -1) { Branch (140:9): [True: 0, False: 1.01k]
|
141 | return NULL; |
142 | } |
143 | if (PyUnicode_READY(second_identifier) == -1) { Branch (143:9): [True: 0, False: 1.01k]
|
144 | return NULL; |
145 | } |
146 | const char *first_str = PyUnicode_AsUTF8(first_identifier); |
147 | if (!first_str) { Branch (147:9): [True: 0, False: 1.01k]
|
148 | return NULL; |
149 | } |
150 | const char *second_str = PyUnicode_AsUTF8(second_identifier); |
151 | if (!second_str) { Branch (151:9): [True: 0, False: 1.01k]
|
152 | return NULL; |
153 | } |
154 | Py_ssize_t len = strlen(first_str) + strlen(second_str) + 1; // +1 for the dot |
155 | |
156 | PyObject *str = PyBytes_FromStringAndSize(NULL, len); |
157 | if (!str) { Branch (157:9): [True: 0, False: 1.01k]
|
158 | return NULL; |
159 | } |
160 | |
161 | char *s = PyBytes_AS_STRING(str); |
162 | if (!s) { Branch (162:9): [True: 0, False: 1.01k]
|
163 | return NULL; |
164 | } |
165 | |
166 | strcpy(s, first_str); |
167 | s += strlen(first_str); |
168 | *s++ = '.'; |
169 | strcpy(s, second_str); |
170 | s += strlen(second_str); |
171 | *s = '\0'; |
172 | |
173 | PyObject *uni = PyUnicode_DecodeUTF8(PyBytes_AS_STRING(str), PyBytes_GET_SIZE(str), NULL); |
174 | Py_DECREF(str); |
175 | if (!uni) { Branch (175:9): [True: 0, False: 1.01k]
|
176 | return NULL; |
177 | } |
178 | PyUnicode_InternInPlace(&uni); |
179 | if (_PyArena_AddPyObject(p->arena, uni) < 0) { Branch (179:9): [True: 0, False: 1.01k]
|
180 | Py_DECREF(uni); |
181 | return NULL; |
182 | } |
183 | |
184 | return _PyAST_Name(uni, Load, EXTRA_EXPR(first_name, second_name)); |
185 | } |
186 | |
187 | /* Counts the total number of dots in seq's tokens */ |
188 | int |
189 | _PyPegen_seq_count_dots(asdl_seq *seq) |
190 | { |
191 | int number_of_dots = 0; |
192 | for (Py_ssize_t i = 0, l = asdl_seq_LEN2.04k (seq); i < l; i++147 ) { Branch (192:51): [True: 147, False: 2.04k]
|
193 | Token *current_expr = asdl_seq_GET_UNTYPED(seq, i); |
194 | switch (current_expr->type) { |
195 | case ELLIPSIS: Branch (195:13): [True: 2, False: 145]
|
196 | number_of_dots += 3; |
197 | break; |
198 | case DOT: Branch (198:13): [True: 145, False: 2]
|
199 | number_of_dots += 1; |
200 | break; |
201 | default: Branch (201:13): [True: 0, False: 147]
|
202 | Py_UNREACHABLE(); |
203 | } |
204 | } |
205 | |
206 | return number_of_dots; |
207 | } |
208 | |
209 | /* Creates an alias with '*' as the identifier name */ |
210 | alias_ty |
211 | _PyPegen_alias_for_star(Parser *p, int lineno, int col_offset, int end_lineno, |
212 | int end_col_offset, PyArena *arena) { |
213 | PyObject *str = PyUnicode_InternFromString("*"); |
214 | if (!str) { Branch (214:9): [True: 0, False: 409]
|
215 | return NULL; |
216 | } |
217 | if (_PyArena_AddPyObject(p->arena, str) < 0) { Branch (217:9): [True: 0, False: 409]
|
218 | Py_DECREF(str); |
219 | return NULL; |
220 | } |
221 | return _PyAST_alias(str, NULL, lineno, col_offset, end_lineno, end_col_offset, arena); |
222 | } |
223 | |
224 | /* Creates a new asdl_seq* with the identifiers of all the names in seq */ |
225 | asdl_identifier_seq * |
226 | _PyPegen_map_names_to_ids(Parser *p, asdl_expr_seq *seq) |
227 | { |
228 | Py_ssize_t len = asdl_seq_LEN(seq); |
229 | assert(len > 0); |
230 | |
231 | asdl_identifier_seq *new_seq = _Py_asdl_identifier_seq_new(len, p->arena); |
232 | if (!new_seq) { Branch (232:9): [True: 0, False: 330]
|
233 | return NULL; |
234 | } |
235 | for (Py_ssize_t i = 0; 330 i < len; i++472 ) { Branch (235:28): [True: 472, False: 330]
|
236 | expr_ty e = asdl_seq_GET(seq, i); |
237 | asdl_seq_SET(new_seq, i, e->v.Name.id); |
238 | } |
239 | return new_seq; |
240 | } |
241 | |
242 | /* Constructs a CmpopExprPair */ |
243 | CmpopExprPair * |
244 | _PyPegen_cmpop_expr_pair(Parser *p, cmpop_ty cmpop, expr_ty expr) |
245 | { |
246 | assert(expr != NULL); |
247 | CmpopExprPair *a = _PyArena_Malloc(p->arena, sizeof(CmpopExprPair)); |
248 | if (!a) { Branch (248:9): [True: 0, False: 22.2k]
|
249 | return NULL; |
250 | } |
251 | a->cmpop = cmpop; |
252 | a->expr = expr; |
253 | return a; |
254 | } |
255 | |
256 | asdl_int_seq * |
257 | _PyPegen_get_cmpops(Parser *p, asdl_seq *seq) |
258 | { |
259 | Py_ssize_t len = asdl_seq_LEN(seq); |
260 | assert(len > 0); |
261 | |
262 | asdl_int_seq *new_seq = _Py_asdl_int_seq_new(len, p->arena); |
263 | if (!new_seq) { Branch (263:9): [True: 0, False: 21.9k]
|
264 | return NULL; |
265 | } |
266 | for (Py_ssize_t i = 0; 21.9k i < len; i++22.2k ) { Branch (266:28): [True: 22.2k, False: 21.9k]
|
267 | CmpopExprPair *pair = asdl_seq_GET_UNTYPED(seq, i); |
268 | asdl_seq_SET(new_seq, i, pair->cmpop); |
269 | } |
270 | return new_seq; |
271 | } |
272 | |
273 | asdl_expr_seq * |
274 | _PyPegen_get_exprs(Parser *p, asdl_seq *seq) |
275 | { |
276 | Py_ssize_t len = asdl_seq_LEN(seq); |
277 | assert(len > 0); |
278 | |
279 | asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena); |
280 | if (!new_seq) { Branch (280:9): [True: 0, False: 21.9k]
|
281 | return NULL; |
282 | } |
283 | for (Py_ssize_t i = 0; 21.9k i < len; i++22.2k ) { Branch (283:28): [True: 22.2k, False: 21.9k]
|
284 | CmpopExprPair *pair = asdl_seq_GET_UNTYPED(seq, i); |
285 | asdl_seq_SET(new_seq, i, pair->expr); |
286 | } |
287 | return new_seq; |
288 | } |
289 | |
290 | /* Creates an asdl_seq* where all the elements have been changed to have ctx as context */ |
291 | static asdl_expr_seq * |
292 | _set_seq_context(Parser *p, asdl_expr_seq *seq, expr_context_ty ctx) |
293 | { |
294 | Py_ssize_t len = asdl_seq_LEN(seq); |
295 | if (len == 0) { Branch (295:9): [True: 5, False: 2]
|
296 | return NULL; |
297 | } |
298 | |
299 | asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena); |
300 | if (!new_seq) { Branch (300:9): [True: 0, False: 2]
|
301 | return NULL; |
302 | } |
303 | for (Py_ssize_t i = 0; 2 i < len; i++4 ) { Branch (303:28): [True: 4, False: 2]
|
304 | expr_ty e = asdl_seq_GET(seq, i); |
305 | asdl_seq_SET(new_seq, i, _PyPegen_set_expr_context(p, e, ctx)); |
306 | } |
307 | return new_seq; |
308 | } |
309 | |
310 | static expr_ty |
311 | _set_name_context(Parser *p, expr_ty e, expr_context_ty ctx) |
312 | { |
313 | return _PyAST_Name(e->v.Name.id, ctx, EXTRA_EXPR(e, e)); |
314 | } |
315 | |
316 | static expr_ty |
317 | _set_tuple_context(Parser *p, expr_ty e, expr_context_ty ctx) |
318 | { |
319 | return _PyAST_Tuple( |
320 | _set_seq_context(p, e->v.Tuple.elts, ctx), |
321 | ctx, |
322 | EXTRA_EXPR(e, e)); |
323 | } |
324 | |
325 | static expr_ty |
326 | _set_list_context(Parser *p, expr_ty e, expr_context_ty ctx) |
327 | { |
328 | return _PyAST_List( |
329 | _set_seq_context(p, e->v.List.elts, ctx), |
330 | ctx, |
331 | EXTRA_EXPR(e, e)); |
332 | } |
333 | |
334 | static expr_ty |
335 | _set_subscript_context(Parser *p, expr_ty e, expr_context_ty ctx) |
336 | { |
337 | return _PyAST_Subscript(e->v.Subscript.value, e->v.Subscript.slice, |
338 | ctx, EXTRA_EXPR(e, e)); |
339 | } |
340 | |
341 | static expr_ty |
342 | _set_attribute_context(Parser *p, expr_ty e, expr_context_ty ctx) |
343 | { |
344 | return _PyAST_Attribute(e->v.Attribute.value, e->v.Attribute.attr, |
345 | ctx, EXTRA_EXPR(e, e)); |
346 | } |
347 | |
348 | static expr_ty |
349 | _set_starred_context(Parser *p, expr_ty e, expr_context_ty ctx) |
350 | { |
351 | return _PyAST_Starred(_PyPegen_set_expr_context(p, e->v.Starred.value, ctx), |
352 | ctx, EXTRA_EXPR(e, e)); |
353 | } |
354 | |
355 | /* Creates an `expr_ty` equivalent to `expr` but with `ctx` as context */ |
356 | expr_ty |
357 | _PyPegen_set_expr_context(Parser *p, expr_ty expr, expr_context_ty ctx) |
358 | { |
359 | assert(expr != NULL); |
360 | |
361 | expr_ty new = NULL; |
362 | switch (expr->kind) { |
363 | case Name_kind: Branch (363:9): [True: 637k, False: 24]
|
364 | new = _set_name_context(p, expr, ctx); |
365 | break; |
366 | case Tuple_kind: Branch (366:9): [True: 4, False: 637k]
|
367 | new = _set_tuple_context(p, expr, ctx); |
368 | break; |
369 | case List_kind: Branch (369:9): [True: 3, False: 637k]
|
370 | new = _set_list_context(p, expr, ctx); |
371 | break; |
372 | case Subscript_kind: Branch (372:9): [True: 7, False: 637k]
|
373 | new = _set_subscript_context(p, expr, ctx); |
374 | break; |
375 | case Attribute_kind: Branch (375:9): [True: 10, False: 637k]
|
376 | new = _set_attribute_context(p, expr, ctx); |
377 | break; |
378 | case Starred_kind: Branch (378:9): [True: 0, False: 637k]
|
379 | new = _set_starred_context(p, expr, ctx); |
380 | break; |
381 | default: Branch (381:9): [True: 0, False: 637k]
|
382 | new = expr; |
383 | } |
384 | return new; |
385 | } |
386 | |
387 | /* Constructs a KeyValuePair that is used when parsing a dict's key value pairs */ |
388 | KeyValuePair * |
389 | _PyPegen_key_value_pair(Parser *p, expr_ty key, expr_ty value) |
390 | { |
391 | KeyValuePair *a = _PyArena_Malloc(p->arena, sizeof(KeyValuePair)); |
392 | if (!a) { Branch (392:9): [True: 0, False: 167k]
|
393 | return NULL; |
394 | } |
395 | a->key = key; |
396 | a->value = value; |
397 | return a; |
398 | } |
399 | |
400 | /* Extracts all keys from an asdl_seq* of KeyValuePair*'s */ |
401 | asdl_expr_seq * |
402 | _PyPegen_get_keys(Parser *p, asdl_seq *seq) |
403 | { |
404 | Py_ssize_t len = asdl_seq_LEN(seq); |
405 | asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena); |
406 | if (!new_seq) { Branch (406:9): [True: 0, False: 8.57k]
|
407 | return NULL; |
408 | } |
409 | for (Py_ssize_t i = 0; 8.57k i < len; i++166k ) { Branch (409:28): [True: 166k, False: 8.57k]
|
410 | KeyValuePair *pair = asdl_seq_GET_UNTYPED(seq, i); |
411 | asdl_seq_SET(new_seq, i, pair->key); |
412 | } |
413 | return new_seq; |
414 | } |
415 | |
416 | /* Extracts all values from an asdl_seq* of KeyValuePair*'s */ |
417 | asdl_expr_seq * |
418 | _PyPegen_get_values(Parser *p, asdl_seq *seq) |
419 | { |
420 | Py_ssize_t len = asdl_seq_LEN(seq); |
421 | asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena); |
422 | if (!new_seq) { Branch (422:9): [True: 0, False: 8.57k]
|
423 | return NULL; |
424 | } |
425 | for (Py_ssize_t i = 0; 8.57k i < len; i++166k ) { Branch (425:28): [True: 166k, False: 8.57k]
|
426 | KeyValuePair *pair = asdl_seq_GET_UNTYPED(seq, i); |
427 | asdl_seq_SET(new_seq, i, pair->value); |
428 | } |
429 | return new_seq; |
430 | } |
431 | |
432 | /* Constructs a KeyPatternPair that is used when parsing mapping & class patterns */ |
433 | KeyPatternPair * |
434 | _PyPegen_key_pattern_pair(Parser *p, expr_ty key, pattern_ty pattern) |
435 | { |
436 | KeyPatternPair *a = _PyArena_Malloc(p->arena, sizeof(KeyPatternPair)); |
437 | if (!a) { Branch (437:9): [True: 0, False: 748]
|
438 | return NULL; |
439 | } |
440 | a->key = key; |
441 | a->pattern = pattern; |
442 | return a; |
443 | } |
444 | |
445 | /* Extracts all keys from an asdl_seq* of KeyPatternPair*'s */ |
446 | asdl_expr_seq * |
447 | _PyPegen_get_pattern_keys(Parser *p, asdl_seq *seq) |
448 | { |
449 | Py_ssize_t len = asdl_seq_LEN(seq); |
450 | asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(len, p->arena); |
451 | if (!new_seq) { Branch (451:9): [True: 0, False: 322]
|
452 | return NULL; |
453 | } |
454 | for (Py_ssize_t i = 0; 322 i < len; i++418 ) { Branch (454:28): [True: 418, False: 322]
|
455 | KeyPatternPair *pair = asdl_seq_GET_UNTYPED(seq, i); |
456 | asdl_seq_SET(new_seq, i, pair->key); |
457 | } |
458 | return new_seq; |
459 | } |
460 | |
461 | /* Extracts all patterns from an asdl_seq* of KeyPatternPair*'s */ |
462 | asdl_pattern_seq * |
463 | _PyPegen_get_patterns(Parser *p, asdl_seq *seq) |
464 | { |
465 | Py_ssize_t len = asdl_seq_LEN(seq); |
466 | asdl_pattern_seq *new_seq = _Py_asdl_pattern_seq_new(len, p->arena); |
467 | if (!new_seq) { Branch (467:9): [True: 0, False: 322]
|
468 | return NULL; |
469 | } |
470 | for (Py_ssize_t i = 0; 322 i < len; i++418 ) { Branch (470:28): [True: 418, False: 322]
|
471 | KeyPatternPair *pair = asdl_seq_GET_UNTYPED(seq, i); |
472 | asdl_seq_SET(new_seq, i, pair->pattern); |
473 | } |
474 | return new_seq; |
475 | } |
476 | |
477 | /* Constructs a NameDefaultPair */ |
478 | NameDefaultPair * |
479 | _PyPegen_name_default_pair(Parser *p, arg_ty arg, expr_ty value, Token *tc) |
480 | { |
481 | NameDefaultPair *a = _PyArena_Malloc(p->arena, sizeof(NameDefaultPair)); |
482 | if (!a) { Branch (482:9): [True: 0, False: 20.1k]
|
483 | return NULL; |
484 | } |
485 | a->arg = _PyPegen_add_type_comment_to_arg(p, arg, tc); |
486 | a->value = value; |
487 | return a; |
488 | } |
489 | |
490 | /* Constructs a SlashWithDefault */ |
491 | SlashWithDefault * |
492 | _PyPegen_slash_with_default(Parser *p, asdl_arg_seq *plain_names, asdl_seq *names_with_defaults) |
493 | { |
494 | SlashWithDefault *a = _PyArena_Malloc(p->arena, sizeof(SlashWithDefault)); |
495 | if (!a) { Branch (495:9): [True: 0, False: 198]
|
496 | return NULL; |
497 | } |
498 | a->plain_names = plain_names; |
499 | a->names_with_defaults = names_with_defaults; |
500 | return a; |
501 | } |
502 | |
503 | /* Constructs a StarEtc */ |
504 | StarEtc * |
505 | _PyPegen_star_etc(Parser *p, arg_ty vararg, asdl_seq *kwonlyargs, arg_ty kwarg) |
506 | { |
507 | StarEtc *a = _PyArena_Malloc(p->arena, sizeof(StarEtc)); |
508 | if (!a) { Branch (508:9): [True: 0, False: 3.56k]
|
509 | return NULL; |
510 | } |
511 | a->vararg = vararg; |
512 | a->kwonlyargs = kwonlyargs; |
513 | a->kwarg = kwarg; |
514 | return a; |
515 | } |
516 | |
517 | asdl_seq * |
518 | _PyPegen_join_sequences(Parser *p, asdl_seq *a, asdl_seq *b) |
519 | { |
520 | Py_ssize_t first_len = asdl_seq_LEN(a); |
521 | Py_ssize_t second_len = asdl_seq_LEN(b); |
522 | asdl_seq *new_seq = (asdl_seq*)_Py_asdl_generic_seq_new(first_len + second_len, p->arena); |
523 | if (!new_seq) { Branch (523:9): [True: 0, False: 28.0k]
|
524 | return NULL; |
525 | } |
526 | |
527 | int k = 0; |
528 | for (Py_ssize_t i = 0; i < first_len; i++50.6k ) { Branch (528:28): [True: 50.6k, False: 28.0k]
|
529 | asdl_seq_SET_UNTYPED(new_seq, k++, asdl_seq_GET_UNTYPED(a, i)); |
530 | } |
531 | for (Py_ssize_t i = 0; i < second_len; i++5.02k ) { Branch (531:28): [True: 5.02k, False: 28.0k]
|
532 | asdl_seq_SET_UNTYPED(new_seq, k++, asdl_seq_GET_UNTYPED(b, i)); |
533 | } |
534 | |
535 | return new_seq; |
536 | } |
537 | |
538 | static asdl_arg_seq* |
539 | _get_names(Parser *p, asdl_seq *names_with_defaults) |
540 | { |
541 | Py_ssize_t len = asdl_seq_LEN(names_with_defaults); |
542 | asdl_arg_seq *seq = _Py_asdl_arg_seq_new(len, p->arena); |
543 | if (!seq) { Branch (543:9): [True: 0, False: 31.6k]
|
544 | return NULL; |
545 | } |
546 | for (Py_ssize_t i = 0; 31.6k i < len; i++9.60k ) { Branch (546:28): [True: 9.60k, False: 31.6k]
|
547 | NameDefaultPair *pair = asdl_seq_GET_UNTYPED(names_with_defaults, i); |
548 | asdl_seq_SET(seq, i, pair->arg); |
549 | } |
550 | return seq; |
551 | } |
552 | |
553 | static asdl_expr_seq * |
554 | _get_defaults(Parser *p, asdl_seq *names_with_defaults) |
555 | { |
556 | Py_ssize_t len = asdl_seq_LEN(names_with_defaults); |
557 | asdl_expr_seq *seq = _Py_asdl_expr_seq_new(len, p->arena); |
558 | if (!seq) { Branch (558:9): [True: 0, False: 31.6k]
|
559 | return NULL; |
560 | } |
561 | for (Py_ssize_t i = 0; 31.6k i < len; i++9.60k ) { Branch (561:28): [True: 9.60k, False: 31.6k]
|
562 | NameDefaultPair *pair = asdl_seq_GET_UNTYPED(names_with_defaults, i); |
563 | asdl_seq_SET(seq, i, pair->value); |
564 | } |
565 | return seq; |
566 | } |
567 | |
568 | static int |
569 | _make_posonlyargs(Parser *p, |
570 | asdl_arg_seq *slash_without_default, |
571 | SlashWithDefault *slash_with_default, |
572 | asdl_arg_seq **posonlyargs) { |
573 | if (slash_without_default != NULL) { Branch (573:9): [True: 443, False: 28.6k]
|
574 | *posonlyargs = slash_without_default; |
575 | } |
576 | else if (slash_with_default != NULL) { Branch (576:14): [True: 181, False: 28.4k]
|
577 | asdl_arg_seq *slash_with_default_names = |
578 | _get_names(p, slash_with_default->names_with_defaults); |
579 | if (!slash_with_default_names) { Branch (579:13): [True: 0, False: 181]
|
580 | return -1; |
581 | } |
582 | *posonlyargs = (asdl_arg_seq*)_PyPegen_join_sequences( |
583 | p, |
584 | (asdl_seq*)slash_with_default->plain_names, |
585 | (asdl_seq*)slash_with_default_names); |
586 | } |
587 | else { |
588 | *posonlyargs = _Py_asdl_arg_seq_new(0, p->arena); |
589 | } |
590 | return *posonlyargs == NULL ? -10 : 0; Branch (590:12): [True: 0, False: 29.0k]
|
591 | } |
592 | |
593 | static int |
594 | _make_posargs(Parser *p, |
595 | asdl_arg_seq *plain_names, |
596 | asdl_seq *names_with_default, |
597 | asdl_arg_seq **posargs) { |
598 | if (plain_names != NULL && names_with_default != NULL27.5k ) { Branch (598:9): [True: 27.5k, False: 1.51k]
Branch (598:32): [True: 27.5k, False: 0]
|
599 | asdl_arg_seq *names_with_default_names = _get_names(p, names_with_default); |
600 | if (!names_with_default_names) { Branch (600:13): [True: 0, False: 27.5k]
|
601 | return -1; |
602 | } |
603 | *posargs = (asdl_arg_seq*)_PyPegen_join_sequences( |
604 | p,(asdl_seq*)plain_names, (asdl_seq*)names_with_default_names); |
605 | } |
606 | else if (plain_names == NULL && names_with_default != NULL) { Branch (606:14): [True: 1.51k, False: 0]
Branch (606:37): [True: 558, False: 954]
|
607 | *posargs = _get_names(p, names_with_default); |
608 | } |
609 | else if (plain_names != NULL && names_with_default == NULL0 ) { Branch (609:14): [True: 0, False: 954]
Branch (609:37): [True: 0, False: 0]
|
610 | *posargs = plain_names; |
611 | } |
612 | else { |
613 | *posargs = _Py_asdl_arg_seq_new(0, p->arena); |
614 | } |
615 | return *posargs == NULL ? -10 : 0; Branch (615:12): [True: 0, False: 29.0k]
|
616 | } |
617 | |
618 | static int |
619 | _make_posdefaults(Parser *p, |
620 | SlashWithDefault *slash_with_default, |
621 | asdl_seq *names_with_default, |
622 | asdl_expr_seq **posdefaults) { |
623 | if (slash_with_default != NULL && names_with_default != NULL181 ) { Branch (623:9): [True: 181, False: 28.9k]
Branch (623:39): [True: 181, False: 0]
|
624 | asdl_expr_seq *slash_with_default_values = |
625 | _get_defaults(p, slash_with_default->names_with_defaults); |
626 | if (!slash_with_default_values) { Branch (626:13): [True: 0, False: 181]
|
627 | return -1; |
628 | } |
629 | asdl_expr_seq *names_with_default_values = _get_defaults(p, names_with_default); |
630 | if (!names_with_default_values) { Branch (630:13): [True: 0, False: 181]
|
631 | return -1; |
632 | } |
633 | *posdefaults = (asdl_expr_seq*)_PyPegen_join_sequences( |
634 | p, |
635 | (asdl_seq*)slash_with_default_values, |
636 | (asdl_seq*)names_with_default_values); |
637 | } |
638 | else if (slash_with_default == NULL && names_with_default != NULL) { Branch (638:14): [True: 28.9k, False: 0]
Branch (638:44): [True: 27.9k, False: 954]
|
639 | *posdefaults = _get_defaults(p, names_with_default); |
640 | } |
641 | else if (slash_with_default != NULL && names_with_default == NULL0 ) { Branch (641:14): [True: 0, False: 954]
Branch (641:44): [True: 0, False: 0]
|
642 | *posdefaults = _get_defaults(p, slash_with_default->names_with_defaults); |
643 | } |
644 | else { |
645 | *posdefaults = _Py_asdl_expr_seq_new(0, p->arena); |
646 | } |
647 | return *posdefaults == NULL ? -10 : 0; Branch (647:12): [True: 0, False: 29.0k]
|
648 | } |
649 | |
650 | static int |
651 | _make_kwargs(Parser *p, StarEtc *star_etc, |
652 | asdl_arg_seq **kwonlyargs, |
653 | asdl_expr_seq **kwdefaults) { |
654 | if (star_etc != NULL && star_etc->kwonlyargs != NULL3.56k ) { Branch (654:9): [True: 3.56k, False: 25.5k]
Branch (654:29): [True: 3.31k, False: 247]
|
655 | *kwonlyargs = _get_names(p, star_etc->kwonlyargs); |
656 | } |
657 | else { |
658 | *kwonlyargs = _Py_asdl_arg_seq_new(0, p->arena); |
659 | } |
660 | |
661 | if (*kwonlyargs == NULL) { Branch (661:9): [True: 0, False: 29.0k]
|
662 | return -1; |
663 | } |
664 | |
665 | if (star_etc != NULL && star_etc->kwonlyargs != NULL3.56k ) { Branch (665:9): [True: 3.56k, False: 25.5k]
Branch (665:29): [True: 3.31k, False: 247]
|
666 | *kwdefaults = _get_defaults(p, star_etc->kwonlyargs); |
667 | } |
668 | else { |
669 | *kwdefaults = _Py_asdl_expr_seq_new(0, p->arena); |
670 | } |
671 | |
672 | if (*kwdefaults == NULL) { Branch (672:9): [True: 0, False: 29.0k]
|
673 | return -1; |
674 | } |
675 | |
676 | return 0; |
677 | } |
678 | |
679 | /* Constructs an arguments_ty object out of all the parsed constructs in the parameters rule */ |
680 | arguments_ty |
681 | _PyPegen_make_arguments(Parser *p, asdl_arg_seq *slash_without_default, |
682 | SlashWithDefault *slash_with_default, asdl_arg_seq *plain_names, |
683 | asdl_seq *names_with_default, StarEtc *star_etc) |
684 | { |
685 | asdl_arg_seq *posonlyargs; |
686 | if (_make_posonlyargs(p, slash_without_default, slash_with_default, &posonlyargs) == -1) { Branch (686:9): [True: 0, False: 29.0k]
|
687 | return NULL; |
688 | } |
689 | |
690 | asdl_arg_seq *posargs; |
691 | if (_make_posargs(p, plain_names, names_with_default, &posargs) == -1) { Branch (691:9): [True: 0, False: 29.0k]
|
692 | return NULL; |
693 | } |
694 | |
695 | asdl_expr_seq *posdefaults; |
696 | if (_make_posdefaults(p,slash_with_default, names_with_default, &posdefaults) == -1) { Branch (696:9): [True: 0, False: 29.0k]
|
697 | return NULL; |
698 | } |
699 | |
700 | arg_ty vararg = NULL; |
701 | if (star_etc != NULL && star_etc->vararg != NULL3.56k ) { Branch (701:9): [True: 3.56k, False: 25.5k]
Branch (701:29): [True: 2.15k, False: 1.40k]
|
702 | vararg = star_etc->vararg; |
703 | } |
704 | |
705 | asdl_arg_seq *kwonlyargs; |
706 | asdl_expr_seq *kwdefaults; |
707 | if (_make_kwargs(p, star_etc, &kwonlyargs, &kwdefaults) == -1) { Branch (707:9): [True: 0, False: 29.0k]
|
708 | return NULL; |
709 | } |
710 | |
711 | arg_ty kwarg = NULL; |
712 | if (star_etc != NULL && star_etc->kwarg != NULL3.56k ) { Branch (712:9): [True: 3.56k, False: 25.5k]
Branch (712:29): [True: 1.85k, False: 1.70k]
|
713 | kwarg = star_etc->kwarg; |
714 | } |
715 | |
716 | return _PyAST_arguments(posonlyargs, posargs, vararg, kwonlyargs, |
717 | kwdefaults, kwarg, posdefaults, p->arena); |
718 | } |
719 | |
720 | |
721 | /* Constructs an empty arguments_ty object, that gets used when a function accepts no |
722 | * arguments. */ |
723 | arguments_ty |
724 | _PyPegen_empty_arguments(Parser *p) |
725 | { |
726 | asdl_arg_seq *posonlyargs = _Py_asdl_arg_seq_new(0, p->arena); |
727 | if (!posonlyargs) { Branch (727:9): [True: 0, False: 5.48k]
|
728 | return NULL; |
729 | } |
730 | asdl_arg_seq *posargs = _Py_asdl_arg_seq_new(0, p->arena); |
731 | if (!posargs) { Branch (731:9): [True: 0, False: 5.48k]
|
732 | return NULL; |
733 | } |
734 | asdl_expr_seq *posdefaults = _Py_asdl_expr_seq_new(0, p->arena); |
735 | if (!posdefaults) { Branch (735:9): [True: 0, False: 5.48k]
|
736 | return NULL; |
737 | } |
738 | asdl_arg_seq *kwonlyargs = _Py_asdl_arg_seq_new(0, p->arena); |
739 | if (!kwonlyargs) { Branch (739:9): [True: 0, False: 5.48k]
|
740 | return NULL; |
741 | } |
742 | asdl_expr_seq *kwdefaults = _Py_asdl_expr_seq_new(0, p->arena); |
743 | if (!kwdefaults) { Branch (743:9): [True: 0, False: 5.48k]
|
744 | return NULL; |
745 | } |
746 | |
747 | return _PyAST_arguments(posonlyargs, posargs, NULL, kwonlyargs, |
748 | kwdefaults, NULL, posdefaults, p->arena); |
749 | } |
750 | |
751 | /* Encapsulates the value of an operator_ty into an AugOperator struct */ |
752 | AugOperator * |
753 | _PyPegen_augoperator(Parser *p, operator_ty kind) |
754 | { |
755 | AugOperator *a = _PyArena_Malloc(p->arena, sizeof(AugOperator)); |
756 | if (!a) { Branch (756:9): [True: 0, False: 2.16k]
|
757 | return NULL; |
758 | } |
759 | a->kind = kind; |
760 | return a; |
761 | } |
762 | |
763 | /* Construct a FunctionDef equivalent to function_def, but with decorators */ |
764 | stmt_ty |
765 | _PyPegen_function_def_decorators(Parser *p, asdl_expr_seq *decorators, stmt_ty function_def) |
766 | { |
767 | assert(function_def != NULL); |
768 | if (function_def->kind == AsyncFunctionDef_kind) { Branch (768:9): [True: 17, False: 2.14k]
|
769 | return _PyAST_AsyncFunctionDef( |
770 | function_def->v.FunctionDef.name, function_def->v.FunctionDef.args, |
771 | function_def->v.FunctionDef.body, decorators, function_def->v.FunctionDef.returns, |
772 | function_def->v.FunctionDef.type_comment, function_def->lineno, |
773 | function_def->col_offset, function_def->end_lineno, function_def->end_col_offset, |
774 | p->arena); |
775 | } |
776 | |
777 | return _PyAST_FunctionDef( |
778 | function_def->v.FunctionDef.name, function_def->v.FunctionDef.args, |
779 | function_def->v.FunctionDef.body, decorators, |
780 | function_def->v.FunctionDef.returns, |
781 | function_def->v.FunctionDef.type_comment, function_def->lineno, |
782 | function_def->col_offset, function_def->end_lineno, |
783 | function_def->end_col_offset, p->arena); |
784 | } |
785 | |
786 | /* Construct a ClassDef equivalent to class_def, but with decorators */ |
787 | stmt_ty |
788 | _PyPegen_class_def_decorators(Parser *p, asdl_expr_seq *decorators, stmt_ty class_def) |
789 | { |
790 | assert(class_def != NULL); |
791 | return _PyAST_ClassDef( |
792 | class_def->v.ClassDef.name, class_def->v.ClassDef.bases, |
793 | class_def->v.ClassDef.keywords, class_def->v.ClassDef.body, decorators, |
794 | class_def->lineno, class_def->col_offset, class_def->end_lineno, |
795 | class_def->end_col_offset, p->arena); |
796 | } |
797 | |
798 | /* Construct a KeywordOrStarred */ |
799 | KeywordOrStarred * |
800 | _PyPegen_keyword_or_starred(Parser *p, void *element, int is_keyword) |
801 | { |
802 | KeywordOrStarred *a = _PyArena_Malloc(p->arena, sizeof(KeywordOrStarred)); |
803 | if (!a) { Branch (803:9): [True: 0, False: 19.0k]
|
804 | return NULL; |
805 | } |
806 | a->element = element; |
807 | a->is_keyword = is_keyword; |
808 | return a; |
809 | } |
810 | |
811 | /* Get the number of starred expressions in an asdl_seq* of KeywordOrStarred*s */ |
812 | static int |
813 | _seq_number_of_starred_exprs(asdl_seq *seq) |
814 | { |
815 | int n = 0; |
816 | for (Py_ssize_t i = 0, l = asdl_seq_LEN11.9k (seq); i < l; i++20.2k ) { Branch (816:51): [True: 20.2k, False: 11.9k]
|
817 | KeywordOrStarred *k = asdl_seq_GET_UNTYPED(seq, i); |
818 | if (!k->is_keyword) { Branch (818:13): [True: 144, False: 20.0k]
|
819 | n++; |
820 | } |
821 | } |
822 | return n; |
823 | } |
824 | |
825 | /* Extract the starred expressions of an asdl_seq* of KeywordOrStarred*s */ |
826 | asdl_expr_seq * |
827 | _PyPegen_seq_extract_starred_exprs(Parser *p, asdl_seq *kwargs) |
828 | { |
829 | int new_len = _seq_number_of_starred_exprs(kwargs); |
830 | if (new_len == 0) { Branch (830:9): [True: 5.92k, False: 72]
|
831 | return NULL; |
832 | } |
833 | asdl_expr_seq *new_seq = _Py_asdl_expr_seq_new(new_len, p->arena); |
834 | if (!new_seq) { Branch (834:9): [True: 0, False: 72]
|
835 | return NULL; |
836 | } |
837 | |
838 | int idx = 0; |
839 | for (Py_ssize_t i = 0, len = asdl_seq_LEN72 (kwargs); i < len; i++228 ) { Branch (839:56): [True: 228, False: 72]
|
840 | KeywordOrStarred *k = asdl_seq_GET_UNTYPED(kwargs, i); |
841 | if (!k->is_keyword) { Branch (841:13): [True: 72, False: 156]
|
842 | asdl_seq_SET(new_seq, idx++, k->element); |
843 | } |
844 | } |
845 | return new_seq; |
846 | } |
847 | |
848 | /* Return a new asdl_seq* with only the keywords in kwargs */ |
849 | asdl_keyword_seq* |
850 | _PyPegen_seq_delete_starred_exprs(Parser *p, asdl_seq *kwargs) |
851 | { |
852 | Py_ssize_t len = asdl_seq_LEN(kwargs); |
853 | Py_ssize_t new_len = len - _seq_number_of_starred_exprs(kwargs); |
854 | if (new_len == 0) { Branch (854:9): [True: 0, False: 5.99k]
|
855 | return NULL; |
856 | } |
857 | asdl_keyword_seq *new_seq = _Py_asdl_keyword_seq_new(new_len, p->arena); |
858 | if (!new_seq) { Branch (858:9): [True: 0, False: 5.99k]
|
859 | return NULL; |
860 | } |
861 | |
862 | int idx = 0; |
863 | for (Py_ssize_t i = 0; i < len; i++10.1k ) { Branch (863:28): [True: 10.1k, False: 5.99k]
|
864 | KeywordOrStarred *k = asdl_seq_GET_UNTYPED(kwargs, i); |
865 | if (k->is_keyword) { Branch (865:13): [True: 10.0k, False: 72]
|
866 | asdl_seq_SET(new_seq, idx++, k->element); |
867 | } |
868 | } |
869 | return new_seq; |
870 | } |
871 | |
872 | expr_ty |
873 | _PyPegen_concatenate_strings(Parser *p, asdl_seq *strings) |
874 | { |
875 | Py_ssize_t len = asdl_seq_LEN(strings); |
876 | assert(len > 0); |
877 | |
878 | Token *first = asdl_seq_GET_UNTYPED(strings, 0); |
879 | Token *last = asdl_seq_GET_UNTYPED(strings, len - 1); |
880 | |
881 | int bytesmode = 0; |
882 | PyObject *bytes_str = NULL; |
883 | |
884 | FstringParser state; |
885 | _PyPegen_FstringParser_Init(&state); |
886 | |
887 | for (Py_ssize_t i = 0; i < len; i++205k ) { Branch (887:28): [True: 205k, False: 180k]
|
888 | Token *t = asdl_seq_GET_UNTYPED(strings, i); |
889 | |
890 | int this_bytesmode; |
891 | int this_rawmode; |
892 | PyObject *s; |
893 | const char *fstr; |
894 | Py_ssize_t fstrlen = -1; |
895 | |
896 | if (_PyPegen_parsestr(p, &this_bytesmode, &this_rawmode, &s, &fstr, &fstrlen, t) != 0) { Branch (896:13): [True: 177, False: 205k]
|
897 | goto error; |
898 | } |
899 | |
900 | /* Check that we are not mixing bytes with unicode. */ |
901 | if (i != 0 && bytesmode != this_bytesmode24.7k ) { Branch (901:13): [True: 24.7k, False: 180k]
Branch (901:23): [True: 2, False: 24.7k]
|
902 | RAISE_SYNTAX_ERROR("cannot mix bytes and nonbytes literals"); |
903 | Py_XDECREF(s); |
904 | goto error; |
905 | } |
906 | bytesmode = this_bytesmode; |
907 | |
908 | if (fstr != NULL) { Branch (908:13): [True: 4.43k, False: 201k]
|
909 | assert(s == NULL && !bytesmode); |
910 | |
911 | int result = _PyPegen_FstringParser_ConcatFstring(p, &state, &fstr, fstr + fstrlen, |
912 | this_rawmode, 0, first, t, last); |
913 | if (result < 0) { Branch (913:17): [True: 122, False: 4.30k]
|
914 | goto error; |
915 | } |
916 | } |
917 | else { |
918 | /* String or byte string. */ |
919 | assert(s != NULL && fstr == NULL); |
920 | assert(bytesmode ? PyBytes_CheckExact(s) : PyUnicode_CheckExact(s)); |
921 | |
922 | if (bytesmode) { Branch (922:17): [True: 4.25k, False: 196k]
|
923 | if (i == 0) { Branch (923:21): [True: 3.10k, False: 1.14k]
|
924 | bytes_str = s; |
925 | } |
926 | else { |
927 | PyBytes_ConcatAndDel(&bytes_str, s); |
928 | if (!bytes_str) { Branch (928:25): [True: 0, False: 1.14k]
|
929 | goto error; |
930 | } |
931 | } |
932 | } |
933 | else { |
934 | /* This is a regular string. Concatenate it. */ |
935 | if (_PyPegen_FstringParser_ConcatAndDel(&state, s) < 0) { Branch (935:21): [True: 0, False: 196k]
|
936 | goto error; |
937 | } |
938 | } |
939 | } |
940 | } |
941 | |
942 | if (bytesmode) { Branch (942:9): [True: 3.10k, False: 177k]
|
943 | if (_PyArena_AddPyObject(p->arena, bytes_str) < 0) { Branch (943:13): [True: 0, False: 3.10k]
|
944 | goto error; |
945 | } |
946 | return _PyAST_Constant(bytes_str, NULL, first->lineno, |
947 | first->col_offset, last->end_lineno, |
948 | last->end_col_offset, p->arena); |
949 | } |
950 | |
951 | return _PyPegen_FstringParser_Finish(p, &state, first, last); |
952 | |
953 | error: |
954 | Py_XDECREF(bytes_str); |
955 | _PyPegen_FstringParser_Dealloc(&state); |
956 | if (PyErr_Occurred()) { Branch (956:9): [True: 301, False: 0]
|
957 | _Pypegen_raise_decode_error(p); |
958 | } |
959 | return NULL; |
960 | } |
961 | |
962 | expr_ty |
963 | _PyPegen_ensure_imaginary(Parser *p, expr_ty exp) |
964 | { |
965 | if (exp->kind != Constant_kind || !PyComplex_CheckExact(exp->v.Constant.value)) { Branch (965:9): [True: 0, False: 38]
Branch (965:39): [True: 2, False: 36]
|
966 | RAISE_SYNTAX_ERROR_KNOWN_LOCATION(exp, "imaginary number required in complex literal"); |
967 | return NULL; |
968 | } |
969 | return exp; |
970 | } |
971 | |
972 | expr_ty |
973 | _PyPegen_ensure_real(Parser *p, expr_ty exp) |
974 | { |
975 | if (exp->kind != Constant_kind || PyComplex_CheckExact(exp->v.Constant.value)) { Branch (975:9): [True: 0, False: 63]
|
976 | RAISE_SYNTAX_ERROR_KNOWN_LOCATION(exp, "real number required in complex literal"); |
977 | return NULL; |
978 | } |
979 | return exp; |
980 | } |
981 | |
982 | mod_ty |
983 | _PyPegen_make_module(Parser *p, asdl_stmt_seq *a) { |
984 | asdl_type_ignore_seq *type_ignores = NULL; |
985 | Py_ssize_t num = p->type_ignore_comments.num_items; |
986 | if (num > 0) { Branch (986:9): [True: 29, False: 16.8k]
|
987 | // Turn the raw (comment, lineno) pairs into TypeIgnore objects in the arena |
988 | type_ignores = _Py_asdl_type_ignore_seq_new(num, p->arena); |
989 | if (type_ignores == NULL) { Branch (989:13): [True: 0, False: 29]
|
990 | return NULL; |
991 | } |
992 | for (int i = 0; 29 i < num; i++74 ) { Branch (992:25): [True: 74, False: 29]
|
993 | PyObject *tag = _PyPegen_new_type_comment(p, p->type_ignore_comments.items[i].comment); |
994 | if (tag == NULL) { Branch (994:17): [True: 0, False: 74]
|
995 | return NULL; |
996 | } |
997 | type_ignore_ty ti = _PyAST_TypeIgnore(p->type_ignore_comments.items[i].lineno, |
998 | tag, p->arena); |
999 | if (ti == NULL) { Branch (999:17): [True: 0, False: 74]
|
1000 | return NULL; |
1001 | } |
1002 | asdl_seq_SET(type_ignores, i, ti); |
1003 | } |
1004 | } |
1005 | return _PyAST_Module(a, type_ignores, p->arena); |
1006 | } |
1007 | |
1008 | PyObject * |
1009 | _PyPegen_new_type_comment(Parser *p, const char *s) |
1010 | { |
1011 | PyObject *res = PyUnicode_DecodeUTF8(s, strlen(s), NULL); |
1012 | if (res == NULL) { Branch (1012:9): [True: 0, False: 913]
|
1013 | return NULL; |
1014 | } |
1015 | if (_PyArena_AddPyObject(p->arena, res) < 0) { Branch (1015:9): [True: 0, False: 913]
|
1016 | Py_DECREF(res); |
1017 | return NULL; |
1018 | } |
1019 | return res; |
1020 | } |
1021 | |
1022 | arg_ty |
1023 | _PyPegen_add_type_comment_to_arg(Parser *p, arg_ty a, Token *tc) |
1024 | { |
1025 | if (tc == NULL) { Branch (1025:9): [True: 235k, False: 747]
|
1026 | return a; |
1027 | } |
1028 | const char *bytes = PyBytes_AsString(tc->bytes); |
1029 | if (bytes == NULL) { Branch (1029:9): [True: 0, False: 747]
|
1030 | return NULL; |
1031 | } |
1032 | PyObject *tco = _PyPegen_new_type_comment(p, bytes); |
1033 | if (tco == NULL) { Branch (1033:9): [True: 0, False: 747]
|
1034 | return NULL; |
1035 | } |
1036 | return _PyAST_arg(a->arg, a->annotation, tco, |
1037 | a->lineno, a->col_offset, a->end_lineno, a->end_col_offset, |
1038 | p->arena); |
1039 | } |
1040 | |
1041 | /* Checks if the NOTEQUAL token is valid given the current parser flags |
1042 | 0 indicates success and nonzero indicates failure (an exception may be set) */ |
1043 | int |
1044 | _PyPegen_check_barry_as_flufl(Parser *p, Token* t) { |
1045 | assert(t->bytes != NULL); |
1046 | assert(t->type == NOTEQUAL); |
1047 | |
1048 | const char* tok_str = PyBytes_AS_STRING(t->bytes); |
1049 | if (p->flags & PyPARSE_BARRY_AS_BDFL && strcmp(tok_str, "<>") != 02 ) { Branch (1049:9): [True: 2, False: 1.72k]
Branch (1049:45): [True: 1, False: 1]
|
1050 | RAISE_SYNTAX_ERROR("with Barry as BDFL, use '<>' instead of '!='"); |
1051 | return -1; |
1052 | } |
1053 | if (!(p->flags & PyPARSE_BARRY_AS_BDFL)) { Branch (1053:9): [True: 1.72k, False: 1]
|
1054 | return strcmp(tok_str, "!="); |
1055 | } |
1056 | return 0; |
1057 | } |
1058 | |
1059 | int |
1060 | _PyPegen_check_legacy_stmt(Parser *p, expr_ty name) { |
1061 | if (name->kind != Name_kind) { Branch (1061:9): [True: 17, False: 161]
|
1062 | return 0; |
1063 | } |
1064 | const char* candidates[2] = {"print", "exec"}; |
1065 | for (int i=0; i<2; i++247 ) { Branch (1065:19): [True: 292, False: 116]
|
1066 | if (PyUnicode_CompareWithASCIIString(name->v.Name.id, candidates[i]) == 0) { Branch (1066:13): [True: 45, False: 247]
|
1067 | return 1; |
1068 | } |
1069 | } |
1070 | return 0; |
1071 | } |
1072 | |
1073 | const char * |
1074 | _PyPegen_get_expr_name(expr_ty e) |
1075 | { |
1076 | assert(e != NULL); |
1077 | switch (e->kind) { |
1078 | case Attribute_kind: Branch (1078:9): [True: 2, False: 125]
|
1079 | return "attribute"; |
1080 | case Subscript_kind: Branch (1080:9): [True: 0, False: 127]
|
1081 | return "subscript"; |
1082 | case Starred_kind: Branch (1082:9): [True: 3, False: 124]
|
1083 | return "starred"; |
1084 | case Name_kind: Branch (1084:9): [True: 0, False: 127]
|
1085 | return "name"; |
1086 | case List_kind: Branch (1086:9): [True: 4, False: 123]
|
1087 | return "list"; |
1088 | case Tuple_kind: Branch (1088:9): [True: 8, False: 119]
|
1089 | return "tuple"; |
1090 | case Lambda_kind: Branch (1090:9): [True: 3, False: 124]
|
1091 | return "lambda"; |
1092 | case Call_kind: Branch (1092:9): [True: 29, False: 98]
|
1093 | return "function call"; |
1094 | case BoolOp_kind: Branch (1094:9): [True: 0, False: 127]
|
1095 | case BinOp_kind: Branch (1095:9): [True: 16, False: 111]
|
1096 | case UnaryOp_kind: Branch (1096:9): [True: 2, False: 125]
|
1097 | return "expression"; |
1098 | case GeneratorExp_kind: Branch (1098:9): [True: 4, False: 123]
|
1099 | return "generator expression"; |
1100 | case Yield_kind: Branch (1100:9): [True: 3, False: 124]
|
1101 | case YieldFrom_kind: Branch (1101:9): [True: 0, False: 127]
|
1102 | return "yield expression"; |
1103 | case Await_kind: Branch (1103:9): [True: 0, False: 127]
|
1104 | return "await expression"; |
1105 | case ListComp_kind: Branch (1105:9): [True: 4, False: 123]
|
1106 | return "list comprehension"; |
1107 | case SetComp_kind: Branch (1107:9): [True: 2, False: 125]
|
1108 | return "set comprehension"; |
1109 | case DictComp_kind: Branch (1109:9): [True: 2, False: 125]
|
1110 | return "dict comprehension"; |
1111 | case Dict_kind: Branch (1111:9): [True: 1, False: 126]
|
1112 | return "dict literal"; |
1113 | case Set_kind: Branch (1113:9): [True: 1, False: 126]
|
1114 | return "set display"; |
1115 | case JoinedStr_kind: Branch (1115:9): [True: 2, False: 125]
|
1116 | case FormattedValue_kind: Branch (1116:9): [True: 0, False: 127]
|
1117 | return "f-string expression"; |
1118 | case Constant_kind: { Branch (1118:9): [True: 38, False: 89]
|
1119 | PyObject *value = e->v.Constant.value; |
1120 | if (value == Py_None) { Branch (1120:17): [True: 17, False: 21]
|
1121 | return "None"; |
1122 | } |
1123 | if (value == Py_False) { Branch (1123:17): [True: 1, False: 20]
|
1124 | return "False"; |
1125 | } |
1126 | if (value == Py_True) { Branch (1126:17): [True: 7, False: 13]
|
1127 | return "True"; |
1128 | } |
1129 | if (value == Py_Ellipsis) { Branch (1129:17): [True: 1, False: 12]
|
1130 | return "ellipsis"; |
1131 | } |
1132 | return "literal"; |
1133 | } |
1134 | case Compare_kind: Branch (1134:9): [True: 0, False: 127]
|
1135 | return "comparison"; |
1136 | case IfExp_kind: Branch (1136:9): [True: 2, False: 125]
|
1137 | return "conditional expression"; |
1138 | case NamedExpr_kind: Branch (1138:9): [True: 1, False: 126]
|
1139 | return "named expression"; |
1140 | default: Branch (1140:9): [True: 0, False: 127]
|
1141 | PyErr_Format(PyExc_SystemError, |
1142 | "unexpected expression in assignment %d (line %d)", |
1143 | e->kind, e->lineno); |
1144 | return NULL; |
1145 | } |
1146 | } |
1147 | |
1148 | expr_ty |
1149 | _PyPegen_get_last_comprehension_item(comprehension_ty comprehension) { |
1150 | if (comprehension->ifs == NULL || asdl_seq_LEN(comprehension->ifs) == 0) { Branch (1150:9): [True: 0, False: 36]
Branch (1150:39): [True: 32, False: 4]
|
1151 | return comprehension->iter; |
1152 | } |
1153 | return PyPegen_last_item(comprehension->ifs, expr_ty); |
1154 | } |
1155 | |
1156 | expr_ty _PyPegen_collect_call_seqs(Parser *p, asdl_expr_seq *a, asdl_seq *b, |
1157 | int lineno, int col_offset, int end_lineno, |
1158 | int end_col_offset, PyArena *arena) { |
1159 | Py_ssize_t args_len = asdl_seq_LEN(a); |
1160 | Py_ssize_t total_len = args_len; |
1161 | |
1162 | if (b == NULL) { Branch (1162:9): [True: 86.7k, False: 3.95k]
|
1163 | return _PyAST_Call(_PyPegen_dummy_name(p), a, NULL, lineno, col_offset, |
1164 | end_lineno, end_col_offset, arena); |
1165 | |
1166 | } |
1167 | |
1168 | asdl_expr_seq *starreds = _PyPegen_seq_extract_starred_exprs(p, b); |
1169 | asdl_keyword_seq *keywords = _PyPegen_seq_delete_starred_exprs(p, b); |
1170 | |
1171 | if (starreds) { Branch (1171:9): [True: 61, False: 3.89k]
|
1172 | total_len += asdl_seq_LEN(starreds); |
1173 | } |
1174 | |
1175 | asdl_expr_seq *args = _Py_asdl_expr_seq_new(total_len, arena); |
1176 | |
1177 | Py_ssize_t i = 0; |
1178 | for (i = 0; i < args_len; i++6.23k ) { Branch (1178:17): [True: 6.23k, False: 3.95k]
|
1179 | asdl_seq_SET(args, i, asdl_seq_GET(a, i)); |
1180 | } |
1181 | for (; i < total_len; i++61 ) { Branch (1181:12): [True: 61, False: 3.95k]
|
1182 | asdl_seq_SET(args, i, asdl_seq_GET(starreds, i - args_len)); |
1183 | } |
1184 | |
1185 | return _PyAST_Call(_PyPegen_dummy_name(p), args, keywords, lineno, |
1186 | col_offset, end_lineno, end_col_offset, arena); |
1187 | } |
1188 | |
1189 | // AST Error reporting helpers |
1190 | |
1191 | expr_ty |
1192 | _PyPegen_get_invalid_target(expr_ty e, TARGETS_TYPE targets_type) |
1193 | { |
1194 | if (e == NULL) { Branch (1194:9): [True: 0, False: 183]
|
1195 | return NULL; |
1196 | } |
1197 | |
1198 | #define VISIT_CONTAINER(CONTAINER, TYPE) do 41 { \ |
1199 | Py_ssize_t len = asdl_seq_LEN((CONTAINER)->v.TYPE.elts);\ |
1200 | for (Py_ssize_t i = 0; i < len; i++43 ) {\ |
1201 | expr_ty other = asdl_seq_GET((CONTAINER)->v.TYPE.elts, i);\ |
1202 | expr_ty child = _PyPegen_get_invalid_target(other, targets_type);\ |
1203 | if (child != NULL) {\ |
1204 | return child;\ |
1205 | }\ |
1206 | }\ |
1207 | } while (02 ) |
1208 | |
1209 | // We only need to visit List and Tuple nodes recursively as those |
1210 | // are the only ones that can contain valid names in targets when |
1211 | // they are parsed as expressions. Any other kind of expression |
1212 | // that is a container (like Sets or Dicts) is directly invalid and |
1213 | // we don't need to visit it recursively. |
1214 | |
1215 | switch (e->kind) { |
1216 | case List_kind: Branch (1216:9): [True: 9, False: 174]
|
1217 | VISIT_CONTAINER(e, List); |
1218 | return NULL; |
1219 | case Tuple_kind: Branch (1219:9): [True: 32, False: 151]
|
1220 | VISIT_CONTAINER(e, Tuple); |
1221 | return NULL; |
1222 | case Starred_kind: Branch (1222:9): [True: 8, False: 175]
|
1223 | if (targets_type == DEL_TARGETS) { Branch (1223:17): [True: 3, False: 5]
|
1224 | return e; |
1225 | } |
1226 | return _PyPegen_get_invalid_target(e->v.Starred.value, targets_type); |
1227 | case Compare_kind: Branch (1227:9): [True: 13, False: 170]
|
1228 | // This is needed, because the `a in b` in `for a in b` gets parsed |
1229 | // as a comparison, and so we need to search the left side of the comparison |
1230 | // for invalid targets. |
1231 | if (targets_type == FOR_TARGETS) { Branch (1231:17): [True: 13, False: 0]
|
1232 | cmpop_ty cmpop = (cmpop_ty) asdl_seq_GET(e->v.Compare.ops, 0); |
1233 | if (cmpop == In) { Branch (1233:21): [True: 12, False: 1]
|
1234 | return _PyPegen_get_invalid_target(e->v.Compare.left, targets_type); |
1235 | } |
1236 | return NULL; |
1237 | } |
1238 | return e; |
1239 | case Name_kind: Branch (1239:9): [True: 46, False: 137]
|
1240 | case Subscript_kind: Branch (1240:9): [True: 2, False: 181]
|
1241 | case Attribute_kind: Branch (1241:9): [True: 1, False: 182]
|
1242 | return NULL; |
1243 | default: Branch (1243:9): [True: 72, False: 111]
|
1244 | return e; |
1245 | } |
1246 | } |
1247 | |
1248 | void *_PyPegen_arguments_parsing_error(Parser *p, expr_ty e) { |
1249 | int kwarg_unpacking = 0; |
1250 | for (Py_ssize_t i = 0, l = asdl_seq_LEN11 (e->v.Call.keywords); i < l; i++12 ) { Branch (1250:66): [True: 12, False: 11]
|
1251 | keyword_ty keyword = asdl_seq_GET(e->v.Call.keywords, i); |
1252 | if (!keyword->arg) { Branch (1252:13): [True: 1, False: 11]
|
1253 | kwarg_unpacking = 1; |
1254 | } |
1255 | } |
1256 | |
1257 | const char *msg = NULL; |
1258 | if (kwarg_unpacking) { Branch (1258:9): [True: 1, False: 10]
|
1259 | msg = "positional argument follows keyword argument unpacking"; |
1260 | } else { |
1261 | msg = "positional argument follows keyword argument"; |
1262 | } |
1263 | |
1264 | return RAISE_SYNTAX_ERROR(msg); |
1265 | } |
1266 | |
1267 | void * |
1268 | _PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args, asdl_comprehension_seq *comprehensions) |
1269 | { |
1270 | /* The rule that calls this function is 'args for_if_clauses'. |
1271 | For the input f(L, x for x in y), L and x are in args and |
1272 | the for is parsed as a for_if_clause. We have to check if |
1273 | len <= 1, so that input like dict((a, b) for a, b in x) |
1274 | gets successfully parsed and then we pass the last |
1275 | argument (x in the above example) as the location of the |
1276 | error */ |
1277 | Py_ssize_t len = asdl_seq_LEN(args->v.Call.args); |
1278 | if (len <= 1) { Branch (1278:9): [True: 2, False: 8]
|
1279 | return NULL; |
1280 | } |
1281 | |
1282 | comprehension_ty last_comprehension = PyPegen_last_item(comprehensions, comprehension_ty); |
1283 | |
1284 | return RAISE_SYNTAX_ERROR_KNOWN_RANGE( |
1285 | (expr_ty) asdl_seq_GET(args->v.Call.args, len - 1), |
1286 | _PyPegen_get_last_comprehension_item(last_comprehension), |
1287 | "Generator expression must be parenthesized" |
1288 | ); |
1289 | } |