comparison src/vim9type.c @ 21711:d2dee69de7c7 v8.2.1405

patch 8.2.1405: Vim9: vim9compile.c is getting too big Commit: https://github.com/vim/vim/commit/a7cc9e697b9140da66a09f71cdf839d08e32f5fb Author: Bram Moolenaar <Bram@vim.org> Date: Sun Aug 9 15:25:14 2020 +0200 patch 8.2.1405: Vim9: vim9compile.c is getting too big Problem: Vim9: vim9compile.c is getting too big. Solution: Split off type code to vim9type.c.
author Bram Moolenaar <Bram@vim.org>
date Sun, 09 Aug 2020 15:30:04 +0200
parents
children 571832713efa
comparison
equal deleted inserted replaced
21710:966d5daed211 21711:d2dee69de7c7
1 /* vi:set ts=8 sts=4 sw=4 noet:
2 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9
10 /*
11 * vim9type.c: handling of types
12 */
13
14 #define USING_FLOAT_STUFF
15 #include "vim.h"
16
17 #if defined(FEAT_EVAL) || defined(PROTO)
18
19 #ifdef VMS
20 # include <float.h>
21 #endif
22
23 /*
24 * Allocate memory for a type_T and add the pointer to type_gap, so that it can
25 * be freed later.
26 */
27 static type_T *
28 alloc_type(garray_T *type_gap)
29 {
30 type_T *type;
31
32 if (ga_grow(type_gap, 1) == FAIL)
33 return NULL;
34 type = ALLOC_CLEAR_ONE(type_T);
35 if (type != NULL)
36 {
37 ((type_T **)type_gap->ga_data)[type_gap->ga_len] = type;
38 ++type_gap->ga_len;
39 }
40 return type;
41 }
42
43 void
44 clear_type_list(garray_T *gap)
45 {
46 while (gap->ga_len > 0)
47 vim_free(((type_T **)gap->ga_data)[--gap->ga_len]);
48 ga_clear(gap);
49 }
50
51 type_T *
52 get_list_type(type_T *member_type, garray_T *type_gap)
53 {
54 type_T *type;
55
56 // recognize commonly used types
57 if (member_type->tt_type == VAR_ANY)
58 return &t_list_any;
59 if (member_type->tt_type == VAR_VOID
60 || member_type->tt_type == VAR_UNKNOWN)
61 return &t_list_empty;
62 if (member_type->tt_type == VAR_BOOL)
63 return &t_list_bool;
64 if (member_type->tt_type == VAR_NUMBER)
65 return &t_list_number;
66 if (member_type->tt_type == VAR_STRING)
67 return &t_list_string;
68
69 // Not a common type, create a new entry.
70 type = alloc_type(type_gap);
71 if (type == NULL)
72 return &t_any;
73 type->tt_type = VAR_LIST;
74 type->tt_member = member_type;
75 type->tt_argcount = 0;
76 type->tt_args = NULL;
77 return type;
78 }
79
80 type_T *
81 get_dict_type(type_T *member_type, garray_T *type_gap)
82 {
83 type_T *type;
84
85 // recognize commonly used types
86 if (member_type->tt_type == VAR_ANY)
87 return &t_dict_any;
88 if (member_type->tt_type == VAR_VOID
89 || member_type->tt_type == VAR_UNKNOWN)
90 return &t_dict_empty;
91 if (member_type->tt_type == VAR_BOOL)
92 return &t_dict_bool;
93 if (member_type->tt_type == VAR_NUMBER)
94 return &t_dict_number;
95 if (member_type->tt_type == VAR_STRING)
96 return &t_dict_string;
97
98 // Not a common type, create a new entry.
99 type = alloc_type(type_gap);
100 if (type == NULL)
101 return &t_any;
102 type->tt_type = VAR_DICT;
103 type->tt_member = member_type;
104 type->tt_argcount = 0;
105 type->tt_args = NULL;
106 return type;
107 }
108
109 /*
110 * Allocate a new type for a function.
111 */
112 type_T *
113 alloc_func_type(type_T *ret_type, int argcount, garray_T *type_gap)
114 {
115 type_T *type = alloc_type(type_gap);
116
117 if (type == NULL)
118 return &t_any;
119 type->tt_type = VAR_FUNC;
120 type->tt_member = ret_type;
121 type->tt_argcount = argcount;
122 type->tt_args = NULL;
123 return type;
124 }
125
126 /*
127 * Get a function type, based on the return type "ret_type".
128 * If "argcount" is -1 or 0 a predefined type can be used.
129 * If "argcount" > 0 always create a new type, so that arguments can be added.
130 */
131 type_T *
132 get_func_type(type_T *ret_type, int argcount, garray_T *type_gap)
133 {
134 // recognize commonly used types
135 if (argcount <= 0)
136 {
137 if (ret_type == &t_unknown)
138 {
139 // (argcount == 0) is not possible
140 return &t_func_unknown;
141 }
142 if (ret_type == &t_void)
143 {
144 if (argcount == 0)
145 return &t_func_0_void;
146 else
147 return &t_func_void;
148 }
149 if (ret_type == &t_any)
150 {
151 if (argcount == 0)
152 return &t_func_0_any;
153 else
154 return &t_func_any;
155 }
156 if (ret_type == &t_number)
157 {
158 if (argcount == 0)
159 return &t_func_0_number;
160 else
161 return &t_func_number;
162 }
163 if (ret_type == &t_string)
164 {
165 if (argcount == 0)
166 return &t_func_0_string;
167 else
168 return &t_func_string;
169 }
170 }
171
172 return alloc_func_type(ret_type, argcount, type_gap);
173 }
174
175 /*
176 * For a function type, reserve space for "argcount" argument types (including
177 * vararg).
178 */
179 int
180 func_type_add_arg_types(
181 type_T *functype,
182 int argcount,
183 garray_T *type_gap)
184 {
185 // To make it easy to free the space needed for the argument types, add the
186 // pointer to type_gap.
187 if (ga_grow(type_gap, 1) == FAIL)
188 return FAIL;
189 functype->tt_args = ALLOC_CLEAR_MULT(type_T *, argcount);
190 if (functype->tt_args == NULL)
191 return FAIL;
192 ((type_T **)type_gap->ga_data)[type_gap->ga_len] =
193 (void *)functype->tt_args;
194 ++type_gap->ga_len;
195 return OK;
196 }
197
198 /*
199 * Get a type_T for a typval_T.
200 * "type_list" is used to temporarily create types in.
201 */
202 type_T *
203 typval2type(typval_T *tv, garray_T *type_gap)
204 {
205 type_T *actual;
206 type_T *member_type;
207
208 if (tv->v_type == VAR_NUMBER)
209 return &t_number;
210 if (tv->v_type == VAR_BOOL)
211 return &t_bool; // not used
212 if (tv->v_type == VAR_STRING)
213 return &t_string;
214
215 if (tv->v_type == VAR_LIST)
216 {
217 if (tv->vval.v_list == NULL || tv->vval.v_list->lv_first == NULL)
218 return &t_list_empty;
219
220 // Use the type of the first member, it is the most specific.
221 member_type = typval2type(&tv->vval.v_list->lv_first->li_tv, type_gap);
222 return get_list_type(member_type, type_gap);
223 }
224
225 if (tv->v_type == VAR_DICT)
226 {
227 dict_iterator_T iter;
228 typval_T *value;
229
230 if (tv->vval.v_dict == NULL
231 || tv->vval.v_dict->dv_hashtab.ht_used == 0)
232 return &t_dict_empty;
233
234 // Use the type of the first value, it is the most specific.
235 dict_iterate_start(tv, &iter);
236 dict_iterate_next(&iter, &value);
237 member_type = typval2type(value, type_gap);
238 return get_dict_type(member_type, type_gap);
239 }
240
241 if (tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL)
242 {
243 char_u *name = NULL;
244 ufunc_T *ufunc = NULL;
245
246 if (tv->v_type == VAR_PARTIAL)
247 {
248 if (tv->vval.v_partial->pt_func != NULL)
249 ufunc = tv->vval.v_partial->pt_func;
250 else
251 name = tv->vval.v_partial->pt_name;
252 }
253 else
254 name = tv->vval.v_string;
255 if (name != NULL)
256 // TODO: how about a builtin function?
257 ufunc = find_func(name, FALSE, NULL);
258 if (ufunc != NULL)
259 {
260 // May need to get the argument types from default values by
261 // compiling the function.
262 if (ufunc->uf_def_status == UF_TO_BE_COMPILED
263 && compile_def_function(ufunc, TRUE, NULL) == FAIL)
264 return NULL;
265 if (ufunc->uf_func_type != NULL)
266 return ufunc->uf_func_type;
267 }
268 }
269
270 actual = alloc_type(type_gap);
271 if (actual == NULL)
272 return NULL;
273 actual->tt_type = tv->v_type;
274 actual->tt_member = &t_any;
275
276 return actual;
277 }
278
279 /*
280 * Get a type_T for a typval_T, used for v: variables.
281 * "type_list" is used to temporarily create types in.
282 */
283 type_T *
284 typval2type_vimvar(typval_T *tv, garray_T *type_gap)
285 {
286 if (tv->v_type == VAR_LIST) // e.g. for v:oldfiles
287 return &t_list_string;
288 if (tv->v_type == VAR_DICT) // e.g. for v:completed_item
289 return &t_dict_any;
290 return typval2type(tv, type_gap);
291 }
292
293
294 /*
295 * Return FAIL if "expected" and "actual" don't match.
296 */
297 int
298 check_typval_type(type_T *expected, typval_T *actual_tv)
299 {
300 garray_T type_list;
301 type_T *actual_type;
302 int res = FAIL;
303
304 ga_init2(&type_list, sizeof(type_T *), 10);
305 actual_type = typval2type(actual_tv, &type_list);
306 if (actual_type != NULL)
307 res = check_type(expected, actual_type, TRUE);
308 clear_type_list(&type_list);
309 return res;
310 }
311
312 void
313 type_mismatch(type_T *expected, type_T *actual)
314 {
315 char *tofree1, *tofree2;
316
317 semsg(_("E1013: type mismatch, expected %s but got %s"),
318 type_name(expected, &tofree1), type_name(actual, &tofree2));
319 vim_free(tofree1);
320 vim_free(tofree2);
321 }
322
323 void
324 arg_type_mismatch(type_T *expected, type_T *actual, int argidx)
325 {
326 char *tofree1, *tofree2;
327
328 semsg(_("E1013: argument %d: type mismatch, expected %s but got %s"),
329 argidx,
330 type_name(expected, &tofree1), type_name(actual, &tofree2));
331 vim_free(tofree1);
332 vim_free(tofree2);
333 }
334
335 /*
336 * Check if the expected and actual types match.
337 * Does not allow for assigning "any" to a specific type.
338 */
339 int
340 check_type(type_T *expected, type_T *actual, int give_msg)
341 {
342 int ret = OK;
343
344 // When expected is "unknown" we accept any actual type.
345 // When expected is "any" we accept any actual type except "void".
346 if (expected->tt_type != VAR_UNKNOWN
347 && !(expected->tt_type == VAR_ANY && actual->tt_type != VAR_VOID))
348
349 {
350 if (expected->tt_type != actual->tt_type)
351 {
352 if (give_msg)
353 type_mismatch(expected, actual);
354 return FAIL;
355 }
356 if (expected->tt_type == VAR_DICT || expected->tt_type == VAR_LIST)
357 {
358 // "unknown" is used for an empty list or dict
359 if (actual->tt_member != &t_unknown)
360 ret = check_type(expected->tt_member, actual->tt_member, FALSE);
361 }
362 else if (expected->tt_type == VAR_FUNC)
363 {
364 if (expected->tt_member != &t_unknown)
365 ret = check_type(expected->tt_member, actual->tt_member, FALSE);
366 if (ret == OK && expected->tt_argcount != -1
367 && (actual->tt_argcount < expected->tt_min_argcount
368 || actual->tt_argcount > expected->tt_argcount))
369 ret = FAIL;
370 if (expected->tt_args != NULL && actual->tt_args != NULL)
371 {
372 int i;
373
374 for (i = 0; i < expected->tt_argcount; ++i)
375 // Allow for using "any" argument type, lambda's have them.
376 if (actual->tt_args[i] != &t_any && check_type(
377 expected->tt_args[i], actual->tt_args[i], FALSE)
378 == FAIL)
379 {
380 ret = FAIL;
381 break;
382 }
383 }
384 }
385 if (ret == FAIL && give_msg)
386 type_mismatch(expected, actual);
387 }
388 return ret;
389 }
390
391 /*
392 * Skip over a type definition and return a pointer to just after it.
393 * When "optional" is TRUE then a leading "?" is accepted.
394 */
395 char_u *
396 skip_type(char_u *start, int optional)
397 {
398 char_u *p = start;
399
400 if (optional && *p == '?')
401 ++p;
402 while (ASCII_ISALNUM(*p) || *p == '_')
403 ++p;
404
405 // Skip over "<type>"; this is permissive about white space.
406 if (*skipwhite(p) == '<')
407 {
408 p = skipwhite(p);
409 p = skip_type(skipwhite(p + 1), FALSE);
410 p = skipwhite(p);
411 if (*p == '>')
412 ++p;
413 }
414 else if ((*p == '(' || (*p == ':' && VIM_ISWHITE(p[1])))
415 && STRNCMP("func", start, 4) == 0)
416 {
417 if (*p == '(')
418 {
419 // handle func(args): type
420 ++p;
421 while (*p != ')' && *p != NUL)
422 {
423 char_u *sp = p;
424
425 if (STRNCMP(p, "...", 3) == 0)
426 p += 3;
427 p = skip_type(p, TRUE);
428 if (p == sp)
429 return p; // syntax error
430 if (*p == ',')
431 p = skipwhite(p + 1);
432 }
433 if (*p == ')')
434 {
435 if (p[1] == ':')
436 p = skip_type(skipwhite(p + 2), FALSE);
437 else
438 ++p;
439 }
440 }
441 else
442 {
443 // handle func: return_type
444 p = skip_type(skipwhite(p + 1), FALSE);
445 }
446 }
447
448 return p;
449 }
450
451 /*
452 * Parse the member type: "<type>" and return "type" with the member set.
453 * Use "type_gap" if a new type needs to be added.
454 * Returns NULL in case of failure.
455 */
456 static type_T *
457 parse_type_member(char_u **arg, type_T *type, garray_T *type_gap)
458 {
459 type_T *member_type;
460 int prev_called_emsg = called_emsg;
461
462 if (**arg != '<')
463 {
464 if (*skipwhite(*arg) == '<')
465 semsg(_(e_no_white_before), "<");
466 else
467 emsg(_("E1008: Missing <type>"));
468 return type;
469 }
470 *arg = skipwhite(*arg + 1);
471
472 member_type = parse_type(arg, type_gap);
473
474 *arg = skipwhite(*arg);
475 if (**arg != '>' && called_emsg == prev_called_emsg)
476 {
477 emsg(_("E1009: Missing > after type"));
478 return type;
479 }
480 ++*arg;
481
482 if (type->tt_type == VAR_LIST)
483 return get_list_type(member_type, type_gap);
484 return get_dict_type(member_type, type_gap);
485 }
486
487 /*
488 * Parse a type at "arg" and advance over it.
489 * Return &t_any for failure.
490 */
491 type_T *
492 parse_type(char_u **arg, garray_T *type_gap)
493 {
494 char_u *p = *arg;
495 size_t len;
496
497 // skip over the first word
498 while (ASCII_ISALNUM(*p) || *p == '_')
499 ++p;
500 len = p - *arg;
501
502 switch (**arg)
503 {
504 case 'a':
505 if (len == 3 && STRNCMP(*arg, "any", len) == 0)
506 {
507 *arg += len;
508 return &t_any;
509 }
510 break;
511 case 'b':
512 if (len == 4 && STRNCMP(*arg, "bool", len) == 0)
513 {
514 *arg += len;
515 return &t_bool;
516 }
517 if (len == 4 && STRNCMP(*arg, "blob", len) == 0)
518 {
519 *arg += len;
520 return &t_blob;
521 }
522 break;
523 case 'c':
524 if (len == 7 && STRNCMP(*arg, "channel", len) == 0)
525 {
526 *arg += len;
527 return &t_channel;
528 }
529 break;
530 case 'd':
531 if (len == 4 && STRNCMP(*arg, "dict", len) == 0)
532 {
533 *arg += len;
534 return parse_type_member(arg, &t_dict_any, type_gap);
535 }
536 break;
537 case 'f':
538 if (len == 5 && STRNCMP(*arg, "float", len) == 0)
539 {
540 #ifdef FEAT_FLOAT
541 *arg += len;
542 return &t_float;
543 #else
544 emsg(_("E1076: This Vim is not compiled with float support"));
545 return &t_any;
546 #endif
547 }
548 if (len == 4 && STRNCMP(*arg, "func", len) == 0)
549 {
550 type_T *type;
551 type_T *ret_type = &t_unknown;
552 int argcount = -1;
553 int flags = 0;
554 int first_optional = -1;
555 type_T *arg_type[MAX_FUNC_ARGS + 1];
556
557 // func({type}, ...{type}): {type}
558 *arg += len;
559 if (**arg == '(')
560 {
561 // "func" may or may not return a value, "func()" does
562 // not return a value.
563 ret_type = &t_void;
564
565 p = ++*arg;
566 argcount = 0;
567 while (*p != NUL && *p != ')')
568 {
569 if (*p == '?')
570 {
571 if (first_optional == -1)
572 first_optional = argcount;
573 ++p;
574 }
575 else if (STRNCMP(p, "...", 3) == 0)
576 {
577 flags |= TTFLAG_VARARGS;
578 p += 3;
579 }
580 else if (first_optional != -1)
581 {
582 emsg(_("E1007: mandatory argument after optional argument"));
583 return &t_any;
584 }
585
586 arg_type[argcount++] = parse_type(&p, type_gap);
587
588 // Nothing comes after "...{type}".
589 if (flags & TTFLAG_VARARGS)
590 break;
591
592 if (*p != ',' && *skipwhite(p) == ',')
593 {
594 semsg(_(e_no_white_before), ",");
595 return &t_any;
596 }
597 if (*p == ',')
598 {
599 ++p;
600 if (!VIM_ISWHITE(*p))
601 {
602 semsg(_(e_white_after), ",");
603 return &t_any;
604 }
605 }
606 p = skipwhite(p);
607 if (argcount == MAX_FUNC_ARGS)
608 {
609 emsg(_("E740: Too many argument types"));
610 return &t_any;
611 }
612 }
613
614 p = skipwhite(p);
615 if (*p != ')')
616 {
617 emsg(_(e_missing_close));
618 return &t_any;
619 }
620 *arg = p + 1;
621 }
622 if (**arg == ':')
623 {
624 // parse return type
625 ++*arg;
626 if (!VIM_ISWHITE(**arg))
627 semsg(_(e_white_after), ":");
628 *arg = skipwhite(*arg);
629 ret_type = parse_type(arg, type_gap);
630 }
631 if (flags == 0 && first_optional == -1 && argcount <= 0)
632 type = get_func_type(ret_type, argcount, type_gap);
633 else
634 {
635 type = alloc_func_type(ret_type, argcount, type_gap);
636 type->tt_flags = flags;
637 if (argcount > 0)
638 {
639 type->tt_argcount = argcount;
640 type->tt_min_argcount = first_optional == -1
641 ? argcount : first_optional;
642 if (func_type_add_arg_types(type, argcount,
643 type_gap) == FAIL)
644 return &t_any;
645 mch_memmove(type->tt_args, arg_type,
646 sizeof(type_T *) * argcount);
647 }
648 }
649 return type;
650 }
651 break;
652 case 'j':
653 if (len == 3 && STRNCMP(*arg, "job", len) == 0)
654 {
655 *arg += len;
656 return &t_job;
657 }
658 break;
659 case 'l':
660 if (len == 4 && STRNCMP(*arg, "list", len) == 0)
661 {
662 *arg += len;
663 return parse_type_member(arg, &t_list_any, type_gap);
664 }
665 break;
666 case 'n':
667 if (len == 6 && STRNCMP(*arg, "number", len) == 0)
668 {
669 *arg += len;
670 return &t_number;
671 }
672 break;
673 case 's':
674 if (len == 6 && STRNCMP(*arg, "string", len) == 0)
675 {
676 *arg += len;
677 return &t_string;
678 }
679 break;
680 case 'v':
681 if (len == 4 && STRNCMP(*arg, "void", len) == 0)
682 {
683 *arg += len;
684 return &t_void;
685 }
686 break;
687 }
688
689 semsg(_("E1010: Type not recognized: %s"), *arg);
690 return &t_any;
691 }
692
693 /*
694 * Check if "type1" and "type2" are exactly the same.
695 */
696 static int
697 equal_type(type_T *type1, type_T *type2)
698 {
699 int i;
700
701 if (type1->tt_type != type2->tt_type)
702 return FALSE;
703 switch (type1->tt_type)
704 {
705 case VAR_UNKNOWN:
706 case VAR_ANY:
707 case VAR_VOID:
708 case VAR_SPECIAL:
709 case VAR_BOOL:
710 case VAR_NUMBER:
711 case VAR_FLOAT:
712 case VAR_STRING:
713 case VAR_BLOB:
714 case VAR_JOB:
715 case VAR_CHANNEL:
716 break; // not composite is always OK
717 case VAR_LIST:
718 case VAR_DICT:
719 return equal_type(type1->tt_member, type2->tt_member);
720 case VAR_FUNC:
721 case VAR_PARTIAL:
722 if (!equal_type(type1->tt_member, type2->tt_member)
723 || type1->tt_argcount != type2->tt_argcount)
724 return FALSE;
725 if (type1->tt_argcount < 0
726 || type1->tt_args == NULL || type2->tt_args == NULL)
727 return TRUE;
728 for (i = 0; i < type1->tt_argcount; ++i)
729 if (!equal_type(type1->tt_args[i], type2->tt_args[i]))
730 return FALSE;
731 return TRUE;
732 }
733 return TRUE;
734 }
735
736 /*
737 * Find the common type of "type1" and "type2" and put it in "dest".
738 * "type2" and "dest" may be the same.
739 */
740 void
741 common_type(type_T *type1, type_T *type2, type_T **dest, garray_T *type_gap)
742 {
743 if (equal_type(type1, type2))
744 {
745 *dest = type1;
746 return;
747 }
748
749 if (type1->tt_type == type2->tt_type)
750 {
751 if (type1->tt_type == VAR_LIST || type2->tt_type == VAR_DICT)
752 {
753 type_T *common;
754
755 common_type(type1->tt_member, type2->tt_member, &common, type_gap);
756 if (type1->tt_type == VAR_LIST)
757 *dest = get_list_type(common, type_gap);
758 else
759 *dest = get_dict_type(common, type_gap);
760 return;
761 }
762 if (type1->tt_type == VAR_FUNC)
763 {
764 type_T *common;
765
766 common_type(type1->tt_member, type2->tt_member, &common, type_gap);
767 if (type1->tt_argcount == type2->tt_argcount
768 && type1->tt_argcount >= 0)
769 {
770 int argcount = type1->tt_argcount;
771 int i;
772
773 *dest = alloc_func_type(common, argcount, type_gap);
774 if (type1->tt_args != NULL && type2->tt_args != NULL)
775 {
776 if (func_type_add_arg_types(*dest, argcount,
777 type_gap) == OK)
778 for (i = 0; i < argcount; ++i)
779 common_type(type1->tt_args[i], type2->tt_args[i],
780 &(*dest)->tt_args[i], type_gap);
781 }
782 }
783 else
784 *dest = alloc_func_type(common, -1, type_gap);
785 return;
786 }
787 }
788
789 *dest = &t_any;
790 }
791
792 char *
793 vartype_name(vartype_T type)
794 {
795 switch (type)
796 {
797 case VAR_UNKNOWN: break;
798 case VAR_ANY: return "any";
799 case VAR_VOID: return "void";
800 case VAR_SPECIAL: return "special";
801 case VAR_BOOL: return "bool";
802 case VAR_NUMBER: return "number";
803 case VAR_FLOAT: return "float";
804 case VAR_STRING: return "string";
805 case VAR_BLOB: return "blob";
806 case VAR_JOB: return "job";
807 case VAR_CHANNEL: return "channel";
808 case VAR_LIST: return "list";
809 case VAR_DICT: return "dict";
810
811 case VAR_FUNC:
812 case VAR_PARTIAL: return "func";
813 }
814 return "unknown";
815 }
816
817 /*
818 * Return the name of a type.
819 * The result may be in allocated memory, in which case "tofree" is set.
820 */
821 char *
822 type_name(type_T *type, char **tofree)
823 {
824 char *name = vartype_name(type->tt_type);
825
826 *tofree = NULL;
827 if (type->tt_type == VAR_LIST || type->tt_type == VAR_DICT)
828 {
829 char *member_free;
830 char *member_name = type_name(type->tt_member, &member_free);
831 size_t len;
832
833 len = STRLEN(name) + STRLEN(member_name) + 3;
834 *tofree = alloc(len);
835 if (*tofree != NULL)
836 {
837 vim_snprintf(*tofree, len, "%s<%s>", name, member_name);
838 vim_free(member_free);
839 return *tofree;
840 }
841 }
842 if (type->tt_type == VAR_FUNC)
843 {
844 garray_T ga;
845 int i;
846 int varargs = (type->tt_flags & TTFLAG_VARARGS) ? 1 : 0;
847
848 ga_init2(&ga, 1, 100);
849 if (ga_grow(&ga, 20) == FAIL)
850 return "[unknown]";
851 *tofree = ga.ga_data;
852 STRCPY(ga.ga_data, "func(");
853 ga.ga_len += 5;
854
855 for (i = 0; i < type->tt_argcount; ++i)
856 {
857 char *arg_free;
858 char *arg_type;
859 int len;
860
861 if (type->tt_args == NULL)
862 arg_type = "[unknown]";
863 else
864 arg_type = type_name(type->tt_args[i], &arg_free);
865 if (i > 0)
866 {
867 STRCPY((char *)ga.ga_data + ga.ga_len, ", ");
868 ga.ga_len += 2;
869 }
870 len = (int)STRLEN(arg_type);
871 if (ga_grow(&ga, len + 8) == FAIL)
872 {
873 vim_free(arg_free);
874 return "[unknown]";
875 }
876 *tofree = ga.ga_data;
877 if (varargs && i == type->tt_argcount - 1)
878 {
879 STRCPY((char *)ga.ga_data + ga.ga_len, "...");
880 ga.ga_len += 3;
881 }
882 else if (i >= type->tt_min_argcount)
883 *((char *)ga.ga_data + ga.ga_len++) = '?';
884 STRCPY((char *)ga.ga_data + ga.ga_len, arg_type);
885 ga.ga_len += len;
886 vim_free(arg_free);
887 }
888
889 if (type->tt_member == &t_void)
890 STRCPY((char *)ga.ga_data + ga.ga_len, ")");
891 else
892 {
893 char *ret_free;
894 char *ret_name = type_name(type->tt_member, &ret_free);
895 int len;
896
897 len = (int)STRLEN(ret_name) + 4;
898 if (ga_grow(&ga, len) == FAIL)
899 {
900 vim_free(ret_free);
901 return "[unknown]";
902 }
903 *tofree = ga.ga_data;
904 STRCPY((char *)ga.ga_data + ga.ga_len, "): ");
905 STRCPY((char *)ga.ga_data + ga.ga_len + 3, ret_name);
906 vim_free(ret_free);
907 }
908 return ga.ga_data;
909 }
910
911 return name;
912 }
913
914
915 #endif // FEAT_EVAL