0
0
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:
Yegappan Lakshmanan
2023-10-27 19:35:26 +02:00
committed by Christian Brabandt
parent 4bca4897a1
commit ec3cebbd2b
22 changed files with 710 additions and 36 deletions

View File

@@ -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;
}
/*