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
|
endfor
|
||||||
enddef
|
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()
|
def Test_class_member()
|
||||||
# check access rules
|
# check access rules
|
||||||
var lines =<< trim END
|
var lines =<< trim END
|
||||||
@@ -750,7 +788,7 @@ def Test_class_used_as_type()
|
|||||||
var p: Point
|
var p: Point
|
||||||
p = 'text'
|
p = 'text'
|
||||||
END
|
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
|
enddef
|
||||||
|
|
||||||
def Test_class_extends()
|
def Test_class_extends()
|
||||||
@@ -895,6 +933,27 @@ def Test_class_extends()
|
|||||||
echo o.ToString()
|
echo o.ToString()
|
||||||
END
|
END
|
||||||
v9.CheckScriptFailure(lines, 'E1358:')
|
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
|
enddef
|
||||||
|
|
||||||
|
|
||||||
|
@@ -695,6 +695,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1181,
|
||||||
/**/
|
/**/
|
||||||
1180,
|
1180,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -874,6 +874,17 @@ check_type_maybe(
|
|||||||
// check the argument count at runtime
|
// check the argument count at runtime
|
||||||
ret = MAYBE;
|
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)
|
if (ret == FAIL && give_msg)
|
||||||
type_mismatch_where(expected, actual, where);
|
type_mismatch_where(expected, actual, where);
|
||||||
}
|
}
|
||||||
@@ -1601,13 +1612,12 @@ type_name(type_T *type, char **tofree)
|
|||||||
if (type == NULL)
|
if (type == NULL)
|
||||||
return "[unknown]";
|
return "[unknown]";
|
||||||
name = vartype_name(type->tt_type);
|
name = vartype_name(type->tt_type);
|
||||||
|
|
||||||
if (type->tt_type == VAR_LIST || type->tt_type == VAR_DICT)
|
if (type->tt_type == VAR_LIST || type->tt_type == VAR_DICT)
|
||||||
{
|
{
|
||||||
char *member_free;
|
char *member_free;
|
||||||
char *member_name = type_name(type->tt_member, &member_free);
|
char *member_name = type_name(type->tt_member, &member_free);
|
||||||
size_t len;
|
size_t len = STRLEN(name) + STRLEN(member_name) + 3;
|
||||||
|
|
||||||
len = STRLEN(name) + STRLEN(member_name) + 3;
|
|
||||||
*tofree = alloc(len);
|
*tofree = alloc(len);
|
||||||
if (*tofree != NULL)
|
if (*tofree != NULL)
|
||||||
{
|
{
|
||||||
@@ -1616,6 +1626,19 @@ type_name(type_T *type, char **tofree)
|
|||||||
return *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)
|
if (type->tt_type == VAR_FUNC)
|
||||||
{
|
{
|
||||||
garray_T ga;
|
garray_T ga;
|
||||||
|
Reference in New Issue
Block a user