forked from aniani/vim
patch 9.0.2078: several problems with type aliases
Problem: several problems with type aliases Solution: Check for more error conditions, add tests, fix issues Check for more error conditions and add additional tests fixes #13434 fixes #13437 fixes #13438 closes #13441 Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
parent
87ca5e86fa
commit
feaccd2395
@ -749,7 +749,9 @@ type alias. For Example: >
|
||||
: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.
|
||||
alias name must start with an upper case character. A type alias can be
|
||||
created only at the script level and not inside a function. A type alias can
|
||||
be exported and used across scripts.
|
||||
|
||||
==============================================================================
|
||||
|
||||
|
14
src/errors.h
14
src/errors.h
@ -3542,8 +3542,8 @@ EXTERN char e_type_can_only_be_defined_in_vim9_script[]
|
||||
INIT(= N_("E1393: Type can only be defined in Vim9 script"));
|
||||
EXTERN char e_type_name_must_start_with_uppercase_letter_str[]
|
||||
INIT(= N_("E1394: Type name must start with an uppercase letter: %s"));
|
||||
EXTERN char e_using_typealias_as_variable[]
|
||||
INIT(= N_("E1395: Type alias \"%s\" cannot be used as a variable"));
|
||||
EXTERN char e_cannot_modify_typealias[]
|
||||
INIT(= N_("E1395: Type alias \"%s\" cannot be modified"));
|
||||
EXTERN char e_typealias_already_exists_for_str[]
|
||||
INIT(= N_("E1396: Type alias \"%s\" already exists"));
|
||||
EXTERN char e_missing_typealias_name[]
|
||||
@ -3552,8 +3552,16 @@ EXTERN char e_missing_typealias_type[]
|
||||
INIT(= N_("E1398: Missing type alias type"));
|
||||
EXTERN char e_type_can_only_be_used_in_script[]
|
||||
INIT(= N_("E1399: Type can only be used in a script"));
|
||||
EXTERN char e_using_typealias_as_number[]
|
||||
INIT(= N_("E1400: Using type alias \"%s\" as a Number"));
|
||||
EXTERN char e_using_typealias_as_float[]
|
||||
INIT(= N_("E1401: Using type alias \"%s\" as a Float"));
|
||||
EXTERN char e_using_typealias_as_string[]
|
||||
INIT(= N_("E1402: Using type alias \"%s\" as a String"));
|
||||
EXTERN char e_using_typealias_as_value[]
|
||||
INIT(= N_("E1403: Type alias \"%s\" cannot be used as a value"));
|
||||
#endif
|
||||
// E1400 - E1499 unused (reserved for Vim9 class support)
|
||||
// E1404 - E1499 unused (reserved for Vim9 class support)
|
||||
EXTERN char e_cannot_mix_positional_and_non_positional_str[]
|
||||
INIT(= N_("E1500: Cannot mix positional and non-positional arguments: %s"));
|
||||
EXTERN char e_fmt_arg_nr_unused_str[]
|
||||
|
@ -1885,7 +1885,7 @@ set_var_lval(
|
||||
{
|
||||
if (di != NULL && di->di_tv.v_type == VAR_TYPEALIAS)
|
||||
{
|
||||
semsg(_(e_using_typealias_as_variable),
|
||||
semsg(_(e_cannot_modify_typealias),
|
||||
di->di_tv.vval.v_typealias->ta_name);
|
||||
clear_tv(&tv);
|
||||
return;
|
||||
@ -4045,7 +4045,8 @@ eval8(
|
||||
|
||||
if (!equal_type(want_type, actual, 0))
|
||||
{
|
||||
if (want_type == &t_bool && actual != &t_bool
|
||||
if (want_type->tt_type == VAR_BOOL
|
||||
&& actual->tt_type != VAR_BOOL
|
||||
&& (actual->tt_flags & TTFLAG_BOOL_OK))
|
||||
{
|
||||
int n = tv2bool(rettv);
|
||||
|
@ -1838,7 +1838,7 @@ ex_let_one(
|
||||
|
||||
if (tv->v_type == VAR_TYPEALIAS)
|
||||
{
|
||||
semsg(_(e_using_typealias_as_variable), tv->vval.v_typealias->ta_name);
|
||||
semsg(_(e_using_typealias_as_value), tv->vval.v_typealias->ta_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -3979,7 +3979,7 @@ set_var_const(
|
||||
|
||||
if (di->di_tv.v_type == VAR_TYPEALIAS)
|
||||
{
|
||||
semsg(_(e_using_typealias_as_variable),
|
||||
semsg(_(e_cannot_modify_typealias),
|
||||
di->di_tv.vval.v_typealias->ta_name);
|
||||
clear_tv(&di->di_tv);
|
||||
goto failed;
|
||||
|
@ -52,6 +52,7 @@ int check_for_list_or_dict_or_blob_arg(typval_T *args, int idx);
|
||||
int check_for_list_or_dict_or_blob_or_string_arg(typval_T *args, int idx);
|
||||
int check_for_opt_buffer_or_dict_arg(typval_T *args, int idx);
|
||||
int check_for_object_arg(typval_T *args, int idx);
|
||||
int tv_class_alias(typval_T *tv);
|
||||
int check_for_class_or_list_arg(typval_T *args, int idx);
|
||||
char_u *tv_get_string(typval_T *varp);
|
||||
char_u *tv_get_string_strict(typval_T *varp);
|
||||
|
@ -4785,16 +4785,15 @@ enddef
|
||||
|
||||
" Test for :type command to create type aliases
|
||||
def Test_typealias()
|
||||
# Use type alias at script level
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
type ListOfStrings = list<string>
|
||||
var a: ListOfStrings = ['a', 'b']
|
||||
assert_equal(['a', 'b'], a)
|
||||
def Foo(b: ListOfStrings): ListOfStrings
|
||||
var c: ListOfStrings = ['c', 'd']
|
||||
assert_equal(['c', 'd'], c)
|
||||
return b
|
||||
def Foo(a: ListOfStrings): ListOfStrings
|
||||
return a
|
||||
enddef
|
||||
var b: ListOfStrings = ['a', 'b']
|
||||
assert_equal(['a', 'b'], b)
|
||||
assert_equal(['e', 'f'], Foo(['e', 'f']))
|
||||
assert_equal('typealias<list<string>>', typename(ListOfStrings))
|
||||
assert_equal(v:t_typealias, type(ListOfStrings))
|
||||
@ -4803,6 +4802,26 @@ def Test_typealias()
|
||||
END
|
||||
v9.CheckSourceSuccess(lines)
|
||||
|
||||
# Use type alias at def function level
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
type ListOfStrings = list<string>
|
||||
def Foo(a: ListOfStrings): ListOfStrings
|
||||
return a
|
||||
enddef
|
||||
def Bar()
|
||||
var c: ListOfStrings = ['c', 'd']
|
||||
assert_equal(['c', 'd'], c)
|
||||
assert_equal(['e', 'f'], Foo(['e', 'f']))
|
||||
assert_equal('typealias<list<string>>', typename(ListOfStrings))
|
||||
assert_equal(v:t_typealias, type(ListOfStrings))
|
||||
assert_equal('ListOfStrings', string(ListOfStrings))
|
||||
assert_equal(false, null == ListOfStrings)
|
||||
enddef
|
||||
Bar()
|
||||
END
|
||||
v9.CheckSourceSuccess(lines)
|
||||
|
||||
# Use :type outside a Vim9 script
|
||||
lines =<< trim END
|
||||
type Index = number
|
||||
@ -4861,9 +4880,9 @@ def Test_typealias()
|
||||
# type alias starting with lower-case letter
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
type index number
|
||||
type index = number
|
||||
END
|
||||
v9.CheckSourceFailure(lines, 'E1394: Type name must start with an uppercase letter: index number', 2)
|
||||
v9.CheckSourceFailure(lines, 'E1394: Type name must start with an uppercase letter: index = number', 2)
|
||||
|
||||
# No white space following the alias name
|
||||
lines =<< trim END
|
||||
@ -4895,27 +4914,74 @@ def Test_typealias()
|
||||
END
|
||||
v9.CheckSourceFailure(lines, 'E1396: Type alias "MyList" already exists', 3)
|
||||
|
||||
# Sourcing a script twice (which will free script local variables)
|
||||
# def function argument name collision with a type alias
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
type A = list<number>
|
||||
def Foo(A: number)
|
||||
enddef
|
||||
END
|
||||
v9.CheckSourceFailure(lines, 'E1168: Argument already declared in the script: A: number)', 3)
|
||||
|
||||
# def function local variable name collision with a type alias
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
type A = list<number>
|
||||
def Foo()
|
||||
var A: number = 10
|
||||
enddef
|
||||
Foo()
|
||||
END
|
||||
v9.CheckSourceFailure(lines, 'E1054: Variable already declared in the script: A', 1)
|
||||
|
||||
# type alias a variable
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
var A: list<number> = []
|
||||
type B = A
|
||||
END
|
||||
v9.CheckSourceFailure(lines, 'E1010: Type not recognized: A', 3)
|
||||
|
||||
# type alias a class
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
class C
|
||||
endclass
|
||||
type AC = C
|
||||
assert_equal('typealias<object<C>>', typename(AC))
|
||||
assert_equal('class<C>', typename(AC))
|
||||
END
|
||||
v9.CheckSourceSuccess(lines)
|
||||
|
||||
# Sourcing a script twice (which will free script local variables)
|
||||
# Uses "lines" from the previous test
|
||||
new
|
||||
setline(1, lines)
|
||||
:source
|
||||
:source
|
||||
bw!
|
||||
|
||||
# type alias a type alias
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
type A = string
|
||||
type B = A
|
||||
var b: B = 'abc'
|
||||
assert_equal('abc', b)
|
||||
def Foo()
|
||||
var c: B = 'def'
|
||||
assert_equal('def', c)
|
||||
enddef
|
||||
Foo()
|
||||
END
|
||||
v9.CheckSourceSuccess(lines)
|
||||
|
||||
# Assigning to a type alias (script level)
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
type MyType = list<number>
|
||||
MyType = [1, 2, 3]
|
||||
END
|
||||
v9.CheckSourceFailure(lines, 'E1395: Type alias "MyType" cannot be used as a variable', 3)
|
||||
v9.CheckSourceFailure(lines, 'E1395: Type alias "MyType" cannot be modified', 3)
|
||||
|
||||
# Assigning a type alias (def function level)
|
||||
lines =<< trim END
|
||||
@ -4926,16 +4992,18 @@ def Test_typealias()
|
||||
enddef
|
||||
Foo()
|
||||
END
|
||||
v9.CheckSourceFailure(lines, 'E1395: Type alias "A" cannot be used as a variable', 1)
|
||||
v9.CheckSourceFailure(lines, 'E1403: Type alias "A" cannot be used as a value', 1)
|
||||
|
||||
# Using type alias in an expression (script level)
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
type MyType = list<number>
|
||||
assert_fails('var m = MyType', 'E1395: Type alias "MyType" cannot be used as a variable')
|
||||
assert_fails('var i = MyType + 1', 'E1395: Type alias "MyType" cannot be used as a variable')
|
||||
assert_fails('var f = 1.0 + MyType', 'E1395: Type alias "MyType" cannot be used as a variable')
|
||||
assert_fails('MyType += 10', 'E1395: Type alias "MyType" cannot be used as a variable')
|
||||
assert_fails('var m = MyType', 'E1403: Type alias "MyType" cannot be used as a value')
|
||||
assert_fails('var i = MyType + 1', 'E1400: Using type alias "MyType" as a Number')
|
||||
assert_fails('var f = 1.0 + MyType', 'E1400: Using type alias "MyType" as a Number')
|
||||
assert_fails('MyType += 10', 'E1395: Type alias "MyType" cannot be modified')
|
||||
assert_fails('var x = $"-{MyType}-"', 'E1402: Using type alias "MyType" as a String')
|
||||
assert_fails('var x = MyType[1]', 'E909: Cannot index a special variable')
|
||||
END
|
||||
v9.CheckSourceSuccess(lines)
|
||||
|
||||
@ -4948,7 +5016,7 @@ def Test_typealias()
|
||||
enddef
|
||||
Foo()
|
||||
END
|
||||
v9.CheckSourceFailure(lines, 'E1395: Type alias "MyType" cannot be used as a variable', 1)
|
||||
v9.CheckSourceFailure(lines, 'E1051: Wrong argument type for +', 1)
|
||||
|
||||
# Using type alias in an expression (def function level)
|
||||
lines =<< trim END
|
||||
@ -4972,6 +5040,25 @@ def Test_typealias()
|
||||
END
|
||||
v9.CheckSourceFailure(lines, 'E46: Cannot change read-only variable "MyType"', 1)
|
||||
|
||||
# Convert type alias to a string (def function level)
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
type MyType = list<number>
|
||||
def Foo()
|
||||
var x = $"-{MyType}-"
|
||||
enddef
|
||||
Foo()
|
||||
END
|
||||
v9.CheckSourceFailure(lines, 'E1105: Cannot convert typealias to string', 1)
|
||||
|
||||
# Using type alias as a float
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
type B = number
|
||||
sort([1.1, B], 'f')
|
||||
END
|
||||
v9.CheckSourceFailure(lines, 'E1401: Using type alias "B" as a Float', 3)
|
||||
|
||||
# Creating a typealias in a def function
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
@ -5010,11 +5097,19 @@ def Test_typealias()
|
||||
enddef
|
||||
Foo()
|
||||
END
|
||||
v9.CheckSourceFailure(lines, 'E1395: Type alias "A" cannot be used as a variable', 2)
|
||||
v9.CheckSourceFailure(lines, 'E1072: Cannot compare typealias with number', 2)
|
||||
|
||||
# casting a number to a type alias (script level)
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
type MyType = bool
|
||||
assert_equal(true, <MyType>1 == true)
|
||||
END
|
||||
v9.CheckSourceSuccess(lines)
|
||||
enddef
|
||||
|
||||
" Test for exporting and importing type aliases
|
||||
def Test_import_typealias()
|
||||
def Test_typealias_import()
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
export type MyType = list<number>
|
||||
@ -5073,6 +5168,24 @@ def Test_import_typealias()
|
||||
assert_equal([4, 5, 6], myList2)
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
|
||||
# Using an exported class to create a type alias
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
export class MyClass
|
||||
this.val = 10
|
||||
endclass
|
||||
END
|
||||
writefile(lines, 'Xtypeexport4.vim', 'D')
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
import './Xtypeexport4.vim' as T
|
||||
|
||||
type MyType3 = T.MyClass
|
||||
var c: MyType3 = T.MyClass.new()
|
||||
assert_equal(10, c.val)
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
" Test for using typealias as a def function argument and return type
|
||||
@ -5131,6 +5244,17 @@ def Test_typealias_with_builtin_functions()
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E701: Invalid type for len()', 3)
|
||||
|
||||
# Using a type alias with len()
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
type A = list<func>
|
||||
def Foo()
|
||||
var x = len(A)
|
||||
enddef
|
||||
Foo()
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch, expected list<any> but got typealias', 1)
|
||||
|
||||
# Using a type alias with eval()
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
@ -5140,7 +5264,7 @@ def Test_typealias_with_builtin_functions()
|
||||
enddef
|
||||
Foo()
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E1395: Type alias "A" cannot be used as a variable', 1)
|
||||
v9.CheckScriptFailure(lines, 'E1403: Type alias "A" cannot be used as a value', 1)
|
||||
enddef
|
||||
|
||||
" Test for type alias refcount
|
||||
@ -5161,6 +5285,37 @@ def Test_typealias_refcount()
|
||||
v9.CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
" Test for using instanceof() with a type alias
|
||||
def Test_typealias_instanceof()
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
class C
|
||||
endclass
|
||||
|
||||
type Ctype = C
|
||||
var o = C.new()
|
||||
assert_equal(1, instanceof(o, Ctype))
|
||||
type Ntype = number
|
||||
assert_fails('instanceof(o, Ntype)', 'E693: List or Class required for argument 2')
|
||||
assert_equal(1, instanceof(o, [Ctype]))
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
" Test for type aliasing a class
|
||||
def Test_typealias_class()
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
class C
|
||||
this.color = 'green'
|
||||
endclass
|
||||
type MyClass = C
|
||||
var o: MyClass = MyClass.new()
|
||||
assert_equal('green', o.color)
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
" Keep this last, it messes up highlighting.
|
||||
def Test_substitute_cmd()
|
||||
new
|
||||
|
20
src/typval.c
20
src/typval.c
@ -271,7 +271,7 @@ tv_get_bool_or_number_chk(
|
||||
emsg(_(e_cannot_use_void_value));
|
||||
break;
|
||||
case VAR_TYPEALIAS:
|
||||
semsg(_(e_using_typealias_as_variable),
|
||||
semsg(_(e_using_typealias_as_number),
|
||||
varp->vval.v_typealias->ta_name);
|
||||
break;
|
||||
case VAR_UNKNOWN:
|
||||
@ -392,7 +392,7 @@ tv_get_float_chk(typval_T *varp, int *error)
|
||||
emsg(_(e_cannot_use_void_value));
|
||||
break;
|
||||
case VAR_TYPEALIAS:
|
||||
semsg(_(e_using_typealias_as_variable),
|
||||
semsg(_(e_using_typealias_as_float),
|
||||
varp->vval.v_typealias->ta_name);
|
||||
break;
|
||||
case VAR_UNKNOWN:
|
||||
@ -1003,13 +1003,24 @@ check_for_object_arg(typval_T *args, int idx)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns TRUE if "tv" is a type alias for a class
|
||||
*/
|
||||
int
|
||||
tv_class_alias(typval_T *tv)
|
||||
{
|
||||
return tv->v_type == VAR_TYPEALIAS &&
|
||||
tv->vval.v_typealias->ta_type->tt_type == VAR_OBJECT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Give an error and return FAIL unless "args[idx]" is a class or a list.
|
||||
*/
|
||||
int
|
||||
check_for_class_or_list_arg(typval_T *args, int idx)
|
||||
{
|
||||
if (args[idx].v_type != VAR_CLASS && args[idx].v_type != VAR_LIST)
|
||||
if (args[idx].v_type != VAR_CLASS && args[idx].v_type != VAR_LIST
|
||||
&& !tv_class_alias(&args[idx]))
|
||||
{
|
||||
semsg(_(e_list_or_class_required_for_argument_nr), idx + 1);
|
||||
return FAIL;
|
||||
@ -1146,6 +1157,9 @@ tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict)
|
||||
emsg(_(e_cannot_use_void_value));
|
||||
break;
|
||||
case VAR_TYPEALIAS:
|
||||
semsg(_(e_using_typealias_as_string),
|
||||
varp->vval.v_typealias->ta_name);
|
||||
break;
|
||||
case VAR_UNKNOWN:
|
||||
case VAR_ANY:
|
||||
case VAR_INSTR:
|
||||
|
@ -704,6 +704,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
2078,
|
||||
/**/
|
||||
2077,
|
||||
/**/
|
||||
|
@ -2196,13 +2196,26 @@ ex_type(exarg_T *eap UNUSED)
|
||||
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;
|
||||
// Create a script-local variable for the type alias.
|
||||
if (type->tt_type != VAR_OBJECT)
|
||||
{
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
// When creating a type alias for a class, use the class type itself to
|
||||
// create the type alias variable. This is needed to use the type
|
||||
// alias to invoke class methods (e.g. new()) and use class variables.
|
||||
tv.v_type = VAR_CLASS;
|
||||
tv.v_lock = 0;
|
||||
tv.vval.v_class = type->tt_class;
|
||||
++tv.vval.v_class->class_refcount;
|
||||
}
|
||||
set_var_const(name_start, current_sctx.sc_sid, NULL, &tv, FALSE,
|
||||
ASSIGN_CONST | ASSIGN_FINAL, 0);
|
||||
|
||||
@ -3155,6 +3168,7 @@ f_instanceof(typval_T *argvars, typval_T *rettv)
|
||||
typval_T *object_tv = &argvars[0];
|
||||
typval_T *classinfo_tv = &argvars[1];
|
||||
listitem_T *li;
|
||||
class_T *c;
|
||||
|
||||
rettv->vval.v_number = VVAL_FALSE;
|
||||
|
||||
@ -3169,25 +3183,35 @@ f_instanceof(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
FOR_ALL_LIST_ITEMS(classinfo_tv->vval.v_list, li)
|
||||
{
|
||||
if (li->li_tv.v_type != VAR_CLASS)
|
||||
if (li->li_tv.v_type != VAR_CLASS && !tv_class_alias(&li->li_tv))
|
||||
{
|
||||
emsg(_(e_class_required));
|
||||
return;
|
||||
}
|
||||
|
||||
if (class_instance_of(object_tv->vval.v_object->obj_class,
|
||||
li->li_tv.vval.v_class) == TRUE)
|
||||
if (li->li_tv.v_type == VAR_TYPEALIAS)
|
||||
c = li->li_tv.vval.v_typealias->ta_type->tt_class;
|
||||
else
|
||||
c = li->li_tv.vval.v_class;
|
||||
|
||||
if (class_instance_of(object_tv->vval.v_object->obj_class, c)
|
||||
== TRUE)
|
||||
{
|
||||
rettv->vval.v_number = VVAL_TRUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if (classinfo_tv->v_type == VAR_CLASS)
|
||||
{
|
||||
rettv->vval.v_number = class_instance_of(object_tv->vval.v_object->obj_class,
|
||||
classinfo_tv->vval.v_class);
|
||||
}
|
||||
|
||||
if (classinfo_tv->v_type == VAR_TYPEALIAS)
|
||||
c = classinfo_tv->vval.v_typealias->ta_type->tt_class;
|
||||
else
|
||||
c = classinfo_tv->vval.v_class;
|
||||
|
||||
rettv->vval.v_number =
|
||||
class_instance_of(object_tv->vval.v_object->obj_class, c);
|
||||
}
|
||||
|
||||
#endif // FEAT_EVAL
|
||||
|
@ -3809,7 +3809,7 @@ exec_instructions(ectx_T *ectx)
|
||||
tv = STACK_TV_VAR(iptr->isn_arg.number);
|
||||
if (STACK_TV_BOT(0)->v_type == VAR_TYPEALIAS)
|
||||
{
|
||||
semsg(_(e_using_typealias_as_variable),
|
||||
semsg(_(e_using_typealias_as_value),
|
||||
STACK_TV_BOT(0)->vval.v_typealias->ta_name);
|
||||
clear_tv(STACK_TV_BOT(0));
|
||||
goto on_error;
|
||||
|
@ -530,13 +530,6 @@ compile_load_scriptvar(
|
||||
{
|
||||
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + idx;
|
||||
|
||||
if (sv->sv_tv->v_type == VAR_TYPEALIAS)
|
||||
{
|
||||
semsg(_(e_using_typealias_as_variable),
|
||||
sv->sv_tv->vval.v_typealias->ta_name);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
generate_VIM9SCRIPT(cctx, ISN_LOADSCRIPT,
|
||||
current_sctx.sc_sid, idx, sv->sv_type);
|
||||
return OK;
|
||||
|
@ -1811,7 +1811,13 @@ f_typename(typval_T *argvars, typval_T *rettv)
|
||||
rettv->v_type = VAR_STRING;
|
||||
ga_init2(&type_list, sizeof(type_T *), 10);
|
||||
if (argvars[0].v_type == VAR_TYPEALIAS)
|
||||
type = argvars[0].vval.v_typealias->ta_type;
|
||||
{
|
||||
type = copy_type(argvars[0].vval.v_typealias->ta_type, &type_list);
|
||||
// A type alias for a class has the type set to VAR_OBJECT. Change it
|
||||
// to VAR_CLASS, so that the name is "typealias<class<xxx>>"
|
||||
if (type->tt_type == VAR_OBJECT)
|
||||
type->tt_type = VAR_CLASS;
|
||||
}
|
||||
else
|
||||
type = typval2type(argvars, get_copyID(), &type_list, TVTT_DO_MEMBER);
|
||||
name = type_name(type, &tofree);
|
||||
|
Loading…
x
Reference in New Issue
Block a user