comparison src/testdir/test_vim9_class.vim @ 32854:5fd9fe58c791 v9.0.1737

patch 9.0.1737: Calling a base class method through an extended class fails Commit: https://github.com/vim/vim/commit/b102728c204430b16a5d9e6720c882e12a687570 Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Sat Aug 19 11:26:42 2023 +0200 patch 9.0.1737: Calling a base class method through an extended class fails Problem: Calling a base class method through an extended class fails Solution: Create lookup table for member index in the interface to to the member class implementing the interface Create additional tests for Vim9 classes. Fix unconvered memory leaks and crashes found by the new tests. closes: #12848 closes: #12089 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>author
author Christian Brabandt <cb@256bit.org>
date Sat, 19 Aug 2023 11:45:03 +0200
parents b3a42579bb3f
children a39314fa9495
comparison
equal deleted inserted replaced
32853:1061521240a3 32854:5fd9fe58c791
132 class Something 132 class Something
133 this.count:number 133 this.count:number
134 endclass 134 endclass
135 END 135 END
136 v9.CheckScriptFailure(lines, 'E1069:') 136 v9.CheckScriptFailure(lines, 'E1069:')
137
138 # Test for unsupported comment specifier
139 lines =<< trim END
140 vim9script
141 class Something
142 # comment
143 #{
144 endclass
145 END
146 v9.CheckScriptFailure(lines, 'E1170:')
137 147
138 lines =<< trim END 148 lines =<< trim END
139 vim9script 149 vim9script
140 150
141 class TextPosition 151 class TextPosition
160 assert_equal(v:t_object, type(pos)) 170 assert_equal(v:t_object, type(pos))
161 assert_equal('class<TextPosition>', typename(TextPosition)) 171 assert_equal('class<TextPosition>', typename(TextPosition))
162 assert_equal('object<TextPosition>', typename(pos)) 172 assert_equal('object<TextPosition>', typename(pos))
163 END 173 END
164 v9.CheckScriptSuccess(lines) 174 v9.CheckScriptSuccess(lines)
175
176 # When referencing object methods, space cannot be used after a "."
177 lines =<< trim END
178 vim9script
179 class A
180 def Foo(): number
181 return 10
182 enddef
183 endclass
184 var a = A.new()
185 var v = a. Foo()
186 END
187 v9.CheckScriptFailure(lines, 'E1202:')
188
189 # Using an object without specifying a method or a member variable
190 lines =<< trim END
191 vim9script
192 class A
193 def Foo(): number
194 return 10
195 enddef
196 endclass
197 var a = A.new()
198 var v = a.
199 END
200 v9.CheckScriptFailure(lines, 'E15:')
201
202 # Error when parsing the arguments of an object method.
203 lines =<< trim END
204 vim9script
205 class A
206 def Foo()
207 enddef
208 endclass
209 var a = A.new()
210 var v = a.Foo(,)
211 END
212 v9.CheckScriptFailure(lines, 'E15:')
165 enddef 213 enddef
166 214
167 def Test_class_defined_twice() 215 def Test_class_defined_twice()
168 # class defined twice should fail 216 # class defined twice should fail
169 var lines =<< trim END 217 var lines =<< trim END
626 this.lnum = v:none 674 this.lnum = v:none
627 this.col = 1 675 this.col = 1
628 endclass 676 endclass
629 END 677 END
630 v9.CheckScriptFailure(lines, 'E1330:') 678 v9.CheckScriptFailure(lines, 'E1330:')
679
680 # Test for initializing an object member with an unknown variable/type
681 lines =<< trim END
682 vim9script
683 class A
684 this.value = init_val
685 endclass
686 END
687 v9.CheckScriptFailureList(lines, ['E121:', 'E1329:'])
631 enddef 688 enddef
632 689
633 def Test_class_object_member_access() 690 def Test_class_object_member_access()
634 var lines =<< trim END 691 var lines =<< trim END
635 vim9script 692 vim9script
655 assert_equal(33, trip.three) 712 assert_equal(33, trip.three)
656 713
657 assert_fails('trip.four = 4', 'E1334') 714 assert_fails('trip.four = 4', 'E1334')
658 END 715 END
659 v9.CheckScriptSuccess(lines) 716 v9.CheckScriptSuccess(lines)
717
718 # Test for a public member variable name beginning with an underscore
719 lines =<< trim END
720 vim9script
721 class A
722 public this._val = 10
723 endclass
724 END
725 v9.CheckScriptFailure(lines, 'E1332:')
660 726
661 lines =<< trim END 727 lines =<< trim END
662 vim9script 728 vim9script
663 729
664 class MyCar 730 class MyCar
733 .Add(1) 799 .Add(1)
734 .Add(2) 800 .Add(2)
735 .x 801 .x
736 END 802 END
737 v9.CheckScriptSuccess(lines) 803 v9.CheckScriptSuccess(lines)
804
805 # Test for "public" cannot be abbreviated
806 lines =<< trim END
807 vim9script
808 class Something
809 pub this.val = 1
810 endclass
811 END
812 v9.CheckScriptFailure(lines, 'E1065:')
813
814 # Test for "public" keyword must be followed by "this" or "static".
815 lines =<< trim END
816 vim9script
817 class Something
818 public val = 1
819 endclass
820 END
821 v9.CheckScriptFailure(lines, 'E1331:')
822
823 # Test for "static" cannot be abbreviated
824 lines =<< trim END
825 vim9script
826 class Something
827 stat this.val = 1
828 endclass
829 END
830 v9.CheckScriptFailure(lines, 'E1065:')
738 enddef 831 enddef
739 832
740 def Test_class_object_compare() 833 def Test_class_object_compare()
741 var class_lines =<< trim END 834 var class_lines =<< trim END
742 vim9script 835 vim9script
1000 1093
1001 var s = Some.new() 1094 var s = Some.new()
1002 s.Method(7) 1095 s.Method(7)
1003 END 1096 END
1004 v9.CheckScriptFailure(lines, 'E1341: Variable already declared in the class: count') 1097 v9.CheckScriptFailure(lines, 'E1341: Variable already declared in the class: count')
1098
1099 # Test for using an invalid type for a member variable
1100 lines =<< trim END
1101 vim9script
1102 class A
1103 this.val: xxx
1104 endclass
1105 END
1106 v9.CheckScriptFailure(lines, 'E1010:')
1107
1108 # Test for no space before or after the '=' when initializing a member
1109 # variable
1110 lines =<< trim END
1111 vim9script
1112 class A
1113 this.val: number= 10
1114 endclass
1115 END
1116 v9.CheckScriptFailure(lines, 'E1004:')
1117 lines =<< trim END
1118 vim9script
1119 class A
1120 this.val: number =10
1121 endclass
1122 END
1123 v9.CheckScriptFailure(lines, 'E1004:')
1124
1125 # Access a non-existing member
1126 lines =<< trim END
1127 vim9script
1128 class A
1129 endclass
1130 var a = A.new()
1131 var v = a.bar
1132 END
1133 v9.CheckScriptFailure(lines, 'E1326:')
1005 enddef 1134 enddef
1006 1135
1007 func Test_class_garbagecollect() 1136 func Test_class_garbagecollect()
1008 let lines =<< trim END 1137 let lines =<< trim END
1009 vim9script 1138 vim9script
1070 assert_equal(1, Value.GetCount()) 1199 assert_equal(1, Value.GetCount())
1071 var v2 = Value.new(7) 1200 var v2 = Value.new(7)
1072 assert_equal(2, Value.GetCount()) 1201 assert_equal(2, Value.GetCount())
1073 END 1202 END
1074 v9.CheckScriptSuccess(lines) 1203 v9.CheckScriptSuccess(lines)
1204
1205 # Test for cleaning up after a class definition failure when using class
1206 # functions.
1207 lines =<< trim END
1208 vim9script
1209 class A
1210 static def Foo()
1211 enddef
1212 aaa
1213 endclass
1214 END
1215 v9.CheckScriptFailure(lines, 'E1318:')
1075 enddef 1216 enddef
1076 1217
1077 def Test_class_defcompile() 1218 def Test_class_defcompile()
1078 var lines =<< trim END 1219 var lines =<< trim END
1079 vim9script 1220 vim9script
1098 endclass 1239 endclass
1099 1240
1100 defcompile C.Fc 1241 defcompile C.Fc
1101 END 1242 END
1102 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected number but got string') 1243 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected number but got string')
1244
1245 # Trying to compile a function using a non-existing class variable
1246 lines =<< trim END
1247 vim9script
1248 defcompile x.Foo()
1249 END
1250 v9.CheckScriptFailure(lines, 'E475:')
1251
1252 # Trying to compile a function using a variable which is not a class
1253 lines =<< trim END
1254 vim9script
1255 var x: number
1256 defcompile x.Foo()
1257 END
1258 v9.CheckScriptFailure(lines, 'E475:')
1259
1260 # Trying to compile a function without specifying the name
1261 lines =<< trim END
1262 vim9script
1263 class A
1264 endclass
1265 defcompile A.
1266 END
1267 v9.CheckScriptFailure(lines, 'E475:')
1268
1269 # Trying to compile a non-existing class object member function
1270 lines =<< trim END
1271 vim9script
1272 class A
1273 endclass
1274 var a = A.new()
1275 defcompile a.Foo()
1276 END
1277 v9.CheckScriptFailureList(lines, ['E1334:', 'E475:'])
1103 enddef 1278 enddef
1104 1279
1105 def Test_class_object_to_string() 1280 def Test_class_object_to_string()
1106 var lines =<< trim END 1281 var lines =<< trim END
1107 vim9script 1282 vim9script
1343 enddef 1518 enddef
1344 1519
1345 Test() 1520 Test()
1346 END 1521 END
1347 v9.CheckScriptSuccess(lines) 1522 v9.CheckScriptSuccess(lines)
1523
1524 # Interface name after "extends" doesn't end in a space or NUL character
1525 lines =<< trim END
1526 vim9script
1527 interface A
1528 endinterface
1529 class B extends A"
1530 endclass
1531 END
1532 v9.CheckScriptFailure(lines, 'E1315:')
1533
1534 # Trailing characters after a class name
1535 lines =<< trim END
1536 vim9script
1537 class A bbb
1538 endclass
1539 END
1540 v9.CheckScriptFailure(lines, 'E488:')
1541
1542 # using "implements" with a non-existing class
1543 lines =<< trim END
1544 vim9script
1545 class A implements B
1546 endclass
1547 END
1548 v9.CheckScriptFailure(lines, 'E1346:')
1549
1550 # using "implements" with a regular class
1551 lines =<< trim END
1552 vim9script
1553 class A
1554 endclass
1555 class B implements A
1556 endclass
1557 END
1558 v9.CheckScriptFailure(lines, 'E1347:')
1559
1560 # using "implements" with a variable
1561 lines =<< trim END
1562 vim9script
1563 var T: number = 10
1564 class A implements T
1565 endclass
1566 END
1567 v9.CheckScriptFailure(lines, 'E1347:')
1568
1569 # all the class methods in an "interface" should be implemented
1570 lines =<< trim END
1571 vim9script
1572 interface A
1573 static def Foo()
1574 endinterface
1575 class B implements A
1576 endclass
1577 END
1578 v9.CheckScriptFailure(lines, 'E1349:')
1348 enddef 1579 enddef
1349 1580
1350 def Test_call_interface_method() 1581 def Test_call_interface_method()
1351 var lines =<< trim END 1582 var lines =<< trim END
1352 vim9script 1583 vim9script
1715 1946
1716 var v = Success.new('asdf') 1947 var v = Success.new('asdf')
1717 assert_equal("object of Success {success: true, value: 'asdf'}", string(v)) 1948 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
1718 END 1949 END
1719 v9.CheckScriptSuccess(lines) 1950 v9.CheckScriptSuccess(lines)
1951
1952 # class name after "extends" doesn't end in a space or NUL character
1953 lines =<< trim END
1954 vim9script
1955 class A
1956 endclass
1957 class B extends A"
1958 endclass
1959 END
1960 v9.CheckScriptFailure(lines, 'E1315:')
1720 enddef 1961 enddef
1721 1962
1722 def Test_using_base_class() 1963 def Test_using_base_class()
1723 var lines =<< trim END 1964 var lines =<< trim END
1724 vim9script 1965 vim9script
1839 abstract class Base 2080 abstract class Base
1840 this.name: string 2081 this.name: string
1841 endclass 2082 endclass
1842 END 2083 END
1843 v9.CheckScriptFailure(lines, 'E1316:') 2084 v9.CheckScriptFailure(lines, 'E1316:')
2085
2086 # Abstract class cannot have a "new" function
2087 lines =<< trim END
2088 vim9script
2089 abstract class Base
2090 def new()
2091 enddef
2092 endclass
2093 END
2094 v9.CheckScriptFailure(lines, 'E1359:')
1844 enddef 2095 enddef
1845 2096
1846 def Test_closure_in_class() 2097 def Test_closure_in_class()
1847 var lines =<< trim END 2098 var lines =<< trim END
1848 vim9script 2099 vim9script
2061 var l = Stack(foo1, foo2) 2312 var l = Stack(foo1, foo2)
2062 END 2313 END
2063 v9.CheckScriptSuccess(lines) 2314 v9.CheckScriptSuccess(lines)
2064 enddef 2315 enddef
2065 2316
2317 " Test for calling methods from three levels of classes
2318 def Test_multi_level_method_call()
2319 var lines =<< trim END
2320 vim9script
2321
2322 var A_func1: number = 0
2323 var A_func2: number = 0
2324 var A_func3: number = 0
2325 var B_func2: number = 0
2326 var B_func3: number = 0
2327 var C_func3: number = 0
2328
2329 class A
2330 def Func1()
2331 A_func1 += 1
2332 enddef
2333
2334 def Func2()
2335 A_func2 += 1
2336 enddef
2337
2338 def Func3()
2339 A_func3 += 1
2340 enddef
2341 endclass
2342
2343 class B extends A
2344 def Func2()
2345 B_func2 += 1
2346 enddef
2347
2348 def Func3()
2349 B_func3 += 1
2350 enddef
2351 endclass
2352
2353 class C extends B
2354 def Func3()
2355 C_func3 += 1
2356 enddef
2357 endclass
2358
2359 def A_CallFuncs(a: A)
2360 a.Func1()
2361 a.Func2()
2362 a.Func3()
2363 enddef
2364
2365 def B_CallFuncs(b: B)
2366 b.Func1()
2367 b.Func2()
2368 b.Func3()
2369 enddef
2370
2371 def C_CallFuncs(c: C)
2372 c.Func1()
2373 c.Func2()
2374 c.Func3()
2375 enddef
2376
2377 var cobj = C.new()
2378 A_CallFuncs(cobj)
2379 B_CallFuncs(cobj)
2380 C_CallFuncs(cobj)
2381 assert_equal(3, A_func1)
2382 assert_equal(0, A_func2)
2383 assert_equal(0, A_func3)
2384 assert_equal(3, B_func2)
2385 assert_equal(0, B_func3)
2386 assert_equal(3, C_func3)
2387 END
2388 v9.CheckScriptSuccess(lines)
2389 enddef
2390
2391 " Test for using members from three levels of classes
2392 def Test_multi_level_member_access()
2393 var lines =<< trim END
2394 vim9script
2395
2396 class A
2397 this.val1: number = 0
2398 this.val2: number = 0
2399 this.val3: number = 0
2400 endclass
2401
2402 class B extends A
2403 this.val2: number = 0
2404 this.val3: number = 0
2405 endclass
2406
2407 class C extends B
2408 this.val3: number = 0
2409 endclass
2410
2411 def A_members(a: A)
2412 a.val1 += 1
2413 a.val2 += 1
2414 a.val3 += 1
2415 enddef
2416
2417 def B_members(b: B)
2418 b.val1 += 1
2419 b.val2 += 1
2420 b.val3 += 1
2421 enddef
2422
2423 def C_members(c: C)
2424 c.val1 += 1
2425 c.val2 += 1
2426 c.val3 += 1
2427 enddef
2428
2429 var cobj = C.new()
2430 A_members(cobj)
2431 B_members(cobj)
2432 C_members(cobj)
2433 assert_equal(3, cobj.val1)
2434 assert_equal(3, cobj.val2)
2435 assert_equal(3, cobj.val3)
2436 END
2437 v9.CheckScriptSuccess(lines)
2438 enddef
2439
2066 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker 2440 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker