forked from aniani/vim
patch 9.0.1181: class inheritance and typing insufficiently tested
Problem: Class inheritance and typing insufficiently tested. Solution: Add more tests. Implement missing behavior.
This commit is contained in:
@@ -419,6 +419,44 @@ def Test_class_object_compare()
|
||||
endfor
|
||||
enddef
|
||||
|
||||
def Test_object_type()
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
|
||||
class One
|
||||
this.one = 1
|
||||
endclass
|
||||
class Two
|
||||
this.two = 2
|
||||
endclass
|
||||
class TwoMore extends Two
|
||||
this.more = 9
|
||||
endclass
|
||||
|
||||
var o: One = One.new()
|
||||
var t: Two = Two.new()
|
||||
var m: TwoMore = TwoMore.new()
|
||||
var tm: Two = TwoMore.new()
|
||||
|
||||
t = m
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
|
||||
class One
|
||||
this.one = 1
|
||||
endclass
|
||||
class Two
|
||||
this.two = 2
|
||||
endclass
|
||||
|
||||
var o: One = Two.new()
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>')
|
||||
enddef
|
||||
|
||||
def Test_class_member()
|
||||
# check access rules
|
||||
var lines =<< trim END
|
||||
@@ -750,7 +788,7 @@ def Test_class_used_as_type()
|
||||
var p: Point
|
||||
p = 'text'
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object but got string')
|
||||
v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
|
||||
enddef
|
||||
|
||||
def Test_class_extends()
|
||||
@@ -895,6 +933,27 @@ def Test_class_extends()
|
||||
echo o.ToString()
|
||||
END
|
||||
v9.CheckScriptFailure(lines, 'E1358:')
|
||||
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
class Base
|
||||
this.name: string
|
||||
static def ToString(): string
|
||||
return 'Base class'
|
||||
enddef
|
||||
endclass
|
||||
|
||||
class Child extends Base
|
||||
this.age: number
|
||||
def ToString(): string
|
||||
return Base.ToString() .. ': ' .. this.age
|
||||
enddef
|
||||
endclass
|
||||
|
||||
var o = Child.new('John', 42)
|
||||
assert_equal('Base class: 42', o.ToString())
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
|
||||
|
@@ -695,6 +695,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1181,
|
||||
/**/
|
||||
1180,
|
||||
/**/
|
||||
|
@@ -874,6 +874,17 @@ check_type_maybe(
|
||||
// check the argument count at runtime
|
||||
ret = MAYBE;
|
||||
}
|
||||
else if (expected->tt_type == VAR_OBJECT)
|
||||
{
|
||||
class_T *cl;
|
||||
for (cl = (class_T *)actual->tt_member; cl != NULL;
|
||||
cl = cl->class_extends)
|
||||
if ((class_T *)expected->tt_member == cl)
|
||||
break;
|
||||
if (cl == NULL)
|
||||
ret = FAIL;
|
||||
}
|
||||
|
||||
if (ret == FAIL && give_msg)
|
||||
type_mismatch_where(expected, actual, where);
|
||||
}
|
||||
@@ -1601,13 +1612,12 @@ type_name(type_T *type, char **tofree)
|
||||
if (type == NULL)
|
||||
return "[unknown]";
|
||||
name = vartype_name(type->tt_type);
|
||||
|
||||
if (type->tt_type == VAR_LIST || type->tt_type == VAR_DICT)
|
||||
{
|
||||
char *member_free;
|
||||
char *member_name = type_name(type->tt_member, &member_free);
|
||||
size_t len;
|
||||
|
||||
len = STRLEN(name) + STRLEN(member_name) + 3;
|
||||
size_t len = STRLEN(name) + STRLEN(member_name) + 3;
|
||||
*tofree = alloc(len);
|
||||
if (*tofree != NULL)
|
||||
{
|
||||
@@ -1616,6 +1626,19 @@ type_name(type_T *type, char **tofree)
|
||||
return *tofree;
|
||||
}
|
||||
}
|
||||
|
||||
if (type->tt_type == VAR_OBJECT || type->tt_type == VAR_CLASS)
|
||||
{
|
||||
char_u *class_name = ((class_T *)type->tt_member)->class_name;
|
||||
size_t len = STRLEN(name) + STRLEN(class_name) + 3;
|
||||
*tofree = alloc(len);
|
||||
if (*tofree != NULL)
|
||||
{
|
||||
vim_snprintf(*tofree, len, "%s<%s>", name, class_name);
|
||||
return *tofree;
|
||||
}
|
||||
}
|
||||
|
||||
if (type->tt_type == VAR_FUNC)
|
||||
{
|
||||
garray_T ga;
|
||||
|
Reference in New Issue
Block a user