comparison src/vim9expr.c @ 31843:ffa11e2757e7 v9.0.1254

patch 9.0.1254: calling a method on an interface does not work Commit: https://github.com/vim/vim/commit/d0200c8631582bbb16a9b585e2ca7adccc84ccdd Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jan 28 15:19:40 2023 +0000 patch 9.0.1254: calling a method on an interface does not work Problem: Calling a method on an interface does not work. Solution: At runtime figure out what method to call. (closes https://github.com/vim/vim/issues/11901)
author Bram Moolenaar <Bram@vim.org>
date Sat, 28 Jan 2023 16:30:04 +0100
parents 5ce5d78afcc9
children f1a5e67e9a1b
comparison
equal deleted inserted replaced
31842:1b6543beb560 31843:ffa11e2757e7
319 child_count = cl->class_obj_method_count_child; 319 child_count = cl->class_obj_method_count_child;
320 functions = cl->class_obj_methods; 320 functions = cl->class_obj_methods;
321 } 321 }
322 322
323 ufunc_T *ufunc = NULL; 323 ufunc_T *ufunc = NULL;
324 for (int i = is_super ? child_count : 0; i < function_count; ++i) 324 int fi;
325 { 325 for (fi = is_super ? child_count : 0; fi < function_count; ++fi)
326 ufunc_T *fp = functions[i]; 326 {
327 ufunc_T *fp = functions[fi];
327 // Use a separate pointer to avoid that ASAN complains about 328 // Use a separate pointer to avoid that ASAN complains about
328 // uf_name[] only being 4 characters. 329 // uf_name[] only being 4 characters.
329 char_u *ufname = (char_u *)fp->uf_name; 330 char_u *ufname = (char_u *)fp->uf_name;
330 if (STRNCMP(name, ufname, len) == 0 && ufname[len] == NUL) 331 if (STRNCMP(name, ufname, len) == 0 && ufname[len] == NUL)
331 { 332 {
345 // before the arguments. 346 // before the arguments.
346 *arg = skipwhite(name_end + 1); 347 *arg = skipwhite(name_end + 1);
347 int argcount = 0; 348 int argcount = 0;
348 if (compile_arguments(arg, cctx, &argcount, CA_NOT_SPECIAL) == FAIL) 349 if (compile_arguments(arg, cctx, &argcount, CA_NOT_SPECIAL) == FAIL)
349 return FAIL; 350 return FAIL;
350 return generate_CALL(cctx, ufunc, argcount); 351
352 if (type->tt_type == VAR_OBJECT
353 && (cl->class_flags & (CLASS_INTERFACE | CLASS_EXTENDED)))
354 return generate_CALL(cctx, ufunc, cl, fi, argcount);
355 return generate_CALL(cctx, ufunc, NULL, 0, argcount);
351 } 356 }
352 357
353 if (type->tt_type == VAR_OBJECT) 358 if (type->tt_type == VAR_OBJECT)
354 { 359 {
355 for (int i = 0; i < cl->class_obj_member_count; ++i) 360 for (int i = 0; i < cl->class_obj_member_count; ++i)
362 semsg(_(e_cannot_access_private_member_str), m->ocm_name); 367 semsg(_(e_cannot_access_private_member_str), m->ocm_name);
363 return FAIL; 368 return FAIL;
364 } 369 }
365 370
366 *arg = name_end; 371 *arg = name_end;
367 if (cl->class_flags & CLASS_INTERFACE) 372 if (cl->class_flags & (CLASS_INTERFACE | CLASS_EXTENDED))
368 return generate_GET_ITF_MEMBER(cctx, cl, i, m->ocm_type); 373 return generate_GET_ITF_MEMBER(cctx, cl, i, m->ocm_type);
369 return generate_GET_OBJ_MEMBER(cctx, i, m->ocm_type); 374 return generate_GET_OBJ_MEMBER(cctx, i, m->ocm_type);
370 } 375 }
371 } 376 }
372 377
1061 ufunc = find_func(name, FALSE); 1066 ufunc = find_func(name, FALSE);
1062 if (ufunc != NULL) 1067 if (ufunc != NULL)
1063 { 1068 {
1064 if (!func_is_global(ufunc)) 1069 if (!func_is_global(ufunc))
1065 { 1070 {
1066 res = generate_CALL(cctx, ufunc, argcount); 1071 res = generate_CALL(cctx, ufunc, NULL, 0, argcount);
1067 goto theend; 1072 goto theend;
1068 } 1073 }
1069 if (!has_g_namespace 1074 if (!has_g_namespace
1070 && vim_strchr(ufunc->uf_name, AUTOLOAD_CHAR) == NULL) 1075 && vim_strchr(ufunc->uf_name, AUTOLOAD_CHAR) == NULL)
1071 { 1076 {
1090 } 1095 }
1091 1096
1092 // If we can find a global function by name generate the right call. 1097 // If we can find a global function by name generate the right call.
1093 if (ufunc != NULL) 1098 if (ufunc != NULL)
1094 { 1099 {
1095 res = generate_CALL(cctx, ufunc, argcount); 1100 res = generate_CALL(cctx, ufunc, NULL, 0, argcount);
1096 goto theend; 1101 goto theend;
1097 } 1102 }
1098 1103
1099 // A global function may be defined only later. Need to figure out at 1104 // A global function may be defined only later. Need to figure out at
1100 // runtime. Also handles a FuncRef at runtime. 1105 // runtime. Also handles a FuncRef at runtime.