Mercurial > vim
diff 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 |
line wrap: on
line diff
--- a/src/vim9class.c +++ b/src/vim9class.c @@ -147,12 +147,30 @@ ex_class(exarg_T *eap) if (type == NULL) break; + char_u *expr_start = skipwhite(type_arg); + if (*expr_start == '=' && (!VIM_ISWHITE(expr_start[-1]) + || !VIM_ISWHITE(expr_start[1]))) + { + semsg(_(e_white_space_required_before_and_after_str_at_str), + "=", type_arg); + break; + } + expr_start = skipwhite(expr_start + 1); + + char_u *expr_end = expr_start; + evalarg_T evalarg; + init_evalarg(&evalarg); + skip_expr(&expr_end, &evalarg); + clear_evalarg(&evalarg, NULL); + if (ga_grow(&objmembers, 1) == FAIL) break; objmember_T *m = ((objmember_T *)objmembers.ga_data) + objmembers.ga_len; m->om_name = vim_strnsave(varname, varname_end - varname); m->om_type = type; + if (expr_end > expr_start) + m->om_init = vim_strnsave(expr_start, expr_end - expr_start); ++objmembers.ga_len; } @@ -190,6 +208,9 @@ ex_class(exarg_T *eap) // TODO: how about errors? if (uf != NULL && ga_grow(&objmethods, 1) == OK) { + if (STRNCMP(uf->uf_name, "new", 3) == 0) + uf->uf_flags |= FC_NEW; + ((ufunc_T **)objmethods.ga_data)[objmethods.ga_len] = uf; ++objmethods.ga_len; } @@ -333,6 +354,7 @@ cleanup: { objmember_T *m = ((objmember_T *)objmembers.ga_data) + i; vim_free(m->om_name); + vim_free(m->om_init); } ga_clear(&objmembers); @@ -520,6 +542,52 @@ class_object_index( } /* + * If "arg" points to a class or object method, return it. + * Otherwise return NULL. + */ + ufunc_T * +find_class_func(char_u **arg) +{ + char_u *name = *arg; + char_u *name_end = find_name_end(name, NULL, NULL, FNE_CHECK_START); + if (name_end == name || *name_end != '.') + return NULL; + + size_t len = name_end - name; + typval_T tv; + tv.v_type = VAR_UNKNOWN; + if (eval_variable(name, len, 0, &tv, NULL, EVAL_VAR_NOAUTOLOAD) == FAIL) + return NULL; + if (tv.v_type != VAR_CLASS && tv.v_type != VAR_OBJECT) + { + clear_tv(&tv); + return NULL; + } + + class_T *cl = tv.v_type == VAR_CLASS ? tv.vval.v_class + : tv.vval.v_object->obj_class; + if (cl == NULL) + return NULL; + char_u *fname = name_end + 1; + char_u *fname_end = find_name_end(fname, NULL, NULL, FNE_CHECK_START); + if (fname_end == fname) + return NULL; + len = fname_end - fname; + + for (int i = 0; i < cl->class_obj_method_count; ++i) + { + ufunc_T *fp = cl->class_obj_methods[i]; + // Use a separate pointer to avoid that ASAN complains about + // uf_name[] only being 4 characters. + char_u *ufname = (char_u *)fp->uf_name; + if (STRNCMP(fname, ufname, len) == 0 && ufname[len] == NUL) + return fp; + } + + return NULL; +} + +/* * Make a copy of an object. */ void @@ -585,6 +653,7 @@ class_unref(class_T *cl) { objmember_T *m = &cl->class_obj_members[i]; vim_free(m->om_name); + vim_free(m->om_init); } vim_free(cl->class_obj_members);