comparison src/vim9script.c @ 23364:17a0e32eefd4 v8.2.2225

patch 8.2.2225: Vim9: error when using :import in legacy script twice Commit: https://github.com/vim/vim/commit/a6294955308fac1d14b9a8481e7f8581146c706c Author: Bram Moolenaar <Bram@vim.org> Date: Sun Dec 27 13:39:50 2020 +0100 patch 8.2.2225: Vim9: error when using :import in legacy script twice Problem: Vim9: error when using :import in legacy script twice. Solution: Make it possible to redefine an import when reloading.
author Bram Moolenaar <Bram@vim.org>
date Sun, 27 Dec 2020 13:45:04 +0100
parents f181fe2150ab
children 9a5f12b36273
comparison
equal deleted inserted replaced
23363:b5274c21249f 23364:17a0e32eefd4
169 ga_clear(&si->sn_imports); 169 ga_clear(&si->sn_imports);
170 170
171 free_all_script_vars(si); 171 free_all_script_vars(si);
172 172
173 clear_type_list(&si->sn_type_list); 173 clear_type_list(&si->sn_type_list);
174 }
175
176 /*
177 * Mark all imports as possible to redefine. Used when a script is loaded
178 * again but not cleared.
179 */
180 void
181 mark_imports_for_reload(int sid)
182 {
183 scriptitem_T *si = SCRIPT_ITEM(sid);
184 int idx;
185
186 for (idx = 0; idx < si->sn_imports.ga_len; ++idx)
187 {
188 imported_T *imp = ((imported_T *)si->sn_imports.ga_data) + idx;
189
190 imp->imp_flags |= IMP_FLAGS_RELOAD;
191 }
174 } 192 }
175 193
176 /* 194 /*
177 * ":import Item from 'filename'" 195 * ":import Item from 'filename'"
178 * ":import Item as Alias from 'filename'" 196 * ":import Item as Alias from 'filename'"
457 } 475 }
458 clear_tv(&tv); 476 clear_tv(&tv);
459 477
460 if (*arg_start == '*') 478 if (*arg_start == '*')
461 { 479 {
462 imported_T *imported = new_imported(gap != NULL ? gap 480 imported_T *imported;
481
482 imported = find_imported(as_name, STRLEN(as_name), cctx);
483 if (imported != NULL && imported->imp_sid == sid)
484 {
485 if (imported->imp_flags & IMP_FLAGS_RELOAD)
486 // import already defined on a previous script load
487 imported->imp_flags &= ~IMP_FLAGS_RELOAD;
488 else
489 {
490 semsg(_(e_name_already_defined_str), as_name);
491 goto erret;
492 }
493 }
494
495 imported = new_imported(gap != NULL ? gap
463 : &SCRIPT_ITEM(import_sid)->sn_imports); 496 : &SCRIPT_ITEM(import_sid)->sn_imports);
464
465 if (imported == NULL) 497 if (imported == NULL)
466 goto erret; 498 goto erret;
467 imported->imp_name = as_name; 499 imported->imp_name = as_name;
468 as_name = NULL; 500 as_name = NULL;
469 imported->imp_sid = sid; 501 imported->imp_sid = sid;
470 imported->imp_all = TRUE; 502 imported->imp_flags = IMP_FLAGS_STAR;
471 } 503 }
472 else 504 else
473 { 505 {
474 int i; 506 int i;
475 507
477 if (*arg == '{') 509 if (*arg == '{')
478 arg = skipwhite(arg + 1); 510 arg = skipwhite(arg + 1);
479 for (i = 0; i < names.ga_len; ++i) 511 for (i = 0; i < names.ga_len; ++i)
480 { 512 {
481 char_u *name = ((char_u **)names.ga_data)[i]; 513 char_u *name = ((char_u **)names.ga_data)[i];
514 size_t len = STRLEN(name);
482 int idx; 515 int idx;
483 imported_T *imported; 516 imported_T *imported;
484 ufunc_T *ufunc = NULL; 517 ufunc_T *ufunc = NULL;
485 type_T *type; 518 type_T *type;
486 519
487 idx = find_exported(sid, name, &ufunc, &type, cctx); 520 idx = find_exported(sid, name, &ufunc, &type, cctx);
488 521
489 if (idx < 0 && ufunc == NULL) 522 if (idx < 0 && ufunc == NULL)
490 goto erret; 523 goto erret;
491 524
492 if (check_defined(name, STRLEN(name), cctx) == FAIL) 525 // If already imported with the same propertis and the
493 goto erret; 526 // IMP_FLAGS_RELOAD set then we keep that entry. Otherwise create
494 527 // a new one (and give an error for an existing import).
495 imported = new_imported(gap != NULL ? gap 528 imported = find_imported(name, len, cctx);
529 if (imported != NULL
530 && (imported->imp_flags & IMP_FLAGS_RELOAD)
531 && imported->imp_sid == sid
532 && (idx >= 0
533 ? (equal_type(imported->imp_type, type)
534 && imported->imp_var_vals_idx == idx)
535 : (equal_type(imported->imp_type, ufunc->uf_func_type)
536 && STRCMP(imported->imp_funcname,
537 ufunc->uf_name) == 0)))
538 {
539 imported->imp_flags &= ~IMP_FLAGS_RELOAD;
540 }
541 else
542 {
543 if (check_defined(name, len, cctx) == FAIL)
544 goto erret;
545
546 imported = new_imported(gap != NULL ? gap
496 : &SCRIPT_ITEM(import_sid)->sn_imports); 547 : &SCRIPT_ITEM(import_sid)->sn_imports);
497 if (imported == NULL) 548 if (imported == NULL)
498 goto erret; 549 goto erret;
499 550
500 // TODO: check for "as" following 551 // TODO: check for "as" following
501 // imported->imp_name = vim_strsave(as_name); 552 // imported->imp_name = vim_strsave(as_name);
502 imported->imp_name = name; 553 imported->imp_name = name;
503 ((char_u **)names.ga_data)[i] = NULL; 554 ((char_u **)names.ga_data)[i] = NULL;
504 imported->imp_sid = sid; 555 imported->imp_sid = sid;
505 if (idx >= 0) 556 if (idx >= 0)
506 { 557 {
507 imported->imp_type = type; 558 imported->imp_type = type;
508 imported->imp_var_vals_idx = idx; 559 imported->imp_var_vals_idx = idx;
509 } 560 }
510 else 561 else
511 { 562 {
512 imported->imp_type = ufunc->uf_func_type; 563 imported->imp_type = ufunc->uf_func_type;
513 imported->imp_funcname = ufunc->uf_name; 564 imported->imp_funcname = ufunc->uf_name;
565 }
514 } 566 }
515 } 567 }
516 } 568 }
517 erret: 569 erret:
518 ga_clear_strings(&names); 570 ga_clear_strings(&names);