Mercurial > vim
comparison src/userfunc.c @ 27267:322b79b002b7 v8.2.4162
patch 8.2.4162: Vim9: no error for redefining function with export
Commit: https://github.com/vim/vim/commit/9c7cae66bc21a3dc5c6e60cd64216ce7c9073003
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Jan 20 19:10:25 2022 +0000
patch 8.2.4162: Vim9: no error for redefining function with export
Problem: Vim9: no error for redefining function with export.
Solution: Check for existing function with/without prefix. (closes https://github.com/vim/vim/issues/9577)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 20 Jan 2022 20:15:03 +0100 |
parents | 73232ed49cf2 |
children | 24da57a079ef |
comparison
equal
deleted
inserted
replaced
27266:06a2610c1661 | 27267:322b79b002b7 |
---|---|
1909 si = SCRIPT_ITEM(sid); | 1909 si = SCRIPT_ITEM(sid); |
1910 if (si->sn_autoload_prefix != NULL) | 1910 if (si->sn_autoload_prefix != NULL) |
1911 { | 1911 { |
1912 size_t len = STRLEN(si->sn_autoload_prefix) + STRLEN(name) + 1; | 1912 size_t len = STRLEN(si->sn_autoload_prefix) + STRLEN(name) + 1; |
1913 char_u *auto_name; | 1913 char_u *auto_name; |
1914 char_u *namep; | |
1915 | |
1916 // skip a "<SNR>99_" prefix | |
1917 namep = untrans_function_name(name); | |
1918 if (namep == NULL) | |
1919 namep = name; | |
1914 | 1920 |
1915 // An exported function in an autoload script is stored as | 1921 // An exported function in an autoload script is stored as |
1916 // "dir#path#name". | 1922 // "dir#path#name". |
1917 if (len < sizeof(buffer)) | 1923 if (len < sizeof(buffer)) |
1918 auto_name = buffer; | 1924 auto_name = buffer; |
1919 else | 1925 else |
1920 auto_name = alloc(len); | 1926 auto_name = alloc(len); |
1921 if (auto_name != NULL) | 1927 if (auto_name != NULL) |
1922 { | 1928 { |
1923 vim_snprintf((char *)auto_name, len, "%s%s", | 1929 vim_snprintf((char *)auto_name, len, "%s%s", |
1924 si->sn_autoload_prefix, name); | 1930 si->sn_autoload_prefix, namep); |
1925 hi = hash_find(&func_hashtab, auto_name); | 1931 hi = hash_find(&func_hashtab, auto_name); |
1926 if (auto_name != buffer) | 1932 if (auto_name != buffer) |
1927 vim_free(auto_name); | 1933 vim_free(auto_name); |
1928 if (!HASHITEM_EMPTY(hi)) | 1934 if (!HASHITEM_EMPTY(hi)) |
1929 return HI2UF(hi); | 1935 return HI2UF(hi); |
4173 | 4179 |
4174 // For "export def FuncName()" in an autoload script the function name | 4180 // For "export def FuncName()" in an autoload script the function name |
4175 // is stored with the legacy autoload name "dir#script#FuncName" so | 4181 // is stored with the legacy autoload name "dir#script#FuncName" so |
4176 // that it can also be found in legacy script. | 4182 // that it can also be found in legacy script. |
4177 if (is_export && name != NULL) | 4183 if (is_export && name != NULL) |
4178 name = may_prefix_autoload(name); | 4184 { |
4185 char_u *prefixed = may_prefix_autoload(name); | |
4186 | |
4187 if (prefixed != NULL && prefixed != name) | |
4188 { | |
4189 vim_free(name); | |
4190 name = prefixed; | |
4191 } | |
4192 } | |
4179 } | 4193 } |
4180 | 4194 |
4181 // An error in a function call during evaluation of an expression in magic | 4195 // An error in a function call during evaluation of an expression in magic |
4182 // braces should not cause the function not to be defined. | 4196 // braces should not cause the function not to be defined. |
4183 saved_did_emsg = did_emsg; | 4197 saved_did_emsg = did_emsg; |
4445 * If there are no errors, add the function | 4459 * If there are no errors, add the function |
4446 */ | 4460 */ |
4447 if (fudi.fd_dict == NULL) | 4461 if (fudi.fd_dict == NULL) |
4448 { | 4462 { |
4449 hashtab_T *ht; | 4463 hashtab_T *ht; |
4464 char_u *find_name = name; | |
4465 int var_conflict = FALSE; | |
4450 | 4466 |
4451 v = find_var(name, &ht, TRUE); | 4467 v = find_var(name, &ht, TRUE); |
4452 if (v != NULL && v->di_tv.v_type == VAR_FUNC) | 4468 if (v != NULL) |
4469 var_conflict = TRUE; | |
4470 | |
4471 if (SCRIPT_ID_VALID(current_sctx.sc_sid)) | |
4472 { | |
4473 scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid); | |
4474 | |
4475 if (si->sn_autoload_prefix != NULL) | |
4476 { | |
4477 if (is_export) | |
4478 { | |
4479 find_name = name + STRLEN(si->sn_autoload_prefix); | |
4480 v = find_var(find_name, &ht, TRUE); | |
4481 if (v != NULL) | |
4482 var_conflict = TRUE; | |
4483 } | |
4484 else | |
4485 { | |
4486 char_u *prefixed = may_prefix_autoload(name); | |
4487 | |
4488 if (prefixed != NULL) | |
4489 { | |
4490 v = find_var(prefixed, &ht, TRUE); | |
4491 if (v != NULL) | |
4492 var_conflict = TRUE; | |
4493 vim_free(prefixed); | |
4494 } | |
4495 } | |
4496 } | |
4497 } | |
4498 if (var_conflict) | |
4453 { | 4499 { |
4454 emsg_funcname(e_function_name_conflicts_with_variable_str, name); | 4500 emsg_funcname(e_function_name_conflicts_with_variable_str, name); |
4455 goto erret; | 4501 goto erret; |
4456 } | 4502 } |
4457 | 4503 |
4458 fp = find_func_even_dead(name, is_global); | 4504 fp = find_func_even_dead(find_name, is_global); |
4459 if (vim9script) | 4505 if (vim9script) |
4460 { | 4506 { |
4461 char_u *uname = untrans_function_name(name); | 4507 char_u *uname = untrans_function_name(name); |
4462 | 4508 |
4463 import = find_imported(uname == NULL ? name : uname, 0, FALSE, NULL); | 4509 import = find_imported(uname == NULL ? name : uname, 0, |
4510 FALSE, NULL); | |
4464 } | 4511 } |
4465 | 4512 |
4466 if (fp != NULL || import != NULL) | 4513 if (fp != NULL || import != NULL) |
4467 { | 4514 { |
4468 int dead = fp != NULL && (fp->uf_flags & FC_DEAD); | 4515 int dead = fp != NULL && (fp->uf_flags & FC_DEAD); |