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>
diff --git a/src/vim9class.c b/src/vim9class.c
index 0e8dc2d..436b2a8 100644
--- a/src/vim9class.c
+++ b/src/vim9class.c
@@ -2196,13 +2196,26 @@
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 @@
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 @@
{
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