1
0
forked from aniani/vim

patch 9.1.1267: Vim9: no support for type list/dict<object<any>>

Problem:  Vim9: no support for type list/dict<object<any>>
Solution: add proper support for t_object_any
          (Yegappan Lakshmanan)

closes: #17025

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Yegappan Lakshmanan
2025-04-01 20:43:36 +02:00
committed by Christian Brabandt
parent 7b6add0b4a
commit de8f8f732a
10 changed files with 343 additions and 41 deletions

View File

@@ -564,7 +564,7 @@ def Test_using_null_class()
lines =<< trim END
vim9script
assert_equal(12, type(null_class))
assert_equal('class<Unknown>', typename(null_class))
assert_equal('class<any>', typename(null_class))
END
v9.CheckSourceSuccess(lines)
enddef
@@ -643,7 +643,6 @@ def Test_object_not_set()
END
v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
# TODO: this should not give an error but be handled at runtime
lines =<< trim END
vim9script
@@ -660,7 +659,7 @@ def Test_object_not_set()
enddef
Func()
END
v9.CheckSourceFailure(lines, 'E1363: Incomplete type', 1)
v9.CheckSourceFailure(lines, 'E1360: Using a null object', 1)
# Reference a object variable through a null class object which is stored in a
# variable of type "any".
@@ -710,7 +709,7 @@ def Test_null_object_assign_compare()
def F(): any
return nullo
enddef
assert_equal('object<Unknown>', typename(F()))
assert_equal('object<any>', typename(F()))
var o0 = F()
assert_true(o0 == null_object)
@@ -12486,37 +12485,325 @@ def Test_method_call_from_list_of_objects()
var lines =<< trim END
vim9script
class C
class A
var n: list<number> = [100, 101]
def F(): string
return 'C.F'
return 'A.F'
enddef
endclass
class D
var x: string
def new(this.x)
class B
var name: string
var n: list<number> = [200, 201]
def new(this.name)
enddef
def F(): string
return 'B.F'
enddef
endclass
var obj1 = A.new()
var obj2 = B.new('b1')
def CheckObjectList()
var objlist = [obj1, obj2]
assert_equal('list<object<any>>', typename(objlist))
# Use a member function
assert_equal('A.F', objlist[0].F())
assert_equal('B.F', objlist[1].F())
# Use a member variable on the RHS
assert_equal([100, 101], objlist[0].n)
assert_equal([200, 201], objlist[1].n)
# Use a member variable on the LHS
objlist[0].n[1] = 110
objlist[1].n[1] = 210
assert_equal([100, 110], objlist[0].n)
assert_equal([200, 210], objlist[1].n)
# Iterate using a for loop
var s1 = []
for o in objlist
add(s1, o.F())
endfor
assert_equal(['A.F', 'B.F'], s1)
# Iterate using foreach()
var s2 = []
foreach(objlist, (k, v) => add(s2, v.F()))
assert_equal(['A.F', 'B.F'], s2)
# Add a new list item
objlist->add(B.new('b2'))
assert_equal('b2', objlist[2].name)
enddef
def F(): string
return 'D.F'
CheckObjectList()
var objlist = [A.new(), B.new('b2')]
assert_equal('list<object<any>>', typename(objlist))
# Use a member function
assert_equal('A.F', objlist[0].F())
assert_equal('B.F', objlist[1].F())
# Use a member variable on the RHS
assert_equal([100, 101], objlist[0].n)
assert_equal([200, 201], objlist[1].n)
# Use a member variable on the LHS
objlist[0].n[1] = 110
objlist[1].n[1] = 210
assert_equal([100, 110], objlist[0].n)
assert_equal([200, 210], objlist[1].n)
# Iterate using a for loop
var s1 = []
for o in objlist
add(s1, o.F())
endfor
assert_equal(['A.F', 'B.F'], s1)
# Iterate using foreach()
var s2 = []
foreach(objlist, (k, v) => add(s2, v.F()))
assert_equal(['A.F', 'B.F'], s2)
# Add a new list item
objlist->add(B.new('b2'))
assert_equal('b2', objlist[2].name)
END
v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
class A
endclass
class B
endclass
var objlist = [A.new(), B.new()]
def Fn()
objlist->add(10)
enddef
endclass
var obj1 = C.new()
var obj2 = D.new('a')
try
Fn()
catch
assert_exception('Vim(eval):E1012: Type mismatch; expected object<any> but got number')
endtry
def CheckObjectList()
var items = [obj1, obj2]
assert_equal('list<any>', typename(items))
assert_equal('C.F', items[0].F())
assert_equal('D.F', items[1].F())
enddef
try
objlist->add(10)
catch
assert_exception('Vim(eval):E1012: Type mismatch; expected object<any> but got number')
endtry
END
v9.CheckSourceSuccess(lines)
CheckObjectList()
# Adding an enum to a List of objects should fail
lines =<< trim END
vim9script
class A
endclass
class B
endclass
enum C
Red,
Green,
endenum
var items = [A.new(), B.new()]
def Fn()
items->add(C.Red)
enddef
var items2 = [obj1, obj2]
assert_equal('list<any>', typename(items2))
assert_equal('C.F', items2[0].F())
assert_equal('D.F', items2[1].F())
try
Fn()
catch
assert_exception('Vim(eval):E1012: Type mismatch; expected object<any> but got enum<C>')
endtry
try
items->add(C.Green)
catch
assert_exception('Vim(eval):E1012: Type mismatch; expected object<any> but got enum<C>')
endtry
var items2 = [C.Red, C.Green]
def Fn2()
items2->add(A.new())
enddef
try
Fn2()
catch
assert_exception('Vim(eval):E1012: Type mismatch; expected enum<C> but got object<A>')
endtry
try
items2->add(B.new())
catch
assert_exception('Vim(eval):E1012: Type mismatch; expected enum<C> but got object<B>')
endtry
END
v9.CheckSourceSuccess(lines)
enddef
" Test for using a dict of objects
def Test_dict_of_objects()
var lines =<< trim END
vim9script
class A
var n: list<number> = [100, 101]
def F(): string
return 'A.F'
enddef
endclass
class B
var name: string
var n: list<number> = [200, 201]
def new(this.name)
enddef
def F(): string
return 'B.F'
enddef
endclass
var obj1 = A.new()
var obj2 = B.new('b1')
def CheckObjectDict()
var objdict = {o_a: obj1, o_b: obj2}
assert_equal('dict<object<any>>', typename(objdict))
# Use a member function
assert_equal('A.F', objdict.o_a.F())
assert_equal('B.F', objdict.o_b.F())
# Use a member variable on the RHS
assert_equal([100, 101], objdict.o_a.n)
assert_equal([200, 201], objdict.o_b.n)
# Use a member variable on the LHS
objdict.o_a.n[1] = 110
objdict.o_b.n[1] = 210
assert_equal([100, 110], objdict.o_a.n)
assert_equal([200, 210], objdict.o_b.n)
# Iterate using a for loop
var l = []
for v in values(objdict)
add(l, v.F())
endfor
assert_equal(['A.F', 'B.F'], l)
# Iterate using foreach()
l = []
foreach(objdict, (k, v) => add(l, v.F()))
assert_equal(['A.F', 'B.F'], l)
# Add a new dict item
objdict['o_b2'] = B.new('b2')
assert_equal('b2', objdict.o_b2.name)
enddef
CheckObjectDict()
var objdict = {o_a: A.new(), o_b: B.new('b2')}
assert_equal('dict<object<any>>', typename(objdict))
assert_equal('A.F', objdict.o_a.F())
assert_equal('B.F', objdict.o_b.F())
assert_equal([100, 101], objdict.o_a.n)
assert_equal([200, 201], objdict.o_b.n)
var l = []
for v in values(objdict)
add(l, v.F())
endfor
assert_equal(['A.F', 'B.F'], l)
# Add a new dict item
objdict['o_b2'] = B.new('b2')
assert_equal('b2', objdict.o_b2.name)
END
v9.CheckSourceSuccess(lines)
lines =<< trim END
vim9script
class A
endclass
class B
endclass
class C
endclass
var objdict = {a: A.new(), b: B.new()}
def Fn()
objdict['c'] = C.new()
enddef
try
Fn()
catch
assert_exception('Vim(eval):E1012: Type mismatch; expected object<any> but got number')
endtry
try
objdict['c'] = C.new()
catch
assert_exception('Vim(eval):E1012: Type mismatch; expected object<any> but got number')
endtry
END
v9.CheckSourceSuccess(lines)
# Adding an enum to a Dict of objects should fail
lines =<< trim END
vim9script
class A
endclass
class B
endclass
enum C
Red,
Green,
endenum
var items = {o_a: A.new(), o_b: B.new()}
def Fn()
items['o_c'] = C.Red
enddef
try
Fn()
catch
assert_exception('Vim(eval):E1012: Type mismatch; expected object<any> but got enum<C>')
endtry
try
items['o_c'] = C.Green
catch
assert_exception('Vim(var):E1012: Type mismatch; expected object<any> but got enum<C>')
endtry
var items2 = {red: C.Red, green: C.Green}
def Fn2()
items2['o_a'] = A.new()
enddef
try
Fn2()
catch
assert_exception('Vim(eval):E1012: Type mismatch; expected enum<C> but got object<A>')
endtry
try
items2['o_a'] = B.new()
catch
assert_exception('Vim(var):E1012: Type mismatch; expected enum<C> but got object<B>')
endtry
END
v9.CheckSourceSuccess(lines)
enddef