blob: 1021114a9d28968e37c9f9a4c9a56c0a6771d7fa [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()
Ernie Rael3da696d2023-09-19 20:14:18 +02003035
3036 var o_null: Base1
3037 assert_false(instanceof(o_null, Base1))
3038
LemonBoyafe04662023-08-23 21:08:11 +02003039 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003040 v9.CheckSourceSuccess(lines)
LemonBoyafe04662023-08-23 21:08:11 +02003041enddef
3042
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003043" Test for calling a method in the parent class that is extended partially.
3044" This used to fail with the 'E118: Too many arguments for function: Text' error
3045" message (Github issue #12524).
3046def Test_call_method_in_parent_class()
3047 var lines =<< trim END
3048 vim9script
3049
3050 class Widget
3051 this._lnum: number = 1
3052
3053 def SetY(lnum: number)
3054 this._lnum = lnum
3055 enddef
3056
3057 def Text(): string
3058 return ''
3059 enddef
3060 endclass
3061
3062 class Foo extends Widget
3063 def Text(): string
3064 return '<Foo>'
3065 enddef
3066 endclass
3067
3068 def Stack(w1: Widget, w2: Widget): list<Widget>
3069 w1.SetY(1)
3070 w2.SetY(2)
3071 return [w1, w2]
3072 enddef
3073
3074 var foo1 = Foo.new()
3075 var foo2 = Foo.new()
3076 var l = Stack(foo1, foo2)
3077 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003078 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02003079enddef
3080
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003081" Test for calling methods from three levels of classes
3082def Test_multi_level_method_call()
3083 var lines =<< trim END
3084 vim9script
3085
3086 var A_func1: number = 0
3087 var A_func2: number = 0
3088 var A_func3: number = 0
3089 var B_func2: number = 0
3090 var B_func3: number = 0
3091 var C_func3: number = 0
3092
3093 class A
3094 def Func1()
3095 A_func1 += 1
3096 enddef
3097
3098 def Func2()
3099 A_func2 += 1
3100 enddef
3101
3102 def Func3()
3103 A_func3 += 1
3104 enddef
3105 endclass
3106
3107 class B extends A
3108 def Func2()
3109 B_func2 += 1
3110 enddef
3111
3112 def Func3()
3113 B_func3 += 1
3114 enddef
3115 endclass
3116
3117 class C extends B
3118 def Func3()
3119 C_func3 += 1
3120 enddef
3121 endclass
3122
3123 def A_CallFuncs(a: A)
3124 a.Func1()
3125 a.Func2()
3126 a.Func3()
3127 enddef
3128
3129 def B_CallFuncs(b: B)
3130 b.Func1()
3131 b.Func2()
3132 b.Func3()
3133 enddef
3134
3135 def C_CallFuncs(c: C)
3136 c.Func1()
3137 c.Func2()
3138 c.Func3()
3139 enddef
3140
3141 var cobj = C.new()
3142 A_CallFuncs(cobj)
3143 B_CallFuncs(cobj)
3144 C_CallFuncs(cobj)
3145 assert_equal(3, A_func1)
3146 assert_equal(0, A_func2)
3147 assert_equal(0, A_func3)
3148 assert_equal(3, B_func2)
3149 assert_equal(0, B_func3)
3150 assert_equal(3, C_func3)
3151 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003152 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003153enddef
3154
3155" Test for using members from three levels of classes
3156def Test_multi_level_member_access()
3157 var lines =<< trim END
3158 vim9script
3159
3160 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003161 public this.val1: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003162 endclass
3163
3164 class B extends A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003165 public this.val2: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003166 endclass
3167
3168 class C extends B
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02003169 public this.val3: number = 0
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003170 endclass
3171
3172 def A_members(a: A)
3173 a.val1 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003174 enddef
3175
3176 def B_members(b: B)
3177 b.val1 += 1
3178 b.val2 += 1
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003179 enddef
3180
3181 def C_members(c: C)
3182 c.val1 += 1
3183 c.val2 += 1
3184 c.val3 += 1
3185 enddef
3186
3187 var cobj = C.new()
3188 A_members(cobj)
3189 B_members(cobj)
3190 C_members(cobj)
3191 assert_equal(3, cobj.val1)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02003192 assert_equal(2, cobj.val2)
3193 assert_equal(1, cobj.val3)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003194 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003195 v9.CheckSourceSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02003196enddef
3197
LemonBoy0ffc17a2023-08-20 18:09:11 +02003198" Test expansion of <stack> with class methods.
3199def Test_stack_expansion_with_methods()
3200 var lines =<< trim END
3201 vim9script
3202
3203 class C
3204 def M1()
3205 F0()
3206 enddef
3207 endclass
3208
3209 def F0()
3210 assert_match('<SNR>\d\+_F\[1\]\.\.C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
3211 enddef
3212
3213 def F()
3214 C.new().M1()
3215 enddef
3216
3217 F()
3218 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003219 v9.CheckSourceSuccess(lines)
LemonBoy0ffc17a2023-08-20 18:09:11 +02003220enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003221
3222" Test the return type of the new() constructor
3223def Test_new_return_type()
3224 # new() uses the default return type and there is no return statement
3225 var lines =<< trim END
3226 vim9script
3227
3228 class C
3229 this._bufnr: number
3230
3231 def new(this._bufnr)
3232 if !bufexists(this._bufnr)
3233 this._bufnr = -1
3234 endif
3235 enddef
3236 endclass
3237
3238 var c = C.new(12345)
3239 assert_equal('object<C>', typename(c))
3240
3241 var v1: C
3242 v1 = C.new(12345)
3243 assert_equal('object<C>', typename(v1))
3244
3245 def F()
3246 var v2: C
3247 v2 = C.new(12345)
3248 assert_equal('object<C>', typename(v2))
3249 enddef
3250 F()
3251 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003252 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003253
3254 # new() uses the default return type and an empty 'return' statement
3255 lines =<< trim END
3256 vim9script
3257
3258 class C
3259 this._bufnr: number
3260
3261 def new(this._bufnr)
3262 if !bufexists(this._bufnr)
3263 this._bufnr = -1
3264 return
3265 endif
3266 enddef
3267 endclass
3268
3269 var c = C.new(12345)
3270 assert_equal('object<C>', typename(c))
3271
3272 var v1: C
3273 v1 = C.new(12345)
3274 assert_equal('object<C>', typename(v1))
3275
3276 def F()
3277 var v2: C
3278 v2 = C.new(12345)
3279 assert_equal('object<C>', typename(v2))
3280 enddef
3281 F()
3282 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003283 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003284
3285 # new() uses "any" return type and returns "this"
3286 lines =<< trim END
3287 vim9script
3288
3289 class C
3290 this._bufnr: number
3291
3292 def new(this._bufnr): any
3293 if !bufexists(this._bufnr)
3294 this._bufnr = -1
3295 return this
3296 endif
3297 enddef
3298 endclass
3299 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003300 v9.CheckSourceFailure(lines, 'E1365:')
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003301
3302 # new() uses 'Dict' return type and returns a Dict
3303 lines =<< trim END
3304 vim9script
3305
3306 class C
3307 this._state: dict<any>
3308
3309 def new(): dict<any>
3310 this._state = {}
3311 return this._state
3312 enddef
3313 endclass
3314
3315 var c = C.new()
3316 assert_equal('object<C>', typename(c))
3317 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003318 v9.CheckSourceFailure(lines, 'E1365:')
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02003319enddef
3320
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003321" Test for checking a member initialization type at run time.
3322def Test_runtime_type_check_for_member_init()
3323 var lines =<< trim END
3324 vim9script
3325
3326 var retnum: bool = false
3327
3328 def F(): any
3329 retnum = !retnum
3330 if retnum
3331 return 1
3332 else
3333 return "hello"
3334 endif
3335 enddef
3336
3337 class C
3338 this._foo: bool = F()
3339 endclass
3340
3341 var c1 = C.new()
3342 var c2 = C.new()
3343 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003344 v9.CheckSourceFailure(lines, 'E1012:')
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003345enddef
3346
3347" Test for locking a variable referring to an object and reassigning to another
3348" object.
3349def Test_object_lockvar()
3350 var lines =<< trim END
3351 vim9script
3352
3353 class C
3354 this.val: number
3355 def new(this.val)
3356 enddef
3357 endclass
3358
3359 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
3360 lockvar 2 some_dict
3361
3362 var current: C
3363 current = some_dict['c']
3364 assert_equal(3, current.val)
3365 current = some_dict['b']
3366 assert_equal(2, current.val)
3367
3368 def F()
3369 current = some_dict['c']
3370 enddef
3371
3372 def G()
3373 current = some_dict['b']
3374 enddef
3375
3376 F()
3377 assert_equal(3, current.val)
3378 G()
3379 assert_equal(2, current.val)
3380 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003381 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02003382enddef
3383
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003384" Test for a private object method
3385def Test_private_object_method()
3386 # Try calling a private method using an object (at the script level)
3387 var lines =<< trim END
3388 vim9script
3389
3390 class A
3391 def _Foo(): number
3392 return 1234
3393 enddef
3394 endclass
3395 var a = A.new()
3396 a._Foo()
3397 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003398 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003399
3400 # Try calling a private method using an object (from a def function)
3401 lines =<< trim END
3402 vim9script
3403
3404 class A
3405 def _Foo(): number
3406 return 1234
3407 enddef
3408 endclass
3409 def T()
3410 var a = A.new()
3411 a._Foo()
3412 enddef
3413 T()
3414 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003415 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003416
3417 # Use a private method from another object method (in script context)
3418 lines =<< trim END
3419 vim9script
3420
3421 class A
3422 def _Foo(): number
3423 return 1234
3424 enddef
3425 def Bar(): number
3426 return this._Foo()
3427 enddef
3428 endclass
3429 var a = A.new()
3430 assert_equal(1234, a.Bar())
3431 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003432 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003433
3434 # Use a private method from another object method (def function context)
3435 lines =<< trim END
3436 vim9script
3437
3438 class A
3439 def _Foo(): number
3440 return 1234
3441 enddef
3442 def Bar(): number
3443 return this._Foo()
3444 enddef
3445 endclass
3446 def T()
3447 var a = A.new()
3448 assert_equal(1234, a.Bar())
3449 enddef
3450 T()
3451 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003452 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003453
3454 # Try calling a private method without the "this" prefix
3455 lines =<< trim END
3456 vim9script
3457
3458 class A
3459 def _Foo(): number
3460 return 1234
3461 enddef
3462 def Bar(): number
3463 return _Foo()
3464 enddef
3465 endclass
3466 var a = A.new()
3467 a.Bar()
3468 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003469 v9.CheckSourceFailure(lines, 'E117: Unknown function: _Foo')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003470
3471 # Try calling a private method using the class name
3472 lines =<< trim END
3473 vim9script
3474
3475 class A
3476 def _Foo(): number
3477 return 1234
3478 enddef
3479 endclass
3480 A._Foo()
3481 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003482 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003483
3484 # Try to use "public" keyword when defining a private method
3485 lines =<< trim END
3486 vim9script
3487
3488 class A
3489 public def _Foo()
3490 enddef
3491 endclass
3492 var a = A.new()
3493 a._Foo()
3494 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003495 v9.CheckSourceFailure(lines, 'E1331: Public must be followed by "this" or "static"')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003496
3497 # Define two private methods with the same name
3498 lines =<< trim END
3499 vim9script
3500
3501 class A
3502 def _Foo()
3503 enddef
3504 def _Foo()
3505 enddef
3506 endclass
3507 var a = A.new()
3508 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003509 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003510
3511 # Define a private method and a object method with the same name
3512 lines =<< trim END
3513 vim9script
3514
3515 class A
3516 def _Foo()
3517 enddef
3518 def Foo()
3519 enddef
3520 endclass
3521 var a = A.new()
3522 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003523 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003524
3525 # Define an object method and a private method with the same name
3526 lines =<< trim END
3527 vim9script
3528
3529 class A
3530 def Foo()
3531 enddef
3532 def _Foo()
3533 enddef
3534 endclass
3535 var a = A.new()
3536 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003537 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003538
3539 # Call a public method and a private method from a private method
3540 lines =<< trim END
3541 vim9script
3542
3543 class A
3544 def Foo(): number
3545 return 100
3546 enddef
3547 def _Bar(): number
3548 return 200
3549 enddef
3550 def _Baz()
3551 assert_equal(100, this.Foo())
3552 assert_equal(200, this._Bar())
3553 enddef
3554 def T()
3555 this._Baz()
3556 enddef
3557 endclass
3558 var a = A.new()
3559 a.T()
3560 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003561 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003562
3563 # Try calling a private method from another class
3564 lines =<< trim END
3565 vim9script
3566
3567 class A
3568 def _Foo(): number
3569 return 100
3570 enddef
3571 endclass
3572 class B
3573 def Foo(): number
3574 var a = A.new()
3575 a._Foo()
3576 enddef
3577 endclass
3578 var b = B.new()
3579 b.Foo()
3580 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003581 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003582
3583 # Call a private object method from a child class object method
3584 lines =<< trim END
3585 vim9script
3586 class A
3587 def _Foo(): number
3588 return 1234
3589 enddef
3590 endclass
3591 class B extends A
3592 def Bar()
3593 enddef
3594 endclass
3595 class C extends B
3596 def Baz(): number
3597 return this._Foo()
3598 enddef
3599 endclass
3600 var c = C.new()
3601 assert_equal(1234, c.Baz())
3602 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003603 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003604
3605 # Call a private object method from a child class object
3606 lines =<< trim END
3607 vim9script
3608 class A
3609 def _Foo(): number
3610 return 1234
3611 enddef
3612 endclass
3613 class B extends A
3614 def Bar()
3615 enddef
3616 endclass
3617 class C extends B
3618 def Baz(): number
3619 enddef
3620 endclass
3621 var c = C.new()
3622 assert_equal(1234, c._Foo())
3623 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003624 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003625
3626 # Using "_" prefix in a method name should fail outside of a class
3627 lines =<< trim END
3628 vim9script
3629 def _Foo(): number
3630 return 1234
3631 enddef
3632 var a = _Foo()
3633 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003634 v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003635enddef
3636
3637" Test for an private class method
3638def Test_private_class_method()
3639 # Try calling a class private method (at the script level)
3640 var lines =<< trim END
3641 vim9script
3642
3643 class A
3644 static def _Foo(): number
3645 return 1234
3646 enddef
3647 endclass
3648 A._Foo()
3649 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003650 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003651
3652 # Try calling a class private method (from a def function)
3653 lines =<< trim END
3654 vim9script
3655
3656 class A
3657 static def _Foo(): number
3658 return 1234
3659 enddef
3660 endclass
3661 def T()
3662 A._Foo()
3663 enddef
3664 T()
3665 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003666 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003667
3668 # Try calling a class private method using an object (at the script level)
3669 lines =<< trim END
3670 vim9script
3671
3672 class A
3673 static def _Foo(): number
3674 return 1234
3675 enddef
3676 endclass
3677 var a = A.new()
3678 a._Foo()
3679 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003680 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003681
3682 # Try calling a class private method using an object (from a def function)
3683 lines =<< trim END
3684 vim9script
3685
3686 class A
3687 static def _Foo(): number
3688 return 1234
3689 enddef
3690 endclass
3691 def T()
3692 var a = A.new()
3693 a._Foo()
3694 enddef
3695 T()
3696 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003697 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003698
3699 # Use a class private method from an object method
3700 lines =<< trim END
3701 vim9script
3702
3703 class A
3704 static def _Foo(): number
3705 return 1234
3706 enddef
3707 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02003708 assert_equal(1234, _Foo())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003709 enddef
3710 endclass
3711 var a = A.new()
3712 a.Bar()
3713 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003714 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003715
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02003716 # Use a class private method from another class private method without the
3717 # class name prefix.
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003718 lines =<< trim END
3719 vim9script
3720
3721 class A
3722 static def _Foo1(): number
3723 return 1234
3724 enddef
3725 static def _Foo2()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02003726 assert_equal(1234, _Foo1())
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003727 enddef
3728 def Bar()
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02003729 _Foo2()
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003730 enddef
3731 endclass
3732 var a = A.new()
3733 a.Bar()
3734 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003735 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003736
3737 # Declare a class method and a class private method with the same name
3738 lines =<< trim END
3739 vim9script
3740
3741 class A
3742 static def _Foo()
3743 enddef
3744 static def Foo()
3745 enddef
3746 endclass
3747 var a = A.new()
3748 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003749 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003750
3751 # Try calling a class private method from another class
3752 lines =<< trim END
3753 vim9script
3754
3755 class A
3756 static def _Foo(): number
3757 return 1234
3758 enddef
3759 endclass
3760 class B
3761 def Foo(): number
3762 return A._Foo()
3763 enddef
3764 endclass
3765 var b = B.new()
3766 assert_equal(1234, b.Foo())
3767 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003768 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003769
3770 # Call a private class method from a child class object method
3771 lines =<< trim END
3772 vim9script
3773 class A
3774 static def _Foo(): number
3775 return 1234
3776 enddef
3777 endclass
3778 class B extends A
3779 def Bar()
3780 enddef
3781 endclass
3782 class C extends B
3783 def Baz(): number
3784 return A._Foo()
3785 enddef
3786 endclass
3787 var c = C.new()
3788 assert_equal(1234, c.Baz())
3789 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003790 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003791
3792 # Call a private class method from a child class private class method
3793 lines =<< trim END
3794 vim9script
3795 class A
3796 static def _Foo(): number
3797 return 1234
3798 enddef
3799 endclass
3800 class B extends A
3801 def Bar()
3802 enddef
3803 endclass
3804 class C extends B
3805 static def Baz(): number
3806 return A._Foo()
3807 enddef
3808 endclass
3809 assert_equal(1234, C.Baz())
3810 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003811 v9.CheckSourceFailure(lines, 'E1366: Cannot access private method: _Foo()')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003812
3813 # Call a private class method from a child class object
3814 lines =<< trim END
3815 vim9script
3816 class A
3817 static def _Foo(): number
3818 return 1234
3819 enddef
3820 endclass
3821 class B extends A
3822 def Bar()
3823 enddef
3824 endclass
3825 class C extends B
3826 def Baz(): number
3827 enddef
3828 endclass
3829 var c = C.new()
3830 assert_equal(1234, C._Foo())
3831 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003832 v9.CheckSourceFailure(lines, 'E1325: Method not found on class "C": _Foo')
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02003833enddef
3834
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02003835" Test for using the return value of a class/object method as a function
3836" argument.
3837def Test_objmethod_funcarg()
3838 var lines =<< trim END
3839 vim9script
3840
3841 class C
3842 def Foo(): string
3843 return 'foo'
3844 enddef
3845 endclass
3846
3847 def Bar(a: number, s: string): string
3848 return s
3849 enddef
3850
3851 def Baz(c: C)
3852 assert_equal('foo', Bar(10, c.Foo()))
3853 enddef
3854
3855 var t = C.new()
3856 Baz(t)
3857 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003858 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02003859
3860 lines =<< trim END
3861 vim9script
3862
3863 class C
3864 static def Foo(): string
3865 return 'foo'
3866 enddef
3867 endclass
3868
3869 def Bar(a: number, s: string): string
3870 return s
3871 enddef
3872
3873 def Baz()
3874 assert_equal('foo', Bar(10, C.Foo()))
3875 enddef
3876
3877 Baz()
3878 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003879 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02003880enddef
3881
Ernie Raelcf138d42023-09-06 20:45:03 +02003882def Test_static_inheritence()
3883 # subclasses get their own static copy
3884 var lines =<< trim END
3885 vim9script
3886
3887 class A
3888 static _svar: number
3889 this._mvar: number
3890 def new()
3891 _svar = 1
3892 this._mvar = 101
3893 enddef
3894 def AccessObject(): number
3895 return this._mvar
3896 enddef
3897 def AccessStaticThroughObject(): number
3898 return _svar
3899 enddef
3900 endclass
3901
3902 class B extends A
3903 def new()
Ernie Raelcf138d42023-09-06 20:45:03 +02003904 this._mvar = 102
3905 enddef
3906 endclass
3907
3908 class C extends B
3909 def new()
Ernie Raelcf138d42023-09-06 20:45:03 +02003910 this._mvar = 103
3911 enddef
3912
3913 def AccessPrivateStaticThroughClassName(): number
3914 assert_equal(1, A._svar)
Ernie Raelcf138d42023-09-06 20:45:03 +02003915 return 444
3916 enddef
3917 endclass
3918
3919 var oa = A.new()
3920 var ob = B.new()
3921 var oc = C.new()
3922 assert_equal(101, oa.AccessObject())
3923 assert_equal(102, ob.AccessObject())
3924 assert_equal(103, oc.AccessObject())
3925
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003926 assert_fails('echo oc.AccessPrivateStaticThroughClassName()', 'E1333: Cannot access private member: _svar')
Ernie Raelcf138d42023-09-06 20:45:03 +02003927
3928 # verify object properly resolves to correct static
3929 assert_equal(1, oa.AccessStaticThroughObject())
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003930 assert_equal(1, ob.AccessStaticThroughObject())
3931 assert_equal(1, oc.AccessStaticThroughObject())
Ernie Raelcf138d42023-09-06 20:45:03 +02003932 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003933 v9.CheckSourceSuccess(lines)
Ernie Raelcf138d42023-09-06 20:45:03 +02003934enddef
3935
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02003936" Test for declaring duplicate object and class members
3937def Test_dup_member_variable()
3938 # Duplicate member variable
3939 var lines =<< trim END
3940 vim9script
3941 class C
3942 this.val = 10
3943 this.val = 20
3944 endclass
3945 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003946 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02003947
3948 # Duplicate private member variable
3949 lines =<< trim END
3950 vim9script
3951 class C
3952 this._val = 10
3953 this._val = 20
3954 endclass
3955 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003956 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _val')
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02003957
3958 # Duplicate public member variable
3959 lines =<< trim END
3960 vim9script
3961 class C
3962 public this.val = 10
3963 public this.val = 20
3964 endclass
3965 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003966 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02003967
3968 # Duplicate private member variable
3969 lines =<< trim END
3970 vim9script
3971 class C
3972 this.val = 10
3973 this._val = 20
3974 endclass
3975 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003976 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _val')
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02003977
3978 # Duplicate public and private member variable
3979 lines =<< trim END
3980 vim9script
3981 class C
3982 this._val = 20
3983 public this.val = 10
3984 endclass
3985 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003986 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02003987
3988 # Duplicate class member variable
3989 lines =<< trim END
3990 vim9script
3991 class C
3992 static s: string = "abc"
3993 static _s: string = "def"
3994 endclass
3995 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02003996 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _s')
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02003997
3998 # Duplicate public and private class member variable
3999 lines =<< trim END
4000 vim9script
4001 class C
4002 public static s: string = "abc"
4003 static _s: string = "def"
4004 endclass
4005 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004006 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _s')
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004007
4008 # Duplicate class and object member variable
4009 lines =<< trim END
4010 vim9script
4011 class C
4012 static val = 10
4013 this.val = 20
4014 def new()
4015 enddef
4016 endclass
4017 var c = C.new()
4018 assert_equal(10, C.val)
4019 assert_equal(20, c.val)
4020 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004021 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004022
4023 # Duplicate object member variable in a derived class
4024 lines =<< trim END
4025 vim9script
4026 class A
4027 this.val = 10
4028 endclass
4029 class B extends A
4030 endclass
4031 class C extends B
4032 this.val = 20
4033 endclass
4034 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004035 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004036
4037 # Duplicate object private member variable in a derived class
4038 lines =<< trim END
4039 vim9script
4040 class A
4041 this._val = 10
4042 endclass
4043 class B extends A
4044 endclass
4045 class C extends B
4046 this._val = 20
4047 endclass
4048 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004049 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _val')
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004050
4051 # Duplicate object private member variable in a derived class
4052 lines =<< trim END
4053 vim9script
4054 class A
4055 this.val = 10
4056 endclass
4057 class B extends A
4058 endclass
4059 class C extends B
4060 this._val = 20
4061 endclass
4062 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004063 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: _val')
Yegappan Lakshmanane3b6c782023-08-29 22:32:02 +02004064
4065 # Duplicate object member variable in a derived class
4066 lines =<< trim END
4067 vim9script
4068 class A
4069 this._val = 10
4070 endclass
4071 class B extends A
4072 endclass
4073 class C extends B
4074 this.val = 20
4075 endclass
4076 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004077 v9.CheckSourceFailure(lines, 'E1369: Duplicate member: val')
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004078
4079 # Two member variables with a common prefix
4080 lines =<< trim END
4081 vim9script
4082 class A
4083 public static svar2: number
4084 public static svar: number
4085 endclass
4086 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004087 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02004088enddef
4089
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004090" Test for accessing a private member outside a class in a def function
4091def Test_private_member_access_outside_class()
4092 # private object member variable
4093 var lines =<< trim END
4094 vim9script
4095 class A
4096 this._val = 10
4097 def GetVal(): number
4098 return this._val
4099 enddef
4100 endclass
4101 def T()
4102 var a = A.new()
4103 a._val = 20
4104 enddef
4105 T()
4106 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004107 v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _val')
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004108
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004109 # access a non-existing private object member variable
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004110 lines =<< trim END
4111 vim9script
4112 class A
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004113 this._val = 10
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004114 endclass
4115 def T()
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004116 var a = A.new()
4117 a._a = 1
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004118 enddef
4119 T()
4120 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004121 v9.CheckSourceFailure(lines, 'E1326: Member not found on object "A": _a')
Ernie Rael18143d32023-09-04 22:30:41 +02004122
4123 # private static member variable
4124 lines =<< trim END
4125 vim9script
4126 class A
4127 static _val = 10
4128 endclass
4129 def T()
4130 var a = A.new()
4131 var x = a._val
4132 enddef
4133 T()
4134 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004135 v9.CheckSourceFailure(lines, 'E1375: Class member "_val" accessible only using class "A"')
Ernie Rael18143d32023-09-04 22:30:41 +02004136
4137 # private static member variable
4138 lines =<< trim END
4139 vim9script
4140 class A
4141 static _val = 10
4142 endclass
4143 def T()
4144 var a = A.new()
4145 a._val = 3
4146 enddef
4147 T()
4148 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004149 v9.CheckSourceFailure(lines, 'E1375: Class member "_val" accessible only using class "A"')
Ernie Rael18143d32023-09-04 22:30:41 +02004150
4151 # private static class variable
4152 lines =<< trim END
4153 vim9script
4154 class A
4155 static _val = 10
4156 endclass
4157 def T()
4158 var x = A._val
4159 enddef
4160 T()
4161 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004162 v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _val')
Ernie Rael18143d32023-09-04 22:30:41 +02004163
4164 # private static class variable
4165 lines =<< trim END
4166 vim9script
4167 class A
4168 static _val = 10
4169 endclass
4170 def T()
4171 A._val = 3
4172 enddef
4173 T()
4174 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004175 v9.CheckSourceFailure(lines, 'E1333: Cannot access private member: _val')
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004176enddef
4177
4178" Test for changing the member access of an interface in a implementation class
4179def Test_change_interface_member_access()
4180 var lines =<< trim END
4181 vim9script
4182 interface A
4183 public this.val: number
4184 endinterface
4185 class B implements A
4186 this.val = 10
4187 endclass
4188 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004189 v9.CheckSourceFailure(lines, 'E1367: Access level of member "val" of interface "A" is different')
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004190
4191 lines =<< trim END
4192 vim9script
4193 interface A
4194 this.val: number
4195 endinterface
4196 class B implements A
4197 public this.val = 10
4198 endclass
4199 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004200 v9.CheckSourceFailure(lines, 'E1367: Access level of member "val" of interface "A" is different')
Yegappan Lakshmananeb91e242023-08-31 18:10:46 +02004201enddef
4202
4203" Test for trying to change a readonly member from a def function
4204def Test_readonly_member_change_in_def_func()
4205 var lines =<< trim END
4206 vim9script
4207 class A
4208 this.val: number
4209 endclass
4210 def T()
4211 var a = A.new()
4212 a.val = 20
4213 enddef
4214 T()
4215 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004216 v9.CheckSourceFailure(lines, 'E46: Cannot change read-only variable "val"')
Yegappan Lakshmanan5bbcfbc2023-08-30 16:38:26 +02004217enddef
4218
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004219" Test for reading and writing a class member from a def function
4220def Test_modify_class_member_from_def_function()
4221 var lines =<< trim END
4222 vim9script
4223 class A
4224 this.var1: number = 10
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02004225 public static var2: list<number> = [1, 2]
4226 public static var3: dict<number> = {a: 1, b: 2}
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004227 static _priv_var4: number = 40
4228 endclass
4229 def T()
Yegappan Lakshmanane651e112023-09-04 07:51:01 +02004230 assert_equal([1, 2], A.var2)
4231 assert_equal({a: 1, b: 2}, A.var3)
4232 A.var2 = [3, 4]
4233 A.var3 = {c: 3, d: 4}
4234 assert_equal([3, 4], A.var2)
4235 assert_equal({c: 3, d: 4}, A.var3)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004236 assert_fails('echo A._priv_var4', 'E1333: Cannot access private member: _priv_var4')
4237 enddef
4238 T()
4239 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004240 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan3775f772023-09-01 22:05:45 +02004241enddef
4242
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004243" Test for accessing a class member variable using an object
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004244def Test_class_variable_access_using_object()
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004245 var lines =<< trim END
4246 vim9script
4247 class A
4248 public static svar1: list<number> = [1]
4249 public static svar2: list<number> = [2]
4250 endclass
4251
4252 A.svar1->add(3)
4253 A.svar2->add(4)
4254 assert_equal([1, 3], A.svar1)
4255 assert_equal([2, 4], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004256
4257 def Foo()
4258 A.svar1->add(7)
4259 A.svar2->add(8)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004260 assert_equal([1, 3, 7], A.svar1)
4261 assert_equal([2, 4, 8], A.svar2)
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004262 enddef
4263 Foo()
4264 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004265 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004266
4267 # Cannot read from a class variable using an object in script context
4268 lines =<< trim END
4269 vim9script
4270 class A
4271 public this.var1: number
4272 public static svar2: list<number> = [1]
4273 endclass
4274
4275 var a = A.new()
4276 echo a.svar2
4277 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004278 v9.CheckSourceFailure(lines, 'E1375: Class member "svar2" accessible only using class "A"')
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004279
4280 # Cannot write to a class variable using an object in script context
4281 lines =<< trim END
4282 vim9script
4283 class A
4284 public this.var1: number
4285 public static svar2: list<number> = [1]
4286 endclass
4287
4288 var a = A.new()
4289 a.svar2 = [2]
4290 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004291 v9.CheckSourceFailure(lines, 'E1375: Class member "svar2" accessible only using class "A"')
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004292
4293 # Cannot read from a class variable using an object in def method context
4294 lines =<< trim END
4295 vim9script
4296 class A
4297 public this.var1: number
4298 public static svar2: list<number> = [1]
4299 endclass
4300
4301 def T()
4302 var a = A.new()
4303 echo a.svar2
4304 enddef
4305 T()
4306 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004307 v9.CheckSourceFailure(lines, 'E1375: Class member "svar2" accessible only using class "A"')
Yegappan Lakshmanan23c92d92023-09-09 11:33:29 +02004308
4309 # Cannot write to a class variable using an object in def method context
4310 lines =<< trim END
4311 vim9script
4312 class A
4313 public this.var1: number
4314 public static svar2: list<number> = [1]
4315 endclass
4316
4317 def T()
4318 var a = A.new()
4319 a.svar2 = [2]
4320 enddef
4321 T()
4322 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004323 v9.CheckSourceFailure(lines, 'E1375: Class member "svar2" accessible only using class "A"')
Yegappan Lakshmanan1689e842023-09-06 20:23:23 +02004324enddef
4325
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02004326" Test for using a interface method using a child object
4327def Test_interface_method_from_child()
4328 var lines =<< trim END
4329 vim9script
4330
4331 interface A
4332 def Foo(): string
4333 endinterface
4334
4335 class B implements A
4336 def Foo(): string
4337 return 'foo'
4338 enddef
4339 endclass
4340
4341 class C extends B
4342 def Bar(): string
4343 return 'bar'
4344 enddef
4345 endclass
4346
4347 def T1(a: A)
4348 assert_equal('foo', a.Foo())
4349 enddef
4350
4351 def T2(b: B)
4352 assert_equal('foo', b.Foo())
4353 enddef
4354
4355 var c = C.new()
4356 T1(c)
4357 T2(c)
4358 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004359 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02004360enddef
4361
4362" Test for using an interface method using a child object when it is overridden
4363" by the child class.
4364" FIXME: This test fails.
4365" def Test_interface_overridden_method_from_child()
4366" var lines =<< trim END
4367" vim9script
4368"
4369" interface A
4370" def Foo(): string
4371" endinterface
4372"
4373" class B implements A
4374" def Foo(): string
4375" return 'b-foo'
4376" enddef
4377" endclass
4378"
4379" class C extends B
4380" def Bar(): string
4381" return 'bar'
4382" enddef
4383" def Foo(): string
4384" return 'c-foo'
4385" enddef
4386" endclass
4387"
4388" def T1(a: A)
4389" assert_equal('c-foo', a.Foo())
4390" enddef
4391"
4392" def T2(b: B)
4393" assert_equal('c-foo', b.Foo())
4394" enddef
4395"
4396" var c = C.new()
4397" T1(c)
4398" T2(c)
4399" END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004400" v9.CheckSourceSuccess(lines)
Yegappan Lakshmanancc0bcf42023-09-08 19:12:03 +02004401" enddef
4402
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004403" Test for abstract methods
4404def Test_abstract_method()
4405 # Use two abstract methods
4406 var lines =<< trim END
4407 vim9script
4408 abstract class A
4409 def M1(): number
4410 return 10
4411 enddef
4412 abstract def M2(): number
4413 abstract def M3(): number
4414 endclass
4415 class B extends A
4416 def M2(): number
4417 return 20
4418 enddef
4419 def M3(): number
4420 return 30
4421 enddef
4422 endclass
4423 var b = B.new()
4424 assert_equal([10, 20, 30], [b.M1(), b.M2(), b.M3()])
4425 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004426 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004427
4428 # Don't define an abstract method
4429 lines =<< trim END
4430 vim9script
4431 abstract class A
4432 abstract def Foo()
4433 endclass
4434 class B extends A
4435 endclass
4436 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004437 v9.CheckSourceFailure(lines, 'E1373: Abstract method "Foo" is not implemented')
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004438
4439 # Use abstract method in a concrete class
4440 lines =<< trim END
4441 vim9script
4442 class A
4443 abstract def Foo()
4444 endclass
4445 class B extends A
4446 endclass
4447 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004448 v9.CheckSourceFailure(lines, 'E1372: Abstract method "abstract def Foo()" cannot be defined in a concrete class')
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004449
4450 # Use abstract method in an interface
4451 lines =<< trim END
4452 vim9script
4453 interface A
4454 abstract def Foo()
4455 endinterface
4456 class B implements A
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02004457 def Foo()
4458 enddef
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004459 endclass
4460 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02004461 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004462
4463 # Abbreviate the "abstract" keyword
4464 lines =<< trim END
4465 vim9script
4466 class A
4467 abs def Foo()
4468 endclass
4469 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004470 v9.CheckSourceFailure(lines, 'E1065: Command cannot be shortened: abs def Foo()')
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004471
4472 # Use "abstract" with a member variable
4473 lines =<< trim END
4474 vim9script
4475 abstract class A
4476 abstract this.val = 10
4477 endclass
4478 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004479 v9.CheckSourceFailure(lines, 'E1371: Abstract must be followed by "def" or "static"')
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004480
4481 # Use a static abstract method
4482 lines =<< trim END
4483 vim9script
4484 abstract class A
4485 abstract static def Foo(): number
4486 endclass
4487 class B extends A
4488 static def Foo(): number
4489 return 4
4490 enddef
4491 endclass
4492 assert_equal(4, B.Foo())
4493 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004494 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004495
4496 # Type mismatch between abstract method and concrete method
4497 lines =<< trim END
4498 vim9script
4499 abstract class A
4500 abstract def Foo(a: string, b: number): list<number>
4501 endclass
4502 class B extends A
4503 def Foo(a: number, b: string): list<string>
4504 return []
4505 enddef
4506 endclass
4507 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02004508 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 +02004509
4510 # Use an abstract class to invoke an abstract method
4511 # FIXME: This should fail
4512 lines =<< trim END
4513 vim9script
4514 abstract class A
4515 abstract static def Foo()
4516 endclass
4517 A.Foo()
4518 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004519 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004520
4521 # Invoke an abstract method from a def function
4522 lines =<< trim END
4523 vim9script
4524 abstract class A
4525 abstract def Foo(): list<number>
4526 endclass
4527 class B extends A
4528 def Foo(): list<number>
4529 return [3, 5]
4530 enddef
4531 endclass
4532 def Bar(c: B)
4533 assert_equal([3, 5], c.Foo())
4534 enddef
4535 var b = B.new()
4536 Bar(b)
4537 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004538 v9.CheckSourceSuccess(lines)
4539enddef
4540
4541" Test for calling a class method from a subclass
4542def Test_class_method_call_from_subclass()
4543 # class method call from a subclass
4544 var lines =<< trim END
4545 vim9script
4546
4547 class A
4548 static def Foo()
4549 echo "foo"
4550 enddef
4551 endclass
4552
4553 class B extends A
4554 def Bar()
4555 Foo()
4556 enddef
4557 endclass
4558
4559 var b = B.new()
4560 b.Bar()
4561 END
4562 v9.CheckSourceFailure(lines, 'E1374: Class member "Foo" accessible only inside class "A"')
Yegappan Lakshmanan7bcd25c2023-09-08 19:27:51 +02004563enddef
4564
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02004565" Test for calling a class method using an object in a def function context and
4566" script context.
4567def Test_class_method_call_using_object()
4568 # script context
4569 var lines =<< trim END
4570 vim9script
4571 class A
4572 static def Foo(): list<string>
4573 return ['a', 'b']
4574 enddef
4575 def Bar()
4576 assert_equal(['a', 'b'], A.Foo())
4577 assert_equal(['a', 'b'], Foo())
4578 enddef
4579 endclass
4580
4581 def T()
4582 assert_equal(['a', 'b'], A.Foo())
4583 var t_a = A.new()
4584 t_a.Bar()
4585 enddef
4586
4587 assert_equal(['a', 'b'], A.Foo())
4588 var a = A.new()
4589 a.Bar()
4590 T()
4591 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004592 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02004593
4594 # script context
4595 lines =<< trim END
4596 vim9script
4597 class A
4598 static def Foo(): string
4599 return 'foo'
4600 enddef
4601 endclass
4602
4603 var a = A.new()
4604 assert_equal('foo', a.Foo())
4605 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004606 v9.CheckSourceFailure(lines, 'E1375: Class member "Foo" accessible only using class "A"')
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02004607
4608 # def function context
4609 lines =<< trim END
4610 vim9script
4611 class A
4612 static def Foo(): string
4613 return 'foo'
4614 enddef
4615 endclass
4616
4617 def T()
4618 var a = A.new()
4619 assert_equal('foo', a.Foo())
4620 enddef
4621 T()
4622 END
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004623 v9.CheckSourceFailure(lines, 'E1375: Class member "Foo" accessible only using class "A"')
4624enddef
4625
4626def Test_class_variable()
4627 var lines =<< trim END
4628 vim9script
4629
4630 class A
4631 public static val: number = 10
4632 static def ClassFunc()
4633 assert_equal(10, val)
4634 enddef
4635 def ObjFunc()
4636 assert_equal(10, val)
4637 enddef
4638 endclass
4639
4640 class B extends A
4641 endclass
4642
4643 assert_equal(10, A.val)
4644 A.ClassFunc()
4645 var a = A.new()
4646 a.ObjFunc()
4647 var b = B.new()
4648 b.ObjFunc()
4649
4650 def T1(a1: A)
4651 a1.ObjFunc()
4652 A.ClassFunc()
4653 enddef
4654 T1(b)
4655
4656 A.val = 20
4657 assert_equal(20, A.val)
4658 END
4659 v9.CheckSourceSuccess(lines)
4660
4661 # Modifying a parent class variable from a child class method
4662 lines =<< trim END
4663 vim9script
4664
4665 class A
4666 static val: number = 10
4667 endclass
4668
4669 class B extends A
4670 static def ClassFunc()
4671 val = 20
4672 enddef
4673 endclass
4674 B.ClassFunc()
4675 END
4676 v9.CheckSourceFailure(lines, 'E1374: Class member "val" accessible only inside class "A"')
4677
4678 # Reading a parent class variable from a child class method
4679 lines =<< trim END
4680 vim9script
4681
4682 class A
4683 static val: number = 10
4684 endclass
4685
4686 class B extends A
4687 static def ClassFunc()
4688 var i = val
4689 enddef
4690 endclass
4691 B.ClassFunc()
4692 END
4693 v9.CheckSourceFailure(lines, 'E1374: Class member "val" accessible only inside class "A"')
4694
4695 # Modifying a parent class variable from a child object method
4696 lines =<< trim END
4697 vim9script
4698
4699 class A
4700 static val: number = 10
4701 endclass
4702
4703 class B extends A
4704 def ObjFunc()
4705 val = 20
4706 enddef
4707 endclass
4708 var b = B.new()
4709 b.ObjFunc()
4710 END
4711 v9.CheckSourceFailure(lines, 'E1374: Class member "val" accessible only inside class "A"')
4712
4713 # Reading a parent class variable from a child object method
4714 lines =<< trim END
4715 vim9script
4716
4717 class A
4718 static val: number = 10
4719 endclass
4720
4721 class B extends A
4722 def ObjFunc()
4723 var i = val
4724 enddef
4725 endclass
4726 var b = B.new()
4727 b.ObjFunc()
4728 END
4729 v9.CheckSourceFailure(lines, 'E1374: Class member "val" accessible only inside class "A"')
4730
4731 # Modifying a class variable using an object at script level
4732 lines =<< trim END
4733 vim9script
4734
4735 class A
4736 static val: number = 10
4737 endclass
4738 var a = A.new()
4739 a.val = 20
4740 END
4741 v9.CheckSourceFailure(lines, 'E1375: Class member "val" accessible only using class "A"')
4742
4743 # Reading a class variable using an object at script level
4744 lines =<< trim END
4745 vim9script
4746
4747 class A
4748 static val: number = 10
4749 endclass
4750 var a = A.new()
4751 var i = a.val
4752 END
4753 v9.CheckSourceFailure(lines, 'E1375: Class member "val" accessible only using class "A"')
4754
4755 # Modifying a class variable using an object at function level
4756 lines =<< trim END
4757 vim9script
4758
4759 class A
4760 static val: number = 10
4761 endclass
4762
4763 def T()
4764 var a = A.new()
4765 a.val = 20
4766 enddef
4767 T()
4768 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02004769 v9.CheckSourceFailure(lines, 'E1375: Class member "val" accessible only using class "A"')
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004770
4771 # Reading a class variable using an object at function level
4772 lines =<< trim END
4773 vim9script
4774
4775 class A
4776 static val: number = 10
4777 endclass
4778 def T()
4779 var a = A.new()
4780 var i = a.val
4781 enddef
4782 T()
4783 END
4784 v9.CheckSourceFailure(lines, 'E1375: Class member "val" accessible only using class "A"')
4785enddef
4786
4787" Test for using a duplicate class method and class variable in a child class
4788def Test_dup_class_member()
4789 # duplicate class variable, class method and overridden object method
4790 var lines =<< trim END
4791 vim9script
4792 class A
4793 static sval = 100
4794 static def Check()
4795 assert_equal(100, sval)
4796 enddef
4797 def GetVal(): number
4798 return sval
4799 enddef
4800 endclass
4801
4802 class B extends A
4803 static sval = 200
4804 static def Check()
4805 assert_equal(200, sval)
4806 enddef
4807 def GetVal(): number
4808 return sval
4809 enddef
4810 endclass
4811
4812 def T1(aa: A): number
4813 return aa.GetVal()
4814 enddef
4815
4816 def T2(bb: B): number
4817 return bb.GetVal()
4818 enddef
4819
4820 assert_equal(100, A.sval)
4821 assert_equal(200, B.sval)
4822 var a = A.new()
4823 assert_equal(100, a.GetVal())
4824 var b = B.new()
4825 assert_equal(200, b.GetVal())
4826 assert_equal(200, T1(b))
4827 assert_equal(200, T2(b))
4828 END
4829 v9.CheckSourceSuccess(lines)
4830
4831 # duplicate class variable and class method
4832 lines =<< trim END
4833 vim9script
4834 class A
4835 static sval = 100
4836 static def Check()
4837 assert_equal(100, sval)
4838 enddef
4839 def GetVal(): number
4840 return sval
4841 enddef
4842 endclass
4843
4844 class B extends A
4845 static sval = 200
4846 static def Check()
4847 assert_equal(200, sval)
4848 enddef
4849 endclass
4850
4851 def T1(aa: A): number
4852 return aa.GetVal()
4853 enddef
4854
4855 def T2(bb: B): number
4856 return bb.GetVal()
4857 enddef
4858
4859 assert_equal(100, A.sval)
4860 assert_equal(200, B.sval)
4861 var a = A.new()
4862 assert_equal(100, a.GetVal())
4863 var b = B.new()
4864 assert_equal(100, b.GetVal())
4865 assert_equal(100, T1(b))
4866 assert_equal(100, T2(b))
4867 END
4868 v9.CheckSourceSuccess(lines)
4869enddef
4870
4871" Test for calling an instance method using the class
4872def Test_instance_method_call_using_class()
4873 # Invoke an object method using a class in script context
4874 var lines =<< trim END
4875 vim9script
4876 class A
4877 def Foo()
4878 echo "foo"
4879 enddef
4880 endclass
4881 A.Foo()
4882 END
4883 v9.CheckSourceFailure(lines, 'E1376: Object member "Foo" accessible only using class "A" object')
4884
4885 # Invoke an object method using a class in def function context
4886 lines =<< trim END
4887 vim9script
4888 class A
4889 def Foo()
4890 echo "foo"
4891 enddef
4892 endclass
4893 def T()
4894 A.Foo()
4895 enddef
4896 T()
4897 END
4898 v9.CheckSourceFailure(lines, 'E1376: Object member "Foo" accessible only using class "A" object')
4899enddef
4900
4901" Test for duplicate class method and instance method
4902def Test_dup_classmethod_objmethod()
4903 # Duplicate instance method
4904 var lines =<< trim END
4905 vim9script
4906 class A
4907 static def Foo()
4908 enddef
4909 def Foo()
4910 enddef
4911 endclass
4912 END
4913 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo')
4914
4915 # Duplicate private instance method
4916 lines =<< trim END
4917 vim9script
4918 class A
4919 static def Foo()
4920 enddef
4921 def _Foo()
4922 enddef
4923 endclass
4924 END
4925 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
4926
4927 # Duplicate class method
4928 lines =<< trim END
4929 vim9script
4930 class A
4931 def Foo()
4932 enddef
4933 static def Foo()
4934 enddef
4935 endclass
4936 END
4937 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: Foo')
4938
4939 # Duplicate private class method
4940 lines =<< trim END
4941 vim9script
4942 class A
4943 def Foo()
4944 enddef
4945 static def _Foo()
4946 enddef
4947 endclass
4948 END
4949 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
4950
4951 # Duplicate private class and object method
4952 lines =<< trim END
4953 vim9script
4954 class A
4955 def _Foo()
4956 enddef
4957 static def _Foo()
4958 enddef
4959 endclass
4960 END
4961 v9.CheckSourceFailure(lines, 'E1355: Duplicate function: _Foo')
4962enddef
4963
4964" Test for an instance method access level comparison with parent instance
4965" methods.
4966def Test_instance_method_access_level()
4967 # Private method in subclass
4968 var lines =<< trim END
4969 vim9script
4970 class A
4971 def Foo()
4972 enddef
4973 endclass
4974 class B extends A
4975 endclass
4976 class C extends B
4977 def _Foo()
4978 enddef
4979 endclass
4980 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02004981 v9.CheckSourceFailure(lines, 'E1377: Access level of method "_Foo" is different in class "A"')
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004982
4983 # Public method in subclass
4984 lines =<< trim END
4985 vim9script
4986 class A
4987 def _Foo()
4988 enddef
4989 endclass
4990 class B extends A
4991 endclass
4992 class C extends B
4993 def Foo()
4994 enddef
4995 endclass
4996 END
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02004997 v9.CheckSourceFailure(lines, 'E1377: Access level of method "Foo" is different in class "A"')
Yegappan Lakshmananc30a90d2023-09-15 20:14:55 +02004998enddef
4999
5000def Test_extend_empty_class()
5001 var lines =<< trim END
5002 vim9script
5003 class A
5004 endclass
5005 class B extends A
5006 endclass
5007 class C extends B
5008 public static rw_class_var = 1
5009 public this.rw_obj_var = 2
5010 static def ClassMethod(): number
5011 return 3
5012 enddef
5013 def ObjMethod(): number
5014 return 4
5015 enddef
5016 endclass
5017 assert_equal(1, C.rw_class_var)
5018 assert_equal(3, C.ClassMethod())
5019 var c = C.new()
5020 assert_equal(2, c.rw_obj_var)
5021 assert_equal(4, c.ObjMethod())
5022 END
5023 v9.CheckSourceSuccess(lines)
Yegappan Lakshmanan342f4f62023-09-09 11:37:23 +02005024enddef
5025
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005026" A interface cannot have a static variable or a static method or a private
5027" variable or a private method
5028def Test_interface_with_unsupported_members()
5029 var lines =<< trim END
5030 vim9script
5031 interface A
5032 static num: number
5033 endinterface
5034 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005035 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface')
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005036
5037 lines =<< trim END
5038 vim9script
5039 interface A
5040 static _num: number
5041 endinterface
5042 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005043 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface')
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005044
5045 lines =<< trim END
5046 vim9script
5047 interface A
5048 public static num: number
5049 endinterface
5050 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005051 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface')
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005052
5053 lines =<< trim END
5054 vim9script
5055 interface A
5056 public static _num: number
5057 endinterface
5058 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005059 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface')
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005060
5061 lines =<< trim END
5062 vim9script
5063 interface A
5064 static def Foo(d: dict<any>): list<string>
5065 endinterface
5066 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005067 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface')
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005068
5069 lines =<< trim END
5070 vim9script
5071 interface A
5072 static def _Foo(d: dict<any>): list<string>
5073 endinterface
5074 END
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005075 v9.CheckSourceFailure(lines, 'E1378: Static member not supported in an interface')
Yegappan Lakshmanan92d9ee52023-09-17 17:03:19 +02005076
5077 lines =<< trim END
5078 vim9script
5079 interface A
5080 this._Foo: list<string>
5081 endinterface
5082 END
5083 v9.CheckSourceFailure(lines, 'E1379: Private variable not supported in an interface')
5084
5085 lines =<< trim END
5086 vim9script
5087 interface A
5088 def _Foo(d: dict<any>): list<string>
5089 endinterface
5090 END
5091 v9.CheckSourceFailure(lines, 'E1380: Private method not supported in an interface')
5092enddef
5093
5094" Test for extending an interface
5095def Test_extend_interface()
5096 var lines =<< trim END
5097 vim9script
5098 interface A
5099 this.var1: list<string>
5100 def Foo()
5101 endinterface
5102 interface B extends A
5103 public this.var2: dict<string>
5104 def Bar()
5105 endinterface
5106 class C implements A, B
5107 this.var1 = [1, 2]
5108 def Foo()
5109 enddef
5110 public this.var2 = {a: '1'}
5111 def Bar()
5112 enddef
5113 endclass
5114 END
5115 v9.CheckSourceSuccess(lines)
5116
5117 lines =<< trim END
5118 vim9script
5119 interface A
5120 def Foo()
5121 endinterface
5122 interface B extends A
5123 public this.var2: dict<string>
5124 endinterface
5125 class C implements A, B
5126 public this.var2 = {a: '1'}
5127 endclass
5128 END
5129 v9.CheckSourceFailure(lines, 'E1349: Method "Foo" of interface "A" is not implemented')
5130
5131 lines =<< trim END
5132 vim9script
5133 interface A
5134 def Foo()
5135 endinterface
5136 interface B extends A
5137 public this.var2: dict<string>
5138 endinterface
5139 class C implements A, B
5140 def Foo()
5141 enddef
5142 endclass
5143 END
5144 v9.CheckSourceFailure(lines, 'E1348: Member "var2" of interface "B" is not implemented')
5145
5146 # interface cannot extend a class
5147 lines =<< trim END
5148 vim9script
5149 class A
5150 endclass
5151 interface B extends A
5152 endinterface
5153 END
5154 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A')
5155
5156 # class cannot extend an interface
5157 lines =<< trim END
5158 vim9script
5159 interface A
5160 endinterface
5161 class B extends A
5162 endclass
5163 END
5164 v9.CheckSourceFailure(lines, 'E1354: Cannot extend A')
5165
5166 # interface cannot implement another interface
5167 lines =<< trim END
5168 vim9script
5169 interface A
5170 endinterface
5171 interface B implements A
5172 endinterface
5173 END
5174 v9.CheckSourceFailure(lines, 'E1381: Interface cannot use "implements"')
5175
5176 # interface cannot extend multiple interfaces
5177 lines =<< trim END
5178 vim9script
5179 interface A
5180 endinterface
5181 interface B
5182 endinterface
5183 interface C extends A, B
5184 endinterface
5185 END
5186 v9.CheckSourceFailure(lines, 'E1315: White space required after name: A, B')
5187
5188 # Variable type in an extended interface is of different type
5189 lines =<< trim END
5190 vim9script
5191 interface A
5192 this.val1: number
5193 endinterface
5194 interface B extends A
5195 this.val2: string
5196 endinterface
5197 interface C extends B
5198 this.val1: string
5199 this.val2: number
5200 endinterface
5201 END
5202 v9.CheckSourceFailure(lines, 'E1382: Member "val1": type mismatch, expected number but got string')
5203enddef
5204
5205" Test for a child class implementing an interface when some of the methods are
5206" defined in the parent class.
5207def Test_child_class_implements_interface()
5208 var lines =<< trim END
5209 vim9script
5210
5211 interface Intf
5212 def F1(): list<list<number>>
5213 def F2(): list<list<number>>
5214 def F3(): list<list<number>>
5215 this.var1: list<dict<number>>
5216 this.var2: list<dict<number>>
5217 this.var3: list<dict<number>>
5218 endinterface
5219
5220 class A
5221 def A1()
5222 enddef
5223 def F3(): list<list<number>>
5224 return [[3]]
5225 enddef
5226 this.v1: list<list<number>> = [[0]]
5227 this.var3 = [{c: 30}]
5228 endclass
5229
5230 class B extends A
5231 def B1()
5232 enddef
5233 def F2(): list<list<number>>
5234 return [[2]]
5235 enddef
5236 this.v2: list<list<number>> = [[0]]
5237 this.var2 = [{b: 20}]
5238 endclass
5239
5240 class C extends B implements Intf
5241 def C1()
5242 enddef
5243 def F1(): list<list<number>>
5244 return [[1]]
5245 enddef
5246 this.v3: list<list<number>> = [[0]]
5247 this.var1 = [{a: 10}]
5248 endclass
5249
5250 def T(if: Intf)
5251 assert_equal([[1]], if.F1())
5252 assert_equal([[2]], if.F2())
5253 assert_equal([[3]], if.F3())
5254 assert_equal([{a: 10}], if.var1)
5255 assert_equal([{b: 20}], if.var2)
5256 assert_equal([{c: 30}], if.var3)
5257 enddef
5258
5259 var c = C.new()
5260 T(c)
5261 assert_equal([[1]], c.F1())
5262 assert_equal([[2]], c.F2())
5263 assert_equal([[3]], c.F3())
5264 assert_equal([{a: 10}], c.var1)
5265 assert_equal([{b: 20}], c.var2)
5266 assert_equal([{c: 30}], c.var3)
5267 END
5268 v9.CheckSourceSuccess(lines)
5269
5270 # One of the interface methods is not found
5271 lines =<< trim END
5272 vim9script
5273
5274 interface Intf
5275 def F1()
5276 def F2()
5277 def F3()
5278 endinterface
5279
5280 class A
5281 def A1()
5282 enddef
5283 endclass
5284
5285 class B extends A
5286 def B1()
5287 enddef
5288 def F2()
5289 enddef
5290 endclass
5291
5292 class C extends B implements Intf
5293 def C1()
5294 enddef
5295 def F1()
5296 enddef
5297 endclass
5298 END
5299 v9.CheckSourceFailure(lines, 'E1349: Method "F3" of interface "Intf" is not implemented')
5300
5301 # One of the interface methods is of different type
5302 lines =<< trim END
5303 vim9script
5304
5305 interface Intf
5306 def F1()
5307 def F2()
5308 def F3()
5309 endinterface
5310
5311 class A
5312 def F3(): number
5313 return 0
5314 enddef
5315 def A1()
5316 enddef
5317 endclass
5318
5319 class B extends A
5320 def B1()
5321 enddef
5322 def F2()
5323 enddef
5324 endclass
5325
5326 class C extends B implements Intf
5327 def C1()
5328 enddef
5329 def F1()
5330 enddef
5331 endclass
5332 END
5333 v9.CheckSourceFailure(lines, 'E1383: Method "F3": type mismatch, expected func() but got func(): number')
5334
5335 # One of the interface variables is not present
5336 lines =<< trim END
5337 vim9script
5338
5339 interface Intf
5340 this.var1: list<dict<number>>
5341 this.var2: list<dict<number>>
5342 this.var3: list<dict<number>>
5343 endinterface
5344
5345 class A
5346 this.v1: list<list<number>> = [[0]]
5347 endclass
5348
5349 class B extends A
5350 this.v2: list<list<number>> = [[0]]
5351 this.var2 = [{b: 20}]
5352 endclass
5353
5354 class C extends B implements Intf
5355 this.v3: list<list<number>> = [[0]]
5356 this.var1 = [{a: 10}]
5357 endclass
5358 END
5359 v9.CheckSourceFailure(lines, 'E1348: Member "var3" of interface "Intf" is not implemented')
5360
5361 # One of the interface variables is of different type
5362 lines =<< trim END
5363 vim9script
5364
5365 interface Intf
5366 this.var1: list<dict<number>>
5367 this.var2: list<dict<number>>
5368 this.var3: list<dict<number>>
5369 endinterface
5370
5371 class A
5372 this.v1: list<list<number>> = [[0]]
5373 this.var3: list<dict<string>>
5374 endclass
5375
5376 class B extends A
5377 this.v2: list<list<number>> = [[0]]
5378 this.var2 = [{b: 20}]
5379 endclass
5380
5381 class C extends B implements Intf
5382 this.v3: list<list<number>> = [[0]]
5383 this.var1 = [{a: 10}]
5384 endclass
5385 END
5386 v9.CheckSourceFailure(lines, 'E1382: Member "var3": type mismatch, expected list<dict<number>> but got list<dict<string>>')
5387enddef
5388
5389" Test for extending an interface with duplicate variables and methods
5390def Test_interface_extends_with_dup_members()
5391 var lines =<< trim END
5392 vim9script
5393 interface A
5394 this.n1: number
5395 def Foo1(): number
5396 endinterface
5397 interface B extends A
5398 this.n2: number
5399 this.n1: number
5400 def Foo2(): number
5401 def Foo1(): number
5402 endinterface
5403 class C implements B
5404 this.n1 = 10
5405 this.n2 = 20
5406 def Foo1(): number
5407 return 30
5408 enddef
5409 def Foo2(): number
5410 return 40
5411 enddef
5412 endclass
5413 def T1(a: A)
5414 assert_equal(10, a.n1)
5415 assert_equal(30, a.Foo1())
5416 enddef
5417 def T2(b: B)
5418 assert_equal(10, b.n1)
5419 assert_equal(20, b.n2)
5420 assert_equal(30, b.Foo1())
5421 assert_equal(40, b.Foo2())
5422 enddef
5423 var c = C.new()
5424 T1(c)
5425 T2(c)
5426 END
5427 v9.CheckSourceSuccess(lines)
5428enddef
5429
5430" Test for using "any" type for a variable in a sub-class while it has a
5431" concrete type in the interface
5432def Test_implements_using_var_type_any()
5433 var lines =<< trim END
5434 vim9script
5435 interface A
5436 this.val: list<dict<string>>
5437 endinterface
5438 class B implements A
5439 this.val = [{a: '1'}, {b: '2'}]
5440 endclass
5441 var b = B.new()
5442 assert_equal([{a: '1'}, {b: '2'}], b.val)
5443 END
5444 v9.CheckSourceSuccess(lines)
5445
5446 # initialize instance variable using a different type
5447 lines =<< trim END
5448 vim9script
5449 interface A
5450 this.val: list<dict<string>>
5451 endinterface
5452 class B implements A
5453 this.val = {a: 1, b: 2}
5454 endclass
5455 var b = B.new()
5456 END
5457 v9.CheckSourceFailure(lines, 'E1382: Member "val": type mismatch, expected list<dict<string>> but got dict<number>')
5458enddef
5459
Yegappan Lakshmanan00cd1822023-09-18 19:56:49 +02005460" Test for assigning to a member variable in a nested class
5461def Test_nested_object_assignment()
5462 var lines =<< trim END
5463 vim9script
5464
5465 class A
5466 this.value: number
5467 endclass
5468
5469 class B
5470 this.a: A = A.new()
5471 endclass
5472
5473 class C
5474 this.b: B = B.new()
5475 endclass
5476
5477 class D
5478 this.c: C = C.new()
5479 endclass
5480
5481 def T(da: D)
5482 da.c.b.a.value = 10
5483 enddef
5484
5485 var d = D.new()
5486 T(d)
5487 END
5488 v9.CheckSourceFailure(lines, 'E46: Cannot change read-only variable "value"')
5489enddef
5490
Bram Moolenaar00b28d62022-12-08 15:32:33 +00005491" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker