Mercurial > vim
comparison src/vim9type.c @ 23332:cdb706d5c43d v8.2.2209
patch 8.2.2209: Vim9: return type of => lambda not parsed
Commit: https://github.com/vim/vim/commit/9e68c32563d8c9ffe1ac04ecd4ccd730af66b97c
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Dec 25 12:38:04 2020 +0100
patch 8.2.2209: Vim9: return type of => lambda not parsed
Problem: Vim9: return type of => lambda not parsed.
Solution: Parse and use the return type.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Fri, 25 Dec 2020 12:45:05 +0100 |
parents | a8bccb0634bc |
children | 4b4f695e9cd1 |
comparison
equal
deleted
inserted
replaced
23331:c5b1246b9557 | 23332:cdb706d5c43d |
---|---|
594 * Parse the member type: "<type>" and return "type" with the member set. | 594 * Parse the member type: "<type>" and return "type" with the member set. |
595 * Use "type_gap" if a new type needs to be added. | 595 * Use "type_gap" if a new type needs to be added. |
596 * Returns NULL in case of failure. | 596 * Returns NULL in case of failure. |
597 */ | 597 */ |
598 static type_T * | 598 static type_T * |
599 parse_type_member(char_u **arg, type_T *type, garray_T *type_gap) | 599 parse_type_member( |
600 char_u **arg, | |
601 type_T *type, | |
602 garray_T *type_gap, | |
603 int give_error) | |
600 { | 604 { |
601 type_T *member_type; | 605 type_T *member_type; |
602 int prev_called_emsg = called_emsg; | 606 int prev_called_emsg = called_emsg; |
603 | 607 |
604 if (**arg != '<') | 608 if (**arg != '<') |
605 { | 609 { |
606 if (*skipwhite(*arg) == '<') | 610 if (give_error) |
607 semsg(_(e_no_white_space_allowed_before_str), "<"); | 611 { |
608 else | 612 if (*skipwhite(*arg) == '<') |
609 emsg(_(e_missing_type)); | 613 semsg(_(e_no_white_space_allowed_before_str), "<"); |
610 return type; | 614 else |
615 emsg(_(e_missing_type)); | |
616 } | |
617 return NULL; | |
611 } | 618 } |
612 *arg = skipwhite(*arg + 1); | 619 *arg = skipwhite(*arg + 1); |
613 | 620 |
614 member_type = parse_type(arg, type_gap); | 621 member_type = parse_type(arg, type_gap, give_error); |
622 if (member_type == NULL) | |
623 return NULL; | |
615 | 624 |
616 *arg = skipwhite(*arg); | 625 *arg = skipwhite(*arg); |
617 if (**arg != '>' && called_emsg == prev_called_emsg) | 626 if (**arg != '>' && called_emsg == prev_called_emsg) |
618 { | 627 { |
619 emsg(_(e_missing_gt_after_type)); | 628 if (give_error) |
620 return type; | 629 emsg(_(e_missing_gt_after_type)); |
630 return NULL; | |
621 } | 631 } |
622 ++*arg; | 632 ++*arg; |
623 | 633 |
624 if (type->tt_type == VAR_LIST) | 634 if (type->tt_type == VAR_LIST) |
625 return get_list_type(member_type, type_gap); | 635 return get_list_type(member_type, type_gap); |
626 return get_dict_type(member_type, type_gap); | 636 return get_dict_type(member_type, type_gap); |
627 } | 637 } |
628 | 638 |
629 /* | 639 /* |
630 * Parse a type at "arg" and advance over it. | 640 * Parse a type at "arg" and advance over it. |
631 * Return &t_any for failure. | 641 * When "give_error" is TRUE give error messages, otherwise be quiet. |
642 * Return NULL for failure. | |
632 */ | 643 */ |
633 type_T * | 644 type_T * |
634 parse_type(char_u **arg, garray_T *type_gap) | 645 parse_type(char_u **arg, garray_T *type_gap, int give_error) |
635 { | 646 { |
636 char_u *p = *arg; | 647 char_u *p = *arg; |
637 size_t len; | 648 size_t len; |
638 | 649 |
639 // skip over the first word | 650 // skip over the first word |
671 break; | 682 break; |
672 case 'd': | 683 case 'd': |
673 if (len == 4 && STRNCMP(*arg, "dict", len) == 0) | 684 if (len == 4 && STRNCMP(*arg, "dict", len) == 0) |
674 { | 685 { |
675 *arg += len; | 686 *arg += len; |
676 return parse_type_member(arg, &t_dict_any, type_gap); | 687 return parse_type_member(arg, &t_dict_any, |
688 type_gap, give_error); | |
677 } | 689 } |
678 break; | 690 break; |
679 case 'f': | 691 case 'f': |
680 if (len == 5 && STRNCMP(*arg, "float", len) == 0) | 692 if (len == 5 && STRNCMP(*arg, "float", len) == 0) |
681 { | 693 { |
682 #ifdef FEAT_FLOAT | 694 #ifdef FEAT_FLOAT |
683 *arg += len; | 695 *arg += len; |
684 return &t_float; | 696 return &t_float; |
685 #else | 697 #else |
686 emsg(_(e_this_vim_is_not_compiled_with_float_support)); | 698 if (give_error) |
687 return &t_any; | 699 emsg(_(e_this_vim_is_not_compiled_with_float_support)); |
700 return NULL; | |
688 #endif | 701 #endif |
689 } | 702 } |
690 if (len == 4 && STRNCMP(*arg, "func", len) == 0) | 703 if (len == 4 && STRNCMP(*arg, "func", len) == 0) |
691 { | 704 { |
692 type_T *type; | 705 type_T *type; |
719 flags |= TTFLAG_VARARGS; | 732 flags |= TTFLAG_VARARGS; |
720 p += 3; | 733 p += 3; |
721 } | 734 } |
722 else if (first_optional != -1) | 735 else if (first_optional != -1) |
723 { | 736 { |
724 emsg(_(e_mandatory_argument_after_optional_argument)); | 737 if (give_error) |
725 return &t_any; | 738 emsg(_(e_mandatory_argument_after_optional_argument)); |
739 return NULL; | |
726 } | 740 } |
727 | 741 |
728 arg_type[argcount++] = parse_type(&p, type_gap); | 742 type = parse_type(&p, type_gap, give_error); |
743 if (type == NULL) | |
744 return NULL; | |
745 arg_type[argcount++] = type; | |
729 | 746 |
730 // Nothing comes after "...{type}". | 747 // Nothing comes after "...{type}". |
731 if (flags & TTFLAG_VARARGS) | 748 if (flags & TTFLAG_VARARGS) |
732 break; | 749 break; |
733 | 750 |
734 if (*p != ',' && *skipwhite(p) == ',') | 751 if (*p != ',' && *skipwhite(p) == ',') |
735 { | 752 { |
736 semsg(_(e_no_white_space_allowed_before_str), ","); | 753 if (give_error) |
737 return &t_any; | 754 semsg(_(e_no_white_space_allowed_before_str), ","); |
755 return NULL; | |
738 } | 756 } |
739 if (*p == ',') | 757 if (*p == ',') |
740 { | 758 { |
741 ++p; | 759 ++p; |
742 if (!VIM_ISWHITE(*p)) | 760 if (!VIM_ISWHITE(*p)) |
743 { | 761 { |
744 semsg(_(e_white_space_required_after_str), ","); | 762 if (give_error) |
745 return &t_any; | 763 semsg(_(e_white_space_required_after_str), ","); |
764 return NULL; | |
746 } | 765 } |
747 } | 766 } |
748 p = skipwhite(p); | 767 p = skipwhite(p); |
749 if (argcount == MAX_FUNC_ARGS) | 768 if (argcount == MAX_FUNC_ARGS) |
750 { | 769 { |
751 emsg(_(e_too_many_argument_types)); | 770 if (give_error) |
752 return &t_any; | 771 emsg(_(e_too_many_argument_types)); |
772 return NULL; | |
753 } | 773 } |
754 } | 774 } |
755 | 775 |
756 p = skipwhite(p); | 776 p = skipwhite(p); |
757 if (*p != ')') | 777 if (*p != ')') |
758 { | 778 { |
759 emsg(_(e_missing_close)); | 779 if (give_error) |
760 return &t_any; | 780 emsg(_(e_missing_close)); |
781 return NULL; | |
761 } | 782 } |
762 *arg = p + 1; | 783 *arg = p + 1; |
763 } | 784 } |
764 if (**arg == ':') | 785 if (**arg == ':') |
765 { | 786 { |
766 // parse return type | 787 // parse return type |
767 ++*arg; | 788 ++*arg; |
768 if (!VIM_ISWHITE(**arg)) | 789 if (!VIM_ISWHITE(**arg) && give_error) |
769 semsg(_(e_white_space_required_after_str), ":"); | 790 semsg(_(e_white_space_required_after_str), ":"); |
770 *arg = skipwhite(*arg); | 791 *arg = skipwhite(*arg); |
771 ret_type = parse_type(arg, type_gap); | 792 ret_type = parse_type(arg, type_gap, give_error); |
793 if (ret_type == NULL) | |
794 return NULL; | |
772 } | 795 } |
773 if (flags == 0 && first_optional == -1 && argcount <= 0) | 796 if (flags == 0 && first_optional == -1 && argcount <= 0) |
774 type = get_func_type(ret_type, argcount, type_gap); | 797 type = get_func_type(ret_type, argcount, type_gap); |
775 else | 798 else |
776 { | 799 { |
781 type->tt_argcount = argcount; | 804 type->tt_argcount = argcount; |
782 type->tt_min_argcount = first_optional == -1 | 805 type->tt_min_argcount = first_optional == -1 |
783 ? argcount : first_optional; | 806 ? argcount : first_optional; |
784 if (func_type_add_arg_types(type, argcount, | 807 if (func_type_add_arg_types(type, argcount, |
785 type_gap) == FAIL) | 808 type_gap) == FAIL) |
786 return &t_any; | 809 return NULL; |
787 mch_memmove(type->tt_args, arg_type, | 810 mch_memmove(type->tt_args, arg_type, |
788 sizeof(type_T *) * argcount); | 811 sizeof(type_T *) * argcount); |
789 } | 812 } |
790 } | 813 } |
791 return type; | 814 return type; |
800 break; | 823 break; |
801 case 'l': | 824 case 'l': |
802 if (len == 4 && STRNCMP(*arg, "list", len) == 0) | 825 if (len == 4 && STRNCMP(*arg, "list", len) == 0) |
803 { | 826 { |
804 *arg += len; | 827 *arg += len; |
805 return parse_type_member(arg, &t_list_any, type_gap); | 828 return parse_type_member(arg, &t_list_any, |
829 type_gap, give_error); | |
806 } | 830 } |
807 break; | 831 break; |
808 case 'n': | 832 case 'n': |
809 if (len == 6 && STRNCMP(*arg, "number", len) == 0) | 833 if (len == 6 && STRNCMP(*arg, "number", len) == 0) |
810 { | 834 { |
826 return &t_void; | 850 return &t_void; |
827 } | 851 } |
828 break; | 852 break; |
829 } | 853 } |
830 | 854 |
831 semsg(_(e_type_not_recognized_str), *arg); | 855 if (give_error) |
832 return &t_any; | 856 semsg(_(e_type_not_recognized_str), *arg); |
857 return NULL; | |
833 } | 858 } |
834 | 859 |
835 /* | 860 /* |
836 * Check if "type1" and "type2" are exactly the same. | 861 * Check if "type1" and "type2" are exactly the same. |
837 */ | 862 */ |
1014 * The result may be in allocated memory, in which case "tofree" is set. | 1039 * The result may be in allocated memory, in which case "tofree" is set. |
1015 */ | 1040 */ |
1016 char * | 1041 char * |
1017 type_name(type_T *type, char **tofree) | 1042 type_name(type_T *type, char **tofree) |
1018 { | 1043 { |
1019 char *name = vartype_name(type->tt_type); | 1044 char *name; |
1020 | 1045 |
1021 *tofree = NULL; | 1046 *tofree = NULL; |
1047 if (type == NULL) | |
1048 return "[unknown]"; | |
1049 name = vartype_name(type->tt_type); | |
1022 if (type->tt_type == VAR_LIST || type->tt_type == VAR_DICT) | 1050 if (type->tt_type == VAR_LIST || type->tt_type == VAR_DICT) |
1023 { | 1051 { |
1024 char *member_free; | 1052 char *member_free; |
1025 char *member_name = type_name(type->tt_member, &member_free); | 1053 char *member_name = type_name(type->tt_member, &member_free); |
1026 size_t len; | 1054 size_t len; |