Mercurial > vim
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); |