lp->ll_tv = &lp->ll_class->class_members_tv[m_idx];
#ifdef LOG_LOCKVAR
ch_log(NULL, "LKVAR: ... class member %s.%s",
- lp->ll_class->class_name, lp->ll_name);
+ lp->ll_class->class_name.string, lp->ll_name);
#endif
return;
}
{
if (om->ocm_type->tt_type == VAR_OBJECT)
semsg(_(e_enumvalue_str_cannot_be_modified),
- cl->class_name, om->ocm_name);
+ cl->class_name.string, om->ocm_name);
else
msg = e_variable_is_not_writable_str;
}
size_t len = vim_snprintf((char *)buf, sizeof(buf), "<SNR>%d_%s.%s",
pt->pt_func->uf_script_ctx.sc_sid,
- pt->pt_func->uf_class->class_name,
+ pt->pt_func->uf_class->class_name.string,
pt->pt_func->uf_name);
if (len >= sizeof(buf))
{
char_u *r = NULL;
size_t rsize;
class_T *cl = tv->vval.v_class;
- char_u *class_name = (char_u *)"[unknown]";
- size_t class_namelen = 9;
- char *s = "class";
- size_t slen = 5;
+ string_T class_name = {(char_u *)"[unknown]", 9};
+ string_T s = {(char_u *)"class", 5};
if (cl != NULL)
{
- class_name = cl->class_name;
- class_namelen = STRLEN(cl->class_name);
+ class_name.string = cl->class_name.string;
+ class_name.length = cl->class_name.length;
if (IS_INTERFACE(cl))
{
- s = "interface";
- slen = 9;
+ s.string = (char_u *)"interface";
+ s.length = 9;
}
else if (IS_ENUM(cl))
{
- s = "enum";
- slen = 4;
+ s.string = (char_u *)"enum";
+ s.length = 4;
}
}
- rsize = slen + 1 + class_namelen + 1;
+ rsize = s.length + 1 + class_name.length + 1;
r = *tofree = alloc(rsize);
if (r != NULL)
- vim_snprintf((char *)r, rsize, "%s %s", s, (char *)class_name);
+ vim_snprintf((char *)r, rsize, "%s %s", s.string, (char *)class_name.string);
return r;
}
else if (copyID != 0 && obj->obj_copyID == copyID
&& obj->obj_class->class_obj_member_count != 0)
{
- size_t n = 25 + STRLEN((char *)obj->obj_class->class_name);
+ size_t n = 25 + obj->obj_class->class_name.length;
r = alloc(n);
if (r != NULL)
(void)vim_snprintf((char *)r, n, "object of %s {...}",
- obj->obj_class->class_name);
+ obj->obj_class->class_name.string);
*tofree = r;
}
else
int did_alloc = FALSE;
char_u *vname = (char_u *)"";
char_u *class_name = lp->ll_class != NULL
- ? lp->ll_class->class_name : (char_u *)"";
+ ? lp->ll_class->class_name.string : (char_u *)"";
if (lp->ll_name != NULL)
{
if (lp->ll_name_end == NULL)
entry = ((estack_T *)exestack.ga_data) + idx;
if (entry->es_name != NULL)
{
- long lnum = 0;
- char_u *type_name = (char_u *)"";
- char_u *class_name = (char_u *)"";
+ long lnum = 0;
+ string_T type_name = {(char_u *)"", 0};
+ string_T class_name = {(char_u *)"", 0};
+ string_T es_name = {entry->es_name, STRLEN(entry->es_name)};
if (entry->es_type != last_type)
{
switch (entry->es_type)
{
- case ETYPE_SCRIPT: type_name = (char_u *)"script "; break;
- case ETYPE_UFUNC: type_name = (char_u *)"function "; break;
- default: type_name = (char_u *)""; break;
+ case ETYPE_SCRIPT:
+ type_name.string = (char_u *)"script ";
+ type_name.length = 7;
+ break;
+ case ETYPE_UFUNC:
+ type_name.string = (char_u *)"function ";
+ type_name.length = 9;
+ break;
+ default:
+ break;
}
last_type = entry->es_type;
}
if (entry->es_type == ETYPE_UFUNC && entry->es_info.ufunc->uf_class != NULL)
- class_name = entry->es_info.ufunc->uf_class->class_name;
+ {
+ class_name.string = entry->es_info.ufunc->uf_class->class_name.string;
+ class_name.length = entry->es_info.ufunc->uf_class->class_name.length;
+ }
if (idx == exestack.ga_len - 1)
lnum = which == ESTACK_STACK ? SOURCING_LNUM : 0;
else
lnum = entry->es_lnum;
- len = STRLEN(entry->es_name) + STRLEN(type_name) + STRLEN(class_name) + 26;
+
+ len = es_name.length + type_name.length + class_name.length + 26;
if (ga_grow(&ga, (int)len) == FAIL)
break;
- ga_concat(&ga, type_name);
- if (*class_name != NUL)
- {
- // For class methods prepend "<class name>." to the function name.
- ga_concat(&ga, (char_u *)"<SNR>");
- ga.ga_len += vim_snprintf((char *)ga.ga_data + ga.ga_len, 23,
- "%d_", entry->es_info.ufunc->uf_script_ctx.sc_sid);
- ga_concat(&ga, class_name);
- ga_append(&ga, '.');
- }
- ga_concat(&ga, entry->es_name);
+ ga_concat_len(&ga, type_name.string, type_name.length);
+ // For class methods prepend "<class name>." to the function name.
+ if (*class_name.string != NUL)
+ ga.ga_len += vim_snprintf_safelen(
+ (char *)ga.ga_data + ga.ga_len,
+ len - (size_t)ga.ga_len,
+ "<SNR>%d_%s.",
+ entry->es_info.ufunc->uf_script_ctx.sc_sid,
+ class_name.string);
+ ga_concat_len(&ga, es_name.string, es_name.length);
// For the bottom entry of <sfile>: do not add the line number, it is used in
// <slnum>. Also leave it out when the number is not set.
if (lnum != 0)
- ga.ga_len += vim_snprintf((char *)ga.ga_data + ga.ga_len, 23, "[%ld]",
- lnum);
+ ga.ga_len += vim_snprintf_safelen(
+ (char *)ga.ga_data + ga.ga_len,
+ len - (size_t)ga.ga_len,
+ "[%ld]",
+ lnum);
if (idx != exestack.ga_len - 1)
- ga_concat(&ga, (char_u *)"..");
+ ga_concat_len(&ga, (char_u *)"..", 2);
}
}
- ga_append(&ga, '\0');
+ ga_append(&ga, NUL);
return (char_u *)ga.ga_data;
#endif
}
// Also used for an interface (class_flags has CLASS_INTERFACE).
struct class_S
{
- char_u *class_name; // allocated
+ string_T class_name; // allocated
int class_flags; // CLASS_ flags
int class_refcount;
{
class_T *cl = varp->vval.v_object->obj_class;
if (cl != NULL && IS_ENUM(cl))
- semsg(_(e_using_enum_str_as_number), cl->class_name);
+ semsg(_(e_using_enum_str_as_number), cl->class_name.string);
else
emsg(_(e_using_object_as_number));
}
{
class_T *cl = varp->vval.v_object->obj_class;
if (cl != NULL && IS_ENUM(cl))
- semsg(_(e_using_enum_str_as_string), cl->class_name);
+ semsg(_(e_using_enum_str_as_string), cl->class_name.string);
else
emsg(_(e_using_object_as_string));
}
else if (lv.ll_tv->v_type == VAR_CLASS
&& lv.ll_tv->vval.v_class != NULL)
{
- name = vim_strsave(lv.ll_tv->vval.v_class->class_name);
+ name = vim_strnsave(lv.ll_tv->vval.v_class->class_name.string,
+ lv.ll_tv->vval.v_class->class_name.length);
*pp = end;
}
else if (lv.ll_tv->v_type == VAR_PARTIAL
(void)compile_def_function(ufunc, FALSE, compile_type, NULL);
else
smsg(_("Function %s%s%s does not need compiling"),
- cl != NULL ? cl->class_name : (char_u *)"",
+ cl != NULL ? cl->class_name.string : (char_u *)"",
cl != NULL ? (char_u *)"." : (char_u *)"",
ufunc->uf_name);
}
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 1983,
/**/
1982,
/**/
return OK;
}
-typedef struct oc_newmember_S oc_newmember_T;
-struct oc_newmember_S
-{
- garray_T *gap;
- char_u *varname;
- char_u *varname_end;
- int has_public;
- int has_final;
- int has_type;
- type_T *type;
- char_u *init_expr;
-};
-
/*
* Add a member to an object or a class.
* Returns OK when successful, "init_expr" will be consumed then.
if (idx >= (is_method ? itf->class_obj_method_count
: itf->class_obj_member_count))
{
- siemsg("index %d out of range for interface %s", idx, itf->class_name);
+ siemsg("index %d out of range for interface %s", idx, itf->class_name.string);
return 0;
}
if (i2c == NULL)
{
siemsg("class %s not found on interface %s",
- cl->class_name, itf->class_name);
+ cl->class_name.string, itf->class_name.string);
return 0;
}
typval_T tv;
int success = FALSE;
- if (STRCMP(cl->class_name, extends_name) == 0)
+ if (STRCMP(cl->class_name.string, extends_name) == 0)
{
semsg(_(e_cannot_extend_str), extends_name);
return success;
else
msg = e_generic_method_str_type_arguments_mismatch_in_class_str;
- semsg(_(msg), cl_fp->uf_name, super_cl->class_name);
+ semsg(_(msg), cl_fp->uf_name, super_cl->class_name.string);
return FALSE;
}
// Method access is different between the super class
// and the subclass
semsg(_(e_method_str_of_class_str_has_different_access),
- cl_fp[j]->uf_name, super->class_name);
+ cl_fp[j]->uf_name, super->class_name.string);
return FALSE;
}
char_u *intf_name;
// Add the interface name to "impl_gap"
- intf_name = vim_strsave(ifcl->class_name);
+ intf_name = vim_strnsave(ifcl->class_name.string, ifcl->class_name.length);
if (intf_name == NULL)
return FALSE;
if (init_expr == NULL)
vim_snprintf(initexpr_buf, sizeof(initexpr_buf), "%s.new()",
- en->class_name);
+ en->class_name.string);
else
{
vim_snprintf(initexpr_buf, sizeof(initexpr_buf), "%s.new%s",
- en->class_name, init_expr);
+ en->class_name.string, init_expr);
vim_free(init_expr);
}
if (add_member(gap, eni_name_start, eni_name_end, FALSE,
int rc = FAIL;
ga_init2(&fga, 1, 1000);
- ga_concat(&fga, (char_u *)"[");
+ ga_concat_len(&fga, (char_u *)"[", 1);
for (int i = 0; i < num_enum_values; ++i)
{
ocmember_T *m = ((ocmember_T *)gap->ga_data) + i;
if (i > 0)
- ga_concat(&fga, (char_u *)", ");
- ga_concat(&fga, en->class_name);
- ga_concat(&fga, (char_u *)".");
+ ga_concat_len(&fga, (char_u *)", ", 2);
+ ga_concat_len(&fga, en->class_name.string, en->class_name.length);
+ ga_concat_len(&fga, (char_u *)".", 1);
ga_concat(&fga, (char_u *)m->ocm_name);
}
- ga_concat(&fga, (char_u *)"]");
+ ga_concat_len(&fga, (char_u *)"]", 1);
ga_append(&fga, NUL);
char_u *varname = (char_u *)"values";
}
rc = add_member(gap, varname, varname + 6, FALSE, FALSE, TRUE, TRUE, type,
- vim_strsave((char_u *)fga.ga_data));
+ vim_strnsave((char_u *)fga.ga_data, fga.ga_len));
done:
vim_free(fga.ga_data);
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)
+ cl->class_name.length = (size_t)(name_end - name_start);
+ cl->class_name.string = vim_strnsave(name_start, cl->class_name.length);
+ if (cl->class_name.string == NULL)
goto cleanup;
cl->class_type.tt_type = VAR_CLASS;
tv.v_type = VAR_CLASS;
tv.vval.v_class = cl;
SOURCING_LNUM = start_lnum;
- int rc = set_var_const(cl->class_name, 0, NULL, &tv, FALSE, 0, 0);
+ int rc = set_var_const(cl->class_name.string, 0, NULL, &tv, FALSE, 0, 0);
if (rc == FAIL)
goto cleanup;
{
// Protected object or class funcref variable
semsg(_(e_cannot_access_protected_variable_str), ocm->ocm_name,
- cl->class_name);
+ cl->class_name.string);
return FAIL;
}
if (m->ocm_flags & (OCMFLAG_FINAL | OCMFLAG_CONST))
{
semsg(_(e_cannot_change_readonly_variable_str_in_class_str),
- m->ocm_name, cl->class_name);
+ m->ocm_name, cl->class_name.string);
return TRUE;
}
return FALSE;
// Freeing what the class contains may recursively come back here.
// Clear "class_name" first, if it is NULL the class does not need to
// be freed.
- VIM_CLEAR(cl->class_name);
+ VIM_CLEAR_STRING(cl->class_name);
class_unref(cl->class_extends);
--cl->class_refcount;
- if (cl->class_name == NULL)
+ if (cl->class_name.string == NULL)
return;
if (can_free_class(cl))
ocmember_T *m;
class_T *cl_def = class_defining_member(cl, name, len, &m);
if (cl_def != NULL)
- semsg(_(msg), m->ocm_name, cl_def->class_name);
+ semsg(_(msg), m->ocm_name, cl_def->class_name.string);
else
emsg(_(e_internal_error_please_report_a_bug));
}
semsg(_(e_cannot_access_protected_method_str), method_name);
else
semsg(_(e_class_method_str_accessible_only_using_class_str),
- method_name, cl->class_name);
+ method_name, cl->class_name.string);
}
else if ((v_type == VAR_CLASS)
&& (object_method_idx(cl, name, len) >= 0))
semsg(_(e_cannot_access_protected_method_str), method_name);
else
semsg(_(e_object_method_str_accessible_only_using_object_str),
- method_name, cl->class_name);
+ method_name, cl->class_name.string);
}
else
semsg(_(e_method_not_found_on_class_str_str), method_name,
- cl->class_name);
+ cl->class_name.string);
vim_free(method_name);
}
{
if (class_member_idx(cl, name, len) >= 0)
semsg(_(e_class_variable_str_accessible_only_using_class_str),
- varname, cl->class_name);
+ varname, cl->class_name.string);
else
semsg(_(e_variable_not_found_on_object_str_str), varname,
- cl->class_name);
+ cl->class_name.string);
}
else
{
if (object_member_idx(cl, name, len) >= 0)
semsg(_(e_object_variable_str_accessible_only_using_object_str),
- varname, cl->class_name);
+ varname, cl->class_name.string);
else
{
if (IS_ENUM(cl))
semsg(_(e_enum_value_str_not_found_in_enum_str),
- varname, cl->class_name);
+ varname, cl->class_name.string);
else
semsg(_(e_class_variable_str_not_found_in_class_str),
- varname, cl->class_name);
+ varname, cl->class_name.string);
}
}
vim_free(varname);
{
for (class_T *cl = first_class; cl != NULL; cl = cl->class_next_used)
{
- if (eval_variable(cl->class_name, 0, 0, NULL, NULL,
+ if (eval_variable(cl->class_name.string, 0, 0, NULL, NULL,
EVAL_VAR_NOAUTOLOAD | EVAL_VAR_NO_FUNC) != FAIL)
defcompile_class(cl);
}
if (cl != NULL && IS_ENUM(cl))
{
- ga_concat(&ga, (char_u *)"enum ");
- ga_concat(&ga, cl->class_name);
+ ga_concat_len(&ga, (char_u *)"enum ", 5);
+ ga_concat_len(&ga, cl->class_name.string, cl->class_name.length);
char_u *enum_name = ((typval_T *)(obj + 1))->vval.v_string;
- ga_concat(&ga, (char_u *)".");
+ ga_concat_len(&ga, (char_u *)".", 1);
ga_concat(&ga, enum_name);
}
else
{
- ga_concat(&ga, (char_u *)"object of ");
- ga_concat(&ga, cl == NULL ? (char_u *)"[unknown]"
- : cl->class_name);
+ ga_concat_len(&ga, (char_u *)"object of ", 10);
+ if (cl == NULL)
+ ga_concat_len(&ga, (char_u *)"[unknown]", 9);
+ else
+ ga_concat_len(&ga, cl->class_name.string, cl->class_name.length);
}
if (cl != NULL)
{
- ga_concat(&ga, (char_u *)" {");
+ ga_concat_len(&ga, (char_u *)" {", 2);
for (int i = 0; i < cl->class_obj_member_count; ++i)
{
if (i > 0)
- ga_concat(&ga, (char_u *)", ");
+ ga_concat_len(&ga, (char_u *)", ", 2);
ocmember_T *m = &cl->class_obj_members[i];
ga_concat(&ga, m->ocm_name);
- ga_concat(&ga, (char_u *)": ");
+ ga_concat_len(&ga, (char_u *)": ", 2);
char_u *tf = NULL;
char_u *s = echo_string_core((typval_T *)(obj + 1) + i,
&tf, numbuf, copyID, echo_style,
}
line_breakcheck();
}
- ga_concat(&ga, (char_u *)"}");
+ ga_concat_len(&ga, (char_u *)"}", 1);
}
if (ok == FAIL)
{
if (*end != '.' && *end != '[')
{
// Push the class of the bare class variable name
- name = cl->class_name;
- len = (int)STRLEN(name);
+ name = cl->class_name.string;
+ len = (int)cl->class_name.length;
#ifdef LOG_LOCKVAR
ch_log(NULL, "LKVAR: ... cctx_class_member: name %s",
name);
if (IS_ENUM(cl))
{
- semsg(_(e_enumvalue_str_cannot_be_modified), cl->class_name,
+ semsg(_(e_enumvalue_str_cannot_be_modified), cl->class_name.string,
m->ocm_name);
return FALSE;
}
// A class variable can be accessed without the class name
// only inside a class.
semsg(_(e_class_variable_str_accessible_only_inside_class_str),
- lhs->lhs_name, defcl->class_name);
+ lhs->lhs_name, defcl->class_name.string);
return FAIL;
}
if (!inside_class(cctx, cl))
{
semsg(_(e_enumvalue_str_cannot_be_modified),
- cl->class_name, m->ocm_name);
+ cl->class_name.string, m->ocm_name);
return FAIL;
}
if (lhs->lhs_type->tt_type == VAR_OBJECT &&
char *msg = lhs->lhs_member_idx == 0 ?
e_enum_str_name_cannot_be_modified :
e_enum_str_ordinal_cannot_be_modified;
- semsg(_(msg), cl->class_name);
+ semsg(_(msg), cl->class_name.string);
return FAIL;
}
}
msg = e_variable_not_found_on_object_str_str;
else
msg = e_class_variable_str_not_found_in_class_str;
- semsg(_(msg), iptr->isn_arg.string, tv_cl->class_name);
+ semsg(_(msg), iptr->isn_arg.string, tv_cl->class_name.string);
return FAIL;
}
{
case ISN_CONSTRUCT:
smsg("%s%4d NEW %s size %d", pfx, current,
- iptr->isn_arg.construct.construct_class->class_name,
+ iptr->isn_arg.construct.construct_class->class_name.string,
(int)iptr->isn_arg.construct.construct_size);
break;
case ISN_EXEC:
smsg("%s%4d %s CLASSMEMBER %s.%s", pfx, current,
iptr->isn_type == ISN_LOAD_CLASSMEMBER
? "LOAD" : "STORE",
- cl->class_name, ocm->ocm_name);
+ cl->class_name.string, ocm->ocm_name);
}
break;
case ISN_PUSHCLASS:
smsg("%s%4d PUSHCLASS %s", pfx, current,
iptr->isn_arg.classarg == NULL ? "null"
- : (char *)iptr->isn_arg.classarg->class_name);
+ : (char *)iptr->isn_arg.classarg->class_name.string);
break;
case ISN_PUSHEXC:
smsg("%s%4d PUSH v:exception", pfx, current);
cmfunc_T *mfunc = iptr->isn_arg.mfunc;
smsg("%s%4d METHODCALL %s.%s(argc %d)", pfx, current,
- mfunc->cmf_itf->class_name,
+ mfunc->cmf_itf->class_name.string,
mfunc->cmf_itf->class_obj_methods[
mfunc->cmf_idx]->uf_name,
mfunc->cmf_argcount);
if (extra != NULL && extra->fre_class != NULL)
{
smsg("%s%4d FUNCREF %s.%s", pfx, current,
- extra->fre_class->class_name, name);
+ extra->fre_class->class_name.string, name);
}
else if (extra == NULL
|| extra->fre_loopvar_info.lvi_depth == 0)
case ISN_GET_ITF_MEMBER: smsg("%s%4d ITF_MEMBER %d on %s",
pfx, current,
(int)iptr->isn_arg.classmember.cm_idx,
- iptr->isn_arg.classmember.cm_class->class_name);
+ iptr->isn_arg.classmember.cm_class->class_name.string);
break;
case ISN_STORE_THIS: smsg("%s%4d STORE_THIS %d", pfx, current,
(int)iptr->isn_arg.number); break;
// Trying to invoke an abstract method in a super class is not
// allowed.
semsg(_(e_abstract_method_str_direct), ufunc->uf_name,
- ufunc->uf_defclass->class_name);
+ ufunc->uf_defclass->class_name.string);
goto done;
}
else
{
semsg(_(e_class_variable_str_accessible_only_inside_class_str),
- name, cl->class_name);
+ name, cl->class_name.string);
res = FAIL;
}
}
else
{
semsg(_(e_class_method_str_accessible_only_inside_class_str),
- name, cl->class_name);
+ name, cl->class_name.string);
res = FAIL;
}
goto theend;
static char *
type_name_class_or_obj(char *name, type_T *type, char **tofree)
{
- char_u *class_name;
+ string_T class_name;
if (type->tt_class != NULL)
{
- class_name = type->tt_class->class_name;
+ class_name.string = type->tt_class->class_name.string;
+ class_name.length = type->tt_class->class_name.length;
if (IS_ENUM(type->tt_class))
name = "enum";
}
else
- class_name = (char_u *)"any";
+ {
+ class_name.string = (char_u *)"any";
+ class_name.length = 3;
+ }
- size_t len = STRLEN(name) + STRLEN(class_name) + 3;
+ size_t len = STRLEN(name) + class_name.length + 3;
*tofree = alloc(len);
if (*tofree == NULL)
return name;
- vim_snprintf(*tofree, len, "%s<%s>", name, class_name);
+ vim_snprintf(*tofree, len, "%s<%s>", name, class_name.string);
return *tofree;
}
{
class_T *cl = tv->vval.v_class;
char_u *class_name = (cl == NULL) ? (char_u *)""
- : cl->class_name;
+ : cl->class_name.string;
if (cl != NULL && IS_ENUM(cl))
semsg(_(e_using_enum_as_value_str), class_name);
else
case VAR_CLASS:
if (type->tt_class != NULL && IS_ENUM(type->tt_class))
semsg(_(e_using_enum_as_value_str),
- type->tt_class->class_name);
+ type->tt_class->class_name.string);
else
semsg(_(e_using_class_as_value_str),
type->tt_class == NULL ? (char_u *)""
- : type->tt_class->class_name);
+ : type->tt_class->class_name.string);
return FAIL;
case VAR_TYPEALIAS: