Mercurial > vim
comparison src/userfunc.c @ 31635:5c1b7a87466e v9.0.1150
patch 9.0.1150: :interface is not implemented yet
Commit: https://github.com/vim/vim/commit/554d0313022c3977c71f7dcbc5c841ef43d988a6
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Jan 5 19:59:18 2023 +0000
patch 9.0.1150: :interface is not implemented yet
Problem: :interface is not implemented yet.
Solution: Implement the basics of :interface.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 05 Jan 2023 21:00:06 +0100 |
parents | 2266b5c4f87b |
children | ec76f9d2319e |
comparison
equal
deleted
inserted
replaced
31634:40a31588b97c | 31635:5c1b7a87466e |
---|---|
213 evalarg_T *evalarg, // context or NULL | 213 evalarg_T *evalarg, // context or NULL |
214 int *varargs, | 214 int *varargs, |
215 garray_T *default_args, | 215 garray_T *default_args, |
216 int skip, | 216 int skip, |
217 exarg_T *eap, // can be NULL | 217 exarg_T *eap, // can be NULL |
218 int in_class, // TRUE when inside a class | 218 int in_class, // non-zero when inside a class or interface |
219 garray_T *newlines, // function body lines | 219 garray_T *newlines, // function body lines |
220 garray_T *lines_to_free) | 220 garray_T *lines_to_free) |
221 { | 221 { |
222 int mustend = FALSE; | 222 int mustend = FALSE; |
223 char_u *arg; | 223 char_u *arg; |
4460 /* | 4460 /* |
4461 * ":function" also supporting nested ":def". | 4461 * ":function" also supporting nested ":def". |
4462 * When "name_arg" is not NULL this is a nested function, using "name_arg" for | 4462 * When "name_arg" is not NULL this is a nested function, using "name_arg" for |
4463 * the function name. | 4463 * the function name. |
4464 * "lines_to_free" is a list of strings to be freed later. | 4464 * "lines_to_free" is a list of strings to be freed later. |
4465 * If "in_class" is TRUE then the function is defined inside a class. | 4465 * If "class_flags" has CF_CLASS then the function is defined inside a class. |
4466 * With CF_INTERFACE the function is define inside an interface, only the | |
4467 * ":def"/":function" line is expected, no function body. | |
4466 * Returns a pointer to the function or NULL if no function defined. | 4468 * Returns a pointer to the function or NULL if no function defined. |
4467 */ | 4469 */ |
4468 ufunc_T * | 4470 ufunc_T * |
4469 define_function( | 4471 define_function( |
4470 exarg_T *eap, | 4472 exarg_T *eap, |
4471 char_u *name_arg, | 4473 char_u *name_arg, |
4472 garray_T *lines_to_free, | 4474 garray_T *lines_to_free, |
4473 int in_class) | 4475 int class_flags) |
4474 { | 4476 { |
4475 int j; | 4477 int j; |
4476 int c; | 4478 int c; |
4477 int saved_did_emsg = FALSE; | 4479 int saved_did_emsg = FALSE; |
4478 char_u *name = name_arg; | 4480 char_u *name = name_arg; |
4543 ga_init(&argtypes); | 4545 ga_init(&argtypes); |
4544 ga_init(&default_args); | 4546 ga_init(&default_args); |
4545 | 4547 |
4546 /* | 4548 /* |
4547 * Get the function name. There are these situations: | 4549 * Get the function name. There are these situations: |
4548 * func normal function name, also when "in_class" is TRUE | 4550 * func normal function name, also when "class_flags" is non-zero |
4549 * "name" == func, "fudi.fd_dict" == NULL | 4551 * "name" == func, "fudi.fd_dict" == NULL |
4550 * dict.func new dictionary entry | 4552 * dict.func new dictionary entry |
4551 * "name" == NULL, "fudi.fd_dict" set, | 4553 * "name" == NULL, "fudi.fd_dict" set, |
4552 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func | 4554 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func |
4553 * dict.func existing dict entry with a Funcref | 4555 * dict.func existing dict entry with a Funcref |
4584 } | 4586 } |
4585 p = eap->arg; | 4587 p = eap->arg; |
4586 } | 4588 } |
4587 | 4589 |
4588 int tfn_flags = TFN_NO_AUTOLOAD | TFN_NEW_FUNC | 4590 int tfn_flags = TFN_NO_AUTOLOAD | TFN_NEW_FUNC |
4589 | (in_class ? TFN_IN_CLASS : 0); | 4591 | (class_flags != 0 ? TFN_IN_CLASS : 0); |
4590 name = save_function_name(&p, &is_global, eap->skip, tfn_flags, &fudi); | 4592 name = save_function_name(&p, &is_global, eap->skip, tfn_flags, &fudi); |
4591 paren = (vim_strchr(p, '(') != NULL); | 4593 paren = (vim_strchr(p, '(') != NULL); |
4592 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) | 4594 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) |
4593 { | 4595 { |
4594 /* | 4596 /* |
4787 // invalid. | 4789 // invalid. |
4788 ++p; | 4790 ++p; |
4789 if (get_function_args(&p, ')', &newargs, | 4791 if (get_function_args(&p, ')', &newargs, |
4790 eap->cmdidx == CMD_def ? &argtypes : NULL, FALSE, | 4792 eap->cmdidx == CMD_def ? &argtypes : NULL, FALSE, |
4791 NULL, &varargs, &default_args, eap->skip, | 4793 NULL, &varargs, &default_args, eap->skip, |
4792 eap, in_class, &newlines, lines_to_free) == FAIL) | 4794 eap, class_flags, &newlines, lines_to_free) == FAIL) |
4793 goto errret_2; | 4795 goto errret_2; |
4794 whitep = p; | 4796 whitep = p; |
4795 | 4797 |
4796 if (eap->cmdidx == CMD_def) | 4798 if (eap->cmdidx == CMD_def) |
4797 { | 4799 { |
4897 // Save the starting line number. | 4899 // Save the starting line number. |
4898 sourcing_lnum_top = SOURCING_LNUM; | 4900 sourcing_lnum_top = SOURCING_LNUM; |
4899 | 4901 |
4900 // Do not define the function when getting the body fails and when | 4902 // Do not define the function when getting the body fails and when |
4901 // skipping. | 4903 // skipping. |
4902 if (get_function_body(eap, &newlines, line_arg, lines_to_free) == FAIL | 4904 if (((class_flags & CF_INTERFACE) == 0 |
4905 && get_function_body(eap, &newlines, line_arg, lines_to_free) | |
4906 == FAIL) | |
4903 || eap->skip) | 4907 || eap->skip) |
4904 goto erret; | 4908 goto erret; |
4905 | 4909 |
4906 /* | 4910 /* |
4907 * If there are no errors, add the function | 4911 * If there are no errors, add the function |
4932 sprintf(numbuf, "%d", ++func_nr); | 4936 sprintf(numbuf, "%d", ++func_nr); |
4933 name = vim_strsave((char_u *)numbuf); | 4937 name = vim_strsave((char_u *)numbuf); |
4934 if (name == NULL) | 4938 if (name == NULL) |
4935 goto erret; | 4939 goto erret; |
4936 } | 4940 } |
4937 else if (!in_class) | 4941 else if (class_flags == 0) |
4938 { | 4942 { |
4939 hashtab_T *ht; | 4943 hashtab_T *ht; |
4940 char_u *find_name = name; | 4944 char_u *find_name = name; |
4941 int var_conflict = FALSE; | 4945 int var_conflict = FALSE; |
4942 int ffed_flags = is_global ? FFED_IS_GLOBAL : 0; | 4946 int ffed_flags = is_global ? FFED_IS_GLOBAL : 0; |
5157 if (overwrite) | 5161 if (overwrite) |
5158 { | 5162 { |
5159 hi = hash_find(&func_hashtab, name); | 5163 hi = hash_find(&func_hashtab, name); |
5160 hi->hi_key = UF2HIKEY(fp); | 5164 hi->hi_key = UF2HIKEY(fp); |
5161 } | 5165 } |
5162 else if (!in_class && hash_add(&func_hashtab, | 5166 else if (class_flags == 0 && hash_add(&func_hashtab, |
5163 UF2HIKEY(fp), "add function") == FAIL) | 5167 UF2HIKEY(fp), "add function") == FAIL) |
5164 { | 5168 { |
5165 free_fp = TRUE; | 5169 free_fp = TRUE; |
5166 goto erret; | 5170 goto erret; |
5167 } | 5171 } |
5249 ex_function(exarg_T *eap) | 5253 ex_function(exarg_T *eap) |
5250 { | 5254 { |
5251 garray_T lines_to_free; | 5255 garray_T lines_to_free; |
5252 | 5256 |
5253 ga_init2(&lines_to_free, sizeof(char_u *), 50); | 5257 ga_init2(&lines_to_free, sizeof(char_u *), 50); |
5254 (void)define_function(eap, NULL, &lines_to_free, FALSE); | 5258 (void)define_function(eap, NULL, &lines_to_free, 0); |
5255 ga_clear_strings(&lines_to_free); | 5259 ga_clear_strings(&lines_to_free); |
5256 } | 5260 } |
5257 | 5261 |
5258 /* | 5262 /* |
5259 * Find a function by name, including "<lambda>123". | 5263 * Find a function by name, including "<lambda>123". |