comparison src/vim9class.c @ 31424:e31fc75f6aff v9.0.1045

patch 9.0.1045: in a class object members cannot be initialized Commit: https://github.com/vim/vim/commit/7ce7daf6cd6a7ed27eac060699026640b4b239a8 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Dec 10 18:42:12 2022 +0000 patch 9.0.1045: in a class object members cannot be initialized Problem: In a class object members cannot be initialized. Solution: Support initializing object members. Make "dissassemble" work on an object method.
author Bram Moolenaar <Bram@vim.org>
date Sat, 10 Dec 2022 19:45:04 +0100
parents 462508d04341
children e572ff386670
comparison
equal deleted inserted replaced
31423:66c85efdf4b0 31424:e31fc75f6aff
145 char_u *type_arg = skipwhite(colon + 1); 145 char_u *type_arg = skipwhite(colon + 1);
146 type_T *type = parse_type(&type_arg, &type_list, TRUE); 146 type_T *type = parse_type(&type_arg, &type_list, TRUE);
147 if (type == NULL) 147 if (type == NULL)
148 break; 148 break;
149 149
150 char_u *expr_start = skipwhite(type_arg);
151 if (*expr_start == '=' && (!VIM_ISWHITE(expr_start[-1])
152 || !VIM_ISWHITE(expr_start[1])))
153 {
154 semsg(_(e_white_space_required_before_and_after_str_at_str),
155 "=", type_arg);
156 break;
157 }
158 expr_start = skipwhite(expr_start + 1);
159
160 char_u *expr_end = expr_start;
161 evalarg_T evalarg;
162 init_evalarg(&evalarg);
163 skip_expr(&expr_end, &evalarg);
164 clear_evalarg(&evalarg, NULL);
165
150 if (ga_grow(&objmembers, 1) == FAIL) 166 if (ga_grow(&objmembers, 1) == FAIL)
151 break; 167 break;
152 objmember_T *m = ((objmember_T *)objmembers.ga_data) 168 objmember_T *m = ((objmember_T *)objmembers.ga_data)
153 + objmembers.ga_len; 169 + objmembers.ga_len;
154 m->om_name = vim_strnsave(varname, varname_end - varname); 170 m->om_name = vim_strnsave(varname, varname_end - varname);
155 m->om_type = type; 171 m->om_type = type;
172 if (expr_end > expr_start)
173 m->om_init = vim_strnsave(expr_start, expr_end - expr_start);
156 ++objmembers.ga_len; 174 ++objmembers.ga_len;
157 } 175 }
158 176
159 // constructors: 177 // constructors:
160 // def new() 178 // def new()
188 ga_clear_strings(&lines_to_free); 206 ga_clear_strings(&lines_to_free);
189 207
190 // TODO: how about errors? 208 // TODO: how about errors?
191 if (uf != NULL && ga_grow(&objmethods, 1) == OK) 209 if (uf != NULL && ga_grow(&objmethods, 1) == OK)
192 { 210 {
211 if (STRNCMP(uf->uf_name, "new", 3) == 0)
212 uf->uf_flags |= FC_NEW;
213
193 ((ufunc_T **)objmethods.ga_data)[objmethods.ga_len] = uf; 214 ((ufunc_T **)objmethods.ga_data)[objmethods.ga_len] = uf;
194 ++objmethods.ga_len; 215 ++objmethods.ga_len;
195 } 216 }
196 } 217 }
197 218
331 cleanup: 352 cleanup:
332 for (int i = 0; i < objmembers.ga_len; ++i) 353 for (int i = 0; i < objmembers.ga_len; ++i)
333 { 354 {
334 objmember_T *m = ((objmember_T *)objmembers.ga_data) + i; 355 objmember_T *m = ((objmember_T *)objmembers.ga_data) + i;
335 vim_free(m->om_name); 356 vim_free(m->om_name);
357 vim_free(m->om_init);
336 } 358 }
337 ga_clear(&objmembers); 359 ga_clear(&objmembers);
338 360
339 for (int i = 0; i < objmethods.ga_len; ++i) 361 for (int i = 0; i < objmethods.ga_len; ++i)
340 { 362 {
518 540
519 return FAIL; 541 return FAIL;
520 } 542 }
521 543
522 /* 544 /*
545 * If "arg" points to a class or object method, return it.
546 * Otherwise return NULL.
547 */
548 ufunc_T *
549 find_class_func(char_u **arg)
550 {
551 char_u *name = *arg;
552 char_u *name_end = find_name_end(name, NULL, NULL, FNE_CHECK_START);
553 if (name_end == name || *name_end != '.')
554 return NULL;
555
556 size_t len = name_end - name;
557 typval_T tv;
558 tv.v_type = VAR_UNKNOWN;
559 if (eval_variable(name, len, 0, &tv, NULL, EVAL_VAR_NOAUTOLOAD) == FAIL)
560 return NULL;
561 if (tv.v_type != VAR_CLASS && tv.v_type != VAR_OBJECT)
562 {
563 clear_tv(&tv);
564 return NULL;
565 }
566
567 class_T *cl = tv.v_type == VAR_CLASS ? tv.vval.v_class
568 : tv.vval.v_object->obj_class;
569 if (cl == NULL)
570 return NULL;
571 char_u *fname = name_end + 1;
572 char_u *fname_end = find_name_end(fname, NULL, NULL, FNE_CHECK_START);
573 if (fname_end == fname)
574 return NULL;
575 len = fname_end - fname;
576
577 for (int i = 0; i < cl->class_obj_method_count; ++i)
578 {
579 ufunc_T *fp = cl->class_obj_methods[i];
580 // Use a separate pointer to avoid that ASAN complains about
581 // uf_name[] only being 4 characters.
582 char_u *ufname = (char_u *)fp->uf_name;
583 if (STRNCMP(fname, ufname, len) == 0 && ufname[len] == NUL)
584 return fp;
585 }
586
587 return NULL;
588 }
589
590 /*
523 * Make a copy of an object. 591 * Make a copy of an object.
524 */ 592 */
525 void 593 void
526 copy_object(typval_T *from, typval_T *to) 594 copy_object(typval_T *from, typval_T *to)
527 { 595 {
583 651
584 for (int i = 0; i < cl->class_obj_member_count; ++i) 652 for (int i = 0; i < cl->class_obj_member_count; ++i)
585 { 653 {
586 objmember_T *m = &cl->class_obj_members[i]; 654 objmember_T *m = &cl->class_obj_members[i];
587 vim_free(m->om_name); 655 vim_free(m->om_name);
656 vim_free(m->om_init);
588 } 657 }
589 vim_free(cl->class_obj_members); 658 vim_free(cl->class_obj_members);
590 659
591 for (int i = 0; i < cl->class_obj_method_count; ++i) 660 for (int i = 0; i < cl->class_obj_method_count; ++i)
592 { 661 {