Mercurial > vim
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 { |