blob: 184e96de0cec15617a56bcda8fed71fe59cde60c [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()
7 var lines =<< trim END
8 class NotWorking
9 endclass
10 END
11 v9.CheckScriptFailure(lines, 'E1316:')
12
13 lines =<< trim END
14 vim9script
15 class notWorking
16 endclass
17 END
18 v9.CheckScriptFailure(lines, 'E1314:')
19
20 lines =<< trim END
21 vim9script
22 class Not@working
23 endclass
24 END
25 v9.CheckScriptFailure(lines, 'E1315:')
26
27 lines =<< trim END
28 vim9script
29 abstract noclass Something
30 endclass
31 END
32 v9.CheckScriptFailure(lines, 'E475:')
33
34 lines =<< trim END
35 vim9script
36 abstract classy Something
37 endclass
38 END
39 v9.CheckScriptFailure(lines, 'E475:')
40
41 lines =<< trim END
42 vim9script
43 class Something
44 endcl
45 END
46 v9.CheckScriptFailure(lines, 'E1065:')
47
48 lines =<< trim END
49 vim9script
50 class Something
Bram Moolenaar94722c52023-01-28 19:19:03 +000051 endclass school's out
Bram Moolenaar00b28d62022-12-08 15:32:33 +000052 END
53 v9.CheckScriptFailure(lines, 'E488:')
54
55 lines =<< trim END
56 vim9script
57 class Something
58 endclass | echo 'done'
59 END
60 v9.CheckScriptFailure(lines, 'E488:')
61
62 lines =<< trim END
63 vim9script
64 class Something
65 this
66 endclass
67 END
68 v9.CheckScriptFailure(lines, 'E1317:')
69
70 lines =<< trim END
71 vim9script
72 class Something
73 this.
74 endclass
75 END
76 v9.CheckScriptFailure(lines, 'E1317:')
77
78 lines =<< trim END
79 vim9script
80 class Something
81 this .count
82 endclass
83 END
84 v9.CheckScriptFailure(lines, 'E1317:')
85
86 lines =<< trim END
87 vim9script
88 class Something
89 this. count
90 endclass
91 END
92 v9.CheckScriptFailure(lines, 'E1317:')
93
94 lines =<< trim END
95 vim9script
96 class Something
97 this.count: number
98 that.count
99 endclass
100 END
101 v9.CheckScriptFailure(lines, 'E1318: Not a valid command in a class: that.count')
102
103 lines =<< trim END
104 vim9script
105 class Something
106 this.count
107 endclass
108 END
109 v9.CheckScriptFailure(lines, 'E1022:')
110
111 lines =<< trim END
112 vim9script
113 class Something
Bram Moolenaarf54cedd2022-12-23 17:56:27 +0000114 def new()
115 this.state = 0
116 enddef
117 endclass
118 var obj = Something.new()
119 END
120 v9.CheckScriptFailure(lines, 'E1089:')
121
122 lines =<< trim END
123 vim9script
124 class Something
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000125 this.count : number
126 endclass
127 END
128 v9.CheckScriptFailure(lines, 'E1059:')
129
130 lines =<< trim END
131 vim9script
132 class Something
133 this.count:number
134 endclass
135 END
136 v9.CheckScriptFailure(lines, 'E1069:')
137
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200138 # Test for unsupported comment specifier
139 lines =<< trim END
140 vim9script
141 class Something
142 # comment
143 #{
144 endclass
145 END
146 v9.CheckScriptFailure(lines, 'E1170:')
147
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000148 lines =<< trim END
149 vim9script
150
151 class TextPosition
152 this.lnum: number
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000153 this.col: number
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000154
Bram Moolenaar418b5472022-12-20 13:38:22 +0000155 # make a nicely formatted string
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000156 def ToString(): string
157 return $'({this.lnum}, {this.col})'
158 enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000159 endclass
160
Bram Moolenaard28d7b92022-12-08 20:42:00 +0000161 # use the automatically generated new() method
162 var pos = TextPosition.new(2, 12)
163 assert_equal(2, pos.lnum)
164 assert_equal(12, pos.col)
Bram Moolenaarffdaca92022-12-09 21:41:48 +0000165
166 # call an object method
167 assert_equal('(2, 12)', pos.ToString())
Bram Moolenaarc0c2c262023-01-12 21:08:53 +0000168
169 assert_equal(v:t_class, type(TextPosition))
170 assert_equal(v:t_object, type(pos))
171 assert_equal('class<TextPosition>', typename(TextPosition))
172 assert_equal('object<TextPosition>', typename(pos))
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000173 END
174 v9.CheckScriptSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200175
176 # When referencing object methods, space cannot be used after a "."
177 lines =<< trim END
178 vim9script
179 class A
180 def Foo(): number
181 return 10
182 enddef
183 endclass
184 var a = A.new()
185 var v = a. Foo()
186 END
187 v9.CheckScriptFailure(lines, 'E1202:')
188
189 # Using an object without specifying a method or a member variable
190 lines =<< trim END
191 vim9script
192 class A
193 def Foo(): number
194 return 10
195 enddef
196 endclass
197 var a = A.new()
198 var v = a.
199 END
200 v9.CheckScriptFailure(lines, 'E15:')
201
202 # Error when parsing the arguments of an object method.
203 lines =<< trim END
204 vim9script
205 class A
206 def Foo()
207 enddef
208 endclass
209 var a = A.new()
210 var v = a.Foo(,)
211 END
212 v9.CheckScriptFailure(lines, 'E15:')
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200213
214 lines =<< trim END
215 vim9script
216 class A
217 this.y = {
218 X: 1
219 }
220 endclass
221 var a = A.new()
222 END
223 v9.CheckScriptSuccess(lines)
Bram Moolenaar00b28d62022-12-08 15:32:33 +0000224enddef
225
Bram Moolenaar83ae6152023-02-25 19:59:31 +0000226def Test_class_defined_twice()
227 # class defined twice should fail
228 var lines =<< trim END
229 vim9script
230 class There
231 endclass
232 class There
233 endclass
234 END
235 v9.CheckScriptFailure(lines, 'E1041: Redefining script item: "There"')
236
237 # one class, reload same script twice is OK
238 lines =<< trim END
239 vim9script
240 class There
241 endclass
242 END
243 writefile(lines, 'XclassTwice.vim', 'D')
244 source XclassTwice.vim
245 source XclassTwice.vim
246enddef
247
Bram Moolenaarc4e1b862023-02-26 18:58:23 +0000248def Test_returning_null_object()
249 # this was causing an internal error
250 var lines =<< trim END
251 vim9script
252
253 class BufferList
254 def Current(): any
255 return null_object
256 enddef
257 endclass
258
259 var buffers = BufferList.new()
260 echo buffers.Current()
261 END
262 v9.CheckScriptSuccess(lines)
263enddef
264
Bram Moolenaard13dd302023-03-11 20:56:35 +0000265def Test_using_null_class()
266 var lines =<< trim END
267 @_ = null_class.member
268 END
269 v9.CheckDefExecAndScriptFailure(lines, ['E715:', 'E1363:'])
270enddef
271
Bram Moolenaar657aea72023-01-27 13:16:19 +0000272def Test_class_interface_wrong_end()
273 var lines =<< trim END
274 vim9script
275 abstract class SomeName
276 this.member = 'text'
277 endinterface
278 END
279 v9.CheckScriptFailure(lines, 'E476: Invalid command: endinterface, expected endclass')
280
281 lines =<< trim END
282 vim9script
283 export interface AnotherName
284 this.member: string
285 endclass
286 END
287 v9.CheckScriptFailure(lines, 'E476: Invalid command: endclass, expected endinterface')
288enddef
289
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000290def Test_object_not_set()
291 var lines =<< trim END
292 vim9script
293
294 class State
295 this.value = 'xyz'
296 endclass
297
Bram Moolenaarf2017f22023-02-17 21:29:57 +0000298 var state: State
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000299 var db = {'xyz': 789}
300 echo db[state.value]
301 END
302 v9.CheckScriptFailure(lines, 'E1360:')
Bram Moolenaar0917e862023-02-18 14:42:44 +0000303
304 lines =<< trim END
305 vim9script
306
Bram Moolenaarc3f971f2023-03-02 17:38:33 +0000307 class Class
308 this.id: string
309 def Method1()
310 echo 'Method1' .. this.id
311 enddef
312 endclass
313
314 var obj: Class
315 def Func()
316 obj.Method1()
317 enddef
318 Func()
319 END
320 v9.CheckScriptFailure(lines, 'E1360:')
321
322 lines =<< trim END
323 vim9script
324
Bram Moolenaar0917e862023-02-18 14:42:44 +0000325 class Background
326 this.background = 'dark'
327 endclass
328
329 class Colorscheme
330 this._bg: Background
331
332 def GetBackground(): string
333 return this._bg.background
334 enddef
335 endclass
336
337 var bg: Background # UNINITIALIZED
338 echo Colorscheme.new(bg).GetBackground()
339 END
Ernie Rael5c018be2023-08-27 18:40:26 +0200340 v9.CheckScriptFailure(lines, 'E1360:')
Ernie Raelf77a7f72023-03-03 15:05:30 +0000341
342 # TODO: this should not give an error but be handled at runtime
343 lines =<< trim END
344 vim9script
345
346 class Class
347 this.id: string
348 def Method1()
349 echo 'Method1' .. this.id
350 enddef
351 endclass
352
353 var obj = null_object
354 def Func()
355 obj.Method1()
356 enddef
357 Func()
358 END
359 v9.CheckScriptFailure(lines, 'E1363:')
Bram Moolenaar552bdca2023-02-17 21:08:50 +0000360enddef
361
Ernie Rael5c018be2023-08-27 18:40:26 +0200362def Test_null_object_assign_compare()
363 var lines =<< trim END
364 vim9script
365
366 var nullo = null_object
367 def F(): any
368 return nullo
369 enddef
370 assert_equal('object<Unknown>', typename(F()))
371
372 var o0 = F()
373 assert_true(o0 == null_object)
374 assert_true(o0 == null)
375
376 var o1: any = nullo
377 assert_true(o1 == null_object)
378 assert_true(o1 == null)
379
380 def G()
381 var x = null_object
382 enddef
383
384 class C
385 endclass
386 var o2: C
387 assert_true(o2 == null_object)
388 assert_true(o2 == null)
389
390 o2 = null_object
391 assert_true(o2 == null)
392
393 o2 = C.new()
394 assert_true(o2 != null)
395
396 o2 = null_object
397 assert_true(o2 == null)
398 END
399 v9.CheckScriptSuccess(lines)
400enddef
401
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000402def Test_class_member_initializer()
403 var lines =<< trim END
404 vim9script
405
406 class TextPosition
407 this.lnum: number = 1
408 this.col: number = 1
409
Bram Moolenaar418b5472022-12-20 13:38:22 +0000410 # constructor with only the line number
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000411 def new(lnum: number)
412 this.lnum = lnum
413 enddef
414 endclass
415
416 var pos = TextPosition.new(3)
417 assert_equal(3, pos.lnum)
418 assert_equal(1, pos.col)
419
420 var instr = execute('disassemble TextPosition.new')
421 assert_match('new\_s*' ..
Bram Moolenaar3ea8a1b2022-12-10 19:03:51 +0000422 '0 NEW TextPosition size \d\+\_s*' ..
Bram Moolenaar7ce7daf2022-12-10 18:42:12 +0000423 '\d PUSHNR 1\_s*' ..
424 '\d STORE_THIS 0\_s*' ..
425 '\d PUSHNR 1\_s*' ..
426 '\d STORE_THIS 1\_s*' ..
427 'this.lnum = lnum\_s*' ..
428 '\d LOAD arg\[-1]\_s*' ..
429 '\d PUSHNR 0\_s*' ..
430 '\d LOAD $0\_s*' ..
431 '\d\+ STOREINDEX object\_s*' ..
432 '\d\+ RETURN object.*',
433 instr)
434 END
435 v9.CheckScriptSuccess(lines)
436enddef
437
Bram Moolenaar2c1c8032023-02-18 18:38:37 +0000438def Test_member_any_used_as_object()
439 var lines =<< trim END
440 vim9script
441
442 class Inner
443 this.value: number = 0
444 endclass
445
446 class Outer
447 this.inner: any
448 endclass
449
450 def F(outer: Outer)
451 outer.inner.value = 1
452 enddef
453
454 var inner_obj = Inner.new(0)
455 var outer_obj = Outer.new(inner_obj)
456 F(outer_obj)
457 assert_equal(1, inner_obj.value)
458 END
459 v9.CheckScriptSuccess(lines)
460
461 lines =<< trim END
462 vim9script
463
464 class Inner
465 this.value: number = 0
466 endclass
467
468 class Outer
469 this.inner: Inner
470 endclass
471
472 def F(outer: Outer)
473 outer.inner.value = 1
474 enddef
475
476 def Test_assign_to_nested_typed_member()
477 var inner = Inner.new(0)
478 var outer = Outer.new(inner)
479 F(outer)
480 assert_equal(1, inner.value)
481 enddef
482
483 Test_assign_to_nested_typed_member()
484 END
485 v9.CheckScriptSuccess(lines)
486enddef
487
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000488def Test_assignment_with_operator()
489 var lines =<< trim END
490 vim9script
491
492 class Foo
493 this.x: number
494
495 def Add(n: number)
496 this.x += n
497 enddef
498 endclass
499
500 var f = Foo.new(3)
501 f.Add(17)
502 assert_equal(20, f.x)
Bram Moolenaar22363c62023-04-24 17:15:25 +0100503
504 def AddToFoo(obj: Foo)
505 obj.x += 3
506 enddef
507
508 AddToFoo(f)
509 assert_equal(23, f.x)
Bram Moolenaar4cae8452023-01-15 15:51:48 +0000510 END
511 v9.CheckScriptSuccess(lines)
512enddef
513
Bram Moolenaarf4508042023-01-15 16:54:57 +0000514def Test_list_of_objects()
515 var lines =<< trim END
516 vim9script
517
518 class Foo
519 def Add()
520 enddef
521 endclass
522
523 def ProcessList(fooList: list<Foo>)
524 for foo in fooList
525 foo.Add()
526 endfor
527 enddef
528
529 var l: list<Foo> = [Foo.new()]
530 ProcessList(l)
531 END
532 v9.CheckScriptSuccess(lines)
533enddef
534
Bram Moolenaar912bfee2023-01-15 20:18:55 +0000535def Test_expr_after_using_object()
536 var lines =<< trim END
537 vim9script
538
539 class Something
540 this.label: string = ''
541 endclass
542
543 def Foo(): Something
544 var v = Something.new()
545 echo 'in Foo(): ' .. typename(v)
546 return v
547 enddef
548
549 Foo()
550 END
551 v9.CheckScriptSuccess(lines)
552enddef
553
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000554def Test_class_default_new()
555 var lines =<< trim END
556 vim9script
557
558 class TextPosition
559 this.lnum: number = 1
560 this.col: number = 1
561 endclass
562
563 var pos = TextPosition.new()
564 assert_equal(1, pos.lnum)
565 assert_equal(1, pos.col)
566
567 pos = TextPosition.new(v:none, v:none)
568 assert_equal(1, pos.lnum)
569 assert_equal(1, pos.col)
570
571 pos = TextPosition.new(3, 22)
572 assert_equal(3, pos.lnum)
573 assert_equal(22, pos.col)
574
575 pos = TextPosition.new(v:none, 33)
576 assert_equal(1, pos.lnum)
577 assert_equal(33, pos.col)
578 END
579 v9.CheckScriptSuccess(lines)
580
581 lines =<< trim END
582 vim9script
583 class Person
584 this.name: string
585 this.age: number = 42
586 this.education: string = "unknown"
587
588 def new(this.name, this.age = v:none, this.education = v:none)
589 enddef
590 endclass
591
592 var piet = Person.new("Piet")
593 assert_equal("Piet", piet.name)
594 assert_equal(42, piet.age)
595 assert_equal("unknown", piet.education)
596
597 var chris = Person.new("Chris", 4, "none")
598 assert_equal("Chris", chris.name)
599 assert_equal(4, chris.age)
600 assert_equal("none", chris.education)
601 END
602 v9.CheckScriptSuccess(lines)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000603
604 lines =<< trim END
605 vim9script
606 class Person
607 this.name: string
608 this.age: number = 42
609 this.education: string = "unknown"
610
611 def new(this.name, this.age = v:none, this.education = v:none)
612 enddef
613 endclass
614
615 var missing = Person.new()
616 END
617 v9.CheckScriptFailure(lines, 'E119:')
Bram Moolenaar65b0d162022-12-13 18:43:22 +0000618enddef
619
h-east2261c892023-08-16 21:49:54 +0900620
621def Test_class_new_with_object_member()
622 var lines =<< trim END
623 vim9script
624
625 class C
626 this.str: string
627 this.num: number
628 def new(this.str, this.num)
629 enddef
630 def newVals(this.str, this.num)
631 enddef
632 endclass
633
634 def Check()
635 try
636 var c = C.new('cats', 2)
637 assert_equal('cats', c.str)
638 assert_equal(2, c.num)
639
640 c = C.newVals('dogs', 4)
641 assert_equal('dogs', c.str)
642 assert_equal(4, c.num)
643 catch
644 assert_report($'Unexpected exception was caught: {v:exception}')
645 endtry
646 enddef
647
648 Check()
649 END
650 v9.CheckScriptSuccess(lines)
651
652 lines =<< trim END
653 vim9script
654
655 class C
656 this.str: string
657 this.num: number
658 def new(this.str, this.num)
659 enddef
660 endclass
661
662 def Check()
663 try
664 var c = C.new(1, 2)
665 catch
666 assert_report($'Unexpected exception was caught: {v:exception}')
667 endtry
668 enddef
669
670 Check()
671 END
672 v9.CheckScriptFailure(lines, 'E1013:')
673
674 lines =<< trim END
675 vim9script
676
677 class C
678 this.str: string
679 this.num: number
680 def newVals(this.str, this.num)
681 enddef
682 endclass
683
684 def Check()
685 try
686 var c = C.newVals('dogs', 'apes')
687 catch
688 assert_report($'Unexpected exception was caught: {v:exception}')
689 endtry
690 enddef
691
692 Check()
693 END
694 v9.CheckScriptFailure(lines, 'E1013:')
695enddef
696
Bram Moolenaar74e12742022-12-13 21:14:28 +0000697def Test_class_object_member_inits()
698 var lines =<< trim END
699 vim9script
700 class TextPosition
701 this.lnum: number
702 this.col = 1
703 this.addcol: number = 2
704 endclass
705
706 var pos = TextPosition.new()
707 assert_equal(0, pos.lnum)
708 assert_equal(1, pos.col)
709 assert_equal(2, pos.addcol)
710 END
711 v9.CheckScriptSuccess(lines)
712
713 lines =<< trim END
714 vim9script
715 class TextPosition
716 this.lnum
717 this.col = 1
718 endclass
719 END
720 v9.CheckScriptFailure(lines, 'E1022:')
721
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200722 # If the type is not specified for a member, then it should be set during
723 # object creation and not when defining the class.
Bram Moolenaar74e12742022-12-13 21:14:28 +0000724 lines =<< trim END
725 vim9script
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200726
727 var init_count = 0
728 def Init(): string
729 init_count += 1
730 return 'foo'
731 enddef
732
733 class A
734 this.str1 = Init()
735 this.str2: string = Init()
Bram Moolenaar74e12742022-12-13 21:14:28 +0000736 this.col = 1
737 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200738
739 assert_equal(init_count, 0)
740 var a = A.new()
741 assert_equal(init_count, 2)
Bram Moolenaar74e12742022-12-13 21:14:28 +0000742 END
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200743 v9.CheckScriptSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200744
745 # Test for initializing an object member with an unknown variable/type
746 lines =<< trim END
747 vim9script
748 class A
749 this.value = init_val
750 endclass
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200751 var a = A.new()
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200752 END
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +0200753 v9.CheckScriptFailure(lines, 'E1001:')
Bram Moolenaar74e12742022-12-13 21:14:28 +0000754enddef
755
Bram Moolenaar3d473ee2022-12-14 20:59:32 +0000756def Test_class_object_member_access()
757 var lines =<< trim END
758 vim9script
759 class Triple
760 this._one = 1
761 this.two = 2
762 public this.three = 3
763
764 def GetOne(): number
765 return this._one
766 enddef
767 endclass
768
769 var trip = Triple.new()
770 assert_equal(1, trip.GetOne())
771 assert_equal(2, trip.two)
772 assert_equal(3, trip.three)
773 assert_fails('echo trip._one', 'E1333')
774
775 assert_fails('trip._one = 11', 'E1333')
776 assert_fails('trip.two = 22', 'E1335')
777 trip.three = 33
778 assert_equal(33, trip.three)
Bram Moolenaard505d172022-12-18 21:42:55 +0000779
780 assert_fails('trip.four = 4', 'E1334')
781 END
782 v9.CheckScriptSuccess(lines)
Bram Moolenaar590162c2022-12-24 21:24:06 +0000783
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200784 # Test for a public member variable name beginning with an underscore
785 lines =<< trim END
786 vim9script
787 class A
788 public this._val = 10
789 endclass
790 END
791 v9.CheckScriptFailure(lines, 'E1332:')
792
Bram Moolenaar590162c2022-12-24 21:24:06 +0000793 lines =<< trim END
794 vim9script
795
796 class MyCar
797 this.make: string
Bram Moolenaar574950d2023-01-03 19:08:50 +0000798 this.age = 5
Bram Moolenaar590162c2022-12-24 21:24:06 +0000799
800 def new(make_arg: string)
801 this.make = make_arg
802 enddef
803
804 def GetMake(): string
805 return $"make = {this.make}"
806 enddef
Bram Moolenaar574950d2023-01-03 19:08:50 +0000807 def GetAge(): number
808 return this.age
809 enddef
Bram Moolenaar590162c2022-12-24 21:24:06 +0000810 endclass
811
812 var c = MyCar.new("abc")
813 assert_equal('make = abc', c.GetMake())
814
815 c = MyCar.new("def")
816 assert_equal('make = def', c.GetMake())
817
818 var c2 = MyCar.new("123")
819 assert_equal('make = 123', c2.GetMake())
Bram Moolenaar574950d2023-01-03 19:08:50 +0000820
821 def CheckCar()
822 assert_equal("make = def", c.GetMake())
823 assert_equal(5, c.GetAge())
824 enddef
825 CheckCar()
Bram Moolenaar590162c2022-12-24 21:24:06 +0000826 END
827 v9.CheckScriptSuccess(lines)
Bram Moolenaar6ef54712022-12-25 19:31:36 +0000828
829 lines =<< trim END
830 vim9script
831
832 class MyCar
833 this.make: string
834
835 def new(make_arg: string)
836 this.make = make_arg
837 enddef
838 endclass
839
840 var c = MyCar.new("abc")
841 var c = MyCar.new("def")
842 END
843 v9.CheckScriptFailure(lines, 'E1041:')
Bram Moolenaarb149d222023-01-24 13:03:37 +0000844
845 lines =<< trim END
846 vim9script
847
848 class Foo
849 this.x: list<number> = []
850
851 def Add(n: number): any
852 this.x->add(n)
853 return this
854 enddef
855 endclass
856
857 echo Foo.new().Add(1).Add(2).x
858 echo Foo.new().Add(1).Add(2)
859 .x
860 echo Foo.new().Add(1)
861 .Add(2).x
862 echo Foo.new()
863 .Add(1).Add(2).x
864 echo Foo.new()
865 .Add(1)
866 .Add(2)
867 .x
868 END
869 v9.CheckScriptSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +0200870
871 # Test for "public" cannot be abbreviated
872 lines =<< trim END
873 vim9script
874 class Something
875 pub this.val = 1
876 endclass
877 END
878 v9.CheckScriptFailure(lines, 'E1065:')
879
880 # Test for "public" keyword must be followed by "this" or "static".
881 lines =<< trim END
882 vim9script
883 class Something
884 public val = 1
885 endclass
886 END
887 v9.CheckScriptFailure(lines, 'E1331:')
888
889 # Test for "static" cannot be abbreviated
890 lines =<< trim END
891 vim9script
892 class Something
893 stat this.val = 1
894 endclass
895 END
896 v9.CheckScriptFailure(lines, 'E1065:')
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +0200897
898 # Test for "static" cannot be followed by "this".
899 lines =<< trim END
900 vim9script
901 class Something
902 static this.val = 1
903 endclass
904 END
905 v9.CheckScriptFailure(lines, 'E1368: Static cannot be followed by "this" in a member name')
Bram Moolenaard505d172022-12-18 21:42:55 +0000906enddef
907
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000908def Test_class_object_compare()
909 var class_lines =<< trim END
910 vim9script
911 class Item
912 this.nr = 0
913 this.name = 'xx'
914 endclass
915 END
916
917 # used at the script level and in a compiled function
918 var test_lines =<< trim END
919 var i1 = Item.new()
920 assert_equal(i1, i1)
921 assert_true(i1 is i1)
922 var i2 = Item.new()
923 assert_equal(i1, i2)
924 assert_false(i1 is i2)
925 var i3 = Item.new(0, 'xx')
926 assert_equal(i1, i3)
927
928 var io1 = Item.new(1, 'xx')
929 assert_notequal(i1, io1)
930 var io2 = Item.new(0, 'yy')
931 assert_notequal(i1, io2)
932 END
933
934 v9.CheckScriptSuccess(class_lines + test_lines)
Bram Moolenaar46ab9252023-01-03 14:01:21 +0000935 v9.CheckScriptSuccess(
936 class_lines + ['def Test()'] + test_lines + ['enddef', 'Test()'])
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000937
938 for op in ['>', '>=', '<', '<=', '=~', '!~']
939 var op_lines = [
940 'var i1 = Item.new()',
941 'var i2 = Item.new()',
942 'echo i1 ' .. op .. ' i2',
943 ]
944 v9.CheckScriptFailure(class_lines + op_lines, 'E1153: Invalid operation for object')
Bram Moolenaar46ab9252023-01-03 14:01:21 +0000945 v9.CheckScriptFailure(class_lines
946 + ['def Test()'] + op_lines + ['enddef', 'Test()'], 'E1153: Invalid operation for object')
Bram Moolenaarbcf31ec2023-01-02 20:32:24 +0000947 endfor
948enddef
949
Bram Moolenaar6481acc2023-01-11 21:14:17 +0000950def Test_object_type()
951 var lines =<< trim END
952 vim9script
953
954 class One
955 this.one = 1
956 endclass
957 class Two
958 this.two = 2
959 endclass
960 class TwoMore extends Two
961 this.more = 9
962 endclass
963
964 var o: One = One.new()
965 var t: Two = Two.new()
966 var m: TwoMore = TwoMore.new()
967 var tm: Two = TwoMore.new()
968
969 t = m
970 END
971 v9.CheckScriptSuccess(lines)
972
973 lines =<< trim END
974 vim9script
975
976 class One
977 this.one = 1
978 endclass
979 class Two
980 this.two = 2
981 endclass
982
983 var o: One = Two.new()
984 END
985 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<One> but got object<Two>')
Bram Moolenaara94bd9d2023-01-12 15:01:32 +0000986
987 lines =<< trim END
988 vim9script
989
990 interface One
991 def GetMember(): number
992 endinterface
993 class Two implements One
994 this.one = 1
995 def GetMember(): number
996 return this.one
997 enddef
998 endclass
999
1000 var o: One = Two.new(5)
1001 assert_equal(5, o.GetMember())
1002 END
1003 v9.CheckScriptSuccess(lines)
Bram Moolenaar450c7a92023-01-16 16:39:37 +00001004
1005 lines =<< trim END
1006 vim9script
1007
1008 class Num
1009 this.n: number = 0
1010 endclass
1011
1012 def Ref(name: string): func(Num): Num
1013 return (arg: Num): Num => {
1014 return eval(name)(arg)
1015 }
1016 enddef
1017
1018 const Fn = Ref('Double')
1019 var Double = (m: Num): Num => Num.new(m.n * 2)
1020
1021 echo Fn(Num.new(4))
1022 END
1023 v9.CheckScriptSuccess(lines)
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001024enddef
1025
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001026def Test_class_member()
1027 # check access rules
Bram Moolenaard505d172022-12-18 21:42:55 +00001028 var lines =<< trim END
1029 vim9script
1030 class TextPos
1031 this.lnum = 1
1032 this.col = 1
1033 static counter = 0
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001034 static _secret = 7
1035 public static anybody = 42
Bram Moolenaard505d172022-12-18 21:42:55 +00001036
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001037 static def AddToCounter(nr: number)
Bram Moolenaard505d172022-12-18 21:42:55 +00001038 counter += nr
1039 enddef
1040 endclass
1041
1042 assert_equal(0, TextPos.counter)
1043 TextPos.AddToCounter(3)
1044 assert_equal(3, TextPos.counter)
Bram Moolenaarf54cedd2022-12-23 17:56:27 +00001045 assert_fails('echo TextPos.noSuchMember', 'E1338:')
Bram Moolenaar94722c52023-01-28 19:19:03 +00001046
Bram Moolenaar3259ff32023-01-04 18:54:09 +00001047 def GetCounter(): number
1048 return TextPos.counter
1049 enddef
1050 assert_equal(3, GetCounter())
Bram Moolenaard505d172022-12-18 21:42:55 +00001051
Bram Moolenaarf54cedd2022-12-23 17:56:27 +00001052 assert_fails('TextPos.noSuchMember = 2', 'E1337:')
Bram Moolenaar9f2d97e2022-12-31 19:01:02 +00001053 assert_fails('TextPos.counter = 5', 'E1335:')
1054 assert_fails('TextPos.counter += 5', 'E1335:')
1055
1056 assert_fails('echo TextPos._secret', 'E1333:')
1057 assert_fails('TextPos._secret = 8', 'E1333:')
1058
1059 assert_equal(42, TextPos.anybody)
1060 TextPos.anybody = 12
1061 assert_equal(12, TextPos.anybody)
1062 TextPos.anybody += 5
1063 assert_equal(17, TextPos.anybody)
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001064 END
1065 v9.CheckScriptSuccess(lines)
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001066
Bram Moolenaar4cae8452023-01-15 15:51:48 +00001067 # example in the help
1068 lines =<< trim END
1069 vim9script
1070 class OtherThing
1071 this.size: number
1072 static totalSize: number
1073
1074 def new(this.size)
1075 totalSize += this.size
1076 enddef
1077 endclass
1078 assert_equal(0, OtherThing.totalSize)
1079 var to3 = OtherThing.new(3)
1080 assert_equal(3, OtherThing.totalSize)
1081 var to7 = OtherThing.new(7)
1082 assert_equal(10, OtherThing.totalSize)
1083 END
1084 v9.CheckScriptSuccess(lines)
1085
Bram Moolenaar4e2406c2023-06-24 19:22:21 +01001086 # using static class member twice
1087 lines =<< trim END
1088 vim9script
1089
1090 class HTML
1091 static author: string = 'John Doe'
1092
1093 static def MacroSubstitute(s: string): string
1094 return substitute(s, '{{author}}', author, 'gi')
1095 enddef
1096 endclass
1097
1098 assert_equal('some text', HTML.MacroSubstitute('some text'))
1099 assert_equal('some text', HTML.MacroSubstitute('some text'))
1100 END
1101 v9.CheckScriptSuccess(lines)
1102
Bram Moolenaar62a69232023-01-24 15:07:04 +00001103 # access private member in lambda
1104 lines =<< trim END
1105 vim9script
1106
1107 class Foo
1108 this._x: number = 0
1109
1110 def Add(n: number): number
1111 const F = (): number => this._x + n
1112 return F()
1113 enddef
1114 endclass
1115
1116 var foo = Foo.new()
1117 assert_equal(5, foo.Add(5))
1118 END
1119 v9.CheckScriptSuccess(lines)
1120
h-east2bd6a092023-05-19 19:01:17 +01001121 # access private member in lambda body
1122 lines =<< trim END
1123 vim9script
1124
1125 class Foo
1126 this._x: number = 6
1127
1128 def Add(n: number): number
1129 var Lam = () => {
1130 this._x = this._x + n
1131 }
1132 Lam()
1133 return this._x
1134 enddef
1135 endclass
1136
1137 var foo = Foo.new()
1138 assert_equal(13, foo.Add(7))
1139 END
1140 v9.CheckScriptSuccess(lines)
1141
Bram Moolenaar6acf7572023-01-01 19:53:30 +00001142 # check shadowing
1143 lines =<< trim END
1144 vim9script
1145
1146 class Some
1147 static count = 0
1148 def Method(count: number)
1149 echo count
1150 enddef
1151 endclass
1152
1153 var s = Some.new()
1154 s.Method(7)
1155 END
1156 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count')
1157
1158 lines =<< trim END
1159 vim9script
1160
1161 class Some
1162 static count = 0
1163 def Method(arg: number)
1164 var count = 3
1165 echo arg count
1166 enddef
1167 endclass
1168
1169 var s = Some.new()
1170 s.Method(7)
1171 END
1172 v9.CheckScriptFailure(lines, 'E1341: Variable already declared in the class: count')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001173
1174 # Test for using an invalid type for a member variable
1175 lines =<< trim END
1176 vim9script
1177 class A
1178 this.val: xxx
1179 endclass
1180 END
1181 v9.CheckScriptFailure(lines, 'E1010:')
1182
1183 # Test for no space before or after the '=' when initializing a member
1184 # variable
1185 lines =<< trim END
1186 vim9script
1187 class A
1188 this.val: number= 10
1189 endclass
1190 END
1191 v9.CheckScriptFailure(lines, 'E1004:')
1192 lines =<< trim END
1193 vim9script
1194 class A
1195 this.val: number =10
1196 endclass
1197 END
1198 v9.CheckScriptFailure(lines, 'E1004:')
1199
1200 # Access a non-existing member
1201 lines =<< trim END
1202 vim9script
1203 class A
1204 endclass
1205 var a = A.new()
1206 var v = a.bar
1207 END
1208 v9.CheckScriptFailure(lines, 'E1326:')
Bram Moolenaar3d473ee2022-12-14 20:59:32 +00001209enddef
1210
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001211func Test_class_garbagecollect()
1212 let lines =<< trim END
1213 vim9script
1214
1215 class Point
1216 this.p = [2, 3]
1217 static pl = ['a', 'b']
1218 static pd = {a: 'a', b: 'b'}
1219 endclass
1220
1221 echo Point.pl Point.pd
1222 call test_garbagecollect_now()
1223 echo Point.pl Point.pd
1224 END
1225 call v9.CheckScriptSuccess(lines)
Bram Moolenaarf7ca56f2023-06-05 16:53:25 +01001226
1227 let lines =<< trim END
1228 vim9script
1229
1230 interface View
1231 endinterface
1232
1233 class Widget
1234 this.view: View
1235 endclass
1236
1237 class MyView implements View
1238 this.widget: Widget
1239
1240 def new()
1241 # this will result in a circular reference to this object
1242 this.widget = Widget.new(this)
1243 enddef
1244 endclass
1245
1246 var view = MyView.new()
1247
1248 # overwrite "view", will be garbage-collected next
1249 view = MyView.new()
1250 test_garbagecollect_now()
1251 END
1252 call v9.CheckScriptSuccess(lines)
Bram Moolenaarcf760d52023-01-05 13:16:04 +00001253endfunc
1254
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001255def Test_class_function()
1256 var lines =<< trim END
1257 vim9script
1258 class Value
1259 this.value = 0
1260 static objects = 0
1261
1262 def new(v: number)
1263 this.value = v
1264 ++objects
1265 enddef
1266
1267 static def GetCount(): number
1268 return objects
1269 enddef
1270 endclass
1271
1272 assert_equal(0, Value.GetCount())
1273 var v1 = Value.new(2)
1274 assert_equal(1, Value.GetCount())
1275 var v2 = Value.new(7)
1276 assert_equal(2, Value.GetCount())
1277 END
1278 v9.CheckScriptSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001279
1280 # Test for cleaning up after a class definition failure when using class
1281 # functions.
1282 lines =<< trim END
1283 vim9script
1284 class A
1285 static def Foo()
1286 enddef
1287 aaa
1288 endclass
1289 END
1290 v9.CheckScriptFailure(lines, 'E1318:')
Bram Moolenaar6bafdd42023-01-01 12:58:33 +00001291enddef
1292
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001293def Test_class_defcompile()
1294 var lines =<< trim END
1295 vim9script
1296
1297 class C
1298 def Fo(i: number): string
1299 return i
1300 enddef
1301 endclass
1302
1303 defcompile C.Fo
1304 END
1305 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected string but got number')
1306
1307 lines =<< trim END
1308 vim9script
1309
1310 class C
1311 static def Fc(): number
1312 return 'x'
1313 enddef
1314 endclass
1315
1316 defcompile C.Fc
1317 END
1318 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected number but got string')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001319
Gianmaria Bajo4b9777a2023-08-29 22:26:30 +02001320 lines =<< trim END
1321 vim9script
1322
1323 class C
1324 static def new()
1325 enddef
1326 endclass
1327
1328 defcompile C.new
1329 END
1330 v9.CheckScriptFailure(lines, 'E1370: Cannot define a "new" function as static')
1331
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001332 # Trying to compile a function using a non-existing class variable
1333 lines =<< trim END
1334 vim9script
1335 defcompile x.Foo()
1336 END
1337 v9.CheckScriptFailure(lines, 'E475:')
1338
1339 # Trying to compile a function using a variable which is not a class
1340 lines =<< trim END
1341 vim9script
1342 var x: number
1343 defcompile x.Foo()
1344 END
1345 v9.CheckScriptFailure(lines, 'E475:')
1346
1347 # Trying to compile a function without specifying the name
1348 lines =<< trim END
1349 vim9script
1350 class A
1351 endclass
1352 defcompile A.
1353 END
1354 v9.CheckScriptFailure(lines, 'E475:')
1355
1356 # Trying to compile a non-existing class object member function
1357 lines =<< trim END
1358 vim9script
1359 class A
1360 endclass
1361 var a = A.new()
1362 defcompile a.Foo()
1363 END
1364 v9.CheckScriptFailureList(lines, ['E1334:', 'E475:'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001365enddef
1366
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00001367def Test_class_object_to_string()
1368 var lines =<< trim END
1369 vim9script
1370 class TextPosition
1371 this.lnum = 1
1372 this.col = 22
1373 endclass
1374
1375 assert_equal("class TextPosition", string(TextPosition))
1376
1377 var pos = TextPosition.new()
1378 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
1379 END
1380 v9.CheckScriptSuccess(lines)
1381enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00001382
Bram Moolenaar554d0312023-01-05 19:59:18 +00001383def Test_interface_basics()
1384 var lines =<< trim END
1385 vim9script
1386 interface Something
1387 this.value: string
1388 static count: number
1389 def GetCount(): number
1390 endinterface
1391 END
1392 v9.CheckScriptSuccess(lines)
1393
1394 lines =<< trim END
1395 interface SomethingWrong
1396 static count = 7
1397 endinterface
1398 END
1399 v9.CheckScriptFailure(lines, 'E1342:')
1400
1401 lines =<< trim END
1402 vim9script
1403
1404 interface Some
1405 static count: number
1406 def Method(count: number)
1407 endinterface
1408 END
h-east61378a12023-04-18 19:07:29 +01001409 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaard40f00c2023-01-13 17:36:49 +00001410
1411 lines =<< trim END
1412 vim9script
1413
1414 interface Some
1415 this.value: number
1416 def Method(value: number)
1417 endinterface
1418 END
h-east61378a12023-04-18 19:07:29 +01001419 # The argument name and the object member name are the same, but this is not a
1420 # problem because object members are always accessed with the "this." prefix.
1421 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001422
1423 lines =<< trim END
1424 vim9script
1425 interface somethingWrong
1426 static count = 7
1427 endinterface
1428 END
1429 v9.CheckScriptFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong')
1430
1431 lines =<< trim END
1432 vim9script
1433 interface SomethingWrong
1434 this.value: string
1435 static count = 7
1436 def GetCount(): number
1437 endinterface
1438 END
1439 v9.CheckScriptFailure(lines, 'E1344:')
1440
1441 lines =<< trim END
1442 vim9script
1443 interface SomethingWrong
1444 this.value: string
1445 static count: number
1446 def GetCount(): number
1447 return 5
1448 enddef
1449 endinterface
1450 END
1451 v9.CheckScriptFailure(lines, 'E1345: Not a valid command in an interface: return 5')
Bram Moolenaar53f54e42023-01-26 20:36:56 +00001452
1453 lines =<< trim END
1454 vim9script
1455 export interface EnterExit
1456 def Enter(): void
1457 def Exit(): void
1458 endinterface
1459 END
1460 writefile(lines, 'XdefIntf.vim', 'D')
1461
1462 lines =<< trim END
1463 vim9script
1464 import './XdefIntf.vim' as defIntf
1465 export def With(ee: defIntf.EnterExit, F: func)
1466 ee.Enter()
1467 try
1468 F()
1469 finally
1470 ee.Exit()
1471 endtry
1472 enddef
1473 END
1474 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00001475
1476 var imported =<< trim END
1477 vim9script
1478 export abstract class EnterExit
1479 def Enter(): void
1480 enddef
1481 def Exit(): void
1482 enddef
1483 endclass
1484 END
1485 writefile(imported, 'XdefIntf2.vim', 'D')
1486
1487 lines[1] = " import './XdefIntf2.vim' as defIntf"
1488 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001489enddef
1490
Bram Moolenaar94674f22023-01-06 18:42:20 +00001491def Test_class_implements_interface()
1492 var lines =<< trim END
1493 vim9script
1494
1495 interface Some
1496 static count: number
1497 def Method(nr: number)
1498 endinterface
1499
1500 class SomeImpl implements Some
1501 static count: number
1502 def Method(nr: number)
1503 echo nr
1504 enddef
1505 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001506
1507 interface Another
1508 this.member: string
1509 endinterface
1510
Bram Moolenaar83ae6152023-02-25 19:59:31 +00001511 class AnotherImpl implements Some, Another
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001512 this.member = 'abc'
1513 static count: number
1514 def Method(nr: number)
1515 echo nr
1516 enddef
1517 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00001518 END
1519 v9.CheckScriptSuccess(lines)
1520
1521 lines =<< trim END
1522 vim9script
1523
1524 interface Some
1525 static counter: number
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001526 endinterface
1527
1528 class SomeImpl implements Some implements Some
1529 static count: number
1530 endclass
1531 END
1532 v9.CheckScriptFailure(lines, 'E1350:')
1533
1534 lines =<< trim END
1535 vim9script
1536
1537 interface Some
1538 static counter: number
1539 endinterface
1540
1541 class SomeImpl implements Some, Some
1542 static count: number
1543 endclass
1544 END
1545 v9.CheckScriptFailure(lines, 'E1351: Duplicate interface after "implements": Some')
1546
1547 lines =<< trim END
1548 vim9script
1549
1550 interface Some
1551 static counter: number
Bram Moolenaar94674f22023-01-06 18:42:20 +00001552 def Method(nr: number)
1553 endinterface
1554
1555 class SomeImpl implements Some
1556 static count: number
1557 def Method(nr: number)
1558 echo nr
1559 enddef
1560 endclass
1561 END
1562 v9.CheckScriptFailure(lines, 'E1348: Member "counter" of interface "Some" not implemented')
1563
1564 lines =<< trim END
1565 vim9script
1566
1567 interface Some
1568 static count: number
1569 def Methods(nr: number)
1570 endinterface
1571
1572 class SomeImpl implements Some
1573 static count: number
1574 def Method(nr: number)
1575 echo nr
1576 enddef
1577 endclass
1578 END
1579 v9.CheckScriptFailure(lines, 'E1349: Function "Methods" of interface "Some" not implemented')
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001580
1581 # Check different order of members in class and interface works.
1582 lines =<< trim END
1583 vim9script
1584
1585 interface Result
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001586 public this.label: string
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001587 this.errpos: number
1588 endinterface
1589
1590 # order of members is opposite of interface
1591 class Failure implements Result
1592 this.errpos: number = 42
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001593 public this.label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001594 endclass
1595
1596 def Test()
1597 var result: Result = Failure.new()
1598
1599 assert_equal('label', result.label)
1600 assert_equal(42, result.errpos)
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001601
1602 result.label = 'different'
1603 assert_equal('different', result.label)
1604 assert_equal(42, result.errpos)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001605 enddef
1606
1607 Test()
1608 END
1609 v9.CheckScriptSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001610
1611 # Interface name after "extends" doesn't end in a space or NUL character
1612 lines =<< trim END
1613 vim9script
1614 interface A
1615 endinterface
1616 class B extends A"
1617 endclass
1618 END
1619 v9.CheckScriptFailure(lines, 'E1315:')
1620
1621 # Trailing characters after a class name
1622 lines =<< trim END
1623 vim9script
1624 class A bbb
1625 endclass
1626 END
1627 v9.CheckScriptFailure(lines, 'E488:')
1628
1629 # using "implements" with a non-existing class
1630 lines =<< trim END
1631 vim9script
1632 class A implements B
1633 endclass
1634 END
1635 v9.CheckScriptFailure(lines, 'E1346:')
1636
1637 # using "implements" with a regular class
1638 lines =<< trim END
1639 vim9script
1640 class A
1641 endclass
1642 class B implements A
1643 endclass
1644 END
1645 v9.CheckScriptFailure(lines, 'E1347:')
1646
1647 # using "implements" with a variable
1648 lines =<< trim END
1649 vim9script
1650 var T: number = 10
1651 class A implements T
1652 endclass
1653 END
1654 v9.CheckScriptFailure(lines, 'E1347:')
1655
1656 # all the class methods in an "interface" should be implemented
1657 lines =<< trim END
1658 vim9script
1659 interface A
1660 static def Foo()
1661 endinterface
1662 class B implements A
1663 endclass
1664 END
1665 v9.CheckScriptFailure(lines, 'E1349:')
LemonBoyc5d27442023-08-19 13:02:35 +02001666
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02001667 # implements should be followed by a white space
1668 lines =<< trim END
1669 vim9script
1670 interface A
1671 endinterface
1672 class B implements A;
1673 endclass
1674 END
1675 v9.CheckScriptFailure(lines, 'E1315:')
1676
LemonBoyc5d27442023-08-19 13:02:35 +02001677 lines =<< trim END
1678 vim9script
1679
1680 interface One
1681 static matching: bool
1682 static as_any: any
1683 static not_matching: number
1684 endinterface
1685 class Two implements One
1686 static not_matching: string
1687 static as_any: string
1688 static matching: bool
1689 endclass
1690 END
1691 v9.CheckScriptFailure(lines, 'E1406: Member "not_matching": type mismatch, expected number but got string')
1692
1693 lines =<< trim END
1694 vim9script
1695
1696 interface One
1697 def IsEven(nr: number): bool
1698 endinterface
1699 class Two implements One
1700 def IsEven(nr: number): string
1701 enddef
1702 endclass
1703 END
1704 v9.CheckScriptFailure(lines, 'E1407: Member "IsEven": type mismatch, expected func(number): bool but got func(number): string')
1705
1706 lines =<< trim END
1707 vim9script
1708
1709 interface One
1710 def IsEven(nr: number): bool
1711 endinterface
1712 class Two implements One
1713 def IsEven(nr: bool): bool
1714 enddef
1715 endclass
1716 END
1717 v9.CheckScriptFailure(lines, 'E1407: Member "IsEven": type mismatch, expected func(number): bool but got func(bool): bool')
1718
1719 lines =<< trim END
1720 vim9script
1721
1722 interface One
1723 def IsEven(nr: number): bool
1724 endinterface
1725 class Two implements One
1726 def IsEven(nr: number, ...extra: list<number>): bool
1727 enddef
1728 endclass
1729 END
1730 v9.CheckScriptFailure(lines, 'E1407: Member "IsEven": type mismatch, expected func(number): bool but got func(number, ...list<number>): bool')
Bram Moolenaar94674f22023-01-06 18:42:20 +00001731enddef
1732
Bram Moolenaard0200c82023-01-28 15:19:40 +00001733def Test_call_interface_method()
1734 var lines =<< trim END
1735 vim9script
1736 interface Base
1737 def Enter(): void
1738 endinterface
1739
1740 class Child implements Base
1741 def Enter(): void
1742 g:result ..= 'child'
1743 enddef
1744 endclass
1745
1746 def F(obj: Base)
1747 obj.Enter()
1748 enddef
1749
1750 g:result = ''
1751 F(Child.new())
1752 assert_equal('child', g:result)
1753 unlet g:result
1754 END
1755 v9.CheckScriptSuccess(lines)
1756
1757 lines =<< trim END
1758 vim9script
1759 class Base
1760 def Enter(): void
1761 g:result ..= 'base'
1762 enddef
1763 endclass
1764
1765 class Child extends Base
1766 def Enter(): void
1767 g:result ..= 'child'
1768 enddef
1769 endclass
1770
1771 def F(obj: Base)
1772 obj.Enter()
1773 enddef
1774
1775 g:result = ''
1776 F(Child.new())
1777 assert_equal('child', g:result)
1778 unlet g:result
1779 END
1780 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00001781
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00001782 # method of interface returns a value
1783 lines =<< trim END
1784 vim9script
1785 interface Base
1786 def Enter(): string
1787 endinterface
1788
1789 class Child implements Base
1790 def Enter(): string
1791 g:result ..= 'child'
1792 return "/resource"
1793 enddef
1794 endclass
1795
1796 def F(obj: Base)
1797 var r = obj.Enter()
1798 g:result ..= r
1799 enddef
1800
1801 g:result = ''
1802 F(Child.new())
1803 assert_equal('child/resource', g:result)
1804 unlet g:result
1805 END
1806 v9.CheckScriptSuccess(lines)
1807
1808 lines =<< trim END
1809 vim9script
1810 class Base
1811 def Enter(): string
1812 return null_string
1813 enddef
1814 endclass
1815
1816 class Child extends Base
1817 def Enter(): string
1818 g:result ..= 'child'
1819 return "/resource"
1820 enddef
1821 endclass
1822
1823 def F(obj: Base)
1824 var r = obj.Enter()
1825 g:result ..= r
1826 enddef
1827
1828 g:result = ''
1829 F(Child.new())
1830 assert_equal('child/resource', g:result)
1831 unlet g:result
1832 END
1833 v9.CheckScriptSuccess(lines)
1834
1835
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00001836 # No class that implements the interface.
1837 lines =<< trim END
1838 vim9script
1839
1840 interface IWithEE
1841 def Enter(): any
1842 def Exit(): void
1843 endinterface
1844
1845 def With1(ee: IWithEE, F: func)
1846 var r = ee.Enter()
1847 enddef
1848
1849 defcompile
1850 END
1851 v9.CheckScriptSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00001852enddef
1853
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00001854def Test_class_used_as_type()
1855 var lines =<< trim END
1856 vim9script
1857
1858 class Point
1859 this.x = 0
1860 this.y = 0
1861 endclass
1862
1863 var p: Point
1864 p = Point.new(2, 33)
1865 assert_equal(2, p.x)
1866 assert_equal(33, p.y)
1867 END
1868 v9.CheckScriptSuccess(lines)
1869
1870 lines =<< trim END
1871 vim9script
1872
1873 interface HasX
1874 this.x: number
1875 endinterface
1876
1877 class Point implements HasX
1878 this.x = 0
1879 this.y = 0
1880 endclass
1881
1882 var p: Point
1883 p = Point.new(2, 33)
1884 var hx = p
1885 assert_equal(2, hx.x)
1886 END
1887 v9.CheckScriptSuccess(lines)
1888
1889 lines =<< trim END
1890 vim9script
1891
1892 class Point
1893 this.x = 0
1894 this.y = 0
1895 endclass
1896
1897 var p: Point
1898 p = 'text'
1899 END
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001900 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00001901enddef
1902
Bram Moolenaar83677162023-01-08 19:54:10 +00001903def Test_class_extends()
1904 var lines =<< trim END
1905 vim9script
1906 class Base
1907 this.one = 1
1908 def GetOne(): number
1909 return this.one
1910 enddef
1911 endclass
1912 class Child extends Base
1913 this.two = 2
1914 def GetTotal(): number
1915 return this.one + this.two
1916 enddef
1917 endclass
1918 var o = Child.new()
1919 assert_equal(1, o.one)
1920 assert_equal(2, o.two)
1921 assert_equal(1, o.GetOne())
1922 assert_equal(3, o.GetTotal())
1923 END
1924 v9.CheckScriptSuccess(lines)
1925
1926 lines =<< trim END
1927 vim9script
1928 class Base
1929 this.one = 1
1930 endclass
1931 class Child extends Base
1932 this.two = 2
1933 endclass
1934 var o = Child.new(3, 44)
1935 assert_equal(3, o.one)
1936 assert_equal(44, o.two)
1937 END
1938 v9.CheckScriptSuccess(lines)
1939
1940 lines =<< trim END
1941 vim9script
1942 class Base
1943 this.one = 1
1944 endclass
1945 class Child extends Base extends Base
1946 this.two = 2
1947 endclass
1948 END
1949 v9.CheckScriptFailure(lines, 'E1352: Duplicate "extends"')
1950
1951 lines =<< trim END
1952 vim9script
1953 class Child extends BaseClass
1954 this.two = 2
1955 endclass
1956 END
1957 v9.CheckScriptFailure(lines, 'E1353: Class name not found: BaseClass')
1958
1959 lines =<< trim END
1960 vim9script
1961 var SomeVar = 99
1962 class Child extends SomeVar
1963 this.two = 2
1964 endclass
1965 END
1966 v9.CheckScriptFailure(lines, 'E1354: Cannot extend SomeVar')
Bram Moolenaar58b40092023-01-11 15:59:05 +00001967
1968 lines =<< trim END
1969 vim9script
1970 class Base
1971 this.name: string
1972 def ToString(): string
1973 return this.name
1974 enddef
1975 endclass
1976
1977 class Child extends Base
1978 this.age: number
1979 def ToString(): string
1980 return super.ToString() .. ': ' .. this.age
1981 enddef
1982 endclass
1983
1984 var o = Child.new('John', 42)
1985 assert_equal('John: 42', o.ToString())
1986 END
1987 v9.CheckScriptSuccess(lines)
Bram Moolenaar6aa09372023-01-11 17:59:38 +00001988
1989 lines =<< trim END
1990 vim9script
1991 class Child
1992 this.age: number
1993 def ToString(): number
1994 return this.age
1995 enddef
1996 def ToString(): string
1997 return this.age
1998 enddef
1999 endclass
2000 END
2001 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: ToString')
2002
2003 lines =<< trim END
2004 vim9script
2005 class Child
2006 this.age: number
2007 def ToString(): string
2008 return super .ToString() .. ': ' .. this.age
2009 enddef
2010 endclass
2011 var o = Child.new(42)
2012 echo o.ToString()
2013 END
2014 v9.CheckScriptFailure(lines, 'E1356:')
2015
2016 lines =<< trim END
2017 vim9script
2018 class Base
2019 this.name: string
2020 def ToString(): string
2021 return this.name
2022 enddef
2023 endclass
2024
2025 var age = 42
2026 def ToString(): string
2027 return super.ToString() .. ': ' .. age
2028 enddef
2029 echo ToString()
2030 END
2031 v9.CheckScriptFailure(lines, 'E1357:')
2032
2033 lines =<< trim END
2034 vim9script
2035 class Child
2036 this.age: number
2037 def ToString(): string
2038 return super.ToString() .. ': ' .. this.age
2039 enddef
2040 endclass
2041 var o = Child.new(42)
2042 echo o.ToString()
2043 END
2044 v9.CheckScriptFailure(lines, 'E1358:')
Bram Moolenaar6481acc2023-01-11 21:14:17 +00002045
2046 lines =<< trim END
2047 vim9script
2048 class Base
2049 this.name: string
2050 static def ToString(): string
2051 return 'Base class'
2052 enddef
2053 endclass
2054
2055 class Child extends Base
2056 this.age: number
2057 def ToString(): string
2058 return Base.ToString() .. ': ' .. this.age
2059 enddef
2060 endclass
2061
2062 var o = Child.new('John', 42)
2063 assert_equal('Base class: 42', o.ToString())
2064 END
2065 v9.CheckScriptSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002066
2067 lines =<< trim END
2068 vim9script
2069 class Base
2070 this.value = 1
2071 def new(init: number)
2072 this.value = number + 1
2073 enddef
2074 endclass
2075 class Child extends Base
2076 def new()
2077 this.new(3)
2078 enddef
2079 endclass
2080 var c = Child.new()
2081 END
2082 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Child": new(')
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002083
2084 # base class with more than one object member
2085 lines =<< trim END
2086 vim9script
2087
2088 class Result
2089 this.success: bool
2090 this.value: any = null
2091 endclass
2092
2093 class Success extends Result
2094 def new(this.value = v:none)
2095 this.success = true
2096 enddef
2097 endclass
2098
2099 var v = Success.new('asdf')
2100 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
2101 END
2102 v9.CheckScriptSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002103
2104 # class name after "extends" doesn't end in a space or NUL character
2105 lines =<< trim END
2106 vim9script
2107 class A
2108 endclass
2109 class B extends A"
2110 endclass
2111 END
2112 v9.CheckScriptFailure(lines, 'E1315:')
Bram Moolenaar83677162023-01-08 19:54:10 +00002113enddef
2114
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002115def Test_using_base_class()
2116 var lines =<< trim END
2117 vim9script
2118
2119 class BaseEE
2120 def Enter(): any
2121 return null
2122 enddef
2123 def Exit(resource: any): void
2124 enddef
2125 endclass
2126
2127 class ChildEE extends BaseEE
2128 def Enter(): any
2129 return 42
2130 enddef
2131
2132 def Exit(resource: number): void
2133 g:result ..= '/exit'
2134 enddef
2135 endclass
2136
2137 def With(ee: BaseEE)
2138 var r = ee.Enter()
2139 try
2140 g:result ..= r
2141 finally
2142 g:result ..= '/finally'
2143 ee.Exit(r)
2144 endtry
2145 enddef
2146
2147 g:result = ''
2148 With(ChildEE.new())
2149 assert_equal('42/finally/exit', g:result)
2150 END
2151 v9.CheckScriptSuccess(lines)
2152 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01002153
2154 # Using super, Child invokes Base method which has optional arg. #12471
2155 lines =<< trim END
2156 vim9script
2157
2158 class Base
2159 this.success: bool = false
2160 def Method(arg = 0)
2161 this.success = true
2162 enddef
2163 endclass
2164
2165 class Child extends Base
2166 def new()
2167 super.Method()
2168 enddef
2169 endclass
2170
2171 var obj = Child.new()
2172 assert_equal(true, obj.success)
2173 END
2174 v9.CheckScriptSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002175enddef
2176
2177
Bram Moolenaara86655a2023-01-12 17:06:27 +00002178def Test_class_import()
2179 var lines =<< trim END
2180 vim9script
2181 export class Animal
2182 this.kind: string
2183 this.name: string
2184 endclass
2185 END
2186 writefile(lines, 'Xanimal.vim', 'D')
2187
2188 lines =<< trim END
2189 vim9script
2190 import './Xanimal.vim' as animal
2191
2192 var a: animal.Animal
2193 a = animal.Animal.new('fish', 'Eric')
2194 assert_equal('fish', a.kind)
2195 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00002196
2197 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
2198 assert_equal('cat', b.kind)
2199 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00002200 END
2201 v9.CheckScriptSuccess(lines)
2202enddef
2203
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002204def Test_abstract_class()
2205 var lines =<< trim END
2206 vim9script
2207 abstract class Base
2208 this.name: string
2209 endclass
2210 class Person extends Base
2211 this.age: number
2212 endclass
2213 var p: Base = Person.new('Peter', 42)
2214 assert_equal('Peter', p.name)
2215 assert_equal(42, p.age)
2216 END
2217 v9.CheckScriptSuccess(lines)
2218
2219 lines =<< trim END
2220 vim9script
2221 abstract class Base
2222 this.name: string
2223 endclass
2224 class Person extends Base
2225 this.age: number
2226 endclass
2227 var p = Base.new('Peter')
2228 END
2229 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Base": new(')
2230
2231 lines =<< trim END
2232 abstract class Base
2233 this.name: string
2234 endclass
2235 END
2236 v9.CheckScriptFailure(lines, 'E1316:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002237
2238 # Abstract class cannot have a "new" function
2239 lines =<< trim END
2240 vim9script
2241 abstract class Base
2242 def new()
2243 enddef
2244 endclass
2245 END
2246 v9.CheckScriptFailure(lines, 'E1359:')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002247enddef
2248
Bram Moolenaar486fc252023-01-18 14:51:07 +00002249def Test_closure_in_class()
2250 var lines =<< trim END
2251 vim9script
2252
2253 class Foo
2254 this.y: list<string> = ['B']
2255
2256 def new()
2257 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
2258 enddef
2259 endclass
2260
2261 Foo.new()
2262 assert_equal(['A'], g:result)
2263 END
2264 v9.CheckScriptSuccess(lines)
2265enddef
2266
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002267def Test_call_constructor_from_legacy()
2268 var lines =<< trim END
2269 vim9script
2270
2271 var newCalled = 'false'
2272
2273 class A
2274 def new()
2275 newCalled = 'true'
2276 enddef
2277 endclass
2278
2279 export def F(options = {}): any
2280 return A
2281 enddef
2282
2283 g:p = F()
2284 legacy call p.new()
2285 assert_equal('true', newCalled)
2286 END
2287 v9.CheckScriptSuccess(lines)
2288enddef
2289
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00002290def Test_defer_with_object()
2291 var lines =<< trim END
2292 vim9script
2293
2294 class CWithEE
2295 def Enter()
2296 g:result ..= "entered/"
2297 enddef
2298 def Exit()
2299 g:result ..= "exited"
2300 enddef
2301 endclass
2302
2303 def With(ee: CWithEE, F: func)
2304 ee.Enter()
2305 defer ee.Exit()
2306 F()
2307 enddef
2308
2309 g:result = ''
2310 var obj = CWithEE.new()
2311 obj->With(() => {
2312 g:result ..= "called/"
2313 })
2314 assert_equal('entered/called/exited', g:result)
2315 END
2316 v9.CheckScriptSuccess(lines)
2317 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00002318
2319 lines =<< trim END
2320 vim9script
2321
2322 class BaseWithEE
2323 def Enter()
2324 g:result ..= "entered-base/"
2325 enddef
2326 def Exit()
2327 g:result ..= "exited-base"
2328 enddef
2329 endclass
2330
2331 class CWithEE extends BaseWithEE
2332 def Enter()
2333 g:result ..= "entered-child/"
2334 enddef
2335 def Exit()
2336 g:result ..= "exited-child"
2337 enddef
2338 endclass
2339
2340 def With(ee: BaseWithEE, F: func)
2341 ee.Enter()
2342 defer ee.Exit()
2343 F()
2344 enddef
2345
2346 g:result = ''
2347 var obj = CWithEE.new()
2348 obj->With(() => {
2349 g:result ..= "called/"
2350 })
2351 assert_equal('entered-child/called/exited-child', g:result)
2352 END
2353 v9.CheckScriptSuccess(lines)
2354 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00002355enddef
2356
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02002357" The following test used to crash Vim (Github issue #12676)
2358def Test_extends_method_crashes_vim()
2359 var lines =<< trim END
2360 vim9script
2361
2362 class Observer
2363 endclass
2364
2365 class Property
2366 this.value: any
2367
2368 def Set(v: any)
2369 if v != this.value
2370 this.value = v
2371 endif
2372 enddef
2373
2374 def Register(observer: Observer)
2375 enddef
2376 endclass
2377
2378 class Bool extends Property
2379 this.value: bool
2380 endclass
2381
2382 def Observe(obj: Property, who: Observer)
2383 obj.Register(who)
2384 enddef
2385
2386 var p = Bool.new(false)
2387 var myObserver = Observer.new()
2388
2389 Observe(p, myObserver)
2390
2391 p.Set(true)
2392 END
2393 v9.CheckScriptSuccess(lines)
2394enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00002395
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02002396" Test for calling a method in a class that is extended
2397def Test_call_method_in_extended_class()
2398 var lines =<< trim END
2399 vim9script
2400
2401 var prop_init_called = false
2402 var prop_register_called = false
2403
2404 class Property
2405 def Init()
2406 prop_init_called = true
2407 enddef
2408
2409 def Register()
2410 prop_register_called = true
2411 enddef
2412 endclass
2413
2414 class Bool extends Property
2415 endclass
2416
2417 def Observe(obj: Property)
2418 obj.Register()
2419 enddef
2420
2421 var p = Property.new()
2422 Observe(p)
2423
2424 p.Init()
2425 assert_true(prop_init_called)
2426 assert_true(prop_register_called)
2427 END
2428 v9.CheckScriptSuccess(lines)
2429enddef
2430
LemonBoyafe04662023-08-23 21:08:11 +02002431def Test_instanceof()
2432 var lines =<< trim END
2433 vim9script
2434
2435 class Base1
2436 endclass
2437
2438 class Base2 extends Base1
2439 endclass
2440
2441 interface Intf1
2442 endinterface
2443
2444 class Mix1 implements Intf1
2445 endclass
2446
2447 class Base3 extends Mix1
2448 endclass
2449
2450 var b1 = Base1.new()
2451 var b2 = Base2.new()
2452 var b3 = Base3.new()
2453
2454 assert_true(instanceof(b1, Base1))
2455 assert_true(instanceof(b2, Base1))
2456 assert_false(instanceof(b1, Base2))
2457 assert_true(instanceof(b3, Mix1))
2458 assert_false(instanceof(b3, []))
2459 assert_true(instanceof(b3, [Base1, Base2, Intf1]))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02002460
2461 def Foo()
2462 var a1 = Base1.new()
2463 var a2 = Base2.new()
2464 var a3 = Base3.new()
2465
2466 assert_true(instanceof(a1, Base1))
2467 assert_true(instanceof(a2, Base1))
2468 assert_false(instanceof(a1, Base2))
2469 assert_true(instanceof(a3, Mix1))
2470 assert_false(instanceof(a3, []))
2471 assert_true(instanceof(a3, [Base1, Base2, Intf1]))
2472 enddef
2473 Foo()
LemonBoyafe04662023-08-23 21:08:11 +02002474 END
2475 v9.CheckScriptSuccess(lines)
2476enddef
2477
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02002478" Test for calling a method in the parent class that is extended partially.
2479" This used to fail with the 'E118: Too many arguments for function: Text' error
2480" message (Github issue #12524).
2481def Test_call_method_in_parent_class()
2482 var lines =<< trim END
2483 vim9script
2484
2485 class Widget
2486 this._lnum: number = 1
2487
2488 def SetY(lnum: number)
2489 this._lnum = lnum
2490 enddef
2491
2492 def Text(): string
2493 return ''
2494 enddef
2495 endclass
2496
2497 class Foo extends Widget
2498 def Text(): string
2499 return '<Foo>'
2500 enddef
2501 endclass
2502
2503 def Stack(w1: Widget, w2: Widget): list<Widget>
2504 w1.SetY(1)
2505 w2.SetY(2)
2506 return [w1, w2]
2507 enddef
2508
2509 var foo1 = Foo.new()
2510 var foo2 = Foo.new()
2511 var l = Stack(foo1, foo2)
2512 END
2513 v9.CheckScriptSuccess(lines)
2514enddef
2515
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002516" Test for calling methods from three levels of classes
2517def Test_multi_level_method_call()
2518 var lines =<< trim END
2519 vim9script
2520
2521 var A_func1: number = 0
2522 var A_func2: number = 0
2523 var A_func3: number = 0
2524 var B_func2: number = 0
2525 var B_func3: number = 0
2526 var C_func3: number = 0
2527
2528 class A
2529 def Func1()
2530 A_func1 += 1
2531 enddef
2532
2533 def Func2()
2534 A_func2 += 1
2535 enddef
2536
2537 def Func3()
2538 A_func3 += 1
2539 enddef
2540 endclass
2541
2542 class B extends A
2543 def Func2()
2544 B_func2 += 1
2545 enddef
2546
2547 def Func3()
2548 B_func3 += 1
2549 enddef
2550 endclass
2551
2552 class C extends B
2553 def Func3()
2554 C_func3 += 1
2555 enddef
2556 endclass
2557
2558 def A_CallFuncs(a: A)
2559 a.Func1()
2560 a.Func2()
2561 a.Func3()
2562 enddef
2563
2564 def B_CallFuncs(b: B)
2565 b.Func1()
2566 b.Func2()
2567 b.Func3()
2568 enddef
2569
2570 def C_CallFuncs(c: C)
2571 c.Func1()
2572 c.Func2()
2573 c.Func3()
2574 enddef
2575
2576 var cobj = C.new()
2577 A_CallFuncs(cobj)
2578 B_CallFuncs(cobj)
2579 C_CallFuncs(cobj)
2580 assert_equal(3, A_func1)
2581 assert_equal(0, A_func2)
2582 assert_equal(0, A_func3)
2583 assert_equal(3, B_func2)
2584 assert_equal(0, B_func3)
2585 assert_equal(3, C_func3)
2586 END
2587 v9.CheckScriptSuccess(lines)
2588enddef
2589
2590" Test for using members from three levels of classes
2591def Test_multi_level_member_access()
2592 var lines =<< trim END
2593 vim9script
2594
2595 class A
2596 this.val1: number = 0
2597 this.val2: number = 0
2598 this.val3: number = 0
2599 endclass
2600
2601 class B extends A
2602 this.val2: number = 0
2603 this.val3: number = 0
2604 endclass
2605
2606 class C extends B
2607 this.val3: number = 0
2608 endclass
2609
2610 def A_members(a: A)
2611 a.val1 += 1
2612 a.val2 += 1
2613 a.val3 += 1
2614 enddef
2615
2616 def B_members(b: B)
2617 b.val1 += 1
2618 b.val2 += 1
2619 b.val3 += 1
2620 enddef
2621
2622 def C_members(c: C)
2623 c.val1 += 1
2624 c.val2 += 1
2625 c.val3 += 1
2626 enddef
2627
2628 var cobj = C.new()
2629 A_members(cobj)
2630 B_members(cobj)
2631 C_members(cobj)
2632 assert_equal(3, cobj.val1)
2633 assert_equal(3, cobj.val2)
2634 assert_equal(3, cobj.val3)
2635 END
2636 v9.CheckScriptSuccess(lines)
2637enddef
2638
LemonBoy0ffc17a2023-08-20 18:09:11 +02002639" Test expansion of <stack> with class methods.
2640def Test_stack_expansion_with_methods()
2641 var lines =<< trim END
2642 vim9script
2643
2644 class C
2645 def M1()
2646 F0()
2647 enddef
2648 endclass
2649
2650 def F0()
2651 assert_match('<SNR>\d\+_F\[1\]\.\.C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
2652 enddef
2653
2654 def F()
2655 C.new().M1()
2656 enddef
2657
2658 F()
2659 END
2660 v9.CheckScriptSuccess(lines)
2661enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002662
2663" Test the return type of the new() constructor
2664def Test_new_return_type()
2665 # new() uses the default return type and there is no return statement
2666 var lines =<< trim END
2667 vim9script
2668
2669 class C
2670 this._bufnr: number
2671
2672 def new(this._bufnr)
2673 if !bufexists(this._bufnr)
2674 this._bufnr = -1
2675 endif
2676 enddef
2677 endclass
2678
2679 var c = C.new(12345)
2680 assert_equal('object<C>', typename(c))
2681
2682 var v1: C
2683 v1 = C.new(12345)
2684 assert_equal('object<C>', typename(v1))
2685
2686 def F()
2687 var v2: C
2688 v2 = C.new(12345)
2689 assert_equal('object<C>', typename(v2))
2690 enddef
2691 F()
2692 END
2693 v9.CheckScriptSuccess(lines)
2694
2695 # new() uses the default return type and an empty 'return' statement
2696 lines =<< trim END
2697 vim9script
2698
2699 class C
2700 this._bufnr: number
2701
2702 def new(this._bufnr)
2703 if !bufexists(this._bufnr)
2704 this._bufnr = -1
2705 return
2706 endif
2707 enddef
2708 endclass
2709
2710 var c = C.new(12345)
2711 assert_equal('object<C>', typename(c))
2712
2713 var v1: C
2714 v1 = C.new(12345)
2715 assert_equal('object<C>', typename(v1))
2716
2717 def F()
2718 var v2: C
2719 v2 = C.new(12345)
2720 assert_equal('object<C>', typename(v2))
2721 enddef
2722 F()
2723 END
2724 v9.CheckScriptSuccess(lines)
2725
2726 # new() uses "any" return type and returns "this"
2727 lines =<< trim END
2728 vim9script
2729
2730 class C
2731 this._bufnr: number
2732
2733 def new(this._bufnr): any
2734 if !bufexists(this._bufnr)
2735 this._bufnr = -1
2736 return this
2737 endif
2738 enddef
2739 endclass
2740 END
2741 v9.CheckScriptFailure(lines, 'E1365:')
2742
2743 # new() uses 'Dict' return type and returns a Dict
2744 lines =<< trim END
2745 vim9script
2746
2747 class C
2748 this._state: dict<any>
2749
2750 def new(): dict<any>
2751 this._state = {}
2752 return this._state
2753 enddef
2754 endclass
2755
2756 var c = C.new()
2757 assert_equal('object<C>', typename(c))
2758 END
2759 v9.CheckScriptFailure(lines, 'E1365:')
2760enddef
2761
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02002762" Test for checking a member initialization type at run time.
2763def Test_runtime_type_check_for_member_init()
2764 var lines =<< trim END
2765 vim9script
2766
2767 var retnum: bool = false
2768
2769 def F(): any
2770 retnum = !retnum
2771 if retnum
2772 return 1
2773 else
2774 return "hello"
2775 endif
2776 enddef
2777
2778 class C
2779 this._foo: bool = F()
2780 endclass
2781
2782 var c1 = C.new()
2783 var c2 = C.new()
2784 END
2785 v9.CheckScriptFailure(lines, 'E1012:')
2786enddef
2787
2788" Test for locking a variable referring to an object and reassigning to another
2789" object.
2790def Test_object_lockvar()
2791 var lines =<< trim END
2792 vim9script
2793
2794 class C
2795 this.val: number
2796 def new(this.val)
2797 enddef
2798 endclass
2799
2800 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
2801 lockvar 2 some_dict
2802
2803 var current: C
2804 current = some_dict['c']
2805 assert_equal(3, current.val)
2806 current = some_dict['b']
2807 assert_equal(2, current.val)
2808
2809 def F()
2810 current = some_dict['c']
2811 enddef
2812
2813 def G()
2814 current = some_dict['b']
2815 enddef
2816
2817 F()
2818 assert_equal(3, current.val)
2819 G()
2820 assert_equal(2, current.val)
2821 END
2822 v9.CheckScriptSuccess(lines)
2823enddef
2824
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02002825" Test for a private object method
2826def Test_private_object_method()
2827 # Try calling a private method using an object (at the script level)
2828 var lines =<< trim END
2829 vim9script
2830
2831 class A
2832 def _Foo(): number
2833 return 1234
2834 enddef
2835 endclass
2836 var a = A.new()
2837 a._Foo()
2838 END
2839 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
2840
2841 # Try calling a private method using an object (from a def function)
2842 lines =<< trim END
2843 vim9script
2844
2845 class A
2846 def _Foo(): number
2847 return 1234
2848 enddef
2849 endclass
2850 def T()
2851 var a = A.new()
2852 a._Foo()
2853 enddef
2854 T()
2855 END
2856 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
2857
2858 # Use a private method from another object method (in script context)
2859 lines =<< trim END
2860 vim9script
2861
2862 class A
2863 def _Foo(): number
2864 return 1234
2865 enddef
2866 def Bar(): number
2867 return this._Foo()
2868 enddef
2869 endclass
2870 var a = A.new()
2871 assert_equal(1234, a.Bar())
2872 END
2873 v9.CheckScriptSuccess(lines)
2874
2875 # Use a private method from another object method (def function context)
2876 lines =<< trim END
2877 vim9script
2878
2879 class A
2880 def _Foo(): number
2881 return 1234
2882 enddef
2883 def Bar(): number
2884 return this._Foo()
2885 enddef
2886 endclass
2887 def T()
2888 var a = A.new()
2889 assert_equal(1234, a.Bar())
2890 enddef
2891 T()
2892 END
2893 v9.CheckScriptSuccess(lines)
2894
2895 # Try calling a private method without the "this" prefix
2896 lines =<< trim END
2897 vim9script
2898
2899 class A
2900 def _Foo(): number
2901 return 1234
2902 enddef
2903 def Bar(): number
2904 return _Foo()
2905 enddef
2906 endclass
2907 var a = A.new()
2908 a.Bar()
2909 END
2910 v9.CheckScriptFailure(lines, 'E117: Unknown function: _Foo')
2911
2912 # Try calling a private method using the class name
2913 lines =<< trim END
2914 vim9script
2915
2916 class A
2917 def _Foo(): number
2918 return 1234
2919 enddef
2920 endclass
2921 A._Foo()
2922 END
2923 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "A": _Foo()')
2924
2925 # Try to use "public" keyword when defining a private method
2926 lines =<< trim END
2927 vim9script
2928
2929 class A
2930 public def _Foo()
2931 enddef
2932 endclass
2933 var a = A.new()
2934 a._Foo()
2935 END
2936 v9.CheckScriptFailure(lines, 'E1331: Public must be followed by "this" or "static"')
2937
2938 # Define two private methods with the same name
2939 lines =<< trim END
2940 vim9script
2941
2942 class A
2943 def _Foo()
2944 enddef
2945 def _Foo()
2946 enddef
2947 endclass
2948 var a = A.new()
2949 END
2950 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: _Foo')
2951
2952 # Define a private method and a object method with the same name
2953 lines =<< trim END
2954 vim9script
2955
2956 class A
2957 def _Foo()
2958 enddef
2959 def Foo()
2960 enddef
2961 endclass
2962 var a = A.new()
2963 END
2964 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: Foo')
2965
2966 # Define an object method and a private method with the same name
2967 lines =<< trim END
2968 vim9script
2969
2970 class A
2971 def Foo()
2972 enddef
2973 def _Foo()
2974 enddef
2975 endclass
2976 var a = A.new()
2977 END
2978 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: _Foo')
2979
2980 # Call a public method and a private method from a private method
2981 lines =<< trim END
2982 vim9script
2983
2984 class A
2985 def Foo(): number
2986 return 100
2987 enddef
2988 def _Bar(): number
2989 return 200
2990 enddef
2991 def _Baz()
2992 assert_equal(100, this.Foo())
2993 assert_equal(200, this._Bar())
2994 enddef
2995 def T()
2996 this._Baz()
2997 enddef
2998 endclass
2999 var a = A.new()
3000 a.T()
3001 END
3002 v9.CheckScriptSuccess(lines)
3003
3004 # Try calling a private method from another class
3005 lines =<< trim END
3006 vim9script
3007
3008 class A
3009 def _Foo(): number
3010 return 100
3011 enddef
3012 endclass
3013 class B
3014 def Foo(): number
3015 var a = A.new()
3016 a._Foo()
3017 enddef
3018 endclass
3019 var b = B.new()
3020 b.Foo()
3021 END
3022 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
3023
3024 # Call a private object method from a child class object method
3025 lines =<< trim END
3026 vim9script
3027 class A
3028 def _Foo(): number
3029 return 1234
3030 enddef
3031 endclass
3032 class B extends A
3033 def Bar()
3034 enddef
3035 endclass
3036 class C extends B
3037 def Baz(): number
3038 return this._Foo()
3039 enddef
3040 endclass
3041 var c = C.new()
3042 assert_equal(1234, c.Baz())
3043 END
3044 v9.CheckScriptSuccess(lines)
3045
3046 # Call a private object method from a child class object
3047 lines =<< trim END
3048 vim9script
3049 class A
3050 def _Foo(): number
3051 return 1234
3052 enddef
3053 endclass
3054 class B extends A
3055 def Bar()
3056 enddef
3057 endclass
3058 class C extends B
3059 def Baz(): number
3060 enddef
3061 endclass
3062 var c = C.new()
3063 assert_equal(1234, c._Foo())
3064 END
3065 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
3066
3067 # Using "_" prefix in a method name should fail outside of a class
3068 lines =<< trim END
3069 vim9script
3070 def _Foo(): number
3071 return 1234
3072 enddef
3073 var a = _Foo()
3074 END
3075 v9.CheckScriptFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number')
3076enddef
3077
3078" Test for an private class method
3079def Test_private_class_method()
3080 # Try calling a class private method (at the script level)
3081 var lines =<< trim END
3082 vim9script
3083
3084 class A
3085 static def _Foo(): number
3086 return 1234
3087 enddef
3088 endclass
3089 A._Foo()
3090 END
3091 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
3092
3093 # Try calling a class private method (from a def function)
3094 lines =<< trim END
3095 vim9script
3096
3097 class A
3098 static def _Foo(): number
3099 return 1234
3100 enddef
3101 endclass
3102 def T()
3103 A._Foo()
3104 enddef
3105 T()
3106 END
3107 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
3108
3109 # Try calling a class private method using an object (at the script level)
3110 lines =<< trim END
3111 vim9script
3112
3113 class A
3114 static def _Foo(): number
3115 return 1234
3116 enddef
3117 endclass
3118 var a = A.new()
3119 a._Foo()
3120 END
3121 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "A": _Foo()')
3122
3123 # Try calling a class private method using an object (from a def function)
3124 lines =<< trim END
3125 vim9script
3126
3127 class A
3128 static def _Foo(): number
3129 return 1234
3130 enddef
3131 endclass
3132 def T()
3133 var a = A.new()
3134 a._Foo()
3135 enddef
3136 T()
3137 END
3138 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "A": _Foo()')
3139
3140 # Use a class private method from an object method
3141 lines =<< trim END
3142 vim9script
3143
3144 class A
3145 static def _Foo(): number
3146 return 1234
3147 enddef
3148 def Bar()
3149 assert_equal(1234, A._Foo())
3150 enddef
3151 endclass
3152 var a = A.new()
3153 a.Bar()
3154 END
3155 v9.CheckScriptSuccess(lines)
3156
3157 # Use a class private method from another class private method
3158 lines =<< trim END
3159 vim9script
3160
3161 class A
3162 static def _Foo1(): number
3163 return 1234
3164 enddef
3165 static def _Foo2()
3166 assert_equal(1234, A._Foo1())
3167 enddef
3168 def Bar()
3169 A._Foo2()
3170 enddef
3171 endclass
3172 var a = A.new()
3173 a.Bar()
3174 END
3175 v9.CheckScriptSuccess(lines)
3176
3177 # Declare a class method and a class private method with the same name
3178 lines =<< trim END
3179 vim9script
3180
3181 class A
3182 static def _Foo()
3183 enddef
3184 static def Foo()
3185 enddef
3186 endclass
3187 var a = A.new()
3188 END
3189 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: Foo')
3190
3191 # Try calling a class private method from another class
3192 lines =<< trim END
3193 vim9script
3194
3195 class A
3196 static def _Foo(): number
3197 return 1234
3198 enddef
3199 endclass
3200 class B
3201 def Foo(): number
3202 return A._Foo()
3203 enddef
3204 endclass
3205 var b = B.new()
3206 assert_equal(1234, b.Foo())
3207 END
3208 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
3209
3210 # Call a private class method from a child class object method
3211 lines =<< trim END
3212 vim9script
3213 class A
3214 static def _Foo(): number
3215 return 1234
3216 enddef
3217 endclass
3218 class B extends A
3219 def Bar()
3220 enddef
3221 endclass
3222 class C extends B
3223 def Baz(): number
3224 return A._Foo()
3225 enddef
3226 endclass
3227 var c = C.new()
3228 assert_equal(1234, c.Baz())
3229 END
3230 v9.CheckScriptSuccess(lines)
3231
3232 # Call a private class method from a child class private class method
3233 lines =<< trim END
3234 vim9script
3235 class A
3236 static def _Foo(): number
3237 return 1234
3238 enddef
3239 endclass
3240 class B extends A
3241 def Bar()
3242 enddef
3243 endclass
3244 class C extends B
3245 static def Baz(): number
3246 return A._Foo()
3247 enddef
3248 endclass
3249 assert_equal(1234, C.Baz())
3250 END
3251 v9.CheckScriptSuccess(lines)
3252
3253 # Call a private class method from a child class object
3254 lines =<< trim END
3255 vim9script
3256 class A
3257 static def _Foo(): number
3258 return 1234
3259 enddef
3260 endclass
3261 class B extends A
3262 def Bar()
3263 enddef
3264 endclass
3265 class C extends B
3266 def Baz(): number
3267 enddef
3268 endclass
3269 var c = C.new()
3270 assert_equal(1234, C._Foo())
3271 END
3272 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
3273enddef
3274
3275" Test for an interface private object_method
3276def Test_interface_private_object_method()
3277 # Implement an interface private method and use it from a public method
3278 var lines =<< trim END
3279 vim9script
3280 interface Intf
3281 def _Foo(): number
3282 endinterface
3283 class A implements Intf
3284 def _Foo(): number
3285 return 1234
3286 enddef
3287 def Bar(): number
3288 return this._Foo()
3289 enddef
3290 endclass
3291 var a = A.new()
3292 assert_equal(1234, a.Bar())
3293 END
3294 v9.CheckScriptSuccess(lines)
3295
3296 # Call an interface private class method (script context)
3297 lines =<< trim END
3298 vim9script
3299 interface Intf
3300 def _Foo(): number
3301 endinterface
3302 class A implements Intf
3303 def _Foo(): number
3304 return 1234
3305 enddef
3306 endclass
3307 var a = A.new()
3308 assert_equal(1234, a._Foo())
3309 END
3310 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
3311
3312 # Call an interface private class method (def context)
3313 lines =<< trim END
3314 vim9script
3315 interface Intf
3316 def _Foo(): number
3317 endinterface
3318 class A implements Intf
3319 def _Foo(): number
3320 return 1234
3321 enddef
3322 endclass
3323 def T()
3324 var a = A.new()
3325 assert_equal(1234, a._Foo())
3326 enddef
3327 T()
3328 END
3329 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
3330
3331 # Implement an interface private object method as a private class method
3332 lines =<< trim END
3333 vim9script
3334 interface Intf
3335 def _Foo(): number
3336 endinterface
3337 class A implements Intf
3338 static def _Foo(): number
3339 return 1234
3340 enddef
3341 endclass
3342 END
3343 v9.CheckScriptFailure(lines, 'E1349: Function "_Foo" of interface "Intf" not implemented')
3344enddef
3345
3346" Test for an interface private class method
3347def Test_interface_private_class_method()
3348 # Implement an interface private class method and use it from a public method
3349 var lines =<< trim END
3350 vim9script
3351 interface Intf
3352 static def _Foo(): number
3353 endinterface
3354 class A implements Intf
3355 static def _Foo(): number
3356 return 1234
3357 enddef
3358 def Bar(): number
3359 return A._Foo()
3360 enddef
3361 endclass
3362 var a = A.new()
3363 assert_equal(1234, a.Bar())
3364 END
3365 v9.CheckScriptSuccess(lines)
3366
3367 # Call an interface private class method (script context)
3368 lines =<< trim END
3369 vim9script
3370 interface Intf
3371 static def _Foo(): number
3372 endinterface
3373 class A implements Intf
3374 static def _Foo(): number
3375 return 1234
3376 enddef
3377 endclass
3378 assert_equal(1234, A._Foo())
3379 END
3380 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo())')
3381
3382 # Call an interface private class method (def context)
3383 lines =<< trim END
3384 vim9script
3385 interface Intf
3386 static def _Foo(): number
3387 endinterface
3388 class A implements Intf
3389 static def _Foo(): number
3390 return 1234
3391 enddef
3392 endclass
3393 def T()
3394 assert_equal(1234, A._Foo())
3395 enddef
3396 T()
3397 END
3398 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo())')
3399
3400 # Implement an interface private class method as a private object method
3401 lines =<< trim END
3402 vim9script
3403 interface Intf
3404 static def _Foo(): number
3405 endinterface
3406 class A implements Intf
3407 def _Foo(): number
3408 return 1234
3409 enddef
3410 endclass
3411 END
3412 v9.CheckScriptFailure(lines, 'E1349: Function "_Foo" of interface "Intf" not implemented')
3413enddef
3414
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02003415" Test for using the return value of a class/object method as a function
3416" argument.
3417def Test_objmethod_funcarg()
3418 var lines =<< trim END
3419 vim9script
3420
3421 class C
3422 def Foo(): string
3423 return 'foo'
3424 enddef
3425 endclass
3426
3427 def Bar(a: number, s: string): string
3428 return s
3429 enddef
3430
3431 def Baz(c: C)
3432 assert_equal('foo', Bar(10, c.Foo()))
3433 enddef
3434
3435 var t = C.new()
3436 Baz(t)
3437 END
3438 v9.CheckScriptSuccess(lines)
3439
3440 lines =<< trim END
3441 vim9script
3442
3443 class C
3444 static def Foo(): string
3445 return 'foo'
3446 enddef
3447 endclass
3448
3449 def Bar(a: number, s: string): string
3450 return s
3451 enddef
3452
3453 def Baz()
3454 assert_equal('foo', Bar(10, C.Foo()))
3455 enddef
3456
3457 Baz()
3458 END
3459 v9.CheckScriptSuccess(lines)
3460enddef
3461
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02003462" Test for declaring duplicate object and class members
3463def Test_dup_member_variable()
3464 # Duplicate member variable
3465 var lines =<< trim END
3466 vim9script
3467 class C
3468 this.val = 10
3469 this.val = 20
3470 endclass
3471 END
3472 v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
3473
3474 # Duplicate private member variable
3475 lines =<< trim END
3476 vim9script
3477 class C
3478 this._val = 10
3479 this._val = 20
3480 endclass
3481 END
3482 v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _val')
3483
3484 # Duplicate public member variable
3485 lines =<< trim END
3486 vim9script
3487 class C
3488 public this.val = 10
3489 public this.val = 20
3490 endclass
3491 END
3492 v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
3493
3494 # Duplicate private member variable
3495 lines =<< trim END
3496 vim9script
3497 class C
3498 this.val = 10
3499 this._val = 20
3500 endclass
3501 END
3502 v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _val')
3503
3504 # Duplicate public and private member variable
3505 lines =<< trim END
3506 vim9script
3507 class C
3508 this._val = 20
3509 public this.val = 10
3510 endclass
3511 END
3512 v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
3513
3514 # Duplicate class member variable
3515 lines =<< trim END
3516 vim9script
3517 class C
3518 static s: string = "abc"
3519 static _s: string = "def"
3520 endclass
3521 END
3522 v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _s')
3523
3524 # Duplicate public and private class member variable
3525 lines =<< trim END
3526 vim9script
3527 class C
3528 public static s: string = "abc"
3529 static _s: string = "def"
3530 endclass
3531 END
3532 v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _s')
3533
3534 # Duplicate class and object member variable
3535 lines =<< trim END
3536 vim9script
3537 class C
3538 static val = 10
3539 this.val = 20
3540 def new()
3541 enddef
3542 endclass
3543 var c = C.new()
3544 assert_equal(10, C.val)
3545 assert_equal(20, c.val)
3546 END
3547 v9.CheckScriptSuccess(lines)
3548enddef
3549
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003550" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker