Mercurial > vim
comparison src/userfunc.c @ 21558:1c4d4aa22b37 v8.2.1329
patch 8.2.1329: Vim9: cannot define global function inside :def function
Commit: https://github.com/vim/vim/commit/38ddf333f6b2806b0ea2dd052ee1cd50dd7f4525
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Jul 31 22:05:04 2020 +0200
patch 8.2.1329: Vim9: cannot define global function inside :def function
Problem: Vim9: cannot define global function inside :def function.
Solution: Assign to global variable instead of local. (closes https://github.com/vim/vim/issues/6584)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Fri, 31 Jul 2020 22:15:04 +0200 |
parents | cbc570e66d11 |
children | 30a997217524 |
comparison
equal
deleted
inserted
replaced
21557:00c9f8522652 | 21558:1c4d4aa22b37 |
---|---|
364 | 364 |
365 fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1); | 365 fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1); |
366 if (fp == NULL) | 366 if (fp == NULL) |
367 return NULL; | 367 return NULL; |
368 | 368 |
369 fp->uf_dfunc_idx = UF_NOT_COMPILED; | 369 fp->uf_def_status = UF_NOT_COMPILED; |
370 fp->uf_refcount = 1; | 370 fp->uf_refcount = 1; |
371 fp->uf_varargs = TRUE; | 371 fp->uf_varargs = TRUE; |
372 fp->uf_flags = FC_CFUNC; | 372 fp->uf_flags = FC_CFUNC; |
373 fp->uf_calls = 0; | 373 fp->uf_calls = 0; |
374 fp->uf_script_ctx = current_sctx; | 374 fp->uf_script_ctx = current_sctx; |
1067 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); | 1067 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); |
1068 if (!HASHITEM_EMPTY(hi)) | 1068 if (!HASHITEM_EMPTY(hi)) |
1069 { | 1069 { |
1070 // When there is a def-function index do not actually remove the | 1070 // When there is a def-function index do not actually remove the |
1071 // function, so we can find the index when defining the function again. | 1071 // function, so we can find the index when defining the function again. |
1072 if (fp->uf_def_status == UF_COMPILED) | 1072 // Do remove it when it's a copy. |
1073 if (fp->uf_def_status == UF_COMPILED && (fp->uf_flags & FC_COPY) == 0) | |
1073 fp->uf_flags |= FC_DEAD; | 1074 fp->uf_flags |= FC_DEAD; |
1074 else | 1075 else |
1075 hash_remove(&func_hashtab, hi); | 1076 hash_remove(&func_hashtab, hi); |
1076 return TRUE; | 1077 return TRUE; |
1077 } | 1078 } |
1120 fp->uf_cleared = TRUE; | 1121 fp->uf_cleared = TRUE; |
1121 | 1122 |
1122 // clear this function | 1123 // clear this function |
1123 func_clear_items(fp); | 1124 func_clear_items(fp); |
1124 funccal_unref(fp->uf_scoped, fp, force); | 1125 funccal_unref(fp->uf_scoped, fp, force); |
1125 clear_def_function(fp); | 1126 if ((fp->uf_flags & FC_COPY) == 0) |
1127 clear_def_function(fp); | |
1126 } | 1128 } |
1127 | 1129 |
1128 /* | 1130 /* |
1129 * Free a function and remove it from the list of functions. Does not free | 1131 * Free a function and remove it from the list of functions. Does not free |
1130 * what a function contains, call func_clear() first. | 1132 * what a function contains, call func_clear() first. |
1148 */ | 1150 */ |
1149 static void | 1151 static void |
1150 func_clear_free(ufunc_T *fp, int force) | 1152 func_clear_free(ufunc_T *fp, int force) |
1151 { | 1153 { |
1152 func_clear(fp, force); | 1154 func_clear(fp, force); |
1153 if (force || fp->uf_dfunc_idx == 0) | 1155 if (force || fp->uf_dfunc_idx == 0 || (fp->uf_flags & FC_COPY)) |
1154 func_free(fp, force); | 1156 func_free(fp, force); |
1155 else | 1157 else |
1156 fp->uf_flags |= FC_DEAD; | 1158 fp->uf_flags |= FC_DEAD; |
1159 } | |
1160 | |
1161 /* | |
1162 * Copy already defined function "lambda" to a new function with name "global". | |
1163 * This is for when a compiled function defines a global function. | |
1164 */ | |
1165 void | |
1166 copy_func(char_u *lambda, char_u *global) | |
1167 { | |
1168 ufunc_T *ufunc = find_func_even_dead(lambda, TRUE, NULL); | |
1169 ufunc_T *fp; | |
1170 | |
1171 if (ufunc == NULL) | |
1172 semsg(_("E1102: lambda function not found: %s"), lambda); | |
1173 else | |
1174 { | |
1175 // TODO: handle ! to overwrite | |
1176 fp = find_func(global, TRUE, NULL); | |
1177 if (fp != NULL) | |
1178 { | |
1179 semsg(_(e_funcexts), global); | |
1180 return; | |
1181 } | |
1182 | |
1183 fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(global) + 1); | |
1184 if (fp == NULL) | |
1185 return; | |
1186 | |
1187 fp->uf_varargs = ufunc->uf_varargs; | |
1188 fp->uf_flags = (ufunc->uf_flags & ~FC_VIM9) | FC_COPY; | |
1189 fp->uf_def_status = ufunc->uf_def_status; | |
1190 fp->uf_dfunc_idx = ufunc->uf_dfunc_idx; | |
1191 if (ga_copy_strings(&fp->uf_args, &ufunc->uf_args) == FAIL | |
1192 || ga_copy_strings(&fp->uf_def_args, &ufunc->uf_def_args) | |
1193 == FAIL | |
1194 || ga_copy_strings(&fp->uf_lines, &ufunc->uf_lines) == FAIL) | |
1195 goto failed; | |
1196 | |
1197 fp->uf_name_exp = ufunc->uf_name_exp == NULL ? NULL | |
1198 : vim_strsave(ufunc->uf_name_exp); | |
1199 if (ufunc->uf_arg_types != NULL) | |
1200 { | |
1201 fp->uf_arg_types = ALLOC_MULT(type_T *, fp->uf_args.ga_len); | |
1202 if (fp->uf_arg_types == NULL) | |
1203 goto failed; | |
1204 mch_memmove(fp->uf_arg_types, ufunc->uf_arg_types, | |
1205 sizeof(type_T *) * fp->uf_args.ga_len); | |
1206 } | |
1207 if (ufunc->uf_def_arg_idx != NULL) | |
1208 { | |
1209 fp->uf_def_arg_idx = ALLOC_MULT(int, fp->uf_def_args.ga_len + 1); | |
1210 if (fp->uf_def_arg_idx == NULL) | |
1211 goto failed; | |
1212 mch_memmove(fp->uf_def_arg_idx, ufunc->uf_def_arg_idx, | |
1213 sizeof(int) * fp->uf_def_args.ga_len + 1); | |
1214 } | |
1215 if (ufunc->uf_va_name != NULL) | |
1216 { | |
1217 fp->uf_va_name = vim_strsave(ufunc->uf_va_name); | |
1218 if (fp->uf_va_name == NULL) | |
1219 goto failed; | |
1220 } | |
1221 | |
1222 fp->uf_refcount = 1; | |
1223 STRCPY(fp->uf_name, global); | |
1224 hash_add(&func_hashtab, UF2HIKEY(fp)); | |
1225 } | |
1226 return; | |
1227 | |
1228 failed: | |
1229 func_clear_free(fp, TRUE); | |
1157 } | 1230 } |
1158 | 1231 |
1159 | 1232 |
1160 /* | 1233 /* |
1161 * Call a user function. | 1234 * Call a user function. |
2519 } | 2592 } |
2520 } | 2593 } |
2521 | 2594 |
2522 /* | 2595 /* |
2523 * ":function" also supporting nested ":def". | 2596 * ":function" also supporting nested ":def". |
2597 * When "name_arg" is not NULL this is a nested function, using "name_arg" for | |
2598 * the function name. | |
2524 * Returns a pointer to the function or NULL if no function defined. | 2599 * Returns a pointer to the function or NULL if no function defined. |
2525 */ | 2600 */ |
2526 ufunc_T * | 2601 ufunc_T * |
2527 def_function(exarg_T *eap, char_u *name_arg) | 2602 def_function(exarg_T *eap, char_u *name_arg) |
2528 { | 2603 { |