blob: fa621b25acf345e0c5d08d1d185746531bbe39ee [file] [log] [blame]
Bram Moolenaar00b28d62022-12-08 15:32:33 +00001" Test Vim9 classes
2
3source check.vim
4import './vim9.vim' as v9
5
6def Test_class_basic()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02007 # Class supported only in "vim9script"
Bram Moolenaar00b28d62022-12-08 15:32:33 +00008 var lines =<< trim END
9 class NotWorking
10 endclass
11 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +020012 v9.CheckSourceFailure(lines, 'E1316:')
Bram Moolenaar00b28d62022-12-08 15:32:33 +000013
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020014 # First character in a class name should be capitalized.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000015 lines =<< trim END
16 vim9script
17 class notWorking
18 endclass
19 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +020020 v9.CheckSourceFailure(lines, 'E1314:')
Bram Moolenaar00b28d62022-12-08 15:32:33 +000021
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020022 # Only alphanumeric characters are supported in a class name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000023 lines =<< trim END
24 vim9script
25 class Not@working
26 endclass
27 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +020028 v9.CheckSourceFailure(lines, 'E1315:')
Bram Moolenaar00b28d62022-12-08 15:32:33 +000029
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020030 # Unsupported keyword (instead of class)
Bram Moolenaar00b28d62022-12-08 15:32:33 +000031 lines =<< trim END
32 vim9script
33 abstract noclass Something
34 endclass
35 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +020036 v9.CheckSourceFailure(lines, 'E475:')
Bram Moolenaar00b28d62022-12-08 15:32:33 +000037
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020038 # Only the completed word "class" should be recognized
Bram Moolenaar00b28d62022-12-08 15:32:33 +000039 lines =<< trim END
40 vim9script
41 abstract classy Something
42 endclass
43 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +020044 v9.CheckSourceFailure(lines, 'E475:')
Bram Moolenaar00b28d62022-12-08 15:32:33 +000045
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020046 # The complete "endclass" should be specified.
Bram Moolenaar00b28d62022-12-08 15:32:33 +000047 lines =<< trim END
48 vim9script
49 class Something
50 endcl
51 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +020052 v9.CheckSourceFailure(lines, 'E1065:')
Bram Moolenaar00b28d62022-12-08 15:32:33 +000053
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020054 # Additional words after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000055 lines =<< trim END
56 vim9script
57 class Something
Bram Moolenaar94722c52023-01-28 19:19:03 +000058 endclass school's out
Bram Moolenaar00b28d62022-12-08 15:32:33 +000059 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +020060 v9.CheckSourceFailure(lines, 'E488:')
Bram Moolenaar00b28d62022-12-08 15:32:33 +000061
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020062 # Additional commands after "endclass"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000063 lines =<< trim END
64 vim9script
65 class Something
66 endclass | echo 'done'
67 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +020068 v9.CheckSourceFailure(lines, 'E488:')
Bram Moolenaar00b28d62022-12-08 15:32:33 +000069
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020070 # Use "this" without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000071 lines =<< trim END
72 vim9script
73 class Something
74 this
75 endclass
76 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +020077 v9.CheckSourceFailure(lines, 'E1317:')
Bram Moolenaar00b28d62022-12-08 15:32:33 +000078
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020079 # Use "this." without any member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000080 lines =<< trim END
81 vim9script
82 class Something
83 this.
84 endclass
85 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +020086 v9.CheckSourceFailure(lines, 'E1317:')
Bram Moolenaar00b28d62022-12-08 15:32:33 +000087
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020088 # Space between "this" and ".<variable>"
Bram Moolenaar00b28d62022-12-08 15:32:33 +000089 lines =<< trim END
90 vim9script
91 class Something
92 this .count
93 endclass
94 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +020095 v9.CheckSourceFailure(lines, 'E1317:')
Bram Moolenaar00b28d62022-12-08 15:32:33 +000096
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +020097 # Space between "this." and the member variable name
Bram Moolenaar00b28d62022-12-08 15:32:33 +000098 lines =<< trim END
99 vim9script
100 class Something
101 this. count
102 endclass
103 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200104 v9.CheckSourceFailure(lines, 'E1317:')
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000105
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200106 # Use "that" instead of "this"
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000107 lines =<< trim END
108 vim9script
109 class Something
110 this.count: number
111 that.count
112 endclass
113 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200114 v9.CheckSourceFailure(lines, 'E1318: Not a valid command in a class: that.count')
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000115
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200116 # Member variable without a type or initialization
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000117 lines =<< trim END
118 vim9script
119 class Something
120 this.count
121 endclass
122 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200123 v9.CheckSourceFailure(lines, 'E1022:')
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000124
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200125 # Use a non-existing member variable in new()
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000126 lines =<< trim END
127 vim9script
128 class Something
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000129 def new()
130 this.state = 0
131 enddef
132 endclass
133 var obj = Something.new()
134 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200135 v9.CheckSourceFailure(lines, 'E1326: Member not found on object "Something": state')
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000136
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200137 # Space before ":" in a member variable declaration
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000138 lines =<< trim END
139 vim9script
140 class Something
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000141 this.count : number
142 endclass
143 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200144 v9.CheckSourceFailure(lines, 'E1059:')
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000145
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200146 # No space after ":" in a member variable declaration
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000147 lines =<< trim END
148 vim9script
149 class Something
150 this.count:number
151 endclass
152 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200153 v9.CheckSourceFailure(lines, 'E1069:')
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000154
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200155 # Test for unsupported comment specifier
156 lines =<< trim END
157 vim9script
158 class Something
159 # comment
160 #{
161 endclass
162 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200163 v9.CheckSourceFailure(lines, 'E1170:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200164
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200165 # Test for using class as a bool
166 lines =<< trim END
167 vim9script
168 class A
169 endclass
170 if A
171 endif
172 END
173 v9.CheckSourceFailure(lines, 'E1319: Using a class as a Number')
174
175 # Test for using object as a bool
176 lines =<< trim END
177 vim9script
178 class A
179 endclass
180 var a = A.new()
181 if a
182 endif
183 END
184 v9.CheckSourceFailure(lines, 'E1320: Using an object as a Number')
185
186 # Test for using class as a float
187 lines =<< trim END
188 vim9script
189 class A
190 endclass
191 sort([1.1, A], 'f')
192 END
193 v9.CheckSourceFailure(lines, 'E1321: Using a class as a Float')
194
195 # Test for using object as a float
196 lines =<< trim END
197 vim9script
198 class A
199 endclass
200 var a = A.new()
201 sort([1.1, a], 'f')
202 END
203 v9.CheckSourceFailure(lines, 'E1322: Using an object as a Float')
204
205 # Test for using class as a string
206 lines =<< trim END
207 vim9script
208 class A
209 endclass
210 :exe 'call ' .. A
211 END
212 v9.CheckSourceFailure(lines, 'E1323: Using a class as a String')
213
214 # Test for using object as a string
215 lines =<< trim END
216 vim9script
217 class A
218 endclass
219 var a = A.new()
220 :exe 'call ' .. a
221 END
222 v9.CheckSourceFailure(lines, 'E1324: Using an object as a String')
223
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200224 # Test creating a class with member variables and methods, calling a object
225 # method. Check for using type() and typename() with a class and an object.
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000226 lines =<< trim END
227 vim9script
228
229 class TextPosition
230 this.lnum: number
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000231 this.col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000232
Bram Moolenaar418b5472022-12-20 13:38:22 +0000233 # make a nicely formatted string
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000234 def ToString(): string
235 return $'({this.lnum}, {this.col})'
236 enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000237 endclass
238
Bram Moolenaard28d7b92022-12-08 20:42:00 +0000239 # use the automatically generated new() method
240 var pos = TextPosition.new(2, 12)
241 assert_equal(2, pos.lnum)
242 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000243
244 # call an object method
245 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000246
247 assert_equal(v:t_class, type(TextPosition))
248 assert_equal(v:t_object, type(pos))
249 assert_equal('class<TextPosition>', typename(TextPosition))
250 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000251 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200252 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200253
254 # When referencing object methods, space cannot be used after a "."
255 lines =<< trim END
256 vim9script
257 class A
258 def Foo(): number
259 return 10
260 enddef
261 endclass
262 var a = A.new()
263 var v = a. Foo()
264 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200265 v9.CheckSourceFailure(lines, 'E1202:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200266
267 # Using an object without specifying a method or a member variable
268 lines =<< trim END
269 vim9script
270 class A
271 def Foo(): number
272 return 10
273 enddef
274 endclass
275 var a = A.new()
276 var v = a.
277 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200278 v9.CheckSourceFailure(lines, 'E15:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200279
280 # Error when parsing the arguments of an object method.
281 lines =<< trim END
282 vim9script
283 class A
284 def Foo()
285 enddef
286 endclass
287 var a = A.new()
288 var v = a.Foo(,)
289 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200290 v9.CheckSourceFailure(lines, 'E15:')
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200291
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200292 # Use a multi-line initialization for a member variable
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200293 lines =<< trim END
294 vim9script
295 class A
296 this.y = {
297 X: 1
298 }
299 endclass
300 var a = A.new()
301 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200302 v9.CheckSourceSuccess(lines)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000303enddef
304
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000305def Test_class_defined_twice()
306 # class defined twice should fail
307 var lines =<< trim END
308 vim9script
309 class There
310 endclass
311 class There
312 endclass
313 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200314 v9.CheckSourceFailure(lines, 'E1041: Redefining script item: "There"')
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000315
316 # one class, reload same script twice is OK
317 lines =<< trim END
318 vim9script
319 class There
320 endclass
321 END
322 writefile(lines, 'XclassTwice.vim', 'D')
323 source XclassTwice.vim
324 source XclassTwice.vim
325enddef
326
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000327def Test_returning_null_object()
328 # this was causing an internal error
329 var lines =<< trim END
330 vim9script
331
332 class BufferList
333 def Current(): any
334 return null_object
335 enddef
336 endclass
337
338 var buffers = BufferList.new()
339 echo buffers.Current()
340 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200341 v9.CheckSourceSuccess(lines)
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000342enddef
343
Bram Moolenaard13dd302023-03-11 20:56:35 +0000344def Test_using_null_class()
345 var lines =<< trim END
346 @_ = null_class.member
347 END
348 v9.CheckDefExecAndScriptFailure(lines, ['E715:', 'E1363:'])
349enddef
350
Bram Moolenaar657aea72023-01-27 13:16:19 +0000351def Test_class_interface_wrong_end()
352 var lines =<< trim END
353 vim9script
354 abstract class SomeName
355 this.member = 'text'
356 endinterface
357 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200358 v9.CheckSourceFailure(lines, 'E476: Invalid command: endinterface, expected endclass')
Bram Moolenaar657aea72023-01-27 13:16:19 +0000359
360 lines =<< trim END
361 vim9script
362 export interface AnotherName
363 this.member: string
364 endclass
365 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200366 v9.CheckSourceFailure(lines, 'E476: Invalid command: endclass, expected endinterface')
Bram Moolenaar657aea72023-01-27 13:16:19 +0000367enddef
368
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000369def Test_object_not_set()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200370 # Use an uninitialized object in script context
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000371 var lines =<< trim END
372 vim9script
373
374 class State
375 this.value = 'xyz'
376 endclass
377
Bram Moolenaarf2017f22023-02-17 21:29:57 +0000378 var state: State
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000379 var db = {'xyz': 789}
380 echo db[state.value]
381 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200382 v9.CheckSourceFailure(lines, 'E1360:')
Bram Moolenaar0917e862023-02-18 14:42:44 +0000383
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200384 # Use an uninitialized object from a def function
Bram Moolenaar0917e862023-02-18 14:42:44 +0000385 lines =<< trim END
386 vim9script
387
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000388 class Class
389 this.id: string
390 def Method1()
391 echo 'Method1' .. this.id
392 enddef
393 endclass
394
395 var obj: Class
396 def Func()
397 obj.Method1()
398 enddef
399 Func()
400 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200401 v9.CheckSourceFailure(lines, 'E1360:')
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000402
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200403 # Pass an uninitialized object variable to a "new" function and try to call an
404 # object method.
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000405 lines =<< trim END
406 vim9script
407
Bram Moolenaar0917e862023-02-18 14:42:44 +0000408 class Background
409 this.background = 'dark'
410 endclass
411
412 class Colorscheme
413 this._bg: Background
414
415 def GetBackground(): string
416 return this._bg.background
417 enddef
418 endclass
419
420 var bg: Background # UNINITIALIZED
421 echo Colorscheme.new(bg).GetBackground()
422 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200423 v9.CheckSourceFailure(lines, 'E1360:')
Ernie Raelf77a7f72023-03-03 15:05:30 +0000424
425 # TODO: this should not give an error but be handled at runtime
426 lines =<< trim END
427 vim9script
428
429 class Class
430 this.id: string
431 def Method1()
432 echo 'Method1' .. this.id
433 enddef
434 endclass
435
436 var obj = null_object
437 def Func()
438 obj.Method1()
439 enddef
440 Func()
441 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200442 v9.CheckSourceFailure(lines, 'E1363:')
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000443enddef
444
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200445" Null object assignment and comparison
Ernie Rael5c018be2023-08-27 18:40:26 +0200446def Test_null_object_assign_compare()
447 var lines =<< trim END
448 vim9script
449
450 var nullo = null_object
451 def F(): any
452 return nullo
453 enddef
454 assert_equal('object<Unknown>', typename(F()))
455
456 var o0 = F()
457 assert_true(o0 == null_object)
458 assert_true(o0 == null)
459
460 var o1: any = nullo
461 assert_true(o1 == null_object)
462 assert_true(o1 == null)
463
464 def G()
465 var x = null_object
466 enddef
467
468 class C
469 endclass
470 var o2: C
471 assert_true(o2 == null_object)
472 assert_true(o2 == null)
473
474 o2 = null_object
475 assert_true(o2 == null)
476
477 o2 = C.new()
478 assert_true(o2 != null)
479
480 o2 = null_object
481 assert_true(o2 == null)
482 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200483 v9.CheckSourceSuccess(lines)
Ernie Rael5c018be2023-08-27 18:40:26 +0200484enddef
485
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200486" Test for object member initialization and disassembly
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000487def Test_class_member_initializer()
488 var lines =<< trim END
489 vim9script
490
491 class TextPosition
492 this.lnum: number = 1
493 this.col: number = 1
494
Bram Moolenaar418b5472022-12-20 13:38:22 +0000495 # constructor with only the line number
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000496 def new(lnum: number)
497 this.lnum = lnum
498 enddef
499 endclass
500
501 var pos = TextPosition.new(3)
502 assert_equal(3, pos.lnum)
503 assert_equal(1, pos.col)
504
505 var instr = execute('disassemble TextPosition.new')
506 assert_match('new\_s*' ..
Bram Moolenaar3ea8a1b2022-12-10 19:03:51 +0000507 '0 NEW TextPosition size \d\+\_s*' ..
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000508 '\d PUSHNR 1\_s*' ..
509 '\d STORE_THIS 0\_s*' ..
510 '\d PUSHNR 1\_s*' ..
511 '\d STORE_THIS 1\_s*' ..
512 'this.lnum = lnum\_s*' ..
513 '\d LOAD arg\[-1]\_s*' ..
514 '\d PUSHNR 0\_s*' ..
515 '\d LOAD $0\_s*' ..
516 '\d\+ STOREINDEX object\_s*' ..
517 '\d\+ RETURN object.*',
518 instr)
519 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200520 v9.CheckSourceSuccess(lines)
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000521enddef
522
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000523def Test_member_any_used_as_object()
524 var lines =<< trim END
525 vim9script
526
527 class Inner
528 this.value: number = 0
529 endclass
530
531 class Outer
532 this.inner: any
533 endclass
534
535 def F(outer: Outer)
536 outer.inner.value = 1
537 enddef
538
539 var inner_obj = Inner.new(0)
540 var outer_obj = Outer.new(inner_obj)
541 F(outer_obj)
542 assert_equal(1, inner_obj.value)
543 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200544 v9.CheckSourceSuccess(lines)
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000545
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200546 # Try modifying a private variable using an "any" object
547 lines =<< trim END
548 vim9script
549
550 class Inner
551 this._value: string = ''
552 endclass
553
554 class Outer
555 this.inner: any
556 endclass
557
558 def F(outer: Outer)
559 outer.inner._value = 'b'
560 enddef
561
562 var inner_obj = Inner.new('a')
563 var outer_obj = Outer.new(inner_obj)
564 F(outer_obj)
565 END
566 v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _value')
567
568 # Try modifying a non-existing variable using an "any" object
569 lines =<< trim END
570 vim9script
571
572 class Inner
573 this.value: string = ''
574 endclass
575
576 class Outer
577 this.inner: any
578 endclass
579
580 def F(outer: Outer)
581 outer.inner.someval = 'b'
582 enddef
583
584 var inner_obj = Inner.new('a')
585 var outer_obj = Outer.new(inner_obj)
586 F(outer_obj)
587 END
588 v9.CheckSourceFailure(lines, 'E1326: Member not found on object "Inner": someval')
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000589enddef
590
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200591" Nested assignment to a object variable which is of another class type
592def Test_assignment_nested_type()
593 var lines =<< trim END
594 vim9script
595
596 class Inner
597 public this.value: number = 0
598 endclass
599
600 class Outer
601 this.inner: Inner
602 endclass
603
604 def F(outer: Outer)
605 outer.inner.value = 1
606 enddef
607
608 def Test_assign_to_nested_typed_member()
609 var inner = Inner.new(0)
610 var outer = Outer.new(inner)
611 F(outer)
612 assert_equal(1, inner.value)
613 enddef
614
615 Test_assign_to_nested_typed_member()
616 END
617 v9.CheckSourceSuccess(lines)
618enddef
619
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000620def Test_assignment_with_operator()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +0200621 # Use "+=" to assign to a object variable
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000622 var lines =<< trim END
623 vim9script
624
625 class Foo
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +0200626 public this.x: number
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000627
628 def Add(n: number)
629 this.x += n
630 enddef
631 endclass
632
633 var f = Foo.new(3)
634 f.Add(17)
635 assert_equal(20, f.x)
Bram Moolenaar22363c62023-04-24 17:15:25 +0100636
637 def AddToFoo(obj: Foo)
638 obj.x += 3
639 enddef
640
641 AddToFoo(f)
642 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000643 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200644 v9.CheckSourceSuccess(lines)
Ernie Rael18143d32023-09-04 22:30:41 +0200645
646 # do the same thing, but through an interface
647 lines =<< trim END
648 vim9script
649
650 interface I
651 public this.x: number
652 endinterface
653
654 class Foo implements I
655 public this.x: number
656
657 def Add(n: number)
658 var i: I = this
659 i.x += n
660 enddef
661 endclass
662
663 var f = Foo.new(3)
664 f.Add(17)
665 assert_equal(20, f.x)
666
667 def AddToFoo(i: I)
668 i.x += 3
669 enddef
670
671 AddToFoo(f)
672 assert_equal(23, f.x)
673 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200674 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000675enddef
676
Bram Moolenaarf4508042023-01-15 16:54:57 +0000677def Test_list_of_objects()
678 var lines =<< trim END
679 vim9script
680
681 class Foo
682 def Add()
683 enddef
684 endclass
685
686 def ProcessList(fooList: list<Foo>)
687 for foo in fooList
688 foo.Add()
689 endfor
690 enddef
691
692 var l: list<Foo> = [Foo.new()]
693 ProcessList(l)
694 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200695 v9.CheckSourceSuccess(lines)
Bram Moolenaarf4508042023-01-15 16:54:57 +0000696enddef
697
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000698def Test_expr_after_using_object()
699 var lines =<< trim END
700 vim9script
701
702 class Something
703 this.label: string = ''
704 endclass
705
706 def Foo(): Something
707 var v = Something.new()
708 echo 'in Foo(): ' .. typename(v)
709 return v
710 enddef
711
712 Foo()
713 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200714 v9.CheckSourceSuccess(lines)
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000715enddef
716
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000717def Test_class_default_new()
718 var lines =<< trim END
719 vim9script
720
721 class TextPosition
722 this.lnum: number = 1
723 this.col: number = 1
724 endclass
725
726 var pos = TextPosition.new()
727 assert_equal(1, pos.lnum)
728 assert_equal(1, pos.col)
729
730 pos = TextPosition.new(v:none, v:none)
731 assert_equal(1, pos.lnum)
732 assert_equal(1, pos.col)
733
734 pos = TextPosition.new(3, 22)
735 assert_equal(3, pos.lnum)
736 assert_equal(22, pos.col)
737
738 pos = TextPosition.new(v:none, 33)
739 assert_equal(1, pos.lnum)
740 assert_equal(33, pos.col)
741 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200742 v9.CheckSourceSuccess(lines)
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000743
744 lines =<< trim END
745 vim9script
746 class Person
747 this.name: string
748 this.age: number = 42
749 this.education: string = "unknown"
750
751 def new(this.name, this.age = v:none, this.education = v:none)
752 enddef
753 endclass
754
755 var piet = Person.new("Piet")
756 assert_equal("Piet", piet.name)
757 assert_equal(42, piet.age)
758 assert_equal("unknown", piet.education)
759
760 var chris = Person.new("Chris", 4, "none")
761 assert_equal("Chris", chris.name)
762 assert_equal(4, chris.age)
763 assert_equal("none", chris.education)
764 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200765 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000766
767 lines =<< trim END
768 vim9script
769 class Person
770 this.name: string
771 this.age: number = 42
772 this.education: string = "unknown"
773
774 def new(this.name, this.age = v:none, this.education = v:none)
775 enddef
776 endclass
777
778 var missing = Person.new()
779 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200780 v9.CheckSourceFailure(lines, 'E119:')
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200781
782 # Using a specific value to initialize an instance variable in the new()
783 # method.
784 lines =<< trim END
785 vim9script
786 class A
787 this.val: string
788 def new(this.val = 'a')
789 enddef
790 endclass
791 END
792 v9.CheckSourceFailure(lines, "E1328: Constructor default value must be v:none: = 'a'")
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000793enddef
794
h-east2261c892023-08-16 21:49:54 +0900795def Test_class_new_with_object_member()
796 var lines =<< trim END
797 vim9script
798
799 class C
800 this.str: string
801 this.num: number
802 def new(this.str, this.num)
803 enddef
804 def newVals(this.str, this.num)
805 enddef
806 endclass
807
808 def Check()
809 try
810 var c = C.new('cats', 2)
811 assert_equal('cats', c.str)
812 assert_equal(2, c.num)
813
814 c = C.newVals('dogs', 4)
815 assert_equal('dogs', c.str)
816 assert_equal(4, c.num)
817 catch
818 assert_report($'Unexpected exception was caught: {v:exception}')
819 endtry
820 enddef
821
822 Check()
823 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200824 v9.CheckSourceSuccess(lines)
h-east2261c892023-08-16 21:49:54 +0900825
826 lines =<< trim END
827 vim9script
828
829 class C
830 this.str: string
831 this.num: number
832 def new(this.str, this.num)
833 enddef
834 endclass
835
836 def Check()
837 try
838 var c = C.new(1, 2)
839 catch
840 assert_report($'Unexpected exception was caught: {v:exception}')
841 endtry
842 enddef
843
844 Check()
845 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200846 v9.CheckSourceFailure(lines, 'E1013:')
h-east2261c892023-08-16 21:49:54 +0900847
848 lines =<< trim END
849 vim9script
850
851 class C
852 this.str: string
853 this.num: number
854 def newVals(this.str, this.num)
855 enddef
856 endclass
857
858 def Check()
859 try
860 var c = C.newVals('dogs', 'apes')
861 catch
862 assert_report($'Unexpected exception was caught: {v:exception}')
863 endtry
864 enddef
865
866 Check()
867 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200868 v9.CheckSourceFailure(lines, 'E1013:')
h-east2261c892023-08-16 21:49:54 +0900869enddef
870
Bram Moolenaar74e12742022-12-13 21:14:28 +0000871def Test_class_object_member_inits()
872 var lines =<< trim END
873 vim9script
874 class TextPosition
875 this.lnum: number
876 this.col = 1
877 this.addcol: number = 2
878 endclass
879
880 var pos = TextPosition.new()
881 assert_equal(0, pos.lnum)
882 assert_equal(1, pos.col)
883 assert_equal(2, pos.addcol)
884 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200885 v9.CheckSourceSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000886
887 lines =<< trim END
888 vim9script
889 class TextPosition
890 this.lnum
891 this.col = 1
892 endclass
893 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200894 v9.CheckSourceFailure(lines, 'E1022:')
Bram Moolenaar74e12742022-12-13 21:14:28 +0000895
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200896 # If the type is not specified for a member, then it should be set during
897 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +0000898 lines =<< trim END
899 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200900
901 var init_count = 0
902 def Init(): string
903 init_count += 1
904 return 'foo'
905 enddef
906
907 class A
908 this.str1 = Init()
909 this.str2: string = Init()
Bram Moolenaar74e12742022-12-13 21:14:28 +0000910 this.col = 1
911 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200912
913 assert_equal(init_count, 0)
914 var a = A.new()
915 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000916 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200917 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200918
919 # Test for initializing an object member with an unknown variable/type
920 lines =<< trim END
921 vim9script
922 class A
923 this.value = init_val
924 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200925 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200926 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200927 v9.CheckSourceFailure(lines, 'E1001:')
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +0200928
929 # Test for initializing an object member with an special type
930 lines =<< trim END
931 vim9script
932 class A
933 this.value: void
934 endclass
935 END
936 v9.CheckSourceFailure(lines, 'E1330: Invalid type for object member: void')
Bram Moolenaar74e12742022-12-13 21:14:28 +0000937enddef
938
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200939" Test for instance variable access
940def Test_instance_variable_access()
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000941 var lines =<< trim END
942 vim9script
943 class Triple
944 this._one = 1
945 this.two = 2
946 public this.three = 3
947
948 def GetOne(): number
949 return this._one
950 enddef
951 endclass
952
953 var trip = Triple.new()
954 assert_equal(1, trip.GetOne())
955 assert_equal(2, trip.two)
956 assert_equal(3, trip.three)
957 assert_fails('echo trip._one', 'E1333')
958
959 assert_fails('trip._one = 11', 'E1333')
960 assert_fails('trip.two = 22', 'E1335')
961 trip.three = 33
962 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +0000963
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200964 assert_fails('trip.four = 4', 'E1326')
Bram Moolenaard505d172022-12-18 21:42:55 +0000965 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200966 v9.CheckSourceSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +0000967
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200968 # Test for a public member variable name beginning with an underscore
969 lines =<< trim END
970 vim9script
971 class A
972 public this._val = 10
973 endclass
974 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +0200975 v9.CheckSourceFailure(lines, 'E1332:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200976
Bram Moolenaar590162c2022-12-24 21:24:06 +0000977 lines =<< trim END
978 vim9script
979
980 class MyCar
981 this.make: string
Bram Moolenaar574950d2023-01-03 19:08:50 +0000982 this.age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +0000983
984 def new(make_arg: string)
985 this.make = make_arg
986 enddef
987
988 def GetMake(): string
989 return $"make = {this.make}"
990 enddef
Bram Moolenaar574950d2023-01-03 19:08:50 +0000991 def GetAge(): number
992 return this.age
993 enddef
Bram Moolenaar590162c2022-12-24 21:24:06 +0000994 endclass
995
996 var c = MyCar.new("abc")
997 assert_equal('make = abc', c.GetMake())
998
999 c = MyCar.new("def")
1000 assert_equal('make = def', c.GetMake())
1001
1002 var c2 = MyCar.new("123")
1003 assert_equal('make = 123', c2.GetMake())
Bram Moolenaar574950d2023-01-03 19:08:50 +00001004
1005 def CheckCar()
1006 assert_equal("make = def", c.GetMake())
1007 assert_equal(5, c.GetAge())
1008 enddef
1009 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +00001010 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001011 v9.CheckSourceSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +00001012
1013 lines =<< trim END
1014 vim9script
1015
1016 class MyCar
1017 this.make: string
1018
1019 def new(make_arg: string)
1020 this.make = make_arg
1021 enddef
1022 endclass
1023
1024 var c = MyCar.new("abc")
1025 var c = MyCar.new("def")
1026 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001027 v9.CheckSourceFailure(lines, 'E1041:')
Bram Moolenaarb149d222023-01-24 13:03:37 +00001028
1029 lines =<< trim END
1030 vim9script
1031
1032 class Foo
1033 this.x: list<number> = []
1034
1035 def Add(n: number): any
1036 this.x->add(n)
1037 return this
1038 enddef
1039 endclass
1040
1041 echo Foo.new().Add(1).Add(2).x
1042 echo Foo.new().Add(1).Add(2)
1043 .x
1044 echo Foo.new().Add(1)
1045 .Add(2).x
1046 echo Foo.new()
1047 .Add(1).Add(2).x
1048 echo Foo.new()
1049 .Add(1)
1050 .Add(2)
1051 .x
1052 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001053 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001054
1055 # Test for "public" cannot be abbreviated
1056 lines =<< trim END
1057 vim9script
1058 class Something
1059 pub this.val = 1
1060 endclass
1061 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001062 v9.CheckSourceFailure(lines, 'E1065:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001063
1064 # Test for "public" keyword must be followed by "this" or "static".
1065 lines =<< trim END
1066 vim9script
1067 class Something
1068 public val = 1
1069 endclass
1070 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001071 v9.CheckSourceFailure(lines, 'E1331:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001072
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001073 # Modify a instance variable using the class name in the script context
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001074 lines =<< trim END
1075 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001076 class A
1077 public this.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001078 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001079 A.val = 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001080 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001081 v9.CheckSourceFailure(lines, 'E1376: Object member "val" accessible only using class "A" object')
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001082
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001083 # Read a instance variable using the class name in the script context
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001084 lines =<< trim END
1085 vim9script
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001086 class A
1087 public this.val = 1
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001088 endclass
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001089 var i = A.val
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02001090 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001091 v9.CheckSourceFailure(lines, 'E1376: Object member "val" accessible only using class "A" object')
1092
1093 # Modify a instance variable using the class name in a def function
1094 lines =<< trim END
1095 vim9script
1096 class A
1097 public this.val = 1
1098 endclass
1099 def T()
1100 A.val = 1
1101 enddef
1102 T()
1103 END
1104 v9.CheckSourceFailure(lines, 'E1376: Object member "val" accessible only using class "A" object')
1105
1106 # Read a instance variable using the class name in a def function
1107 lines =<< trim END
1108 vim9script
1109 class A
1110 public this.val = 1
1111 endclass
1112 def T()
1113 var i = A.val
1114 enddef
1115 T()
1116 END
1117 v9.CheckSourceFailure(lines, 'E1376: Object member "val" accessible only using class "A" object')
Ernie Raelcf138d42023-09-06 20:45:03 +02001118
1119 # Access from child class extending a class:
1120 lines =<< trim END
1121 vim9script
1122 class A
1123 this.ro_obj_var = 10
1124 public this.rw_obj_var = 20
1125 this._priv_obj_var = 30
Ernie Raelcf138d42023-09-06 20:45:03 +02001126 endclass
1127
1128 class B extends A
1129 def Foo()
1130 var x: number
1131 x = this.ro_obj_var
1132 this.ro_obj_var = 0
1133 x = this.rw_obj_var
1134 this.rw_obj_var = 0
1135 x = this._priv_obj_var
1136 this._priv_obj_var = 0
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001137 enddef
1138 endclass
Ernie Raelcf138d42023-09-06 20:45:03 +02001139
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001140 var b = B.new()
1141 b.Foo()
1142 END
1143 v9.CheckSourceSuccess(lines)
1144enddef
Ernie Raelcf138d42023-09-06 20:45:03 +02001145
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001146" Test for class variable access
1147def Test_class_variable_access()
1148 # Test for "static" cannot be abbreviated
1149 var lines =<< trim END
1150 vim9script
1151 class Something
1152 stat this.val = 1
1153 endclass
1154 END
1155 v9.CheckSourceFailure(lines, 'E1065:')
1156
1157 # Test for "static" cannot be followed by "this".
1158 lines =<< trim END
1159 vim9script
1160 class Something
1161 static this.val = 1
1162 endclass
1163 END
1164 v9.CheckSourceFailure(lines, 'E1368: Static cannot be followed by "this" in a member name')
1165
1166 # Test for "static" cannot be followed by "public".
1167 lines =<< trim END
1168 vim9script
1169 class Something
1170 static public val = 1
1171 endclass
1172 END
1173 v9.CheckSourceFailure(lines, 'E1022: Type or initialization required')
1174
1175 # A readonly class variable cannot be modified from a child class
1176 lines =<< trim END
1177 vim9script
1178 class A
1179 static ro_class_var = 40
1180 endclass
1181
1182 class B extends A
1183 def Foo()
1184 A.ro_class_var = 50
1185 enddef
1186 endclass
1187
1188 var b = B.new()
1189 b.Foo()
1190 END
1191 v9.CheckSourceFailure(lines, 'E46: Cannot change read-only variable "ro_class_var"')
1192
1193 # A private class variable cannot be accessed from a child class
1194 lines =<< trim END
1195 vim9script
1196 class A
1197 static _priv_class_var = 60
1198 endclass
1199
1200 class B extends A
1201 def Foo()
1202 var i = A._priv_class_var
1203 enddef
1204 endclass
1205
1206 var b = B.new()
1207 b.Foo()
1208 END
1209 v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _priv_class_var')
1210
1211 # A private class variable cannot be modified from a child class
1212 lines =<< trim END
1213 vim9script
1214 class A
1215 static _priv_class_var = 60
1216 endclass
1217
1218 class B extends A
1219 def Foo()
Ernie Raelcf138d42023-09-06 20:45:03 +02001220 A._priv_class_var = 0
1221 enddef
1222 endclass
1223
1224 var b = B.new()
1225 b.Foo()
1226 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001227 v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _priv_class_var')
1228
1229 # Access from child class extending a class and from script context
1230 lines =<< trim END
1231 vim9script
1232 class A
1233 static ro_class_var = 10
1234 public static rw_class_var = 20
1235 static _priv_class_var = 30
1236 endclass
1237
1238 class B extends A
1239 def Foo()
1240 var x: number
1241 x = A.ro_class_var
1242 assert_equal(10, x)
1243 x = A.rw_class_var
1244 assert_equal(25, x)
1245 A.rw_class_var = 20
1246 assert_equal(20, A.rw_class_var)
1247 enddef
1248 endclass
1249
1250 assert_equal(10, A.ro_class_var)
1251 assert_equal(20, A.rw_class_var)
1252 A.rw_class_var = 25
1253 assert_equal(25, A.rw_class_var)
1254 var b = B.new()
1255 b.Foo()
1256 END
1257 v9.CheckSourceSuccess(lines)
Bram Moolenaard505d172022-12-18 21:42:55 +00001258enddef
1259
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001260def Test_class_object_compare()
1261 var class_lines =<< trim END
1262 vim9script
1263 class Item
1264 this.nr = 0
1265 this.name = 'xx'
1266 endclass
1267 END
1268
1269 # used at the script level and in a compiled function
1270 var test_lines =<< trim END
1271 var i1 = Item.new()
1272 assert_equal(i1, i1)
1273 assert_true(i1 is i1)
1274 var i2 = Item.new()
1275 assert_equal(i1, i2)
1276 assert_false(i1 is i2)
1277 var i3 = Item.new(0, 'xx')
1278 assert_equal(i1, i3)
1279
1280 var io1 = Item.new(1, 'xx')
1281 assert_notequal(i1, io1)
1282 var io2 = Item.new(0, 'yy')
1283 assert_notequal(i1, io2)
1284 END
1285
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001286 v9.CheckSourceSuccess(class_lines + test_lines)
1287 v9.CheckSourceSuccess(
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001288 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001289
1290 for op in ['>', '>=', '<', '<=', '=~', '!~']
1291 var op_lines = [
1292 'var i1 = Item.new()',
1293 'var i2 = Item.new()',
1294 'echo i1 ' .. op .. ' i2',
1295 ]
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001296 v9.CheckSourceFailure(class_lines + op_lines, 'E1153: Invalid operation for object')
1297 v9.CheckSourceFailure(class_lines
Bram Moolenaar46ab9252023-01-03 14:01:21 +00001298 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +00001299 endfor
1300enddef
1301
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001302def Test_object_type()
1303 var lines =<< trim END
1304 vim9script
1305
1306 class One
1307 this.one = 1
1308 endclass
1309 class Two
1310 this.two = 2
1311 endclass
1312 class TwoMore extends Two
1313 this.more = 9
1314 endclass
1315
1316 var o: One = One.new()
1317 var t: Two = Two.new()
1318 var m: TwoMore = TwoMore.new()
1319 var tm: Two = TwoMore.new()
1320
1321 t = m
1322 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001323 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001324
1325 lines =<< trim END
1326 vim9script
1327
1328 class One
1329 this.one = 1
1330 endclass
1331 class Two
1332 this.two = 2
1333 endclass
1334
1335 var o: One = Two.new()
1336 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001337 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>')
Bram Moolenaara94bd9d2023-01-12 15:01:32 +00001338
1339 lines =<< trim END
1340 vim9script
1341
1342 interface One
1343 def GetMember(): number
1344 endinterface
1345 class Two implements One
1346 this.one = 1
1347 def GetMember(): number
1348 return this.one
1349 enddef
1350 endclass
1351
1352 var o: One = Two.new(5)
1353 assert_equal(5, o.GetMember())
1354 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001355 v9.CheckSourceSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001356
1357 lines =<< trim END
1358 vim9script
1359
1360 class Num
1361 this.n: number = 0
1362 endclass
1363
1364 def Ref(name: string): func(Num): Num
1365 return (arg: Num): Num => {
1366 return eval(name)(arg)
1367 }
1368 enddef
1369
1370 const Fn = Ref('Double')
1371 var Double = (m: Num): Num => Num.new(m.n * 2)
1372
1373 echo Fn(Num.new(4))
1374 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001375 v9.CheckSourceSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001376enddef
1377
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001378def Test_class_member()
1379 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001380 var lines =<< trim END
1381 vim9script
1382 class TextPos
1383 this.lnum = 1
1384 this.col = 1
1385 static counter = 0
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001386 static _secret = 7
1387 public static anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001388
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001389 static def AddToCounter(nr: number)
Bram Moolenaard505d172022-12-18 21:42:55 +00001390 counter += nr
1391 enddef
1392 endclass
1393
1394 assert_equal(0, TextPos.counter)
1395 TextPos.AddToCounter(3)
1396 assert_equal(3, TextPos.counter)
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001397 assert_fails('echo TextPos.noSuchMember', 'E1337:')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001398
Bram Moolenaar3259ff32023-01-04 18:54:09 +00001399 def GetCounter(): number
1400 return TextPos.counter
1401 enddef
1402 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001403
Bram Moolenaarf54cedd2022-12-23 17:56:27 +00001404 assert_fails('TextPos.noSuchMember = 2', 'E1337:')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001405 assert_fails('TextPos.counter = 5', 'E1335:')
1406 assert_fails('TextPos.counter += 5', 'E1335:')
1407
1408 assert_fails('echo TextPos._secret', 'E1333:')
1409 assert_fails('TextPos._secret = 8', 'E1333:')
1410
1411 assert_equal(42, TextPos.anybody)
1412 TextPos.anybody = 12
1413 assert_equal(12, TextPos.anybody)
1414 TextPos.anybody += 5
1415 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001416 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001417 v9.CheckSourceSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001418
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001419 # example in the help
1420 lines =<< trim END
1421 vim9script
1422 class OtherThing
1423 this.size: number
1424 static totalSize: number
1425
1426 def new(this.size)
1427 totalSize += this.size
1428 enddef
1429 endclass
1430 assert_equal(0, OtherThing.totalSize)
1431 var to3 = OtherThing.new(3)
1432 assert_equal(3, OtherThing.totalSize)
1433 var to7 = OtherThing.new(7)
1434 assert_equal(10, OtherThing.totalSize)
1435 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001436 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001437
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001438 # using static class member twice
1439 lines =<< trim END
1440 vim9script
1441
1442 class HTML
1443 static author: string = 'John Doe'
1444
1445 static def MacroSubstitute(s: string): string
1446 return substitute(s, '{{author}}', author, 'gi')
1447 enddef
1448 endclass
1449
1450 assert_equal('some text', HTML.MacroSubstitute('some text'))
1451 assert_equal('some text', HTML.MacroSubstitute('some text'))
1452 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001453 v9.CheckSourceSuccess(lines)
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001454
Bram Moolenaar62a69232023-01-24 15:07:04 +00001455 # access private member in lambda
1456 lines =<< trim END
1457 vim9script
1458
1459 class Foo
1460 this._x: number = 0
1461
1462 def Add(n: number): number
1463 const F = (): number => this._x + n
1464 return F()
1465 enddef
1466 endclass
1467
1468 var foo = Foo.new()
1469 assert_equal(5, foo.Add(5))
1470 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001471 v9.CheckSourceSuccess(lines)
Bram Moolenaar62a69232023-01-24 15:07:04 +00001472
h-east2bd6a092023-05-19 19:01:17 +01001473 # access private member in lambda body
1474 lines =<< trim END
1475 vim9script
1476
1477 class Foo
1478 this._x: number = 6
1479
1480 def Add(n: number): number
1481 var Lam = () => {
1482 this._x = this._x + n
1483 }
1484 Lam()
1485 return this._x
1486 enddef
1487 endclass
1488
1489 var foo = Foo.new()
1490 assert_equal(13, foo.Add(7))
1491 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001492 v9.CheckSourceSuccess(lines)
h-east2bd6a092023-05-19 19:01:17 +01001493
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001494 # check shadowing
1495 lines =<< trim END
1496 vim9script
1497
1498 class Some
1499 static count = 0
1500 def Method(count: number)
1501 echo count
1502 enddef
1503 endclass
1504
1505 var s = Some.new()
1506 s.Method(7)
1507 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001508 v9.CheckSourceFailure(lines, 'E1340: Argument already declared in the class: count')
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001509
1510 lines =<< trim END
1511 vim9script
1512
1513 class Some
1514 static count = 0
1515 def Method(arg: number)
1516 var count = 3
1517 echo arg count
1518 enddef
1519 endclass
1520
1521 var s = Some.new()
1522 s.Method(7)
1523 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001524 v9.CheckSourceFailure(lines, 'E1341: Variable already declared in the class: count')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001525
1526 # Test for using an invalid type for a member variable
1527 lines =<< trim END
1528 vim9script
1529 class A
1530 this.val: xxx
1531 endclass
1532 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001533 v9.CheckSourceFailure(lines, 'E1010:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001534
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001535 # Test for setting a member on a null object
1536 lines =<< trim END
1537 vim9script
1538 class A
Gianmaria Bajo6ad4a602023-08-31 20:55:35 +02001539 public this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001540 endclass
1541
1542 def F()
1543 var obj: A
1544 obj.val = ""
1545 enddef
1546 F()
1547 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001548 v9.CheckSourceFailure(lines, 'E1360: Using a null object')
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001549
1550 # Test for accessing a member on a null object
1551 lines =<< trim END
1552 vim9script
1553 class A
1554 this.val: string
1555 endclass
1556
1557 def F()
1558 var obj: A
1559 echo obj.val
1560 enddef
1561 F()
1562 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001563 v9.CheckSourceFailure(lines, 'E1360: Using a null object')
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001564
1565 # Test for setting a member on a null object, at script level
1566 lines =<< trim END
1567 vim9script
1568 class A
Gianmaria Bajo6ad4a602023-08-31 20:55:35 +02001569 public this.val: string
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001570 endclass
1571
1572 var obj: A
1573 obj.val = ""
1574 END
1575 # FIXME(in source): this should give E1360 as well!
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001576 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<A> but got string')
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001577
1578 # Test for accessing a member on a null object, at script level
1579 lines =<< trim END
1580 vim9script
1581 class A
1582 this.val: string
1583 endclass
1584
1585 var obj: A
1586 echo obj.val
1587 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001588 v9.CheckSourceFailure(lines, 'E1360: Using a null object')
Gianmaria Bajod7085a02023-08-31 18:15:26 +02001589
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001590 # Test for no space before or after the '=' when initializing a member
1591 # variable
1592 lines =<< trim END
1593 vim9script
1594 class A
1595 this.val: number= 10
1596 endclass
1597 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001598 v9.CheckSourceFailure(lines, 'E1004:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001599 lines =<< trim END
1600 vim9script
1601 class A
1602 this.val: number =10
1603 endclass
1604 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001605 v9.CheckSourceFailure(lines, 'E1004:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001606
1607 # Access a non-existing member
1608 lines =<< trim END
1609 vim9script
1610 class A
1611 endclass
1612 var a = A.new()
1613 var v = a.bar
1614 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001615 v9.CheckSourceFailure(lines, 'E1326: Member not found on object "A": bar')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001616enddef
1617
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001618func Test_class_garbagecollect()
1619 let lines =<< trim END
1620 vim9script
1621
1622 class Point
1623 this.p = [2, 3]
1624 static pl = ['a', 'b']
1625 static pd = {a: 'a', b: 'b'}
1626 endclass
1627
1628 echo Point.pl Point.pd
1629 call test_garbagecollect_now()
1630 echo Point.pl Point.pd
1631 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001632 call v9.CheckSourceSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001633
1634 let lines =<< trim END
1635 vim9script
1636
1637 interface View
1638 endinterface
1639
1640 class Widget
1641 this.view: View
1642 endclass
1643
1644 class MyView implements View
1645 this.widget: Widget
1646
1647 def new()
1648 # this will result in a circular reference to this object
1649 this.widget = Widget.new(this)
1650 enddef
1651 endclass
1652
1653 var view = MyView.new()
1654
1655 # overwrite "view", will be garbage-collected next
1656 view = MyView.new()
1657 test_garbagecollect_now()
1658 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001659 call v9.CheckSourceSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001660endfunc
1661
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001662" Test interface garbage collection
1663func Test_interface_garbagecollect()
1664 let lines =<< trim END
1665 vim9script
1666
1667 interface I
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001668 this.ro_obj_var: number
1669 public this.rw_obj_var: number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001670
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001671 def ObjFoo(): number
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001672 endinterface
1673
1674 class A implements I
1675 static ro_class_var: number = 10
1676 public static rw_class_var: number = 20
1677 static _priv_class_var: number = 30
1678 this.ro_obj_var: number = 40
1679 public this.rw_obj_var: number = 50
1680 this._priv_obj_var: number = 60
1681
1682 static def _ClassBar(): number
1683 return _priv_class_var
1684 enddef
1685
1686 static def ClassFoo(): number
1687 return ro_class_var + rw_class_var + A._ClassBar()
1688 enddef
1689
1690 def _ObjBar(): number
1691 return this._priv_obj_var
1692 enddef
1693
1694 def ObjFoo(): number
1695 return this.ro_obj_var + this.rw_obj_var + this._ObjBar()
1696 enddef
1697 endclass
1698
1699 assert_equal(60, A.ClassFoo())
1700 var o = A.new()
1701 assert_equal(150, o.ObjFoo())
1702 test_garbagecollect_now()
1703 assert_equal(60, A.ClassFoo())
1704 assert_equal(150, o.ObjFoo())
1705 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001706 call v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan544be0d2023-09-04 22:14:28 +02001707endfunc
1708
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02001709def Test_class_method()
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001710 var lines =<< trim END
1711 vim9script
1712 class Value
1713 this.value = 0
1714 static objects = 0
1715
1716 def new(v: number)
1717 this.value = v
1718 ++objects
1719 enddef
1720
1721 static def GetCount(): number
1722 return objects
1723 enddef
1724 endclass
1725
1726 assert_equal(0, Value.GetCount())
1727 var v1 = Value.new(2)
1728 assert_equal(1, Value.GetCount())
1729 var v2 = Value.new(7)
1730 assert_equal(2, Value.GetCount())
1731 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001732 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001733
1734 # Test for cleaning up after a class definition failure when using class
1735 # functions.
1736 lines =<< trim END
1737 vim9script
1738 class A
1739 static def Foo()
1740 enddef
1741 aaa
1742 endclass
1743 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001744 v9.CheckSourceFailure(lines, 'E1318:')
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02001745
1746 # Test for calling a class method from another class method without the class
1747 # name prefix.
1748 lines =<< trim END
1749 vim9script
1750 class A
1751 static myList: list<number> = [1]
1752 static def Foo(n: number)
1753 myList->add(n)
1754 enddef
1755 static def Bar()
1756 Foo(2)
1757 enddef
1758 def Baz()
1759 Foo(3)
1760 enddef
1761 endclass
1762 A.Bar()
1763 var a = A.new()
1764 a.Baz()
1765 assert_equal([1, 2, 3], A.myList)
1766 END
1767 v9.CheckSourceSuccess(lines)
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001768enddef
1769
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001770def Test_class_defcompile()
1771 var lines =<< trim END
1772 vim9script
1773
1774 class C
1775 def Fo(i: number): string
1776 return i
1777 enddef
1778 endclass
1779
1780 defcompile C.Fo
1781 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001782 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected string but got number')
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001783
1784 lines =<< trim END
1785 vim9script
1786
1787 class C
1788 static def Fc(): number
1789 return 'x'
1790 enddef
1791 endclass
1792
1793 defcompile C.Fc
1794 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001795 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected number but got string')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001796
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02001797 lines =<< trim END
1798 vim9script
1799
1800 class C
1801 static def new()
1802 enddef
1803 endclass
1804
1805 defcompile C.new
1806 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001807 v9.CheckSourceFailure(lines, 'E1370: Cannot define a "new" function as static')
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02001808
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001809 # Trying to compile a function using a non-existing class variable
1810 lines =<< trim END
1811 vim9script
1812 defcompile x.Foo()
1813 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001814 v9.CheckSourceFailure(lines, 'E475:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001815
1816 # Trying to compile a function using a variable which is not a class
1817 lines =<< trim END
1818 vim9script
1819 var x: number
1820 defcompile x.Foo()
1821 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001822 v9.CheckSourceFailure(lines, 'E475:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001823
1824 # Trying to compile a function without specifying the name
1825 lines =<< trim END
1826 vim9script
1827 class A
1828 endclass
1829 defcompile A.
1830 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001831 v9.CheckSourceFailure(lines, 'E475:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001832
1833 # Trying to compile a non-existing class object member function
1834 lines =<< trim END
1835 vim9script
1836 class A
1837 endclass
1838 var a = A.new()
1839 defcompile a.Foo()
1840 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001841 v9.CheckSourceFailureList(lines, ['E1326:', 'E475:'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001842enddef
1843
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00001844def Test_class_object_to_string()
1845 var lines =<< trim END
1846 vim9script
1847 class TextPosition
1848 this.lnum = 1
1849 this.col = 22
1850 endclass
1851
1852 assert_equal("class TextPosition", string(TextPosition))
1853
1854 var pos = TextPosition.new()
1855 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
1856 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001857 v9.CheckSourceSuccess(lines)
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00001858enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00001859
Bram Moolenaar554d0312023-01-05 19:59:18 +00001860def Test_interface_basics()
1861 var lines =<< trim END
1862 vim9script
1863 interface Something
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001864 this.ro_var: string
1865 public this.rw_var: list<number>
Bram Moolenaar554d0312023-01-05 19:59:18 +00001866 def GetCount(): number
1867 endinterface
1868 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001869 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001870
1871 lines =<< trim END
1872 interface SomethingWrong
1873 static count = 7
1874 endinterface
1875 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001876 v9.CheckSourceFailure(lines, 'E1342:')
Bram Moolenaar554d0312023-01-05 19:59:18 +00001877
1878 lines =<< trim END
1879 vim9script
1880
1881 interface Some
Bram Moolenaard40f00c2023-01-13 17:36:49 +00001882 this.value: number
1883 def Method(value: number)
1884 endinterface
1885 END
h-east61378a12023-04-18 19:07:29 +01001886 # The argument name and the object member name are the same, but this is not a
1887 # problem because object members are always accessed with the "this." prefix.
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001888 v9.CheckSourceSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001889
1890 lines =<< trim END
1891 vim9script
1892 interface somethingWrong
1893 static count = 7
1894 endinterface
1895 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001896 v9.CheckSourceFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong')
Bram Moolenaar554d0312023-01-05 19:59:18 +00001897
1898 lines =<< trim END
1899 vim9script
1900 interface SomethingWrong
1901 this.value: string
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001902 this.count = 7
Bram Moolenaar554d0312023-01-05 19:59:18 +00001903 def GetCount(): number
1904 endinterface
1905 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001906 v9.CheckSourceFailure(lines, 'E1344:')
Bram Moolenaar554d0312023-01-05 19:59:18 +00001907
1908 lines =<< trim END
1909 vim9script
1910 interface SomethingWrong
1911 this.value: string
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001912 this.count: number
Bram Moolenaar554d0312023-01-05 19:59:18 +00001913 def GetCount(): number
1914 return 5
1915 enddef
1916 endinterface
1917 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001918 v9.CheckSourceFailure(lines, 'E1345: Not a valid command in an interface: return 5')
Bram Moolenaar53f54e42023-01-26 20:36:56 +00001919
1920 lines =<< trim END
1921 vim9script
1922 export interface EnterExit
1923 def Enter(): void
1924 def Exit(): void
1925 endinterface
1926 END
1927 writefile(lines, 'XdefIntf.vim', 'D')
1928
1929 lines =<< trim END
1930 vim9script
1931 import './XdefIntf.vim' as defIntf
1932 export def With(ee: defIntf.EnterExit, F: func)
1933 ee.Enter()
1934 try
1935 F()
1936 finally
1937 ee.Exit()
1938 endtry
1939 enddef
1940 END
1941 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00001942
1943 var imported =<< trim END
1944 vim9script
1945 export abstract class EnterExit
1946 def Enter(): void
1947 enddef
1948 def Exit(): void
1949 enddef
1950 endclass
1951 END
1952 writefile(imported, 'XdefIntf2.vim', 'D')
1953
1954 lines[1] = " import './XdefIntf2.vim' as defIntf"
1955 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001956enddef
1957
Bram Moolenaar94674f22023-01-06 18:42:20 +00001958def Test_class_implements_interface()
1959 var lines =<< trim END
1960 vim9script
1961
1962 interface Some
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001963 this.count: number
Bram Moolenaar94674f22023-01-06 18:42:20 +00001964 def Method(nr: number)
1965 endinterface
1966
1967 class SomeImpl implements Some
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001968 this.count: number
Bram Moolenaar94674f22023-01-06 18:42:20 +00001969 def Method(nr: number)
1970 echo nr
1971 enddef
1972 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001973
1974 interface Another
1975 this.member: string
1976 endinterface
1977
Bram Moolenaar83ae6152023-02-25 19:59:31 +00001978 class AnotherImpl implements Some, Another
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001979 this.member = 'abc'
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001980 this.count = 20
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001981 def Method(nr: number)
1982 echo nr
1983 enddef
1984 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00001985 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001986 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00001987
1988 lines =<< trim END
1989 vim9script
1990
1991 interface Some
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001992 this.count: number
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001993 endinterface
1994
1995 class SomeImpl implements Some implements Some
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02001996 this.count: number
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001997 endclass
1998 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02001999 v9.CheckSourceFailure(lines, 'E1350:')
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002000
2001 lines =<< trim END
2002 vim9script
2003
2004 interface Some
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02002005 this.count: number
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002006 endinterface
2007
2008 class SomeImpl implements Some, Some
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02002009 this.count: number
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002010 endclass
2011 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002012 v9.CheckSourceFailure(lines, 'E1351: Duplicate interface after "implements": Some')
Bram Moolenaardf8f9472023-01-07 14:51:03 +00002013
2014 lines =<< trim END
2015 vim9script
2016
2017 interface Some
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02002018 this.counter: number
Bram Moolenaar94674f22023-01-06 18:42:20 +00002019 def Method(nr: number)
2020 endinterface
2021
2022 class SomeImpl implements Some
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02002023 this.count: number
Bram Moolenaar94674f22023-01-06 18:42:20 +00002024 def Method(nr: number)
2025 echo nr
2026 enddef
2027 endclass
2028 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02002029 v9.CheckSourceFailure(lines, 'E1348: Member "counter" of interface "Some" is not implemented')
Bram Moolenaar94674f22023-01-06 18:42:20 +00002030
2031 lines =<< trim END
2032 vim9script
2033
2034 interface Some
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02002035 this.count: number
Bram Moolenaar94674f22023-01-06 18:42:20 +00002036 def Methods(nr: number)
2037 endinterface
2038
2039 class SomeImpl implements Some
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02002040 this.count: number
Bram Moolenaar94674f22023-01-06 18:42:20 +00002041 def Method(nr: number)
2042 echo nr
2043 enddef
2044 endclass
2045 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02002046 v9.CheckSourceFailure(lines, 'E1349: Method "Methods" of interface "Some" is not implemented')
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002047
2048 # Check different order of members in class and interface works.
2049 lines =<< trim END
2050 vim9script
2051
2052 interface Result
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00002053 public this.label: string
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002054 this.errpos: number
2055 endinterface
2056
2057 # order of members is opposite of interface
2058 class Failure implements Result
2059 this.errpos: number = 42
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00002060 public this.label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002061 endclass
2062
2063 def Test()
2064 var result: Result = Failure.new()
2065
2066 assert_equal('label', result.label)
2067 assert_equal(42, result.errpos)
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00002068
2069 result.label = 'different'
2070 assert_equal('different', result.label)
2071 assert_equal(42, result.errpos)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00002072 enddef
2073
2074 Test()
2075 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002076 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002077
2078 # Interface name after "extends" doesn't end in a space or NUL character
2079 lines =<< trim END
2080 vim9script
2081 interface A
2082 endinterface
2083 class B extends A"
2084 endclass
2085 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002086 v9.CheckSourceFailure(lines, 'E1315:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002087
2088 # Trailing characters after a class name
2089 lines =<< trim END
2090 vim9script
2091 class A bbb
2092 endclass
2093 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002094 v9.CheckSourceFailure(lines, 'E488:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002095
2096 # using "implements" with a non-existing class
2097 lines =<< trim END
2098 vim9script
2099 class A implements B
2100 endclass
2101 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002102 v9.CheckSourceFailure(lines, 'E1346:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002103
2104 # using "implements" with a regular class
2105 lines =<< trim END
2106 vim9script
2107 class A
2108 endclass
2109 class B implements A
2110 endclass
2111 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002112 v9.CheckSourceFailure(lines, 'E1347:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002113
2114 # using "implements" with a variable
2115 lines =<< trim END
2116 vim9script
2117 var T: number = 10
2118 class A implements T
2119 endclass
2120 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002121 v9.CheckSourceFailure(lines, 'E1347:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002122
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002123 # implements should be followed by a white space
2124 lines =<< trim END
2125 vim9script
2126 interface A
2127 endinterface
2128 class B implements A;
2129 endclass
2130 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002131 v9.CheckSourceFailure(lines, 'E1315:')
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002132
LemonBoyc5d27442023-08-19 13:02:35 +02002133 lines =<< trim END
2134 vim9script
2135
2136 interface One
LemonBoyc5d27442023-08-19 13:02:35 +02002137 def IsEven(nr: number): bool
2138 endinterface
2139 class Two implements One
2140 def IsEven(nr: number): string
2141 enddef
2142 endclass
2143 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02002144 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number): string')
LemonBoyc5d27442023-08-19 13:02:35 +02002145
2146 lines =<< trim END
2147 vim9script
2148
2149 interface One
2150 def IsEven(nr: number): bool
2151 endinterface
2152 class Two implements One
2153 def IsEven(nr: bool): bool
2154 enddef
2155 endclass
2156 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02002157 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(bool): bool')
LemonBoyc5d27442023-08-19 13:02:35 +02002158
2159 lines =<< trim END
2160 vim9script
2161
2162 interface One
2163 def IsEven(nr: number): bool
2164 endinterface
2165 class Two implements One
2166 def IsEven(nr: number, ...extra: list<number>): bool
2167 enddef
2168 endclass
2169 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02002170 v9.CheckSourceFailure(lines, 'E1383: Method "IsEven": type mismatch, expected func(number): bool but got func(number, ...list<number>): bool')
Ernie Raelcf138d42023-09-06 20:45:03 +02002171
2172 # access superclass interface members from subclass, mix variable order
2173 lines =<< trim END
2174 vim9script
2175
2176 interface I1
Ernie Raelcf138d42023-09-06 20:45:03 +02002177 public this.mvar1: number
2178 public this.mvar2: number
2179 endinterface
2180
2181 # NOTE: the order is swapped
2182 class A implements I1
2183 public this.mvar2: number
2184 public this.mvar1: number
2185 public static svar2: number
2186 public static svar1: number
2187 def new()
2188 svar1 = 11
2189 svar2 = 12
2190 this.mvar1 = 111
2191 this.mvar2 = 112
2192 enddef
2193 endclass
2194
2195 class B extends A
2196 def new()
Ernie Raelcf138d42023-09-06 20:45:03 +02002197 this.mvar1 = 121
2198 this.mvar2 = 122
2199 enddef
2200 endclass
2201
2202 class C extends B
2203 def new()
Ernie Raelcf138d42023-09-06 20:45:03 +02002204 this.mvar1 = 131
2205 this.mvar2 = 132
2206 enddef
2207 endclass
2208
Ernie Raelcf138d42023-09-06 20:45:03 +02002209 def F2(i: I1): list<number>
2210 return [ i.mvar1, i.mvar2 ]
2211 enddef
2212
2213 var oa = A.new()
2214 var ob = B.new()
2215 var oc = C.new()
2216
Ernie Raelcf138d42023-09-06 20:45:03 +02002217 assert_equal([111, 112], F2(oa))
2218 assert_equal([121, 122], F2(ob))
2219 assert_equal([131, 132], F2(oc))
2220 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002221 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02002222
2223 # Access superclass interface members from subclass, mix variable order.
2224 # Two interfaces, one on A, one on B; each has both kinds of variables
2225 lines =<< trim END
2226 vim9script
2227
2228 interface I1
Ernie Raelcf138d42023-09-06 20:45:03 +02002229 public this.mvar1: number
2230 public this.mvar2: number
2231 endinterface
2232
2233 interface I2
Ernie Raelcf138d42023-09-06 20:45:03 +02002234 public this.mvar3: number
2235 public this.mvar4: number
2236 endinterface
2237
2238 class A implements I1
2239 public static svar1: number
2240 public static svar2: number
2241 public this.mvar1: number
2242 public this.mvar2: number
2243 def new()
2244 svar1 = 11
2245 svar2 = 12
2246 this.mvar1 = 111
2247 this.mvar2 = 112
2248 enddef
2249 endclass
2250
2251 class B extends A implements I2
2252 public static svar3: number
2253 public static svar4: number
2254 public this.mvar3: number
2255 public this.mvar4: number
2256 def new()
Ernie Raelcf138d42023-09-06 20:45:03 +02002257 svar3 = 23
2258 svar4 = 24
2259 this.mvar1 = 121
2260 this.mvar2 = 122
2261 this.mvar3 = 123
2262 this.mvar4 = 124
2263 enddef
2264 endclass
2265
2266 class C extends B
2267 public static svar5: number
2268 def new()
Ernie Raelcf138d42023-09-06 20:45:03 +02002269 svar5 = 1001
2270 this.mvar1 = 131
2271 this.mvar2 = 132
2272 this.mvar3 = 133
2273 this.mvar4 = 134
2274 enddef
2275 endclass
2276
Ernie Raelcf138d42023-09-06 20:45:03 +02002277 def F2(i: I1): list<number>
2278 return [ i.mvar1, i.mvar2 ]
2279 enddef
2280
Ernie Raelcf138d42023-09-06 20:45:03 +02002281 def F4(i: I2): list<number>
2282 return [ i.mvar3, i.mvar4 ]
2283 enddef
2284
Ernie Raelcf138d42023-09-06 20:45:03 +02002285 var oa = A.new()
2286 var ob = B.new()
2287 var oc = C.new()
2288
Ernie Raelcf138d42023-09-06 20:45:03 +02002289 assert_equal([[111, 112]], [F2(oa)])
2290 assert_equal([[121, 122], [123, 124]], [F2(ob), F4(ob)])
2291 assert_equal([[131, 132], [133, 134]], [F2(oc), F4(oc)])
Ernie Raelcf138d42023-09-06 20:45:03 +02002292 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002293 v9.CheckSourceSuccess(lines)
Bram Moolenaar94674f22023-01-06 18:42:20 +00002294enddef
2295
Bram Moolenaard0200c82023-01-28 15:19:40 +00002296def Test_call_interface_method()
2297 var lines =<< trim END
2298 vim9script
2299 interface Base
2300 def Enter(): void
2301 endinterface
2302
2303 class Child implements Base
2304 def Enter(): void
2305 g:result ..= 'child'
2306 enddef
2307 endclass
2308
2309 def F(obj: Base)
2310 obj.Enter()
2311 enddef
2312
2313 g:result = ''
2314 F(Child.new())
2315 assert_equal('child', g:result)
2316 unlet g:result
2317 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002318 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002319
2320 lines =<< trim END
2321 vim9script
2322 class Base
2323 def Enter(): void
2324 g:result ..= 'base'
2325 enddef
2326 endclass
2327
2328 class Child extends Base
2329 def Enter(): void
2330 g:result ..= 'child'
2331 enddef
2332 endclass
2333
2334 def F(obj: Base)
2335 obj.Enter()
2336 enddef
2337
2338 g:result = ''
2339 F(Child.new())
2340 assert_equal('child', g:result)
2341 unlet g:result
2342 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002343 v9.CheckSourceSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002344
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002345 # method of interface returns a value
2346 lines =<< trim END
2347 vim9script
2348 interface Base
2349 def Enter(): string
2350 endinterface
2351
2352 class Child implements Base
2353 def Enter(): string
2354 g:result ..= 'child'
2355 return "/resource"
2356 enddef
2357 endclass
2358
2359 def F(obj: Base)
2360 var r = obj.Enter()
2361 g:result ..= r
2362 enddef
2363
2364 g:result = ''
2365 F(Child.new())
2366 assert_equal('child/resource', g:result)
2367 unlet g:result
2368 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002369 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002370
2371 lines =<< trim END
2372 vim9script
2373 class Base
2374 def Enter(): string
2375 return null_string
2376 enddef
2377 endclass
2378
2379 class Child extends Base
2380 def Enter(): string
2381 g:result ..= 'child'
2382 return "/resource"
2383 enddef
2384 endclass
2385
2386 def F(obj: Base)
2387 var r = obj.Enter()
2388 g:result ..= r
2389 enddef
2390
2391 g:result = ''
2392 F(Child.new())
2393 assert_equal('child/resource', g:result)
2394 unlet g:result
2395 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002396 v9.CheckSourceSuccess(lines)
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00002397
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00002398 # No class that implements the interface.
2399 lines =<< trim END
2400 vim9script
2401
2402 interface IWithEE
2403 def Enter(): any
2404 def Exit(): void
2405 endinterface
2406
2407 def With1(ee: IWithEE, F: func)
2408 var r = ee.Enter()
2409 enddef
2410
2411 defcompile
2412 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002413 v9.CheckSourceSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00002414enddef
2415
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002416def Test_class_used_as_type()
2417 var lines =<< trim END
2418 vim9script
2419
2420 class Point
2421 this.x = 0
2422 this.y = 0
2423 endclass
2424
2425 var p: Point
2426 p = Point.new(2, 33)
2427 assert_equal(2, p.x)
2428 assert_equal(33, p.y)
2429 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002430 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002431
2432 lines =<< trim END
2433 vim9script
2434
2435 interface HasX
2436 this.x: number
2437 endinterface
2438
2439 class Point implements HasX
2440 this.x = 0
2441 this.y = 0
2442 endclass
2443
2444 var p: Point
2445 p = Point.new(2, 33)
2446 var hx = p
2447 assert_equal(2, hx.x)
2448 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002449 v9.CheckSourceSuccess(lines)
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002450
2451 lines =<< trim END
2452 vim9script
2453
2454 class Point
2455 this.x = 0
2456 this.y = 0
2457 endclass
2458
2459 var p: Point
2460 p = 'text'
2461 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002462 v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00002463enddef
2464
Bram Moolenaar83677162023-01-08 19:54:10 +00002465def Test_class_extends()
2466 var lines =<< trim END
2467 vim9script
2468 class Base
2469 this.one = 1
2470 def GetOne(): number
2471 return this.one
2472 enddef
2473 endclass
2474 class Child extends Base
2475 this.two = 2
2476 def GetTotal(): number
2477 return this.one + this.two
2478 enddef
2479 endclass
2480 var o = Child.new()
2481 assert_equal(1, o.one)
2482 assert_equal(2, o.two)
2483 assert_equal(1, o.GetOne())
2484 assert_equal(3, o.GetTotal())
2485 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002486 v9.CheckSourceSuccess(lines)
Bram Moolenaar83677162023-01-08 19:54:10 +00002487
2488 lines =<< trim END
2489 vim9script
2490 class Base
2491 this.one = 1
2492 endclass
2493 class Child extends Base
2494 this.two = 2
2495 endclass
2496 var o = Child.new(3, 44)
2497 assert_equal(3, o.one)
2498 assert_equal(44, o.two)
2499 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002500 v9.CheckSourceSuccess(lines)
Bram Moolenaar83677162023-01-08 19:54:10 +00002501
2502 lines =<< trim END
2503 vim9script
2504 class Base
2505 this.one = 1
2506 endclass
2507 class Child extends Base extends Base
2508 this.two = 2
2509 endclass
2510 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002511 v9.CheckSourceFailure(lines, 'E1352: Duplicate "extends"')
Bram Moolenaar83677162023-01-08 19:54:10 +00002512
2513 lines =<< trim END
2514 vim9script
2515 class Child extends BaseClass
2516 this.two = 2
2517 endclass
2518 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002519 v9.CheckSourceFailure(lines, 'E1353: Class name not found: BaseClass')
Bram Moolenaar83677162023-01-08 19:54:10 +00002520
2521 lines =<< trim END
2522 vim9script
2523 var SomeVar = 99
2524 class Child extends SomeVar
2525 this.two = 2
2526 endclass
2527 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002528 v9.CheckSourceFailure(lines, 'E1354: Cannot extend SomeVar')
Bram Moolenaar58b40092023-01-11 15:59:05 +00002529
2530 lines =<< trim END
2531 vim9script
2532 class Base
2533 this.name: string
2534 def ToString(): string
2535 return this.name
2536 enddef
2537 endclass
2538
2539 class Child extends Base
2540 this.age: number
2541 def ToString(): string
2542 return super.ToString() .. ': ' .. this.age
2543 enddef
2544 endclass
2545
2546 var o = Child.new('John', 42)
2547 assert_equal('John: 42', o.ToString())
2548 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002549 v9.CheckSourceSuccess(lines)
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002550
2551 lines =<< trim END
2552 vim9script
2553 class Child
2554 this.age: number
2555 def ToString(): number
2556 return this.age
2557 enddef
2558 def ToString(): string
2559 return this.age
2560 enddef
2561 endclass
2562 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002563 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: ToString')
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002564
2565 lines =<< trim END
2566 vim9script
2567 class Child
2568 this.age: number
2569 def ToString(): string
2570 return super .ToString() .. ': ' .. this.age
2571 enddef
2572 endclass
2573 var o = Child.new(42)
2574 echo o.ToString()
2575 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002576 v9.CheckSourceFailure(lines, 'E1356:')
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002577
2578 lines =<< trim END
2579 vim9script
2580 class Base
2581 this.name: string
2582 def ToString(): string
2583 return this.name
2584 enddef
2585 endclass
2586
2587 var age = 42
2588 def ToString(): string
2589 return super.ToString() .. ': ' .. age
2590 enddef
2591 echo ToString()
2592 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002593 v9.CheckSourceFailure(lines, 'E1357:')
Bram Moolenaar6aa09372023-01-11 17:59:38 +00002594
2595 lines =<< trim END
2596 vim9script
2597 class Child
2598 this.age: number
2599 def ToString(): string
2600 return super.ToString() .. ': ' .. this.age
2601 enddef
2602 endclass
2603 var o = Child.new(42)
2604 echo o.ToString()
2605 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002606 v9.CheckSourceFailure(lines, 'E1358:')
Bram Moolenaar6481acc2023-01-11 21:14:17 +00002607
2608 lines =<< trim END
2609 vim9script
2610 class Base
2611 this.name: string
2612 static def ToString(): string
2613 return 'Base class'
2614 enddef
2615 endclass
2616
2617 class Child extends Base
2618 this.age: number
2619 def ToString(): string
2620 return Base.ToString() .. ': ' .. this.age
2621 enddef
2622 endclass
2623
2624 var o = Child.new('John', 42)
2625 assert_equal('Base class: 42', o.ToString())
2626 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002627 v9.CheckSourceSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002628
2629 lines =<< trim END
2630 vim9script
2631 class Base
2632 this.value = 1
2633 def new(init: number)
2634 this.value = number + 1
2635 enddef
2636 endclass
2637 class Child extends Base
2638 def new()
2639 this.new(3)
2640 enddef
2641 endclass
2642 var c = Child.new()
2643 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002644 v9.CheckSourceFailure(lines, 'E1375: Class member "new" accessible only using class "Child"')
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002645
2646 # base class with more than one object member
2647 lines =<< trim END
2648 vim9script
2649
2650 class Result
2651 this.success: bool
2652 this.value: any = null
2653 endclass
2654
2655 class Success extends Result
2656 def new(this.value = v:none)
2657 this.success = true
2658 enddef
2659 endclass
2660
2661 var v = Success.new('asdf')
2662 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
2663 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002664 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002665
2666 # class name after "extends" doesn't end in a space or NUL character
2667 lines =<< trim END
2668 vim9script
2669 class A
2670 endclass
2671 class B extends A"
2672 endclass
2673 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002674 v9.CheckSourceFailure(lines, 'E1315:')
Bram Moolenaar83677162023-01-08 19:54:10 +00002675enddef
2676
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002677def Test_using_base_class()
2678 var lines =<< trim END
2679 vim9script
2680
2681 class BaseEE
2682 def Enter(): any
2683 return null
2684 enddef
2685 def Exit(resource: any): void
2686 enddef
2687 endclass
2688
2689 class ChildEE extends BaseEE
2690 def Enter(): any
2691 return 42
2692 enddef
2693
2694 def Exit(resource: number): void
2695 g:result ..= '/exit'
2696 enddef
2697 endclass
2698
2699 def With(ee: BaseEE)
2700 var r = ee.Enter()
2701 try
2702 g:result ..= r
2703 finally
2704 g:result ..= '/finally'
2705 ee.Exit(r)
2706 endtry
2707 enddef
2708
2709 g:result = ''
2710 With(ChildEE.new())
2711 assert_equal('42/finally/exit', g:result)
2712 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002713 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002714 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01002715
2716 # Using super, Child invokes Base method which has optional arg. #12471
2717 lines =<< trim END
2718 vim9script
2719
2720 class Base
2721 this.success: bool = false
2722 def Method(arg = 0)
2723 this.success = true
2724 enddef
2725 endclass
2726
2727 class Child extends Base
2728 def new()
2729 super.Method()
2730 enddef
2731 endclass
2732
2733 var obj = Child.new()
2734 assert_equal(true, obj.success)
2735 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002736 v9.CheckSourceSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002737enddef
2738
Bram Moolenaara86655a2023-01-12 17:06:27 +00002739def Test_class_import()
2740 var lines =<< trim END
2741 vim9script
2742 export class Animal
2743 this.kind: string
2744 this.name: string
2745 endclass
2746 END
2747 writefile(lines, 'Xanimal.vim', 'D')
2748
2749 lines =<< trim END
2750 vim9script
2751 import './Xanimal.vim' as animal
2752
2753 var a: animal.Animal
2754 a = animal.Animal.new('fish', 'Eric')
2755 assert_equal('fish', a.kind)
2756 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00002757
2758 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
2759 assert_equal('cat', b.kind)
2760 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00002761 END
2762 v9.CheckScriptSuccess(lines)
2763enddef
2764
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002765def Test_abstract_class()
2766 var lines =<< trim END
2767 vim9script
2768 abstract class Base
2769 this.name: string
2770 endclass
2771 class Person extends Base
2772 this.age: number
2773 endclass
2774 var p: Base = Person.new('Peter', 42)
2775 assert_equal('Peter', p.name)
2776 assert_equal(42, p.age)
2777 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002778 v9.CheckSourceSuccess(lines)
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002779
2780 lines =<< trim END
2781 vim9script
2782 abstract class Base
2783 this.name: string
2784 endclass
2785 class Person extends Base
2786 this.age: number
2787 endclass
2788 var p = Base.new('Peter')
2789 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002790 v9.CheckSourceFailure(lines, 'E1325: Method not found on class "Base": new')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002791
2792 lines =<< trim END
2793 abstract class Base
2794 this.name: string
2795 endclass
2796 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002797 v9.CheckSourceFailure(lines, 'E1316:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002798
2799 # Abstract class cannot have a "new" function
2800 lines =<< trim END
2801 vim9script
2802 abstract class Base
2803 def new()
2804 enddef
2805 endclass
2806 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002807 v9.CheckSourceFailure(lines, 'E1359:')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002808enddef
2809
Bram Moolenaar486fc252023-01-18 14:51:07 +00002810def Test_closure_in_class()
2811 var lines =<< trim END
2812 vim9script
2813
2814 class Foo
2815 this.y: list<string> = ['B']
2816
2817 def new()
2818 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
2819 enddef
2820 endclass
2821
2822 Foo.new()
2823 assert_equal(['A'], g:result)
2824 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002825 v9.CheckSourceSuccess(lines)
Bram Moolenaar486fc252023-01-18 14:51:07 +00002826enddef
2827
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002828def Test_call_constructor_from_legacy()
2829 var lines =<< trim END
2830 vim9script
2831
2832 var newCalled = 'false'
2833
2834 class A
2835 def new()
2836 newCalled = 'true'
2837 enddef
2838 endclass
2839
2840 export def F(options = {}): any
2841 return A
2842 enddef
2843
2844 g:p = F()
2845 legacy call p.new()
2846 assert_equal('true', newCalled)
2847 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002848 v9.CheckSourceSuccess(lines)
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002849enddef
2850
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00002851def Test_defer_with_object()
2852 var lines =<< trim END
2853 vim9script
2854
2855 class CWithEE
2856 def Enter()
2857 g:result ..= "entered/"
2858 enddef
2859 def Exit()
2860 g:result ..= "exited"
2861 enddef
2862 endclass
2863
2864 def With(ee: CWithEE, F: func)
2865 ee.Enter()
2866 defer ee.Exit()
2867 F()
2868 enddef
2869
2870 g:result = ''
2871 var obj = CWithEE.new()
2872 obj->With(() => {
2873 g:result ..= "called/"
2874 })
2875 assert_equal('entered/called/exited', g:result)
2876 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002877 v9.CheckSourceSuccess(lines)
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00002878 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00002879
2880 lines =<< trim END
2881 vim9script
2882
2883 class BaseWithEE
2884 def Enter()
2885 g:result ..= "entered-base/"
2886 enddef
2887 def Exit()
2888 g:result ..= "exited-base"
2889 enddef
2890 endclass
2891
2892 class CWithEE extends BaseWithEE
2893 def Enter()
2894 g:result ..= "entered-child/"
2895 enddef
2896 def Exit()
2897 g:result ..= "exited-child"
2898 enddef
2899 endclass
2900
2901 def With(ee: BaseWithEE, F: func)
2902 ee.Enter()
2903 defer ee.Exit()
2904 F()
2905 enddef
2906
2907 g:result = ''
2908 var obj = CWithEE.new()
2909 obj->With(() => {
2910 g:result ..= "called/"
2911 })
2912 assert_equal('entered-child/called/exited-child', g:result)
2913 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002914 v9.CheckSourceSuccess(lines)
Bram Moolenaar313e4722023-02-08 20:55:27 +00002915 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00002916enddef
2917
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02002918" The following test used to crash Vim (Github issue #12676)
2919def Test_extends_method_crashes_vim()
2920 var lines =<< trim END
2921 vim9script
2922
2923 class Observer
2924 endclass
2925
2926 class Property
2927 this.value: any
2928
2929 def Set(v: any)
2930 if v != this.value
2931 this.value = v
2932 endif
2933 enddef
2934
2935 def Register(observer: Observer)
2936 enddef
2937 endclass
2938
2939 class Bool extends Property
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02002940 this.value2: bool
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02002941 endclass
2942
2943 def Observe(obj: Property, who: Observer)
2944 obj.Register(who)
2945 enddef
2946
2947 var p = Bool.new(false)
2948 var myObserver = Observer.new()
2949
2950 Observe(p, myObserver)
2951
2952 p.Set(true)
2953 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002954 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02002955enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00002956
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02002957" Test for calling a method in a class that is extended
2958def Test_call_method_in_extended_class()
2959 var lines =<< trim END
2960 vim9script
2961
2962 var prop_init_called = false
2963 var prop_register_called = false
2964
2965 class Property
2966 def Init()
2967 prop_init_called = true
2968 enddef
2969
2970 def Register()
2971 prop_register_called = true
2972 enddef
2973 endclass
2974
2975 class Bool extends Property
2976 endclass
2977
2978 def Observe(obj: Property)
2979 obj.Register()
2980 enddef
2981
2982 var p = Property.new()
2983 Observe(p)
2984
2985 p.Init()
2986 assert_true(prop_init_called)
2987 assert_true(prop_register_called)
2988 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02002989 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02002990enddef
2991
LemonBoyafe04662023-08-23 21:08:11 +02002992def Test_instanceof()
2993 var lines =<< trim END
2994 vim9script
2995
2996 class Base1
2997 endclass
2998
2999 class Base2 extends Base1
3000 endclass
3001
3002 interface Intf1
3003 endinterface
3004
3005 class Mix1 implements Intf1
3006 endclass
3007
3008 class Base3 extends Mix1
3009 endclass
3010
3011 var b1 = Base1.new()
3012 var b2 = Base2.new()
3013 var b3 = Base3.new()
3014
3015 assert_true(instanceof(b1, Base1))
3016 assert_true(instanceof(b2, Base1))
3017 assert_false(instanceof(b1, Base2))
3018 assert_true(instanceof(b3, Mix1))
3019 assert_false(instanceof(b3, []))
3020 assert_true(instanceof(b3, [Base1, Base2, Intf1]))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02003021
3022 def Foo()
3023 var a1 = Base1.new()
3024 var a2 = Base2.new()
3025 var a3 = Base3.new()
3026
3027 assert_true(instanceof(a1, Base1))
3028 assert_true(instanceof(a2, Base1))
3029 assert_false(instanceof(a1, Base2))
3030 assert_true(instanceof(a3, Mix1))
3031 assert_false(instanceof(a3, []))
3032 assert_true(instanceof(a3, [Base1, Base2, Intf1]))
3033 enddef
3034 Foo()
LemonBoyafe04662023-08-23 21:08:11 +02003035 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003036 v9.CheckSourceSuccess(lines)
LemonBoyafe04662023-08-23 21:08:11 +02003037enddef
3038
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003039" Test for calling a method in the parent class that is extended partially.
3040" This used to fail with the 'E118: Too many arguments for function: Text' error
3041" message (Github issue #12524).
3042def Test_call_method_in_parent_class()
3043 var lines =<< trim END
3044 vim9script
3045
3046 class Widget
3047 this._lnum: number = 1
3048
3049 def SetY(lnum: number)
3050 this._lnum = lnum
3051 enddef
3052
3053 def Text(): string
3054 return ''
3055 enddef
3056 endclass
3057
3058 class Foo extends Widget
3059 def Text(): string
3060 return '<Foo>'
3061 enddef
3062 endclass
3063
3064 def Stack(w1: Widget, w2: Widget): list<Widget>
3065 w1.SetY(1)
3066 w2.SetY(2)
3067 return [w1, w2]
3068 enddef
3069
3070 var foo1 = Foo.new()
3071 var foo2 = Foo.new()
3072 var l = Stack(foo1, foo2)
3073 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003074 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003075enddef
3076
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003077" Test for calling methods from three levels of classes
3078def Test_multi_level_method_call()
3079 var lines =<< trim END
3080 vim9script
3081
3082 var A_func1: number = 0
3083 var A_func2: number = 0
3084 var A_func3: number = 0
3085 var B_func2: number = 0
3086 var B_func3: number = 0
3087 var C_func3: number = 0
3088
3089 class A
3090 def Func1()
3091 A_func1 += 1
3092 enddef
3093
3094 def Func2()
3095 A_func2 += 1
3096 enddef
3097
3098 def Func3()
3099 A_func3 += 1
3100 enddef
3101 endclass
3102
3103 class B extends A
3104 def Func2()
3105 B_func2 += 1
3106 enddef
3107
3108 def Func3()
3109 B_func3 += 1
3110 enddef
3111 endclass
3112
3113 class C extends B
3114 def Func3()
3115 C_func3 += 1
3116 enddef
3117 endclass
3118
3119 def A_CallFuncs(a: A)
3120 a.Func1()
3121 a.Func2()
3122 a.Func3()
3123 enddef
3124
3125 def B_CallFuncs(b: B)
3126 b.Func1()
3127 b.Func2()
3128 b.Func3()
3129 enddef
3130
3131 def C_CallFuncs(c: C)
3132 c.Func1()
3133 c.Func2()
3134 c.Func3()
3135 enddef
3136
3137 var cobj = C.new()
3138 A_CallFuncs(cobj)
3139 B_CallFuncs(cobj)
3140 C_CallFuncs(cobj)
3141 assert_equal(3, A_func1)
3142 assert_equal(0, A_func2)
3143 assert_equal(0, A_func3)
3144 assert_equal(3, B_func2)
3145 assert_equal(0, B_func3)
3146 assert_equal(3, C_func3)
3147 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003148 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003149enddef
3150
3151" Test for using members from three levels of classes
3152def Test_multi_level_member_access()
3153 var lines =<< trim END
3154 vim9script
3155
3156 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003157 public this.val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003158 endclass
3159
3160 class B extends A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003161 public this.val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003162 endclass
3163
3164 class C extends B
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003165 public this.val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003166 endclass
3167
3168 def A_members(a: A)
3169 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003170 enddef
3171
3172 def B_members(b: B)
3173 b.val1 += 1
3174 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003175 enddef
3176
3177 def C_members(c: C)
3178 c.val1 += 1
3179 c.val2 += 1
3180 c.val3 += 1
3181 enddef
3182
3183 var cobj = C.new()
3184 A_members(cobj)
3185 B_members(cobj)
3186 C_members(cobj)
3187 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003188 assert_equal(2, cobj.val2)
3189 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003190 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003191 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003192enddef
3193
LemonBoy0ffc17a2023-08-20 18:09:11 +02003194" Test expansion of <stack> with class methods.
3195def Test_stack_expansion_with_methods()
3196 var lines =<< trim END
3197 vim9script
3198
3199 class C
3200 def M1()
3201 F0()
3202 enddef
3203 endclass
3204
3205 def F0()
3206 assert_match('<SNR>\d\+_F\[1\]\.\.C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
3207 enddef
3208
3209 def F()
3210 C.new().M1()
3211 enddef
3212
3213 F()
3214 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003215 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003216enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003217
3218" Test the return type of the new() constructor
3219def Test_new_return_type()
3220 # new() uses the default return type and there is no return statement
3221 var lines =<< trim END
3222 vim9script
3223
3224 class C
3225 this._bufnr: number
3226
3227 def new(this._bufnr)
3228 if !bufexists(this._bufnr)
3229 this._bufnr = -1
3230 endif
3231 enddef
3232 endclass
3233
3234 var c = C.new(12345)
3235 assert_equal('object<C>', typename(c))
3236
3237 var v1: C
3238 v1 = C.new(12345)
3239 assert_equal('object<C>', typename(v1))
3240
3241 def F()
3242 var v2: C
3243 v2 = C.new(12345)
3244 assert_equal('object<C>', typename(v2))
3245 enddef
3246 F()
3247 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003248 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003249
3250 # new() uses the default return type and an empty 'return' statement
3251 lines =<< trim END
3252 vim9script
3253
3254 class C
3255 this._bufnr: number
3256
3257 def new(this._bufnr)
3258 if !bufexists(this._bufnr)
3259 this._bufnr = -1
3260 return
3261 endif
3262 enddef
3263 endclass
3264
3265 var c = C.new(12345)
3266 assert_equal('object<C>', typename(c))
3267
3268 var v1: C
3269 v1 = C.new(12345)
3270 assert_equal('object<C>', typename(v1))
3271
3272 def F()
3273 var v2: C
3274 v2 = C.new(12345)
3275 assert_equal('object<C>', typename(v2))
3276 enddef
3277 F()
3278 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003279 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003280
3281 # new() uses "any" return type and returns "this"
3282 lines =<< trim END
3283 vim9script
3284
3285 class C
3286 this._bufnr: number
3287
3288 def new(this._bufnr): any
3289 if !bufexists(this._bufnr)
3290 this._bufnr = -1
3291 return this
3292 endif
3293 enddef
3294 endclass
3295 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003296 v9.CheckSourceFailure(lines, 'E1365:')
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003297
3298 # new() uses 'Dict' return type and returns a Dict
3299 lines =<< trim END
3300 vim9script
3301
3302 class C
3303 this._state: dict<any>
3304
3305 def new(): dict<any>
3306 this._state = {}
3307 return this._state
3308 enddef
3309 endclass
3310
3311 var c = C.new()
3312 assert_equal('object<C>', typename(c))
3313 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003314 v9.CheckSourceFailure(lines, 'E1365:')
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003315enddef
3316
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003317" Test for checking a member initialization type at run time.
3318def Test_runtime_type_check_for_member_init()
3319 var lines =<< trim END
3320 vim9script
3321
3322 var retnum: bool = false
3323
3324 def F(): any
3325 retnum = !retnum
3326 if retnum
3327 return 1
3328 else
3329 return "hello"
3330 endif
3331 enddef
3332
3333 class C
3334 this._foo: bool = F()
3335 endclass
3336
3337 var c1 = C.new()
3338 var c2 = C.new()
3339 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003340 v9.CheckSourceFailure(lines, 'E1012:')
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003341enddef
3342
3343" Test for locking a variable referring to an object and reassigning to another
3344" object.
3345def Test_object_lockvar()
3346 var lines =<< trim END
3347 vim9script
3348
3349 class C
3350 this.val: number
3351 def new(this.val)
3352 enddef
3353 endclass
3354
3355 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
3356 lockvar 2 some_dict
3357
3358 var current: C
3359 current = some_dict['c']
3360 assert_equal(3, current.val)
3361 current = some_dict['b']
3362 assert_equal(2, current.val)
3363
3364 def F()
3365 current = some_dict['c']
3366 enddef
3367
3368 def G()
3369 current = some_dict['b']
3370 enddef
3371
3372 F()
3373 assert_equal(3, current.val)
3374 G()
3375 assert_equal(2, current.val)
3376 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003377 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003378enddef
3379
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003380" Test for a private object method
3381def Test_private_object_method()
3382 # Try calling a private method using an object (at the script level)
3383 var lines =<< trim END
3384 vim9script
3385
3386 class A
3387 def _Foo(): number
3388 return 1234
3389 enddef
3390 endclass
3391 var a = A.new()
3392 a._Foo()
3393 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003394 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003395
3396 # Try calling a private method using an object (from a def function)
3397 lines =<< trim END
3398 vim9script
3399
3400 class A
3401 def _Foo(): number
3402 return 1234
3403 enddef
3404 endclass
3405 def T()
3406 var a = A.new()
3407 a._Foo()
3408 enddef
3409 T()
3410 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003411 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003412
3413 # Use a private method from another object method (in script context)
3414 lines =<< trim END
3415 vim9script
3416
3417 class A
3418 def _Foo(): number
3419 return 1234
3420 enddef
3421 def Bar(): number
3422 return this._Foo()
3423 enddef
3424 endclass
3425 var a = A.new()
3426 assert_equal(1234, a.Bar())
3427 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003428 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003429
3430 # Use a private method from another object method (def function context)
3431 lines =<< trim END
3432 vim9script
3433
3434 class A
3435 def _Foo(): number
3436 return 1234
3437 enddef
3438 def Bar(): number
3439 return this._Foo()
3440 enddef
3441 endclass
3442 def T()
3443 var a = A.new()
3444 assert_equal(1234, a.Bar())
3445 enddef
3446 T()
3447 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003448 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003449
3450 # Try calling a private method without the "this" prefix
3451 lines =<< trim END
3452 vim9script
3453
3454 class A
3455 def _Foo(): number
3456 return 1234
3457 enddef
3458 def Bar(): number
3459 return _Foo()
3460 enddef
3461 endclass
3462 var a = A.new()
3463 a.Bar()
3464 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003465 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003466
3467 # Try calling a private method using the class name
3468 lines =<< trim END
3469 vim9script
3470
3471 class A
3472 def _Foo(): number
3473 return 1234
3474 enddef
3475 endclass
3476 A._Foo()
3477 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003478 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003479
3480 # Try to use "public" keyword when defining a private method
3481 lines =<< trim END
3482 vim9script
3483
3484 class A
3485 public def _Foo()
3486 enddef
3487 endclass
3488 var a = A.new()
3489 a._Foo()
3490 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003491 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003492
3493 # Define two private methods with the same name
3494 lines =<< trim END
3495 vim9script
3496
3497 class A
3498 def _Foo()
3499 enddef
3500 def _Foo()
3501 enddef
3502 endclass
3503 var a = A.new()
3504 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003505 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003506
3507 # Define a private method and a object method with the same name
3508 lines =<< trim END
3509 vim9script
3510
3511 class A
3512 def _Foo()
3513 enddef
3514 def Foo()
3515 enddef
3516 endclass
3517 var a = A.new()
3518 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003519 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003520
3521 # Define an object method and a private method with the same name
3522 lines =<< trim END
3523 vim9script
3524
3525 class A
3526 def Foo()
3527 enddef
3528 def _Foo()
3529 enddef
3530 endclass
3531 var a = A.new()
3532 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003533 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003534
3535 # Call a public method and a private method from a private method
3536 lines =<< trim END
3537 vim9script
3538
3539 class A
3540 def Foo(): number
3541 return 100
3542 enddef
3543 def _Bar(): number
3544 return 200
3545 enddef
3546 def _Baz()
3547 assert_equal(100, this.Foo())
3548 assert_equal(200, this._Bar())
3549 enddef
3550 def T()
3551 this._Baz()
3552 enddef
3553 endclass
3554 var a = A.new()
3555 a.T()
3556 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003557 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003558
3559 # Try calling a private method from another class
3560 lines =<< trim END
3561 vim9script
3562
3563 class A
3564 def _Foo(): number
3565 return 100
3566 enddef
3567 endclass
3568 class B
3569 def Foo(): number
3570 var a = A.new()
3571 a._Foo()
3572 enddef
3573 endclass
3574 var b = B.new()
3575 b.Foo()
3576 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003577 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003578
3579 # Call a private object method from a child class object method
3580 lines =<< trim END
3581 vim9script
3582 class A
3583 def _Foo(): number
3584 return 1234
3585 enddef
3586 endclass
3587 class B extends A
3588 def Bar()
3589 enddef
3590 endclass
3591 class C extends B
3592 def Baz(): number
3593 return this._Foo()
3594 enddef
3595 endclass
3596 var c = C.new()
3597 assert_equal(1234, c.Baz())
3598 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003599 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003600
3601 # Call a private object method from a child class object
3602 lines =<< trim END
3603 vim9script
3604 class A
3605 def _Foo(): number
3606 return 1234
3607 enddef
3608 endclass
3609 class B extends A
3610 def Bar()
3611 enddef
3612 endclass
3613 class C extends B
3614 def Baz(): number
3615 enddef
3616 endclass
3617 var c = C.new()
3618 assert_equal(1234, c._Foo())
3619 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003620 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003621
3622 # Using "_" prefix in a method name should fail outside of a class
3623 lines =<< trim END
3624 vim9script
3625 def _Foo(): number
3626 return 1234
3627 enddef
3628 var a = _Foo()
3629 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003630 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003631enddef
3632
3633" Test for an private class method
3634def Test_private_class_method()
3635 # Try calling a class private method (at the script level)
3636 var lines =<< trim END
3637 vim9script
3638
3639 class A
3640 static def _Foo(): number
3641 return 1234
3642 enddef
3643 endclass
3644 A._Foo()
3645 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003646 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003647
3648 # Try calling a class private method (from a def function)
3649 lines =<< trim END
3650 vim9script
3651
3652 class A
3653 static def _Foo(): number
3654 return 1234
3655 enddef
3656 endclass
3657 def T()
3658 A._Foo()
3659 enddef
3660 T()
3661 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003662 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003663
3664 # Try calling a class private method using an object (at the script level)
3665 lines =<< trim END
3666 vim9script
3667
3668 class A
3669 static def _Foo(): number
3670 return 1234
3671 enddef
3672 endclass
3673 var a = A.new()
3674 a._Foo()
3675 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003676 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003677
3678 # Try calling a class private method using an object (from a def function)
3679 lines =<< trim END
3680 vim9script
3681
3682 class A
3683 static def _Foo(): number
3684 return 1234
3685 enddef
3686 endclass
3687 def T()
3688 var a = A.new()
3689 a._Foo()
3690 enddef
3691 T()
3692 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003693 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003694
3695 # Use a class private method from an object method
3696 lines =<< trim END
3697 vim9script
3698
3699 class A
3700 static def _Foo(): number
3701 return 1234
3702 enddef
3703 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02003704 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003705 enddef
3706 endclass
3707 var a = A.new()
3708 a.Bar()
3709 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003710 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003711
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02003712 # Use a class private method from another class private method without the
3713 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003714 lines =<< trim END
3715 vim9script
3716
3717 class A
3718 static def _Foo1(): number
3719 return 1234
3720 enddef
3721 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02003722 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003723 enddef
3724 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02003725 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003726 enddef
3727 endclass
3728 var a = A.new()
3729 a.Bar()
3730 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003731 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003732
3733 # Declare a class method and a class private method with the same name
3734 lines =<< trim END
3735 vim9script
3736
3737 class A
3738 static def _Foo()
3739 enddef
3740 static def Foo()
3741 enddef
3742 endclass
3743 var a = A.new()
3744 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003745 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003746
3747 # Try calling a class private method from another class
3748 lines =<< trim END
3749 vim9script
3750
3751 class A
3752 static def _Foo(): number
3753 return 1234
3754 enddef
3755 endclass
3756 class B
3757 def Foo(): number
3758 return A._Foo()
3759 enddef
3760 endclass
3761 var b = B.new()
3762 assert_equal(1234, b.Foo())
3763 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003764 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003765
3766 # Call a private class method from a child class object method
3767 lines =<< trim END
3768 vim9script
3769 class A
3770 static def _Foo(): number
3771 return 1234
3772 enddef
3773 endclass
3774 class B extends A
3775 def Bar()
3776 enddef
3777 endclass
3778 class C extends B
3779 def Baz(): number
3780 return A._Foo()
3781 enddef
3782 endclass
3783 var c = C.new()
3784 assert_equal(1234, c.Baz())
3785 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003786 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003787
3788 # Call a private class method from a child class private class method
3789 lines =<< trim END
3790 vim9script
3791 class A
3792 static def _Foo(): number
3793 return 1234
3794 enddef
3795 endclass
3796 class B extends A
3797 def Bar()
3798 enddef
3799 endclass
3800 class C extends B
3801 static def Baz(): number
3802 return A._Foo()
3803 enddef
3804 endclass
3805 assert_equal(1234, C.Baz())
3806 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003807 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003808
3809 # Call a private class method from a child class object
3810 lines =<< trim END
3811 vim9script
3812 class A
3813 static def _Foo(): number
3814 return 1234
3815 enddef
3816 endclass
3817 class B extends A
3818 def Bar()
3819 enddef
3820 endclass
3821 class C extends B
3822 def Baz(): number
3823 enddef
3824 endclass
3825 var c = C.new()
3826 assert_equal(1234, C._Foo())
3827 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003828 v9.CheckSourceFailure(lines, 'E1325: Method not found on class "C": _Foo')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003829enddef
3830
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02003831" Test for using the return value of a class/object method as a function
3832" argument.
3833def Test_objmethod_funcarg()
3834 var lines =<< trim END
3835 vim9script
3836
3837 class C
3838 def Foo(): string
3839 return 'foo'
3840 enddef
3841 endclass
3842
3843 def Bar(a: number, s: string): string
3844 return s
3845 enddef
3846
3847 def Baz(c: C)
3848 assert_equal('foo', Bar(10, c.Foo()))
3849 enddef
3850
3851 var t = C.new()
3852 Baz(t)
3853 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003854 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02003855
3856 lines =<< trim END
3857 vim9script
3858
3859 class C
3860 static def Foo(): string
3861 return 'foo'
3862 enddef
3863 endclass
3864
3865 def Bar(a: number, s: string): string
3866 return s
3867 enddef
3868
3869 def Baz()
3870 assert_equal('foo', Bar(10, C.Foo()))
3871 enddef
3872
3873 Baz()
3874 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003875 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02003876enddef
3877
Ernie Raelcf138d42023-09-06 20:45:03 +02003878def Test_static_inheritence()
3879 # subclasses get their own static copy
3880 var lines =<< trim END
3881 vim9script
3882
3883 class A
3884 static _svar: number
3885 this._mvar: number
3886 def new()
3887 _svar = 1
3888 this._mvar = 101
3889 enddef
3890 def AccessObject(): number
3891 return this._mvar
3892 enddef
3893 def AccessStaticThroughObject(): number
3894 return _svar
3895 enddef
3896 endclass
3897
3898 class B extends A
3899 def new()
Ernie Raelcf138d42023-09-06 20:45:03 +02003900 this._mvar = 102
3901 enddef
3902 endclass
3903
3904 class C extends B
3905 def new()
Ernie Raelcf138d42023-09-06 20:45:03 +02003906 this._mvar = 103
3907 enddef
3908
3909 def AccessPrivateStaticThroughClassName(): number
3910 assert_equal(1, A._svar)
Ernie Raelcf138d42023-09-06 20:45:03 +02003911 return 444
3912 enddef
3913 endclass
3914
3915 var oa = A.new()
3916 var ob = B.new()
3917 var oc = C.new()
3918 assert_equal(101, oa.AccessObject())
3919 assert_equal(102, ob.AccessObject())
3920 assert_equal(103, oc.AccessObject())
3921
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003922 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access private member: _svar')
Ernie Raelcf138d42023-09-06 20:45:03 +02003923
3924 # verify object properly resolves to correct static
3925 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003926 assert_equal(1, ob.AccessStaticThroughObject())
3927 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02003928 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003929 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02003930enddef
3931
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02003932" Test for declaring duplicate object and class members
3933def Test_dup_member_variable()
3934 # Duplicate member variable
3935 var lines =<< trim END
3936 vim9script
3937 class C
3938 this.val = 10
3939 this.val = 20
3940 endclass
3941 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003942 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02003943
3944 # Duplicate private member variable
3945 lines =<< trim END
3946 vim9script
3947 class C
3948 this._val = 10
3949 this._val = 20
3950 endclass
3951 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003952 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _val')
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02003953
3954 # Duplicate public member variable
3955 lines =<< trim END
3956 vim9script
3957 class C
3958 public this.val = 10
3959 public this.val = 20
3960 endclass
3961 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003962 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02003963
3964 # Duplicate private member variable
3965 lines =<< trim END
3966 vim9script
3967 class C
3968 this.val = 10
3969 this._val = 20
3970 endclass
3971 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003972 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _val')
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02003973
3974 # Duplicate public and private member variable
3975 lines =<< trim END
3976 vim9script
3977 class C
3978 this._val = 20
3979 public this.val = 10
3980 endclass
3981 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003982 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02003983
3984 # Duplicate class member variable
3985 lines =<< trim END
3986 vim9script
3987 class C
3988 static s: string = "abc"
3989 static _s: string = "def"
3990 endclass
3991 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003992 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _s')
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02003993
3994 # Duplicate public and private class member variable
3995 lines =<< trim END
3996 vim9script
3997 class C
3998 public static s: string = "abc"
3999 static _s: string = "def"
4000 endclass
4001 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004002 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _s')
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004003
4004 # Duplicate class and object member variable
4005 lines =<< trim END
4006 vim9script
4007 class C
4008 static val = 10
4009 this.val = 20
4010 def new()
4011 enddef
4012 endclass
4013 var c = C.new()
4014 assert_equal(10, C.val)
4015 assert_equal(20, c.val)
4016 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004017 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004018
4019 # Duplicate object member variable in a derived class
4020 lines =<< trim END
4021 vim9script
4022 class A
4023 this.val = 10
4024 endclass
4025 class B extends A
4026 endclass
4027 class C extends B
4028 this.val = 20
4029 endclass
4030 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004031 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004032
4033 # Duplicate object private member variable in a derived class
4034 lines =<< trim END
4035 vim9script
4036 class A
4037 this._val = 10
4038 endclass
4039 class B extends A
4040 endclass
4041 class C extends B
4042 this._val = 20
4043 endclass
4044 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004045 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _val')
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004046
4047 # Duplicate object private member variable in a derived class
4048 lines =<< trim END
4049 vim9script
4050 class A
4051 this.val = 10
4052 endclass
4053 class B extends A
4054 endclass
4055 class C extends B
4056 this._val = 20
4057 endclass
4058 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004059 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _val')
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004060
4061 # Duplicate object member variable in a derived class
4062 lines =<< trim END
4063 vim9script
4064 class A
4065 this._val = 10
4066 endclass
4067 class B extends A
4068 endclass
4069 class C extends B
4070 this.val = 20
4071 endclass
4072 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004073 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004074
4075 # Two member variables with a common prefix
4076 lines =<< trim END
4077 vim9script
4078 class A
4079 public static svar2: number
4080 public static svar: number
4081 endclass
4082 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004083 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004084enddef
4085
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004086" Test for accessing a private member outside a class in a def function
4087def Test_private_member_access_outside_class()
4088 # private object member variable
4089 var lines =<< trim END
4090 vim9script
4091 class A
4092 this._val = 10
4093 def GetVal(): number
4094 return this._val
4095 enddef
4096 endclass
4097 def T()
4098 var a = A.new()
4099 a._val = 20
4100 enddef
4101 T()
4102 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004103 v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _val')
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004104
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004105 # access a non-existing private object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004106 lines =<< trim END
4107 vim9script
4108 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004109 this._val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004110 endclass
4111 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004112 var a = A.new()
4113 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004114 enddef
4115 T()
4116 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004117 v9.CheckSourceFailure(lines, 'E1326: Member not found on object "A": _a')
Ernie Rael18143d32023-09-04 22:30:41 +02004118
4119 # private static member variable
4120 lines =<< trim END
4121 vim9script
4122 class A
4123 static _val = 10
4124 endclass
4125 def T()
4126 var a = A.new()
4127 var x = a._val
4128 enddef
4129 T()
4130 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004131 v9.CheckSourceFailure(lines, 'E1375: Class member "_val" accessible only using class "A"')
Ernie Rael18143d32023-09-04 22:30:41 +02004132
4133 # private static member variable
4134 lines =<< trim END
4135 vim9script
4136 class A
4137 static _val = 10
4138 endclass
4139 def T()
4140 var a = A.new()
4141 a._val = 3
4142 enddef
4143 T()
4144 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004145 v9.CheckSourceFailure(lines, 'E1375: Class member "_val" accessible only using class "A"')
Ernie Rael18143d32023-09-04 22:30:41 +02004146
4147 # private static class variable
4148 lines =<< trim END
4149 vim9script
4150 class A
4151 static _val = 10
4152 endclass
4153 def T()
4154 var x = A._val
4155 enddef
4156 T()
4157 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004158 v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _val')
Ernie Rael18143d32023-09-04 22:30:41 +02004159
4160 # private static class variable
4161 lines =<< trim END
4162 vim9script
4163 class A
4164 static _val = 10
4165 endclass
4166 def T()
4167 A._val = 3
4168 enddef
4169 T()
4170 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004171 v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _val')
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004172enddef
4173
4174" Test for changing the member access of an interface in a implementation class
4175def Test_change_interface_member_access()
4176 var lines =<< trim END
4177 vim9script
4178 interface A
4179 public this.val: number
4180 endinterface
4181 class B implements A
4182 this.val = 10
4183 endclass
4184 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004185 v9.CheckSourceFailure(lines, 'E1367: Access level of member "val" of interface "A" is different')
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004186
4187 lines =<< trim END
4188 vim9script
4189 interface A
4190 this.val: number
4191 endinterface
4192 class B implements A
4193 public this.val = 10
4194 endclass
4195 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004196 v9.CheckSourceFailure(lines, 'E1367: Access level of member "val" of interface "A" is different')
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004197enddef
4198
4199" Test for trying to change a readonly member from a def function
4200def Test_readonly_member_change_in_def_func()
4201 var lines =<< trim END
4202 vim9script
4203 class A
4204 this.val: number
4205 endclass
4206 def T()
4207 var a = A.new()
4208 a.val = 20
4209 enddef
4210 T()
4211 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004212 v9.CheckSourceFailure(lines, 'E46: Cannot change read-only variable "val"')
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004213enddef
4214
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004215" Test for reading and writing a class member from a def function
4216def Test_modify_class_member_from_def_function()
4217 var lines =<< trim END
4218 vim9script
4219 class A
4220 this.var1: number = 10
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02004221 public static var2: list<number> = [1, 2]
4222 public static var3: dict<number> = {a: 1, b: 2}
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004223 static _priv_var4: number = 40
4224 endclass
4225 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02004226 assert_equal([1, 2], A.var2)
4227 assert_equal({a: 1, b: 2}, A.var3)
4228 A.var2 = [3, 4]
4229 A.var3 = {c: 3, d: 4}
4230 assert_equal([3, 4], A.var2)
4231 assert_equal({c: 3, d: 4}, A.var3)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004232 assert_fails('echo A._priv_var4', 'E1333: Cannot access private member: _priv_var4')
4233 enddef
4234 T()
4235 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004236 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004237enddef
4238
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004239" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004240def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004241 var lines =<< trim END
4242 vim9script
4243 class A
4244 public static svar1: list<number> = [1]
4245 public static svar2: list<number> = [2]
4246 endclass
4247
4248 A.svar1->add(3)
4249 A.svar2->add(4)
4250 assert_equal([1, 3], A.svar1)
4251 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004252
4253 def Foo()
4254 A.svar1->add(7)
4255 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004256 assert_equal([1, 3, 7], A.svar1)
4257 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004258 enddef
4259 Foo()
4260 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004261 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004262
4263 # Cannot read from a class variable using an object in script context
4264 lines =<< trim END
4265 vim9script
4266 class A
4267 public this.var1: number
4268 public static svar2: list<number> = [1]
4269 endclass
4270
4271 var a = A.new()
4272 echo a.svar2
4273 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004274 v9.CheckSourceFailure(lines, 'E1375: Class member "svar2" accessible only using class "A"')
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004275
4276 # Cannot write to a class variable using an object in script context
4277 lines =<< trim END
4278 vim9script
4279 class A
4280 public this.var1: number
4281 public static svar2: list<number> = [1]
4282 endclass
4283
4284 var a = A.new()
4285 a.svar2 = [2]
4286 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004287 v9.CheckSourceFailure(lines, 'E1375: Class member "svar2" accessible only using class "A"')
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004288
4289 # Cannot read from a class variable using an object in def method context
4290 lines =<< trim END
4291 vim9script
4292 class A
4293 public this.var1: number
4294 public static svar2: list<number> = [1]
4295 endclass
4296
4297 def T()
4298 var a = A.new()
4299 echo a.svar2
4300 enddef
4301 T()
4302 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004303 v9.CheckSourceFailure(lines, 'E1375: Class member "svar2" accessible only using class "A"')
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004304
4305 # Cannot write to a class variable using an object in def method context
4306 lines =<< trim END
4307 vim9script
4308 class A
4309 public this.var1: number
4310 public static svar2: list<number> = [1]
4311 endclass
4312
4313 def T()
4314 var a = A.new()
4315 a.svar2 = [2]
4316 enddef
4317 T()
4318 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004319 v9.CheckSourceFailure(lines, 'E1375: Class member "svar2" accessible only using class "A"')
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004320enddef
4321
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02004322" Test for using a interface method using a child object
4323def Test_interface_method_from_child()
4324 var lines =<< trim END
4325 vim9script
4326
4327 interface A
4328 def Foo(): string
4329 endinterface
4330
4331 class B implements A
4332 def Foo(): string
4333 return 'foo'
4334 enddef
4335 endclass
4336
4337 class C extends B
4338 def Bar(): string
4339 return 'bar'
4340 enddef
4341 endclass
4342
4343 def T1(a: A)
4344 assert_equal('foo', a.Foo())
4345 enddef
4346
4347 def T2(b: B)
4348 assert_equal('foo', b.Foo())
4349 enddef
4350
4351 var c = C.new()
4352 T1(c)
4353 T2(c)
4354 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004355 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02004356enddef
4357
4358" Test for using an interface method using a child object when it is overridden
4359" by the child class.
4360" FIXME: This test fails.
4361" def Test_interface_overridden_method_from_child()
4362" var lines =<< trim END
4363" vim9script
4364"
4365" interface A
4366" def Foo(): string
4367" endinterface
4368"
4369" class B implements A
4370" def Foo(): string
4371" return 'b-foo'
4372" enddef
4373" endclass
4374"
4375" class C extends B
4376" def Bar(): string
4377" return 'bar'
4378" enddef
4379" def Foo(): string
4380" return 'c-foo'
4381" enddef
4382" endclass
4383"
4384" def T1(a: A)
4385" assert_equal('c-foo', a.Foo())
4386" enddef
4387"
4388" def T2(b: B)
4389" assert_equal('c-foo', b.Foo())
4390" enddef
4391"
4392" var c = C.new()
4393" T1(c)
4394" T2(c)
4395" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004396" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02004397" enddef
4398
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004399" Test for abstract methods
4400def Test_abstract_method()
4401 # Use two abstract methods
4402 var lines =<< trim END
4403 vim9script
4404 abstract class A
4405 def M1(): number
4406 return 10
4407 enddef
4408 abstract def M2(): number
4409 abstract def M3(): number
4410 endclass
4411 class B extends A
4412 def M2(): number
4413 return 20
4414 enddef
4415 def M3(): number
4416 return 30
4417 enddef
4418 endclass
4419 var b = B.new()
4420 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
4421 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004422 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004423
4424 # Don't define an abstract method
4425 lines =<< trim END
4426 vim9script
4427 abstract class A
4428 abstract def Foo()
4429 endclass
4430 class B extends A
4431 endclass
4432 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004433 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented')
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004434
4435 # Use abstract method in a concrete class
4436 lines =<< trim END
4437 vim9script
4438 class A
4439 abstract def Foo()
4440 endclass
4441 class B extends A
4442 endclass
4443 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004444 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class')
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004445
4446 # Use abstract method in an interface
4447 lines =<< trim END
4448 vim9script
4449 interface A
4450 abstract def Foo()
4451 endinterface
4452 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02004453 def Foo()
4454 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004455 endclass
4456 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02004457 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004458
4459 # Abbreviate the "abstract" keyword
4460 lines =<< trim END
4461 vim9script
4462 class A
4463 abs def Foo()
4464 endclass
4465 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004466 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()')
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004467
4468 # Use "abstract" with a member variable
4469 lines =<< trim END
4470 vim9script
4471 abstract class A
4472 abstract this.val = 10
4473 endclass
4474 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004475 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def" or "static"')
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004476
4477 # Use a static abstract method
4478 lines =<< trim END
4479 vim9script
4480 abstract class A
4481 abstract static def Foo(): number
4482 endclass
4483 class B extends A
4484 static def Foo(): number
4485 return 4
4486 enddef
4487 endclass
4488 assert_equal(4, B.Foo())
4489 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004490 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004491
4492 # Type mismatch between abstract method and concrete method
4493 lines =<< trim END
4494 vim9script
4495 abstract class A
4496 abstract def Foo(a: string, b: number): list<number>
4497 endclass
4498 class B extends A
4499 def Foo(a: number, b: string): list<string>
4500 return []
4501 enddef
4502 endclass
4503 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02004504 v9.CheckSourceFailure(lines, 'E1383: Method "Foo": type mismatch, expected func(string, number): list<number> but got func(number, string): list<string>')
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004505
4506 # Use an abstract class to invoke an abstract method
4507 # FIXME: This should fail
4508 lines =<< trim END
4509 vim9script
4510 abstract class A
4511 abstract static def Foo()
4512 endclass
4513 A.Foo()
4514 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004515 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004516
4517 # Invoke an abstract method from a def function
4518 lines =<< trim END
4519 vim9script
4520 abstract class A
4521 abstract def Foo(): list<number>
4522 endclass
4523 class B extends A
4524 def Foo(): list<number>
4525 return [3, 5]
4526 enddef
4527 endclass
4528 def Bar(c: B)
4529 assert_equal([3, 5], c.Foo())
4530 enddef
4531 var b = B.new()
4532 Bar(b)
4533 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004534 v9.CheckSourceSuccess(lines)
4535enddef
4536
4537" Test for calling a class method from a subclass
4538def Test_class_method_call_from_subclass()
4539 # class method call from a subclass
4540 var lines =<< trim END
4541 vim9script
4542
4543 class A
4544 static def Foo()
4545 echo "foo"
4546 enddef
4547 endclass
4548
4549 class B extends A
4550 def Bar()
4551 Foo()
4552 enddef
4553 endclass
4554
4555 var b = B.new()
4556 b.Bar()
4557 END
4558 v9.CheckSourceFailure(lines, 'E1374: Class member "Foo" accessible only inside class "A"')
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004559enddef
4560
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02004561" Test for calling a class method using an object in a def function context and
4562" script context.
4563def Test_class_method_call_using_object()
4564 # script context
4565 var lines =<< trim END
4566 vim9script
4567 class A
4568 static def Foo(): list<string>
4569 return ['a', 'b']
4570 enddef
4571 def Bar()
4572 assert_equal(['a', 'b'], A.Foo())
4573 assert_equal(['a', 'b'], Foo())
4574 enddef
4575 endclass
4576
4577 def T()
4578 assert_equal(['a', 'b'], A.Foo())
4579 var t_a = A.new()
4580 t_a.Bar()
4581 enddef
4582
4583 assert_equal(['a', 'b'], A.Foo())
4584 var a = A.new()
4585 a.Bar()
4586 T()
4587 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004588 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02004589
4590 # script context
4591 lines =<< trim END
4592 vim9script
4593 class A
4594 static def Foo(): string
4595 return 'foo'
4596 enddef
4597 endclass
4598
4599 var a = A.new()
4600 assert_equal('foo', a.Foo())
4601 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004602 v9.CheckSourceFailure(lines, 'E1375: Class member "Foo" accessible only using class "A"')
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02004603
4604 # def function context
4605 lines =<< trim END
4606 vim9script
4607 class A
4608 static def Foo(): string
4609 return 'foo'
4610 enddef
4611 endclass
4612
4613 def T()
4614 var a = A.new()
4615 assert_equal('foo', a.Foo())
4616 enddef
4617 T()
4618 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004619 v9.CheckSourceFailure(lines, 'E1375: Class member "Foo" accessible only using class "A"')
4620enddef
4621
4622def Test_class_variable()
4623 var lines =<< trim END
4624 vim9script
4625
4626 class A
4627 public static val: number = 10
4628 static def ClassFunc()
4629 assert_equal(10, val)
4630 enddef
4631 def ObjFunc()
4632 assert_equal(10, val)
4633 enddef
4634 endclass
4635
4636 class B extends A
4637 endclass
4638
4639 assert_equal(10, A.val)
4640 A.ClassFunc()
4641 var a = A.new()
4642 a.ObjFunc()
4643 var b = B.new()
4644 b.ObjFunc()
4645
4646 def T1(a1: A)
4647 a1.ObjFunc()
4648 A.ClassFunc()
4649 enddef
4650 T1(b)
4651
4652 A.val = 20
4653 assert_equal(20, A.val)
4654 END
4655 v9.CheckSourceSuccess(lines)
4656
4657 # Modifying a parent class variable from a child class method
4658 lines =<< trim END
4659 vim9script
4660
4661 class A
4662 static val: number = 10
4663 endclass
4664
4665 class B extends A
4666 static def ClassFunc()
4667 val = 20
4668 enddef
4669 endclass
4670 B.ClassFunc()
4671 END
4672 v9.CheckSourceFailure(lines, 'E1374: Class member "val" accessible only inside class "A"')
4673
4674 # Reading a parent class variable from a child class method
4675 lines =<< trim END
4676 vim9script
4677
4678 class A
4679 static val: number = 10
4680 endclass
4681
4682 class B extends A
4683 static def ClassFunc()
4684 var i = val
4685 enddef
4686 endclass
4687 B.ClassFunc()
4688 END
4689 v9.CheckSourceFailure(lines, 'E1374: Class member "val" accessible only inside class "A"')
4690
4691 # Modifying a parent class variable from a child object method
4692 lines =<< trim END
4693 vim9script
4694
4695 class A
4696 static val: number = 10
4697 endclass
4698
4699 class B extends A
4700 def ObjFunc()
4701 val = 20
4702 enddef
4703 endclass
4704 var b = B.new()
4705 b.ObjFunc()
4706 END
4707 v9.CheckSourceFailure(lines, 'E1374: Class member "val" accessible only inside class "A"')
4708
4709 # Reading a parent class variable from a child object method
4710 lines =<< trim END
4711 vim9script
4712
4713 class A
4714 static val: number = 10
4715 endclass
4716
4717 class B extends A
4718 def ObjFunc()
4719 var i = val
4720 enddef
4721 endclass
4722 var b = B.new()
4723 b.ObjFunc()
4724 END
4725 v9.CheckSourceFailure(lines, 'E1374: Class member "val" accessible only inside class "A"')
4726
4727 # Modifying a class variable using an object at script level
4728 lines =<< trim END
4729 vim9script
4730
4731 class A
4732 static val: number = 10
4733 endclass
4734 var a = A.new()
4735 a.val = 20
4736 END
4737 v9.CheckSourceFailure(lines, 'E1375: Class member "val" accessible only using class "A"')
4738
4739 # Reading a class variable using an object at script level
4740 lines =<< trim END
4741 vim9script
4742
4743 class A
4744 static val: number = 10
4745 endclass
4746 var a = A.new()
4747 var i = a.val
4748 END
4749 v9.CheckSourceFailure(lines, 'E1375: Class member "val" accessible only using class "A"')
4750
4751 # Modifying a class variable using an object at function level
4752 lines =<< trim END
4753 vim9script
4754
4755 class A
4756 static val: number = 10
4757 endclass
4758
4759 def T()
4760 var a = A.new()
4761 a.val = 20
4762 enddef
4763 T()
4764 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004765 v9.CheckSourceFailure(lines, 'E1375: Class member "val" accessible only using class "A"')
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004766
4767 # Reading a class variable using an object at function level
4768 lines =<< trim END
4769 vim9script
4770
4771 class A
4772 static val: number = 10
4773 endclass
4774 def T()
4775 var a = A.new()
4776 var i = a.val
4777 enddef
4778 T()
4779 END
4780 v9.CheckSourceFailure(lines, 'E1375: Class member "val" accessible only using class "A"')
4781enddef
4782
4783" Test for using a duplicate class method and class variable in a child class
4784def Test_dup_class_member()
4785 # duplicate class variable, class method and overridden object method
4786 var lines =<< trim END
4787 vim9script
4788 class A
4789 static sval = 100
4790 static def Check()
4791 assert_equal(100, sval)
4792 enddef
4793 def GetVal(): number
4794 return sval
4795 enddef
4796 endclass
4797
4798 class B extends A
4799 static sval = 200
4800 static def Check()
4801 assert_equal(200, sval)
4802 enddef
4803 def GetVal(): number
4804 return sval
4805 enddef
4806 endclass
4807
4808 def T1(aa: A): number
4809 return aa.GetVal()
4810 enddef
4811
4812 def T2(bb: B): number
4813 return bb.GetVal()
4814 enddef
4815
4816 assert_equal(100, A.sval)
4817 assert_equal(200, B.sval)
4818 var a = A.new()
4819 assert_equal(100, a.GetVal())
4820 var b = B.new()
4821 assert_equal(200, b.GetVal())
4822 assert_equal(200, T1(b))
4823 assert_equal(200, T2(b))
4824 END
4825 v9.CheckSourceSuccess(lines)
4826
4827 # duplicate class variable and class method
4828 lines =<< trim END
4829 vim9script
4830 class A
4831 static sval = 100
4832 static def Check()
4833 assert_equal(100, sval)
4834 enddef
4835 def GetVal(): number
4836 return sval
4837 enddef
4838 endclass
4839
4840 class B extends A
4841 static sval = 200
4842 static def Check()
4843 assert_equal(200, sval)
4844 enddef
4845 endclass
4846
4847 def T1(aa: A): number
4848 return aa.GetVal()
4849 enddef
4850
4851 def T2(bb: B): number
4852 return bb.GetVal()
4853 enddef
4854
4855 assert_equal(100, A.sval)
4856 assert_equal(200, B.sval)
4857 var a = A.new()
4858 assert_equal(100, a.GetVal())
4859 var b = B.new()
4860 assert_equal(100, b.GetVal())
4861 assert_equal(100, T1(b))
4862 assert_equal(100, T2(b))
4863 END
4864 v9.CheckSourceSuccess(lines)
4865enddef
4866
4867" Test for calling an instance method using the class
4868def Test_instance_method_call_using_class()
4869 # Invoke an object method using a class in script context
4870 var lines =<< trim END
4871 vim9script
4872 class A
4873 def Foo()
4874 echo "foo"
4875 enddef
4876 endclass
4877 A.Foo()
4878 END
4879 v9.CheckSourceFailure(lines, 'E1376: Object member "Foo" accessible only using class "A" object')
4880
4881 # Invoke an object method using a class in def function context
4882 lines =<< trim END
4883 vim9script
4884 class A
4885 def Foo()
4886 echo "foo"
4887 enddef
4888 endclass
4889 def T()
4890 A.Foo()
4891 enddef
4892 T()
4893 END
4894 v9.CheckSourceFailure(lines, 'E1376: Object member "Foo" accessible only using class "A" object')
4895enddef
4896
4897" Test for duplicate class method and instance method
4898def Test_dup_classmethod_objmethod()
4899 # Duplicate instance method
4900 var lines =<< trim END
4901 vim9script
4902 class A
4903 static def Foo()
4904 enddef
4905 def Foo()
4906 enddef
4907 endclass
4908 END
4909 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo')
4910
4911 # Duplicate private instance method
4912 lines =<< trim END
4913 vim9script
4914 class A
4915 static def Foo()
4916 enddef
4917 def _Foo()
4918 enddef
4919 endclass
4920 END
4921 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
4922
4923 # Duplicate class method
4924 lines =<< trim END
4925 vim9script
4926 class A
4927 def Foo()
4928 enddef
4929 static def Foo()
4930 enddef
4931 endclass
4932 END
4933 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo')
4934
4935 # Duplicate private class method
4936 lines =<< trim END
4937 vim9script
4938 class A
4939 def Foo()
4940 enddef
4941 static def _Foo()
4942 enddef
4943 endclass
4944 END
4945 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
4946
4947 # Duplicate private class and object method
4948 lines =<< trim END
4949 vim9script
4950 class A
4951 def _Foo()
4952 enddef
4953 static def _Foo()
4954 enddef
4955 endclass
4956 END
4957 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
4958enddef
4959
4960" Test for an instance method access level comparison with parent instance
4961" methods.
4962def Test_instance_method_access_level()
4963 # Private method in subclass
4964 var lines =<< trim END
4965 vim9script
4966 class A
4967 def Foo()
4968 enddef
4969 endclass
4970 class B extends A
4971 endclass
4972 class C extends B
4973 def _Foo()
4974 enddef
4975 endclass
4976 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02004977 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"')
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004978
4979 # Public method in subclass
4980 lines =<< trim END
4981 vim9script
4982 class A
4983 def _Foo()
4984 enddef
4985 endclass
4986 class B extends A
4987 endclass
4988 class C extends B
4989 def Foo()
4990 enddef
4991 endclass
4992 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02004993 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"')
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004994enddef
4995
4996def Test_extend_empty_class()
4997 var lines =<< trim END
4998 vim9script
4999 class A
5000 endclass
5001 class B extends A
5002 endclass
5003 class C extends B
5004 public static rw_class_var = 1
5005 public this.rw_obj_var = 2
5006 static def ClassMethod(): number
5007 return 3
5008 enddef
5009 def ObjMethod(): number
5010 return 4
5011 enddef
5012 endclass
5013 assert_equal(1, C.rw_class_var)
5014 assert_equal(3, C.ClassMethod())
5015 var c = C.new()
5016 assert_equal(2, c.rw_obj_var)
5017 assert_equal(4, c.ObjMethod())
5018 END
5019 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005020enddef
5021
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005022" A interface cannot have a static variable or a static method or a private
5023" variable or a private method
5024def Test_interface_with_unsupported_members()
5025 var lines =<< trim END
5026 vim9script
5027 interface A
5028 static num: number
5029 endinterface
5030 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005031 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface')
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005032
5033 lines =<< trim END
5034 vim9script
5035 interface A
5036 static _num: number
5037 endinterface
5038 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005039 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface')
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005040
5041 lines =<< trim END
5042 vim9script
5043 interface A
5044 public static num: number
5045 endinterface
5046 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005047 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface')
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005048
5049 lines =<< trim END
5050 vim9script
5051 interface A
5052 public static _num: number
5053 endinterface
5054 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005055 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface')
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005056
5057 lines =<< trim END
5058 vim9script
5059 interface A
5060 static def Foo(d: dict<any>): list<string>
5061 endinterface
5062 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005063 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface')
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005064
5065 lines =<< trim END
5066 vim9script
5067 interface A
5068 static def _Foo(d: dict<any>): list<string>
5069 endinterface
5070 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005071 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface')
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005072
5073 lines =<< trim END
5074 vim9script
5075 interface A
5076 this._Foo: list<string>
5077 endinterface
5078 END
5079 v9.CheckSourceFailure(lines, 'E1379: Private variable not supported in an interface')
5080
5081 lines =<< trim END
5082 vim9script
5083 interface A
5084 def _Foo(d: dict<any>): list<string>
5085 endinterface
5086 END
5087 v9.CheckSourceFailure(lines, 'E1380: Private method not supported in an interface')
5088enddef
5089
5090" Test for extending an interface
5091def Test_extend_interface()
5092 var lines =<< trim END
5093 vim9script
5094 interface A
5095 this.var1: list<string>
5096 def Foo()
5097 endinterface
5098 interface B extends A
5099 public this.var2: dict<string>
5100 def Bar()
5101 endinterface
5102 class C implements A, B
5103 this.var1 = [1, 2]
5104 def Foo()
5105 enddef
5106 public this.var2 = {a: '1'}
5107 def Bar()
5108 enddef
5109 endclass
5110 END
5111 v9.CheckSourceSuccess(lines)
5112
5113 lines =<< trim END
5114 vim9script
5115 interface A
5116 def Foo()
5117 endinterface
5118 interface B extends A
5119 public this.var2: dict<string>
5120 endinterface
5121 class C implements A, B
5122 public this.var2 = {a: '1'}
5123 endclass
5124 END
5125 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented')
5126
5127 lines =<< trim END
5128 vim9script
5129 interface A
5130 def Foo()
5131 endinterface
5132 interface B extends A
5133 public this.var2: dict<string>
5134 endinterface
5135 class C implements A, B
5136 def Foo()
5137 enddef
5138 endclass
5139 END
5140 v9.CheckSourceFailure(lines, 'E1348: Member "var2" of interface "B" is not implemented')
5141
5142 # interface cannot extend a class
5143 lines =<< trim END
5144 vim9script
5145 class A
5146 endclass
5147 interface B extends A
5148 endinterface
5149 END
5150 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A')
5151
5152 # class cannot extend an interface
5153 lines =<< trim END
5154 vim9script
5155 interface A
5156 endinterface
5157 class B extends A
5158 endclass
5159 END
5160 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A')
5161
5162 # interface cannot implement another interface
5163 lines =<< trim END
5164 vim9script
5165 interface A
5166 endinterface
5167 interface B implements A
5168 endinterface
5169 END
5170 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"')
5171
5172 # interface cannot extend multiple interfaces
5173 lines =<< trim END
5174 vim9script
5175 interface A
5176 endinterface
5177 interface B
5178 endinterface
5179 interface C extends A, B
5180 endinterface
5181 END
5182 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B')
5183
5184 # Variable type in an extended interface is of different type
5185 lines =<< trim END
5186 vim9script
5187 interface A
5188 this.val1: number
5189 endinterface
5190 interface B extends A
5191 this.val2: string
5192 endinterface
5193 interface C extends B
5194 this.val1: string
5195 this.val2: number
5196 endinterface
5197 END
5198 v9.CheckSourceFailure(lines, 'E1382: Member "val1": type mismatch, expected number but got string')
5199enddef
5200
5201" Test for a child class implementing an interface when some of the methods are
5202" defined in the parent class.
5203def Test_child_class_implements_interface()
5204 var lines =<< trim END
5205 vim9script
5206
5207 interface Intf
5208 def F1(): list<list<number>>
5209 def F2(): list<list<number>>
5210 def F3(): list<list<number>>
5211 this.var1: list<dict<number>>
5212 this.var2: list<dict<number>>
5213 this.var3: list<dict<number>>
5214 endinterface
5215
5216 class A
5217 def A1()
5218 enddef
5219 def F3(): list<list<number>>
5220 return [[3]]
5221 enddef
5222 this.v1: list<list<number>> = [[0]]
5223 this.var3 = [{c: 30}]
5224 endclass
5225
5226 class B extends A
5227 def B1()
5228 enddef
5229 def F2(): list<list<number>>
5230 return [[2]]
5231 enddef
5232 this.v2: list<list<number>> = [[0]]
5233 this.var2 = [{b: 20}]
5234 endclass
5235
5236 class C extends B implements Intf
5237 def C1()
5238 enddef
5239 def F1(): list<list<number>>
5240 return [[1]]
5241 enddef
5242 this.v3: list<list<number>> = [[0]]
5243 this.var1 = [{a: 10}]
5244 endclass
5245
5246 def T(if: Intf)
5247 assert_equal([[1]], if.F1())
5248 assert_equal([[2]], if.F2())
5249 assert_equal([[3]], if.F3())
5250 assert_equal([{a: 10}], if.var1)
5251 assert_equal([{b: 20}], if.var2)
5252 assert_equal([{c: 30}], if.var3)
5253 enddef
5254
5255 var c = C.new()
5256 T(c)
5257 assert_equal([[1]], c.F1())
5258 assert_equal([[2]], c.F2())
5259 assert_equal([[3]], c.F3())
5260 assert_equal([{a: 10}], c.var1)
5261 assert_equal([{b: 20}], c.var2)
5262 assert_equal([{c: 30}], c.var3)
5263 END
5264 v9.CheckSourceSuccess(lines)
5265
5266 # One of the interface methods is not found
5267 lines =<< trim END
5268 vim9script
5269
5270 interface Intf
5271 def F1()
5272 def F2()
5273 def F3()
5274 endinterface
5275
5276 class A
5277 def A1()
5278 enddef
5279 endclass
5280
5281 class B extends A
5282 def B1()
5283 enddef
5284 def F2()
5285 enddef
5286 endclass
5287
5288 class C extends B implements Intf
5289 def C1()
5290 enddef
5291 def F1()
5292 enddef
5293 endclass
5294 END
5295 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented')
5296
5297 # One of the interface methods is of different type
5298 lines =<< trim END
5299 vim9script
5300
5301 interface Intf
5302 def F1()
5303 def F2()
5304 def F3()
5305 endinterface
5306
5307 class A
5308 def F3(): number
5309 return 0
5310 enddef
5311 def A1()
5312 enddef
5313 endclass
5314
5315 class B extends A
5316 def B1()
5317 enddef
5318 def F2()
5319 enddef
5320 endclass
5321
5322 class C extends B implements Intf
5323 def C1()
5324 enddef
5325 def F1()
5326 enddef
5327 endclass
5328 END
5329 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number')
5330
5331 # One of the interface variables is not present
5332 lines =<< trim END
5333 vim9script
5334
5335 interface Intf
5336 this.var1: list<dict<number>>
5337 this.var2: list<dict<number>>
5338 this.var3: list<dict<number>>
5339 endinterface
5340
5341 class A
5342 this.v1: list<list<number>> = [[0]]
5343 endclass
5344
5345 class B extends A
5346 this.v2: list<list<number>> = [[0]]
5347 this.var2 = [{b: 20}]
5348 endclass
5349
5350 class C extends B implements Intf
5351 this.v3: list<list<number>> = [[0]]
5352 this.var1 = [{a: 10}]
5353 endclass
5354 END
5355 v9.CheckSourceFailure(lines, 'E1348: Member "var3" of interface "Intf" is not implemented')
5356
5357 # One of the interface variables is of different type
5358 lines =<< trim END
5359 vim9script
5360
5361 interface Intf
5362 this.var1: list<dict<number>>
5363 this.var2: list<dict<number>>
5364 this.var3: list<dict<number>>
5365 endinterface
5366
5367 class A
5368 this.v1: list<list<number>> = [[0]]
5369 this.var3: list<dict<string>>
5370 endclass
5371
5372 class B extends A
5373 this.v2: list<list<number>> = [[0]]
5374 this.var2 = [{b: 20}]
5375 endclass
5376
5377 class C extends B implements Intf
5378 this.v3: list<list<number>> = [[0]]
5379 this.var1 = [{a: 10}]
5380 endclass
5381 END
5382 v9.CheckSourceFailure(lines, 'E1382: Member "var3": type mismatch, expected list<dict<number>> but got list<dict<string>>')
5383enddef
5384
5385" Test for extending an interface with duplicate variables and methods
5386def Test_interface_extends_with_dup_members()
5387 var lines =<< trim END
5388 vim9script
5389 interface A
5390 this.n1: number
5391 def Foo1(): number
5392 endinterface
5393 interface B extends A
5394 this.n2: number
5395 this.n1: number
5396 def Foo2(): number
5397 def Foo1(): number
5398 endinterface
5399 class C implements B
5400 this.n1 = 10
5401 this.n2 = 20
5402 def Foo1(): number
5403 return 30
5404 enddef
5405 def Foo2(): number
5406 return 40
5407 enddef
5408 endclass
5409 def T1(a: A)
5410 assert_equal(10, a.n1)
5411 assert_equal(30, a.Foo1())
5412 enddef
5413 def T2(b: B)
5414 assert_equal(10, b.n1)
5415 assert_equal(20, b.n2)
5416 assert_equal(30, b.Foo1())
5417 assert_equal(40, b.Foo2())
5418 enddef
5419 var c = C.new()
5420 T1(c)
5421 T2(c)
5422 END
5423 v9.CheckSourceSuccess(lines)
5424enddef
5425
5426" Test for using "any" type for a variable in a sub-class while it has a
5427" concrete type in the interface
5428def Test_implements_using_var_type_any()
5429 var lines =<< trim END
5430 vim9script
5431 interface A
5432 this.val: list<dict<string>>
5433 endinterface
5434 class B implements A
5435 this.val = [{a: '1'}, {b: '2'}]
5436 endclass
5437 var b = B.new()
5438 assert_equal([{a: '1'}, {b: '2'}], b.val)
5439 END
5440 v9.CheckSourceSuccess(lines)
5441
5442 # initialize instance variable using a different type
5443 lines =<< trim END
5444 vim9script
5445 interface A
5446 this.val: list<dict<string>>
5447 endinterface
5448 class B implements A
5449 this.val = {a: 1, b: 2}
5450 endclass
5451 var b = B.new()
5452 END
5453 v9.CheckSourceFailure(lines, 'E1382: Member "val": type mismatch, expected list<dict<string>> but got dict<number>')
5454enddef
5455
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005456" Test for assigning to a member variable in a nested class
5457def Test_nested_object_assignment()
5458 var lines =<< trim END
5459 vim9script
5460
5461 class A
5462 this.value: number
5463 endclass
5464
5465 class B
5466 this.a: A = A.new()
5467 endclass
5468
5469 class C
5470 this.b: B = B.new()
5471 endclass
5472
5473 class D
5474 this.c: C = C.new()
5475 endclass
5476
5477 def T(da: D)
5478 da.c.b.a.value = 10
5479 enddef
5480
5481 var d = D.new()
5482 T(d)
5483 END
5484 v9.CheckSourceFailure(lines, 'E46: Cannot change read-only variable "value"')
5485enddef
5486
Bram Moolenaar00b28d62022-12-08 15:32:33 +00005487" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker