diff options
Diffstat (limited to 'src/vim9class.c')
-rw-r--r-- | src/vim9class.c | 90 |
1 files changed, 39 insertions, 51 deletions
diff --git a/src/vim9class.c b/src/vim9class.c index 7357520199..7227c3dc28 100644 --- a/src/vim9class.c +++ b/src/vim9class.c @@ -208,7 +208,7 @@ add_member( * "parent_count" is the number of members in the parent class * "members" will be set to the newly allocated array of members and * "member_count" set to the number of members. - * Returns OK or FAIL. + * Returns OK on success and FAIL on memory allocation failure. */ static int add_members_to_class( @@ -301,6 +301,7 @@ object_index_from_itf_index(class_T *itf, int is_method, int idx, class_T *cl) */ static int validate_extends_class( + class_T *cl, char_u *extends_name, class_T **extends_clp, int is_class) @@ -308,6 +309,12 @@ validate_extends_class( typval_T tv; int success = FALSE; + if (STRCMP(cl->class_name, extends_name) == 0) + { + semsg(_(e_cannot_extend_str), extends_name); + return success; + } + tv.v_type = VAR_UNKNOWN; if (eval_variable_import(extends_name, &tv) == FAIL) { @@ -1642,6 +1649,36 @@ early_ret: garray_T objmethods; ga_init2(&objmethods, sizeof(ufunc_T *), 10); + class_T *cl = NULL; + class_T *extends_cl = NULL; // class from "extends" argument + class_T **intf_classes = NULL; + + cl = ALLOC_CLEAR_ONE(class_T); + if (cl == NULL) + goto cleanup; + if (!is_class) + cl->class_flags = CLASS_INTERFACE; + else if (is_abstract) + cl->class_flags = CLASS_ABSTRACT; + + cl->class_refcount = 1; + cl->class_name = vim_strnsave(name_start, name_end - name_start); + if (cl->class_name == NULL) + goto cleanup; + + // Add the class to the script-local variables. + // TODO: handle other context, e.g. in a function + // TODO: does uf_hash need to be cleared? + typval_T tv; + tv.v_type = VAR_CLASS; + tv.vval.v_class = cl; + is_export = class_export; + SOURCING_LNUM = start_lnum; + int rc = set_var_const(cl->class_name, current_sctx.sc_sid, + NULL, &tv, FALSE, 0, 0); + if (rc == FAIL) + goto cleanup; + /* * Go over the body of the class/interface until "endclass" or * "endinterface" is found. @@ -1981,15 +2018,13 @@ early_ret: } vim_free(theline); - class_T *extends_cl = NULL; // class from "extends" argument - /* * Check a few things before defining the class. */ // Check the "extends" class is valid. if (success && extends != NULL) - success = validate_extends_class(extends, &extends_cl, is_class); + success = validate_extends_class(cl, extends, &extends_cl, is_class); VIM_CLEAR(extends); // Check the new object methods to make sure their access (public or @@ -2016,8 +2051,6 @@ early_ret: success = validate_abstract_class_methods(&classfunctions, &objmethods, extends_cl); - class_T **intf_classes = NULL; - // Check all "implements" entries are valid. if (success && ga_impl.ga_len > 0) { @@ -2032,24 +2065,10 @@ early_ret: success = check_func_arg_names(&classfunctions, &objmethods, &classmembers); - class_T *cl = NULL; if (success) { // "endclass" encountered without failures: Create the class. - cl = ALLOC_CLEAR_ONE(class_T); - if (cl == NULL) - goto cleanup; - if (!is_class) - cl->class_flags = CLASS_INTERFACE; - else if (is_abstract) - cl->class_flags = CLASS_ABSTRACT; - - cl->class_refcount = 1; - cl->class_name = vim_strnsave(name_start, name_end - name_start); - if (cl->class_name == NULL) - goto cleanup; - if (extends_cl != NULL) { cl->class_extends = extends_cl; @@ -2136,41 +2155,10 @@ early_ret: // TODO: // - Fill hashtab with object members and methods ? - // Add the class to the script-local variables. - // TODO: handle other context, e.g. in a function - // TODO: does uf_hash need to be cleared? - typval_T tv; - tv.v_type = VAR_CLASS; - tv.vval.v_class = cl; - is_export = class_export; - SOURCING_LNUM = start_lnum; - set_var_const(cl->class_name, current_sctx.sc_sid, - NULL, &tv, FALSE, 0, 0); return; } cleanup: - if (cl != NULL) - { - vim_free(cl->class_name); - vim_free(cl->class_class_functions); - if (cl->class_interfaces != NULL) - { - for (int i = 0; i < cl->class_interface_count; ++i) - vim_free(cl->class_interfaces[i]); - vim_free(cl->class_interfaces); - } - if (cl->class_interfaces_cl != NULL) - { - for (int i = 0; i < cl->class_interface_count; ++i) - class_unref(cl->class_interfaces_cl[i]); - vim_free(cl->class_interfaces_cl); - } - vim_free(cl->class_obj_members); - vim_free(cl->class_obj_methods); - vim_free(cl); - } - vim_free(extends); class_unref(extends_cl); |