Mercurial > vim
comparison src/vim9execute.c @ 31416:f088f1d97eee v9.0.1041
patch 9.0.1041: cannot define a method in a class
Commit: https://github.com/vim/vim/commit/ffdaca9e6f3d39af6857ac52ced9385df203a152
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Dec 9 21:41:48 2022 +0000
patch 9.0.1041: cannot define a method in a class
Problem: Cannot define a method in a class.
Solution: Implement defining an object method. Make calling an object
method work.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Fri, 09 Dec 2022 22:45:03 +0100 |
parents | 60b1d266548d |
children | e31fc75f6aff |
comparison
equal
deleted
inserted
replaced
31415:4fd33db887f2 | 31416:f088f1d97eee |
---|---|
4223 garray_T lines_to_free; | 4223 garray_T lines_to_free; |
4224 | 4224 |
4225 CLEAR_FIELD(ea); | 4225 CLEAR_FIELD(ea); |
4226 ea.cmd = ea.arg = iptr->isn_arg.string; | 4226 ea.cmd = ea.arg = iptr->isn_arg.string; |
4227 ga_init2(&lines_to_free, sizeof(char_u *), 50); | 4227 ga_init2(&lines_to_free, sizeof(char_u *), 50); |
4228 define_function(&ea, NULL, &lines_to_free, NULL); | 4228 define_function(&ea, NULL, &lines_to_free, FALSE); |
4229 ga_clear_strings(&lines_to_free); | 4229 ga_clear_strings(&lines_to_free); |
4230 } | 4230 } |
4231 break; | 4231 break; |
4232 | 4232 |
4233 // jump if a condition is met | 4233 // jump if a condition is met |
5112 | 5112 |
5113 copy_tv(&di->di_tv, tv); | 5113 copy_tv(&di->di_tv, tv); |
5114 } | 5114 } |
5115 break; | 5115 break; |
5116 | 5116 |
5117 case ISN_OBJ_MEMBER: | |
5118 { | |
5119 tv = STACK_TV_BOT(-1); | |
5120 if (tv->v_type != VAR_OBJECT) | |
5121 { | |
5122 SOURCING_LNUM = iptr->isn_lnum; | |
5123 garray_T type_list; | |
5124 ga_init2(&type_list, sizeof(type_T *), 10); | |
5125 type_T *type = typval2type(tv, get_copyID(), | |
5126 &type_list, TVTT_DO_MEMBER); | |
5127 char *tofree = NULL; | |
5128 char *typename = type_name(type, &tofree); | |
5129 semsg(_(e_object_required_found_str), typename); | |
5130 vim_free(tofree); | |
5131 clear_type_list(&type_list); | |
5132 goto on_error; | |
5133 } | |
5134 int idx = iptr->isn_arg.number; | |
5135 object_T *obj = tv->vval.v_object; | |
5136 // the members are located right after the object struct | |
5137 typval_T *mtv = ((typval_T *)(obj + 1)) + idx; | |
5138 *tv = *mtv; | |
5139 | |
5140 // Unreference the object after getting the member, it may | |
5141 // be freed. | |
5142 object_unref(obj); | |
5143 } | |
5144 break; | |
5145 | |
5117 case ISN_CLEARDICT: | 5146 case ISN_CLEARDICT: |
5118 dict_stack_drop(); | 5147 dict_stack_drop(); |
5119 break; | 5148 break; |
5120 | 5149 |
5121 case ISN_USEDICT: | 5150 case ISN_USEDICT: |
5575 ufunc_T *ufunc, | 5604 ufunc_T *ufunc, |
5576 int argc_arg, // nr of arguments | 5605 int argc_arg, // nr of arguments |
5577 typval_T *argv, // arguments | 5606 typval_T *argv, // arguments |
5578 int flags, // DEF_ flags | 5607 int flags, // DEF_ flags |
5579 partial_T *partial, // optional partial for context | 5608 partial_T *partial, // optional partial for context |
5609 object_T *object, // object, e.g. for this.Func() | |
5580 funccall_T *funccal, | 5610 funccall_T *funccal, |
5581 typval_T *rettv) // return value | 5611 typval_T *rettv) // return value |
5582 { | 5612 { |
5583 ectx_T ectx; // execution context | 5613 ectx_T ectx; // execution context |
5584 int argc = argc_arg; | 5614 int argc = argc_arg; |
5816 { | 5846 { |
5817 STACK_TV_VAR(idx)->v_type = VAR_NUMBER; | 5847 STACK_TV_VAR(idx)->v_type = VAR_NUMBER; |
5818 STACK_TV_VAR(idx)->vval.v_number = 0; | 5848 STACK_TV_VAR(idx)->vval.v_number = 0; |
5819 } | 5849 } |
5820 ectx.ec_stack.ga_len += dfunc->df_varcount; | 5850 ectx.ec_stack.ga_len += dfunc->df_varcount; |
5851 | |
5852 if (object != NULL) | |
5853 { | |
5854 // the object is always the variable at index zero | |
5855 tv = STACK_TV_VAR(0); | |
5856 tv->v_type = VAR_OBJECT; | |
5857 tv->vval.v_object = object; | |
5858 } | |
5859 | |
5821 if (dfunc->df_has_closure) | 5860 if (dfunc->df_has_closure) |
5822 { | 5861 { |
5823 // Initialize the variable that counts how many closures were | 5862 // Initialize the variable that counts how many closures were |
5824 // created. This is used in handle_closure_in_use(). | 5863 // created. This is used in handle_closure_in_use(). |
5825 STACK_TV_VAR(idx)->v_type = VAR_NUMBER; | 5864 STACK_TV_VAR(idx)->v_type = VAR_NUMBER; |
6764 iptr->isn_arg.getitem.gi_with_op ? | 6803 iptr->isn_arg.getitem.gi_with_op ? |
6765 " with op" : ""); break; | 6804 " with op" : ""); break; |
6766 case ISN_MEMBER: smsg("%s%4d MEMBER", pfx, current); break; | 6805 case ISN_MEMBER: smsg("%s%4d MEMBER", pfx, current); break; |
6767 case ISN_STRINGMEMBER: smsg("%s%4d MEMBER %s", pfx, current, | 6806 case ISN_STRINGMEMBER: smsg("%s%4d MEMBER %s", pfx, current, |
6768 iptr->isn_arg.string); break; | 6807 iptr->isn_arg.string); break; |
6808 case ISN_OBJ_MEMBER: smsg("%s%4d OBJ_MEMBER %d", pfx, current, | |
6809 (int)iptr->isn_arg.number); break; | |
6769 case ISN_CLEARDICT: smsg("%s%4d CLEARDICT", pfx, current); break; | 6810 case ISN_CLEARDICT: smsg("%s%4d CLEARDICT", pfx, current); break; |
6770 case ISN_USEDICT: smsg("%s%4d USEDICT", pfx, current); break; | 6811 case ISN_USEDICT: smsg("%s%4d USEDICT", pfx, current); break; |
6771 | 6812 |
6772 case ISN_NEGATENR: smsg("%s%4d NEGATENR", pfx, current); break; | 6813 case ISN_NEGATENR: smsg("%s%4d NEGATENR", pfx, current); break; |
6773 | 6814 |