Skip to content

Commit

Permalink
patch 9.0.1181: class inheritance and typing insufficiently tested
Browse files Browse the repository at this point in the history
Problem:    Class inheritance and typing insufficiently tested.
Solution:   Add more tests.  Implement missing behavior.
  • Loading branch information
brammool committed Jan 11, 2023
1 parent bcbfaf3 commit 6481acc
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 4 deletions.
61 changes: 60 additions & 1 deletion src/testdir/test_vim9_class.vim
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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


Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -695,6 +695,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1181,
/**/
1180,
/**/
Expand Down
29 changes: 26 additions & 3 deletions src/vim9type.c
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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)
{
Expand All @@ -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;
Expand Down

0 comments on commit 6481acc

Please sign in to comment.