mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
patch 9.0.2076: Vim9: No support for type aliases
Problem: Vim9: No support for type aliases Solution: Implement :type command A type definition is giving a name to a type specification. This also known type alias. :type ListOfStrings = list<string> The type alias can be used wherever a built-in type can be used. The type alias name must start with an upper case character. closes: #13407 Signed-off-by: Christian Brabandt <cb@256bit.org> Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
This commit is contained in:
committed by
Christian Brabandt
parent
4bca4897a1
commit
ec3cebbd2b
111
src/vim9class.c
111
src/vim9class.c
@@ -2095,12 +2095,119 @@ ex_enum(exarg_T *eap UNUSED)
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle ":type".
|
||||
* Type aliases (:type)
|
||||
*/
|
||||
|
||||
void
|
||||
typealias_free(typealias_T *ta)
|
||||
{
|
||||
// ta->ta_type is freed in clear_type_list()
|
||||
vim_free(ta->ta_name);
|
||||
vim_free(ta);
|
||||
}
|
||||
|
||||
void
|
||||
typealias_unref(typealias_T *ta)
|
||||
{
|
||||
if (ta != NULL && --ta->ta_refcount <= 0)
|
||||
typealias_free(ta);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle ":type". Create an alias for a type specification.
|
||||
*/
|
||||
void
|
||||
ex_type(exarg_T *eap UNUSED)
|
||||
{
|
||||
// TODO
|
||||
char_u *arg = eap->arg;
|
||||
|
||||
if (!current_script_is_vim9()
|
||||
|| (cmdmod.cmod_flags & CMOD_LEGACY)
|
||||
|| !getline_equal(eap->getline, eap->cookie, getsourceline))
|
||||
{
|
||||
emsg(_(e_type_can_only_be_defined_in_vim9_script));
|
||||
return;
|
||||
}
|
||||
|
||||
if (*arg == NUL)
|
||||
{
|
||||
emsg(_(e_missing_typealias_name));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ASCII_ISUPPER(*arg))
|
||||
{
|
||||
semsg(_(e_type_name_must_start_with_uppercase_letter_str), arg);
|
||||
return;
|
||||
}
|
||||
|
||||
char_u *name_end = find_name_end(arg, NULL, NULL, FNE_CHECK_START);
|
||||
if (!IS_WHITE_OR_NUL(*name_end))
|
||||
{
|
||||
semsg(_(e_white_space_required_after_name_str), arg);
|
||||
return;
|
||||
}
|
||||
char_u *name_start = arg;
|
||||
|
||||
arg = skipwhite(name_end);
|
||||
if (*arg != '=')
|
||||
{
|
||||
semsg(_(e_missing_equal_str), arg);
|
||||
return;
|
||||
}
|
||||
if (!IS_WHITE_OR_NUL(*(arg + 1)))
|
||||
{
|
||||
semsg(_(e_white_space_required_after_str_str), "=", arg);
|
||||
return;
|
||||
}
|
||||
arg++;
|
||||
arg = skipwhite(arg);
|
||||
|
||||
if (*arg == NUL)
|
||||
{
|
||||
emsg(_(e_missing_typealias_type));
|
||||
return;
|
||||
}
|
||||
|
||||
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
|
||||
type_T *type = parse_type(&arg, &si->sn_type_list, TRUE);
|
||||
if (type == NULL)
|
||||
return;
|
||||
|
||||
if (*arg != NUL)
|
||||
{
|
||||
// some text after the type
|
||||
semsg(_(e_trailing_characters_str), arg);
|
||||
return;
|
||||
}
|
||||
|
||||
int cc = *name_end;
|
||||
*name_end = NUL;
|
||||
|
||||
typval_T tv;
|
||||
tv.v_type = VAR_UNKNOWN;
|
||||
if (eval_variable_import(name_start, &tv) == OK)
|
||||
{
|
||||
if (tv.v_type == VAR_TYPEALIAS)
|
||||
semsg(_(e_typealias_already_exists_for_str), name_start);
|
||||
else
|
||||
semsg(_(e_redefining_script_item_str), name_start);
|
||||
clear_tv(&tv);
|
||||
goto done;
|
||||
}
|
||||
|
||||
// Add the user-defined type to the script-local variables.
|
||||
tv.v_type = VAR_TYPEALIAS;
|
||||
tv.v_lock = 0;
|
||||
tv.vval.v_typealias = ALLOC_CLEAR_ONE(typealias_T);
|
||||
++tv.vval.v_typealias->ta_refcount;
|
||||
tv.vval.v_typealias->ta_name = vim_strsave(name_start);
|
||||
tv.vval.v_typealias->ta_type = type;
|
||||
set_var_const(name_start, current_sctx.sc_sid, NULL, &tv, FALSE,
|
||||
ASSIGN_CONST | ASSIGN_FINAL, 0);
|
||||
|
||||
done:
|
||||
*name_end = cc;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user