Mirror of the Vim source from https://github.com/vim/vim
Revision | 7b5b9558500a62a53992edccff3a4e229b9d3c65 (tree) |
---|---|
Zeit | 2020-08-02 05:30:04 |
Autor | Bram Moolenaar <Bram@vim....> |
Commiter | Bram Moolenaar |
patch 8.2.1349: Vim9: can define a function with the name of an import
Commit: https://github.com/vim/vim/commit/eef2102e20d24f5fbd1c9f53c7a35df61585c5ab
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Aug 1 22:16:43 2020 +0200
@@ -1746,6 +1746,7 @@ | ||
1746 | 1746 | EXTERN char e_duplicate_key[] INIT(= N_("E721: Duplicate key in Dictionary: \"%s\"")); |
1747 | 1747 | EXTERN char e_missing_dict_comma[] INIT(= N_("E722: Missing comma in Dictionary: %s")); |
1748 | 1748 | EXTERN char e_missing_dict_end[] INIT(= N_("E723: Missing end of Dictionary '}': %s")); |
1749 | +EXTERN char e_already_defined[] INIT(= N_("E1073: name already defined: %s")); | |
1749 | 1750 | #endif |
1750 | 1751 | #ifdef FEAT_CLIENTSERVER |
1751 | 1752 | EXTERN char e_invexprmsg[] INIT(= N_("E449: Invalid expression received")); |
@@ -1618,6 +1618,39 @@ | ||
1618 | 1618 | delete('Ximport.vim') |
1619 | 1619 | enddef |
1620 | 1620 | |
1621 | +def Test_func_overrules_import_fails() | |
1622 | + let export_lines =<< trim END | |
1623 | + vim9script | |
1624 | + export def Func() | |
1625 | + echo 'imported' | |
1626 | + enddef | |
1627 | + END | |
1628 | + writefile(export_lines, 'XexportedFunc.vim') | |
1629 | + | |
1630 | + let lines =<< trim END | |
1631 | + vim9script | |
1632 | + import Func from './XexportedFunc.vim' | |
1633 | + def Func() | |
1634 | + echo 'local to function' | |
1635 | + enddef | |
1636 | + END | |
1637 | + CheckScriptFailure(lines, 'E1073:') | |
1638 | + | |
1639 | + lines =<< trim END | |
1640 | + vim9script | |
1641 | + import Func from './XexportedFunc.vim' | |
1642 | + def Outer() | |
1643 | + def Func() | |
1644 | + echo 'local to function' | |
1645 | + enddef | |
1646 | + enddef | |
1647 | + defcompile | |
1648 | + END | |
1649 | + CheckScriptFailure(lines, 'E1073:') | |
1650 | + | |
1651 | + delete('XexportedFunc.vim') | |
1652 | +enddef | |
1653 | + | |
1621 | 1654 | def Test_fixed_size_list() |
1622 | 1655 | # will be allocated as one piece of memory, check that changes work |
1623 | 1656 | let l = [1, 2, 3, 4] |
@@ -2652,6 +2652,7 @@ | ||
2652 | 2652 | char_u *skip_until = NULL; |
2653 | 2653 | char_u *heredoc_trimmed = NULL; |
2654 | 2654 | int vim9script = in_vim9script(); |
2655 | + imported_T *import = NULL; | |
2655 | 2656 | |
2656 | 2657 | /* |
2657 | 2658 | * ":function" without argument: list functions. |
@@ -3235,17 +3236,29 @@ | ||
3235 | 3236 | } |
3236 | 3237 | |
3237 | 3238 | fp = find_func_even_dead(name, is_global, NULL); |
3238 | - if (fp != NULL) | |
3239 | + if (vim9script) | |
3239 | 3240 | { |
3240 | - int dead = fp->uf_flags & FC_DEAD; | |
3241 | + char_u *uname = untrans_function_name(name); | |
3242 | + | |
3243 | + import = find_imported(uname == NULL ? name : uname, 0, NULL); | |
3244 | + } | |
3245 | + | |
3246 | + if (fp != NULL || import != NULL) | |
3247 | + { | |
3248 | + int dead = fp != NULL && (fp->uf_flags & FC_DEAD); | |
3241 | 3249 | |
3242 | 3250 | // Function can be replaced with "function!" and when sourcing the |
3243 | 3251 | // same script again, but only once. |
3244 | - if (!dead && !eap->forceit | |
3252 | + // A name that is used by an import can not be overruled. | |
3253 | + if (import != NULL | |
3254 | + || (!dead && !eap->forceit | |
3245 | 3255 | && (fp->uf_script_ctx.sc_sid != current_sctx.sc_sid |
3246 | - || fp->uf_script_ctx.sc_seq == current_sctx.sc_seq)) | |
3256 | + || fp->uf_script_ctx.sc_seq == current_sctx.sc_seq))) | |
3247 | 3257 | { |
3248 | - emsg_funcname(e_funcexts, name); | |
3258 | + if (vim9script) | |
3259 | + emsg_funcname(e_already_defined, name); | |
3260 | + else | |
3261 | + emsg_funcname(e_funcexts, name); | |
3249 | 3262 | goto erret; |
3250 | 3263 | } |
3251 | 3264 | if (fp->uf_calls > 0) |
@@ -755,6 +755,8 @@ | ||
755 | 755 | static int included_patches[] = |
756 | 756 | { /* Add new patch number below this line */ |
757 | 757 | /**/ |
758 | + 1349, | |
759 | +/**/ | |
758 | 760 | 1348, |
759 | 761 | /**/ |
760 | 762 | 1347, |
@@ -294,9 +294,10 @@ | ||
294 | 294 | if (lookup_script(p, len) == OK |
295 | 295 | || (cctx != NULL |
296 | 296 | && (lookup_local(p, len, cctx) != NULL |
297 | - || find_imported(p, len, cctx) != NULL))) | |
298 | - { | |
299 | - semsg("E1073: imported name already defined: %s", p); | |
297 | + || lookup_arg(p, len, NULL, NULL, NULL, cctx) == OK)) | |
298 | + || find_imported(p, len, cctx) != NULL) | |
299 | + { | |
300 | + semsg(_(e_already_defined), p); | |
300 | 301 | return FAIL; |
301 | 302 | } |
302 | 303 | return OK; |
@@ -4899,17 +4900,21 @@ | ||
4899 | 4900 | int is_global = *eap->arg == 'g' && eap->arg[1] == ':'; |
4900 | 4901 | char_u *name_start = eap->arg; |
4901 | 4902 | char_u *name_end = to_name_end(eap->arg, is_global); |
4902 | - char_u *name = get_lambda_name(); | |
4903 | + char_u *lambda_name; | |
4903 | 4904 | lvar_T *lvar; |
4904 | 4905 | ufunc_T *ufunc; |
4905 | 4906 | int r; |
4906 | 4907 | |
4908 | + if (check_defined(name_start, name_end - name_start, cctx) == FAIL) | |
4909 | + return NULL; | |
4910 | + | |
4907 | 4911 | eap->arg = name_end; |
4908 | 4912 | eap->getline = exarg_getline; |
4909 | 4913 | eap->cookie = cctx; |
4910 | 4914 | eap->skip = cctx->ctx_skip == SKIP_YES; |
4911 | 4915 | eap->forceit = FALSE; |
4912 | - ufunc = def_function(eap, name); | |
4916 | + lambda_name = get_lambda_name(); | |
4917 | + ufunc = def_function(eap, lambda_name); | |
4913 | 4918 | |
4914 | 4919 | if (ufunc == NULL) |
4915 | 4920 | return NULL; |
@@ -4925,13 +4930,15 @@ | ||
4925 | 4930 | if (func_name == NULL) |
4926 | 4931 | r = FAIL; |
4927 | 4932 | else |
4928 | - r = generate_NEWFUNC(cctx, name, func_name); | |
4933 | + r = generate_NEWFUNC(cctx, lambda_name, func_name); | |
4929 | 4934 | } |
4930 | 4935 | else |
4931 | 4936 | { |
4932 | 4937 | // Define a local variable for the function reference. |
4933 | 4938 | lvar = reserve_local(cctx, name_start, name_end - name_start, |
4934 | 4939 | TRUE, ufunc->uf_func_type); |
4940 | + if (lvar == NULL) | |
4941 | + return NULL; | |
4935 | 4942 | if (generate_FUNCREF(cctx, ufunc->uf_dfunc_idx) == FAIL) |
4936 | 4943 | return NULL; |
4937 | 4944 | r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL); |