blob: 319eb0546db5520967cf4aa12a72505f0fd6cec9 [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
1320 # Trying to compile a function using a non-existing class variable
1321 lines =<< trim END
1322 vim9script
1323 defcompile x.Foo()
1324 END
1325 v9.CheckScriptFailure(lines, 'E475:')
1326
1327 # Trying to compile a function using a variable which is not a class
1328 lines =<< trim END
1329 vim9script
1330 var x: number
1331 defcompile x.Foo()
1332 END
1333 v9.CheckScriptFailure(lines, 'E475:')
1334
1335 # Trying to compile a function without specifying the name
1336 lines =<< trim END
1337 vim9script
1338 class A
1339 endclass
1340 defcompile A.
1341 END
1342 v9.CheckScriptFailure(lines, 'E475:')
1343
1344 # Trying to compile a non-existing class object member function
1345 lines =<< trim END
1346 vim9script
1347 class A
1348 endclass
1349 var a = A.new()
1350 defcompile a.Foo()
1351 END
1352 v9.CheckScriptFailureList(lines, ['E1334:', 'E475:'])
Bram Moolenaar99a7c0d2023-02-21 19:55:14 +00001353enddef
1354
Bram Moolenaar91c9d6d2022-12-14 17:30:37 +00001355def Test_class_object_to_string()
1356 var lines =<< trim END
1357 vim9script
1358 class TextPosition
1359 this.lnum = 1
1360 this.col = 22
1361 endclass
1362
1363 assert_equal("class TextPosition", string(TextPosition))
1364
1365 var pos = TextPosition.new()
1366 assert_equal("object of TextPosition {lnum: 1, col: 22}", string(pos))
1367 END
1368 v9.CheckScriptSuccess(lines)
1369enddef
Bram Moolenaar74e12742022-12-13 21:14:28 +00001370
Bram Moolenaar554d0312023-01-05 19:59:18 +00001371def Test_interface_basics()
1372 var lines =<< trim END
1373 vim9script
1374 interface Something
1375 this.value: string
1376 static count: number
1377 def GetCount(): number
1378 endinterface
1379 END
1380 v9.CheckScriptSuccess(lines)
1381
1382 lines =<< trim END
1383 interface SomethingWrong
1384 static count = 7
1385 endinterface
1386 END
1387 v9.CheckScriptFailure(lines, 'E1342:')
1388
1389 lines =<< trim END
1390 vim9script
1391
1392 interface Some
1393 static count: number
1394 def Method(count: number)
1395 endinterface
1396 END
h-east61378a12023-04-18 19:07:29 +01001397 v9.CheckScriptFailure(lines, 'E1340: Argument already declared in the class: count', 5)
Bram Moolenaard40f00c2023-01-13 17:36:49 +00001398
1399 lines =<< trim END
1400 vim9script
1401
1402 interface Some
1403 this.value: number
1404 def Method(value: number)
1405 endinterface
1406 END
h-east61378a12023-04-18 19:07:29 +01001407 # The argument name and the object member name are the same, but this is not a
1408 # problem because object members are always accessed with the "this." prefix.
1409 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001410
1411 lines =<< trim END
1412 vim9script
1413 interface somethingWrong
1414 static count = 7
1415 endinterface
1416 END
1417 v9.CheckScriptFailure(lines, 'E1343: Interface name must start with an uppercase letter: somethingWrong')
1418
1419 lines =<< trim END
1420 vim9script
1421 interface SomethingWrong
1422 this.value: string
1423 static count = 7
1424 def GetCount(): number
1425 endinterface
1426 END
1427 v9.CheckScriptFailure(lines, 'E1344:')
1428
1429 lines =<< trim END
1430 vim9script
1431 interface SomethingWrong
1432 this.value: string
1433 static count: number
1434 def GetCount(): number
1435 return 5
1436 enddef
1437 endinterface
1438 END
1439 v9.CheckScriptFailure(lines, 'E1345: Not a valid command in an interface: return 5')
Bram Moolenaar53f54e42023-01-26 20:36:56 +00001440
1441 lines =<< trim END
1442 vim9script
1443 export interface EnterExit
1444 def Enter(): void
1445 def Exit(): void
1446 endinterface
1447 END
1448 writefile(lines, 'XdefIntf.vim', 'D')
1449
1450 lines =<< trim END
1451 vim9script
1452 import './XdefIntf.vim' as defIntf
1453 export def With(ee: defIntf.EnterExit, F: func)
1454 ee.Enter()
1455 try
1456 F()
1457 finally
1458 ee.Exit()
1459 endtry
1460 enddef
1461 END
1462 v9.CheckScriptSuccess(lines)
Bram Moolenaar657aea72023-01-27 13:16:19 +00001463
1464 var imported =<< trim END
1465 vim9script
1466 export abstract class EnterExit
1467 def Enter(): void
1468 enddef
1469 def Exit(): void
1470 enddef
1471 endclass
1472 END
1473 writefile(imported, 'XdefIntf2.vim', 'D')
1474
1475 lines[1] = " import './XdefIntf2.vim' as defIntf"
1476 v9.CheckScriptSuccess(lines)
Bram Moolenaar554d0312023-01-05 19:59:18 +00001477enddef
1478
Bram Moolenaar94674f22023-01-06 18:42:20 +00001479def Test_class_implements_interface()
1480 var lines =<< trim END
1481 vim9script
1482
1483 interface Some
1484 static count: number
1485 def Method(nr: number)
1486 endinterface
1487
1488 class SomeImpl implements Some
1489 static count: number
1490 def Method(nr: number)
1491 echo nr
1492 enddef
1493 endclass
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001494
1495 interface Another
1496 this.member: string
1497 endinterface
1498
Bram Moolenaar83ae6152023-02-25 19:59:31 +00001499 class AnotherImpl implements Some, Another
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001500 this.member = 'abc'
1501 static count: number
1502 def Method(nr: number)
1503 echo nr
1504 enddef
1505 endclass
Bram Moolenaar94674f22023-01-06 18:42:20 +00001506 END
1507 v9.CheckScriptSuccess(lines)
1508
1509 lines =<< trim END
1510 vim9script
1511
1512 interface Some
1513 static counter: number
Bram Moolenaardf8f9472023-01-07 14:51:03 +00001514 endinterface
1515
1516 class SomeImpl implements Some implements Some
1517 static count: number
1518 endclass
1519 END
1520 v9.CheckScriptFailure(lines, 'E1350:')
1521
1522 lines =<< trim END
1523 vim9script
1524
1525 interface Some
1526 static counter: number
1527 endinterface
1528
1529 class SomeImpl implements Some, Some
1530 static count: number
1531 endclass
1532 END
1533 v9.CheckScriptFailure(lines, 'E1351: Duplicate interface after "implements": Some')
1534
1535 lines =<< trim END
1536 vim9script
1537
1538 interface Some
1539 static counter: number
Bram Moolenaar94674f22023-01-06 18:42:20 +00001540 def Method(nr: number)
1541 endinterface
1542
1543 class SomeImpl implements Some
1544 static count: number
1545 def Method(nr: number)
1546 echo nr
1547 enddef
1548 endclass
1549 END
1550 v9.CheckScriptFailure(lines, 'E1348: Member "counter" of interface "Some" not implemented')
1551
1552 lines =<< trim END
1553 vim9script
1554
1555 interface Some
1556 static count: number
1557 def Methods(nr: number)
1558 endinterface
1559
1560 class SomeImpl implements Some
1561 static count: number
1562 def Method(nr: number)
1563 echo nr
1564 enddef
1565 endclass
1566 END
1567 v9.CheckScriptFailure(lines, 'E1349: Function "Methods" of interface "Some" not implemented')
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001568
1569 # Check different order of members in class and interface works.
1570 lines =<< trim END
1571 vim9script
1572
1573 interface Result
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001574 public this.label: string
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001575 this.errpos: number
1576 endinterface
1577
1578 # order of members is opposite of interface
1579 class Failure implements Result
1580 this.errpos: number = 42
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001581 public this.label: string = 'label'
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001582 endclass
1583
1584 def Test()
1585 var result: Result = Failure.new()
1586
1587 assert_equal('label', result.label)
1588 assert_equal(42, result.errpos)
Bram Moolenaarf7d1c6e2023-01-16 20:47:57 +00001589
1590 result.label = 'different'
1591 assert_equal('different', result.label)
1592 assert_equal(42, result.errpos)
Bram Moolenaar29ac5df2023-01-16 19:43:47 +00001593 enddef
1594
1595 Test()
1596 END
1597 v9.CheckScriptSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02001598
1599 # Interface name after "extends" doesn't end in a space or NUL character
1600 lines =<< trim END
1601 vim9script
1602 interface A
1603 endinterface
1604 class B extends A"
1605 endclass
1606 END
1607 v9.CheckScriptFailure(lines, 'E1315:')
1608
1609 # Trailing characters after a class name
1610 lines =<< trim END
1611 vim9script
1612 class A bbb
1613 endclass
1614 END
1615 v9.CheckScriptFailure(lines, 'E488:')
1616
1617 # using "implements" with a non-existing class
1618 lines =<< trim END
1619 vim9script
1620 class A implements B
1621 endclass
1622 END
1623 v9.CheckScriptFailure(lines, 'E1346:')
1624
1625 # using "implements" with a regular class
1626 lines =<< trim END
1627 vim9script
1628 class A
1629 endclass
1630 class B implements A
1631 endclass
1632 END
1633 v9.CheckScriptFailure(lines, 'E1347:')
1634
1635 # using "implements" with a variable
1636 lines =<< trim END
1637 vim9script
1638 var T: number = 10
1639 class A implements T
1640 endclass
1641 END
1642 v9.CheckScriptFailure(lines, 'E1347:')
1643
1644 # all the class methods in an "interface" should be implemented
1645 lines =<< trim END
1646 vim9script
1647 interface A
1648 static def Foo()
1649 endinterface
1650 class B implements A
1651 endclass
1652 END
1653 v9.CheckScriptFailure(lines, 'E1349:')
LemonBoyc5d27442023-08-19 13:02:35 +02001654
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02001655 # implements should be followed by a white space
1656 lines =<< trim END
1657 vim9script
1658 interface A
1659 endinterface
1660 class B implements A;
1661 endclass
1662 END
1663 v9.CheckScriptFailure(lines, 'E1315:')
1664
LemonBoyc5d27442023-08-19 13:02:35 +02001665 lines =<< trim END
1666 vim9script
1667
1668 interface One
1669 static matching: bool
1670 static as_any: any
1671 static not_matching: number
1672 endinterface
1673 class Two implements One
1674 static not_matching: string
1675 static as_any: string
1676 static matching: bool
1677 endclass
1678 END
1679 v9.CheckScriptFailure(lines, 'E1406: Member "not_matching": type mismatch, expected number but got string')
1680
1681 lines =<< trim END
1682 vim9script
1683
1684 interface One
1685 def IsEven(nr: number): bool
1686 endinterface
1687 class Two implements One
1688 def IsEven(nr: number): string
1689 enddef
1690 endclass
1691 END
1692 v9.CheckScriptFailure(lines, 'E1407: Member "IsEven": type mismatch, expected func(number): bool but got func(number): string')
1693
1694 lines =<< trim END
1695 vim9script
1696
1697 interface One
1698 def IsEven(nr: number): bool
1699 endinterface
1700 class Two implements One
1701 def IsEven(nr: bool): bool
1702 enddef
1703 endclass
1704 END
1705 v9.CheckScriptFailure(lines, 'E1407: Member "IsEven": type mismatch, expected func(number): bool but got func(bool): bool')
1706
1707 lines =<< trim END
1708 vim9script
1709
1710 interface One
1711 def IsEven(nr: number): bool
1712 endinterface
1713 class Two implements One
1714 def IsEven(nr: number, ...extra: list<number>): bool
1715 enddef
1716 endclass
1717 END
1718 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 +00001719enddef
1720
Bram Moolenaard0200c82023-01-28 15:19:40 +00001721def Test_call_interface_method()
1722 var lines =<< trim END
1723 vim9script
1724 interface Base
1725 def Enter(): void
1726 endinterface
1727
1728 class Child implements Base
1729 def Enter(): void
1730 g:result ..= 'child'
1731 enddef
1732 endclass
1733
1734 def F(obj: Base)
1735 obj.Enter()
1736 enddef
1737
1738 g:result = ''
1739 F(Child.new())
1740 assert_equal('child', g:result)
1741 unlet g:result
1742 END
1743 v9.CheckScriptSuccess(lines)
1744
1745 lines =<< trim END
1746 vim9script
1747 class Base
1748 def Enter(): void
1749 g:result ..= 'base'
1750 enddef
1751 endclass
1752
1753 class Child extends Base
1754 def Enter(): void
1755 g:result ..= 'child'
1756 enddef
1757 endclass
1758
1759 def F(obj: Base)
1760 obj.Enter()
1761 enddef
1762
1763 g:result = ''
1764 F(Child.new())
1765 assert_equal('child', g:result)
1766 unlet g:result
1767 END
1768 v9.CheckScriptSuccess(lines)
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00001769
Bram Moolenaar7a1bdae2023-02-04 15:45:27 +00001770 # method of interface returns a value
1771 lines =<< trim END
1772 vim9script
1773 interface Base
1774 def Enter(): string
1775 endinterface
1776
1777 class Child implements Base
1778 def Enter(): string
1779 g:result ..= 'child'
1780 return "/resource"
1781 enddef
1782 endclass
1783
1784 def F(obj: Base)
1785 var r = obj.Enter()
1786 g:result ..= r
1787 enddef
1788
1789 g:result = ''
1790 F(Child.new())
1791 assert_equal('child/resource', g:result)
1792 unlet g:result
1793 END
1794 v9.CheckScriptSuccess(lines)
1795
1796 lines =<< trim END
1797 vim9script
1798 class Base
1799 def Enter(): string
1800 return null_string
1801 enddef
1802 endclass
1803
1804 class Child extends Base
1805 def Enter(): string
1806 g:result ..= 'child'
1807 return "/resource"
1808 enddef
1809 endclass
1810
1811 def F(obj: Base)
1812 var r = obj.Enter()
1813 g:result ..= r
1814 enddef
1815
1816 g:result = ''
1817 F(Child.new())
1818 assert_equal('child/resource', g:result)
1819 unlet g:result
1820 END
1821 v9.CheckScriptSuccess(lines)
1822
1823
Bram Moolenaarb8bebd02023-01-30 20:24:23 +00001824 # No class that implements the interface.
1825 lines =<< trim END
1826 vim9script
1827
1828 interface IWithEE
1829 def Enter(): any
1830 def Exit(): void
1831 endinterface
1832
1833 def With1(ee: IWithEE, F: func)
1834 var r = ee.Enter()
1835 enddef
1836
1837 defcompile
1838 END
1839 v9.CheckScriptSuccess(lines)
Bram Moolenaard0200c82023-01-28 15:19:40 +00001840enddef
1841
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00001842def Test_class_used_as_type()
1843 var lines =<< trim END
1844 vim9script
1845
1846 class Point
1847 this.x = 0
1848 this.y = 0
1849 endclass
1850
1851 var p: Point
1852 p = Point.new(2, 33)
1853 assert_equal(2, p.x)
1854 assert_equal(33, p.y)
1855 END
1856 v9.CheckScriptSuccess(lines)
1857
1858 lines =<< trim END
1859 vim9script
1860
1861 interface HasX
1862 this.x: number
1863 endinterface
1864
1865 class Point implements HasX
1866 this.x = 0
1867 this.y = 0
1868 endclass
1869
1870 var p: Point
1871 p = Point.new(2, 33)
1872 var hx = p
1873 assert_equal(2, hx.x)
1874 END
1875 v9.CheckScriptSuccess(lines)
1876
1877 lines =<< trim END
1878 vim9script
1879
1880 class Point
1881 this.x = 0
1882 this.y = 0
1883 endclass
1884
1885 var p: Point
1886 p = 'text'
1887 END
Bram Moolenaar6481acc2023-01-11 21:14:17 +00001888 v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<Point> but got string')
Bram Moolenaareca2c5f2023-01-07 12:08:41 +00001889enddef
1890
Bram Moolenaar83677162023-01-08 19:54:10 +00001891def Test_class_extends()
1892 var lines =<< trim END
1893 vim9script
1894 class Base
1895 this.one = 1
1896 def GetOne(): number
1897 return this.one
1898 enddef
1899 endclass
1900 class Child extends Base
1901 this.two = 2
1902 def GetTotal(): number
1903 return this.one + this.two
1904 enddef
1905 endclass
1906 var o = Child.new()
1907 assert_equal(1, o.one)
1908 assert_equal(2, o.two)
1909 assert_equal(1, o.GetOne())
1910 assert_equal(3, o.GetTotal())
1911 END
1912 v9.CheckScriptSuccess(lines)
1913
1914 lines =<< trim END
1915 vim9script
1916 class Base
1917 this.one = 1
1918 endclass
1919 class Child extends Base
1920 this.two = 2
1921 endclass
1922 var o = Child.new(3, 44)
1923 assert_equal(3, o.one)
1924 assert_equal(44, o.two)
1925 END
1926 v9.CheckScriptSuccess(lines)
1927
1928 lines =<< trim END
1929 vim9script
1930 class Base
1931 this.one = 1
1932 endclass
1933 class Child extends Base extends Base
1934 this.two = 2
1935 endclass
1936 END
1937 v9.CheckScriptFailure(lines, 'E1352: Duplicate "extends"')
1938
1939 lines =<< trim END
1940 vim9script
1941 class Child extends BaseClass
1942 this.two = 2
1943 endclass
1944 END
1945 v9.CheckScriptFailure(lines, 'E1353: Class name not found: BaseClass')
1946
1947 lines =<< trim END
1948 vim9script
1949 var SomeVar = 99
1950 class Child extends SomeVar
1951 this.two = 2
1952 endclass
1953 END
1954 v9.CheckScriptFailure(lines, 'E1354: Cannot extend SomeVar')
Bram Moolenaar58b40092023-01-11 15:59:05 +00001955
1956 lines =<< trim END
1957 vim9script
1958 class Base
1959 this.name: string
1960 def ToString(): string
1961 return this.name
1962 enddef
1963 endclass
1964
1965 class Child extends Base
1966 this.age: number
1967 def ToString(): string
1968 return super.ToString() .. ': ' .. this.age
1969 enddef
1970 endclass
1971
1972 var o = Child.new('John', 42)
1973 assert_equal('John: 42', o.ToString())
1974 END
1975 v9.CheckScriptSuccess(lines)
Bram Moolenaar6aa09372023-01-11 17:59:38 +00001976
1977 lines =<< trim END
1978 vim9script
1979 class Child
1980 this.age: number
1981 def ToString(): number
1982 return this.age
1983 enddef
1984 def ToString(): string
1985 return this.age
1986 enddef
1987 endclass
1988 END
1989 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: ToString')
1990
1991 lines =<< trim END
1992 vim9script
1993 class Child
1994 this.age: number
1995 def ToString(): string
1996 return super .ToString() .. ': ' .. this.age
1997 enddef
1998 endclass
1999 var o = Child.new(42)
2000 echo o.ToString()
2001 END
2002 v9.CheckScriptFailure(lines, 'E1356:')
2003
2004 lines =<< trim END
2005 vim9script
2006 class Base
2007 this.name: string
2008 def ToString(): string
2009 return this.name
2010 enddef
2011 endclass
2012
2013 var age = 42
2014 def ToString(): string
2015 return super.ToString() .. ': ' .. age
2016 enddef
2017 echo ToString()
2018 END
2019 v9.CheckScriptFailure(lines, 'E1357:')
2020
2021 lines =<< trim END
2022 vim9script
2023 class Child
2024 this.age: number
2025 def ToString(): string
2026 return super.ToString() .. ': ' .. this.age
2027 enddef
2028 endclass
2029 var o = Child.new(42)
2030 echo o.ToString()
2031 END
2032 v9.CheckScriptFailure(lines, 'E1358:')
Bram Moolenaar6481acc2023-01-11 21:14:17 +00002033
2034 lines =<< trim END
2035 vim9script
2036 class Base
2037 this.name: string
2038 static def ToString(): string
2039 return 'Base class'
2040 enddef
2041 endclass
2042
2043 class Child extends Base
2044 this.age: number
2045 def ToString(): string
2046 return Base.ToString() .. ': ' .. this.age
2047 enddef
2048 endclass
2049
2050 var o = Child.new('John', 42)
2051 assert_equal('Base class: 42', o.ToString())
2052 END
2053 v9.CheckScriptSuccess(lines)
Bram Moolenaar4cae8452023-01-15 15:51:48 +00002054
2055 lines =<< trim END
2056 vim9script
2057 class Base
2058 this.value = 1
2059 def new(init: number)
2060 this.value = number + 1
2061 enddef
2062 endclass
2063 class Child extends Base
2064 def new()
2065 this.new(3)
2066 enddef
2067 endclass
2068 var c = Child.new()
2069 END
2070 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Child": new(')
Bram Moolenaarae3205a2023-01-15 20:49:00 +00002071
2072 # base class with more than one object member
2073 lines =<< trim END
2074 vim9script
2075
2076 class Result
2077 this.success: bool
2078 this.value: any = null
2079 endclass
2080
2081 class Success extends Result
2082 def new(this.value = v:none)
2083 this.success = true
2084 enddef
2085 endclass
2086
2087 var v = Success.new('asdf')
2088 assert_equal("object of Success {success: true, value: 'asdf'}", string(v))
2089 END
2090 v9.CheckScriptSuccess(lines)
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002091
2092 # class name after "extends" doesn't end in a space or NUL character
2093 lines =<< trim END
2094 vim9script
2095 class A
2096 endclass
2097 class B extends A"
2098 endclass
2099 END
2100 v9.CheckScriptFailure(lines, 'E1315:')
Bram Moolenaar83677162023-01-08 19:54:10 +00002101enddef
2102
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002103def Test_using_base_class()
2104 var lines =<< trim END
2105 vim9script
2106
2107 class BaseEE
2108 def Enter(): any
2109 return null
2110 enddef
2111 def Exit(resource: any): void
2112 enddef
2113 endclass
2114
2115 class ChildEE extends BaseEE
2116 def Enter(): any
2117 return 42
2118 enddef
2119
2120 def Exit(resource: number): void
2121 g:result ..= '/exit'
2122 enddef
2123 endclass
2124
2125 def With(ee: BaseEE)
2126 var r = ee.Enter()
2127 try
2128 g:result ..= r
2129 finally
2130 g:result ..= '/finally'
2131 ee.Exit(r)
2132 endtry
2133 enddef
2134
2135 g:result = ''
2136 With(ChildEE.new())
2137 assert_equal('42/finally/exit', g:result)
2138 END
2139 v9.CheckScriptSuccess(lines)
2140 unlet g:result
Ernie Rael114ec812023-06-04 18:11:35 +01002141
2142 # Using super, Child invokes Base method which has optional arg. #12471
2143 lines =<< trim END
2144 vim9script
2145
2146 class Base
2147 this.success: bool = false
2148 def Method(arg = 0)
2149 this.success = true
2150 enddef
2151 endclass
2152
2153 class Child extends Base
2154 def new()
2155 super.Method()
2156 enddef
2157 endclass
2158
2159 var obj = Child.new()
2160 assert_equal(true, obj.success)
2161 END
2162 v9.CheckScriptSuccess(lines)
Bram Moolenaar094cf9f2023-02-10 15:52:25 +00002163enddef
2164
2165
Bram Moolenaara86655a2023-01-12 17:06:27 +00002166def Test_class_import()
2167 var lines =<< trim END
2168 vim9script
2169 export class Animal
2170 this.kind: string
2171 this.name: string
2172 endclass
2173 END
2174 writefile(lines, 'Xanimal.vim', 'D')
2175
2176 lines =<< trim END
2177 vim9script
2178 import './Xanimal.vim' as animal
2179
2180 var a: animal.Animal
2181 a = animal.Animal.new('fish', 'Eric')
2182 assert_equal('fish', a.kind)
2183 assert_equal('Eric', a.name)
Bram Moolenaar40594002023-01-12 20:04:51 +00002184
2185 var b: animal.Animal = animal.Animal.new('cat', 'Garfield')
2186 assert_equal('cat', b.kind)
2187 assert_equal('Garfield', b.name)
Bram Moolenaara86655a2023-01-12 17:06:27 +00002188 END
2189 v9.CheckScriptSuccess(lines)
2190enddef
2191
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002192def Test_abstract_class()
2193 var lines =<< trim END
2194 vim9script
2195 abstract class Base
2196 this.name: string
2197 endclass
2198 class Person extends Base
2199 this.age: number
2200 endclass
2201 var p: Base = Person.new('Peter', 42)
2202 assert_equal('Peter', p.name)
2203 assert_equal(42, p.age)
2204 END
2205 v9.CheckScriptSuccess(lines)
2206
2207 lines =<< trim END
2208 vim9script
2209 abstract class Base
2210 this.name: string
2211 endclass
2212 class Person extends Base
2213 this.age: number
2214 endclass
2215 var p = Base.new('Peter')
2216 END
2217 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "Base": new(')
2218
2219 lines =<< trim END
2220 abstract class Base
2221 this.name: string
2222 endclass
2223 END
2224 v9.CheckScriptFailure(lines, 'E1316:')
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002225
2226 # Abstract class cannot have a "new" function
2227 lines =<< trim END
2228 vim9script
2229 abstract class Base
2230 def new()
2231 enddef
2232 endclass
2233 END
2234 v9.CheckScriptFailure(lines, 'E1359:')
Bram Moolenaar24a8d062023-01-14 13:12:06 +00002235enddef
2236
Bram Moolenaar486fc252023-01-18 14:51:07 +00002237def Test_closure_in_class()
2238 var lines =<< trim END
2239 vim9script
2240
2241 class Foo
2242 this.y: list<string> = ['B']
2243
2244 def new()
2245 g:result = filter(['A', 'B'], (_, v) => index(this.y, v) == -1)
2246 enddef
2247 endclass
2248
2249 Foo.new()
2250 assert_equal(['A'], g:result)
2251 END
2252 v9.CheckScriptSuccess(lines)
2253enddef
2254
Bram Moolenaar5ca05fa2023-06-10 16:45:13 +01002255def Test_call_constructor_from_legacy()
2256 var lines =<< trim END
2257 vim9script
2258
2259 var newCalled = 'false'
2260
2261 class A
2262 def new()
2263 newCalled = 'true'
2264 enddef
2265 endclass
2266
2267 export def F(options = {}): any
2268 return A
2269 enddef
2270
2271 g:p = F()
2272 legacy call p.new()
2273 assert_equal('true', newCalled)
2274 END
2275 v9.CheckScriptSuccess(lines)
2276enddef
2277
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00002278def Test_defer_with_object()
2279 var lines =<< trim END
2280 vim9script
2281
2282 class CWithEE
2283 def Enter()
2284 g:result ..= "entered/"
2285 enddef
2286 def Exit()
2287 g:result ..= "exited"
2288 enddef
2289 endclass
2290
2291 def With(ee: CWithEE, F: func)
2292 ee.Enter()
2293 defer ee.Exit()
2294 F()
2295 enddef
2296
2297 g:result = ''
2298 var obj = CWithEE.new()
2299 obj->With(() => {
2300 g:result ..= "called/"
2301 })
2302 assert_equal('entered/called/exited', g:result)
2303 END
2304 v9.CheckScriptSuccess(lines)
2305 unlet g:result
Bram Moolenaar313e4722023-02-08 20:55:27 +00002306
2307 lines =<< trim END
2308 vim9script
2309
2310 class BaseWithEE
2311 def Enter()
2312 g:result ..= "entered-base/"
2313 enddef
2314 def Exit()
2315 g:result ..= "exited-base"
2316 enddef
2317 endclass
2318
2319 class CWithEE extends BaseWithEE
2320 def Enter()
2321 g:result ..= "entered-child/"
2322 enddef
2323 def Exit()
2324 g:result ..= "exited-child"
2325 enddef
2326 endclass
2327
2328 def With(ee: BaseWithEE, F: func)
2329 ee.Enter()
2330 defer ee.Exit()
2331 F()
2332 enddef
2333
2334 g:result = ''
2335 var obj = CWithEE.new()
2336 obj->With(() => {
2337 g:result ..= "called/"
2338 })
2339 assert_equal('entered-child/called/exited-child', g:result)
2340 END
2341 v9.CheckScriptSuccess(lines)
2342 unlet g:result
Bram Moolenaar8dbab1d2023-01-27 20:14:02 +00002343enddef
2344
Yegappan Lakshmanan57a02cc2023-08-13 10:19:38 +02002345" The following test used to crash Vim (Github issue #12676)
2346def Test_extends_method_crashes_vim()
2347 var lines =<< trim END
2348 vim9script
2349
2350 class Observer
2351 endclass
2352
2353 class Property
2354 this.value: any
2355
2356 def Set(v: any)
2357 if v != this.value
2358 this.value = v
2359 endif
2360 enddef
2361
2362 def Register(observer: Observer)
2363 enddef
2364 endclass
2365
2366 class Bool extends Property
2367 this.value: bool
2368 endclass
2369
2370 def Observe(obj: Property, who: Observer)
2371 obj.Register(who)
2372 enddef
2373
2374 var p = Bool.new(false)
2375 var myObserver = Observer.new()
2376
2377 Observe(p, myObserver)
2378
2379 p.Set(true)
2380 END
2381 v9.CheckScriptSuccess(lines)
2382enddef
Bram Moolenaar00b28d62022-12-08 15:32:33 +00002383
Yegappan Lakshmanan74cc13c2023-08-13 17:41:26 +02002384" Test for calling a method in a class that is extended
2385def Test_call_method_in_extended_class()
2386 var lines =<< trim END
2387 vim9script
2388
2389 var prop_init_called = false
2390 var prop_register_called = false
2391
2392 class Property
2393 def Init()
2394 prop_init_called = true
2395 enddef
2396
2397 def Register()
2398 prop_register_called = true
2399 enddef
2400 endclass
2401
2402 class Bool extends Property
2403 endclass
2404
2405 def Observe(obj: Property)
2406 obj.Register()
2407 enddef
2408
2409 var p = Property.new()
2410 Observe(p)
2411
2412 p.Init()
2413 assert_true(prop_init_called)
2414 assert_true(prop_register_called)
2415 END
2416 v9.CheckScriptSuccess(lines)
2417enddef
2418
LemonBoyafe04662023-08-23 21:08:11 +02002419def Test_instanceof()
2420 var lines =<< trim END
2421 vim9script
2422
2423 class Base1
2424 endclass
2425
2426 class Base2 extends Base1
2427 endclass
2428
2429 interface Intf1
2430 endinterface
2431
2432 class Mix1 implements Intf1
2433 endclass
2434
2435 class Base3 extends Mix1
2436 endclass
2437
2438 var b1 = Base1.new()
2439 var b2 = Base2.new()
2440 var b3 = Base3.new()
2441
2442 assert_true(instanceof(b1, Base1))
2443 assert_true(instanceof(b2, Base1))
2444 assert_false(instanceof(b1, Base2))
2445 assert_true(instanceof(b3, Mix1))
2446 assert_false(instanceof(b3, []))
2447 assert_true(instanceof(b3, [Base1, Base2, Intf1]))
Yegappan Lakshmananb49ad282023-08-27 19:08:40 +02002448
2449 def Foo()
2450 var a1 = Base1.new()
2451 var a2 = Base2.new()
2452 var a3 = Base3.new()
2453
2454 assert_true(instanceof(a1, Base1))
2455 assert_true(instanceof(a2, Base1))
2456 assert_false(instanceof(a1, Base2))
2457 assert_true(instanceof(a3, Mix1))
2458 assert_false(instanceof(a3, []))
2459 assert_true(instanceof(a3, [Base1, Base2, Intf1]))
2460 enddef
2461 Foo()
LemonBoyafe04662023-08-23 21:08:11 +02002462 END
2463 v9.CheckScriptSuccess(lines)
2464enddef
2465
Yegappan Lakshmanana456b122023-08-16 20:14:37 +02002466" Test for calling a method in the parent class that is extended partially.
2467" This used to fail with the 'E118: Too many arguments for function: Text' error
2468" message (Github issue #12524).
2469def Test_call_method_in_parent_class()
2470 var lines =<< trim END
2471 vim9script
2472
2473 class Widget
2474 this._lnum: number = 1
2475
2476 def SetY(lnum: number)
2477 this._lnum = lnum
2478 enddef
2479
2480 def Text(): string
2481 return ''
2482 enddef
2483 endclass
2484
2485 class Foo extends Widget
2486 def Text(): string
2487 return '<Foo>'
2488 enddef
2489 endclass
2490
2491 def Stack(w1: Widget, w2: Widget): list<Widget>
2492 w1.SetY(1)
2493 w2.SetY(2)
2494 return [w1, w2]
2495 enddef
2496
2497 var foo1 = Foo.new()
2498 var foo2 = Foo.new()
2499 var l = Stack(foo1, foo2)
2500 END
2501 v9.CheckScriptSuccess(lines)
2502enddef
2503
Yegappan Lakshmananb1027282023-08-19 11:26:42 +02002504" Test for calling methods from three levels of classes
2505def Test_multi_level_method_call()
2506 var lines =<< trim END
2507 vim9script
2508
2509 var A_func1: number = 0
2510 var A_func2: number = 0
2511 var A_func3: number = 0
2512 var B_func2: number = 0
2513 var B_func3: number = 0
2514 var C_func3: number = 0
2515
2516 class A
2517 def Func1()
2518 A_func1 += 1
2519 enddef
2520
2521 def Func2()
2522 A_func2 += 1
2523 enddef
2524
2525 def Func3()
2526 A_func3 += 1
2527 enddef
2528 endclass
2529
2530 class B extends A
2531 def Func2()
2532 B_func2 += 1
2533 enddef
2534
2535 def Func3()
2536 B_func3 += 1
2537 enddef
2538 endclass
2539
2540 class C extends B
2541 def Func3()
2542 C_func3 += 1
2543 enddef
2544 endclass
2545
2546 def A_CallFuncs(a: A)
2547 a.Func1()
2548 a.Func2()
2549 a.Func3()
2550 enddef
2551
2552 def B_CallFuncs(b: B)
2553 b.Func1()
2554 b.Func2()
2555 b.Func3()
2556 enddef
2557
2558 def C_CallFuncs(c: C)
2559 c.Func1()
2560 c.Func2()
2561 c.Func3()
2562 enddef
2563
2564 var cobj = C.new()
2565 A_CallFuncs(cobj)
2566 B_CallFuncs(cobj)
2567 C_CallFuncs(cobj)
2568 assert_equal(3, A_func1)
2569 assert_equal(0, A_func2)
2570 assert_equal(0, A_func3)
2571 assert_equal(3, B_func2)
2572 assert_equal(0, B_func3)
2573 assert_equal(3, C_func3)
2574 END
2575 v9.CheckScriptSuccess(lines)
2576enddef
2577
2578" Test for using members from three levels of classes
2579def Test_multi_level_member_access()
2580 var lines =<< trim END
2581 vim9script
2582
2583 class A
2584 this.val1: number = 0
2585 this.val2: number = 0
2586 this.val3: number = 0
2587 endclass
2588
2589 class B extends A
2590 this.val2: number = 0
2591 this.val3: number = 0
2592 endclass
2593
2594 class C extends B
2595 this.val3: number = 0
2596 endclass
2597
2598 def A_members(a: A)
2599 a.val1 += 1
2600 a.val2 += 1
2601 a.val3 += 1
2602 enddef
2603
2604 def B_members(b: B)
2605 b.val1 += 1
2606 b.val2 += 1
2607 b.val3 += 1
2608 enddef
2609
2610 def C_members(c: C)
2611 c.val1 += 1
2612 c.val2 += 1
2613 c.val3 += 1
2614 enddef
2615
2616 var cobj = C.new()
2617 A_members(cobj)
2618 B_members(cobj)
2619 C_members(cobj)
2620 assert_equal(3, cobj.val1)
2621 assert_equal(3, cobj.val2)
2622 assert_equal(3, cobj.val3)
2623 END
2624 v9.CheckScriptSuccess(lines)
2625enddef
2626
LemonBoy0ffc17a2023-08-20 18:09:11 +02002627" Test expansion of <stack> with class methods.
2628def Test_stack_expansion_with_methods()
2629 var lines =<< trim END
2630 vim9script
2631
2632 class C
2633 def M1()
2634 F0()
2635 enddef
2636 endclass
2637
2638 def F0()
2639 assert_match('<SNR>\d\+_F\[1\]\.\.C\.M1\[1\]\.\.<SNR>\d\+_F0\[1\]$', expand('<stack>'))
2640 enddef
2641
2642 def F()
2643 C.new().M1()
2644 enddef
2645
2646 F()
2647 END
2648 v9.CheckScriptSuccess(lines)
2649enddef
Yegappan Lakshmanan6ac15442023-08-20 18:20:17 +02002650
2651" Test the return type of the new() constructor
2652def Test_new_return_type()
2653 # new() uses the default return type and there is no return statement
2654 var lines =<< trim END
2655 vim9script
2656
2657 class C
2658 this._bufnr: number
2659
2660 def new(this._bufnr)
2661 if !bufexists(this._bufnr)
2662 this._bufnr = -1
2663 endif
2664 enddef
2665 endclass
2666
2667 var c = C.new(12345)
2668 assert_equal('object<C>', typename(c))
2669
2670 var v1: C
2671 v1 = C.new(12345)
2672 assert_equal('object<C>', typename(v1))
2673
2674 def F()
2675 var v2: C
2676 v2 = C.new(12345)
2677 assert_equal('object<C>', typename(v2))
2678 enddef
2679 F()
2680 END
2681 v9.CheckScriptSuccess(lines)
2682
2683 # new() uses the default return type and an empty 'return' statement
2684 lines =<< trim END
2685 vim9script
2686
2687 class C
2688 this._bufnr: number
2689
2690 def new(this._bufnr)
2691 if !bufexists(this._bufnr)
2692 this._bufnr = -1
2693 return
2694 endif
2695 enddef
2696 endclass
2697
2698 var c = C.new(12345)
2699 assert_equal('object<C>', typename(c))
2700
2701 var v1: C
2702 v1 = C.new(12345)
2703 assert_equal('object<C>', typename(v1))
2704
2705 def F()
2706 var v2: C
2707 v2 = C.new(12345)
2708 assert_equal('object<C>', typename(v2))
2709 enddef
2710 F()
2711 END
2712 v9.CheckScriptSuccess(lines)
2713
2714 # new() uses "any" return type and returns "this"
2715 lines =<< trim END
2716 vim9script
2717
2718 class C
2719 this._bufnr: number
2720
2721 def new(this._bufnr): any
2722 if !bufexists(this._bufnr)
2723 this._bufnr = -1
2724 return this
2725 endif
2726 enddef
2727 endclass
2728 END
2729 v9.CheckScriptFailure(lines, 'E1365:')
2730
2731 # new() uses 'Dict' return type and returns a Dict
2732 lines =<< trim END
2733 vim9script
2734
2735 class C
2736 this._state: dict<any>
2737
2738 def new(): dict<any>
2739 this._state = {}
2740 return this._state
2741 enddef
2742 endclass
2743
2744 var c = C.new()
2745 assert_equal('object<C>', typename(c))
2746 END
2747 v9.CheckScriptFailure(lines, 'E1365:')
2748enddef
2749
Yegappan Lakshmanan618e47d2023-08-22 21:29:28 +02002750" Test for checking a member initialization type at run time.
2751def Test_runtime_type_check_for_member_init()
2752 var lines =<< trim END
2753 vim9script
2754
2755 var retnum: bool = false
2756
2757 def F(): any
2758 retnum = !retnum
2759 if retnum
2760 return 1
2761 else
2762 return "hello"
2763 endif
2764 enddef
2765
2766 class C
2767 this._foo: bool = F()
2768 endclass
2769
2770 var c1 = C.new()
2771 var c2 = C.new()
2772 END
2773 v9.CheckScriptFailure(lines, 'E1012:')
2774enddef
2775
2776" Test for locking a variable referring to an object and reassigning to another
2777" object.
2778def Test_object_lockvar()
2779 var lines =<< trim END
2780 vim9script
2781
2782 class C
2783 this.val: number
2784 def new(this.val)
2785 enddef
2786 endclass
2787
2788 var some_dict: dict<C> = { a: C.new(1), b: C.new(2), c: C.new(3), }
2789 lockvar 2 some_dict
2790
2791 var current: C
2792 current = some_dict['c']
2793 assert_equal(3, current.val)
2794 current = some_dict['b']
2795 assert_equal(2, current.val)
2796
2797 def F()
2798 current = some_dict['c']
2799 enddef
2800
2801 def G()
2802 current = some_dict['b']
2803 enddef
2804
2805 F()
2806 assert_equal(3, current.val)
2807 G()
2808 assert_equal(2, current.val)
2809 END
2810 v9.CheckScriptSuccess(lines)
2811enddef
2812
Yegappan Lakshmanancd7293b2023-08-27 19:18:23 +02002813" Test for a private object method
2814def Test_private_object_method()
2815 # Try calling a private method using an object (at the script level)
2816 var lines =<< trim END
2817 vim9script
2818
2819 class A
2820 def _Foo(): number
2821 return 1234
2822 enddef
2823 endclass
2824 var a = A.new()
2825 a._Foo()
2826 END
2827 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
2828
2829 # Try calling a private method using an object (from a def function)
2830 lines =<< trim END
2831 vim9script
2832
2833 class A
2834 def _Foo(): number
2835 return 1234
2836 enddef
2837 endclass
2838 def T()
2839 var a = A.new()
2840 a._Foo()
2841 enddef
2842 T()
2843 END
2844 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
2845
2846 # Use a private method from another object method (in script context)
2847 lines =<< trim END
2848 vim9script
2849
2850 class A
2851 def _Foo(): number
2852 return 1234
2853 enddef
2854 def Bar(): number
2855 return this._Foo()
2856 enddef
2857 endclass
2858 var a = A.new()
2859 assert_equal(1234, a.Bar())
2860 END
2861 v9.CheckScriptSuccess(lines)
2862
2863 # Use a private method from another object method (def function context)
2864 lines =<< trim END
2865 vim9script
2866
2867 class A
2868 def _Foo(): number
2869 return 1234
2870 enddef
2871 def Bar(): number
2872 return this._Foo()
2873 enddef
2874 endclass
2875 def T()
2876 var a = A.new()
2877 assert_equal(1234, a.Bar())
2878 enddef
2879 T()
2880 END
2881 v9.CheckScriptSuccess(lines)
2882
2883 # Try calling a private method without the "this" prefix
2884 lines =<< trim END
2885 vim9script
2886
2887 class A
2888 def _Foo(): number
2889 return 1234
2890 enddef
2891 def Bar(): number
2892 return _Foo()
2893 enddef
2894 endclass
2895 var a = A.new()
2896 a.Bar()
2897 END
2898 v9.CheckScriptFailure(lines, 'E117: Unknown function: _Foo')
2899
2900 # Try calling a private method using the class name
2901 lines =<< trim END
2902 vim9script
2903
2904 class A
2905 def _Foo(): number
2906 return 1234
2907 enddef
2908 endclass
2909 A._Foo()
2910 END
2911 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "A": _Foo()')
2912
2913 # Try to use "public" keyword when defining a private method
2914 lines =<< trim END
2915 vim9script
2916
2917 class A
2918 public def _Foo()
2919 enddef
2920 endclass
2921 var a = A.new()
2922 a._Foo()
2923 END
2924 v9.CheckScriptFailure(lines, 'E1331: Public must be followed by "this" or "static"')
2925
2926 # Define two private methods with the same name
2927 lines =<< trim END
2928 vim9script
2929
2930 class A
2931 def _Foo()
2932 enddef
2933 def _Foo()
2934 enddef
2935 endclass
2936 var a = A.new()
2937 END
2938 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: _Foo')
2939
2940 # Define a private method and a object method with the same name
2941 lines =<< trim END
2942 vim9script
2943
2944 class A
2945 def _Foo()
2946 enddef
2947 def Foo()
2948 enddef
2949 endclass
2950 var a = A.new()
2951 END
2952 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: Foo')
2953
2954 # Define an object method and a private method with the same name
2955 lines =<< trim END
2956 vim9script
2957
2958 class A
2959 def Foo()
2960 enddef
2961 def _Foo()
2962 enddef
2963 endclass
2964 var a = A.new()
2965 END
2966 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: _Foo')
2967
2968 # Call a public method and a private method from a private method
2969 lines =<< trim END
2970 vim9script
2971
2972 class A
2973 def Foo(): number
2974 return 100
2975 enddef
2976 def _Bar(): number
2977 return 200
2978 enddef
2979 def _Baz()
2980 assert_equal(100, this.Foo())
2981 assert_equal(200, this._Bar())
2982 enddef
2983 def T()
2984 this._Baz()
2985 enddef
2986 endclass
2987 var a = A.new()
2988 a.T()
2989 END
2990 v9.CheckScriptSuccess(lines)
2991
2992 # Try calling a private method from another class
2993 lines =<< trim END
2994 vim9script
2995
2996 class A
2997 def _Foo(): number
2998 return 100
2999 enddef
3000 endclass
3001 class B
3002 def Foo(): number
3003 var a = A.new()
3004 a._Foo()
3005 enddef
3006 endclass
3007 var b = B.new()
3008 b.Foo()
3009 END
3010 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
3011
3012 # Call a private object method from a child class object method
3013 lines =<< trim END
3014 vim9script
3015 class A
3016 def _Foo(): number
3017 return 1234
3018 enddef
3019 endclass
3020 class B extends A
3021 def Bar()
3022 enddef
3023 endclass
3024 class C extends B
3025 def Baz(): number
3026 return this._Foo()
3027 enddef
3028 endclass
3029 var c = C.new()
3030 assert_equal(1234, c.Baz())
3031 END
3032 v9.CheckScriptSuccess(lines)
3033
3034 # Call a private object method from a child class object
3035 lines =<< trim END
3036 vim9script
3037 class A
3038 def _Foo(): number
3039 return 1234
3040 enddef
3041 endclass
3042 class B extends A
3043 def Bar()
3044 enddef
3045 endclass
3046 class C extends B
3047 def Baz(): number
3048 enddef
3049 endclass
3050 var c = C.new()
3051 assert_equal(1234, c._Foo())
3052 END
3053 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
3054
3055 # Using "_" prefix in a method name should fail outside of a class
3056 lines =<< trim END
3057 vim9script
3058 def _Foo(): number
3059 return 1234
3060 enddef
3061 var a = _Foo()
3062 END
3063 v9.CheckScriptFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number')
3064enddef
3065
3066" Test for an private class method
3067def Test_private_class_method()
3068 # Try calling a class private method (at the script level)
3069 var lines =<< trim END
3070 vim9script
3071
3072 class A
3073 static def _Foo(): number
3074 return 1234
3075 enddef
3076 endclass
3077 A._Foo()
3078 END
3079 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
3080
3081 # Try calling a class private method (from a def function)
3082 lines =<< trim END
3083 vim9script
3084
3085 class A
3086 static def _Foo(): number
3087 return 1234
3088 enddef
3089 endclass
3090 def T()
3091 A._Foo()
3092 enddef
3093 T()
3094 END
3095 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
3096
3097 # Try calling a class private method using an object (at the script level)
3098 lines =<< trim END
3099 vim9script
3100
3101 class A
3102 static def _Foo(): number
3103 return 1234
3104 enddef
3105 endclass
3106 var a = A.new()
3107 a._Foo()
3108 END
3109 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "A": _Foo()')
3110
3111 # Try calling a class private method using an object (from a def function)
3112 lines =<< trim END
3113 vim9script
3114
3115 class A
3116 static def _Foo(): number
3117 return 1234
3118 enddef
3119 endclass
3120 def T()
3121 var a = A.new()
3122 a._Foo()
3123 enddef
3124 T()
3125 END
3126 v9.CheckScriptFailure(lines, 'E1325: Method not found on class "A": _Foo()')
3127
3128 # Use a class private method from an object method
3129 lines =<< trim END
3130 vim9script
3131
3132 class A
3133 static def _Foo(): number
3134 return 1234
3135 enddef
3136 def Bar()
3137 assert_equal(1234, A._Foo())
3138 enddef
3139 endclass
3140 var a = A.new()
3141 a.Bar()
3142 END
3143 v9.CheckScriptSuccess(lines)
3144
3145 # Use a class private method from another class private method
3146 lines =<< trim END
3147 vim9script
3148
3149 class A
3150 static def _Foo1(): number
3151 return 1234
3152 enddef
3153 static def _Foo2()
3154 assert_equal(1234, A._Foo1())
3155 enddef
3156 def Bar()
3157 A._Foo2()
3158 enddef
3159 endclass
3160 var a = A.new()
3161 a.Bar()
3162 END
3163 v9.CheckScriptSuccess(lines)
3164
3165 # Declare a class method and a class private method with the same name
3166 lines =<< trim END
3167 vim9script
3168
3169 class A
3170 static def _Foo()
3171 enddef
3172 static def Foo()
3173 enddef
3174 endclass
3175 var a = A.new()
3176 END
3177 v9.CheckScriptFailure(lines, 'E1355: Duplicate function: Foo')
3178
3179 # Try calling a class private method from another class
3180 lines =<< trim END
3181 vim9script
3182
3183 class A
3184 static def _Foo(): number
3185 return 1234
3186 enddef
3187 endclass
3188 class B
3189 def Foo(): number
3190 return A._Foo()
3191 enddef
3192 endclass
3193 var b = B.new()
3194 assert_equal(1234, b.Foo())
3195 END
3196 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
3197
3198 # Call a private class method from a child class object method
3199 lines =<< trim END
3200 vim9script
3201 class A
3202 static def _Foo(): number
3203 return 1234
3204 enddef
3205 endclass
3206 class B extends A
3207 def Bar()
3208 enddef
3209 endclass
3210 class C extends B
3211 def Baz(): number
3212 return A._Foo()
3213 enddef
3214 endclass
3215 var c = C.new()
3216 assert_equal(1234, c.Baz())
3217 END
3218 v9.CheckScriptSuccess(lines)
3219
3220 # Call a private class method from a child class private class method
3221 lines =<< trim END
3222 vim9script
3223 class A
3224 static def _Foo(): number
3225 return 1234
3226 enddef
3227 endclass
3228 class B extends A
3229 def Bar()
3230 enddef
3231 endclass
3232 class C extends B
3233 static def Baz(): number
3234 return A._Foo()
3235 enddef
3236 endclass
3237 assert_equal(1234, C.Baz())
3238 END
3239 v9.CheckScriptSuccess(lines)
3240
3241 # Call a private class method from a child class object
3242 lines =<< trim END
3243 vim9script
3244 class A
3245 static def _Foo(): number
3246 return 1234
3247 enddef
3248 endclass
3249 class B extends A
3250 def Bar()
3251 enddef
3252 endclass
3253 class C extends B
3254 def Baz(): number
3255 enddef
3256 endclass
3257 var c = C.new()
3258 assert_equal(1234, C._Foo())
3259 END
3260 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
3261enddef
3262
3263" Test for an interface private object_method
3264def Test_interface_private_object_method()
3265 # Implement an interface private method and use it from a public method
3266 var lines =<< trim END
3267 vim9script
3268 interface Intf
3269 def _Foo(): number
3270 endinterface
3271 class A implements Intf
3272 def _Foo(): number
3273 return 1234
3274 enddef
3275 def Bar(): number
3276 return this._Foo()
3277 enddef
3278 endclass
3279 var a = A.new()
3280 assert_equal(1234, a.Bar())
3281 END
3282 v9.CheckScriptSuccess(lines)
3283
3284 # Call an interface private class method (script context)
3285 lines =<< trim END
3286 vim9script
3287 interface Intf
3288 def _Foo(): number
3289 endinterface
3290 class A implements Intf
3291 def _Foo(): number
3292 return 1234
3293 enddef
3294 endclass
3295 var a = A.new()
3296 assert_equal(1234, a._Foo())
3297 END
3298 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
3299
3300 # Call an interface private class method (def context)
3301 lines =<< trim END
3302 vim9script
3303 interface Intf
3304 def _Foo(): number
3305 endinterface
3306 class A implements Intf
3307 def _Foo(): number
3308 return 1234
3309 enddef
3310 endclass
3311 def T()
3312 var a = A.new()
3313 assert_equal(1234, a._Foo())
3314 enddef
3315 T()
3316 END
3317 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo()')
3318
3319 # Implement an interface private object method as a private class method
3320 lines =<< trim END
3321 vim9script
3322 interface Intf
3323 def _Foo(): number
3324 endinterface
3325 class A implements Intf
3326 static def _Foo(): number
3327 return 1234
3328 enddef
3329 endclass
3330 END
3331 v9.CheckScriptFailure(lines, 'E1349: Function "_Foo" of interface "Intf" not implemented')
3332enddef
3333
3334" Test for an interface private class method
3335def Test_interface_private_class_method()
3336 # Implement an interface private class method and use it from a public method
3337 var lines =<< trim END
3338 vim9script
3339 interface Intf
3340 static def _Foo(): number
3341 endinterface
3342 class A implements Intf
3343 static def _Foo(): number
3344 return 1234
3345 enddef
3346 def Bar(): number
3347 return A._Foo()
3348 enddef
3349 endclass
3350 var a = A.new()
3351 assert_equal(1234, a.Bar())
3352 END
3353 v9.CheckScriptSuccess(lines)
3354
3355 # Call an interface private class method (script context)
3356 lines =<< trim END
3357 vim9script
3358 interface Intf
3359 static def _Foo(): number
3360 endinterface
3361 class A implements Intf
3362 static def _Foo(): number
3363 return 1234
3364 enddef
3365 endclass
3366 assert_equal(1234, A._Foo())
3367 END
3368 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo())')
3369
3370 # Call an interface private class method (def context)
3371 lines =<< trim END
3372 vim9script
3373 interface Intf
3374 static def _Foo(): number
3375 endinterface
3376 class A implements Intf
3377 static def _Foo(): number
3378 return 1234
3379 enddef
3380 endclass
3381 def T()
3382 assert_equal(1234, A._Foo())
3383 enddef
3384 T()
3385 END
3386 v9.CheckScriptFailure(lines, 'E1366: Cannot access private method: _Foo())')
3387
3388 # Implement an interface private class method as a private object method
3389 lines =<< trim END
3390 vim9script
3391 interface Intf
3392 static def _Foo(): number
3393 endinterface
3394 class A implements Intf
3395 def _Foo(): number
3396 return 1234
3397 enddef
3398 endclass
3399 END
3400 v9.CheckScriptFailure(lines, 'E1349: Function "_Foo" of interface "Intf" not implemented')
3401enddef
3402
Yegappan Lakshmanan639751d2023-08-27 19:23:37 +02003403" Test for using the return value of a class/object method as a function
3404" argument.
3405def Test_objmethod_funcarg()
3406 var lines =<< trim END
3407 vim9script
3408
3409 class C
3410 def Foo(): string
3411 return 'foo'
3412 enddef
3413 endclass
3414
3415 def Bar(a: number, s: string): string
3416 return s
3417 enddef
3418
3419 def Baz(c: C)
3420 assert_equal('foo', Bar(10, c.Foo()))
3421 enddef
3422
3423 var t = C.new()
3424 Baz(t)
3425 END
3426 v9.CheckScriptSuccess(lines)
3427
3428 lines =<< trim END
3429 vim9script
3430
3431 class C
3432 static def Foo(): string
3433 return 'foo'
3434 enddef
3435 endclass
3436
3437 def Bar(a: number, s: string): string
3438 return s
3439 enddef
3440
3441 def Baz()
3442 assert_equal('foo', Bar(10, C.Foo()))
3443 enddef
3444
3445 Baz()
3446 END
3447 v9.CheckScriptSuccess(lines)
3448enddef
3449
Yegappan Lakshmanan2ba9d2e2023-08-28 21:26:23 +02003450" Test for declaring duplicate object and class members
3451def Test_dup_member_variable()
3452 # Duplicate member variable
3453 var lines =<< trim END
3454 vim9script
3455 class C
3456 this.val = 10
3457 this.val = 20
3458 endclass
3459 END
3460 v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
3461
3462 # Duplicate private member variable
3463 lines =<< trim END
3464 vim9script
3465 class C
3466 this._val = 10
3467 this._val = 20
3468 endclass
3469 END
3470 v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _val')
3471
3472 # Duplicate public member variable
3473 lines =<< trim END
3474 vim9script
3475 class C
3476 public this.val = 10
3477 public this.val = 20
3478 endclass
3479 END
3480 v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
3481
3482 # Duplicate private member variable
3483 lines =<< trim END
3484 vim9script
3485 class C
3486 this.val = 10
3487 this._val = 20
3488 endclass
3489 END
3490 v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _val')
3491
3492 # Duplicate public and private member variable
3493 lines =<< trim END
3494 vim9script
3495 class C
3496 this._val = 20
3497 public this.val = 10
3498 endclass
3499 END
3500 v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
3501
3502 # Duplicate class member variable
3503 lines =<< trim END
3504 vim9script
3505 class C
3506 static s: string = "abc"
3507 static _s: string = "def"
3508 endclass
3509 END
3510 v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _s')
3511
3512 # Duplicate public and private class member variable
3513 lines =<< trim END
3514 vim9script
3515 class C
3516 public static s: string = "abc"
3517 static _s: string = "def"
3518 endclass
3519 END
3520 v9.CheckScriptFailure(lines, 'E1369: Duplicate member: _s')
3521
3522 # Duplicate class and object member variable
3523 lines =<< trim END
3524 vim9script
3525 class C
3526 static val = 10
3527 this.val = 20
3528 def new()
3529 enddef
3530 endclass
3531 var c = C.new()
3532 assert_equal(10, C.val)
3533 assert_equal(20, c.val)
3534 END
3535 v9.CheckScriptSuccess(lines)
3536enddef
3537
Bram Moolenaar00b28d62022-12-08 15:32:33 +00003538" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker