comparison src/vim9expr.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 307f68a41b03
children e31fc75f6aff
comparison
equal deleted inserted replaced
31415:4fd33db887f2 31416:f088f1d97eee
246 emsg(_(e_string_list_dict_or_blob_required)); 246 emsg(_(e_string_list_dict_or_blob_required));
247 } 247 }
248 return FAIL; 248 return FAIL;
249 } 249 }
250 return OK; 250 return OK;
251 }
252
253 /*
254 * Compile ".member" coming after an object or class.
255 */
256
257 static int
258 compile_class_object_index(cctx_T *cctx, char_u **arg, type_T *type)
259 {
260 if (VIM_ISWHITE((*arg)[1]))
261 {
262 semsg(_(e_no_white_space_allowed_after_str_str), ".", *arg);
263 return FAIL;
264 }
265
266 ++*arg;
267 char_u *name = *arg;
268 char_u *name_end = find_name_end(name, NULL, NULL, FNE_CHECK_START);
269 if (name_end == name)
270 return FAIL;
271 size_t len = name_end - name;
272
273 class_T *cl = (class_T *)type->tt_member;
274 if (*name_end == '(')
275 {
276 // TODO
277 }
278 else if (type->tt_type == VAR_OBJECT)
279 {
280 for (int i = 0; i < cl->class_obj_member_count; ++i)
281 {
282 objmember_T *m = &cl->class_obj_members[i];
283 if (STRNCMP(name, m->om_name, len) == 0 && m->om_name[len] == NUL)
284 {
285 generate_OBJ_MEMBER(cctx, i, m->om_type);
286
287 *arg = name_end;
288 return OK;
289 }
290 }
291
292 semsg(_(e_member_not_found_on_object_str_str), cl->class_name, name);
293 }
294 else
295 {
296 // TODO: class member
297 emsg("compile_class_object_index(): not handled");
298 }
299
300 return FAIL;
251 } 301 }
252 302
253 /* 303 /*
254 * Generate an instruction to load script-local variable "name", without the 304 * Generate an instruction to load script-local variable "name", without the
255 * leading "s:". 305 * leading "s:".
1795 int keeping_dict = FALSE; 1845 int keeping_dict = FALSE;
1796 1846
1797 for (;;) 1847 for (;;)
1798 { 1848 {
1799 char_u *p = skipwhite(*arg); 1849 char_u *p = skipwhite(*arg);
1850 type_T *type;
1800 1851
1801 if (*p == NUL || (VIM_ISWHITE(**arg) && vim9_comment_start(p))) 1852 if (*p == NUL || (VIM_ISWHITE(**arg) && vim9_comment_start(p)))
1802 { 1853 {
1803 char_u *next = peek_next_line_from_context(cctx); 1854 char_u *next = peek_next_line_from_context(cctx);
1804 1855
1822 1873
1823 // Do not skip over white space to find the "(", "execute 'x' (expr)" 1874 // Do not skip over white space to find the "(", "execute 'x' (expr)"
1824 // is not a function call. 1875 // is not a function call.
1825 if (**arg == '(') 1876 if (**arg == '(')
1826 { 1877 {
1827 type_T *type;
1828 int argcount = 0; 1878 int argcount = 0;
1829 1879
1830 if (generate_ppconst(cctx, ppconst) == FAIL) 1880 if (generate_ppconst(cctx, ppconst) == FAIL)
1831 return FAIL; 1881 return FAIL;
1832 ppconst->pp_is_const = FALSE; 1882 ppconst->pp_is_const = FALSE;
1909 if (alt != 1) 1959 if (alt != 1)
1910 { 1960 {
1911 int argcount = 1; 1961 int argcount = 1;
1912 garray_T *stack = &cctx->ctx_type_stack; 1962 garray_T *stack = &cctx->ctx_type_stack;
1913 int type_idx_start = stack->ga_len; 1963 int type_idx_start = stack->ga_len;
1914 type_T *type;
1915 int expr_isn_start = cctx->ctx_instr.ga_len; 1964 int expr_isn_start = cctx->ctx_instr.ga_len;
1916 int expr_isn_end; 1965 int expr_isn_end;
1917 int arg_isn_count; 1966 int arg_isn_count;
1918 1967
1919 if (alt == 2) 1968 if (alt == 2)
2093 keeping_dict = FALSE; 2142 keeping_dict = FALSE;
2094 if (generate_instr(cctx, ISN_CLEARDICT) == NULL) 2143 if (generate_instr(cctx, ISN_CLEARDICT) == NULL)
2095 return FAIL; 2144 return FAIL;
2096 } 2145 }
2097 if (compile_member(is_slice, &keeping_dict, cctx) == FAIL) 2146 if (compile_member(is_slice, &keeping_dict, cctx) == FAIL)
2147 return FAIL;
2148 }
2149 else if (*p == '.'
2150 && (type = get_type_on_stack(cctx, 0)) != &t_unknown
2151 && (type->tt_type == VAR_CLASS || type->tt_type == VAR_OBJECT))
2152 {
2153 // class member: SomeClass.varname
2154 // class method: SomeClass.SomeMethod()
2155 // class constructor: SomeClass.new()
2156 // object member: someObject.varname, this.varname
2157 // object method: someObject.SomeMethod(), this.SomeMethod()
2158 if (compile_class_object_index(cctx, arg, type) == FAIL)
2098 return FAIL; 2159 return FAIL;
2099 } 2160 }
2100 else if (*p == '.' && p[1] != '.') 2161 else if (*p == '.' && p[1] != '.')
2101 { 2162 {
2102 // dictionary member: dict.name 2163 // dictionary member: dict.name